1.6 Kube Scheduler

1.6 Kube Scheduler

Kube Scheduler 是 Kubernetes 控制平面的核心组件之一,负责将新创建的 Pod 分配到集群中合适的节点上运行。scheduler只决定哪个pod放在哪里,但不执行任何操作。

以下是基于 Kubernetes 官方文档和 Udemy 课程内容的详细解析:

一、核心工作原理

1. 调度流程概述

  1. **过滤阶段 (Predicates)**:从所有节点中筛选出符合 Pod 要求的候选节点
  2. **打分阶段 (Priorities)**:对候选节点进行评分,选择最优节点
  3. **绑定阶段 (Binding)**:将 Pod 与选定节点绑定

2. 详细工作流程

  1. Pod 创建:用户通过 kubectl 或 API 创建 Pod
  2. 进入调度队列:Pod 进入 Scheduler 的待调度队列
  3. 调度周期开始
    • 从队列中取出一个 Pod
    • 检查 Pod 是否可调度(如是否有 nodeSelector 等限制)
  4. 过滤阶段
    • 检查节点资源是否足够(CPU、内存)
    • 检查节点是否满足 Pod 的亲和性/反亲和性规则
    • 检查节点是否有污点而 Pod 是否有相应容忍
    • 检查端口冲突等
  5. 打分阶段
    • 对通过过滤的节点进行评分(0-10 分)
    • 考虑因素包括:资源平衡、亲和性得分、数据局部性等
  6. 选择节点:选择得分最高的节点
  7. 绑定:通过 API Server 更新 Pod 的 nodeName 字段

二、调度策略详解

1. 预选策略 (Predicates)

  • PodFitsResources:检查节点资源是否满足
  • PodFitsHostPorts:检查请求的 HostPort 是否可用
  • MatchNodeSelector:检查节点标签匹配
  • CheckVolumeBinding:检查卷绑定情况
  • NoDiskConflict:检查存储卷冲突(已弃用)
  • PodToleratesNodeTaints:检查污点容忍

2. 优选策略 (Priorities)

  • LeastRequestedPriority:优先选择请求资源少的节点
  • BalancedResourceAllocation:平衡 CPU 和内存使用
  • NodeAffinityPriority:节点亲和性权重
  • TaintTolerationPriority:污点容忍权重
  • ImageLocalityPriority:优先选择已有所需镜像的节点

三、常用命令

1. 查看 Scheduler 状态

1
2
3
kubectl get componentstatuses scheduler
# 或缩写
kubectl get cs scheduler

2. 查看 Scheduler Pod

1
kubectl get pods -n kube-system -l component=kube-scheduler

3. 查看调度日志

1
2
3
kubectl logs -n kube-system <scheduler-pod-name>
# 带时间戳查看
kubectl logs -n kube-system <scheduler-pod-name> --timestamps=true

4. 查看调度事件

1
kubectl get events --field-selector involvedObject.kind=Pod

5. 查看未调度 Pod

1
kubectl get pods --all-namespaces --field-selector status.phase=Pending

6. 查看 Pod 调度详情

1
kubectl describe pod <pod-name> | grep -A 10 Events

7. 检查调度器配置

1
kubectl get pod <scheduler-pod-name> -n kube-system -o yaml

四、与其他功能的交互

1. 与 API Server 交互

  • 监听未绑定 Pod 的变化
  • 通过 API Server 更新 Pod 的绑定信息
  • 使用领导者选举机制实现高可用

2. 与 Controller Manager 交互

  • Controller Manager 创建的 Pod 需要 Scheduler 调度
  • 某些控制器(如 Deployment)会响应调度失败事件

3. 与 Kubelet 交互

  • Kubelet 接收调度结果并启动 Pod
  • Kubelet 上报节点资源使用情况影响后续调度

4. 与集群自动扩缩容 (Cluster Autoscaler) 交互

  • 当没有合适节点时,Cluster Autoscaler 可能扩展集群
  • Scheduler 会考虑自动扩缩容约束

五、高级配置

1. 自定义调度策略

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: kubescheduler.config.k8s.io/v1beta2
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
plugins:
preScore:
enabled:
- name: InterPodAffinity
score:
enabled:
- name: InterPodAffinity
weight: 10

2. 多调度器配置

1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
schedulerName: my-custom-scheduler
containers:
- name: nginx
image: nginx

3. 调度器调优参数

  • --percentage-of-nodes-to-score: 设置评分节点的百分比(默认 50%)
  • --kube-api-qps: 控制 API Server 的 QPS(默认 50)
  • --kube-api-burst: 控制 API Server 的突发请求量(默认 100)

六、常见问题排查

1. Pod 处于 Pending 状态

1
2
# 查看原因
kubectl describe pod <pod-name> | grep -i "failed scheduling"

2. 调度器性能问题

1
2
# 查看调度延迟
kubectl get --raw /metrics | grep scheduler_scheduling_algorithm_duration_seconds

3. 节点资源不足

1
kubectl describe node <node-name> | grep -A 10 Allocatable

七、最佳实践(来自 Udemy 课程)

  1. 合理设置资源请求和限制:帮助调度器做出更好决策
  2. 使用亲和性/反亲和性规则:控制 Pod 分布
  3. 使用污点和容忍:专用节点管理
  4. 监控调度延迟:确保调度性能
  5. 考虑 Pod 优先级:重要 Pod 优先调度
  6. 使用 PodTopologySpread:实现 Pod 拓扑分布

八、调试技巧

  1. 模拟调度
1
kubectl create -f pod.yaml --dry-run=server
  1. 查看调度器决策
1
kubectl get events --sort-by=.metadata.creationTimestamp
  1. 检查节点容量
1
kubectl describe nodes | grep -A 5 Capacity
  1. 检查调度器指标
1
2
kubectl proxy &
curl http://localhost:8001/metrics | grep scheduler

1.7 Kubelet

1.7 Kubelet :节点代理的核心组件

一、Kubelet 概述

Kubelet 是 Kubernetes 集群中运行在每个工作节点上的主要”节点代理”,负责管理 Pod 和容器的生命周期。它是 Kubernetes 操作的最小单元,确保容器按照预期运行。

二、核心功能详解

接收到在节点上加载容器或pod的指令时,请求容器运行时引擎(Docker)拉取所需的Image并运行一个实例;Kubelet继续监控pod和容器的状态并及时向Kube API服务器报告。

1. 节点注册 (Register Node)

工作流程

  1. 启动时注册
    1
    2
    # 查看节点注册信息
    kubectl describe node <node-name> | grep -A 10 "System Info"
  2. 定期心跳
    • 通过 --node-status-update-frequency 参数控制频率(默认10秒)
      1
      2
      # 查看节点状态更新时间戳
      kubectl get node <node-name> -o jsonpath='{.status.conditions[?(@.type=="Ready")].lastHeartbeatTime}'

关键配置

1
2
# 查看kubelet注册参数
ps aux | grep kubelet | grep -E "register-node|node-labels|node-ip"

2. 创建和管理 Pods

Pod 创建流程

  1. 接收 PodSpec:通过以下方式之一:

    • API Server(主要方式)
    • 静态 Pod 的清单文件(--pod-manifest-path 指定目录)
  2. 容器运行时交互

    1
    2
    # 查看kubelet与容器运行时通信配置
    ps aux | grep kubelet | grep -E "container-runtime|pod-infra-container-image"
  3. 资源准备

    • 挂载卷(Volumes)
    • 下载镜像(Images)
    • 准备网络命名空间

3. 监控节点和 Pods

监控机制

  1. 节点健康检查

    1
    2
    # 查看节点健康状况
    kubectl get node <node-name> -o jsonpath='{.status.conditions}'
  2. Pod 健康检查

    • Liveness probes
    • Readiness probes
    • Startup probes
  3. 状态上报

    1
    2
    # 查看kubelet状态上报频率
    ps aux | grep kubelet | grep -E "node-status-update-frequency|sync-frequency"

三、Kubelet 架构深入

1. 主要组件

  • **PLEG (Pod Lifecycle Event Generator)**:生成Pod生命周期事件
  • cAdvisor:容器监控数据收集
  • Volume Manager:卷管理
  • **Container Runtime Interface (CRI)**:与容器运行时交互

2. 关键目录结构

1
2
# 查看kubelet工作目录
ls -l /var/lib/kubelet/

重要子目录:

  • pods/:Pod数据目录
  • plugins/:卷插件
  • pod-resources/:Pod资源信息

四、Kubelet 命令与操作

1. 服务管理

1
2
3
4
5
6
# 查看kubelet服务状态
systemctl status kubelet
# 重启kubelet
sudo systemctl restart kubelet
# 查看日志
journalctl -u kubelet -f

2. 运行时检查

1
2
3
4
# 查看kubelet进程详情
ps aux | grep kubelet
# 检查kubelet端口监听
sudo netstat -tulnp | grep kubelet

3. 调试命令

1
2
3
4
# 强制删除异常Pod
kubectl delete pod <pod-name> --grace-period=0 --force
# 检查kubelet证书
openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text

五、Kubelet 配置详解

1. 重要启动参数

1
2
# 查看当前运行的参数
ps aux | grep kubelet

关键参数:

  • --config:配置文件路径
  • --kubeconfig:连接API Server的认证文件
  • --pod-manifest-path:静态Pod路径
  • --fail-swap-on:是否禁止swap
  • --container-runtime:容器运行时选择
  • --node-status-update-frequency:状态上报频率

2. 配置文件示例

/var/lib/kubelet/config.yaml 典型内容:

1
2
3
4
5
6
7
8
9
10
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
address: "0.0.0.0"
port: 10250
serializeImagePulls: false
evictionHard:
memory.available: "100Mi"
nodefs.available: "10%"
nodefs.inodesFree: "5%"
imagefs.available: "15%"

六、Kubelet 与其他组件交互

1. 与 API Server 交互

  • 认证:使用 TLS 证书
  • 授权:通过 Node authorizer
  • 通信:通过 --kubeconfig 指定配置

2. 与容器运行时交互

支持多种运行时:

1
2
# 查看当前使用的运行时
ps aux | grep kubelet | grep container-runtime

3. 与 cAdvisor 集成

1
2
3
# 获取节点监控数据(需要先进行端口转发)
kubectl proxy &
curl http://localhost:8001/api/v1/nodes/<node-name>/proxy/metrics/cadvisor

七、特殊注意事项

1. Kubeadm 不部署 Kubelet

1
2
3
# 手动安装kubelet示例(Ubuntu)
sudo apt-get update && sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

2. 证书轮换管理

1
2
3
4
# 检查证书状态
sudo journalctl -u kubelet | grep -i "certificate"
# 手动轮换证书
sudo systemctl restart kubelet

3. 资源清理

1
2
3
4
# 清理未使用的镜像
sudo docker image prune -a
# 清理终止的容器
sudo docker container prune

八、故障排查指南

1. 常见问题诊断

1
2
3
4
# 检查kubelet日志中的错误
sudo journalctl -u kubelet --no-pager | grep -i error
# 检查证书过期
openssl x509 -in /var/lib/kubelet/pki/kubelet.crt -noout -dates

2. 健康检查端点

1
2
3
curl -sk https://<node-ip>:10250/healthz
# 或通过kubectl proxy
kubectl get --raw "/api/v1/nodes/<node-name>/proxy/healthz"

3. 资源不足处理

1
2
3
4
# 查看节点资源压力
kubectl describe node <node-name> | grep -A 10 "Allocated resources"
# 查看被驱逐的Pod
kubectl get pods --all-namespaces -o wide | grep Evicted