K8S和容器概念
Docker vs K8S
Docker 是“创建容器”的工具,而 K8S 是“管理容器集群”的系统。
类比:Docker 像是一台汽车的发动机,而 K8S 则是整个交通管理系统,协调成千上万辆汽车(容器)的运行。
虽然 K8S 最初主要支持 Docker,但它不依赖特定容器运行时。目前,K8S 支持多种容器运行时,包括:
- containerd(Docker 的核心组件,现已成为主流)
- CRI-O(专为 K8S 设计的轻量级运行时)
- Kata Containers(安全容器)
- 其他符合 CRI(Container Runtime Interface) 标准的运行时。
关键业务概念
https://www.cnblogs.com/aibi1/p/18762342
K8S 编排的核心能力
K8S 对容器(无论是否由 Docker 创建)的编排能力包括:
调度(Scheduling)**:自动将容器分配到合适的节点(基于资源需求、亲和性等)。
Kubernetes(K8S)的 调度(Scheduling) 是指将 Pod 分配到集群中合适的 Node(节点) 上的过程。调度器(kube-scheduler)基于资源需求、约束策略和集群状态,确保 Pod 在满足条件的节点上运行。以下是核心机制和示例说明:
一、调度的核心机制
调度过程分为两个阶段:
- 过滤(Predicates):排除不满足 Pod 需求的节点(如资源不足、标签不匹配)。
- 评分(Priorities):对剩余节点打分,选择最优节点(如资源利用率最均衡的节点)。
最终,调度器将 Pod 绑定到得分最高的节点,由该节点的 kubelet 启动容器。
二、调度关键概念
-
资源请求(Resource Requests)
Pod 需要声明所需的 CPU、内存等资源(如requests.cpu: 1),调度器根据此分配节点。
示例:若 Pod 请求2 CPU,但节点只剩1 CPU,该节点会被过滤。 -
节点亲和性(Node Affinity)
定义 Pod 倾向于调度到哪些节点(基于节点标签)。
示例:将 Pod 部署到带有disktype=ssd标签的节点。 -
Pod 亲和性/反亲和性(Pod Affinity/Anti-Affinity)
定义 Pod 与其他 Pod 的共存规则。
示例:避免同一服务的多个副本部署到同一节点(反亲和性)。 -
污点与容忍(Taints and Tolerations)
- 污点(Taint):节点标记为“排斥某些 Pod”。
- 容忍(Toleration):Pod 声明可以容忍污点。
示例:专用 GPU 节点添加污点,只有声明了容忍的 Pod(如 AI 训练任务)才能调度。
-
节点选择器(nodeSelector)
强制 Pod 调度到特定标签的节点(旧版简化亲和性)。
示例:将 Pod 部署到带有env=prod标签的节点。
三、调度示例场景
示例 1:资源请求不足导致调度失败
- Pod 定义:请求
2 CPU,但集群中没有节点满足。apiVersion: v1 kind: Pod metadata: name: web-app spec: containers: - name: nginx image: nginx resources: requests: cpu: "2" memory: "1Gi" nodeSelector: env: prod - 调度结果:
若所有env=prod的节点可用 CPU < 2,Pod 处于Pending状态,直到资源满足。
示例 2:节点亲和性
- 节点标签:
节点node-1有标签disktype=ssd。 - Pod 定义:优先调度到
disktype=ssd的节点。apiVersion: v1 kind: Pod metadata: name: db-pod spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: disktype operator: In values: [ssd] containers: - name: mysql image: mysql - 调度结果:
优先选择node-1,若无满足条件的节点,则选择其他节点。
示例 3:Pod 反亲和性(避免单节点部署多个副本)
- Deployment 定义:同一服务的 Pod 避免部署到同一节点。
apiVersion: apps/v1 kind: Deployment metadata: name: web spec: replicas: 3 selector: matchLabels: app: web template: metadata: labels: app: web spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: [web] topologyKey: kubernetes.io/hostname containers: - name: nginx image: nginx - 调度结果:
三个 Pod 会分布在三个不同节点(若节点数 ≥3)。
示例 4:污点与容忍(专用节点)
- 节点污点:标记一个节点为专用 GPU 节点。
kubectl taint nodes node-1 gpu=true:NoSchedule - Pod 定义:声明容忍污点。
apiVersion: v1 kind: Pod metadata: name: ai-task spec: tolerations: - key: "gpu" operator: "Equal" value: "true" effect: "NoSchedule" containers: - name: tensorflow image: tensorflow/gpu nodeSelector: gpu: "true" - 调度结果:
只有node-1能运行此 Pod。
四、调度过程调试
-
查看 Pod 调度失败原因:
kubectl describe pod <pod-name>输出中的
Events会显示调度失败原因(如资源不足、无匹配节点)。 -
手动绑定 Pod 到节点(仅调试用):
spec: nodeName: node-2 # 跳过调度器,直接指定节点
扩缩容(Scaling)**:根据负载自动调整容器副本数量(如 Horizontal Pod Autoscaler)。
Horizontal Pod Autoscaler(HPA)的配置并不是直接基于 Deployment 的配置文件,而是通过 独立的 HPA 资源对象 来定义。HPA 通过引用目标 Deployment(或其他可扩缩资源,如 StatefulSet)的名称,监控其关联的 Pod 指标,并动态调整副本数。
一、HPA 的配置方式
HPA 的配置有以下两种方式,均不依赖 Deployment 的 YAML 文件:
1. 通过 kubectl autoscale 命令创建
直接通过命令行工具快速创建 HPA,无需编写 YAML 文件:
kubectl autoscale deployment <deployment-name> \
--cpu-percent=50 \ # 目标 CPU 使用率阈值
--min=2 \ # 最小副本数
--max=10 # 最大副本数
2. 通过 YAML 文件定义独立的 HPA 资源
创建单独的 HPA 配置文件(如 hpa.yaml),引用目标 Deployment:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa # HPA 资源名称
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app # 指向目标 Deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50 # 目标 CPU 使用率 50%
然后应用配置:
kubectl apply -f hpa.yaml
二、HPA 与 Deployment 的关系
-
HPA 通过
scaleTargetRef关联 Deployment
HPA 通过字段scaleTargetRef指定要管理的 Deployment(或其他资源),并不需要修改原 Deployment 的配置文件。 -
HPA 操作 Deployment 的副本数
HPA 通过 Kubernetes API 动态调整 Deployment 的replicas字段,触发 Pod 的扩缩容。 -
Deployment 无需特殊配置
Deployment 本身无需任何 HPA 相关配置,只需确保:- Pod 配置中声明了 资源请求(
resources.requests)(若使用 CPU/内存指标)。 - 目标 Deployment 已正常运行。
- Pod 配置中声明了 资源请求(
三、配置示例与验证
1. 示例:Deployment 的资源配置
Deployment 的 Pod 模板需要声明资源请求(requests),否则 HPA 无法计算 CPU/内存使用率:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 2
template:
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "100m" # 必须声明 CPU 请求
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
2. 验证 HPA 状态
# 查看 HPA 状态
kubectl get hpa
# 输出示例
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
web-app-hpa Deployment/web-app 0%/50% 2 10 2 1m
# 查看扩缩容事件详情
kubectl describe hpa web-app-hpa
四、HPA 的高级配置
1. 多指标扩缩容
HPA 支持基于 CPU、内存、自定义指标 或 外部指标 的组合策略:
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
- type: Pods
pods:
metric:
name: http_requests_per_second # 自定义指标(需预先配置)
target:
type: AverageValue
averageValue: 100
2. 行为控制(Behavior)
调整扩缩容的冷却时间和速率:
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 缩容冷却时间 5 分钟
policies:
- type: Percent
value: 10 # 每次最多缩容 10% 的副本
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 60 # 扩容冷却时间 1 分钟
policies:
- type: Pods
value: 4 # 每次最多扩容 4 个副本
periodSeconds: 15
五、核心注意事项
-
资源请求必须声明
如果使用 CPU/内存作为指标,Pod 必须配置resources.requests,否则 HPA 无法计算使用率。 -
监控组件需就绪
- 使用内置资源指标(CPU/内存)需安装 Metrics Server。
- 使用自定义指标需部署 Prometheus + Prometheus Adapter 或其他指标提供者。
-
避免频繁震荡(Flapping)
合理设置behavior参数,避免副本数因指标波动频繁变化。
六、总结
- HPA 的配置独立于 Deployment,通过 YAML 文件或
kubectl autoscale命令单独定义。 - HPA 通过 API 动态管理 Deployment 的副本数,无需修改原 Deployment 的配置。
- 确保 Pod 声明资源请求,并正确配置监控组件,是 HPA 正常工作的关键。
- 服务发现与负载均衡:通过 Service 和 Ingress 暴露服务,并分配流量。
Pod 是临时性的,其 IP 地址会因重启、扩缩容或故障而频繁变化。直接依赖 Pod IP 会导致服务不可靠。
Service 为 Pod 组分配一个 固定的虚拟 IP(ClusterIP) 和 DNS 名称,屏蔽后端 Pod 的变化细节。
服务发现:Service 通过 标签选择器(Label Selector) 动态发现匹配的 Pod,并自动更新后端端点列表。
简单的理解:Service暴露固定IP或者域名和其他Service通讯。 流量请求到Service,Service会基于负载均衡算法路由到POD。
但是,在微服务架构里面。 都是POD和POD通过IP通讯,由注册中心提供服务发现的功能。

浙公网安备 33010602011771号