目录
一、概述
二、Deployment 控制器
2.1Deployment 部署应用
2.2Deployment滚动升级
2.2.1应用部署完成
2.2.2更新镜像三种方式
2.3 Deployment 发布失败回滚
2.4Deployment 水平扩容
三、DaemonSet控制器
四、Job控制器
4.1Job一次性执行
4.2定时任务(CronJob)
五、总结
一、概述
在Kubernetes中,Pod是最小的管理单元,是一组紧密关联的容器组合。
但是,单独的Pod并不能保障总是可用,比如我们创建一个nginx的Pod,因为某些原因,该Pod被意外删除,我们希望其能够自动新建一个同属性的Pod。很遗憾,单纯的Pod并不能满足需求。
为此,Kubernetes实现了一系列控制器来管理Pod,使Pod的期望状态和实际状态保持一致
工作负载控制器(Workload Controllers)是K8s的一个抽象概念,用于更高级层次对象,部署和管理Pod。常用工作负载控制器:
• Deployment :无状态应用部署
• StatefulSet :有状态应用部署
• DaemonSet :确保所有Node运行同一个Pod
• Job :一次性任务
• Cronjob :定时任务
控制器的作用:
• 管理Pod对象
• 使用标签与Pod关联
• 控制器实现了Pod的运维,例如滚动更新、伸缩、副本管理、维护Pod状态等。
Deployment的功能:
• 管理Pod和ReplicaSet
• 具有上线部署、副本设定、滚动升级、回滚等功能
• 提供声明式更新,例如只更新一个新的Image 应用场景:网站、API、微服务
二、Deployment 控制器
2.1Deployment 部署应用
deployment部署一个应用,副本数为3
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 3 # 副本数量
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx # Pod副本的标签
spec:
containers:
- name: web
image: nginx:1.15
pod 副本为3 , 成功调度到 node1和node2两个节点上
服务暴露出来,查询对用的服务端口
kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
三个节点的任意 IP加上 31812端口 都可以访问
2.2Deployment滚动升级
业务应用基本都是通过Deployment的方式部署在Kubernetes中的,应用的更新和回滚是常态的工作,特别是在互联网企业,快速迭代抓住用户的一个重要途径。
但是,并不是每一次的迭代都是100%正常的,如果异常,如何快速恢复也是要考虑的事情。为适应这种场景,Deployment提供滚动更新和快速回滚的能力。
Deployment默认的更新方式就是滚动更新,可以通过strategy.type来指定更新方式。
- Recreate:先删除所有的Pod,再创建
- RollingUpdate:先启动新的Pod,再替换老的Pod
2.2.1应用部署完成
## 部署应用
kubectl apply -f deployment.yaml
## 暴露应用服务的端口
kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
2.2.2更新镜像三种方式
• kubectl apply -f xxx.yaml
• kubectl set image deployment/web nginx=nginx:1.16
• kubectl edit deployment/web
滚动升级:K8s对Pod升级的默认策略,通过使用新版本Pod逐步更新旧版本Pod,实现零停机发布,用户无感知。
查看三个pod 服务 对应的 IP和端口
[root@k8s-master1 ~]# kubectl get ep
NAME ENDPOINTS AGE
kubernetes 192.168.2.117:6443,192.168.2.119:6443 7d2h
pod-check <none> 6h
web 10.244.159.134:80,10.244.224.10:80,10.244.36.74:80 32m
nginx:1.15 镜像升级到 nginx:1.16
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: web
image: nginx:1.16
replicas 一个一个升级创建一个新的删除旧的,具体的策略可以,自行配置
导出 web deployment, 查看完整的 Deployment 配置
kubectl get deployment web -o yaml > deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "7"
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"kubernetes.io/change-cause":"web.v1-nginx-1.17"},"name":"web","namespace":"default"},"spec":{"replicas":3,"selector":{"matchLabels":{"app":"nginx"}},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx:1.17","name":"web"}]}}}}
kubernetes.io/change-cause: web.v1-nginx-1.17
creationTimestamp: "2022-11-12T09:11:15Z"
generation: 8
managedFields:
- apiVersion: apps/v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.: {}
f:kubectl.kubernetes.io/last-applied-configuration: {}
f:spec:
f:progressDeadlineSeconds: {}
f:replicas: {}
f:revisionHistoryLimit: {}
f:selector:
f:matchLabels:
.: {}
f:app: {}
f:strategy:
f:rollingUpdate:
.: {}
f:maxSurge: {}
f:maxUnavailable: {}
f:type: {}
f:template:
f:metadata:
f:labels:
.: {}
f:app: {}
f:spec:
f:containers:
k:{"name":"web"}:
.: {}
f:imagePullPolicy: {}
f:name: {}
f:resources: {}
f:terminationMessagePath: {}
f:terminationMessagePolicy: {}
f:dnsPolicy: {}
f:restartPolicy: {}
f:schedulerName: {}
f:securityContext: {}
f:terminationGracePeriodSeconds: {}
manager: kubectl-client-side-apply
operation: Update
time: "2022-11-12T10:33:02Z"
- apiVersion: apps/v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
f:kubernetes.io/change-cause: {}
f:spec:
f:template:
f:spec:
f:containers:
k:{"name":"web"}:
f:image: {}
manager: kubectl
operation: Update
time: "2022-11-12T10:33:12Z"
- apiVersion: apps/v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
f:deployment.kubernetes.io/revision: {}
f:status:
f:availableReplicas: {}
f:conditions:
.: {}
k:{"type":"Available"}:
.: {}
f:lastTransitionTime: {}
f:lastUpdateTime: {}
f:message: {}
f:reason: {}
f:status: {}
f:type: {}
k:{"type":"Progressing"}:
.: {}
f:lastTransitionTime: {}
f:lastUpdateTime: {}
f:message: {}
f:reason: {}
f:status: {}
f:type: {}
f:observedGeneration: {}
f:readyReplicas: {}
f:replicas: {}
f:updatedReplicas: {}
manager: kube-controller-manager
operation: Update
time: "2022-11-12T10:33:21Z"
name: web
namespace: default
resourceVersion: "1262530"
selfLink: /apis/apps/v1/namespaces/default/deployments/web
uid: 7b334d04-b47e-4023-bb3f-8043fd1474e2
spec:
progressDeadlineSeconds: 600
replicas: 3
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 25% ###
maxUnavailable: 25% ###
type: RollingUpdate ###
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.17
imagePullPolicy: IfNotPresent
name: web
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status:
availableReplicas: 3 ###
conditions:
- lastTransitionTime: "2022-11-12T09:23:15Z"
lastUpdateTime: "2022-11-12T09:23:15Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: "2022-11-12T09:11:15Z"
lastUpdateTime: "2022-11-12T10:33:21Z"
message: ReplicaSet "web-76f5f6d7f5" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
observedGeneration: 8
readyReplicas: 3
replicas: 3
updatedReplicas: 3
- maxSurge: 表示升级过程中最多可以比原先设置多出的pod数量,如上maxSurge=1,replicas:3 就表示kubennetes会先启动一个新的pod,然后删除掉一个旧的pod,整个升级过程中最多会有3+1pod
- maxUnavailable: 表示升级过程中最多有多少个pod处于无法提供服务的状态,当manSurge不为0时,该值也不能为0,maxUnavailable =1 表示kubernetes整个升级过程中最多会有一个pod处于无法服务的状态
- minReadySeconds: 表示kubernetes在等待设置时间后才进行升级,如果没有设置该值kubernete会假设容器启动起来就提供服务了,如果没有设置该值,在某些极端情况下可能会造成服务不正常运行,默认值是0
- type:RollingUpdate表示,设置更新策略为滚动更新,可以设置为recreate和RollingUpdate两个值,recreate表示全部重新创建,默认值就是RollingUpdate
当然,这时候应在Pod中加上health check检查应用的健康状态,而不是简单的依赖容器的running状态。配置相应的健康检查可以确保服务的可靠性和延续性。
2.3 Deployment 发布失败回滚
发布失败恢复正常版本
# 查看历史发布版本
kubectl rollout history deployment/web
# 回滚上一个版本
kubectl rollout undo deployment/web
# 回滚历史指定版本
kubectl rollout undo deployment/web --to-revision=2
ngnix 版本可自由改动 ,尝试 升级和回滚
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
annotations: # 记录回滚参数
kubernetes.io/change-cause: "web.v1-nginx-1.17" #记录到revision中的内容,记录版本号
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: web
image: nginx:1.17
注:回滚是重新部署某一次部署时的状态,即当时版本所有配置
查看正在运行的服务版本,镜像是 nginx: 1.17
回滚到上个版本,镜像是 nginx: 1.16
2.4Deployment 水平扩容
ReplicaSet控制器用途:
• Pod副本数量管理,不断对比当前Pod数量与期望Pod数量
• Deployment每次发布都会创建一个RS作为记录,用于实现回滚
# 查看RS记录
kubectl get rs
# 版本对应RS记录
kubectl rollout history deployment web
# 命令直接修改副本个数,或者 修改yaml重新应用下
kubectl scale deployment web --replicas 5 deployment.apps/web scaled
## 也可以直接修改 ep 文件
kubectl edit ep web -o yaml
新增两个 pod
三、DaemonSet控制器
DaemonSet保证在每个Node上都运行一个Pod,如果新增一个Node,这个Pod也会运行在新增的Node上,如果删除这个DadmonSet,就会清除它所创建的Pod。常用来部署一些集群日志收集,监控等全局应用。
DaemonSet也是支持更新和回滚的,具体操作和Deployment类似。
常见的场景如下:
1、运行存储集群daemon,比如ceph,glusterd等;
2、运行一个日志收集daemon,比如logstash,fluentd等;
3、运行监控daemon,比如Prometheus Node Exporter,collectd,New Relic agent,Ganglia gmond等;
部署一个日志采集程序,因为使用 kubeadm 安装 所以 master 节点打了污点,下面filebeat 配置污点容忍,使其在 master 节点 也可以调度成功。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat
namespace: kube-system
spec:
selector:
matchLabels:
name: filebeat
template:
metadata:
labels:
name: filebeat
spec:
tolerations:
- effect: NoSchedule
operator: Exists
containers:
- name: log
image: elastic/filebeat:7.3.2
三个 节点成功部署 filebeat
四、Job控制器
4.1Job一次性执行
计算圆周率
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
4.2定时任务(CronJob)
应用场景:离线数据处理,视频解码等业务
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello kangll
restartPolicy: OnFailure
需要注意的是,由于cron的特殊性,有时候会存在由于上一个定时任务还没有执行完成,新的定时任务又开始了的情况,我们可以通过定义spec.concurrencyPolicy字段来定义规则,比如:
- concurrencyPolicy=Allow:表示这些Job可以同时存在
- concurrencyPolicy=Firbid:表示不会创建新的Job,也就是这个定时任务被跳过
- concurrencyPolicy=Replace:表示产生的新Job会替代旧的Job
五、总结
上面介绍的是日常工作中常用的控制器,其中Deployment和DaemonSet的使用频率最高,熟练掌握这些控制器,并且学会在什么时候选择什么样的控制器,合理使用使工作效率最高。