跳转到内容

Pod和Deployment管理

课程目标

通过本课程的学习,你将能够:

  • 理解Pod的生命周期和状态转换
  • 掌握Deployment的创建、更新、回滚和扩缩容
  • 配置Pod健康检查(存活探针和就绪探针)
  • 使用标签和选择器管理K8S资源
  • 掌握Pod调度策略(节点亲和性、污点容忍等)
  • 排查Pod和Deployment的常见故障

前置要求:已完成《K8S学习环境搭建与初体验》和《Kubernetes架构和核心概念》课程

1. 深入理解Pod

1.1 什么是Pod

Pod是Kubernetes中最小的部署单元,一个Pod可以包含一个或多个容器,这些容器:

  • 共享网络命名空间(IP地址和端口空间)
  • 共享存储卷(可以挂载相同的存储)
  • 一起被调度和管理(生命周期相同)

为什么需要Pod?

  • 紧密耦合的容器:如主应用+日志收集器(Sidecar模式)
  • 资源共享:容器之间可以直接通过localhost通信
  • 统一管理:一起创建、一起销毁

1.2 Pod的生命周期

Pod从创建到销毁会经历多个阶段:

创建 → Pending → Running → Succeeded/Failed → Terminating
状态说明常见原因
PendingPod已创建,等待调度或拉取镜像镜像拉取中、资源不足、调度失败
RunningPod已调度到节点,容器正在运行正常运行状态
Succeeded所有容器成功完成(一次性任务)Job执行完成
Failed所有容器终止,至少一个失败应用启动失败
CrashLoopBackOff容器反复崩溃重启应用错误、配置错误
Unknown无法获取Pod状态节点通信异常

状态转换图

                    ┌─────────────┐
                    │   Created   │
                    └──────┬──────┘


                    ┌─────────────┐
         ┌─────────│   Pending   │─────────┐
         │         └──────┬──────┘         │
         │                │                │
         ▼                ▼                ▼
   ┌──────────┐    ┌──────────┐    ┌──────────┐
   │  Failed  │    │ Running  │    │Succeeded │
   └──────────┘    └────┬─────┘    └──────────┘

           ┌────────────┼────────────┐
           ▼            ▼            ▼
    ┌──────────┐ ┌──────────┐ ┌──────────┐
    │CrashLoop │ │Completed │ │ Terminat-│
    │ BackOff  │ │          │ │   ing    │
    └──────────┘ └──────────┘ └──────────┘

1.3 创建和管理Pod

实战:创建第一个Pod

让我们创建一个简单的Nginx Pod:

yaml
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: my-app
    environment: production
spec:
  containers:
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80
    resources:
      requests:
        cpu: 100m
        memory: 256Mi
      limits:
        cpu: 500m
        memory: 512Mi

执行步骤

bash
# 1. 创建Pod
kubectl apply -f pod.yaml
# 输出:pod/my-pod created

# 2. 查看Pod状态
kubectl get pods
# 输出示例:
# NAME     READY   STATUS    RESTARTS   AGE
# my-pod   1/1     Running   0          10s

# 3. 查看Pod详情(排查问题时使用)
kubectl describe pod my-pod

# 4. 查看Pod日志
kubectl logs my-pod

# 5. 进入Pod内部执行命令
kubectl exec -it my-pod -- /bin/bash
# 在容器内执行:
# ls /usr/share/nginx/html
# exit

# 6. 删除Pod
kubectl delete pod my-pod

Pod管理常用命令速查

命令作用
kubectl get pods查看所有Pod
kubectl get pods -o wide查看Pod详细信息(包括IP和节点)
kubectl describe pod <name>查看Pod事件和详情
kubectl logs <name>查看Pod日志
kubectl logs <name> -f实时查看日志
kubectl exec -it <name> -- /bin/bash进入Pod容器
kubectl delete pod <name>删除Pod

1.4 Pod的健康检查(探针)

Kubernetes提供两种探针来监控容器健康状态:

探针类型作用失败时的行为
存活探针(Liveness Probe)检测容器是否存活重启容器
就绪探针(Readiness Probe)检测容器是否准备好接收流量从Service端点移除

为什么需要探针?

  • 存活探针:防止应用死锁但进程仍在运行的情况
  • 就绪探针:防止流量发送到还未启动完成的容器

实战:配置健康检查

yaml
apiVersion: v1
kind: Pod
metadata:
  name: health-check-demo
spec:
  containers:
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80
    # 存活探针:检测容器是否存活
    livenessProbe:
      httpGet:
        path: /  # 访问根路径
        port: 80
      initialDelaySeconds: 30  # 容器启动30秒后开始检测
      periodSeconds: 10        # 每10秒检测一次
      timeoutSeconds: 5        # 超时时间5秒
      failureThreshold: 3      # 连续失败3次才认为不健康
    # 就绪探针:检测容器是否准备好接收流量
    readinessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 5   # 容器启动5秒后开始检测
      periodSeconds: 10
      successThreshold: 1      # 连续成功1次就认为就绪

探针配置参数详解

参数说明默认值
initialDelaySeconds容器启动后首次检测的延迟时间0
periodSeconds检测间隔时间10
timeoutSeconds检测超时时间1
successThreshold连续成功次数认为健康1
failureThreshold连续失败次数认为不健康3

三种探针检测方式

1. HTTP GET检测(最常用)

yaml
livenessProbe:
  httpGet:
    path: /health  # 健康检查接口
    port: 8080
    httpHeaders:   # 自定义请求头
    - name: Custom-Header
      value: Awesome

2. TCP Socket检测

yaml
livenessProbe:
  tcpSocket:
    port: 3306  # 检测MySQL端口
  initialDelaySeconds: 30
  periodSeconds: 10

3. Exec命令检测

yaml
livenessProbe:
  exec:
    command:
    - /bin/sh
    - -c
    - "cat /tmp/healthy"  # 检查文件是否存在
  initialDelaySeconds: 5
  periodSeconds: 5

实战:验证探针效果

bash
# 1. 创建带健康检查的Pod
kubectl apply -f health-check-demo.yaml

# 2. 查看Pod状态
kubectl get pod health-check-demo

# 3. 查看探针事件
kubectl describe pod health-check-demo | grep -A 5 Events

# 4. 模拟探针失败(进入容器删除健康检查文件)
kubectl exec -it health-check-demo -- rm /tmp/healthy

# 5. 观察容器重启
kubectl get pod health-check-demo -w
# 你会看到RESTARTS计数增加

1.5 Pod的资源管理

资源单位详解

Kubernetes使用特定的单位来表示CPU和内存资源:

CPU资源

  • 1 = 1个CPU核心
  • 1000m = 1000毫核 = 1核
  • 500m = 0.5核
  • 100m = 0.1核(适合轻量级应用)

内存资源

  • Mi = Mebibytes(1024进制)
  • Gi = Gibibytes
  • M = Megabytes(1000进制)
  • G = Gigabytes

资源请求和限制

配置项说明作用
requests资源请求调度时保证分配的资源
limits资源限制容器能使用的最大资源

实战配置示例

yaml
apiVersion: v1
kind: Pod
metadata:
  name: resource-demo
spec:
  containers:
  - name: nginx
    image: nginx:1.21
    resources:
      requests:
        cpu: 100m        # 请求0.1核CPU
        memory: 256Mi    # 请求256MB内存
      limits:
        cpu: 500m        # 限制最多使用0.5核CPU
        memory: 512Mi    # 限制最多使用512MB内存

requests vs limits的区别

  • requests:调度器用此值决定Pod放在哪个节点
  • limits:运行时限制,容器不能超过这个值
  • CPU超限时会被节流(throttle),内存超限时会被OOM Kill

QoS级别(服务质量等级)

Kubernetes根据资源配置将Pod分为三个QoS级别,用于资源紧张时的驱逐决策:

QoS级别条件优先级驱逐顺序
Guaranteedrequests = limits,且只设置limits最高最后被驱逐
Burstablerequests < limits,或只设置requests中等中等优先级
BestEffort未设置requests和limits最低首先被驱逐

查看Pod的QoS级别

bash
kubectl get pod <pod-name> -o jsonpath='{.status.qosClass}'

1.5 Pod的调度

节点选择器

使用节点标签和Pod的节点选择器控制Pod调度到特定节点。

bash
# 为节点添加标签
kubectl label node worker-1 app=frontend

# 查看节点标签
kubectl get nodes --show-labels
yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  nodeSelector:
    app: frontend
  containers:
  - name: nginx
    image: nginx:1.21

节点亲和性和反亲和性

  • 节点亲和性:将Pod调度到满足条件的节点
  • 节点反亲和性:避免将Pod调度到满足条件的节点
yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: app
            operator: In
            values:
            - frontend
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        preference:
          matchExpressions:
          - key: hardware-type
            operator: In
            values:
            - ssd
  containers:
  - name: nginx
    image: nginx:1.21

Pod亲和性和反亲和性

  • Pod亲和性:将相关Pod调度到同一节点或区域
  • Pod反亲和性:避免将相关Pod调度到同一节点或区域
yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - frontend
        topologyKey: kubernetes.io/hostname
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - database
          topologyKey: kubernetes.io/hostname
  containers:
  - name: nginx
    image: nginx:1.21

污点和容忍度

  • 污点(Taints):节点上的标记,排斥Pod调度
  • 容忍度(Tolerations):Pod上的标记,允许Pod调度到有污点的节点
bash
# 为节点添加污点
kubectl taint node worker-1 dedicated=special-user:NoSchedule

# 查看节点污点
kubectl describe node worker-1 | grep Taints

# 移除节点污点
kubectl taint node worker-1 dedicated=special-user:NoSchedule-
yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  tolerations:
  - key: "dedicated"
    operator: "Equal"
    value: "special-user"
    effect: "NoSchedule"
  containers:
  - name: nginx
    image: nginx:1.21

2. Deployment管理

2.1 创建和管理Deployment

Deployment是管理Pod副本的控制器,提供声明式更新、滚动更新和回滚功能。

创建Deployment

yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 100m
            memory: 256Mi
          limits:
            cpu: 500m
            memory: 512Mi
bash
# 创建Deployment
kubectl apply -f deployment.yaml

# 查看Deployment状态
kubectl get deployments

# 查看Deployment详情
kubectl describe deployment nginx-deployment

# 查看Deployment创建的Pod
kubectl get pods -l app=nginx

# 查看Deployment的滚动更新状态
kubectl rollout status deployment nginx-deployment

# 删除Deployment
kubectl delete deployment nginx-deployment

2.2 Deployment的更新策略

Deployment支持两种更新策略:

  1. 滚动更新(RollingUpdate):默认策略,逐步替换旧Pod
  2. 重建(Recreate):先删除所有旧Pod,再创建新Pod

配置更新策略

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
  • maxSurge:更新过程中允许超出副本数的最大Pod数
  • maxUnavailable:更新过程中允许不可用的最大Pod数

2.3 执行滚动更新

更新镜像版本

bash
# 更新镜像版本
kubectl set image deployment nginx-deployment nginx=nginx:1.22

# 查看更新状态
kubectl rollout status deployment nginx-deployment

# 查看更新历史
kubectl rollout history deployment nginx-deployment

# 查看特定版本的详情
kubectl rollout history deployment nginx-deployment --revision=2

# 回滚到之前版本
kubectl rollout undo deployment nginx-deployment

# 回滚到特定版本
kubectl rollout undo deployment nginx-deployment --to-revision=1

使用kubectl edit更新

bash
# 编辑Deployment配置
kubectl edit deployment nginx-deployment

# 查看更新状态
kubectl rollout status deployment nginx-deployment

2.4 Deployment的扩缩容

手动扩缩容

bash
# 扩缩容到5个副本
kubectl scale deployment nginx-deployment --replicas=5

# 查看状态
kubectl get deployment nginx-deployment
kubectl get pods -l app=nginx

自动扩缩容

使用Horizontal Pod Autoscaler(HPA)根据资源使用情况自动扩缩容。

bash
# 安装Metrics Server(如果未安装)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# 创建HPA
kubectl autoscale deployment nginx-deployment --min=3 --max=10 --cpu-percent=50

# 查看HPA状态
kubectl get hpa

# 查看Pod状态
kubectl get pods -l app=nginx

2.5 Deployment的最佳实践

  1. 使用标签和选择器:合理使用标签管理资源
  2. 配置资源限制:为容器设置合理的资源请求和限制
  3. 健康检查:配置存活探针和就绪探针
  4. 更新策略:根据应用特性选择合适的更新策略
  5. 自动扩缩容:使用HPA实现自动扩缩容
  6. 滚动更新:使用滚动更新实现零停机部署
  7. 回滚机制:利用Deployment的回滚功能快速恢复故障
  8. 版本管理:使用不同的标签管理不同版本的应用

3. 标签和选择器

3.1 标签管理

标签是附加到Kubernetes资源上的键值对,用于组织和选择资源。

bash
# 为Pod添加标签
kubectl label pod my-pod environment=production tier=frontend

# 查看Pod标签
kubectl get pod my-pod --show-labels

# 更新Pod标签
kubectl label pod my-pod environment=staging --overwrite

# 删除Pod标签
kubectl label pod my-pod tier-

# 为所有Pod添加标签
kubectl label pods --all environment=production

3.2 选择器使用

选择器用于根据标签选择资源。

bash
# 按标签选择Pod
kubectl get pods -l environment=production

# 按多个标签选择Pod
kubectl get pods -l environment=production,tier=frontend

# 按标签表达式选择Pod
kubectl get pods -l 'environment in (production, staging)'

# 按标签表达式选择Pod(不包含)
kubectl get pods -l 'environment notin (production)'

# 按标签存在性选择Pod
kubectl get pods -l 'environment'

# 按标签不存在性选择Pod
kubectl get pods -l '!environment'

3.3 标签的最佳实践

  1. 一致性:使用一致的标签命名约定
  2. 语义化:标签应具有明确的语义
  3. 层次化:使用层次化的标签结构
  4. 标准化:建立组织内部的标签标准
  5. 自动化:在CI/CD流程中自动添加标签

推荐的标签

标签描述示例
app.kubernetes.io/name应用名称nginx
app.kubernetes.io/instance应用实例nginx-production
app.kubernetes.io/version应用版本1.21.0
app.kubernetes.io/component应用组件frontend
app.kubernetes.io/part-of所属应用ecommerce
app.kubernetes.io/managed-by管理工具helm
environment环境production, staging, development
tier层级frontend, backend, database
release发布版本v1, v2
team负责团队devops, frontend
region区域us-east, eu-west

4. 实战案例:部署和管理应用

4.1 部署多副本应用

yaml
# app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app.kubernetes.io/name: my-app
    app.kubernetes.io/instance: my-app-production
    environment: production
    tier: frontend
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: my-app
      app.kubernetes.io/instance: my-app-production
  template:
    metadata:
      labels:
        app.kubernetes.io/name: my-app
        app.kubernetes.io/instance: my-app-production
        environment: production
        tier: frontend
    spec:
      containers:
      - name: my-app
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 100m
            memory: 256Mi
          limits:
            cpu: 500m
            memory: 512Mi
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 10
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app.kubernetes.io/name
                  operator: In
                  values:
                  - my-app
              topologyKey: kubernetes.io/hostname
bash
# 部署应用
kubectl apply -f app-deployment.yaml

# 查看Deployment状态
kubectl get deployment my-app

# 查看Pod状态
kubectl get pods -l app.kubernetes.io/name=my-app

# 查看Pod分布
kubectl get pods -l app.kubernetes.io/name=my-app -o wide

4.2 服务暴露

yaml
# app-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  selector:
    app.kubernetes.io/name: my-app
    app.kubernetes.io/instance: my-app-production
  ports:
  - port: 80
    targetPort: 80
  type: NodePort
bash
# 创建Service
kubectl apply -f app-service.yaml

# 查看Service状态
kubectl get service my-app

# 获取Service的NodePort
NODE_PORT=$(kubectl get service my-app -o jsonpath='{.spec.ports[0].nodePort}')

# 访问应用
echo "应用访问地址: http://<node-ip>:$NODE_PORT"

4.3 应用更新和回滚

bash
# 更新应用版本
kubectl set image deployment my-app my-app=nginx:1.22

# 查看更新状态
kubectl rollout status deployment my-app

# 查看更新历史
kubectl rollout history deployment my-app

# 回滚到之前版本
kubectl rollout undo deployment my-app

# 查看回滚状态
kubectl rollout status deployment my-app

4.4 应用扩缩容

bash
# 手动扩缩容
kubectl scale deployment my-app --replicas=10

# 查看状态
kubectl get deployment my-app
kubectl get pods -l app.kubernetes.io/name=my-app

# 创建HPA
kubectl autoscale deployment my-app --min=5 --max=15 --cpu-percent=70

# 查看HPA状态
kubectl get hpa

# 查看Pod状态
kubectl get pods -l app.kubernetes.io/name=my-app

5. 故障排查

5.1 Pod故障排查

bash
# 查看Pod状态
kubectl get pods

# 查看Pod详情
kubectl describe pod my-pod

# 查看Pod日志
kubectl logs my-pod

# 查看Pod的前一个容器日志
kubectl logs my-pod --previous

# 进入Pod执行命令
kubectl exec -it my-pod -- /bin/bash

# 查看Pod的事件
kubectl get events --field-selector involvedObject.name=my-pod

5.2 Deployment故障排查

bash
# 查看Deployment状态
kubectl get deployment my-deployment

# 查看Deployment详情
kubectl describe deployment my-deployment

# 查看Deployment的Pod状态
kubectl get pods -l app=my-app

# 查看Deployment的滚动更新状态
kubectl rollout status deployment my-deployment

# 查看Deployment的更新历史
kubectl rollout history deployment my-deployment

# 回滚Deployment
kubectl rollout undo deployment my-deployment

5.3 常见故障及解决方案

故障症状原因解决方案
Pod 处于 Pending 状态Pod 一直处于 Pending 状态资源不足或调度失败检查节点资源,调整资源请求或添加节点
Pod 处于 CrashLoopBackOff 状态Pod 反复崩溃重启应用错误或配置问题查看Pod日志,修复应用错误
Pod 处于 ImagePullBackOff 状态无法拉取镜像镜像不存在或网络问题检查镜像名称和标签,检查网络连接
Pod 处于 ErrImagePull 状态拉取镜像失败镜像不存在或权限问题检查镜像名称和标签,检查镜像仓库权限
Pod 处于 Terminating 状态Pod 无法正常终止应用无法优雅退出强制删除Pod:kubectl delete pod my-pod --grace-period=0 --force
Deployment 滚动更新失败更新卡住或回滚健康检查失败或资源不足查看Pod日志,检查健康检查配置,调整更新策略

6. 课程总结

6.1 重点回顾

  • Pod管理:掌握Pod的创建、监控和故障排查
  • 健康检查:理解并配置存活探针和就绪探针
  • 资源管理:为容器设置合理的资源请求和限制
  • Pod调度:使用节点选择器、亲和性和反亲和性控制Pod调度
  • Deployment管理:掌握Deployment的创建、更新和回滚
  • 标签和选择器:使用标签和选择器组织和管理资源
  • 故障排查:学会排查Pod和Deployment的常见故障

6.2 实践建议

  1. 动手实践:在本地或云平台上部署Kubernetes集群,实践Pod和Deployment管理
  2. 实验场景:模拟各种故障场景,练习故障排查
  3. 最佳实践:遵循Kubernetes的最佳实践,建立标准化的部署流程
  4. 自动化:使用CI/CD工具自动化应用部署和管理
  5. 监控:配置Prometheus和Grafana监控Pod和Deployment的状态

6.3 进阶学习

  • StatefulSet:学习管理有状态应用
  • DaemonSet:学习在每个节点上运行Pod
  • Job和CronJob:学习管理批处理任务
  • 自定义控制器:学习开发自定义Kubernetes控制器
  • Operator模式:学习使用Operator模式管理复杂应用

通过本课程的学习,你已经掌握了Pod和Deployment的核心管理技能,可以在Kubernetes集群中高效地部署、管理和维护应用。

评论区

专业的Linux技术学习平台,从入门到精通的完整学习路径