工作负载控制器是什么?

kubernetes 工作负载

工作负载控制器 Work Controllers 是 k8s 的一个抽象概念,用于更高级层次对象,部署和管理 Pod。

常用工作负载控制器:

  • Deployment 无状态应用部署
  • StatefulSet 有状态应用部署
  • DaemonSet 确保所有 node 运行同一个 Pod
  • Job 一次性任务
  • Cronjob 定时任务

控制器的作用:

  • 管理 Pod 对象
  • 使用标签与 Pod 关联
  • 控制器实现了 Pod 的运维,例如滚动更新、伸缩、副本管理、维护 Pod 状态等。

kubernetes 工作负载控制器(一):Deployment

Deployment

1.Deployment 控制器介绍

Deployment 的功能

  • 管理 Pod 和 ReplicaSet
  • 具有上线部署、副本设定、滚动升级、回滚等功能
  • 提供声明式更新,例如只更新一个新的 Image

Deployment 应用场景:网站、API、微服务

什么是 ReplicaSet 控制器?

ReplicaSet 控制器用途:

  • Pod 维护副本数量管理,不断对比当前 Pod 数量与期望 Pod 数量
  • Deployment 每次发布都会创建一个 RS 作为记录,用于实现回滚
1
2
3
4
5
6
7
8
9
# 查看 RS 记录
$ kubectl get replicasets
NAME DESIRED CURRENT READY AGE
nfs-client-provisioner-58c9577d89 1 1 1 5d2h
# 或者
$ kubectl get rs

# 查看 replicaset 详细信息
$ kubectl describe rs

2.Deployment 控制器部署

部署方式1:编排yaml(推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
cat >  deployment-test.yaml << EOF 
apiVersion: apps/v1
kind: Deployment
metadata:
name: web1
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: web1
template:
metadata:
labels:
app: web1
spec:
restartPolicy: Always
containers:
- name: web1
image: nginx:1.16.1
imagePullPolicy: Always
ports:
- containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
name: web1
labels:
app: web1
spec:
type: NodePort
selector:
app: web1
ports:
- port: 80
protocol: TCP
targetPort: 80
nodePort: 30011
EOF

部署yaml

1
$ kubectl apply -f deployment.yaml

部署方式2:命令行创建

1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建deployment
$ kubectl create deployment ${DEPLOYMENT_NAME} --image=${IMAGE_NAME}

# 绑定service
$ kubectl expose deployment ${DEPLOYMENT_NAME} --port=80 --target-port=80 --type=NodePort
# 查看 deployment 的详细信息:

$ kubectl describe deployment ${DEPLOYMENT_NAME}
# 删除

$ kubectl delete deploy <DEPLOYMENT_NAME> # 删除 deployment
$ kubectl delete svc <SERVICE_NAME> # 删除 service
$ kubectl delete -f . # 删除当前目前下所有yaml文件配置的资源

3.Deployment 特性:滚动更新与回滚

滚动升级:k8s对 Pod 升级的默认策略,通过使用新版本 Pod 逐步更新旧版本 Pod,实现零停机发布,用户无感知。

瀑布式升级:即停服一次性升级全部

K8S 更新 Pod 镜像的三种方式

1
2
3
4
5
6
7
8
9
# 1.修改 deployment .yaml文件
$ kubectl apply -f deploy.yaml --record
# --record 的作用是将当前命令记录到 revision 记录中

# 2.命令行 set image
$ kubectl set image deployment/${DEPLOYMENT_NAME} ${CONTAINER_NAME}=${NEW_IMAGE_NAME}

# 3.edit deployment 在线编译deployment控制器yaml
$ kubectl edit deployment <DEPLOYMENT_NAME>

滚动更新策略

  • maxSurge 滚动更新过程中最大 Pod 副本数,确保在更新时启动的 Pod 数量比期望(replicas) Pod 数量最大多出 25%(默认)
  • maxUnavailable 滚动更新过程中最大不可用 Pod 副本数,确保在更新时最大 25%(默认) Pod数量不可用,即确保 75% Pod 数量是可用状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 导出 deployment.yaml 查看默认的滚动升级字段规则
$ kubectl get deployment web -o yaml > deployment.yaml

# 编排 yaml
cat > deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 3
revisionHistoryLimit: 10 # 默认值10,RS历史版本保留数量
selector:
matchLabels:
app: web
strategy:
rollingUpdate:
maxSurge: 25% # 滚动更新过程中最大 ``Pod`` 副本数
maxUnavailable: 25% # 滚动更新过程中最大不可用 ``Pod`` 副本数
type: RollingUpdate # 类型:滚动升级
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx
EOF

回滚
k8s自带的回滚功能是重新部署某一次部署时的状态,即当时版本所有配置。

1
2
3
$ kubectl rollout history deployment/web                # 查看历史发布版本
$ kubectl rollout undo deployment/web # 回滚上一个版本
$ kubectl rollout undo deployment/web --to-revision=2 # 回滚指定历史版本

4.Deployment 特性:scale 水平扩容/缩容

kubectl scale 用于横向扩容或缩容 Deployment, ReplicaSet, Replication Controller 或 Job 中 Pod 数量。

scale 可以指定多个前提条件,如:当前副本数量 –current-replicas 或资源版本 –resource-version,进行伸缩比例设置前,系统会先验证前提条件是否成立。

1
2
3
4
5
6
7
8
# 设置某个 ${dp_name} 的 pod 数量为3
$ kubectl scale --replicas=3 deploy/${dp_name}

# 由 .yaml 中的控制器对象来设置其副本数量
$ kubectl scale --replicas=3 -f foo.yaml

# 如果当前副本数是2,则扩容到3
$ kubectl scale --current-replicas=2 --replicas=3 deployment/mysql

参考资料