Kubernetes从入门到实战:手把手教你部署高可用的容器化应用

引言

随着微服务和容器化的普及,传统的应用部署方式正被颠覆。如何统一管理成百上千的容器实例,实现自动扩缩、服务发现与负载均衡?这就不得不提云原生的核心——Kubernetes(K8s)。不过,入门Kubernetes常因概念繁杂、命令众多而让人望而却步。本文不会堆砌理论,而是用一个完整的实战项目,带你从零搭建集群(Minikube)、编写部署清单,最终让一个可水平扩展的Web应用真正跑起来。读完你会发现,Kubernetes没有想象中那么难。

1. 先理解几个核心概念

如果只是敲命令,你很快会迷失方向。我们先梳理最重要的三大资源对象,后续操作都会围绕它们展开。

1.1 Pod——最小的调度单元

Pod是Kubernetes里最小、最简单的部署单位。一个Pod可以包含一个或多个紧密共享网络和存储的容器。在生产中,我们通常不在Pod里直接运行多个复杂服务,而是让一个Pod只跑一个应用实例。

1.2 Deployment——管理Pod的控制器

你很少会直接创建裸Pod。Deployment负责声明式地管理Pod的期望副本数、更新策略等。一旦某个Pod挂了,Deployment会自动重建并恢复到声明状态,它也是实现滚动更新的基础。

1.3 Service——稳定的访问入口

Pod IP是易变的,每次重建都会改变。Service为一组Pod提供一个固定的虚拟IP(集群内)和DNS名,并通过标签选择器找到后端的Pod。Service类型包括ClusterIP(内部访问)、NodePort(物理节点端口)和LoadBalancer(云负载均衡)。

这三个对象的关系可以用下图理解:

[Deployment] -- 管理 --> [Pod集合] -- 暴露 --> [Service]

下面,我们马上动手实践。

2. 环境准备:启动本地Kubernetes集群

为了让所有人都能复现,我们使用Minikube在本地运行一套单节点K8s集群。如果你的机器已安装Docker Desktop等内置K8s,也可以直接使用。

2.1 安装Minikube

  • macOS:
    bash brew install minikube
  • Windows (使用Chocolatey):
    powershell choco install minikube
  • Linux:
    bash curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 sudo install minikube-linux-amd64 /usr/local/bin/minikube

详细说明可参考官方文档

2.2 启动集群并验证

minikube start --driver=docker   # 使用docker驱动
kubectl cluster-info             # 查看集群信息
kubectl get nodes                # 应能看到一个Ready节点

如果没有kubectl,可通过minikube kubectl -- get pods替代,或单独安装kubectl。

3. 实战:部署一个可伸缩的Nginx应用

我们将执行一套完整的部署流水线:创建Deployment → 暴露Service → 验证连通性 → 演示扩缩容。

3.1 编写Deployment清单

新建文件 nginx-deployment.yaml,内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment      # Deployment名称
  labels:
    app: nginx                # 可选的标签
spec:
  replicas: 3                 # 期望副本数
  selector:
    matchLabels:
      app: nginx              # 必须与Pod模板的标签一致
  template:                   # Pod模板
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25.3   # 指定镜像版本
        ports:
        - containerPort: 80   # 容器监听端口
        resources:            # 资源限制(生产必备)
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "200m"
            memory: "256Mi"
        readinessProbe:       # 就绪探针,确保Pod准备好后才接收流量
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:        # 存活探针,容器不正常时自动重启
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 15
          periodSeconds: 20
  • replicas: 3:我们一开始就部署3个副本,体现高可用。
  • resources:设置了最少100m CPU、128Mi内存,最大200m CPU、256Mi内存。
  • readinessProbe:只有在http://:80/ 返回成功时,才将Pod标记为Ready并加入Service端点。
  • livenessProbe:持续检查健康状态,异常时重启容器。

3.2 应用Deployment

kubectl apply -f nginx-deployment.yaml
# 输出:deployment.apps/nginx-deployment created

# 查看Deployment状态
kubectl get deployments
# NAME               READY   UP-TO-DATE   AVAILABLE   AGE
# nginx-deployment   3/3     3            3           10s

# 查看Pod(由于是3副本,你会看到3个Pod)
kubectl get pods -o wide
# 输出三个状况为Running的Pod

3.3 创建Service暴露应用

Pod运行在集群内部,外部无法直接访问。我们需要创建一个 NodePort 类型的Service(Minikube不支持直接LoadBalancer,但可用NodePort或minikube tunnel模拟LoadBalancer)。

新建 nginx-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort            # 也可设为ClusterIP(仅集群内),这里为了方便演示选NodePort
  selector:
    app: nginx              # 与Pod标签匹配
  ports:
    - protocol: TCP
      port: 80              # Service自己的端口
      targetPort: 80        # 容器端口
      nodePort: 30080       # 节点上暴露的端口(范围30000-32767)

执行创建:

kubectl apply -f nginx-service.yaml
# 输出:service/nginx-service created

# 查看Service详情
kubectl get svc nginx-service
# NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
# nginx-service   NodePort   10.100.200.50   <none>        80:30080/TCP   5s

3.4 验证服务可访问性

Minikube环境下,获取节点的IP地址:

minikube ip
# 假设输出 192.168.49.2

然后在浏览器访问 http://192.168.49.2:30080,你会看到Nginx的欢迎页面。或者在终端用curl测试:

curl http://$(minikube ip):30080
# 返回HTML内容,证明成功

如果你用的是Docker Desktop内置K8s,则直接访问 http://localhost:30080 即可。

3.5 实操:水平扩缩容

假设流量激增,我们需要将副本数从3扩展到5:

kubectl scale deployment nginx-deployment --replicas=5
# 查看Pod数量变化
kubectl get pods
# 你会看到新增两个Pod正在启动

之后若想缩容回3个,只需执行:

kubectl scale deployment nginx-deployment --replicas=3

所有变化都由控制器异步完成,保证最终状态符合期望。

4. 深入理解:资源清单与常用命令

4.1 管理工具的黄金组合

  • kubectl apply -f <file>:声明式部署,推荐使用。
  • kubectl delete -f <file>:删除对应资源。
  • kubectl describe pod <pod-name>:查看Pod事件与详情,排错利器。
  • kubectl logs <pod-name>:查看容器日志,可加 -f 实时跟踪。
  • kubectl exec -it <pod-name> -- /bin/bash:进入容器交互式命令行。

4.2 为什么要使用 requestslimits

  • requests 告诉调度器Pod需要的最小资源量,调度器会保证节点上有足量资源。
  • limits 防止单个Pod消耗过多资源影响同一节点上的其他Pod。超过limit时,CPU会被节流,而内存超出则会被OOM Killer杀掉。

4.3 探针的正确设置

探针配置不当会导致容器频繁重启或永远不能就绪。建议:
- initialDelaySeconds 设得比应用启动到完全运行所需时间稍长。
- 生产环境一定要配置 readinessProbe,因为Pod Running不代表服务已ready。
- 探针路径尽量简单高效,避免占用过多资源。

5. 常见问题与注意事项

  1. 镜像拉取失败
    如果使用本地私有镜像或命名空间错误,查看Pod事件:kubectl describe pod <pod>。常见错误有ImagePullBackOff,这时要检查镜像名、仓库凭证(imagePullSecrets)。

  2. Service无法访问
    先检查Service的selector与Pod标签是否一致:kubectl get endpoints nginx-service,若无端点,说明label没有匹配到任何Pod。接着用kubectl port-forward直接转发Pod端口测试Pod本身服务是否正常。

  3. Minikube资源不足
    默认Minikube只分配2GB内存。如需更多,启动时指定:minikube start --memory=4096。生产环境推荐的多节点集群不应使用Minikube。

  4. 配置文件版本问题
    apiVersion必须与集群K8s版本兼容。例如apps/v1适用于1.9以后的版本。可先用kubectl api-versions查看支持的API组。

  5. 敏感信息处理
    不要在YAML中硬编码密码等,应使用Secret对象,并通过环境变量或卷挂载到Pod。

6. 总结

通过这个实战,我们完整经历了:搭建K8s环境 → 编写Deployment清单 → 部署多副本应用 → 暴露Service → 测试验证 → 动态扩缩容。这些是生产级应用最基础的技能。

Kubernetes的门槛并不在于敲几条命令,而在于理解声明式设计的哲学。当你习惯描述“我想要什么状态”,而不是“如何一步步达到”时,就真正迈入了云原生的大门。

下一步,你可以尝试:
- 添加Ingress资源,实现基于域名的路由。
- 使用ConfigMap和Secret配置应用环境。
- 学习Helm,将复杂应用打包实现一键部署。
- 引入CI/CD流程,自动化构建和发布。

动手是最好的学习方式,建议你亲自敲完上面的所有命令,遇到问题多查看 describelogs。Kubernetes生态广阔,但基础牢固后,进阶之路就会越走越宽。希望本文能为你打开一扇窗,让容器编排变得亲切起来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

至乐活着

失业续命中,这篇有用就赏杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值