Deployment
概述
Deployment是Kubernetes中用于管理无状态应用的核心对象。它提供了Pod和ReplicaSet的声明式更新,支持滚动更新、回滚、扩缩容等功能。
Deployment核心功能
1. 副本管理
- 确保指定数量的Pod副本运行
- 自动替换失败的Pod
- 支持水平扩缩容
2. 滚动更新
- 零停机更新应用
- 控制更新速度和顺序
- 支持暂停和恢复更新
3. 版本回滚
- 回滚到历史版本
- 查看更新历史
- 手动控制回滚
4. 健康检查
- 集成Pod探针
- 自动健康检查
- 失败Pod自动替换
Deployment配置详解
基本Deployment配置
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
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:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"完整Deployment配置
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-deployment
namespace: production
annotations:
deployment.kubernetes.io/revision: "1"
spec:
replicas: 5
revisionHistoryLimit: 10
progressDeadlineSeconds: 600
minReadySeconds: 30
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
selector:
matchLabels:
app: web
tier: frontend
template:
metadata:
labels:
app: web
tier: frontend
annotations:
sidecar.istio.io/inject: "false"
spec:
serviceAccountName: web-service-account
containers:
- name: web
image: nginx:1.21
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
env:
- name: ENVIRONMENT
value: "production"
- name: LOG_LEVEL
value: "INFO"
envFrom:
- configMapRef:
name: web-config
- secretRef:
name: web-secrets
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
startupProbe:
httpGet:
path: /startup
port: 80
failureThreshold: 30
periodSeconds: 10
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/conf.d
- name: logs-volume
mountPath: /var/log/nginx
volumes:
- name: config-volume
configMap:
name: nginx-config
- name: logs-volume
emptyDir: {}
nodeSelector:
disktype: ssd
tolerations:
- key: "dedicated"
operator: "Equal"
value: "web"
effect: "NoSchedule"
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: kubernetes.io/hostname更新策略
1. 滚动更新(RollingUpdate)
yaml
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%参数说明:
maxSurge: 更新过程中可以超过期望副本数的最大Pod数量(可以是具体数字或百分比)maxUnavailable: 更新过程中不可用的Pod的最大数量(可以是具体数字或百分比)
2. 重建更新(Recreate)
yaml
strategy:
type: Recreate特点:
- 先删除所有旧Pod
- 然后创建新Pod
- 会有短暂的服务中断
操作命令
创建Deployment
bash
# 从YAML文件创建
kubectl apply -f deployment.yaml
# 直接创建
kubectl create deployment nginx --image=nginx:1.21 --replicas=3查看Deployment
bash
# 查看所有Deployment
kubectl get deployments
kubectl get deploy
# 查看详细信息
kubectl describe deployment <deployment-name>
# 查看YAML格式
kubectl get deployment <deployment-name> -o yaml
# 查看JSON格式
kubectl get deployment <deployment-name> -o json扩缩容
bash
# 扩展副本数
kubectl scale deployment nginx --replicas=5
# 自动扩缩容(需要Metrics Server)
kubectl autoscale deployment nginx --min=3 --max=10 --cpu-percent=80更新Deployment
bash
# 更新镜像
kubectl set image deployment/nginx-deployment nginx=nginx:1.22
# 更新环境变量
kubectl set env deployment/nginx-deployment ENVIRONMENT=production
# 更新资源限制
kubectl set resources deployment/nginx-deployment -c nginx --limits=cpu=500m,memory=256Mi查看更新状态
bash
# 查看更新状态
kubectl rollout status deployment/nginx-deployment
# 查看更新历史
kubectl rollout history deployment/nginx-deployment
# 查看特定版本详情
kubectl rollout history deployment/nginx-deployment --revision=2回滚操作
bash
# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment
# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2暂停和恢复更新
bash
# 暂停更新
kubectl rollout pause deployment/nginx-deployment
# 恢复更新
kubectl rollout resume deployment/nginx-deployment删除Deployment
bash
# 删除Deployment(保留Pod)
kubectl delete deployment nginx-deployment
# 删除Deployment及其所有Pod
kubectl delete deployment nginx-deployment --cascade=foreground
# 删除Deployment但不删除Pod
kubectl delete deployment nginx-deployment --cascade=orphan实践示例
示例1:Web应用Deployment
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web
environment: production
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.21
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"示例2:API服务Deployment
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-service
labels:
app: api
tier: backend
spec:
replicas: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: myapi:v1.2.0
ports:
- containerPort: 8080
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-secret
key: url
- name: REDIS_HOST
value: "redis-service"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/ready
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
resources:
requests:
memory: "256Mi"
cpu: "500m"
limits:
memory: "512Mi"
cpu: "1000m"示例3:Worker服务Deployment
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: worker-service
labels:
app: worker
tier: backend
spec:
replicas: 2
strategy:
type: Recreate
selector:
matchLabels:
app: worker
template:
metadata:
labels:
app: worker
spec:
containers:
- name: worker
image: worker:v1.0.0
command: ["python", "worker.py"]
args: ["--queue", "default"]
env:
- name: REDIS_URL
value: "redis://redis-service:6379"
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-secret
key: url
resources:
requests:
memory: "512Mi"
cpu: "1000m"
limits:
memory: "1Gi"
cpu: "2000m"
volumeMounts:
- name: config
mountPath: /app/config
volumes:
- name: config
configMap:
name: worker-config高级部署策略
1. 金丝雀发布
详细配置
yaml
# canary-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-canary
labels:
app: web
version: canary
spec:
replicas: 1 # 小比例的金丝雀实例
selector:
matchLabels:
app: web
version: canary
template:
metadata:
labels:
app: web
version: canary
spec:
containers:
- name: web
image: web-app:v2.0.0 # 新版本
ports:
- containerPort: 80
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"流量控制
yaml
# canary-service.yaml
apiVersion: v1
kind: Service
metadata:
name: web-app
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
type: LoadBalancer通过Ingress控制流量
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10" # 10%流量到金丝雀版本
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-canary
port:
number: 802. 蓝绿部署
蓝色版本
yaml
# blue-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-blue
spec:
replicas: 3
selector:
matchLabels:
app: web
version: blue
template:
metadata:
labels:
app: web
version: blue
spec:
containers:
- name: web
image: web-app:v1.0.0 # 旧版本
ports:
- containerPort: 80绿色版本
yaml
# green-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-green
spec:
replicas: 3
selector:
matchLabels:
app: web
version: green
template:
metadata:
labels:
app: web
version: green
spec:
containers:
- name: web
image: web-app:v2.0.0 # 新版本
ports:
- containerPort: 80切换流量
bash
# 切换到绿色版本
kubectl patch service web-app -p '{"spec":{"selector":{"app":"web","version":"green"}}}'
# 如果出现问题,回滚到蓝色版本
kubectl patch service web-app -p '{"spec":{"selector":{"app":"web","version":"blue"}}}'3. A/B测试
基于用户特性的路由
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "X-User-Group"
nginx.ingress.kubernetes.io/canary-by-header-value: "beta"
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-beta
port:
number: 804. 灰度发布策略
基于百分比的流量分配
yaml
# 使用Istio进行更精细的流量控制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: web-app
spec:
hosts:
- web-app
http:
- route:
- destination:
host: web-app-v1
weight: 90 # 90%流量到v1
- destination:
host: web-app-v2
weight: 10 # 10%流量到v23. 自动扩缩容(HPA)
yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80故障排查
常见问题
1. Deployment无法更新
bash
# 查看Deployment事件
kubectl describe deployment <deployment-name>
# 查看Pod事件
kubectl get pods --selector=app=<app-name>
# 检查镜像拉取
kubectl describe pod <pod-name>2. Pod无法启动
bash
# 查看Pod日志
kubectl logs <pod-name>
# 查看容器退出码
kubectl describe pod <pod-name>
# 检查资源配额
kubectl describe resourcequota3. 滚动更新卡住
bash
# 查看更新状态
kubectl rollout status deployment/<deployment-name>
# 查看ReplicaSet
kubectl get replicasets
# 暂停并恢复更新
kubectl rollout pause deployment/<deployment-name>
# 修复问题后
kubectl rollout resume deployment/<deployment-name>健康检查最佳实践
1. 探针类型和配置
存活探针(Liveness Probe)
- 目的:检测容器是否需要重启
- 配置示例:
yaml
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 60 # 应用启动时间
periodSeconds: 10 # 检查间隔
timeoutSeconds: 5 # 超时时间
successThreshold: 1 # 成功阈值
failureThreshold: 3 # 失败阈值就绪探针(Readiness Probe)
- 目的:检测容器是否可以接收流量
- 配置示例:
yaml
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 10 # 就绪检查延迟
periodSeconds: 5 # 检查间隔
timeoutSeconds: 3 # 超时时间
successThreshold: 1 # 成功阈值
failureThreshold: 3 # 失败阈值启动探针(Startup Probe)
- 目的:处理启动时间长的应用
- 配置示例:
yaml
startupProbe:
httpGet:
path: /startup
port: 8080
failureThreshold: 30 # 启动尝试次数
periodSeconds: 10 # 检查间隔2. 探针实现方式
HTTP探针
- 优点:实现简单,直接检查应用状态
- 适用场景:Web应用、API服务
- 示例:
yaml
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
httpHeaders:
- name: Custom-Header
value: Health-Check命令探针
- 优点:灵活性高,可以执行任意命令
- 适用场景:非HTTP应用、后台服务
- 示例:
yaml
livenessProbe:
exec:
command:
- cat
- /tmp/healthyTCP探针
- 优点:检查网络连接,适用于任何TCP服务
- 适用场景:数据库、缓存服务
- 示例:
yaml
livenessProbe:
tcpSocket:
port: 33063. 健康检查最佳实践
根据应用特性配置:
- Web应用:使用HTTP探针
- 数据库:使用TCP探针
- 后台服务:使用命令探针
合理设置参数:
initialDelaySeconds:根据应用启动时间设置periodSeconds:平衡检查频率和系统负载timeoutSeconds:避免检查超时影响应用failureThreshold:允许短暂的故障
实现健康检查端点:
- 提供专门的健康检查端点
- 检查应用依赖(数据库、缓存等)
- 返回合适的HTTP状态码
监控健康状态:
- 监控探针失败事件
- 设置告警机制
- 分析重启原因
渐进式部署:
- 使用就绪探针控制流量接入
- 确保新Pod就绪后再移除旧Pod
- 避免滚动更新过程中的服务中断
4. 常见健康检查问题
问题1:探针过于敏感
症状:Pod频繁重启,影响服务稳定性 解决方案:
- 增加
failureThreshold值 - 调整
periodSeconds间隔 - 优化健康检查逻辑
问题2:探针设置不足
症状:不健康的Pod仍在接收流量 解决方案:
- 配置就绪探针
- 确保探针能检测出真实的健康状态
- 定期测试探针有效性
问题3:启动时间过长
症状:Pod在启动过程中被重启 解决方案:
- 使用启动探针
- 增加
initialDelaySeconds - 优化应用启动时间
部署最佳实践
1. 标签管理
- 使用有意义的标签:便于资源管理和查询
- 标准化标签:使用推荐的标签规范
- 标签一致性:保持标签在整个应用中的一致性
- 使用标签选择器:精确选择目标资源
2. 资源管理
- 设置资源请求和限制:根据应用实际需求配置
- 监控资源使用:定期检查资源使用情况
- 使用自动扩缩容:根据负载自动调整副本数
- 资源配额:在命名空间级别限制资源使用
3. 更新策略
- 生产环境:使用滚动更新,零停机部署
- 测试环境:可以使用重建更新
- 合理配置参数:根据应用特性设置
maxSurge和maxUnavailable - 暂停和恢复:复杂更新时使用暂停功能
4. 版本控制
- 保留更新历史:设置合理的
revisionHistoryLimit - 使用有意义的镜像标签:避免使用
latest标签 - 记录更新说明:使用annotations记录更新内容
- 定期清理历史版本:避免过多的历史记录
5. 安全配置
- 使用非root用户:以非特权用户运行容器
- 限制权限:使用最小权限原则
- 只读文件系统:配置容器使用只读根文件系统
- 安全上下文:设置适当的安全上下文
- 镜像安全:使用官方镜像,定期更新
6. 监控和日志
- 配置日志收集:使用Sidecar容器或日志驱动
- 暴露指标:实现应用指标的采集
- 健康检查端点:提供应用健康状态
- 事件监控:关注Deployment相关事件
7. 故障排查
- 日志分析:检查容器日志
- 事件查看:分析Deployment事件
- 资源监控:检查资源使用情况
- 网络诊断:测试网络连通性
- 配置验证:检查Deployment配置是否正确
总结
Deployment是Kubernetes中管理无状态应用的核心对象,通过本章的学习,您已经掌握了:
核心功能
基本功能:
- 副本管理和自动扩缩容
- 滚动更新和版本回滚
- 健康检查和故障自动修复
- 声明式配置管理
高级部署策略:
- 金丝雀发布:小比例流量测试新版本
- 蓝绿部署:无停机切换版本
- A/B测试:基于用户特性的流量路由
- 灰度发布:渐进式流量迁移
健康检查:
- 探针类型:存活探针、就绪探针、启动探针
- 实现方式:HTTP探针、命令探针、TCP探针
- 最佳实践:根据应用特性配置合适的探针
- 常见问题:探针敏感度、启动时间、健康检查逻辑
部署最佳实践:
- 标签管理和资源配置
- 更新策略和版本控制
- 安全配置和监控日志
- 故障排查和问题解决
Deployment提供了一套完整的无状态应用管理解决方案,支持从开发到生产的全生命周期管理。通过合理配置Deployment,您可以实现零停机部署、自动故障恢复、弹性扩缩容等高级功能,构建更加可靠、高效的容器化应用。
掌握Deployment的使用是Kubernetes学习的重要一步,它为您提供了构建现代化、弹性、高可用应用的基础能力。