k8s集群安装学习笔记三——资源控制器

简介:

资源控制器
ReplicationController 和 ReplicaSet(RS)
Deployment
Deployment回退
DaemonSet
Job & CronJob
StatefulSet

资源控制器

什么是控制器?
Kubernetes 中内建了很多 controller(控制器),这些相当于一个状态机,用来控制 Pod 的具体状态和行为。
 
控制器类型
ReplicationController(基本淘汰了) 和 ReplicaSet
Deployment
DaemonSet
StateFulSet
Job/CronJob
Horizontal Pod Autoscaling
 
ReplicationController 和 ReplicaSet
ReplicationController(RC)用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退
出,会自动创建新的 Pod 来替代;而如果异常多出来的容器也会自动回收;
在新版本的 Kubernetes 中建议使用 ReplicaSet 来取代 ReplicationController 。ReplicaSet 跟
ReplicationController 没有本质的不同,只是名字不一样,并且 ReplicaSet 支持集合式的 selector;
 
 
Deployment
Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义 (declarative) 方法,用来替代以前的
ReplicationController 来方便的管理应用。典型的应用场景包括;
1.定义 Deployment 来创建 Pod 和 ReplicaSet
2.滚动升级和回滚应用
3.扩容和缩容
4.暂停和继续 Deployment
 
DaemonSet
DaemonSet 确保全部(打了污点的除外)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个
Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod
使用 DaemonSet 的一些典型用法:
1.运行集群存储 daemon,例如在每个 Node 上运行 glusterd 、 ceph
2.在每个 Node 上运行日志收集 daemon,例如 fluentd 、 logstash
3.在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、 collectd 、Datadog 代理、
New Relic 代理,或 Ganglia gmond
 
Job
Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束。
 
CronJob
Cron Job 管理基于时间的 Job,即:
1.在给定时间点只运行一次
2.周期性地在给定时间点运行
* * * * * (分时日月周)和linux的crontab有点类似
 
使用前提条件:**当前使用的 Kubernetes 集群,版本 >= 1.8(对 CronJob)。对于先前版本的集群,版本 < 1.8,
启动 API Server时,通过传递选项 --runtime-config=batch/v2alpha1=true可以开启 batch/v2alpha1API**
 
典型的用法如下所示:
1.在给定的时间点调度 Job 运行
2.创建周期性运行的 Job,例如:数据库备份、发送邮件
 
StatefulSet
前面介绍的控制器都面向无状态服务(Deployments/ReplicaSets)。但是现实场景中有很多有状态的,特别是一些复杂的中间件集群,比如mysql集群、mongodb集群、zookeeper集群等,这些集群有一些共同点:

1.每个节点都有共同的身份ID,通过这个ID,集群中的成员可以相互发现并且通信
2.集群的规模是比较固定的
3.集群中的每个节点都是有状态的,通常会持久化数据到永久存储中
4.如果磁盘损坏,集群中的某个节点会损坏,集群功能受损

所以引入了StatefulSet

其特性如下:
1.稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现,删除Pod时默认不会删除相关联的存储卷
2.稳定唯一的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现。
3.有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),
基于init containers来实现。
4.有序收缩,有序删除(即从N-1到0)
 
Horizontal Pod Autoscaling
应用的资源使用率通常都有高峰和低谷的时候,如何削峰填谷,提高集群的整体资源利用率,让service中的Pod
个数自动调整呢?这就有赖于Horizontal Pod Autoscaling了,顾名思义,使Pod水平自动缩放。
 
 

RS 与 RC 与 Deployment 关联

RC (ReplicationController )主要的作用就是用来确保容器应用的副本数始终保持在用户定义的副本数 。
即如果有容器异常退出,会自动创建新的Pod来替代;而如果异常多出来的容器也会自动回收。
Kubernetes 官方建议使用 RS(ReplicaSet ) 替代 RC (ReplicationController ) 进行部署,RS 跟 RC 没有
本质的不同,只是名字不一样,并且 RS 支持集合式的 selector。
举例一个简单的RS模板:
复制代码
$ vim rs.yaml
apiVersion: extensions/v1beta1 kind: ReplicaSet #kind类型 metadata: #元数据信息 name: frontend spec: #详细描述信息 replicas: 3 #副本数 selector: matchLabels: #标签 tier: frontend #匹配的key:values template: #模板(通过怎样的方式创建RS,以下可以理解为嵌套了一个pod模板信息) metadata: labels: tier: frontend spec: containers: - name: php-redis image: gcr.io/google_samples/gb-frontend:v3 env: - name: GET_HOSTS_FROM value: dns ports: - containerPort: 80
复制代码
kubectl create -f rs.yaml

 

测试自主式pod和资源控制器控制的pod的区别

查看pod状态

kubectl get pod

可以看到所有pod信息,包括在运行的之前创建的自主式pod和上面创建的资源控制器pod

删除所有pod

kubectl delete pod --all

再次查看pod

可以看到删除的自主式Pod没有重新创建,而资源控制器pod会根据期望副本值,重新生成pod。

 

查看选择标签(标签是控制器识别副本数的标记)

kubectl get pod --show-labels

 

 标签也可以修改

kubectl label pod frontend-m8hpc tier=frontend1 --overwrite=True

 

删除rs

kubectl delete rs --all

 

RS 与 Deployment 的关联图例

 

 

Deployment

Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义(declarative)方法,用来替代以前的
ReplicationController 来方便的管理应用。典型的应用场景包括:
1.定义Deployment来创建Pod和ReplicaSet
2.滚动升级和回滚应用
3.扩容和缩容
4.暂停和继续
 
 
Ⅰ、部署一个简单的 Nginx 应用
复制代码
$ vim deployment.yaml
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
复制代码
kubectl create -f deployment.yaml --record  # --record参数可以记录命令,我们可以很方便的查看每次 revision 的变化

 

查看deployment (deployment创建后随即会创建相应的RS)

kubectl get deployment

 

 查看RS

 

 查看pod

 

查看网络

kubectl get pod -o wide

 

 

 从上面结果即可看出deployment、RS、pod的关系

 

Ⅱ、扩容
kubectl scale deployment nginx-deployment --replicas 10

查看扩容后结果

 

Ⅲ、如果集群支持 horizontal pod autoscaling 的话,还可以为Deployment设置自动扩展
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80

 

Ⅳ、更新镜像也比较简单
kubectl set image deployment/nginx-deployment nginx=wangyanglinux/myapp:v2

 

 

Ⅴ、回滚(回滚到上一个版本)
kubectl rollout undo deployment/nginx-deployment

 

 

更新 Deployment
假如我们现在想要让 nginx pod 使用
nginx:1.9.1 的镜像来代替原来的 nginx:1.7.9 的镜像 
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 
deployment "nginx-deployment" image updated

 

可以使用 edit 命令来编辑 Deployment 
$ kubectl edit deployment/nginx-deployment 
deployment "nginx-deployment" edited
 
查看 rollout 的状态
$ kubectl rollout status deployment/nginx-deployment 
Waiting for rollout to finish: 2 out of 3 new replicas have been updated... 
deployment "nginx-deployment" successfully rolled out

 

查看历史 RS 
$ kubectl get rs 
NAME               DESIRED   CURRENT   READY   AGE 
nginx-deployment-1564180365   3       3     0     6s 
nginx-deployment-2035384211   0       0     0     36s

 

Deployment 更新策略 
Deployment 可以保证在升级时只有一定数量的 Pod 是 down 的。默认的,它会确保至少有比期望的Pod数量少一个是up状态(最多一个不可用)
Deployment 同时也可以确保只创建出超过期望数量的一定数量的 Pod。默认的,它会确保最多比期望的Pod数量多一个的 Pod 是 up 的(最多1个 surge )
未来的 Kuberentes 版本中,将从1-1变成25%-25% 
$ kubectl describe deployments

 

Rollover(多个rollout并行)

假如您创建了一个有5个 niginx:1.7.9  replica的 Deployment,但是当还只有3个nginx:1.7.9的 replica 创建出来的时候您就开始更新含有5个 nginx:1.9.1  replica 的 Deployment。
在这种情况下,Deployment 会立即杀掉已创建的3个 nginx:1.7.9 的 Pod,并开始创建 nginx:1.9.1 的 Pod。它不会等到所有的5个nginx:1.7.9 的Pod 都创建完成后才开始改变航道。
 
回退 Deployment 
kubectl set image deployment/nginx-deployment nginx=nginx:1.91 
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 # 可以使用 --revision参数指定 某个历史版本 kubectl rollout pause deployment/nginx-deployment # 暂停deployment 的更新

 

 

可以用 kubectl rollout status 命令查看 Deployment 是否完成。
如果 rollout 成功完成, kubectl rollout status 将返回一个0值的 Exit Code 
$ kubectl rollout status deployment/nginx-deployment 
Waiting for rollout to finish: 2 of 3 updated replicas are available... deployment "nginx-deployment" successfully rolled out 
$ echo $? 
0

 

清理 Policy
可以通过设置 .spec.revisonHistoryLimit项来指定 deployment 最多保留多少 revision 历史记录。
默认的会保留所有的 revision;如果将该项设置为0,Deployment 就不允许回退了。
 
 
 

DaemonSet

什么是 DaemonSet ?
DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一
个 Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod
使用 DaemonSet 的一些典型用法:
1.运行集群存储 daemon,例如在每个 Node 上运行 glusterd 、 ceph
2.在每个 Node 上运行日志收集 daemon,例如 fluentd 、 logstash
3.在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、 collectd 、Datadog 代理、New Relic 代理,或 Ganglia gmond
 
复制代码
$ vim deamonset.yaml
apiVersion: apps/v1 kind: DaemonSet metadata: name: deamonset-example labels: app: deamonset spec: selector: matchLabels: name: deamonset-example #和上面对应,必须一样,否创建不成功(创建出来一个新的pod,标签是deamonset-example,和上面的元数据信息匹配才能成功创建) template: metadata: labels: name: deamonset-example spec: containers: - name: daemonset-example image: wangyanglinux/myapp:v1
复制代码
kubectl create -f deamonset.yaml

 

 
Job
Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束
特殊说明
1.spec.template格式同Pod
2.RestartPolicy仅支持Never或OnFailure
3.单个Pod时,默认Pod成功运行后Job即结束
 
4..spec.completions标志Job结束需要成功运行的Pod个数,默认为1
5..spec.parallelism标志并行运行的Pod的个数,默认为1
6.spec.activeDeadlineSeconds 标志失败Pod的重试最大时间,超过这个时间不会继续重试。
 
在 Job 对象中,负责并行控制的参数有两个:
1. spec.parallelism,它定义的是一个 Job 在任意时间最多可以启动多少个 Pod 同时运行;
2. spec.completions,它定义的是 Job 至少要完成的 Pod 数目,即 Job 的最小完成数
 
Example
复制代码
apiVersion: batch/v1 
kind: Job 
metadata: 
  name: pi 
spec: 
  parallelism: 2 #最大并行数
  completions: 4 #最小完成数
  template: 
    metadata: 
      name: pi 
    spec: 
      containers: 
      - name: pi 
        image: perl 
        command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] 
      restartPolicy: Never   
      #执行成功后不重启,执行失败后Job Controller就会不断地尝试创建一个新Pod,默认重试次数在spec.backoffLimit定义,默认为6
复制代码

 

 
CronJob
Cron Job 管理基于时间的 Job,即:
1.在给定时间点只运行一次
2.周期性地在给定时间点运行
 
使用条件:当前使用的 Kubernetes 集群,版本 >= 1.8(对 CronJob)
 
典型的用法如下所示:
1.在给定的时间点调度 Job 运行
2.创建周期性运行的 Job,例如:数据库备份、发送邮件
 
CronJob Spec
1).spec.schedule :调度,必需字段,指定任务运行周期,格式同 Cron
2).spec.jobTemplate :Job 模板,必需字段,指定需要运行的任务,格式同 Job
3).spec.startingDeadlineSeconds :启动 Job 的期限(秒级别),该字段是可选的。
  如果因为任何原因而错过了被调度的时间,那么错过执行时间的 Job 将被认为是失败的。如果没有指定,则没有期限
4).spec.concurrencyPolicy :并发策略,该字段也是可选的。它指定了如何处理被 Cron Job 创建的 Job 的并发执行。只允许指定下面策略中的一种:
  Allow (默认):允许并发运行 Job
  Forbid :禁止并发运行,如果前一个还没有完成,则直接跳过下一个
  Replace :取消当前正在运行的 Job,用一个新的来替换
  注意,当前策略只能应用于同一个 Cron Job 创建的 Job。如果存在多个 Cron Job,它们创建的 Job 之间总是允许并发运行
5).spec.suspend :挂起,该字段也是可选的。如果设置为 true ,后续所有执行都会被挂起。
  它对已经开始执行的 Job 不起作用。默认值为 false 。
6).spec.successfulJobsHistoryLimit 和 .spec.failedJobsHistoryLimit :历史限制,是可选的字段。
  它们指定了可以保留多少完成和失败的 Job。默认情况下,它们分别设置为 3 和 1 。
  设置限制的值为 0 ,相关类型的 Job 完成后将不会被保留。
 
Example
复制代码
apiVersion: batch/v1beta1 
kind: CronJob 
metadata: 
  name: hello 
spec: 
  schedule: "*/1 * * * *"   #每分钟执行一次
  jobTemplate: 
    spec: 
      template: 
        spec:
          containers: 
          - name: hello 
            image: busybox 
            args: 
            - /bin/sh 
            - -c 
            - date; echo Hello from the Kubernetes cluster 
          restartPolicy: OnFailure #任务执行失败后,Job Controller 不会去尝试创建新的 Pod,但是,它会不断地尝试重启Pod里的容器
复制代码

 

 一段时间后,可看到pod状态变为了Completed,说明任务执行完成,此时查看任务日志,可看到执行结果。

 

如前所述,当一个 Job 的 Pod 运行结束后,它会进入 Completed 状态。但是,如果这个 Pod 因为某种原因一直不肯结束呢?

在 Job 的 API 对象里,有一个 spec.activeDeadlineSeconds 字段可以设置最长运行时间,比如:

spec:
 backoffLimit: 5
 activeDeadlineSeconds: 100

一旦运行超过了 100 s,这个 Job 的所有 Pod 都会被终止。并且,你可以在 Pod 的状态里看到终 止的原因是 reason: DeadlineExceeded

 

 删除任务

复制代码
$ kubectl get cronjob 
NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE 
hello */1 * * * * False 0 <none> 
$ kubectl get jobs 
NAME DESIRED SUCCESSFUL AGE 
hello-1202039034 1 1 49s 
$ pods=$(kubectl get pods --selector=job-name=hello-1202039034 --output=jsonpath= {.items..metadata.name}) 
$ kubectl logs $pods 
Mon Aug 29 21:34:09 UTC 2016 Hello from the Kubernetes cluster 
# 注意,删除 cronjob 的时候不会自动删除 job,这些 job 可以用 kubectl delete job 来删除 
$ kubectl delete cronjob hello 
cronjob "hello" deleted
复制代码

 

CrondJob 本身的一些限制

1.创建Job操作应该是幂等的

2.CronJob并不太好去判断任务是否成功,CronJob通过创建Job去完成任务,Job成功与否可以判断,但CronJob无法链接到Job去获取成功与否,Cron只会定期的去创建Job,仅此而已。

Cron Job 在每次调度运行时间内 大概 会创建一个 Job 对象。我们之所以说 大概 ,是因为在特定的环境下可能会创建两个 Job,或者一个 Job 都没创建。我们尝试少发生这种情况,但却不能完全避免。因此,创建 Job 操作应该是幂等的。

Job 根据它所创建的 Pod 的并行度,负责重试创建 Pod,并就决定这一组 Pod 的成功或失败。Cron Job 根本就不会去检查 Pod

 
posted @   叮伱格斐呃  阅读(275)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2018-09-14 添加操作审计记录
Live2D
欢迎阅读『k8s集群安装学习笔记三——资源控制器』
点击右上角即可分享
微信分享提示