Pod 与 Deployment

核心知识点

1. Pod 详解

1.1 Pod 的概念

Pod 是 Kubernetes 中最小的可部署单元,它包含一个或多个容器,这些容器共享存储、网络和运行配置。

┌─────────────────────────────────────────────────────┐
│                    Pod                               │
├─────────────────────────────────────────────────────┤
│                                                     │
│  ┌──────────────┐  ┌──────────────┐               │
│  │  容器 A      │  │  容器 B      │               │
│  │  (主容器)    │  │  (辅助容器)  │               │
│  │              │  │              │               │
│  │  应用程序     │  │  日志收集     │               │
│  └──────────────┘  └──────────────┘               │
│         │                   │                      │
│         └─────────┬─────────┘                      │
│                   │                                │
│         ┌─────────▼─────────┐                      │
│         │   共享网络命名空间  │                      │
│         │   共享存储卷       │                      │
│         │   共享 IPC         │                      │
│         └───────────────────┘                      │
│                                                     │
└─────────────────────────────────────────────────────┘

1.2 Pod 的生命周期

┌─────────────────────────────────────────────────────┐
│              Pod 生命周期状态机                     │
├─────────────────────────────────────────────────────┤
│                                                     │
│   ┌─────────┐                                      │
│   │ Pending │                                      │
│   └────┬────┘                                      │
│        │                                          │
│        ▼                                          │
│   ┌─────────┐      ┌─────────┐                   │
│   │Running  │◄────►│Unknown  │                   │
│   └────┬────┘      └─────────┘                   │
│        │                                          │
│        ▼                                          │
│   ┌─────────┐      ┌─────────┐                   │
│   │Succeeded│      │Failed   │                   │
│   └─────────┘      └─────────┘                   │
│                                                     │
└─────────────────────────────────────────────────────┘

1.3 Pod 配置示例

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: myapp
    environment: production
spec:
  containers:
  - name: main-container
    image: nginx:1.21
    ports:
    - containerPort: 80
    env:
    - name: ENV_VAR
      value: "production"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
  - name: sidecar-container
    image: fluentd:v1.12
    volumeMounts:
    - name: log-volume
      mountPath: /var/log
  volumes:
  - name: config-volume
    configMap:
      name: app-config
  - name: log-volume
    emptyDir: {}
  restartPolicy: Always

2. Deployment 详解

2.1 Deployment 的概念

Deployment 是 Kubernetes 中用于管理 Pod 副本和更新的控制器,它提供声明式更新、滚动升级、回滚等功能。

┌─────────────────────────────────────────────────────┐
│              Deployment 架构                        │
├─────────────────────────────────────────────────────┤
│                                                     │
│   ┌──────────────┐                                 │
│   │ Deployment   │                                 │
│   │              │                                 │
│   │ - 副本数: 3  │                                 │
│   │ - 镜像: v1.0 │                                 │
│   └──────┬───────┘                                 │
│          │                                         │
│          ▼                                         │
│   ┌──────────────┐                                 │
│   │ ReplicaSet   │                                 │
│   │              │                                 │
│   │ - 确保副本数  │                                 │
│   │ - 管理 Pod    │                                 │
│   └──────┬───────┘                                 │
│          │                                         │
│          ▼                                         │
│   ┌─────────────────────────────────┐               │
│   │         Pods                    │               │
│   │  ┌─────┐  ┌─────┐  ┌─────┐    │               │
│   │  │Pod 1│  │Pod 2│  │Pod 3│    │               │
│   │  └─────┘  └─────┘  └─────┘    │               │
│   └─────────────────────────────────┘               │
│                                                     │
└─────────────────────────────────────────────────────┘

2.2 Deployment 更新策略

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v2.0
        ports:
        - containerPort: 8080

2.3 Deployment 配置选项

apiVersion: apps/v1
kind: Deployment
metadata:
  name: advanced-deployment
  annotations:
    kubernetes.io/change-cause: "Update to version 2.0"
spec:
  replicas: 5
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
  minReadySeconds: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
  selector:
    matchLabels:
      app: advanced-app
      tier: backend
  template:
    metadata:
      labels:
        app: advanced-app
        tier: backend
        version: v2.0
    spec:
      containers:
      - name: app
        image: advanced-app:v2.0
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: url
        - name: CONFIG_FILE
          value: "/etc/config/app.yaml"
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 3
          successThreshold: 1
          failureThreshold: 3
        volumeMounts:
        - name: config
          mountPath: /etc/config
          readOnly: true
        - name: data
          mountPath: /data
      volumes:
      - name: config
        configMap:
          name: app-config
      - name: data
        persistentVolumeClaim:
          claimName: data-pvc
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - advanced-app
              topologyKey: kubernetes.io/hostname

3. Pod 管理命令

3.1 创建和查看 Pod

# 创建 Pod
kubectl apply -f pod.yaml

# 查看 Pod 列表
kubectl get pods

# 查看 Pod 详细信息
kubectl describe pod my-pod

# 查看 Pod YAML 配置
kubectl get pod my-pod -o yaml

# 查看 Pod 日志
kubectl logs my-pod

# 实时查看 Pod 日志
kubectl logs -f my-pod

# 查看多个容器的 Pod 日志
kubectl logs my-pod -c sidecar-container

# 进入 Pod
kubectl exec -it my-pod -- /bin/bash

# 在 Pod 中执行命令
kubectl exec my-pod -- ls -la

# 删除 Pod
kubectl delete pod my-pod

# 强制删除 Pod
kubectl delete pod my-pod --force --grace-period=0

3.2 Pod 状态诊断

# 查看 Pod 事件
kubectl describe pod my-pod

# 查看 Pod 所在节点
kubectl get pods -o wide

# 查看 Pod 资源使用情况
kubectl top pod my-pod

# 查看 Pod 标签
kubectl get pods --show-labels

# 根据标签选择 Pod
kubectl get pods -l app=myapp

# 查看 Pod 的 IP 地址
kubectl get pod my-pod -o jsonpath='{.status.podIP}'

4. Deployment 管理命令

4.1 创建和更新 Deployment

# 创建 Deployment
kubectl apply -f deployment.yaml

# 查看 Deployment 列表
kubectl get deployments

# 查看 Deployment 详细信息
kubectl describe deployment my-deployment

# 查看 Deployment 状态
kubectl rollout status deployment/my-deployment

# 查看 Deployment 历史
kubectl rollout history deployment/my-deployment

# 查看特定版本的详细信息
kubectl rollout history deployment/my-deployment --revision=2

# 更新 Deployment 镜像
kubectl set image deployment/my-deployment myapp=myapp:v2.0

# 回滚到上一版本
kubectl rollout undo deployment/my-deployment

# 回滚到指定版本
kubectl rollout undo deployment/my-deployment --to-revision=2

# 扩展副本数
kubectl scale deployment/my-deployment --replicas=5

# 自动扩展 Deployment
kubectl autoscale deployment my-deployment --min=3 --max=10 --cpu-percent=80

# 暂停 Deployment 更新
kubectl rollout pause deployment/my-deployment

# 恢复 Deployment 更新
kubectl rollout resume deployment/my-deployment

# 删除 Deployment
kubectl delete deployment my-deployment

4.2 Deployment 监控

# 查看 Deployment 副本状态
kubectl get deployments

# 查看 Deployment 关联的 ReplicaSet
kubectl get replicasets

# 查看 Deployment 关联的 Pod
kubectl get pods -l app=myapp

# 查看 Deployment 更新进度
kubectl rollout status deployment/my-deployment

# 查看 Deployment 资源使用
kubectl top deployment my-deployment

5. 高级配置

5.1 多容器 Pod

apiVersion: v1
kind: Pod
metadata:
  name: multi-container-pod
spec:
  containers:
  - name: web-app
    image: nginx:1.21
    ports:
    - containerPort: 80
    volumeMounts:
    - name: shared-data
      mountPath: /usr/share/nginx/html
  - name: log-collector
    image: fluentd:v1.12
    volumeMounts:
    - name: shared-data
      mountPath: /var/log/nginx
    - name: log-config
      mountPath: /fluentd/etc
      readOnly: true
  - name: monitoring
    image: prom/prometheus:latest
    volumeMounts:
    - name: shared-data
      mountPath: /data
  volumes:
  - name: shared-data
    emptyDir: {}
  - name: log-config
    configMap:
      name: fluentd-config

5.2 Init 容器

apiVersion: v1
kind: Pod
metadata:
  name: init-container-pod
spec:
  initContainers:
  - name: init-myservice
    image: busybox:1.34
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
  - name: init-mydb
    image: busybox:1.34
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
  containers:
  - name: myapp-container
    image: myapp:v1.0
    ports:
    - containerPort: 8080

5.3 资源限制和请求

apiVersion: v1
kind: Pod
metadata:
  name: resource-limited-pod
spec:
  containers:
  - name: app
    image: myapp:v1.0
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
        ephemeral-storage: "1Gi"
      limits:
        memory: "128Mi"
        cpu: "500m"
        ephemeral-storage: "2Gi"

实用案例分析

案例 1:创建 Web 应用 Deployment

场景描述

部署一个高可用的 Nginx Web 应用,包含健康检查和资源限制。

操作步骤

# 1. 创建 Deployment 配置文件
cat > web-deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
  labels:
    app: web
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
EOF

# 2. 创建 Service 配置文件
cat > web-service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: LoadBalancer
EOF

# 3. 部署应用
kubectl apply -f web-deployment.yaml
kubectl apply -f web-service.yaml

# 4. 查看部署状态
kubectl get deployments
kubectl get pods

# 5. 查看服务
kubectl get services

# 6. 查看详细信息
kubectl describe deployment web-deployment

# 7. 扩展副本数
kubectl scale deployment web-deployment --replicas=5

# 8. 查看扩展后的状态
kubectl get pods

# 9. 更新镜像版本
kubectl set image deployment/web-deployment nginx=nginx:1.22

# 10. 查看更新状态
kubectl rollout status deployment/web-deployment

# 11. 查看更新历史
kubectl rollout history deployment/web-deployment

# 12. 回滚到上一版本
kubectl rollout undo deployment/web-deployment

# 13. 清理资源
kubectl delete -f web-deployment.yaml
kubectl delete -f web-service.yaml

案例 2:多容器 Pod 应用

场景描述

创建一个包含主应用、日志收集和监控的多容器 Pod。

操作步骤

# 1. 创建 ConfigMap
cat > log-config.yaml << 'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
  name: log-config
data:
  fluent.conf: |
    <source>
      @type tail
      path /var/log/nginx/access.log
      pos_file /var/log/fluentd-access.log.pos
      tag nginx.access
      format nginx
    </source>
    <match **>
      @type stdout
    </match>
EOF

kubectl apply -f log-config.yaml

# 2. 创建多容器 Pod
cat > multi-container-pod.yaml << 'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: multi-container-app
  labels:
    app: multi-app
spec:
  containers:
  - name: web
    image: nginx:1.21
    ports:
    - containerPort: 80
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/nginx
  - name: log-collector
    image: fluentd:v1.12
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/nginx
      readOnly: true
    - name: log-config
      mountPath: /fluentd/etc
      readOnly: true
  - name: monitor
    image: prom/node-exporter:latest
    ports:
    - containerPort: 9100
      name: metrics
  volumes:
  - name: shared-logs
    emptyDir: {}
  - name: log-config
    configMap:
      name: log-config
EOF

kubectl apply -f multi-container-pod.yaml

# 3. 查看 Pod 状态
kubectl get pods multi-container-app

# 4. 查看各容器日志
kubectl logs multi-container-app -c web
kubectl logs multi-container-app -c log-collector
kubectl logs multi-container-app -c monitor

# 5. 进入主容器
kubectl exec -it multi-container-app -c web -- /bin/bash

# 6. 查看共享日志
kubectl exec multi-container-app -c log-collector -- ls -la /var/log/nginx

# 7. 清理资源
kubectl delete pod multi-container-app
kubectl delete configmap log-config

案例 3:滚动更新和回滚

场景描述

演示 Deployment 的滚动更新和回滚功能。

操作步骤

# 1. 创建初始 Deployment
cat > app-deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
        version: v1.0
    spec:
      containers:
      - name: myapp
        image: myapp:v1.0
        ports:
        - containerPort: 8080
        env:
        - name: VERSION
          value: "1.0"
EOF

kubectl apply -f app-deployment.yaml

# 2. 查看初始状态
kubectl get deployments
kubectl get pods

# 3. 记录更新原因
kubectl annotate deployment/app-deployment kubernetes.io/change-cause="Initial deployment v1.0"

# 4. 更新到 v2.0
kubectl set image deployment/app-deployment myapp=myapp:v2.0

# 5. 查看更新进度
kubectl rollout status deployment/app-deployment

# 6. 查看更新过程中的 Pod
kubectl get pods -w

# 7. 记录更新原因
kubectl annotate deployment/app-deployment kubernetes.io/change-cause="Update to v2.0"

# 8. 更新到 v3.0
kubectl set image deployment/app-deployment myapp=myapp:v3.0

# 9. 查看历史版本
kubectl rollout history deployment/app-deployment

# 10. 查看特定版本详情
kubectl rollout history deployment/app-deployment --revision=2

# 11. 回滚到 v2.0
kubectl rollout undo deployment/app-deployment --to-revision=2

# 12. 验证回滚
kubectl rollout status deployment/app-deployment
kubectl get pods

# 13. 清理资源
kubectl delete deployment app-deployment

最佳实践

  1. 使用 Deployment 而非直接管理 Pod:Deployment 提供声明式更新和自愈能力。

  2. 配置健康检查:确保应用正常运行。

livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 10
readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5
  1. 设置资源限制:防止单个 Pod 耗尽节点资源。
resources:
  requests:
    memory: "64Mi"
    cpu: "250m"
  limits:
    memory: "128Mi"
    cpu: "500m"
  1. 使用标签和选择器:便于管理和查询资源。
metadata:
  labels:
    app: myapp
    environment: production
    version: v1.0
  1. 配置滚动更新策略:确保零停机部署。
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0
  1. 使用 ConfigMap 和 Secret:分离配置和敏感信息。

  2. 记录变更原因:便于追踪和回滚。

kubectl annotate deployment/app-deployment kubernetes.io/change-cause="Update to v2.0"
  1. 监控 Pod 状态:及时发现和解决问题。
kubectl get pods -w
kubectl describe pod my-pod
kubectl logs my-pod -f

总结

本教程详细介绍了 Kubernetes 中 Pod 和 Deployment 的概念、配置和管理。通过实际案例,我们学习了如何创建和管理容器化应用的部署。掌握这些知识后,可以继续学习 Service、Ingress 等 Kubernetes 网络功能,构建完整的容器化应用架构。

« 上一篇 Pod 与 Deployment 下一篇 » Service 与 Ingress