目录
一、什么是控制器
控制器也是管理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控制器
3.1 replicaset功能
-
ReplicaSet 是下一代的 Replication Controller,官方推荐使用ReplicaSet
-
ReplicaSet和Replication Controller的唯一区别是选择器的支持,ReplicaSet支持新的基于集合的选择器需求
-
ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行
-
虽然 ReplicaSets 可以独立使用,但今天它主要被Deployments 用作协调 Pod 创建、删除和更新的机制
3.2 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 |
3.3 replicaset 示例
生成一个replicaset控制器yaml文件模板
[root@k8s-master deployment]# kubectl create deployment replicaset --image k8s/myapp:v1 --dry-run=client -o yaml > replicaset.yml
编辑yaml文件
[root@k8s-master deployment]# vim replicaset.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
labels:
app: replicaset
name: replicaset#指定pod名称
spec:
replicas: 2#指定维护pod数量为2
selector:#指定检测匹配方式
matchLabels:#指定匹配方式为匹配标签
app: myapp#指定匹配的标签
template:#模板,当副本数量不足时会根据下面的模板创建pod副本
metadata:
labels:
app: myapp
spec:
containers:
- image: k8s/myapp:v1
name: myapp
通过yaml文件创建控制器
[root@k8s-master deployment]# kubectl apply -f replicaset.yml
replicaset.apps/replicaset created
查看pod标签
[root@k8s-master deployment]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
replicaset-7m6k7 1/1 Running 0 20s app=myapp
replicaset-ppz8n 1/1 Running 0 20s app=myapp
修改第一个pod的标签
[root@k8s-master deployment]# kubectl label pod replicaset-7m6k7 app=jcl --overwrite
pod/replicaset-7m6k7 labeled
可以看到修改后replicatset控制器会自动生成一个标签为myapp的pod
[root@k8s-master deployment]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
replicaset-7m6k7 1/1 Running 0 70s app=jcl
replicaset-ppz8n 1/1 Running 0 70s app=myapp
replicaset-z8nh8 1/1 Running 0 2s app=myapp
恢复标签
[root@k8s-master deployment]# kubectl label pod replicaset-7m6k7 app=myapp --overwrite pod/replicaset-7m6k7 labeled
自动删除一个多余的myapp标签的pod
[root@k8s-master deployment]# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS
replicaset-7m6k7 1/1 Running 0 87s app=myapp
replicaset-ppz8n 1/1 Running 0 87s app=myapp
将一个pod删除的话也会自动创建一个标签为myapp的pod
[root@k8s-master deployment]# kubectl delete pods replicaset-7m6k7
pod "replicaset-7m6k7" deleted
[root@k8s-master deployment]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
replicaset-4m2ks 1/1 Running 0 7s app=myapp
replicaset-ppz8n 1/1 Running 0 2m23s app=myapp
四 deployment 控制器
4.1 deployment控制器的功能
-
为了更好的解决服务编排的问题,kubernetes在V1.2版本开始,引入了Deployment控制器。
-
Deployment控制器并不直接管理pod,而是通过管理ReplicaSet来间接管理Pod
-
Deployment管理ReplicaSet,ReplicaSet管理Pod
-
Deployment 为 Pod 和 ReplicaSet 提供了一个申明式的定义方法
-
在Deployment中ReplicaSet相当于一个版本
典型的应用场景:
-
用来创建Pod和ReplicaSet
-
滚动更新和回滚
-
扩容和缩容
-
暂停与恢复
4.2 deployment控制器示例
生成yaml文件
[root@k8s-master deployment]# kubectl create deployment deployment --image k8s/myapp:v1 --dry-run=client -o yaml > deployment.yml
[root@k8s-master deployment]# vim deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment
spec:
replicas: 4
selector:
matchLabels:
app: deployment
template:
metadata:
labels:
app: deployment
spec:
containers:
- image: k8s/myapp:v1
name: myapp
建立pod
[root@k8s-master deployment]# kubectl apply -f deployment.yml
deployment.apps/deployment created
查看pod信息
[root@k8s-master deployment]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
deployment-5fb8bcd94c-289p2 1/1 Running 0 18s app=deployment,pod-template-hash=5fb8bcd94c
deployment-5fb8bcd94c-f87s8 1/1 Running 0 18s app=deployment,pod-template-hash=5fb8bcd94c
deployment-5fb8bcd94c-g8jqk 1/1 Running 0 18s app=deployment,pod-template-hash=5fb8bcd94c
deployment-5fb8bcd94c-qjnw2 1/1 Running 0 18s app=deployment,pod-template-hash=5fb8bcd94c
4.2.1版本迭代
[root@k8s-master deployment]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment-5fb8bcd94c-289p2 1/1 Running 0 54s 10.244.1.7 k8s-node1 <none> <none>
deployment-5fb8bcd94c-f87s8 1/1 Running 0 54s 10.244.1.8 k8s-node1 <none> <none>
deployment-5fb8bcd94c-g8jqk 1/1 Running 0 54s 10.244.2.7 k8s-node2 <none> <none>
deployment-5fb8bcd94c-qjnw2 1/1 Running 0 54s 10.244.2.6 k8s-node2 <none> <none>
查看到当前版本为v1
[root@k8s-master deployment]# curl 10.244.1.7
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
可以看到版本更新策略
[root@k8s-master deployment]# kubectl describe deployments.apps deployment
Name: deployment
Namespace: default
CreationTimestamp: Thu, 05 Sep 2024 14:37:49 +0800
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=deployment
Replicas: 4 desired | 4 updated | 4 total | 4 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
版本升级
[root@k8s-master deployment]# vim deployment.yml
[root@k8s-master deployment]# kubectl apply -f deployment.yml
deployment.apps/deployment configured
[root@k8s-master deployment]kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment-7d54fb7586-dtvvc 1/1 Running 0 2m8s 10.244.1.9 k8s-node1 <none> <none>
deployment-7d54fb7586-gt4gv 1/1 Running 0 2m7s 10.244.1.10 k8s-node1 <none> <none>
deployment-7d54fb7586-qxd4l 1/1 Running 0 2m8s 10.244.2.8 k8s-node2 <none> <none>
deployment-7d54fb7586-vrfp7 1/1 Running 0 2m7s 10.244.2.9 k8s-node2 <none> <none>
可以看到当前版本为v2
[root@k8s-master deployment]# curl 10.244.1.9
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
给yaml文件追加service
[root@k8s-master deployment]# kubectl expose deployment deployment --port 80 --target-port 80 --dry-run=client -o yaml >> deployment.yml
[root@k8s-master deployment]# vim deployment.yml
[root@k8s-master deployment]# kubectl apply -f deployment.yml
deployment.apps/deployment unchanged
service/deployment created
[root@k8s-master deployment]# kubectl get svc deployment
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
deployment ClusterIP 10.111.98.188 <none> 80/TCP 21s
[root@k8s-master deployment]# curl 10.111.98.188
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
4.2.2版本回滚
版本回滚
[root@k8s-master deployment]# 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 deployment]# kubectl apply -f deployment.yml
deployment.apps/deployment configured
service/deployment configured
[root@k8s-master deployment]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment-5fb8bcd94c-5n9dc 1/1 Running 0 21s 10.244.1.12 k8s-node1 <none> <none>
deployment-5fb8bcd94c-fz664 1/1 Running 0 21s 10.244.2.11 k8s-node2 <none> <none>
deployment-5fb8bcd94c-tk6gv 1/1 Running 0 22s 10.244.2.10 k8s-node2 <none> <none>
deployment-5fb8bcd94c-w75j5 1/1 Running 0 22s 10.244.1.11 k8s-node1 <none> <none>
[root@k8s-master deployment]# curl 10.244.1.12
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
4.2.3 滚动更新策略
[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数量多几个
maxUnavailable: 0 #比定义pod个数少几个
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- image: myapp:v1
name: myapp
[root@k8s2 pod]# kubectl apply -f deployment-example.yaml
4.2.4 暂停及恢复
在实际生产环境中我们做的变更可能不止一处,当修改了一处后,如果执行变更就直接触发了
我们期望的触发时当我们把所有修改都搞定后一次触发
暂停,避免触发不必要的线上更新
[root@k8s2 pod]# kubectl rollout pause deployment deployment-example
[root@k8s2 pod]# vim deployment-example.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-example
spec:
minReadySeconds: 5
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
replicas: 6
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: nginx
resources:
limits:
cpu: 0.5
memory: 200Mi
requests:
cpu: 0.5
memory: 200Mi
[root@k8s2 pod]# kubectl apply -f deployment-example.yaml
#调整副本数,不受影响
[root@k8s-master ~]# kubectl describe pods deployment-7f4786db9c-8jw22
Name: deployment-7f4786db9c-8jw22
Namespace: default
Priority: 0
Service Account: default
Node: k8s-node1/172.25.254.10
Start Time: Mon, 02 Sep 2024 00:27:20 +0800
Labels: app=myapp
pod-template-hash=7f4786db9c
Annotations: <none>
Status: Running
IP: 10.244.1.31
IPs:
IP: 10.244.1.31
Controlled By: ReplicaSet/deployment-7f4786db9c
Containers:
myapp:
Container ID: docker://01ad7216e0a8c2674bf17adcc9b071e9bfb951eb294cafa2b8482bb8b4940c1d
Image: myapp:v2
Image ID: docker-pullable://myapp@sha256:5f4afc8302ade316fc47c99ee1d41f8ba94dbe7e3e7747dd87215a15429b9102
Port: <none>
Host Port: <none>
State: Running
Started: Mon, 02 Sep 2024 00:27:21 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-mfjjp (ro)
Conditions:
Type Status
PodReadyToStartContainers True
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-mfjjp:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 6m22s default-scheduler Successfully assigned default/deployment-7f4786db9c-8jw22 to k8s-node1
Normal Pulled 6m22s kubelet Container image "myapp:v2" already present on machine
Normal Created 6m21s kubelet Created container myapp
Normal Started 6m21s kubelet Started container myapp
#但是更新镜像和修改资源并没有触发更新
[root@k8s2 pod]# kubectl rollout history deployment deployment-example
deployment.apps/deployment-example
REVISION CHANGE-CAUSE
3 <none>
4 <none>
#恢复后开始触发更新
[root@k8s2 pod]# kubectl rollout resume deployment deployment-example
[root@k8s2 pod]# kubectl rollout history deployment deployment-example
deployment.apps/deployment-example
REVISION CHANGE-CAUSE
3 <none>
4 <none>
5 <none>
#回收
[root@k8s2 pod]# kubectl delete -f deployment-example.yaml
五 daemonset控制器
5.1 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 要求
5.2 daemonset 示例
该控制器不会运行有污点的节点
[root@k8s-master deployment]# vim daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: daemonset
spec:
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: k8s/myapp:v1
创建pod
[root@k8s-master deployment]# kubectl apply -f daemonset.yml
daemonset.apps/daemonset created
查看pod节点运行状况
[root@k8s-master deployment]# kubectl get pods
NAME READY STATUS RESTARTS AGE
daemonset-24nph 1/1 Running 0 3s
daemonset-2ffz5 1/1 Running 0 3s
没有master上的节点因为有污点
[root@k8s-master deployment]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
daemonset-24nph 1/1 Running 0 22s 10.244.1.19 k8s-node1 <none> <none>
daemonset-2ffz5 1/1 Running 0 22s 10.244.2.18 k8s-node2 <none> <none>
对于污点节点的容忍设置
[root@k8s-master deployment]# vim daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: daemonset
spec:
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
tolerations:
- effect: NoSchedule
operator: Exists
containers:
- name: myapp
image: k8s/myapp:v1
[root@k8s-master deployment]# kubectl apply -f daemonset.yml
daemonset.apps/daemonset configured
[root@k8s-master deployment]# kubectl get pods
NAME READY STATUS RESTARTS AGE
daemonset-czngm 1/1 Running 0 15s
daemonset-h5nrf 1/1 Running 0 16s
daemonset-km25n 1/1 Running 0 17s
[root@k8s-master deployment]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
daemonset-czngm 1/1 Running 0 34s 10.244.2.19 k8s-node2 <none> <none>
daemonset-h5nrf 1/1 Running 0 35s 10.244.1.20 k8s-node1 <none> <none>
daemonset-km25n 1/1 Running 0 36s 10.244.0.4 k8s-master <none> <none>
六 job 控制器
6.1 job控制器功能
Job,主要用于负责批量处理(一次要处理指定数量任务)短暂的一次性(每个任务仅运行一次就结束)任务
Job特点如下:
-
当Job创建的pod执行成功结束时,Job将记录成功结束的pod数量
-
当成功结束的pod达到指定的数量时,Job将完成执行
6.2 job 控制器示例:
[root@k8s-master deployment]# kubectl create job job --image perl:5.34.0 --dry-run=client -o yaml > job.yml
[root@k8s-master deployment]# vim job.yml
apiVersion: batch/v1
kind: Job
metadata:
name: job
spec:
completions: 8
parallelism: 1
backoffLimit: 4
template:
metadata:
spec:
containers:
- image: perl:5.34.0
name: job
command: ["perl","-Mbignum=bpi","-wle","print bpi(2000)"]
restartPolicy: Never
[root@k8s-master deployment]# kubectl apply -f job.yml
job.batch/job created
[root@k8s-master deployment]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
job-fl5jn 0/1 Completed 0 43s 10.244.1.21 k8s-node1 <none> <none>
job-xd4sj 0/1 ContainerCreating 0 18s <none> k8s-node2 <none> <none>
可以看到每次运行一个,依次运行
关于重启策略设置的说明:
如果指定为OnFailure,则job会在pod出现故障时重启容器
而不是创建pod,failed次数不变
如果指定为Never,则job会在pod出现故障时创建新的pod
并且故障pod不会消失,也不会重启,failed次数加1
如果指定为Always的话,就意味着一直重启,意味着job任务会重复去执行了
七 cronjob 控制器
7.1 cronjob 控制器功能
-
Cron Job 创建基于时间调度的 Jobs。
-
CronJob控制器以Job控制器资源为其管控对象,并借助它管理pod资源对象,
-
CronJob可以以类似于Linux操作系统的周期性任务作业计划的方式控制其运行时间点及重复运行的方式。
-
CronJob可以在特定的时间点(反复的)去运行job任务。
7.2 cronjob 控制器
生成yml文件
[root@k8s-master deployment]# kubectl create cronjob cronjob --image k8s/busybox:latest --schedule="* * * * *" --restart OnFailure --dry-run=client -o yaml > cronjob.yml
[root@k8s-master deployment]# vim cronjob.yml
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob
spec:
jobTemplate:
spec:
template:
spec:
containers:
- image: k8s/busyboxplus:latest
name: cronjob
command: ["/bin/sh","-c","date;echo Hello from the Kubernetes cluster"]
restartPolicy: Never
schedule: '* * * * *'
[root@k8s-master deployment]# kubectl apply -f cronjob.yml
cronjob.batch/cronjob created
[root@k8s-master deployment]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
cronjob-28758797-9gps4 0/1 Completed 0 2m16s 10.244.1.37 k8s-node1 <none> <none>
cronjob-28758798-27g5s 0/1 Completed 0 76s 10.244.2.29 k8s-node2 <none> <none>
cronjob-28758799-rpt7m 0/1 Completed 0 16s 10.244.2.30 k8s-node2 <none> <none>
[root@k8s-master deployment]# kubectl logs pods/cronjob-28758795-khc2t
Thu Sep 5 09:15:00 UTC 2024
Hello from the Kubernetes cluster
[root@k8s-master deployment]# kubectl logs pods/cronjob-28758796-pcdgg
Thu Sep 5 09:16:00 UTC 2024