Deployment - 应用部署
Deployment - 应用部署
为什么需要 Deployment
在上一章我们学习了 Pod,但实际生产中很少直接创建 Pod,而是使用 Deployment。
Pod 的问题
直接创建 Pod 存在这些问题:
- Pod 删除后不会自动重建
- 无法方便地扩缩容
- 更新应用需要手动操作
- 无法实现滚动更新和回滚
Deployment 的优势
Deployment 提供了声明式的更新机制:
- 自动恢复:Pod 失败自动重建
- 扩缩容:轻松调整副本数量
- 滚动更新:零停机更新应用
- 版本回滚:出问题立即回退
- 暂停/恢复:分批更新控制
创建 Deployment
基础示例
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
应用配置:
kubectl apply -f deployment.yaml
# 查看 Deployment
kubectl get deployments
# 查看 Pod
kubectl get pods
字段说明
replicas:期望的 Pod 副本数
selector:选择器,用于匹配 Pod
template:Pod 模板,定义 Pod 的配置
管理 Deployment
查看状态
# 查看 Deployment
kubectl get deployment nginx-deployment
# 输出
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 2m
# 详细信息
kubectl describe deployment nginx-deployment
# 查看事件
kubectl get events --sort-by=.metadata.creationTimestamp
字段含义:
- READY:就绪的 Pod 数量 / 期望数量
- UP-TO-DATE:已更新到最新版本的 Pod 数量
- AVAILABLE:可用的 Pod 数量
扩缩容
# 扩容到 5 个副本
kubectl scale deployment nginx-deployment --replicas=5
# 缩容到 2 个副本
kubectl scale deployment nginx-deployment --replicas=2
# 查看效果
kubectl get pods -w
也可以修改 YAML 文件的 replicas 字段后重新 apply。
更新应用
方法一:修改镜像
# 更新镜像版本
kubectl set image deployment/nginx-deployment nginx=nginx:1.22
# 查看滚动更新状态
kubectl rollout status deployment/nginx-deployment
# 输出
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out
方法二:修改 YAML
spec:
containers:
- name: nginx
image: nginx:1.22 # 修改版本
kubectl apply -f deployment.yaml
滚动更新策略
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2 # 最多可以超出期望数量的 Pod 数
maxUnavailable: 1 # 最多不可用的 Pod 数
template:
# ...
更新过程:
- 创建新版本 Pod(不超过 maxSurge)
- 等待新 Pod 就绪
- 删除旧版本 Pod(不超过 maxUnavailable)
- 重复 1-3 直到所有 Pod 更新完成
回滚
# 查看历史版本
kubectl rollout history deployment/nginx-deployment
# 输出
REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image deployment/nginx-deployment nginx=nginx:1.22
3 kubectl set image deployment/nginx-deployment nginx=nginx:1.23
# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment
# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2
# 查看回滚状态
kubectl rollout status deployment/nginx-deployment
暂停和恢复
暂停更新可以避免频繁更新触发多次滚动更新。
# 暂停更新
kubectl rollout pause deployment/nginx-deployment
# 进行多次修改
kubectl set image deployment/nginx-deployment nginx=nginx:1.22
kubectl set resources deployment/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
# 恢复更新(一次性滚动更新)
kubectl rollout resume deployment/nginx-deployment
资源配置
CPU 和内存限制
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: app
image: myapp:v1
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
- requests:Pod 调度时保证的资源
- limits:Pod 运行时的最大资源
环境变量
spec:
containers:
- name: app
image: myapp:v1
env:
- name: DATABASE_HOST
value: "mysql.example.com"
- name: DATABASE_PORT
value: "3306"
- name: APP_ENV
value: "production"
健康检查
spec:
containers:
- name: app
image: myapp:v1
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 3
ReplicaSet
Deployment 内部使用 ReplicaSet 来管理 Pod。
# 查看 ReplicaSet
kubectl get replicaset
# 输出
NAME DESIRED CURRENT READY AGE
nginx-deployment-5d59d67564 3 3 3 5m
关系链:
Deployment → ReplicaSet → Pod
每次更新会创建新的 ReplicaSet,旧的 ReplicaSet 会保留(副本数为 0),用于回滚。
完整示例
部署一个 Web 应用
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
labels:
app: webapp
spec:
replicas: 3
selector:
matchLabels:
app: webapp
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: webapp
version: v1
spec:
containers:
- name: webapp
image: nginx:1.21
ports:
- containerPort: 80
name: http
env:
- name: APP_ENV
value: "production"
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
操作流程
# 1. 部署应用
kubectl apply -f webapp-deployment.yaml
# 2. 查看状态
kubectl get deployment webapp
kubectl get pods -l app=webapp
# 3. 扩容
kubectl scale deployment webapp --replicas=5
# 4. 更新版本
kubectl set image deployment/webapp webapp=nginx:1.22
# 5. 监控更新过程
kubectl rollout status deployment/webapp
# 6. 查看历史
kubectl rollout history deployment/webapp
# 7. 回滚(如果需要)
kubectl rollout undo deployment/webapp
常用命令总结
# 创建
kubectl create deployment nginx --image=nginx
kubectl apply -f deployment.yaml
# 查看
kubectl get deployments
kubectl describe deployment <name>
kubectl get pods -l app=<label>
# 扩缩容
kubectl scale deployment <name> --replicas=<count>
# 更新
kubectl set image deployment/<name> <container>=<image>
kubectl apply -f deployment.yaml
# 回滚
kubectl rollout history deployment/<name>
kubectl rollout undo deployment/<name>
kubectl rollout undo deployment/<name> --to-revision=<n>
# 滚动更新控制
kubectl rollout status deployment/<name>
kubectl rollout pause deployment/<name>
kubectl rollout resume deployment/<name>
# 删除
kubectl delete deployment <name>
最佳实践
1. 始终声明资源限制
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
2. 配置健康检查
livenessProbe:
httpGet:
path: /healthz
port: 8080
readinessProbe:
httpGet:
path: /ready
port: 8080
3. 使用标签管理
metadata:
labels:
app: myapp
env: prod
version: v1.2.3
4. 记录更新原因
kubectl apply -f deployment.yaml --record
5. 合理设置副本数
- 开发环境:1-2 个
- 测试环境:2-3 个
- 生产环境:3+ 个(根据负载调整)
小结
Deployment 是 Kubernetes 中最常用的工作负载资源:
- 声明式:描述期望状态,系统自动实现
- 自动恢复:Pod 失败自动重建
- 扩缩容:轻松调整副本数量
- 滚动更新:零停机更新应用
- 版本管理:支持回滚到任意版本
下一章我们将学习如何通过 Service 暴露应用。