前言:掌握Kubernetes核心资源

要有效地使用Kubernetes,必须完全理解三个核心资源:Pod、Deployment和Service。这三者是在Kubernetes中部署和运营应用程序最基本的构建块。在本第8篇中,我们将详细介绍每个资源的概念、YAML编写方法以及实际使用模式。

1. 深入理解Pod

Pod是Kubernetes中可部署的最小单元。它包含一个或多个容器,同一Pod内的容器共享网络和存储。

1.1 Pod的特点

  • 容器组:可以在一个Pod中放置多个容器
  • 共享网络:同一Pod内的容器通过localhost通信
  • 共享存储:可以通过卷共享数据
  • 临时性:Pod可能随时被删除和重新创建
  • 唯一IP:每个Pod在集群中有唯一的IP地址

1.2 Sidecar模式

Sidecar模式是将辅助容器与主容器一起部署的模式。用于日志收集、代理、配置管理等。

# sidecar-example.yaml
apiVersion: v1
kind: Pod
metadata:
  name: web-with-sidecar
spec:
  containers:
  # 主应用程序容器
  - name: web-app
    image: nginx:1.25
    ports:
    - containerPort: 80
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/nginx

  # Sidecar:日志收集
  - name: log-collector
    image: busybox
    command: ['sh', '-c', 'tail -F /var/log/nginx/access.log']
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/nginx

  volumes:
  - name: shared-logs
    emptyDir: {}

1.3 Init Container

Init Container是在主容器启动之前运行的初始化容器。用于等待数据库、创建配置文件、设置权限等。

# init-container-example.yaml
apiVersion: v1
kind: Pod
metadata:
  name: app-with-init
spec:
  initContainers:
  # 第一个Init Container:等待数据库
  - name: wait-for-db
    image: busybox
    command: ['sh', '-c', 'until nc -z mysql-service 3306; do echo waiting for db; sleep 2; done']

  # 第二个Init Container:准备配置文件
  - name: prepare-config
    image: busybox
    command: ['sh', '-c', 'cp /config-source/app.conf /config/app.conf']
    volumeMounts:
    - name: config-volume
      mountPath: /config
    - name: config-source
      mountPath: /config-source

  containers:
  - name: main-app
    image: my-app:latest
    volumeMounts:
    - name: config-volume
      mountPath: /app/config

  volumes:
  - name: config-volume
    emptyDir: {}
  - name: config-source
    configMap:
      name: app-config

1.4 Pod YAML编写

让我们看一个完整的Pod YAML示例。

# complete-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: web
    environment: production
  annotations:
    description: "生产环境Web服务器"
spec:
  # 重启策略
  restartPolicy: Always  # Always, OnFailure, Never

  # 节点选择
  nodeSelector:
    disktype: ssd

  # 容器定义
  containers:
  - name: web
    image: nginx:1.25

    # 端口设置
    ports:
    - name: http
      containerPort: 80
      protocol: TCP

    # 资源限制
    resources:
      requests:
        memory: "128Mi"
        cpu: "250m"
      limits:
        memory: "256Mi"
        cpu: "500m"

    # 环境变量
    env:
    - name: ENV_NAME
      value: "production"
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-secrets
          key: password

    # 健康检查
    livenessProbe:
      httpGet:
        path: /healthz
        port: 80
      initialDelaySeconds: 30
      periodSeconds: 10

    readinessProbe:
      httpGet:
        path: /ready
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 5

    # 卷挂载
    volumeMounts:
    - name: data-volume
      mountPath: /data

  volumes:
  - name: data-volume
    persistentVolumeClaim:
      claimName: my-pvc

2. 完全理解Deployment

Deployment管理Pod的声明式更新。通过ReplicaSet维护期望数量的Pod,并提供滚动更新和回滚功能。

2.1 Deployment与ReplicaSet的关系

Deployment创建和管理ReplicaSet。ReplicaSet维护指定数量的Pod副本。

  • Deployment:高级抽象,管理更新策略
  • ReplicaSet:维护Pod副本数量
  • Pod:实际运行应用程序

2.2 Deployment YAML编写

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
  labels:
    app: web
spec:
  # 副本数
  replicas: 3

  # 选择器(管理哪些Pod)
  selector:
    matchLabels:
      app: web

  # 更新策略
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # 可额外创建的Pod数
      maxUnavailable: 0  # 不可用Pod的最大数

  # Pod模板
  template:
    metadata:
      labels:
        app: web
        version: v1
    spec:
      containers:
      - name: web
        image: nginx:1.25
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "200m"
            memory: "256Mi"
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 5
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 3

2.3 滚动更新

滚动更新在部署新版本Pod的同时逐步替换旧Pod。

# 更新镜像(触发滚动更新)
kubectl set image deployment/web-deployment web=nginx:1.26

# 检查更新状态
kubectl rollout status deployment/web-deployment

# 检查更新历史
kubectl rollout history deployment/web-deployment

# 查看特定修订版详情
kubectl rollout history deployment/web-deployment --revision=2

2.4 回滚

出现问题时可以轻松回滚到之前的版本。

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

# 回滚到特定修订版
kubectl rollout undo deployment/web-deployment --to-revision=2

# 回滚后检查状态
kubectl rollout status deployment/web-deployment

3. 扩缩容

Kubernetes支持手动扩缩容和自动扩缩容(HPA)。

3.1 手动扩缩容

# 调整副本数
kubectl scale deployment/web-deployment --replicas=5

# 检查当前状态
kubectl get deployment web-deployment

# 通过YAML修改进行扩缩容
kubectl edit deployment web-deployment

3.2 HPA (Horizontal Pod Autoscaler)

HPA基于CPU、内存使用量或自定义指标自动调整Pod数量。

# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-deployment

  minReplicas: 2
  maxReplicas: 10

  metrics:
  # 基于CPU的扩缩容
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

  # 基于内存的扩缩容
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

  # 扩缩容行为详细设置
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300  # 缩容前等待时间
      policies:
      - type: Percent
        value: 10
        periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
      - type: Percent
        value: 100
        periodSeconds: 15
      - type: Pods
        value: 4
        periodSeconds: 15
      selectPolicy: Max
# 创建HPA(命令方式)
kubectl autoscale deployment web-deployment --min=2 --max=10 --cpu-percent=70

# 检查HPA状态
kubectl get hpa

# HPA详细信息
kubectl describe hpa web-hpa

4. Service类型

Service为Pod集合提供稳定的网络端点。Pod的IP可能会改变,但Service的IP是固定的。

4.1 ClusterIP(默认)

提供只能在集群内部访问的虚拟IP。

# clusterip-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: ClusterIP  # 默认值,可省略
  selector:
    app: web
  ports:
  - name: http
    protocol: TCP
    port: 80        # 服务端口
    targetPort: 80  # Pod端口

使用场景:内部微服务间通信、数据库连接

4.2 NodePort

通过每个节点的特定端口允许外部访问。

# nodeport-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-nodeport
spec:
  type: NodePort
  selector:
    app: web
  ports:
  - name: http
    protocol: TCP
    port: 80         # 服务端口
    targetPort: 80   # Pod端口
    nodePort: 30080  # 节点端口(30000-32767)

使用场景:开发/测试环境、无负载均衡器时需要外部访问

4.3 LoadBalancer

通过云提供商的负载均衡器获取外部IP。

# loadbalancer-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-loadbalancer
  annotations:
    # AWS示例
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 80
  - name: https
    protocol: TCP
    port: 443
    targetPort: 443

使用场景:生产环境的外部服务暴露

4.4 ExternalName

为外部服务提供DNS CNAME。

# externalname-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  type: ExternalName
  externalName: db.example.com

使用场景:外部数据库、外部API服务连接

5. 标签和选择器

标签和选择器是组织和连接Kubernetes资源的核心机制。

5.1 标签(Labels)

标签是附加到资源上的键值对。

# 标签示例
metadata:
  labels:
    app: web
    environment: production
    version: v1.0.0
    team: backend
    tier: frontend
# 通过标签查询资源
kubectl get pods -l app=web
kubectl get pods -l 'environment in (production, staging)'
kubectl get pods -l app=web,environment=production

# 添加/修改标签
kubectl label pods my-pod new-label=new-value

# 删除标签
kubectl label pods my-pod new-label-

# 显示所有标签
kubectl get pods --show-labels

5.2 选择器(Selectors)

选择器基于标签选择资源。

# 等式选择器(Equality-based)
selector:
  matchLabels:
    app: web
    environment: production

# 集合选择器(Set-based)
selector:
  matchLabels:
    app: web
  matchExpressions:
  - key: environment
    operator: In
    values:
    - production
    - staging
  - key: version
    operator: NotIn
    values:
    - v1.0.0
  - key: team
    operator: Exists

6. 实用命令汇总

6.1 Pod相关

# Pod查询
kubectl get pods
kubectl get pods -o wide
kubectl get pods -w  # 实时监控

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

# 查看Pod日志
kubectl logs my-pod
kubectl logs my-pod -c container-name  # 特定容器
kubectl logs my-pod -f  # 实时日志
kubectl logs my-pod --previous  # 之前容器的日志

# 进入Pod内部
kubectl exec -it my-pod -- /bin/bash
kubectl exec -it my-pod -c container-name -- /bin/sh

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

6.2 Deployment相关

# Deployment管理
kubectl create deployment nginx --image=nginx
kubectl get deployments
kubectl describe deployment my-deployment

# 更新和回滚
kubectl set image deployment/my-deployment container=image:tag
kubectl rollout status deployment/my-deployment
kubectl rollout history deployment/my-deployment
kubectl rollout undo deployment/my-deployment

# 扩缩容
kubectl scale deployment/my-deployment --replicas=5

# 暂停/恢复
kubectl rollout pause deployment/my-deployment
kubectl rollout resume deployment/my-deployment

6.3 Service相关

# Service管理
kubectl expose deployment my-deployment --port=80 --type=ClusterIP
kubectl get services
kubectl describe service my-service

# 查看服务端点
kubectl get endpoints my-service

# 端口转发(本地测试用)
kubectl port-forward service/my-service 8080:80

结论

在本第8篇中,我们深入探讨了Kubernetes的核心资源:Pod、Deployment和Service。Pod是容器组的基本单元,通过Sidecar模式和Init Container可以实现各种模式。Deployment提供Pod的声明式管理和滚动更新、回滚功能,还可以通过HPA实现自动扩缩容。Service为Pod提供稳定的网络访问,根据用途可以选择ClusterIP、NodePort、LoadBalancer等。

利用标签和选择器可以灵活地连接和管理这些资源。在下一篇中,我们将介绍ConfigMap、Secret、Volume等数据和配置管理。