383 lines
8.2 KiB
Markdown
383 lines
8.2 KiB
Markdown
> 本文作者:丁辉
|
||
|
||
# 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. 先部署稳定版本(v1,9个副本)
|
||
2. 部署金丝雀版本(v2,1个副本)
|
||
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%,即完成更新
|
||
|