概念解析

Pod是Kubernetes中最小的可部署單元,代表了集羣中運行的進程。Pod封裝了一個或多個容器、存儲資源、唯一的網絡IP以及管理容器運行方式的選項。

Pod的核心特點

  1. 共享網絡:Pod內的所有容器共享同一個網絡命名空間,擁有相同的IP地址和端口空間。
  2. 共享存儲:Pod可以指定一組共享存儲卷,Pod中的所有容器都可以訪問這些卷。
  3. 原子性:Pod是原子性的,要麼所有容器都運行,要麼都不運行。
  4. 短暫性:Pod是臨時的,當Pod被刪除或重建時,其IP地址會發生變化。

Pod的分類

  1. 單容器Pod:最常見的Pod類型,一個Pod中只運行一個容器。
  2. 多容器Pod:一個Pod中運行多個緊密耦合的容器,通常是一個主容器和一個或多個輔助容器(如sidecar、init容器)。

核心特性

  1. 生命週期管理:Pod有明確的生命週期狀態,包括Pending、Running、Succeeded、Failed、Unknown。
  2. 重啓策略:支持Always、OnFailure、Never三種重啓策略。
  3. 健康檢查:支持Liveness Probe和Readiness Probe兩種健康檢查機制。
  4. 資源限制:可以為Pod中的容器設置CPU和內存的請求(requests)和限制(limits)。
  5. 環境變量:支持多種方式注入環境變量,包括直接定義、ConfigMap和Secret。
  6. Init容器:在主容器啓動之前運行的初始化容器,用於執行前置任務。

實踐教程

創建簡單的Pod

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

創建Pod:

kubectl apply -f nginx-pod.yaml

創建多容器Pod

apiVersion: v1
kind: Pod
metadata:
  name: multi-container-pod
spec:
  containers:
  - name: web
    image: nginx
    ports:
    - containerPort: 80
  - name: sidecar
    image: busybox
    command: ['sh', '-c']
    args:
    - while true; do
        echo "$(date) INFO" >> /var/log/app.log;
        sleep 10;
      done
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log
  volumes:
  - name: shared-logs
    emptyDir: {}

使用Init容器

apiVersion: v1
kind: Pod
metadata:
  name: init-demo
spec:
  containers:
  - name: main-container
    image: busybox
    command: ['sh', '-c']
    args:
    - echo "Main container running";
      sleep 3600
  initContainers:
  - name: init-myservice
    image: busybox
    command: ['sh', '-c']
    args:
    - echo "Initializing service...";
      sleep 10

真實案例

案例:日誌收集系統

在一個微服務架構中,每個服務都需要將日誌發送到中央日誌收集系統。我們可以使用多容器Pod來實現這一需求:

  1. 主容器:運行業務應用
  2. Sidecar容器:運行日誌收集代理,監控主容器的日誌文件併發送到中央系統
apiVersion: v1
kind: Pod
metadata:
  name: app-with-log-collector
  labels:
    app: web-app
spec:
  containers:
  - name: app
    image: my-web-app:latest
    volumeMounts:
    - name: app-logs
      mountPath: /var/log/app
  - name: log-collector
    image: fluentd:latest
    volumeMounts:
    - name: app-logs
      mountPath: /var/log/app
  volumes:
  - name: app-logs
    emptyDir: {}

這種方式的優勢:

  • 日誌收集與業務應用緊密耦合,確保日誌能夠及時收集
  • 每個Pod都有獨立的日誌收集器,避免單點故障
  • 簡化了日誌收集系統的配置

配置詳解

Pod生命週期狀態

apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: nginx
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
      preStop:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the preStop handler > /usr/share/message"]

資源限制和請求

apiVersion: v1
kind: Pod
metadata:
  name: resource-limit-pod
spec:
  containers:
  - name: app
    image: nginx
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

健康檢查配置

apiVersion: v1
kind: Pod
metadata:
  name: health-check-pod
spec:
  containers:
  - name: liveness
    image: nginx
    livenessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 30
      periodSeconds: 10
    readinessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 5

故障排除

常見問題及解決方案

  1. Pod處於Pending狀態

    # 查看Pod事件
    kubectl describe pod <pod-name>
    
    # 檢查資源配額
    kubectl get resourcequota
    
  2. Pod不斷重啓

    # 查看Pod日誌
    kubectl logs <pod-name> --previous
    
    # 檢查健康檢查配置
    kubectl describe pod <pod-name>
    
  3. 容器無法啓動

    # 檢查鏡像是否存在
    kubectl describe pod <pod-name>
    
    # 檢查節點是否有足夠的資源
    kubectl describe node <node-name>
    
  4. 網絡連接問題

    # 進入Pod檢查網絡
    kubectl exec -it <pod-name> -- /bin/bash
    
    # 檢查DNS配置
    kubectl exec -it <pod-name> -- cat /etc/resolv.conf
    

最佳實踐

  1. 合理設計Pod大小

    • 單一職責原則:一個Pod應該只負責一個功能
    • 緊密耦合的服務可以放在同一個Pod中
  2. 資源管理

    • 為所有容器設置合理的requests和limits
    • 使用LimitRange對象為命名空間設置默認資源限制
  3. 健康檢查

    • 為所有生產環境的Pod配置liveness和readiness探針
    • 設置合適的initialDelaySeconds和periodSeconds
  4. 標籤和註解

    • 使用有意義的標籤便於管理和選擇
    • 使用註解記錄Pod的元數據信息
  5. 安全性

    • 避免使用特權容器
    • 使用SecurityContext限制容器權限
    • 定期更新基礎鏡像

安全考慮

SecurityContext配置

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
  containers:
  - name: sec-ctx-demo
    image: busybox
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true

網絡策略

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379

命令速查

命令 描述
kubectl get pods 查看Pod列表
kubectl describe pod <name> 查看Pod詳細信息
kubectl logs <pod-name> 查看Pod日誌
kubectl exec -it <pod-name> -- <command> 在Pod中執行命令
kubectl delete pod <name> 刪除Pod
kubectl apply -f <pod.yaml> 創建或更新Pod
kubectl port-forward <pod-name> <local-port>:<pod-port> 端口轉發
kubectl cp <pod-name>:<path> <local-path> 從Pod複製文件
kubectl wait --for=condition=ready pod/<name> 等待Pod就緒
kubectl top pod <name> 查看Pod資源使用情況

總結

Pod是Kubernetes中最基本的部署單元,理解和掌握Pod的管理對於使用K8s至關重要。通過本文檔的學習,你應該能夠:

  • 理解Pod的概念和特點
  • 創建和管理單容器和多容器Pod
  • 配置Pod的生命週期鈎子、資源限制和健康檢查
  • 排查常見的Pod問題
  • 遵循Pod管理的最佳實踐和安全考慮

在下一文檔中,我們將深入學習Deployment控制器,它是管理Pod副本的高級抽象。