📚 Kubernetes调度与部署机制详解

🎯 学习目标

  • 掌握Kubernetes Pod调度的核心机制
  • 理解部署管理策略和最佳实践
  • 学会配置自动扩缩容和优化调度性能

🏗️ 一、Kubernetes调度机制

1.1 NodeSelector(节点选择器)🎯

  • 概念: 最简单的Pod调度约束方式,通过匹配节点标签控制Pod调度
  • 实现: 在Pod的spec字段中添加nodeSelector字段
  • 应用场景: 将Pod调度到具有特定标签的节点上
  • 示例: 将Pod调度到具有source=qikqiak标签的节点上

1.2 亲和性与反亲和性 🔗

节点亲和性

  • 软策略 (preferredDuringSchedulingIgnoredDuringExecution): 优先满足但不强制
  • 硬策略 (requiredDuringSchedulingIgnoredDuringExecution): 必须满足条件
  • 支持的操作符: In、NotIn、Gt、Lt、Exists、DoesNotExist

Pod亲和性与反亲和性

  • podAffinity: 让Pod与指定Pod部署在同一拓扑域
  • podAntiAffinity: 让Pod不与指定Pod部署在同一拓扑域
  • 拓扑域: 通过topologyKey指定,常用如kubernetes.io/hostname

1.3 污点与容忍 🚫

污点效果

  • NoSchedule: Pod不会被调度到标记的节点
  • PreferNoSchedule: NoSchedule的软策略版本
  • NoExecute: 无对应Tolerate的Pod会被直接逐出

🚀 二、Kubernetes部署管理

2.1 滚动更新 🔄

  • 特点: 默认部署策略,零停机部署
  • 机制: 逐步替换现有Pod实例,确保足够数量的Pod可用
  • 优势: 平滑过渡,最小化服务中断

2.2 回滚机制 ⏪

  • 命令: kubectl rollout undo deployment <DEPLOYMENT-NAME>
  • 作用: 快速恢复生产环境问题
  • 重要性: 保障系统稳定性和可恢复性

2.3 HPA(水平自动扩缩)📈

  • 功能: 根据负载自动调整Pod数量
  • 指标: 基于CPU、内存或自定义指标
  • 特点: 水平扩缩与垂直扩缩不同

💻 三、命令汇总

调度相关命令

1
2
3
4
5
6
# 查看节点标签
kubectl get nodes --show-labels
# 给节点添加标签
kubectl label nodes NODE-NAME KEY=VALUE
# 给节点添加污点
kubectl taint nodes NODE-NAME KEY=VALUE:EFFECT

部署管理命令

1
2
3
4
5
6
7
8
# 更新部署
kubectl apply -f deployment.yaml
# 查看部署状态
kubectl rollout status deployment/<DEPLOYMENT-NAME>
# 回滚部署
kubectl rollout undo deployment/<DEPLOYMENT-NAME>
# 查看部署历史
kubectl rollout history deployment/<DEPLOYMENT-NAME>

自动扩缩命令

1
2
3
4
# 创建HPA
kubectl autoscale deployment <DEPLOYMENT-NAME> --min=2 --max=10 --cpu-percent=80
# 查看HPA状态
kubectl get hpa

🆕 四、最新技术补充

4.1 HPA高级配置 🎛️

基于最新实践,HPA现在支持更丰富的指标类型:

自定义指标扩缩容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: custom-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: packets-per-second
target:
type: AverageValue
averageValue: 1k

4.2 滚动更新优化策略 ⚡

最新的滚动更新实践建议:

优化配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
apiVersion: apps/v1
kind: Deployment
metadata:
name: optimized-deployment
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 额外加1个副本平滑引入新版本
maxUnavailable: 0 # 保证服务不减容
template:
metadata:
labels:
app: my-app
spec:
terminationGracePeriodSeconds: 60
containers:
- name: app
image: my-app:v2
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 3
periodSeconds: 5
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 10"]

4.3 调度策略最佳实践 🎯

根据2024-2025年的最新实践:

节点亲和性配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: gpu
operator: In
values:
- "true"
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- "az1"

📊 五、技术要点总结

调度机制核心要点 🎯

  1. NodeSelector: 简单但功能有限,适合基础场景
  2. 节点亲和性: 支持软硬策略,操作符丰富,灵活性强
  3. Pod亲和性: 基于拓扑域控制Pod间部署关系
  4. 污点容忍: 节点级别的排斥机制,配合Pod容忍使用

部署管理核心要点 🚀

  1. 滚动更新: 零停机部署,通过maxSurge和maxUnavailable控制
  2. 回滚机制: 支持快速回退到历史版本
  3. HPA: 基于指标自动扩缩,支持多种指标类型

最佳实践建议 💡

  1. 合理设置资源请求和限制: 确保调度决策准确
  2. 使用readinessProbe: 确保Pod就绪后才接收流量
  3. 配置优雅终止: 通过preStop和terminationGracePeriodSeconds实现平滑关闭
  4. 监控调度效果: 使用Prometheus等工具监控调度性能

🎓 六、学习建议

学习路径 📈

  1. 基础掌握: 先理解NodeSelector和基本亲和性配置
  2. 实践操作: 通过实际部署练习滚动更新和回滚
  3. 深入理解: 学习HPA的自定义指标配置
  4. 性能优化: 掌握调度策略的性能调优技巧

实践建议 🛠️

  • 从简单的NodeSelector开始,逐步学习复杂的亲和性配置
  • 在测试环境中充分练习滚动更新和回滚操作
  • 结合监控工具观察调度效果和性能指标
  • 关注Kubernetes版本的更新和新特性

第二阶段:Docker(容器引擎入门)·多容器编排

多容器编排入门

  • 概念:通过声明式 YAML 文件定义多容器应用的服务、网络、卷等依赖关系,单命令实现整体启动和停止。
  • 实现
    • Compose 解析 YAML 文件,生成每个服务的容器配置。
    • 自动创建项目专属的桥接网络,服务名解析为容器 IP(通过内部 DNS)。
    • 依赖关系(depends_on)仅控制启动顺序,不保证健康。
    • Compose v3 支持定义多种部署模式(swarm 模式除外,单纯 Compose 是单机编排)。

第三阶段:Docker 的实际应用(部署项目概念与实现)·安装与部署 Nginx

安装 Docker Engine 的概览

  • 概念:Docker Engine 是一组软件包,包括 dockerd、containerd、runc 以及客户端。
  • 实现:Linux 版本通过包管理器安装,利用 systemd 管理守护进程。守护进程以 root 权限运行,监听 Unix socket(/var/run/docker.sock),客户端通过该 socket 通信。

部署 Web 应用的基本流程

  • 概念:容器化部署指将应用及依赖打包到镜像,运行容器并对外暴露服务。
  • 实现
    • 镜像拉取:从仓库下载镜像各层,存储到本地内容寻址存储。
    • 容器创建:分配 rootfs(镜像层 + 容器可写层)、网络 netns、IP 地址及 Cgroups 配置。
    • 端口映射:在宿主机 iptables 上添加 DNAT 规则。
    • 卷挂载:通过绑定挂载或 volume 挂载将数据目录映射进容器。

第三阶段:Docker 的实际应用(部署项目概念与实现)·构建自定义镜像

本地构建 Docker 镜像

  • 概念:通过 Dockerfile 描述镜像构建步骤,生成可复用的应用镜像。
  • 实现
    • 构建上下文:Docker 将指定目录(或 URL)发送到守护进程。
    • 指令执行:守护进程逐条解析 Dockerfile 指令,每条指令启动临时容器执行(如 RUN),并将结果文件系统提交为新层。
    • 缓存机制:若指令及依赖文件未变更,则复用已有层(避免重复构建)。
    • 多阶段构建:构建器维护多个阶段镜像,最终仅将最后阶段的层导出为结果镜像。

第二阶段:Docker(容器引擎入门)·容器生命周期管理

生命周期状态

已创建、运行中、已暂停、已停止、已删除。

实现机制

  • 创建:准备 rootfs、配置 Namespace 和 Cgroups,但不启动进程。
  • 启动:通过 runc 执行容器进程(通常是 init 进程),设置网络和挂载点。
  • 运行:容器进程在隔离环境中运行,守护进程通过 waitptrace 监控状态。
  • 停止:发送 SIGTERM 信号,等待进程退出,若超时则 SIGKILL。然后清理 Namespace 和 Cgroups。
  • 资源限制:通过 Cgroups 在容器启动前或运行时动态设置 CPU、内存、IO 配额。

第二阶段:Docker(容器引擎入门)·数据持久化

Volume

  • 概念:Docker 管理的宿主机目录(默认位于 /var/lib/docker/volumes/),独立于容器生命周期。
  • 实现:Volume 以目录形式存在,可通过 docker volume 命令创建和管理。挂载到容器时,实际上是 bind mount 到该目录。Volume 支持驱动程序(如本地、NFS、云存储)实现不同后端。

Bind Mount

  • 概念:将宿主机任意路径直接挂载到容器目录。
  • 实现:通过 Linux 的 mount 系统调用将源路径(宿主机)绑定到目标路径(容器内 mount namespace)。依赖宿主机目录结构,不提供跨主机可移植性。

区别本质

Volume 是 Docker 对 Bind Mount 的封装,增加了命名管理、驱动扩展和备份恢复接口;Bind Mount 是直接利用内核特性。

第二阶段:Docker(容器引擎入门)·Docker 架构解析

Docker 架构

  • 概念:Docker 采用 C/S 架构,各组件相互协作。
  • 组件作用与实现
    • 客户端(CLI):接收用户指令,通过 REST API 与守护进程通信。
    • 守护进程:核心后台进程,管理镜像、容器、网络、卷。监听 REST API,处理请求并调用 containerd。
    • containerd:容器运行时管理器,负责镜像传输、存储、容器执行及生命周期管理,通过 gRPC 与 dockerd 交互。
    • runc:OCI 底层运行时,实际创建 Namespace 和 Cgroups 并启动容器进程。
    • 镜像(Image):只读模板,采用分层 UnionFS 存储。
    • 容器(Container):镜像的运行实例,在镜像层之上增加可写层(容器层)。
    • 仓库(Registry):存储和分发镜像的服务端(如 Docker Hub)。

第二阶段:Docker(容器引擎入门)·容器网络模型

Bridge(默认)

  • 概念:每个容器连接到虚拟桥接设备(docker0),通过 NAT 实现与外网通信。
  • 实现:Docker 创建名为 docker0 的虚拟以太网桥,为每个容器创建 veth pair(一端在容器 netns,另一端挂到 docker0)。容器间通过桥转发通信。出站流量通过 iptables 的 MASQUERADE 规则做源地址转换。

Host

  • 概念:容器直接使用宿主机网络栈,不创建 netns。
  • 实现:容器启动时不设置独立 netns,而是加入宿主机 netns,因此容器端口直接监听宿主机网络。

None

  • 概念:容器拥有独立 netns 但无任何网络接口,完全隔离。
  • 实现:仅创建 netns 但不分配 veth,用于需要自定义网络配置的场景。

Container

  • 概念:新容器与已有容器共享 netns。
  • 实现:设置 net namespace 为指定容器的 PID 对应的 netns。

端口映射

  • 实现:通过 iptables 的 DNAT(目标地址转换)规则,将访问宿主机特定端口的流量重定向到容器的 IP 和端口(容器 IP 是 bridge 网络内的地址)。

第二阶段:Docker(容器引擎入门)·镜像管理

镜像分层构建

  • 概念:每个 Dockerfile 指令产生一个只读层,层之间通过 UnionFS 叠加形成统一文件系统。
  • 实现
    • UnionFS 类型:OverlayFS(最常用)、AUFS、btrfs、devicemapper。
    • OverlayFS 原理:使用 lowerdir(只读下层)、upperdir(可写上层)、merged(统一视图)。容器启动时镜像层作为 lowerdir,容器可写层作为 upperdir。
  • 写时复制:修改文件时,将文件从下层复制到上层再修改,下层保持不变。

多阶段构建

  • 概念:在一个 Dockerfile 中使用多个 FROM 指令,前阶段用于编译或构建,后阶段仅复制产物,避免将构建工具和中间文件带入最终镜像。
  • 实现:每个阶段独立构建,最终镜像只包含最后阶段的层。Docker 构建器在阶段间传递文件(通过 COPY --from=)。

镜像内容寻址

每个镜像层由哈希(SHA256)标识,相同内容(例如基础层)可跨镜像共享,节省存储和传输。

第四阶段:Kubernetes(容器编排)·可观测性

Metrics Server

  • 概念:采集节点和 Pod 的 CPU、内存等资源指标。
  • 实现:通过 kubelet 的 cAdvisor 接口(汇总 cgroups 数据)获取指标,暴露给 HPA、kubectl top 等。

日志收集

  • 概念:采集容器 stdout/stderr 日志和容器内文件日志。
  • 常见实现(EFK/ELK):Fluentd 或 Filebeat 作为 DaemonSet 运行,读取容器日志文件(位于 /var/log/containers/),转发到 Elasticsearch 集群,并由 Kibana 可视化。

常见排查机制

  • 事件:Kubernetes 资源状态变化时生成 Event 对象,存储在 API Server 中,可通过 kubectl describe 查看。
  • 日志:kubelet 将容器标准输出日志轮转存储,默认保留近期文件。
  • exec 调试:通过 API Server 与 kubelet 的 /exec 子资源建立流式连接,在容器内执行命令(基于容器运行时 exec API)。
0%