Files
Kubernetes/使用文档/Deployment的使用.md
offends 8a87b699ba
All checks were successful
continuous-integration/drone Build is passing
first commit
2025-12-13 18:06:23 +08:00

383 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

> 本文作者:丁辉
# Deployment的使用
[官方文档](https://kubernetes.io/zh-cn/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro/)
## 命令部署一个应用
```bash
kubectl create deployment nginx --image=nginx:alpine
```
## Yaml 部署一个 Deployment 应用
1. 部署应用(最小化 Yaml)
```yaml
cat <<EOF | kubectl apply -f -
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:alpine
ports:
- containerPort: 80
EOF
```
2. 验证
```bash
kubectl get deployments
```
## 更新和回滚
> Deployment 支持两种更新策略滚动更新RollingUpdate默认和删除式更新Recreate又称单批次更新
- ReCreate
**删除式更新Recreate**:更新时先删除所有运行中的 Pod待其彻底终止后创建新 ReplicaSet 及对应 Pod更新期间服务暂不可用。
```yaml
spec:
strategy:
type: Recreate
```
- RollingUpdate
**滚动更新RollingUpdate**:分批更新 Pod待一批更新后的 Pod 就绪后再更新下一批,实现服务不中断;更新过程中会存在新老版本应用共存的情况,不同客户端可能获取不同版本响应。
```yaml
spec:
strategy:
type: RollingUpdate
```
### 更新
1. 更新镜像
在这里,`deployment/nginx-deployment` 表明 Deployment 的名称,`nginx` 表明需要进行更新的容器, 而 `nginx:latest` 则表示镜像的新版本以及它的标签。
```bash
kubectl set image deployment/nginx-deployment nginx=nginx:latest
```
2. 查看进度
```bash
kubectl rollout status deployment/nginx-deployment
```
3. 查看状态
```bash
kubectl get rs
```
### 回滚
1. 查看 Deployment 修订历史
```bash
kubectl rollout history deployment/nginx-deployment
```
设置 `CHANGE-CAUSE` 消息
```bash
kubectl annotate deployment/nginx-deployment kubernetes.io/change-cause="image updated to latest"
```
2. 查看修订历史的详细信息
```bash
kubectl rollout history deployment/nginx-deployment --revision=2
```
3. 回滚
```bash
kubectl rollout undo deployment/nginx-deployment
```
或回滚到特定版本
```bash
kubectl rollout undo deployment/nginx-deployment --to-revision=2
```
### 重启
```bash
kubectl rollout restart deployment deployment/nginx-deployment
```
### 副本数调整
```bash
kubectl scale deployment/nginx-deployment --replicas=3
```
## 暂停、恢复 Deployment 的上线过程
1. 暂停上线
```bash
kubectl rollout pause deployment/nginx-deployment
```
2. 更新 Deployment 镜像
```bash
kubectl set image deployment/nginx-deployment nginx=nginx:latest
```
你可以根据需要执行很多更新操作,例如,可以要使用的资源
```bash
kubectl set resources deployment/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
```
3. 最终,恢复 Deployment 上线并观察新的 ReplicaSet 的创建过程,其中包含了所应用的所有更新
```bash
kubectl rollout resume deployment/nginx-deployment
```
4. 监视上线的状态,直到完成
```bash
watch kubectl get rs
```
## 更新失败标记为 **"Failed"** 状态
```bash
kubectl patch deployment/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'
```
`progressDeadlineSeconds`
- **作用**: 定义 Deployment 滚动更新Rolling Update的最大允许时间
- **值 600**: 表示 600 秒1 分钟)
- **默认值**: 通常为 600 秒,但显式设置可确保明确性
- **工作逻辑**:
1. 当 Deployment 开始更新(如镜像版本升级)时启动计时
2. 如果更新过程超过 600 秒仍未完成
3. Kubernetes 会将 Deployment 标记为 **"Failed"** 状态
4. 并自动回滚到之前的稳定版本(如果配置了回滚策略)
## 配置 ReplicaSet 清理策略
你可以在 Deployment 中设置 `.spec.revisionHistoryLimit` 字段以指定保留此 Deployment 的多少个旧有 ReplicaSet。其余的 ReplicaSet 将在后台被垃圾回收。 默认情况下,此值为 10。
```bash
kubectl patch deployment/nginx-deployment -p '{"spec":{"revisionHistoryLimit":10}}'
```
## 金丝雀部署
[官方文档](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/#canary-deployment)
### 通过副本数控制
**操作步骤:**
1. 先部署稳定版本v19个副本
2. 部署金丝雀版本v21个副本
3. Service会自动将约9%的流量1/10导向v2
4. 观察监控如果v2正常逐步增加v2副本数减少v1副本数
1. 部署 Pod-1
```yaml
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-1
labels:
app: nginx
spec:
replicas: 9
strategy:
type: RollingUpdate
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
version: v1
spec:
containers:
- name: nginx
image: registry.cn-hangzhou.aliyuncs.com/offends/demo:nginx-alpine-v1
ports:
- containerPort: 80
EOF
```
2. 部署 Pod-2
```yaml
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-2
labels:
app: nginx
spec:
replicas: 1
strategy:
type: RollingUpdate
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
version: v2
spec:
containers:
- name: nginx
image: registry.cn-hangzhou.aliyuncs.com/offends/demo:nginx-alpine-v2
ports:
- containerPort: 80
EOF
```
3. 部署 Service同时选择v1和v2的Pod
```yaml
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: nginx-deployment-service
spec:
selector:
app: nginx # 同时选择两个版本的Pod
ports:
- port: 80
targetPort: 80
EOF
```
4. 修改权重将流量导向 v2
- 增加 v2
```bash
kubectl scale deployment/nginx-deployment-2 --replicas=10
```
- 降低 v1
```bash
kubectl scale deployment/nginx-deployment-1 --replicas=0
```
### 通过 Ingress 实现基于权重的金丝雀
方法类似于前者,只是对象从副本数变换为 Ingress控制
1. 创建两个 Service
```bash
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: nginx-deployment-service-1
spec:
selector:
app: nginx
version: v1
ports:
- port: 80
targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-deployment-service-2
spec:
selector:
app: nginx
version: v2
ports:
- port: 80
targetPort: 80
EOF
```
2. 创建 Ingress 资源
```yaml
cat <<EOF | kubectl apply -f -
# 金丝雀 Ingress 对象为 v1 版本
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress-1
spec:
rules:
- host: demo.offends.cn
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-deployment-service-1
port:
number: 80
---
# 金丝雀 Ingress 对象为 v2 版本
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress-2
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10" # 10%流量到金丝雀
spec:
rules:
- host: demo.offends.cn
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-deployment-service-2
port:
number: 80
EOF
```
3. 慢慢调整 nginx-ingress-2 流量到 100%,即完成更新