Skip to content

Kubernetes 详解:容器编排

  Kubernetes(K8s)是容器编排的事实标准,由 Google 基于 Borg 系统经验开源。它负责容器的自动化部署、扩缩容、负载均衡、自愈、滚动更新,是微服务运行的"操作系统"。

一、为什么需要 K8s?

1.1 没有 K8s 的运维困境

场景:30 个微服务,每个 3 个实例 = 90 个容器

运维的一天:
  8:00  服务器 A 宕机,手动把 15 个容器迁移到其他机器
  9:30  流量上涨,手动启动 10 个新实例
  10:00  新版本发布,手动停旧起新,一台一台操作
  11:00  某服务 CPU 100%,手动重启
  14:00  又一台服务器宕机...

  问题:
  ❌ 全是手工操作,运维 996
  ❌ 故障恢复靠"人盯着"
  ❌ 发布靠"一个一个来"
  ❌ 资源利用率低,每台机器跑什么全靠 Excel

1.2 有了 K8s 之后

K8s 自动处理的一切:

  ✅ 容器调度:自动选择最优节点运行容器
  ✅ 自愈:容器挂了自动重启,节点宕机自动迁移
  ✅ 弹性伸缩:CPU 高了自动加实例,低了自动减
  ✅ 滚动更新:新版本逐步替换旧版本,不中断服务
  ✅ 服务发现:容器 IP 变来变去,Service 提供固定访问入口
  ✅ 负载均衡:自动分发请求到多个实例
  ✅ 配置管理:ConfigMap/Secret 管理配置和密码
  ✅ 存储管理:自动挂载持久化存储

运维只需要:kubectl apply -f deployment.yaml,剩下的 K8s 全包了

二、核心概念

2.1 架构全景

┌──────────────────────────────────────────────────────────────────┐
│                     K8s 集群架构                                   │
│                                                                  │
│  ┌────────────────────────────────────────────────────────────┐  │
│  │                    Control Plane(控制平面)                  │  │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐  │  │
│  │  │API Server│  │Scheduler │  │Controller│  │  etcd    │  │  │
│  │  │ 统一入口  │  │ 调度器    │  │ Manager  │  │ 状态存储  │  │  │
│  │  └──────────┘  └──────────┘  └──────────┘  └──────────┘  │  │
│  └────────────────────────────────────────────────────────────┘  │
│                              │                                    │
│              ┌───────────────┼───────────────┐                    │
│              ▼               ▼               ▼                    │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐            │
│  │  Worker 1    │  │  Worker 2    │  │  Worker 3    │            │
│  │              │  │              │  │              │            │
│  │ ┌──┐ ┌──┐   │  │ ┌──┐ ┌──┐   │  │ ┌──┐ ┌──┐   │            │
│  │ │Po│ │Po│   │  │ │Po│ │Po│   │  │ │Po│ │Po│   │            │
│  │ │d │ │d │   │  │ │d │ │d │   │  │ │d │ │d │   │            │
│  │ └──┘ └──┘   │  │ └──┘ └──┘   │  │ └──┘ └──┘   │            │
│  │ kubelet     │  │ kubelet     │  │ kubelet     │            │
│  │ kube-proxy  │  │ kube-proxy  │  │ kube-proxy  │            │
│  └──────────────┘  └──────────────┘  └──────────────┘            │
│                                                                  │
│  控制平面负责:调度、管理、存储状态                                 │
│  Worker 负责:运行容器                                             │
└──────────────────────────────────────────────────────────────────┘

2.2 核心对象层级

┌──────────────────────────────────────────────────────────────┐
│  从大到小:Cluster → Node → Pod → Container                   │
│                                                               │
│  Cluster(集群)                                               │
│    └── Node(节点,物理机/虚拟机)                               │
│          └── Pod(最小调度单元,1 个或多个容器)                  │
│                └── Container(容器,Docker 容器)                │
│                                                               │
│  类比:                                                        │
│  集群 = 整栋楼                                                │
│  节点 = 每层楼                                                │
│  Pod  = 每个房间(共享网络和存储)                               │
│  容器 = 房间里的人                                              │
└──────────────────────────────────────────────────────────────┘

2.3 十大核心对象速览

对象缩写一句话类比
Podpo最小调度单元,1 个或多个容器豆荚(容器在豆荚里)
Deploymentdeploy管理 Pod 副本、滚动更新、回滚工头,管一批 Pod 的生死
Servicesvc给 Pod 提供固定访问入口(IP + DNS)前台,不管 Pod 怎么换,入口不变
ConfigMapcm非敏感配置(环境变量/配置文件)配置字典
Secret-敏感配置(密码/Token/TLS 证书)加密配置字典
Ingressing七层负载均衡,HTTP/HTTPS 路由大堂门禁,按 URL 分流
Namespacens逻辑隔离(dev/test/prod)不同楼层,互不干扰
StatefulSetsts有状态应用(数据库/消息队列)带编号的 Pod,固定身份
DaemonSetds每个节点跑一个 Pod(日志/监控)每层楼一个保安
PersistentVolumepv持久化存储(不会随 Pod 销毁)保险柜

三、核心对象详解

3.1 Pod — 最小调度单元

yaml
apiVersion: v1
kind: Pod
metadata:
  name: order-service
  labels:
    app: order-service
spec:
  containers:
    - name: order-service
      image: registry.example.com/order-service:1.0
      ports:
        - containerPort: 8080
      env:
        - name: SPRING_PROFILES_ACTIVE
          value: "prod"
      resources:
        requests:    # 最低保证资源
          memory: "256Mi"
          cpu: "250m"
        limits:      # 最高限制资源
          memory: "512Mi"
          cpu: "500m"
      livenessProbe:  # 存活探针:容器挂了就重启
        httpGet:
          path: /actuator/health/liveness
          port: 8080
        initialDelaySeconds: 30
        periodSeconds: 10
      readinessProbe:  # 就绪探针:准备好了才接流量
        httpGet:
          path: /actuator/health/readiness
          port: 8080
        initialDelaySeconds: 20
        periodSeconds: 5

探针类型:

探针作用失败后果
livenessProbe容器是否活着重启容器
readinessProbe容器是否准备好接流量从 Service 摘除,不重启
startupProbe启动是否完成在成功前禁用 liveness 和 readiness

3.2 Deployment — 管理 Pod 副本

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  replicas: 3                    # 3 个副本
  selector:
    matchLabels:
      app: order-service
  strategy:
    type: RollingUpdate          # 滚动更新
    rollingUpdate:
      maxSurge: 1                # 更新时最多多 1 个 Pod
      maxUnavailable: 0          # 更新时最少可用 3 个 Pod
  template:                      # Pod 模板
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service
          image: registry.example.com/order-service:1.0
          ports:
            - containerPort: 8080

滚动更新过程:

更新前:3 个 Pod 都运行 v1.0

  ┌──┐  ┌──┐  ┌──┐
  │v1│  │v1│  │v1│
  └──┘  └──┘  └──┘

更新开始:kubectl set image → v2.0

  步骤 1:     步骤 2:     步骤 3:     步骤 4:
  ┌──┐┌──┐    ┌──┐┌──┐    ┌──┐┌──┐    ┌──┐┌──┐┌──┐
  │v2││v1│    │v2││v2│    │v2││v2│    │v2││v2││v2│
  └──┘└──┘    └──┘└──┘    └──┘└──┘    └──┘└──┘└──┘
  ┌──┐        ┌──┐
  │v1│        │v1│ (已删除)
  └──┘        └──┘

  整个过程服务不中断,用户无感知

3.3 Service — 固定访问入口

yaml
apiVersion: v1
kind: Service
metadata:
  name: order-service
spec:
  type: ClusterIP        # 集群内部访问
  selector:
    app: order-service   # 通过标签选择 Pod
  ports:
    - port: 8080         # Service 端口
      targetPort: 8080   # Pod 端口
      protocol: TCP

Service 类型:

类型访问范围场景
ClusterIP集群内部微服务间调用
NodePort集群外部(NodeIP:Port)开发测试
LoadBalancer云负载均衡器生产环境
ExternalNameDNS 别名外部服务映射

3.4 Ingress — HTTP 路由

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
spec:
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /order
            pathType: Prefix
            backend:
              service:
                name: order-service
                port:
                  number: 8080
          - path: /user
            pathType: Prefix
            backend:
              service:
                name: user-service
                port:
                  number: 8080

3.5 ConfigMap + Secret

yaml
# ConfigMap(非敏感配置)
apiVersion: v1
kind: ConfigMap
metadata:
  name: order-service-config
data:
  application.yml: |
    spring:
      datasource:
        url: jdbc:mysql://mysql:3306/order_db
      redis:
        host: redis

---
# Secret(敏感配置,Base64 编码)
apiVersion: v1
kind: Secret
metadata:
  name: order-service-secret
type: Opaque
data:
  db-password: cm9vdDEyMw==     # echo -n 'root123' | base64
  jwt-secret: bXktc2VjcmV0LWtleQ==

在 Pod 中使用:

yaml
spec:
  containers:
    - name: order-service
      image: order-service:1.0
      env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: order-service-secret
              key: db-password
      volumeMounts:
        - name: config
          mountPath: /app/config
  volumes:
    - name: config
      configMap:
        name: order-service-config

四、弹性伸缩

4.1 HPA(水平 Pod 自动伸缩)

yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: order-service-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: order-service
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80

HPA 工作流程:

┌──────────────────────────────────────────────────────────────┐
│  监控 → 计算 → 决策 → 扩缩容                                  │
│                                                               │
│  1. Metrics Server 采集每个 Pod 的 CPU/内存                   │
│  2. HPA 每 15 秒计算平均使用率                                  │
│  3. 目标副本数 = ceil(当前副本数 × 当前使用率 / 目标使用率)      │
│  4. 操作 Deployment 的 replicas 字段                           │
│                                                               │
│  示例:                                                       │
│  当前 3 个副本,CPU 平均 85%,目标 70%                          │
│  目标副本数 = ceil(3 × 85/70) = ceil(3.64) = 4              │
│  → 扩容到 4 个副本                                            │
│                                                               │
│  冷却时间:默认扩容后 3 分钟内不缩容,缩容后 5 分钟内不扩容     │
│  防止抖动:频繁扩缩容比短期高负载损害更大                        │
└──────────────────────────────────────────────────────────────┘

4.2 VPA(垂直 Pod 自动伸缩)

yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: order-service-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: order-service
  updatePolicy:
    updateMode: "Auto"  # 自动调整 Pod 的 CPU/内存限额

五、常用命令

5.1 资源管理

bash
# 查看资源
kubectl get pods                          # 查看 Pod
kubectl get pods -o wide                  # 查看 Pod 详情(含 IP/节点)
kubectl get deployments                   # 查看 Deployment
kubectl get services                      # 查看 Service
kubectl get all                           # 查看所有资源

# 查看详情
kubectl describe pod <pod-name>           # Pod 详细信息
kubectl logs -f <pod-name>                # 实时日志
kubectl logs <pod-name> --tail=100         # 最后 100 行日志

# 进入容器
kubectl exec -it <pod-name> -- /bin/bash

5.2 更新与回滚

bash
# 更新镜像
kubectl set image deployment/order-service order-service=registry/order-service:v2.0

# 查看更新状态
kubectl rollout status deployment/order-service

# 查看历史版本
kubectl rollout history deployment/order-service

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

# 回滚到指定版本
kubectl rollout undo deployment/order-service --to-revision=3

5.3 扩缩容

bash
# 手动扩容
kubectl scale deployment/order-service --replicas=5

# 查看 HPA 状态
kubectl get hpa

# 查看 HPA 详情
kubectl describe hpa order-service-hpa

5.4 调试

bash
# 查看 Pod 事件
kubectl describe pod <pod-name> | grep Events -A 20

# 查看最近事件
kubectl get events --sort-by=.metadata.creationTimestamp

# 临时运行调试 Pod
kubectl run debug --rm -it --image=busybox -- sh

# 端口转发(本地调试)
kubectl port-forward pod/<pod-name> 8080:8080

六、微服务部署实战

6.1 完整部署清单

yaml
# order-service-deployment.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: production
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: order-service-config
  namespace: production
data:
  application.yml: |
    spring:
      datasource:
        url: jdbc:mysql://mysql:3306/order_db
      redis:
        host: redis
---
apiVersion: v1
kind: Secret
metadata:
  name: order-service-secret
  namespace: production
type: Opaque
data:
  db-password: cm9vdDEyMw==
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service
          image: registry.example.com/order-service:1.0
          ports:
            - containerPort: 8080
          env:
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: order-service-secret
                  key: db-password
          resources:
            requests:
              memory: "256Mi"
              cpu: "250m"
            limits:
              memory: "512Mi"
              cpu: "500m"
          livenessProbe:
            httpGet:
              path: /actuator/health/liveness
              port: 8080
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /actuator/health/readiness
              port: 8080
            initialDelaySeconds: 20
            periodSeconds: 5
          volumeMounts:
            - name: config
              mountPath: /app/config
      volumes:
        - name: config
          configMap:
            name: order-service-config
---
apiVersion: v1
kind: Service
metadata:
  name: order-service
  namespace: production
spec:
  selector:
    app: order-service
  ports:
    - port: 8080
      targetPort: 8080
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: order-service-hpa
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: order-service
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70

6.2 一键部署

bash
# 应用所有配置
kubectl apply -f order-service-deployment.yaml

# 查看部署状态
kubectl get all -n production

# 查看 Pod 日志
kubectl logs -f -l app=order-service -n production --tail=50

七、面试要点

Q1:Pod 是什么?为什么 Pod 是 K8s 最小调度单元?

  Pod 是一组共享网络和存储的容器集合。K8s 不直接调度容器,而是调度 Pod,因为同一 Pod 内的容器需要紧密协作(如 sidecar 模式),共享 localhost 网络和存储卷。

Q2:Deployment 和 StatefulSet 的区别?

维度DeploymentStatefulSet
Pod 标识随机名称(order-xxx-yyy)固定序号(order-0, order-1)
网络标识无固定 DNS固定 DNS(order-0.svc.ns)
存储共享 PV每个 Pod 独立 PVC
启停顺序并行按序号顺序(0→1→2)
适用无状态(Web、API)有状态(MySQL、Kafka)

Q3:Service 如何实现负载均衡?

  Service 通过 selector 标签匹配 Pod,kube-proxy 在每台节点上维护 iptables/IPVS 规则。请求到达 Service IP 时,kube-proxy 按随机或轮询分发到后端 Pod。ClusterIP 是虚拟 IP,只在集群内可达。

Q4:滚动更新和蓝绿发布的区别?

维度滚动更新蓝绿发布
方式逐个替换 Pod新老版本各一套完整环境
资源只需少量额外资源需要双倍资源
回滚逐步回滚瞬间切换流量
验证渐进式验证完整验证后再切换

Q5:livenessProbe 和 readinessProbe 的区别?

  livenessProbe 检查容器是否活着,失败则重启容器;readinessProbe 检查容器是否准备好接流量,失败则从 Service 摘除,不重启。典型场景:应用启动中,readiness 未就绪,但 liveness 正常。

Q6:HPA 如何决定扩缩容?

  HPA 每 15 秒通过 Metrics Server 采集指标,计算 目标副本数 = ceil(当前副本数 × 当前值 / 目标值)。扩容冷却 3 分钟,缩容冷却 5 分钟,防止抖动。

Q7:K8s 如何实现自愈?

  Controller Manager 持续监控集群状态,发现实际状态与期望状态不一致时自动修复:Pod 挂了 → 重启;节点宕机 → 在其他节点重新调度;Deployment 副本数不够 → 自动补齐。