Kubernetes工作负载
工作负载控制器是什么
工作负载控制器(Workload Controllers)是K8s的一个抽象概念,用于更高级层次对象,部署和管理Pod。
常用工作负载控制器:
Deployment:无状态应用部署
StatefulSet:有状态应用部署
DaemonSet:确保所有Node运行同一个Pod
Job:一次性任务
Cronjob:定时任务
控制器的作用:
- 管理Pod对象
- 使用标签与Pod关联
- 控制器实现了Pod的运维,例如滚动更新、伸缩、副本管理、维护Pod状态等
Deployment详解
Deployment的功能:
管理Pod和ReplicaSet
- 具有上线部署、副本设定、滚动升级、回滚等功能
- 提供声明式更新,例如只更新一个新的Image
应用场景:网站、API、微服务
Deployment:部署
第一步:部署镜像
- kubectl apply -f xxx.yaml
- kubectl create deployment web --image=nginx:1.15
[root@master ~]# cat test.yaml
---
apiVersion: apps/v1 // api版本
kind: Deployment // 类型
metadata:
name: syb // 容器名字
namespace: default // 默认名称空间
spec:
replicas: 3 // 复制成3个容器
selector:
matchLabels:
app: busybox // 标签
template:
metadata:
labels:
app: busybox // 标签
spec:
containers:
- name: b1
image: busybox // 使用镜像busybox
command: ["/bin/sh","-c","sleep 9000"] // 一直运行
[root@master ~]# kubectl apply -f test.yaml
deployment.apps/syb created
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
syb-864fd4fb54-45j9h 1/1 Running 0 75s
syb-864fd4fb54-89kt4 1/1 Running 0 75s
syb-864fd4fb54-5k96l 0/1 ContainerCreating 0 75s
Deployment:滚动升级
第二步:应用升级(更新镜像三种方式)
- kubectl apply -f xxx.yaml
- kubectl set image deployment/web nginx=nignx:1.16
- kubectl edit deployment/web
滚动升级:K8s对Pod升级的默认策略,通过使用新版本Pod逐步更新旧版本Pod,实现停机发布,用户无感知。
滚动升级在K8s中的实现:
- 1个Deployment
- 2个ReplicaSet
滚动更新策略:
spec:
replicas: 3
revisionHistoryLimit: 10 # RS历史版本保存数量
selector:
matchLabels:
app: web
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavaliable: 25%
type: RollingUpdate
- maxSurge:滚动更新过程中最大Pod副本数,确保在更新时启动的Pod数量比期望(replicsa)Pod数量最大多出25%
- maxUnavailable:滚动更新过程中最大不可用Pod副本数,确保在更新时最大25%Pod数量不可用,即确保75%Pod数量是可用状态
实例
// 本地有镜像
[root@master ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
syblyw0806/httpd latest f61bb05k1b9a 11 days ago 92.3MB
// 创建四个httpd容器。名字都叫web
[root@master ~]# cat test2.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 4
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: syblyw0806/httpd:latest
imagePullPolicy: IfNotPresent
[root@master ~]# kubectl apply -f test2.yaml
deployment.apps/web created
[root@master ~]# kubectl get pods
web-5d688b9745-7gx4g 1/1 Running 0 100s
web-5d688b9745-9hnxz 1/1 Running 0 100s
web-5d688b9745-ft6w9 1/1 Running 0 100s
web-5d688b9745-vmcbv 1/1 Running 0 100s
// 再次编写test2.yaml文件,设置maxSurge、maxUnavaliable
[root@master ~]# cat test2.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 4
strategy: // 策略
rollingUpdate: // 滚动更新
maxSurge: 25% // 最大可超出25% #这两个参数可以一起使用也可以分开使用,根据需求决定
maxUnavailable: 25% // 最大不可用25%
type: RollingUpdate
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: syblyw0806/httpd:latest
imagePullPolicy: IfNotPresent
// 应用
[root@master ~]# kubectl apply -f test2.yaml
deployment.apps/web configured
// 查看发现暂未发生变化
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-5d688b9745-7gx4g 1/1 Running 0 10m
web-5d688b9745-9hnxz 1/1 Running 0 10m
web-5d688b9745-ft6w9 1/1 Running 0 10m
web-5d688b9745-vmcbv 1/1 Running 0 10m
// 我们去test2.yaml里面修改一下镜像
#其余内容不变
[root@master ~]# vim test2.yaml
image: httpd // 镜像修改就会更新
// 修改完之后应用
[root@master ~]# kubectl apply -f test2.yaml
deployment.apps/web configured
// 发现停止了三个旧的web,启动了两个新的web和一个旧的web,还有两个新web正在创建
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-5d688b9745-7gx4g 1/1 Terminating 0 10m
web-5d688b9745-9hnxz 0/1 Running 0 22m
web-5d688b9745-ft6w9 0/1 Terminating 0 22m
web-5d688b9745-vmcbv 0/1 Terminating 0 22m
web-f8bcfc88-bcvcd 0/1 Running 0 92s
web-f8bcfc88-kkx4f 0/1 Running 0 92s
web-f8bcfc88-w4dxx 1/1 ContainerCreating 0 65s
web-f8bcfc88-x6q5z 1/1 ContainerCreating 0 47s
// 最后变为四个新的web
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-f8bcfc88-bcvcd 1/1 Running 0 92s
web-f8bcfc88-kkx4f 1/1 Running 0 92s
web-f8bcfc88-w4dxx 1/1 Running 0 65s
web-f8bcfc88-x6q5z 1/1 Running 0 47s
Deployment:水平扩锁容
第三步:水平扩充容(启动多实例,提高并发)
- 修改yanl里replicas值,再apply
- kubectl scale deployment web --replicas=10
注:replicas参数控制Pod副本数量
实例:
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-f8bcfc88-bcvcd 1/1 Running 0 92s
web-f8bcfc88-kkx4f 1/1 Running 0 92s
web-f8bcfc88-w4dxx 1/1 Running 0 65s
web-f8bcfc88-x6q5z 1/1 Running 0 47s
// 创建10个容器
[root@master ~]# cat test2.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 10 // 复制成10个
strategy:
rollingUpdate:
maxSurge: 55% // 最大可超出55%
maxUnavailable: 50% // 最大不可用50%
type: RollingUpdate
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: syblyw0806/httpd:latest
imagePullPolicy: IfNotPresent
// 应用
[root@master ~]# kubectl apply -f test2.yaml
deployment.apps/web created
// 查看,发现10个容器已经创建好了,都已经运行了
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-5d688b9745-6dqcl 1/1 Running 0 63s
web-5d688b9745-bkmbf 1/1 Running 0 63s
web-5d688b9745-cpxkx 1/1 Running 0 63s
web-5d688b9745-gxjf6 1/1 Running 0 63s
web-5d688b9745-k2l2b 1/1 Running 0 63s
web-5d688b9745-ll5cc 1/1 Running 0 63s
web-5d688b9745-sqckx 1/1 Running 0 63s
web-5d688b9745-t578c 1/1 Running 0 63s
web-5d688b9745-txwh9 1/1 Running 0 63s
web-5d688b9745-z25kc 1/1 Running 0 63s
// 修改replicas值,实现水平扩缩容
#其余内容不变
[root@master ~]# vim test2.yaml
replicas: 3
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-5d688b9745-6dqcl 1/1 Running 0 63s
web-5d688b9745-bkmbf 1/1 Running 0 63s
web-5d688b9745-cpxkx 1/1 Terminating 0 63s
web-5d688b9745-gxjf6 1/1 Terminating 0 63s
web-5d688b9745-k2l2b 1/1 Terminating 0 63s
web-5d688b9745-ll5cc 1/1 Terminating 0 63s
web-5d688b9745-sqckx 1/1 Terminating 0 63s
web-5d688b9745-t578c 1/1 Terminating 0 63s
web-5d688b9745-txwh9 1/1 Terminating 0 63s
web-5d688b9745-z25kc 1/1 Terminating 0 63s
web-f8bcfc88-hb8dz 0/1 ContainerCreating 0 5s
web-f8bcfc88-ldqt5 0/1 ContainerCreating 0 5s
web-f8bcfc88-r8zn7 0/1 ContainerCreating 0 5s
// 最后结果只剩3个
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-f8bcfc88-hb8dz 1/1 Running 0 3m44s
web-f8bcfc88-ldqt5 1/1 Running 0 3m44s
web-f8bcfc88-r8zn7 1/1 Running 0 3m44s
Deployment:回滚
第四步:回滚(发布失败恢复正常版本)
-
kubectl rollout history deployment/web # 查看历史发布版本
-
kubectl rollout undo deployment/web # 回滚上一个版本
-
kubectl rollout undo deployment/web --to-revision=2 # 回滚历史指定版本
实例:
// 查看版本
[root@master ~]# kubectl rollout history deploy/web
deployment.apps/web
REVISION CHANGE-CAUSE
1 <none> // 有两个版本
2 <none>
// 如果你回滚的是当前版本,就会跳过
[root@master ~]# kubectl rollout undo deploy/web --to-revision 2
deployment.apps/web skipped rollback (current template already matches revision 2)
// 回滚第一个版本
[root@master ~]# kubectl rollout undo deploy/web --to-revision 1
deployment.apps/web rolled back
// 回滚成功
[root@master ~]# kubectl rollout history deploy/web
deployment.apps/web
REVISION CHANGE-CAUSE
2 <none>
3 <none>
revisionHistoryLimit: 5/可以保留多个版本
[root@master ~]# vim test2.yaml
revisionHistoryLimit: 5 // 保留五个版本
注:回滚是重新部署某一次部署时的状态,既当时版本所有配置
Deployment:删除
第五步:最后,项目下线:
-
kubectl delete deploy/web
-
kubectl delete svc/web
-
kubectl delete pods/web
// 创建
[root@master ~]# kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
// 查看
[root@master ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 29s
web 3/3 3 3 16m
// 单个删除
[root@master ~]# kubectl delete deploy/nginx
deployment.apps "nginx" deleted
[root@master ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
web 3/3 3 3 16m
// --all 删除所有
[root@master ~]# kubectl delete deployment --all
deployment.apps "web" deleted
[root@master ~]# kubectl get deployment
No resources found in default namespace.
Deployment:ReplicaSet
ReplicaSet控制器用途:
- Pod副本数量管理,不断对比当前Pod数量与期望Pod数量
- Deployment每次发布都会创建一个RS作为记录,用于实现回滚
kubectl get rs 查看RS记录
[root@master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
web-5d688b9745 3 3 3 7m5s
web-f8bcfc88 0 0 0 6m33s
kubectl rollout history deployment web # 版本对应RS记录
[root@master ~]# kubectl rollout history deployment web
deployment.apps/web
REVISION CHANGE-CAUSE
2 <none>
3 <none>
[root@master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
web-5d688b9745 3 3 3 7m5s
web-f8bcfc88 0 0 0 6m33s
// 修改镜像
#其余内容不变
[root@master ~]# vim test2.yaml
image: httpd
// 应用
[root@master ~]# kubectl apply -f test2.yaml
deployment.apps/web configured`在这里插入代码片`
[root@master ~]# kubectl get pods
web-5d688b9745-dpmsd 1/1 Terminating 0 11m
web-5d688b9745-q6dls 1/1 Terminating 0 11m
web-f8bcfc88-4rkfx 0/1 ContainerCreating 0 2s
web-f8bcfc88-6knsw 1/1 Running 0 2s
web-f8bcfc88-bd9zz 1/1 Running 0 2s
// 每一个版本对应一个RS,上一个版本被干掉了,新的版本会有新的Rs
[root@master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
web-5d688b9745 0 0 0 12m
web-f8bcfc88 3 3 3 12m
ReplicaSet:由Deployment里面的relicas的参数控制的,我们不需要单独的定义这个控制器!
实例:
[root@node2 ~]# docker ps | grep web
4c938ad0c01d dabbfbe0c57b "httpd-foreground" 13 seconds ago Up 12 seconds k8s_httpd_web-f8bcfc88-4rkfx_default_562616cd-1552-4610-bf98-e470225e4c31_1
452713eeccad registry.aliyuncs.com/google_containers/pause:3.6 "/pause" 5 minutes ago Up 5 minutes k8s_POD_web-f8bcfc88-4rkfx_default_562616cd-1552-4610-bf98-e470225e4c31_0
// 你干掉了一个
[root@node2 ~]# docker kill 4c938ad0c01d
4c938ad0c01d
[root@master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
web-5d688b9745 0 0 0 17m
web-f8bcfc88 3 3 2 17m
// 等会他自己会启用
[root@master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
web-5d688b9745 0 0 0 18m
web-f8bcfc88 3 3 3 17m
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-f8bcfc88-4rkfx 1/1 Running 2 (80s ago) 6m32s
web-f8bcfc88-6knsw 1/1 Running 0 6m32s
web-f8bcfc88-bd9zz 1/1 Running 0 6m32s
DameonSet
DameonSet功能:
- 在每一个Node上运行一个Pod
- 新加入的Node也同样会自动运行一个Pod
应用场景:网络插件(kube-proxy、calicao)、其他Agent
// 删除资源,容器也会被删除
[root@master ~]# kubectl delete -f test2.yaml
deployment.apps "web" deleted
[root@master ~]# cat daemon.yaml
---
apiVersion: apps/v1
kind: DaemonSet // 类型是DaemonSet
metadata:
name: filebeat
namespace: kube-system // 命名空间:设置为在系统里面
spec:
selector:
matchLabels:
name: filebeat
template:
metadata:
labels:
name: filebeat
spec:
containers: // 记录日志的镜像
- name: log
image: elastic/filebeat:7.16.2
imagePullPolicy: IfNotPresent
[root@master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-6d8c4cb4d-9m5jg 1/1 Running 11 (4h36m ago) 6d4h
coredns-6d8c4cb4d-mp662 1/1 Running 11 (4h36m ago) 6d4h
etcd-master 1/1 Running 13 (4h36m ago) 6d4h
kube-apiserver-master 1/1 Running 13 (4h36m ago) 6d4h
kube-controller-manager-master 1/1 Running 14 (4h36m ago) 6d4h
kube-flannel-ds-g9jsh 1/1 Running 11 (4h36m ago) 6d1h
kube-flannel-ds-qztxc 1/1 Running 11 (4h36m ago) 6d1h
kube-flannel-ds-t8lts 1/1 Running 13 (4h36m ago) 6d1h
kube-proxy-q2jmh 1/1 Running 12 (4h36m ago) 6d4h
kube-proxy-r28dn 1/1 Running 13 (4h36m ago) 6d4h
kube-proxy-x4cns 1/1 Running 12 (4h36m ago) 6d4h
kube-scheduler-master 1/1 Running 14 (4h36m ago) 6d4h
[root@master ~]# kubectl apply -f daemon.yaml
deployment.apps/filebeat created
// 这是系统相关的,普通用户一半不会用,也不会影响
所以你需要在每个节点都运行容器的时候,可以用DameonSet来执行:公共任务
[root@master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-6d8c4cb4d-9m5jg 1/1 Running 11 (4h36m ago) 6d4h
coredns-6d8c4cb4d-mp662 1/1 Running 11 (4h36m ago) 6d4h
etcd-master 1/1 Running 13 (4h36m ago) 6d4h
filebeat-9ck6z 1/1 Running 0 68s
filebeat-d2psf 1/1 Running 0 68s
kube-apiserver-master 1/1 Running 13 (4h36m ago) 6d4h
kube-controller-manager-master 1/1 Running 14 (4h36m ago) 6d4h
kube-flannel-ds-g9jsh 1/1 Running 11 (4h36m ago) 6d1h
kube-flannel-ds-qztxc 1/1 Running 11 (4h36m ago) 6d1h
kube-flannel-ds-t8lts 1/1 Running 13 (4h36m ago) 6d1h
kube-proxy-q2jmh 1/1 Running 12 (4h36m ago) 6d4h
kube-proxy-r28dn 1/1 Running 13 (4h36m ago) 6d4h
kube-proxy-x4cns 1/1 Running 12 (4h36m ago) 6d4h
kube-scheduler-master 1/1 Running 14 (4h36m ago) 6d4h
// 所以节点都可以跑,除了master,master默认不可被调度
[root@master ~]# kubectl get pods -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
filebeat-9ck6z 1/1 Running 0 3m9s 10.244.2.219 node2.example.com <none> <none>
filebeat-d2psf 1/1 Running 0 3m9s 10.244.1.141 node1.example.com <none> <none>
注意:资源创建成功,文件是可以删除的,资源一样运行,资源不会随着文件改变而改变,你想改变的时候就在写一个文件
Job 和 CronJob
Job分为普通任务(Job)和定时任务(CronJob)
- 一次性执行
应用场景:离线数据处理,视频解码等业务
实例:
// 写一个job.yaml文件
[root@master ~]# cat job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl","-Mbignum=bpi","-wle","print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
// 运用job.yaml文件
[root@master ~]# kubectl apply -f job.yaml
job.batch/pi created
// 查看pod详细情况
在node2节点上面运行
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pi-27xrt 0/1 ContainerCreating 0 9m20s <none> node2.example.com <none> <none>
// 去node2上面过滤
[root@node2 ~]# docker ps | grep pi
e55ac8842c89 registry.aliyuncs.com/google_containers/pause:3.6 "/pause" 9 minutes ago Up 9 minutes k8s_POD_pi-27xrt_default_698b4c91-ef54-4fe9-b62b-e0abc00031fd_0
// 已经完成了
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pi-27xrt 0/1 Completed 0 22m
// 去node2节点上查看
[root@node2 ~]# docker images | grep perl
perl latest f9596eddf06f 3 days ago 890MB
// 成功创建
[root@master ~]# kubectl describe job/pi
Name: pi
Namespace: default
Selector: controller-uid=5058b8e2-fc49-4247-9b5b-6f2b5df6dc67
Labels: controller-uid=5058b8e2-fc49-4247-9b5b-6f2b5df6dc67
job-name=pi
Annotations: batch.kubernetes.io/job-tracking:
Parallelism: 1
Completions: 1
Completion Mode: NonIndexed
Start Time: Fri, 24 Dec 2021 23:15:29 +0800
Completed At: Fri, 24 Dec 2021 23:15:56 +0800
Duration: 20m
Pods Statuses: 0 Active / 1 Succeeded / 0 Failed // 看这里
......以下省略
CronJob用于实现定时任务,像Linux的Crontab一样
- 定时任务
应用场景:通知、备份
实例:
[root@master ~]# kubelet --version
Kubernetes v1.23.1
// 写一个cronjob.yaml文件
[root@master ~]# cat cronjob.yaml
---
apiVersion: batch/v1 # v1.23.1版本这里要这么编写
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1****"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date;echo Hello aliang
restartPolicy: OnFailure
[root@master ~]# date
Fri Dec 24 11:58:50 CST 2021
// 运行计划任务
[root@master ~]# kubectl apply -f cronjob.yaml
Warning: batch/v1beta1 CronJob is deprecated in v1.21+, unavailable in v1.25+; use batch/v1 CronJob
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-27338645-xddbs 0/1 Completed 0 2m54s
hello-27338646-54jvb 0/1 Completed 0 114s
hello-27338647-ntnhq 0/1 Completed 0 54s
// 开始运行
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-27338645-xddbs 0/1 Completed 0 3m16s
hello-27338646-54jvb 0/1 Completed 0 2m16s
hello-27338647-ntnhq 0/1 Completed 0 76s
hello-27338648-hlh49 0/1 ContainerCreating 0 16s
// 运行完成
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-27338646-54jvb 0/1 Completed 0 2m54s
hello-27338647-ntnhq 0/1 Completed 0 114s
hello-27338648-hlh49 0/1 Completed 0 54s
// 创建成功
[root@master ~]# kubectl describe cronjob/hello
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 3m27s (x133 over 135m) cronjob-controller (combined from similar events): Created job hello-27338944
注意:batch/v1beta1 CronJob 在 v1.21+ 中被弃用,在 v1.25+ 中不可用; 使用批处理/v1 CronJob。