通俗来说就是,控制器就是pod的幕后老板
k8s发展到今天,产生了很多种控制器,以下列举常用的几类控制器;
ReplicaSet 主要具备下面的特点:
rs,主要是控制由其管理的pod,使pod副本的数量始终维持在预设的个数 ;通过控制ReplicaSet来控制Pod,并支持滚动升级、回退版本,适合无状态的服务部署
主要特点如下:
在K8S集群部署中由于节点数量不定,那么如果我们需要对每个节点中都运行一个守护进程、日志收集进程等情况时,在k8s中如何实现呢?这个时候就是DaemonSet应用场景了
其主要特点如下:
像RS、Deployment、DaemonSet都是面向无状态的服务,所管理的Pod的IP、名字,启停顺序都是随机 ,StatefulSet就是有状态的集合,管理所有有状态的服务
其特点如下:
应用场景:比如MySQL、MongoDB集群
顾名思义,Linux 中有 cron 程序定时执行任务,K8s的 CronJob 提供了类似的功能,可以定时执行 Job;
上文系统介绍了k8s中常用的几类控制器,接下来以ReplicaSet这种控制器为例进行详细的说明;
早期k8s没那么多控制器,使用Replication Controller 来部署、升级Pod,简称RC ,也被称为下一代Replication Controller
rs,主要是控制由其管理的pod,使pod副本的数量始终维持在预设的个数 ;通常在实际业务中,控制器的设置,也是通过在yaml中通过一些标签元素进行设置,如下:
apiVersion: apps/v1 # 版本号
kind: ReplicaSet #资源文件
metadata: # 元对象信息name: test-rs #rs控制器名称namespace: default #名称空间
spec: #具体详情replicas: 2 #副本数量selector: # 选择器,指定rs控制器管理哪些pod资源matchLabels: # 标签匹配规则app: test-nginx-pod #标签key是app,值是xdclass-nginx-podtemplate: # pod模板,当数量不满足的时候,根据下面编码创建pod副本metadata: # 元对象信息labels: # pod资源标签app: test-nginx-podspec: #具体详情containers: # 容器数组列表- name: test-nginx #容器名称image: nginx:1.23.0 # 镜像和版本
在当前目录下创建一个yaml,拷贝上面的内容,然后执行 apply命令创建pod
kubectl apply -f rep-nginx.yaml
执行完成后,可以看到,上面创建了2个副本的pod
如果在业务的低峰期,不需要开启那么多pod的时候,就可以考虑缩减pod的个数,使用ReplicaSet的操作命令很容易达到这个目的;
kubectl scale rs test-rs --replicas=1 -n default
参数说明:
执行完成后,可以看到 pod只剩1个了;

可以直接删除rs;也可以通过yaml删除
kubectl delete -f rep-nginx.yaml
执行之后,可以看到下面的效果,pod就被删掉了

Deployment 也是一种控制器,在之前的文章中也在反复的使用它创建pod,其特点如下:
总的来说,Deployment、ReplicaSet、Pod三者之间是一种阶梯控制的关系
apiVersion: apps/v1
kind: Deployment
metadata:name: test-deploynamespace: default
spec:replicas: 2selector: matchLabels:app: test-nginx-podtemplate:metadata:labels:app: test-nginx-podspec:containers:- name: test-nginximage: nginx:1.23.0
在当前目录下创建一个yaml,拷贝上面的内容,然后执行 apply命令创建pod
kubectl apply -f pod-nginx.yaml
执行完成后,可以看到,上面创建了2个副本的pod

kubectl get deploy -o wide -n default

结果参数说明:
NAME : 列出了集群中 Deployment 的名称;READY 显示应用程序的可用的“副本”数,格式是“就绪个数/期望个数” ;UP-TO-DATE 显示为了达到期望状态已经更新的副本数 ;AVAILABLE 显示可用的副本数;AGE 应用程序运行的时间;通过apply创建的pod直接使用 delete -f 删除即可
kubectl delete -f pod-nginx.yaml

滚动升级在日常的生产变更过程中可以说是非常常见的业务了,简单来说,滚动升级的目的就是为了保证在升级过程中不停服,减少因升级带来服务不可用造成的用户不好的产品体验;
通常,传统的滚动升级,一般是针对无状态的应用服务,而且是集群部署的那种,升级的时候,先通过一定的手段,控制集群中的部分节点服务先升级,然后再逐步完成全部节点的升级;
一般这个过程可以通过脚本控制,或者可视化操作界面手工来完成,在k8s中,Deployment这种控制器提供了一种很好的控制机制,基于rollout就可以完成服务的滚动升级;
对应于yaml中的核心配置参数
spec:strategy: # 策略 RollingUpdate Recreate type: RollingUpdate
策略1:Recreate
删除全部旧的pod,然后创建新的pod
策略2:RollingUpdate
滚动升级更新,删除部分,更新部分,在整个更新过程中,存在两个版本的pod
经验来讲,RollingUpdate实际应用场景更多,RollingUpdate根据业务需求的不同,又有下面两个重要的参数可供选择:
1、升级过程中不可用Pod的最大数量,默认为25%;
2、在滚动更新时,我们可以忍受多少个 Pod 无法提供服务;
3、值越小越能保证服务稳定,更新越平滑;
1、升级过程中可以超过期望的Pod的最大数量,默认为25%;
2、在滚动更新时,可以有多少个额外的 Pod;
3、值调的越大,副本更新速度越快;
在当前目录下创建一个deploy-rollout.yaml的文件,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:name: congge-deploynamespace: default
spec:replicas: 5revisionHistoryLimit: 5 #保留历史版本5个strategy: type: RollingUpdateselector: matchLabels:app: congge-nginx-podtemplate:metadata:labels:app: congge-nginx-podspec:containers:- name: congge-nginximage: nginx:1.23.0
在当前的目录下执行命令
kubectl apply -f deploy-rollout.yaml
执行后,可以看到一个5副本的pod就创建出来

使用下面的命令,可以查看上面控制器的详细描述信息
kubectl describe deploy congge-deploy -n default

关于图中展示的信息中的几点补充说明:
MaxSurge 为100%, 立即启动所有新 Pod,也就是有足够的资源希望尽快完成更新,默认两个值都是 25%;
如果更新一个 100 Pod 的 Deployment,会立刻创建 25 个新 Old,同时会关闭 25 个旧 Pod;
每次有 Pod 启动就绪,就可以关闭旧 Pod;
在上面部署的nginx的版本为1.23.0,现在来实现一个需求,将现有的版本降至1.15.8,直接使用下面的命令:
kubectl set image deployment/congge-deploy congge-nginx=nginx:1.15.8 -n default
注意:命令里面的参数主要涉及到deploy的名称和一个container的名称,与上面的yaml中保持一致即可;
当前的状态

执行之后的状态,从状态上来看,有一个短暂的切换状态,并不是一下子就把所有现有的容器停止掉,而是一个很明显的中间状态,也就是滚动升级的过程;

稍等一会儿再看,这时候5个pod对应的nginx就全部完成了版本的降级;

可以在上面的命令行后面追加 --record 以保存正在更改资源的 kubectl 命令,方便查看history版本列表修改命令
kubectl set image deployment/congge-deploy congge-nginx=nginx:1.15.8 -n default --record=true
升级过程中,如果涉及到的pod非常多,也可以动态查看升级过程中存在的不同版本的pod
kubectl get pods -n dev -w
如果在升级之后发现问题,需要进行回退,就可以用上回退相关的操作命令了;
kubectl rollout 版本升级(回滚)相关参数介绍
kubectl rollout history deployment/congge-deploy -n default
这里会展示出版本回退的相关历史记录信息

kubectl rollout history deployment/congge-deploy -n default --revision=3

kubectl rollout undo deployment/congge-deploy -n default

kubectl rollout status deployment/congge-deploy -n default

如果历史版本比较多的情况下,也可以根据实际需要回滚到某个指定的版本
kubectl rollout undo deployment/congge-deploy -n default --to-revision=3
kubectl delete -f deploy-nginx-pod.yaml

在K8S集群部署中由于节点数量不定,那么如果我们需要对每个节点中都运行一个守护进程、日志收集进程等情况时,在k8s中如何实现呢?这个时候就是DaemonSet应用场景了
在当前目录下创建一个daemonset-nginx.yaml的文件,配置如下:
apiVersion: apps/v1
kind: DaemonSet
metadata:name: congge-dsnamespace: default
spec:selector: matchLabels:app: congge-nginx-podtemplate:metadata:labels:app: congge-nginx-podspec:containers:- name: congge-nginximage: nginx:1.23.0imagePullPolicy: IfNotPresent
内容和上面的差不多,主要把kind那里调整下即可,执行apply命令创建pod,创建成功后,使用命令查看:
kubectl get pod,deploy,ds,rs -o wide -n default

可以看到,通过这种方式创建的pod,在其他节点上也会开启一个pod,类似于JVM中的守护进程;
job控制器是一种普通任务容器控制器,只会执行一次,只要完成任务就立即退出,不需要重启或重建 ;
应用场景:批处理程序,完成后容器就退出等
apiVersion: batch/v1
kind: Job
metadata:name: test-jobnamespace: default
spec:parallelism: 2 #job并发运行Pods的数量,默认 1completions: 3 #job需要成功运行Pods的次数,默认 1backoffLimit: 5 #job失败后进行重试的次数,默认是6activeDeadlineSeconds: 100 #job运行超时时间,当job超过timeout时间,则job的状态也会更新为failedtemplate:spec:restartPolicy: Never #job重启策略,OnFailure或Never containers:- name: demoimage: busybox:1.35.0 # 容器的启动命令列表,在pod中的容器初始化完毕后运行命令command: ["echo","hello k8s job"]
BusyBox 参数补充说明:
在当前目录下创建一个job-test.yaml的文件,配置内容如下:
apiVersion: batch/v1
kind: Job
metadata:name: test-job
spec:parallelism: 2completions: 3backoffLimit: 5activeDeadlineSeconds: 100template:spec:restartPolicy: Nevercontainers:- name: demoimage: busybox:1.35.0 command: ["echo","hello k8s job"]
使用apply命令执行创建pod;

kubectl get job -n default -o wide

在yaml中,容器那一栏里面输出了一段内容,可以查看下容器的日志看看是否输出了,选择其中一个job,执行下面的命令进行查看,发现内容成功输出了;
kubectl logs test-job-bl9n7
