1. Deployment:全自动调度

Deployment 是 Kubernetes 中最核心的控制器之一,它通过声明式 API 实现 Pod 的生命周期管理,包括自动扩缩容、滚动更新、回滚等功能。其核心优势在于无需手动干预即可维护集群的稳定性和高可用性。

1.1 核心功能详解

  • 声明式配置:通过 YAML 文件定义期望状态(如副本数、镜像版本),Kubernetes 会持续监控实际状态与目标状态的差异并自动修复。

  • 滚动更新策略:支持 maxSurge 和 maxUnavailable 参数控制更新过程中的资源分配。例如:

    strategy:
      type: RollingUpdate
      rollingUpdate:
        maxSurge: 25%  # 最多允许超出预期副本数的25%
        maxUnavailable: 25%  # 最多允许25%的副本不可用
    

    这种策略确保服务在更新过程中始终有部分实例在线。

  • 版本回滚:通过 kubectl rollout undo 可快速回退到历史版本。

    kubectl rollout history deployment/nginx-deployment  # 查看历史版本
    kubectl rollout undo deployment/nginx-deployment --to-revision=3  # 回滚到第3个版本
    

1.2 实战场景:蓝绿部署与金丝雀发布

蓝绿部署(Blue/Green Deployment)通过两个独立的 Deployment 实现无缝切换:

# 蓝色环境(当前生产)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-blue
spec:
  replicas: 10
  selector:
    matchLabels:
      app: nginx
      version: blue
  template:
    metadata:
      labels:
        app: nginx
        version: blue
    spec:
      containers:
      - name: nginx
        image: nginx:1.23
        ports:
        - containerPort: 80

# 绿色环境(新版本)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-green
spec:
  replicas: 0
  selector:
    matchLabels:
      app: nginx
      version: green
  template:
    metadata:
      labels:
        app: nginx
        version: green
    spec:
      containers:
      - name: nginx
        image: nginx:1.24
        ports:
        - containerPort: 80

通过调整 Service 的 selector 切换流量:

# 初始指向蓝色
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
    version: blue
  ports:
  - port: 80
    targetPort: 80

# 切换至绿色
spec:
  selector:
    app: nginx
    version: green

金丝雀发布(Canary Release)则通过逐步增加新版本副本数验证稳定性:

# 创建新版本副本
kubectl set image deployment/nginx-deployment nginx=nginx:1.24
# 限制新版本副本数为10%
kubectl scale deployment nginx-deployment --replicas=1
# 监控指标后逐步扩容

2. NodeSelector:定向调度

NodeSelector 是最基础的调度策略,通过标签匹配实现 Pod 与特定节点的绑定。其核心原理是利用 Kubernetes 的标签系统(Label)进行节点筛选。

2.1 标签管理与策略设计

  • 节点标签的生命周期管理:
    kubectl label nodes <node-name> disk=ssd   # 添加SSD磁盘标签
    kubectl label nodes <node-name> disk-      # 移除标签
    
  • 多标签组合调度:
    spec:
      nodeSelector:
        disk: ssd
        env: production
    
    该 Pod 只能调度到同时满足 disk=ssd 和 env=production 的节点。

2.2 场景应用:硬件资源隔离

在 GPU 计算集群中,通过 NodeSelector 绑定 GPU 节点:

apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  containers:
  - name: ai-train
    image: nvidia/cuda:11.8.0-base
    resources:
      limits:
        nvidia.com/gpu: 1
  nodeSelector:
    nvidia.com/gpu.present: "true"

此配置确保 AI 训练任务仅运行在具备 GPU 的节点上。


3. NodeAffinity:Node 亲和性调度

NodeAffinity 提供更灵活的调度逻辑,支持 required(硬性约束)和 preferred(软性偏好)两种模式。

3.1 拓扑键与跨可用区调度

通过 topologyKey 实现跨可用区的高可用部署:

spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: "failure-domain.beta.kubernetes.io/zone"
            operator: In
            values:
            - zone-a
            - zone-b

此配置要求 Pod 必须调度到 zone-a 或 zone-b 区域,避免单点故障。

3.2 多条件组合策略

使用 operator 字段实现复杂逻辑:

  • In:包含指定值
  • NotIn:排除指定值
  • Gt/Lt:数值比较(适用于资源指标)
    示例:
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: "kubernetes.io/os"
            operator: NotIn
            values:
            - windows

此配置禁止 Pod 调度到 Windows 节点。


4. PodAffinity:Pod 亲和与互斥调度

PodAffinity 用于控制 Pod 之间的协同部署策略,常用于分布式系统中。

4.1 分布式数据库部署

以 MySQL 集群为例,通过 PodAffinity 实现主从节点分离:

# 主节点配置
apiVersion: v1
kind: Pod
metadata:
  name: mysql-master
  labels:
    role: master
spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: "role"
            operator: In
            values:
            - master
        topologyKey: "kubernetes.io/hostname"

# 从节点配置
apiVersion: v1
kind: Pod
metadata:
  name: mysql-slave
  labels:
    role: slave
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: "role"
            operator: In
            values:
            - master
        topologyKey: "kubernetes.io/zone"

主节点禁止部署在同一主机(避免单点故障),从节点必须与主节点同区(降低网络延迟)。


5. Taints 和 Tolerations:污点与容忍

Taints 是 Kubernetes 的高级调度机制,通过标记节点限制 Pod 的调度行为。

5.1 污点类型与 Effect

  • NoSchedule:禁止未容忍该污点的 Pod 调度
  • PreferNoSchedule:优先禁止,但允许紧急调度
  • NoExecute:不仅禁止调度,还会驱逐已运行的 Pod

5.2 典型场景:专用节点池

创建 GPU 专用节点池并标记为专用:

kubectl taint nodes gpu-node dedicated=gpu:NoSchedule

再通过 Tolerations 允许特定任务使用 GPU:

spec:
  tolerations:
  - key: "dedicated"
    operator: "Equal"
    value: "gpu"
    effect: "NoSchedule"

6. Pod 优先级和抢占

PriorityClass 为 Pod 分配优先级,高优先级 Pod 可抢占低优先级 Pod 的资源。

6.1 抢占机制详解

当高优先级 Pod 被调度时,Kubernetes 会尝试终止低优先级 Pod:

  1. 资源释放:优先选择可释放资源最少的节点
  2. 优雅终止:发送 SIGTERM 信号并等待终止超时(默认 30s)
  3. 抢占失败:若无法腾出资源则调度失败

6.2 配置示例

# 高优先级配置
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: critical-priority
value: 1000000
globalDefault: false
description: "For critical system components"

在紧急任务中引用:

spec:
  priorityClassName: critical-priority

7. DaemonSet:每个 Node 上运行一个 Pod

DaemonSet 确保每个符合条件的节点运行一个 Pod,适用于日志收集、监控等场景。

7.1 更新策略与滚动升级

  • RollingUpdate:逐步替换旧 Pod
  • OnDelete:仅在删除旧 Pod 时创建新 Pod
spec:
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1

7.2 实战案例:日志收集系统

使用 Fluentd 收集所有节点日志:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
spec:
  selector:
    matchLabels:
      name: fluentd
  template:
    metadata:
      labels:
        name: fluentd
    spec:
      containers:
      - name: fluentd
        image: fluent/fluentd-kubernetes-daemonset:v1.14.5-debian-1.2
        volumeMounts:
        - name: varlog
          mountPath: /var/log
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

8. Job:批处理调度

Job 用于执行一次性任务,直到所有 Pod 成功完成。

8.1 并行与串行执行

  • 并行执行:默认同时运行多个 Pod
  • 串行执行:通过 completions 和 parallelism 控制:
    spec:
      completions: 10  # 总共需要完成10个任务
      parallelism: 3    # 同时运行3个Pod
    

8.2 容错机制

  • BackoffLimit:失败重试次数
  • ActiveDeadlineSeconds:任务最大运行时间
    示例:
spec:
  backoffLimit: 5
  activeDeadlineSeconds: 3600

9. CronJob:定时批处理调度

CronJob 按计划周期性执行 Job,适用于定时备份、数据同步等场景。

9.1 高级配置

  • 并发策略:
    • Forbid:禁止并发执行
    • Replace:终止旧任务并启动新任务
  • 历史保留:
    successfulJobsHistoryLimit: 3
    failedJobsHistoryLimit: 1
    

9.2 实战案例:数据库备份

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: backup-mysql
spec:
  schedule: "0 2 * * *"  # 每天凌晨2点执行
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: mysql:5.7
            command: ["sh", "-c", "mysqldump -h db -u root -p$MYSQL_ROOT_PASSWORD mydb > /backup.sql"]
          volumes:
          - name: backup-volume
            persistentVolumeClaim:
              claimName: backup-pvc

10. Pod 容灾调度

通过 PodDisruptionBudget (PDB) 和 Pod 重启策略 实现容灾能力。

10.1 PodDisruptionBudget 详解

PDB 确保在滚动更新或节点维护时保留最小可用副本数:

spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: nginx

此配置要求至少 2 个 Nginx Pod 始终可用。

10.2 重启策略与优雅终止

  • Always:无论退出码如何都重启
  • OnFailure:仅在失败时重启
  • Never:从不重启
    示例:
spec:
  restartPolicy: Always
  terminationGracePeriodSeconds: 30

11. Init Container:初始化容器

Init Container 在主容器启动前运行,用于执行依赖检查或数据预加载。

11.1 多阶段初始化

多个 Init Container 按顺序执行:

spec:
  initContainers:
  - name: init-db
    image: mysql:5.7
    command: ["sh", "-c", "until mysql -h db -u root -p$MYSQL_ROOT_PASSWORD -e 'SELECT 1'; do sleep 1; done"]
  - name: init-config
    image: busybox
    command: ["sh", "-c", "curl http://config-server/config > /app/config.json"]

11.2 健康检查与依赖管理

结合 Liveness/Readiness Probes 确保初始化完成后再启动主容器:

readinessProbe:
  exec:
    command: ["cat", "/tmp/ready"]
  initialDelaySeconds: 5

12. 调度策略性能调优

12.1 调度器参数调整

  • percentageOfNodesToScore:控制调度器评估的节点比例
  • algorithmSource:自定义调度算法
    示例:
apiVersion: kubescheduler.config.k8s.io/v1beta3
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: default-scheduler
    pluginConfig:
    - name: NodeResourcesFit
      args:
        scoringStrategy:
          type: LeastAllocated

12.2 大规模集群优化

  • 多调度器并行运行:
    kubectl apply -f custom-scheduler.yaml
    
  • 节点分组标签:通过标签划分计算、存储等节点组
  • 资源预留:为系统组件预留资源
    kube-reserved:
      cpu: "500m"
      memory: "1Gi"
    

13. 自定义调度器开发

当内置调度器无法满足需求时,可开发自定义调度器。

13.1 核心开发步骤

  1. 监听 Pod 事件:
    watcher := kubeClient.CoreV1().Pods("").Watch(context.TODO(), metav1.ListOptions{})
    for event := range watcher.ResultChan() {
        pod := event.Object.(*corev1.Pod)
        if pod.Spec.NodeName == "" {
            schedule(pod)
        }
    }
    
  2. 自定义调度算法:
    func customAlgorithm(pod *corev1.Pod, nodes []corev1.Node) *corev1.Node {
        // 实现业务逻辑
    }
    
  3. 绑定 Pod 到节点:
    binding := &corev1.Binding{
        ObjectMeta: metav1.ObjectMeta{
            Name: pod.Name,
        },
        Target: corev1.ObjectReference{
            Kind: "Node",
            Name: selectedNode.Name,
        },
    }
    kubeClient.CoreV1().Pods(pod.Namespace).Bind(context.TODO(), pod.Name, binding, metav1.CreateOptions{})
    

14. 调度策略监控与调试

14.1 Prometheus 监控

部署 Prometheus 抓取调度器指标:

- job_name: kube-scheduler
  metrics_path: /metrics
  kubernetes_sd_configs:
  - role: endpoints
    namespaces:
      names: [kube-system]

14.2 常见问题排查

  • Pod Stuck in Pending:
    kubectl describe pod <pod-name> | grep Events
    
  • 资源不足:
    kubectl describe node <node-name> | grep -i allocatable
    

15. 实战总结与最佳实践

15.1 调度策略选型指南

场景推荐策略
GPU 任务NodeSelector + Taints
分布式数据库PodAffinity + AntiAffinity
日志收集DaemonSet
定时任务CronJob
高优先级任务PriorityClass + Preemption

15.2 资源利用率优化

  • 合理设置资源请求:
    resources:
      requests:
        memory: "256Mi"
        cpu: "250m"
      limits:
        memory: "512Mi"
        cpu: "500m"
    
  • 使用 HPA 自动扩缩容:
    apiVersion: autoscaling/v2beta2
    kind: HorizontalPodAutoscaler
    metadata:
      name: nginx-hpa
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: nginx-deployment
      minReplicas: 2
      maxReplicas: 10
      metrics:
      - type: Resource
        resource:
          name: cpu
          target:
            type: Utilization
            averageUtilization: 80
    

16. 未来趋势:Serverless 与调度器智能化

  • KEDA:基于事件驱动的自动扩缩容
  • AI 调度器:通过机器学习预测负载并动态调整策略
  • 多云调度:跨云厂商资源统一调度

附录:完整示例代码库

所有示例代码可在 GitHub 获取:

git clone https://github.com/example/k8s-scheduler-examples.git

在这里插入图片描述

更多推荐