[toc]
0x00 Controller 介绍 Q: 什么是资源控制器(资源控制器介绍)? 答:Kubernetes中内建了很多controller(控制器),这些相当于一个状态机,用来控制Pod的具体状态和行为。
Q: 为什么要使用控制器? 答: 前面说过Pod是k8s最小的部署单元,而如果需要创建批量的Pod副本并进行扩容缩以及POD回退
就必须使用Controller进行实现;
Q: 有那些类型的控制器?
(1) Replication Controller 和 ReplicaSet
(2) Deployment
(3) DaemonSet
(4) Job/CronJob
(5) StatefulSet
(6) Horizontal Pod Autoscaling
0x01 Controller 详述 1.Replication Controller Q: 什么是Replication Controller(RC)?
答: ReplicationController是一个基本的控制器类型, 它即我们所说的RC(副本控制器
), 用于确保任意时间都有指定数量的Pod”副本”在运行;
Q: RC它有何作用?
答: 确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的Pod
来替代而如果异常多出来的容器也会自动回收
;
Q: RC工作原理
答: 创建RC之后K8S Master节点上的Controller Manager(控制器管理器)组件接到创建RC的通知进行创建满足副本数相应的Pod, 然后它会定期巡视系统当中的存活的目标Pod, 然后进行标签匹配来监视对应的Pod,并确保目标Pod实例刚好等于RC中定义的副本数期望值,而目标Pod超过副本期望值将会被销毁;
Q: RC组成部分
1) Pod 期待的副本数 Replicas
2) 用于筛选目标Pod的Lable Selector,对应Pod模板(Template)
3) Pod 数量小于副本期望值时根据Pod模板创建相应的Pod
Q: RC使用实例
[toc]
0x00 Controller 介绍 Q: 什么是资源控制器(资源控制器介绍)? 答:Kubernetes中内建了很多controller(控制器),这些相当于一个状态机,用来控制Pod的具体状态和行为。
Q: 为什么要使用控制器? 答: 前面说过Pod是k8s最小的部署单元,而如果需要创建批量的Pod副本并进行扩容缩以及POD回退
就必须使用Controller进行实现;
Q: 有那些类型的控制器?
(1) Replication Controller 和 ReplicaSet
(2) Deployment
(3) DaemonSet
(4) Job/CronJob
(5) StatefulSet
(6) Horizontal Pod Autoscaling
0x01 Controller 详述 1.Replication Controller Q: 什么是Replication Controller(RC)?
答: ReplicationController是一个基本的控制器类型, 它即我们所说的RC(副本控制器
), 用于确保任意时间都有指定数量的Pod”副本”在运行;
Q: RC它有何作用?
答: 确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的Pod
来替代而如果异常多出来的容器也会自动回收
;
Q: RC工作原理
答: 创建RC之后K8S Master节点上的Controller Manager(控制器管理器)组件接到创建RC的通知进行创建满足副本数相应的Pod, 然后它会定期巡视系统当中的存活的目标Pod, 然后进行标签匹配来监视对应的Pod,并确保目标Pod实例刚好等于RC中定义的副本数期望值,而目标Pod超过副本期望值将会被销毁;
Q: RC组成部分
1) Pod 期待的副本数 Replicas
2) 用于筛选目标Pod的Lable Selector,对应Pod模板(Template)
3) Pod 数量小于副本期望值时根据Pod模板创建相应的Pod
Q: RC使用实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 apiVersion: v1 kind: ReplicationCaontroller metadata: name: rc-demo spec: replicas: 3 selector: app: nginx template: metadata: name: nginx lables: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - contianerPort: 80
操作实践: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 kubectl create -f rc-demo.yaml kubectl get rc/rc-demo kubectl describe rc/rc-demo kubectl get pod -l app=nginx kubectl delete pod nginx-* kubectl delete -f rc-demo.yaml
Tips: 我们可以在删除RC时不删除其构建的Pod进行更新修改RC,可以采用delete命令子参数cascade=false
(级联),原RC被删除后可以创建一个新的RC来替换它,前提是旧的和新.spec.selector相匹配,那么新的将会采用旧的Pod; Tips: 官方在新版本的Kubernetes中建议舍弃ReplicationController,切换使用功能能更强的ReplicaSet(RS) 这也是下一节的主要内容;
2.ReplicaSet Q: 什么是ReplicaSet?
答: ReplicaSet即是我们说的(RS)副本集, 它是在k8s v1.2引入可以将它看做是RC的升级版本; 而ReplicaSet跟ReplicationController 没有本质的不同只是名字不一样,然后支持集合式(Set-Based selecor)的 selector【标签】,这使得RS在资源选择上更为灵活;
Q: ReplicaSet有何作用?
答: RS 和 RC 一样都能确保运行满足副本数期望值的Pod; 虽然RS可以独立使用而它主要用于协调Deployment对Pod创建、删除、更新等,当使用Deployment时候不用担心RS因为可以直接通过Deployment对其进行管理;
Tips : 快速查看控制器的apiVsersion1 2 $ kubectl api-versions | grep $(kubectl api-resources | grep "ReplicaSet" | awk -F " " '{print $3}' ) apps/v1
Pod 资源文件示例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 cat > pod-demo.yaml <<'EOF' apiVersion: v1 kind: Pod metadata: name: pod-demo labels: app: pod-demo spec: containers: - name: nginx-pod-demo image: harbor.weiyigeek.top/test/nginx:v1.0 ports: - containerPort: 80 EOF
ReplicaSet 资源文件示例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 cat > replicaset-demo.yaml <<'EOF' apiVersion: apps/v1 kind: ReplicaSet metadata: name: replicaset-demo labels: app: replicaset-demo spec: replicas: 3 selector: matchLabels: app: replicaset-demo matchExpressions: - {key: tier, operator: In, values: {frontend}} template: metadata: labels: app: replicaset-demo spec: containers: - name: nginx-replicaset-demo image: harbor.weiyigeek.top/test/nginx:v1.0 command: ["sh","-c","java -jar nginx-app-${RELASE_VER}.jar"] env: - name: GET_HOSTS_FROM value: dns - name: RELASE_VER value: 1.3 .5 ports: - containerPort: 80 EOF
操作流程:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 ~/K8s/Day5/demo1$ kubectl create -f pod-demo.yaml ~/K8s/Day5/demo1$ kubectl create -f replicaset-demo.yaml ~/K8s/Day5/demo1$ kubectl get pod --show-labels -o wide $ kubectl get rs -o wide $ kubectl exec replicaset-demo-9j457 -it -- env ~/K8s/Day5/demo1$ curl http://10.244.1.{16..19}/host.html ~/K8s/Day5/demo1 $ kubectl delete pod --all ~/K8s/Day5/demo1 $ kubectl get pod --show-labels -o wide ~/K8s/Day5/demo2$ kubectl delete rs replicaset-demo
Tips : 除非需要自定义更新编排或者根本不需要更新,否则建议使用Deployment来创建Pod而不是直接使用ReplicaSets创建Pod;
3.Deployment Q: 什么是Deployment?
答: Deployment 也是在k8s v1.2版本引入,其内部使用了RS进行实现副本期望值数量Pod的创建,即通过RS去创建和管理对应的pod及不同的RS交替去完成滚动更新
。
Q: 为何要使用Deployment?
答: 使用其的主要原因是其支持更新、回滚(Rollback)可以极大节约部署时间以及简化部署流程, 全部在其控制器内部完成对用户是不可见的(Pod 创建过程可以参考上一章的声明周期);
Q: Deployment组成部分
1) 其对象生成RS并完成满足Pod副本数的Pod创建
2) 通过其对象方便升级或者回滚Pod应用 【Deployment自身具备的特点】
3) 通过其对象方便暂停或回复发布 【Deployment自身具备的特点】
4) 通过其对象方便扩容和缩容【RS就已经实现,Deployment通过RS管理Pod因此也支持】
Pod、RelicationController 、ReplicaSet、Deployment关系说明
RelicationController -> Pod (一直满足Pod副本数除非RC被删除)
ReplicaSet -> Pod (一直满足Pod副本数除非RS被删除,较RC其主要特点是支持标签得集合得选择)
Deployment -> ReplicaSet -> Pod (在RS基础之上可用快速完成更新、回滚、扩容、收缩等)
weiyigeek.top-deployment-scale-replicas
Deployment 资源文件示例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 cat > nginx-deployment-demo.yaml<<'EOF' apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment-demo spec: replicas: 3 selector: matchLabels: app: nginx-deployment template: metadata: labels: app: nginx-deployment spec: containers: - name: nginx-deployment image: harbor.weiyigeek.top/test/nginx:v1.0 ports: - containerPort: 80 EOF
演示流程: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 ~/K8s/Day5/demo2$ docker push harbor.weiyigeek.top/test /nginx:v1.0 ~/K8s/Day5/demo2$ docker push harbor.weiyigeek.top/test /nginx:v2.0 ~/K8s/Day5/demo2$ kubectl create -f nginx-deployment-demo.yaml --record ~/K8s/Day5/demo2$ kubectl get deploy -o wide ~/K8s/Day5/demo2$ kubectl get rs ~/K8s/Day5/demo2$ kubectl get pod -o wide --show-labels ~/K8s/Day5/demo2$ curl http://10.244.1.{23..25}/host.html ~/K8s/Day5/demo2$ kubectl scale deployment nginx-deployment-demo --replicas 5 kubectl autoscale deployment nginx-deployment-demo --min=10 --max=15 --cpu-percent=80 kubectl set image deployment/nginx-deployment-demo nginx-deployment=harbor.weiyigeek.top/test /nginx:v2.0 kubectl get rs -o wide ~$ curl http://10.244.1.{38..42}/host.html $ kubectl rollout undo deployment/nginx-deployment-demo $ kubectl rollout status deployment/nginx-deployment-demo $ kubectl rollout history deployment/nginx-deployment-demo ~/K8s/Day5/demo2$ kubectl edit deployment/nginx-deployment-demo ~/K8s/Day5/demo2$ kubectl scale deployment nginx-deployment-demo --replicas 0 ~/K8s/Day5/demo2$ kubectl get pod ~/K8s/Day5/demo2$ kubectl get pod ~/K8s/Day5/demo2$ kubectl delete deploy nginx-deployment-demo ~/K8s/Day5/demo2$ kubectl get pod ~/K8s/Day5/demo2$ kubectl get pod
Tips : Deployment、ReplicaSet和Pod间得命名关系1 2 3 Deployment Name: [Name] ReplicaSet Name: [deployment-name]-[随机字符串] Pod Name: [replicaset-name]-[随机字符串]
Tips: Deployment 更新策略【如果我们需要更新时将会创建出两个RS,其中旧的RS一次减少25%的pod而新的RS一次创建25%的pod
】
Deployment 可以保证在升级时只有一定数量的Pod是down的。默认的,它会确保至少有比期望的Pod数量少一个是up状态(最多一个不可用)
Deployment同时也可以确保只创建出超过期望数量的一定数量的Pod。默认的,它会确保最多比期望的Pod数量多一个的Pod是up的(最多1个surge)
未来的Kuberentes 版本中,将从1-1变成25%-25%1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 ~$ kubectl describe deployments
Tips : Deployment 回滚策略Rollover【多个rollout并行】
只要Deployment的rollout被触发,就会创建一个revision。也就是说当且仅当Deployment的Pod template(如.spec.template
)被更改,例如更新template中的label和容器镜像时,就会创建出一个新的revision。其他的更新,
比如扩容Deployment不会创建revision, 因此我们可以很方便的手动或者自动扩容。这意味着当您回退到历史revision时,只有Deployment中的Pod template
部分才会回退1 2 3 4 5 6 7 8 9 10 11 12 kubectl set image deployment/Pod名称 容器名称=镜像仓库/名称:版本 kubectl rollout status deployments nginx-deployment kubectl get pods kubectl rollout history deployment/nginx-deployment kubectl rollout undo deployment/nginx-deployment kubectl rollout undo deployment/nginx-deployment --to-revision=2 kubectl rollout pause deployment/nginx-deployment
您可以用 kubectl rollout status
命令查看Deployment是否完成。如果 rollout成功完成,kubect1rollout status
将返回一个0值的 Exit Code
【非常值得注意在进行自动化运维脚本编程时非常使用】1 2 3 $ kubect1 rollout status deploy/nginx $ echo $? 0
Tips : Deployment 历史版本策略
您可以通过设置 .spec.revisonHistoryLimit 项来指定 deployment 最多保留多少revision历史记录(缺省revisionHistoryLimit: 10
), 如果将该项设置为 0 Deployment 就不允许回退了
Tips: 命令式 & 申明式编程
命令式编程(rs
) create(优) apply
它侧重于如何实现程序,就像我们刚接触编程的时候那样,我们需要把程序的实现过程按照逻辑结果一步步写下来;
申明式编程(Deployment
)apply(优) create
它侧重于定义想要什么然后告诉计算机/引擎让他帮你去实现, 类似于SQL语句;
4.DaemonSet 描述: 如果我们需要在每一台Node节点上运行一个容器应用, 我们可以采用k8s提供的DaemonSet控制器满足我们的需求; 即 DaemonSet 类似与守护进程的应用程序可用,它能够让所有或指定的Node上运行同一个Pod;
DaemonSet 功能说明:
(1) 当一个新节点加入到k8s集群中时DaemonSet创建的Pod将会被自动调度到该节点之中;
(2) 当一个节点从k8s集群中被移除时DeamonSet创建的Pod也将会从该节点移除;
(3) 如果删除某个创建的DaemonSet所有跟这个DaemonSet相关的Pods在各个节点都将会被删除;
Q:DaemonSet 的应用场景:
示例: 例如 kube-proxy 、kube-system 在每个节点上都有一个Pod;1 2 3 4 ~$ kubectl get daemonsets.apps --all-namespaces
DaemonSet的创建和查看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 cat > daemonset-example.yaml <<'EOF' apiVersion: apps/v1 kind: DaemonSet metadata: name: daemonset-example labels: app: daemonset spec: selector: matchLabels: name: daemonset-example template: metadata: labels: name: daemonset-example spec: containers: - name: daemonset-example image: harbor.weiyigeek.top/test/nginx:v2.0 imagePullPolicy: IfNotPresent resources: limits: cpu: 200 m memory: 200 Mi requests: cpu: 100 m memory: 100 Mi terminationGracePeriodSeconds: 30 EOF
操作流程:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 $ kubectl api-resources | grep "DaemonSet" $ kubectl create -f daemonset-example.yaml ~/K8s/Day5/demo3$ kubectl get ds -o wide ~/K8s/Day5/demo3$ kubectl get pod -o wide --show-labels $ kubectl describe node k8s-master-1 | grep "Taints" Taints: node-role.kubernetes.io/master:NoSchedule $ kubectl taint nodes k8s-master-1 node-role.kubernetes.io/master=:NoSchedule- ~/K8s/Day5/demo3$ kubectl describe node k8s-master-1 | grep "Taints" Taints: <none> ~/K8s/Day5/demo3$ kubectl get ds -o wide ~/K8s/Day5/demo3$ kubectl get pod -o wide --show-labels ~/K8s/Day5/demo3$ curl http://10.244.0.6/host.html ~/K8s/Day5/demo3$ curl http://10.244.1.43/host.html ~/K8s/Day5/demo3$ kubectl taint node k8s-master-1 node-role.kubernetes.io/master=:NoSchedule ~/K8s/Day5/demo3$ kubectl get ds ~$ kubectl get pod -o wide --show-labels ~$ kubectl delete pod daemonset-example-4rvkf $ kubectl -cascade=false delete ds daemonset-example $ kubectl -cascade=true delete ds daemonset-example
PS : 由于污点的原因所有的Pod不会运行在Master节点中,但是我们可以手动或者在资源清单中申明取消污点,或者在yaml资源清单文件中的 ·spec
对象中添加如下;1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ``` **Q: 静态 Pod 与 DaemonSet 的不同点。** > A: 前面我们说过 Static Pod 不受kubectl和其他k8s API 客户端管理,并且不依赖于Api Server,这使得它们在集群启动的情况下非常有用,实际环境中除非有特殊应用请不要使用此种方式; Tips :可以通过 `.spec.template.spec.nodeSelector` 或者 `Affinity` 等高级调度策略部署DaemonSet到指定节点或者拓扑; <br/> ### 5.Job 描述: Job 控制器资源对象有自身的纠错能力, 如果Job运行的脚本(script)没有以0状态码退出的话(或者脚本执行),Job将会重新执行Job负责批处理任务,仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束 即当返回结果为非0的情况下将会重新执行, 并且保证批处理成功执行; <br/> **Q: 什么是Job?** > A: Job负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束 资源对象特殊说明: ```bash ·spec.template 格式同Pod ·RestartPolicy 仅支持 `Never 或 OnFailure` 单个Pod时,默认Pod成功运行后Job即结束 .spec.completions 标志Job结束需要成功运行的Pod个数,默认为1· .spec.parallelism 标志并行运行的Pod的个数,默认为1 ·spec.activeDeadlineseconds 标志失败Pod的重试最大时间,超过这个时间不会继续重试
Job & CronJob 控制器资源类型及版本: 1 2 3 4 5 6 7 $ kubectl api-resources | grep "Job" $ kubectl api-versions | grep $(kubectl api-resources | grep " Job" | awk -F " " '{print $2}' )
Job资源文件示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 cat > job-demo.yaml <<'EOF' apiVersion: batch/v1 kind: Job metadata: name: job-demo-pi spec: template: metadata: name: job-demo-pi spec: containers: - name: busybox-pi image: busybox command: ["/bin/sh","-c","date;echo Job Controller Demo!"] imagePullPolicy: IfNotPresent restartPolicy: Never EOF
操作实例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 ~/K8s/Day5/demo3$ kubectl create -f job-demo.yaml ~/K8s/Day5/demo3$ kubectl get jobs -o wide --show-labels ~/K8s/Day5/demo3$ kubectl get pod -o wide --show-labels ~/K8s/Day5/demo3$ kubectl logs job-demo-pi-p7j59 ~/K8s/Day5/demo3$ kubectl describe pod job-demo-pi-p7j59 ~/K8s/Day5/demo3$ kubectl delete -f job-demo.yaml ~/K8s/Day5/demo3$ kubectl delete jobs --all ~/K8s/Day5/demo3$ kubectl get jobs ~/K8s/Day5/demo3$ kubectl get pod
6.CronJob 5.CronJob【本质上是在特定的时间循环创建Job去实现的】批处理脚本程序可用 CronJob 管理基于时间的Job,即: ·在给定时间点只运行一次 分 时 日 月 周
·周期性地在给定时间点运行 使用前提条件:当前使用的Kubernetes集群,版本>=1.8(对Cronjob)。对于先前版本的集群,版本<1.8,启动API Server时,通过传递选项–runtime-config=batch/v2alpha1=true 可以开启batch/v2alpha1API 典型的用法如下所示: ·在给定的时间点调度Job运行 创建周期性运行的Job,例如:数据库备份、发送邮件
CronJob Spec ·spec.template格式同Pod ·RestartPolicy仅支持Never或OnFailure ·单个Pod时,默认Pod成功运行后Job即结束· .spec.completions标志Job结束需要成功运行的Pod个数,默认为1· .spec.parallelism 标志并行运行的Pod的个数,默认为1 ·spec.activeDeadlineSeconds 标志失败Pod的重试最大时间,超过这个时间不会继续重试
.spec.schedule:调度,必需字段,指定任务运行周期,格式同 Cron· .spec.jobTemplate:Job模板,必需字段,指定需要运行的任务,格式同Job .spec.startingDeadlineSeconds:启动Job的期限(秒级别),该字段是可选的。如果因为任何原因而错过了被调度的时间,那么错过执行时间的Job将被认为是失败的。如果没有指定,则没有期限.spec.concurrencyPolicy:并发策略,该字段也是可选的。 它指定了如何处理被 Cron Job创建的Job的并发执行。只允许指定下面策略中的一种: Allow(默认):允许并发运行Job Forbid:禁止并发运行,如果前一个还没有完成,则直接跳过下一个 Replace:取消当前正在运行的Job,用一个新的来替换 注意,当前策略只能应用于同一个CronJob创建的Job。如果存在多个Cron Job,它们创建的Job之间总是允许并发运行。 .spec.suspend:挂起,该字段也是可选的。如果设置为true,后续所有执行都会被挂起。它对已经开始执行的Job不起作用。默认值为false。 .spec.successfulJobsHistoryLimit和.spec.failed]obsHistoryLimit:历史限制,是可选的字段。它们指定了可以保留多少完成和失败的Job。默认情况下,它们分别设置为3和1。设置限制的值为0,相关类型的Job完成后将不会被保留。
CronJob资源文件示例1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 cat > cronjob-demo.yaml <<'EOF' apiVersion: batch/v1 kind: CronJob metadata: name: cronjob-demo spec: schedule: "*/1 * * * *" jobTemplate: spec: template: spec: containers: - name: cronjob-demo image: busybox args: - /bin/sh - -c - date;echo Hello from the Kubernetes cluster, This is cronjob-demo; imagePullPolicy: IfNotPresent restartPolicy: OnFailure EOF
操作流程:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 ~$ kubectl explain CronJob.spec.jobTemplate.spec.template.spec.containers ~/K8s/Day5/demo3$ kubectl create -f cronjob-demo.yaml cronjob.batch/cronjob-demo created $ kubectl get cj -o wide --show-labels $ kubectl get jobs -o wide ~/K8s/Day5/demo3$ kubectl get pod -o wide --show-labels ~$ kubectl get pod | grep "cronjob" | cut -d " " -f1 ~$ kubectl logs cronjob-demo-1605083580-twsb8 ~$ kubectl logs cronjob-demo-1605083640-dtscf ~$ kubectl logs cronjob-demo-1605083700-64g88 ~/K8s/Day5/demo3$ kubectl delete cronjob --all ~/K8s/Day5/demo3$ kubectl delete -f cronjob-demo.yaml cronjob.batch "cronjob-demo" deleted
PS : Cronjob 本身的一些限制创建Job操作应该是幂等的, CronJob并不太好去判断任务是否成功,CronJob通过创建Job去完成任务,Job成功与否可以判断,但CronJob无法链接到Job去获取成功与否,Cron只会定期的去创建Job仅此而已。
7.StatefulSet 描述: 前面我们学习了RC、RS、Deployment、DaemonSet 与 Job 等它们都是面向无状态服务的,而本节学习的StatefulSet的控制器是有状态服务的即主要用于部署(有状态服务的应用程序)。
在 K8s 中使用 StatefulSet 控制器来部署有状态服务, StatefulSet 是一个给Pod提供唯一标准的控制器,它可以保证部署 和 扩展收缩的顺序;
Q: 什么是有状态服务? 什么又是无状态服务?
A: 服务所维护的与客户交互活动的信息称为状态信息 Stateless Service(无状态服务):在应用程序运行过程之中不保存任何数据和状态信息的服务;例如 Mysql 它需要存储产生的新数据; Stataful Service (有状态服务) : 在应用程序运行过程之中保存的数据或状态的服务;例如 Nginx;
StatefulSet 特征
(1) 稳定(固定)的网络标识符,即Pod重新调度后其 PodName 和 HostName 不变基于Headless Service(即没有Cluster IP的Service)
来实现,例如一个Pod叫做mysql-0,第二个叫做mysql-1,然后依次顺序满足其期望值即n的一个叫做mysql-(n-1)。
(2) 有序部署和有序扩展:基于 init containers 来实现,在第n个Pod启动之间,前一个Pod必须是处于Ready且Running状态;
(3) 稳定的持久化存储:即Pod重新调度后还是能访问到相同的持久化数据,基于PV/PVC、以及StorageClass来实现。
(4) 有序删除和停止: 即从N-1 到 0 Terminal依次销毁;
Statefulset 启停顺序详述:
1.有序部署: 部罢Statefulset时,如果有多个Pod副本,它们会被顺序地创建(从0到N-1)并且,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态
。
2.有序删除: 当Pod被删除时,它们被终止的顺序是从N-1到0。
3.有序扩展: 当对Pod执行扩展操作时,与部署一样,它前面的Pod必须都处于Running和Ready状态
Tips : StatefulSet 除了需要采用PV/PVC持久化Pod状态数据之外还需使用到Headless Service, 该Service为StatefulSet控制的每个Pod创建一个DNS域名,其格式PodName.HeadlessServiceName
1 2 3 mysql-app-1.database mysql-app-2.database
此次是针对于StatefulSet控制器做一个简单的了解后续在进行PVC持久化卷数据时演示;1 2 3 4 5 6 7 8 9 ~$ kubectl api-resources | grep "stateful" ~$ kubectl api-versions | grep "apps" ~$ kubectl get storageclass
资源清单示例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 cat > statefulset-demo.yaml <<'END' apiVersion: v1 kind: Service metadata: name: nginx-statefulset-service labels: app: nginx spec: clusterIP: None selector: app: nginx-sfs ports: - name: web port: 80 --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: selector: matchLabels: app: nginx-sfs serviceName: "nginx-statefulset-service" replicas: 3 template: metadata: labels: app: nginx-sfs spec: containers: - name: nginx image: nginx:1.19.6 ports: - containerPort: 80 name: web volumeMounts: - name: www mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: www spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "managed-nfs-storage" resources: requests: storage: 200 Mi END
构建部署:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ~/K8s/Day5/demo4$ kubectl apply -f statefulset-demo.yaml ~/K8s/Day5/demo4$ kubectl get sts,pvc -o wide | egrep "web" ~/K8s/Day5/demo4$ kubectl get svc | grep "nginx-statefulset-service" ~/K8s/Day5/demo4$ kubectl get ep -o wide | grep "nginx-statefulset-service" ~/K8s/Day5/demo4$ echo "Web-0" > /nfs/data/default-www-web-0-pvc-c1352011-6bc8-450f-941c-d6369ca55ca6/index.html ~/K8s/Day5/demo4$ curl http://10.244.0.247 Web-0
8.Horizontal Pod Autoscaling - 水平扩展 描述: 前面我们知道 Kubernetes 集群可以通过 Replication Controller
的 scale 机制完成服务的扩容或缩容,实现具有伸缩性的服务, 但是其需要我们进行人工干预。
Q: 那么是否有自动完成扩容和收缩的机制? 答: 那就本文主要讲解的 HPA (Horizontal Pod Autoscaling
) 进行服务的 autoscale 自动伸缩;
描述: Horizontal Pod Autoscaling (简称HPA
) 自动扩展, 它可以根据当前pod资源的使用率(如CPU、磁盘、内存等),进行副本数的动态的扩容与缩容,以便减轻各个pod的压力。当pod负载达到一定的阈值后,会根据扩缩容的策略生成更多新的pod来分担压力,当pod的使用比较空闲时,在稳定空闲一段时间后,还会自动减少pod的副本数量。
HPA 起始作用是 Pod 按照一定的策略进行自动扩容缩,例如根据CPU利用率自动伸缩一个 Replication Controller、 Deployment 或者 ReplicaSet
中管理的的Pod副本数量; 您可以简单理解为它并不是一个控制器而是一个控制器的附属品
, 可以使用它去控制其他的控制器,从而使其他的控制器具有自动扩展的功能;
Tips: 若要实现自动扩缩容的功能,还需要部署heapster
服务,用来收集及统计资源的利用率,支持kubectl top命令
,heapster服务集成在prometheus(普罗米修斯) MertricServer服务中,所以说,为了方便,我这里基于prometheus服务的环境上进行部署HPA(动态扩缩容)的服务。
集群资源伸缩方式说明:
sacle 手动伸缩: kubernetes资源对象的升级、回滚、扩容、缩容;
autoscale 自动伸缩:也就是(本篇博文所介绍的HPA);
Kubernetes AutoScale (自动扩展) 主要分为两种方式:
水平扩展:针对实例数目的增减;
垂直扩展:即单个实例就可以使用的资源的增减,比如增加CPU、内存;
简单实例:
1) 构建测试专业的镜像 (#运行构建Deployment的hpa资源,名称为php-apache,并设置请求CPU的资源为200m并暴露一个80端口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 ~/K8s/Day11$ cat > hpa-demo.yaml <<'EOF' kind: Deployment apiVersion: apps/v1 metadata: name: php-apache-deployment labels: app: php-apache-deploy spec: selector: matchLabels: app: php-apache matchExpressions: - key: app operator: In values: [php-apache] template: metadata: labels: app: php-apache spec: containers: - name: nginx image: mirrorgooglecontainers/hpa-example ports: - containerPort: 80 resources: requests: cpu: 128 m memory: 128 Mi limits: cpu: 200 m memory: 200 Mi imagePullPolicy: IfNotPresent --- kind: Service apiVersion: v1 metadata: name: php-apache spec: type: ClusterIP selector: app: php-apache ports: - protocol: TCP port: 80 targetPort: 80 EOF
2) 按照上面的资源清单构建 Deloyment 资源控制器并查看对应的资源;
1 2 3 4 5 6 7 8 9 10 11 12 13 ~/K8s/Day11$ kubectl create -f hpa-demo.yaml ~/K8s/Day11$ kubectl get deployments -o wide ~/K8s/Day11$ kubectl get svc ~/K8s/Day11$ kubectl get replicasets.apps -o wide
(3) 创建HPA控制器(#当hpa资源的deployment资源对象的CPU使用率达到50%时,就进行扩容最多可以扩容到10个
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ~/K8s/Day11$ kubectl autoscale deployment php-apache-deployment --cpu-percent=50 --min=1 --max=10 ~/K8s/Day11$ tee HorizontalPodAutoscaler.yaml <<'EOF' apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: php-apache-deployment namespace: default spec: minReplicas: 1 maxReplicas: 10 scaleTargetRef: kind: Deployment name: php-apache-deployment apiVersion: apps/v1 targetCPUUtilizationPercentage: 50 EOF ~/K8s/Day11$ kubectl get hpa
(4) 模拟消耗php-apache的资源,并验证pod是否会自动扩容与缩容
1 2 3 4 5 6 7 8 9 $ kubectl run -i --tty load-generator --image=busybox /bin/sh $ while true ; do wget -q -O- http://php-apache.default.svc.cluster.local; done $ ab -c 5000 -n 2000000 http://tomcat-svc:8080/
(5) 监控查看hpa资源对cpu的占用情况以及Pod扩容结果;
1 2 3 4 5 6 7 8 9 10 11 ~/K8s/Day11$ watch -n 2 "kubectl get deployments | grep " php-apache-deployment" && kubectl get hpa && kubectl top pod -l app=php-apache" php-apache-deployment 4/4 4 4 6m46s NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE php-apache-deployment Deployment/php-apache-deployment 93%/50% 1 10 4 4m46s NAME CPU(cores) MEMORY(bytes) php-apache-deployment-5c6b89b758-55m2m 122m 12Mi php-apache-deployment-5c6b89b758-gm8rz 0m 2Mi php-apache-deployment-5c6b89b758-s8ldx 118m 12Mi php-apache-deployment-5c6b89b758-wdt9p 0m 0Mi
(6) 当停止死循环请求后,也并不会立即减少pod数量,会等一段时间(大约5分分钟)后减少pod数量(5~10分钟),防止流量再次激增。
1 2 3 4 5 6 7 ~/K8s/Day11$ watch -c -t -n 2 "kubectl get deployments | grep " php-apache-deployment" && kubectl get hpa && kubectl get pod -l app=php-apache"
(7) 至此HPA实现pod副本数量的自动扩容与缩容就实现了,下面可以测试删除策略扩容HPA
1 2 ~/K8s/Day11$ kubectl delete horizontalpodautoscalers.autoscaling php-apache-deployment
Tips: K8s 1.19.x 的 HAP 控制器只能针对于Deployment, ReplicaSet, StatefulSet, or ReplicationController
等资源控制器创建的Pod资源进行扩容缩;1 2 3 4 5 6 7 kubectl create php-apache-test --image=mirrorgooglecontainers/hpa-example --requests=cpu=200m --expose --port=80 kubectl get pod