K8s 之控制器的定义及详细调用案例
什么是控制器
官方文档:
https://v1-30.docs.kubernetes.io/zh-cn/docs/concepts/workloads/controllers/
控制器也是管理pod的一种手段
- 自主式pod:pod退出或意外关闭后不会被重新创建
- 控制器管理的 Pod:在控制器的生命周期里,始终要维持 Pod 的副本数目
Pod控制器是管理pod的中间层,使用Pod控制器之后,只需要告诉Pod控制器,想要多少个什么样的Pod就可以了,它会创建出满足条件的Pod并确保每一个Pod资源处于用户期望的目标状态。如果Pod资源在运行中出现故障,它会基于指定策略重新编排Pod
当建立控制器后,会把期望值写入etcd,k8s中的apiserver检索etcd中我们保存的期望状态,并对比pod的当前状态,如果出现差异代码则会自动消除差异并立即恢复
控制器常用类型
控制器名称 | 控制器用途 |
---|---|
Replication Controller | 比较原始的pod控制器,已经被废弃,由ReplicaSet替代 |
ReplicaSet | ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行 |
Deployment | 一个 Deployment 为 Pod 和 ReplicaSet 提供声明式的更新能力 |
DaemonSet | DaemonSet 确保全指定节点上运行一个 Pod 的副本 |
StatefulSet | StatefulSet 是用来管理有状态应用的工作负载 API 对象 |
Job | 执行批次处理任务,仅执行一次任务,保证任务的一个或多个Pod成功结束 |
CronJob | Cron Job 创建基于时间调度的 Jobs |
HPA全称Horizontal Pod Autoscaler | 根据资源利用率自动调整service中Pod数量,实现Pod水平自动缩放 |
replicaset 控制器
replicaset 功能
- ReplicaSet 是下一代的 Replication Controller,官方推荐使用ReplicaSet
- ReplicaSet和Replication Controller的唯一区别是选择器的支持,ReplicaSet支持新的基于集合的选择器需求
- ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行
- 虽然 ReplicaSets 可以独立使用,但今天它主要被Deployments 用作协调 Pod 创建、删除和更新的机制
replicaset 参数说明
参数名称 | 字段类型 | 参数说明 |
---|---|---|
spec | Object | 详细定义对象,固定值就写Spec |
spec.replicas | integer | 指定维护pod数量 |
spec.selector | Object | Selector是对pod的标签查询,与pod数量匹配 |
spec.selector.matchLabels | string | 指定Selector查询标签的名称和值,以key:value方式指定 |
spec.template | Object | 指定对pod的描述信息,比如lab标签,运行容器的信息等 |
spec.template.metadata | Object | 指定pod属性 |
spec.template.metadata.labels | string | 指定pod标签 |
spec.template.spec | Object | 详细定义对象 |
spec.template.spec.containers | list | Spec对象的容器列表定义 |
spec.template.spec.containers.name | string | 指定容器名称 |
spec.template.spec.containers.image | string | 指定容器镜像 |
replicaset 示例
1、生成yml文件
[root@k8s-master ~]# kubectl create deployment replicaset --image myapp:v1 --dry-run=client -o yaml > replicaset.yml
2、编辑yml文件内容
[root@k8s-master ~]# vim replicaset.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replicaset #指定pod名称,一定小写,如果出现大写报错
spec:
replicas: 2 #指定维护pod数量为2
selector: #指定检测匹配方式
matchLabels: #指定匹配方式为匹配标签
app: repli #指定匹配的标签为app=repli
template: #模板,当副本数量不足时,会根据下面的模板创建pod副本
metadata:
labels:
app: repli
spec:
containers:
- image: myapp:v1
name: myapp
[root@k8s-master ~]# kubectl apply -f replicaset.yml
replicaset.apps/replicaset created
3、查看其pod的标签详情
[root@k8s-master ~]# kubectl get pods --show-labels
4、修改其标签,查看其pod内容器运行详情
[root@k8s-master ~]# kubectl label pod replicaset-lw2m5 app=lll --overwrite
5、修改标签,查看其pod内容器运行详情
[root@k8s-master ~]# kubectl label pod replicaset-lw2m5 app=repli --overwrite
6、回收资源
[root@k8s2 pod]# kubectl delete -f replicaset.yml
deployment 控制器
deployment 控制器的功能
- 为了更好的解决服务编排的问题,kubernetes在V1.2版本开始,引入了Deployment控制器。
- Deployment控制器并不直接管理pod,而是通过管理ReplicaSet来间接管理Pod
- Deployment管理ReplicaSet,ReplicaSet管理Pod
- Deployment 为 Pod 和 ReplicaSet 提供了一个声明式的定义方法
- 在Deployment中ReplicaSet相当于一个版本
典型的应用场景:
- 用来创建Pod和ReplicaSet
- 滚动更新和回滚
- 扩容和缩容
- 暂停与恢复
deployment 控制器示例
1、生成yml文件
[root@k8s-master ~]# kubectl create deployment deployment --image myapp:v1 --dry-run=client -o yaml > deployment.yml
2、编辑yml文件内容
[root@k8s-master ~]# vim deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment
spec:
replicas: 4
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- image: myapp:v1
name: myapp
root@k8s-master ~]# kubectl apply -f deployment.yml
deployment.apps/deployment created
效果演示:
[root@k8s-master yaml]# kubectl get pods
版本迭代
1、查看现版本
[root@k8s-master yaml]# kubectl get pods -o wide
#查看pod的详细信息
[root@k8s-master yaml]# curl 10.244.2.20
#访问pod内的容器
[root@k8s-master yaml]# kubectl describe deployments.apps deployment
#查看控制器的详细信息
2、更新版本
[root@k8s-master ~]# vim deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment
spec:
replicas: 4
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- image: myapp:v2 #更新为版本2
name: myapp
[root@k8s-master yaml]# kubectl apply -f deployment.yml
[root@k8s-master yaml]# kubectl get pods -o wide
[root@k8s-master yaml]# curl 10.244.2.20
#访问pod内的容器
[root@k8s-master yaml]# kubectl describe deployments.apps deployment
#查看控制器的详细信息
更新的过程是重新建立一个版本的RS,新版本的RS会把pod 重建,然后把老版本的RS回收
版本回滚
1、编辑yml文件内容
[root@k8s-master ~]# vim deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment
spec:
replicas: 4
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- image: myapp:v1 #回滚到之前版本
name: myapp
[root@k8s-master ~]# kubectl apply -f deployment.yml
deployment.apps/deployment configured
效果演示:
[root@k8s-master yaml]# curl 10.244.1.16
版本回滚的过程:
滚动更新策略
[root@k8s-master ~]# vim deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment
spec:
minReadySeconds: 5 #最小就绪时间,指定pod每隔多久更新一次
replicas: 4
strategy: #指定更新策略
rollingUpdate:
maxSurge: 1 #比定义pod数量多几个,即每次更新1个
maxUnavailable: 0 #比定义pod个数少几个,即4个pod都能用
selector:
matchLabels:
app: deployment
template:
metadata:
labels:
app: deployment
spec:
containers:
- image: myapp:v1
name: myapp
[root@k8s2 pod]# kubectl apply -f deployment.yaml
暂停及恢复
1、在实际生产环境中我们做的变更可能不止一处,当修改了一处后,如果直接执行,那么变更就直接触发了
2、我们期望的是当把所有修改都完成后,一次触发完成所有的修改
3、所有这时我们就需要进行暂停,避免触发不必要的线上更新
1、编辑yml文件内容
[root@k8s2 pod]# vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment
spec:
minReadySeconds: 5
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
replicas: 6 #将原本4个pod数量更改为6个
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- image: myapp:v2 #将版本更新为v2
name: myapp
resources:
limits:
cpu: 0.5
memory: 200Mi
requests:
cpu: 0.5
memory: 200Mi
2、进行资源更新的暂停
[root@k8s2 pod]# kubectl rollout pause deployment deployment
deployment.apps/deployment paused
#将控制器下的deployment控制器更新暂停
3、利用控制器生成资源
[root@k8s2 pod]# kubectl apply -f deployment.yaml
4、查看新生成的资源信息
[root@k8s2 pod]# kubectl rollout history deployment deployment
5、恢复后开始触发更新
[root@k8s2 pod]# kubectl rollout resume deployment deployment
deployment.apps/deployment resumed
6、查看资源信息
[root@k8s-master yaml]# kubectl rollout history deployment deployment
7、回收资源
[root@k8s-master yaml]# kubectl delete deployments.apps deployment
daemonset 控制器
daemonset 功能
DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。当有节点加入集群时, 也会为他们新增一个 Pod ,当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod
DaemonSet 的典型用法:
- 在每个节点上运行集群存储 DaemonSet,例如 glusterd、ceph。
- 在每个节点上运行日志收集 DaemonSet,例如 fluentd、logstash。
- 在每个节点上运行监控 DaemonSet,例如 Prometheus Node Exporter、zabbix agent等
- 一个简单的用法是在所有的节点上都启动一个 DaemonSet,将被作为每种类型的 daemon 使用
- 一个稍微复杂的用法是单独对每种 daemon 类型使用多个 DaemonSet,但具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求
daemonset 示例
1、查看设备是否存在污点
[root@k8s-master yaml]# kubectl describe nodes k8s-master
2、利用没有容忍污点的控制器创建pod
[root@k8s-master yaml]# kubectl apply -f daemonset.yml
3、利用容忍污点的控制器创建podls
[root@k8s2 pod]# cat daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: daemonset
spec:
selector:
matchLabels:
app: daemonset
template:
metadata:
labels:
app: daemonset
spec:
tolerations: #对于污点节点的容忍
- effect: NoSchedule
operator: Exists
containers:
- name: nginx
image: nginx
[root@k8s-master yaml]# kubectl apply -f daemonset.yml
job 控制器
job控制器功能
Job,主要用于负责批量处理(一次要处理指定数量任务)短暂的一次性(每个任务仅运行一次就结束)任务
job特点如下:
当Job创建的pod执行成功结束时,Job将记录成功结束的pod数量
当成功结束的pod达到指定的数量时,Job将完成执行
关于重启策略设置的说明:
1、如果指定为OnFailure,则job会在pod出现故障时重启容器,而不是创建pod,failed次数不变
2、如果指定为Never,则job会在pod出现故障时创建新的pod,并且故障pod不会消失,也不会重启,failed次数加1
3、如果指定为Always的话,就意味着一直重启,意味着job任务会重复去执行了
job 控制器示例:
1、生成 job 控制器的yaml文件
[root@k8s-master images]# kubectl create job --image perl:5.34.0 perl --dry-run=client -o yaml > job.yml
2、编辑有yml文件内容
[root@k8s2 pod]# vim job.yml
apiVersion: batch/v1
kind: Job
metadata:
name: job
spec:
completions: 4 #一共完成任务数为6
parallelism: 1 #每次并行完成1个
backoffLimit: 4 #失败后尝试运行4次,如果都失败则任务结束
template:
spec:
containers:
- image: perl:5.34.0
name: perl
command: ["perl","-Mbignum=bpi","-wle","print bpi(2000)"] 计算小数点的后2000位
restartPolicy: Never #关闭后不自动重启
[root@k8s-master yaml]# kubectl apply -f job.yml
效果演示:
[root@k8s-master yaml]# kubectl get all
cronjob 控制器
cronjob 控制器功能
-
Cron Job 创建基于时间调度的 Jobs
-
CronJob控制器以Job控制器资源为其管控对象,并借助它管理pod资源对象
-
CronJob可以以类似于Linux操作系统的周期性任务作业计划的方式控制其运行时间点及重复运行的方式
-
CronJob可以在特定的时间点(反复的)去运行job任务
cronjob 控制器示例
[root@k8s2 pod]# vim cronjob.yml
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob
spec:
schedule: "* * * * *" #每一分钟执行一次
jobTemplate:
spec:
template:
spec:
containers:
- image: myapp:v1
name: myapp
command: ["/bin/sh","-c","date;echo hello"]
restartPolicy: Never #在执行一次后不会自动重启
[root@k8s2 pod]# kubectl apply -f cronjob.yml
效果演示:
[root@k8s-master yaml]# kubectl get pods