主题
Pod和Deployment管理
课程目标
通过本课程的学习,你将能够:
- 理解Pod的生命周期和状态转换
- 掌握Deployment的创建、更新、回滚和扩缩容
- 配置Pod健康检查(存活探针和就绪探针)
- 使用标签和选择器管理K8S资源
- 掌握Pod调度策略(节点亲和性、污点容忍等)
- 排查Pod和Deployment的常见故障
前置要求:已完成《K8S学习环境搭建与初体验》和《Kubernetes架构和核心概念》课程
1. 深入理解Pod
1.1 什么是Pod
Pod是Kubernetes中最小的部署单元,一个Pod可以包含一个或多个容器,这些容器:
- 共享网络命名空间(IP地址和端口空间)
- 共享存储卷(可以挂载相同的存储)
- 一起被调度和管理(生命周期相同)
为什么需要Pod?
- 紧密耦合的容器:如主应用+日志收集器(Sidecar模式)
- 资源共享:容器之间可以直接通过localhost通信
- 统一管理:一起创建、一起销毁
1.2 Pod的生命周期
Pod从创建到销毁会经历多个阶段:
创建 → Pending → Running → Succeeded/Failed → Terminating| 状态 | 说明 | 常见原因 |
|---|---|---|
| Pending | Pod已创建,等待调度或拉取镜像 | 镜像拉取中、资源不足、调度失败 |
| Running | Pod已调度到节点,容器正在运行 | 正常运行状态 |
| Succeeded | 所有容器成功完成(一次性任务) | Job执行完成 |
| Failed | 所有容器终止,至少一个失败 | 应用启动失败 |
| CrashLoopBackOff | 容器反复崩溃重启 | 应用错误、配置错误 |
| Unknown | 无法获取Pod状态 | 节点通信异常 |
状态转换图:
┌─────────────┐
│ Created │
└──────┬──────┘
│
▼
┌─────────────┐
┌─────────│ Pending │─────────┐
│ └──────┬──────┘ │
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Failed │ │ Running │ │Succeeded │
└──────────┘ └────┬─────┘ └──────────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│CrashLoop │ │Completed │ │ Terminat-│
│ BackOff │ │ │ │ ing │
└──────────┘ └──────────┘ └──────────┘1.3 创建和管理Pod
实战:创建第一个Pod
让我们创建一个简单的Nginx Pod:
yaml
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: my-app
environment: production
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi执行步骤:
bash
# 1. 创建Pod
kubectl apply -f pod.yaml
# 输出:pod/my-pod created
# 2. 查看Pod状态
kubectl get pods
# 输出示例:
# NAME READY STATUS RESTARTS AGE
# my-pod 1/1 Running 0 10s
# 3. 查看Pod详情(排查问题时使用)
kubectl describe pod my-pod
# 4. 查看Pod日志
kubectl logs my-pod
# 5. 进入Pod内部执行命令
kubectl exec -it my-pod -- /bin/bash
# 在容器内执行:
# ls /usr/share/nginx/html
# exit
# 6. 删除Pod
kubectl delete pod my-podPod管理常用命令速查:
| 命令 | 作用 |
|---|---|
kubectl get pods | 查看所有Pod |
kubectl get pods -o wide | 查看Pod详细信息(包括IP和节点) |
kubectl describe pod <name> | 查看Pod事件和详情 |
kubectl logs <name> | 查看Pod日志 |
kubectl logs <name> -f | 实时查看日志 |
kubectl exec -it <name> -- /bin/bash | 进入Pod容器 |
kubectl delete pod <name> | 删除Pod |
1.4 Pod的健康检查(探针)
Kubernetes提供两种探针来监控容器健康状态:
| 探针类型 | 作用 | 失败时的行为 |
|---|---|---|
| 存活探针(Liveness Probe) | 检测容器是否存活 | 重启容器 |
| 就绪探针(Readiness Probe) | 检测容器是否准备好接收流量 | 从Service端点移除 |
为什么需要探针?
- 存活探针:防止应用死锁但进程仍在运行的情况
- 就绪探针:防止流量发送到还未启动完成的容器
实战:配置健康检查
yaml
apiVersion: v1
kind: Pod
metadata:
name: health-check-demo
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
# 存活探针:检测容器是否存活
livenessProbe:
httpGet:
path: / # 访问根路径
port: 80
initialDelaySeconds: 30 # 容器启动30秒后开始检测
periodSeconds: 10 # 每10秒检测一次
timeoutSeconds: 5 # 超时时间5秒
failureThreshold: 3 # 连续失败3次才认为不健康
# 就绪探针:检测容器是否准备好接收流量
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5 # 容器启动5秒后开始检测
periodSeconds: 10
successThreshold: 1 # 连续成功1次就认为就绪探针配置参数详解:
| 参数 | 说明 | 默认值 |
|---|---|---|
initialDelaySeconds | 容器启动后首次检测的延迟时间 | 0 |
periodSeconds | 检测间隔时间 | 10 |
timeoutSeconds | 检测超时时间 | 1 |
successThreshold | 连续成功次数认为健康 | 1 |
failureThreshold | 连续失败次数认为不健康 | 3 |
三种探针检测方式
1. HTTP GET检测(最常用)
yaml
livenessProbe:
httpGet:
path: /health # 健康检查接口
port: 8080
httpHeaders: # 自定义请求头
- name: Custom-Header
value: Awesome2. TCP Socket检测
yaml
livenessProbe:
tcpSocket:
port: 3306 # 检测MySQL端口
initialDelaySeconds: 30
periodSeconds: 103. Exec命令检测
yaml
livenessProbe:
exec:
command:
- /bin/sh
- -c
- "cat /tmp/healthy" # 检查文件是否存在
initialDelaySeconds: 5
periodSeconds: 5实战:验证探针效果
bash
# 1. 创建带健康检查的Pod
kubectl apply -f health-check-demo.yaml
# 2. 查看Pod状态
kubectl get pod health-check-demo
# 3. 查看探针事件
kubectl describe pod health-check-demo | grep -A 5 Events
# 4. 模拟探针失败(进入容器删除健康检查文件)
kubectl exec -it health-check-demo -- rm /tmp/healthy
# 5. 观察容器重启
kubectl get pod health-check-demo -w
# 你会看到RESTARTS计数增加1.5 Pod的资源管理
资源单位详解
Kubernetes使用特定的单位来表示CPU和内存资源:
CPU资源:
1= 1个CPU核心1000m= 1000毫核 = 1核500m= 0.5核100m= 0.1核(适合轻量级应用)
内存资源:
Mi= Mebibytes(1024进制)Gi= GibibytesM= Megabytes(1000进制)G= Gigabytes
资源请求和限制
| 配置项 | 说明 | 作用 |
|---|---|---|
| requests | 资源请求 | 调度时保证分配的资源 |
| limits | 资源限制 | 容器能使用的最大资源 |
实战配置示例:
yaml
apiVersion: v1
kind: Pod
metadata:
name: resource-demo
spec:
containers:
- name: nginx
image: nginx:1.21
resources:
requests:
cpu: 100m # 请求0.1核CPU
memory: 256Mi # 请求256MB内存
limits:
cpu: 500m # 限制最多使用0.5核CPU
memory: 512Mi # 限制最多使用512MB内存requests vs limits的区别:
- requests:调度器用此值决定Pod放在哪个节点
- limits:运行时限制,容器不能超过这个值
- CPU超限时会被节流(throttle),内存超限时会被OOM Kill
QoS级别(服务质量等级)
Kubernetes根据资源配置将Pod分为三个QoS级别,用于资源紧张时的驱逐决策:
| QoS级别 | 条件 | 优先级 | 驱逐顺序 |
|---|---|---|---|
| Guaranteed | requests = limits,且只设置limits | 最高 | 最后被驱逐 |
| Burstable | requests < limits,或只设置requests | 中等 | 中等优先级 |
| BestEffort | 未设置requests和limits | 最低 | 首先被驱逐 |
查看Pod的QoS级别:
bash
kubectl get pod <pod-name> -o jsonpath='{.status.qosClass}'1.5 Pod的调度
节点选择器
使用节点标签和Pod的节点选择器控制Pod调度到特定节点。
bash
# 为节点添加标签
kubectl label node worker-1 app=frontend
# 查看节点标签
kubectl get nodes --show-labelsyaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
nodeSelector:
app: frontend
containers:
- name: nginx
image: nginx:1.21节点亲和性和反亲和性
- 节点亲和性:将Pod调度到满足条件的节点
- 节点反亲和性:避免将Pod调度到满足条件的节点
yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: app
operator: In
values:
- frontend
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: hardware-type
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx:1.21Pod亲和性和反亲和性
- Pod亲和性:将相关Pod调度到同一节点或区域
- Pod反亲和性:避免将相关Pod调度到同一节点或区域
yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- frontend
topologyKey: kubernetes.io/hostname
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- database
topologyKey: kubernetes.io/hostname
containers:
- name: nginx
image: nginx:1.21污点和容忍度
- 污点(Taints):节点上的标记,排斥Pod调度
- 容忍度(Tolerations):Pod上的标记,允许Pod调度到有污点的节点
bash
# 为节点添加污点
kubectl taint node worker-1 dedicated=special-user:NoSchedule
# 查看节点污点
kubectl describe node worker-1 | grep Taints
# 移除节点污点
kubectl taint node worker-1 dedicated=special-user:NoSchedule-yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "special-user"
effect: "NoSchedule"
containers:
- name: nginx
image: nginx:1.212. Deployment管理
2.1 创建和管理Deployment
Deployment是管理Pod副本的控制器,提供声明式更新、滚动更新和回滚功能。
创建Deployment
yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mibash
# 创建Deployment
kubectl apply -f deployment.yaml
# 查看Deployment状态
kubectl get deployments
# 查看Deployment详情
kubectl describe deployment nginx-deployment
# 查看Deployment创建的Pod
kubectl get pods -l app=nginx
# 查看Deployment的滚动更新状态
kubectl rollout status deployment nginx-deployment
# 删除Deployment
kubectl delete deployment nginx-deployment2.2 Deployment的更新策略
Deployment支持两种更新策略:
- 滚动更新(RollingUpdate):默认策略,逐步替换旧Pod
- 重建(Recreate):先删除所有旧Pod,再创建新Pod
配置更新策略
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80- maxSurge:更新过程中允许超出副本数的最大Pod数
- maxUnavailable:更新过程中允许不可用的最大Pod数
2.3 执行滚动更新
更新镜像版本
bash
# 更新镜像版本
kubectl set image deployment nginx-deployment nginx=nginx:1.22
# 查看更新状态
kubectl rollout status deployment nginx-deployment
# 查看更新历史
kubectl rollout history deployment nginx-deployment
# 查看特定版本的详情
kubectl rollout history deployment nginx-deployment --revision=2
# 回滚到之前版本
kubectl rollout undo deployment nginx-deployment
# 回滚到特定版本
kubectl rollout undo deployment nginx-deployment --to-revision=1使用kubectl edit更新
bash
# 编辑Deployment配置
kubectl edit deployment nginx-deployment
# 查看更新状态
kubectl rollout status deployment nginx-deployment2.4 Deployment的扩缩容
手动扩缩容
bash
# 扩缩容到5个副本
kubectl scale deployment nginx-deployment --replicas=5
# 查看状态
kubectl get deployment nginx-deployment
kubectl get pods -l app=nginx自动扩缩容
使用Horizontal Pod Autoscaler(HPA)根据资源使用情况自动扩缩容。
bash
# 安装Metrics Server(如果未安装)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 创建HPA
kubectl autoscale deployment nginx-deployment --min=3 --max=10 --cpu-percent=50
# 查看HPA状态
kubectl get hpa
# 查看Pod状态
kubectl get pods -l app=nginx2.5 Deployment的最佳实践
- 使用标签和选择器:合理使用标签管理资源
- 配置资源限制:为容器设置合理的资源请求和限制
- 健康检查:配置存活探针和就绪探针
- 更新策略:根据应用特性选择合适的更新策略
- 自动扩缩容:使用HPA实现自动扩缩容
- 滚动更新:使用滚动更新实现零停机部署
- 回滚机制:利用Deployment的回滚功能快速恢复故障
- 版本管理:使用不同的标签管理不同版本的应用
3. 标签和选择器
3.1 标签管理
标签是附加到Kubernetes资源上的键值对,用于组织和选择资源。
bash
# 为Pod添加标签
kubectl label pod my-pod environment=production tier=frontend
# 查看Pod标签
kubectl get pod my-pod --show-labels
# 更新Pod标签
kubectl label pod my-pod environment=staging --overwrite
# 删除Pod标签
kubectl label pod my-pod tier-
# 为所有Pod添加标签
kubectl label pods --all environment=production3.2 选择器使用
选择器用于根据标签选择资源。
bash
# 按标签选择Pod
kubectl get pods -l environment=production
# 按多个标签选择Pod
kubectl get pods -l environment=production,tier=frontend
# 按标签表达式选择Pod
kubectl get pods -l 'environment in (production, staging)'
# 按标签表达式选择Pod(不包含)
kubectl get pods -l 'environment notin (production)'
# 按标签存在性选择Pod
kubectl get pods -l 'environment'
# 按标签不存在性选择Pod
kubectl get pods -l '!environment'3.3 标签的最佳实践
- 一致性:使用一致的标签命名约定
- 语义化:标签应具有明确的语义
- 层次化:使用层次化的标签结构
- 标准化:建立组织内部的标签标准
- 自动化:在CI/CD流程中自动添加标签
推荐的标签
| 标签 | 描述 | 示例 |
|---|---|---|
| app.kubernetes.io/name | 应用名称 | nginx |
| app.kubernetes.io/instance | 应用实例 | nginx-production |
| app.kubernetes.io/version | 应用版本 | 1.21.0 |
| app.kubernetes.io/component | 应用组件 | frontend |
| app.kubernetes.io/part-of | 所属应用 | ecommerce |
| app.kubernetes.io/managed-by | 管理工具 | helm |
| environment | 环境 | production, staging, development |
| tier | 层级 | frontend, backend, database |
| release | 发布版本 | v1, v2 |
| team | 负责团队 | devops, frontend |
| region | 区域 | us-east, eu-west |
4. 实战案例:部署和管理应用
4.1 部署多副本应用
yaml
# app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app.kubernetes.io/name: my-app
app.kubernetes.io/instance: my-app-production
environment: production
tier: frontend
spec:
replicas: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2
maxUnavailable: 1
selector:
matchLabels:
app.kubernetes.io/name: my-app
app.kubernetes.io/instance: my-app-production
template:
metadata:
labels:
app.kubernetes.io/name: my-app
app.kubernetes.io/instance: my-app-production
environment: production
tier: frontend
spec:
containers:
- name: my-app
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- my-app
topologyKey: kubernetes.io/hostnamebash
# 部署应用
kubectl apply -f app-deployment.yaml
# 查看Deployment状态
kubectl get deployment my-app
# 查看Pod状态
kubectl get pods -l app.kubernetes.io/name=my-app
# 查看Pod分布
kubectl get pods -l app.kubernetes.io/name=my-app -o wide4.2 服务暴露
yaml
# app-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
selector:
app.kubernetes.io/name: my-app
app.kubernetes.io/instance: my-app-production
ports:
- port: 80
targetPort: 80
type: NodePortbash
# 创建Service
kubectl apply -f app-service.yaml
# 查看Service状态
kubectl get service my-app
# 获取Service的NodePort
NODE_PORT=$(kubectl get service my-app -o jsonpath='{.spec.ports[0].nodePort}')
# 访问应用
echo "应用访问地址: http://<node-ip>:$NODE_PORT"4.3 应用更新和回滚
bash
# 更新应用版本
kubectl set image deployment my-app my-app=nginx:1.22
# 查看更新状态
kubectl rollout status deployment my-app
# 查看更新历史
kubectl rollout history deployment my-app
# 回滚到之前版本
kubectl rollout undo deployment my-app
# 查看回滚状态
kubectl rollout status deployment my-app4.4 应用扩缩容
bash
# 手动扩缩容
kubectl scale deployment my-app --replicas=10
# 查看状态
kubectl get deployment my-app
kubectl get pods -l app.kubernetes.io/name=my-app
# 创建HPA
kubectl autoscale deployment my-app --min=5 --max=15 --cpu-percent=70
# 查看HPA状态
kubectl get hpa
# 查看Pod状态
kubectl get pods -l app.kubernetes.io/name=my-app5. 故障排查
5.1 Pod故障排查
bash
# 查看Pod状态
kubectl get pods
# 查看Pod详情
kubectl describe pod my-pod
# 查看Pod日志
kubectl logs my-pod
# 查看Pod的前一个容器日志
kubectl logs my-pod --previous
# 进入Pod执行命令
kubectl exec -it my-pod -- /bin/bash
# 查看Pod的事件
kubectl get events --field-selector involvedObject.name=my-pod5.2 Deployment故障排查
bash
# 查看Deployment状态
kubectl get deployment my-deployment
# 查看Deployment详情
kubectl describe deployment my-deployment
# 查看Deployment的Pod状态
kubectl get pods -l app=my-app
# 查看Deployment的滚动更新状态
kubectl rollout status deployment my-deployment
# 查看Deployment的更新历史
kubectl rollout history deployment my-deployment
# 回滚Deployment
kubectl rollout undo deployment my-deployment5.3 常见故障及解决方案
| 故障 | 症状 | 原因 | 解决方案 |
|---|---|---|---|
| Pod 处于 Pending 状态 | Pod 一直处于 Pending 状态 | 资源不足或调度失败 | 检查节点资源,调整资源请求或添加节点 |
| Pod 处于 CrashLoopBackOff 状态 | Pod 反复崩溃重启 | 应用错误或配置问题 | 查看Pod日志,修复应用错误 |
| Pod 处于 ImagePullBackOff 状态 | 无法拉取镜像 | 镜像不存在或网络问题 | 检查镜像名称和标签,检查网络连接 |
| Pod 处于 ErrImagePull 状态 | 拉取镜像失败 | 镜像不存在或权限问题 | 检查镜像名称和标签,检查镜像仓库权限 |
| Pod 处于 Terminating 状态 | Pod 无法正常终止 | 应用无法优雅退出 | 强制删除Pod:kubectl delete pod my-pod --grace-period=0 --force |
| Deployment 滚动更新失败 | 更新卡住或回滚 | 健康检查失败或资源不足 | 查看Pod日志,检查健康检查配置,调整更新策略 |
6. 课程总结
6.1 重点回顾
- Pod管理:掌握Pod的创建、监控和故障排查
- 健康检查:理解并配置存活探针和就绪探针
- 资源管理:为容器设置合理的资源请求和限制
- Pod调度:使用节点选择器、亲和性和反亲和性控制Pod调度
- Deployment管理:掌握Deployment的创建、更新和回滚
- 标签和选择器:使用标签和选择器组织和管理资源
- 故障排查:学会排查Pod和Deployment的常见故障
6.2 实践建议
- 动手实践:在本地或云平台上部署Kubernetes集群,实践Pod和Deployment管理
- 实验场景:模拟各种故障场景,练习故障排查
- 最佳实践:遵循Kubernetes的最佳实践,建立标准化的部署流程
- 自动化:使用CI/CD工具自动化应用部署和管理
- 监控:配置Prometheus和Grafana监控Pod和Deployment的状态
6.3 进阶学习
- StatefulSet:学习管理有状态应用
- DaemonSet:学习在每个节点上运行Pod
- Job和CronJob:学习管理批处理任务
- 自定义控制器:学习开发自定义Kubernetes控制器
- Operator模式:学习使用Operator模式管理复杂应用
通过本课程的学习,你已经掌握了Pod和Deployment的核心管理技能,可以在Kubernetes集群中高效地部署、管理和维护应用。