目录
一、概述
二、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部署一个应用,副本数为3
apiVersion: apps/v1
kind: Deployment
metadata:name: webnamespace: default
spec:replicas: 3 # 副本数量selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginx # Pod副本的标签spec:containers:- name: webimage: nginx:1.15
pod 副本为3 , 成功调度到 node1和node2两个节点上
服务暴露出来,查询对用的服务端口
kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
三个节点的任意 IP加上 31812端口 都可以访问
业务应用基本都是通过Deployment的方式部署在Kubernetes中的,应用的更新和回滚是常态的工作,特别是在互联网企业,快速迭代抓住用户的一个重要途径。
但是,并不是每一次的迭代都是100%正常的,如果异常,如何快速恢复也是要考虑的事情。为适应这种场景,Deployment提供滚动更新和快速回滚的能力。
Deployment默认的更新方式就是滚动更新,可以通过strategy.type来指定更新方式。
## 部署应用
kubectl apply -f deployment.yaml## 暴露应用服务的端口
kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
• 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 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: webnamespace: default
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: webimage: nginx:1.16
replicas 一个一个升级创建一个新的删除旧的,具体的策略可以,自行配置
导出 web deployment, 查看完整的 Deployment 配置
kubectl get deployment web -o yaml > deploy.yamlapiVersion: 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.17creationTimestamp: "2022-11-12T09:11:15Z"generation: 8managedFields:- apiVersion: apps/v1fieldsType: FieldsV1fieldsV1: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-applyoperation: Updatetime: "2022-11-12T10:33:02Z"- apiVersion: apps/v1fieldsType: FieldsV1fieldsV1:f:metadata:f:annotations:f:kubernetes.io/change-cause: {}f:spec:f:template:f:spec:f:containers:k:{"name":"web"}:f:image: {}manager: kubectloperation: Updatetime: "2022-11-12T10:33:12Z"- apiVersion: apps/v1fieldsType: FieldsV1fieldsV1: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-manageroperation: Updatetime: "2022-11-12T10:33:21Z"name: webnamespace: defaultresourceVersion: "1262530"selfLink: /apis/apps/v1/namespaces/default/deployments/webuid: 7b334d04-b47e-4023-bb3f-8043fd1474e2
spec:progressDeadlineSeconds: 600replicas: 3revisionHistoryLimit: 10selector:matchLabels:app: nginxstrategy:rollingUpdate:maxSurge: 25% ### maxUnavailable: 25% ###type: RollingUpdate ###template:metadata:creationTimestamp: nulllabels:app: nginxspec:containers:- image: nginx:1.17imagePullPolicy: IfNotPresentname: webresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilednsPolicy: ClusterFirstrestartPolicy: AlwaysschedulerName: default-schedulersecurityContext: {}terminationGracePeriodSeconds: 30
status:availableReplicas: 3 ### conditions:- lastTransitionTime: "2022-11-12T09:23:15Z"lastUpdateTime: "2022-11-12T09:23:15Z"message: Deployment has minimum availability.reason: MinimumReplicasAvailablestatus: "True"type: Available- lastTransitionTime: "2022-11-12T09:11:15Z"lastUpdateTime: "2022-11-12T10:33:21Z"message: ReplicaSet "web-76f5f6d7f5" has successfully progressed.reason: NewReplicaSetAvailablestatus: "True"type: ProgressingobservedGeneration: 8readyReplicas: 3replicas: 3updatedReplicas: 3
当然,这时候应在Pod中加上health check检查应用的健康状态,而不是简单的依赖容器的running状态。配置相应的健康检查可以确保服务的可靠性和延续性。
发布失败恢复正常版本
# 查看历史发布版本
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: webnamespace: defaultannotations: # 记录回滚参数kubernetes.io/change-cause: "web.v1-nginx-1.17" #记录到revision中的内容,记录版本号
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: webimage: nginx:1.17
注:回滚是重新部署某一次部署时的状态,即当时版本所有配置
查看正在运行的服务版本,镜像是 nginx: 1.17
回滚到上个版本,镜像是 nginx: 1.16
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保证在每个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: filebeatnamespace: kube-system
spec:selector:matchLabels:name: filebeattemplate:metadata:labels:name: filebeatspec:tolerations:- effect: NoScheduleoperator: Existscontainers:- name: logimage: elastic/filebeat:7.3.2
三个 节点成功部署 filebeat
计算圆周率
apiVersion: batch/v1
kind: Job
metadata:name: pi
spec:template:spec:containers:- name: piimage: perl # 自定义的一次性需要运行的镜像command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]restartPolicy: Never
应用场景:离线数据处理,视频解码等业务
apiVersion: batch/v1beta1
kind: CronJob
metadata:name: hello
spec:schedule: "*/1 * * * *"jobTemplate:spec:template:spec:containers:- name: helloimage: busyboxargs:- /bin/sh- -c- date; echo Hello kangllrestartPolicy: OnFailure
需要注意的是,由于cron的特殊性,有时候会存在由于上一个定时任务还没有执行完成,新的定时任务又开始了的情况,我们可以通过定义spec.concurrencyPolicy字段来定义规则,比如:
上面介绍的是日常工作中常用的控制器,其中Deployment和DaemonSet的使用频率最高,熟练掌握这些控制器,并且学会在什么时候选择什么样的控制器,合理使用使工作效率最高。