5.3、k8s资源控制器学习

第一节 资源控制器-控制器说明

1.1 相关概念介绍

  1. Pod分类
    • 自主式Pod: Pod退出了, 此类型的Pod不会被创建(无法保证它的稳定性)
    • 控制器管理的pod: 在控制器的生命周期里,始终要维持Pod的副本数目(这是我们最常用的Pod)
  2. 命令式编程:它侧重于如何实现程序,就像我们刚接触编程的时候那样,我们需要把程序的实现过程按照逻辑结果一步步写下来
    • 典型命令:RS的create(最优) apply
  3. 声明式编程:它侧重于定义想要什么,然后告诉计算机/引擎,让他帮你去实现
    • 典型命令:apply(最优) create

1.2 控制器介绍

什么是控制器:Kubernetes内建了很多controller (控制器),这些相当于一个状态机,用来控制Pod的具体状态和行为。
控制器类型
• ReplicationController 和ReplicaSet(RC和RS) RC已经废弃
• Deployment
• DaemonSet
• StateFulSet
• Job/CronJob
• Horizontal Pod Autoscaling
5.3、k8s资源控制器学习

ReplicationController和ReplicaSet介绍

• ReplicationController(RC)用来**确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的Pod来替代;而如果异常多出来的容器也会自动回收;
• 在新版本的Kubernetes中建议使用ReplicaSet 来取代ReplicationController。
• ReplicaSet 跟ReplicationController没有本质的不同,只是名字不一样,并且
ReplicaSet支持集合式的selector;**通过标签选择控
Deployment介绍:(如果在RC和Deployment选择,选Deployment有很多功能。比如:滚动更新RC就做不到)
• Deployment为Pod和ReplicaSet提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController来方便的管理应用。
• 典型的应用场景包括:
• 定义Deployment来创建Pod和ReplicaSet,这里是自动执行的
• 滚动升级和回滚应用
• 扩容和缩容
• 暂停和继续Deployment

DaemonSet介绍(Node节点的)

• DaemonSet确保全部(或者一些) Node上运行一个Pod的副本(注意只有一个,一个Node多个Pod可以定义多个DaemonSet)。当有Node加入集群时,也会为他们新增一个Pod。当Node从集群移除时,这些Pod也会被回收。删除DaemonSet将会删除它创建的所有Pod
• 使用DaemonSet的一些典型用法:
• 运行集群存储daemon,例如在每个Node上运行glusterd、 ceph
• 在每个Node上运行日志收集daemon, 例如fluentd、logstash
• 在每个Node上运行监控daemon,例如Prometheus Node Exporter、 collectd、 Datadog 代理、New Relic代理,或Ganglia gmond

Job介绍:(批处理任务) Job负责批处理任务,即仅执行一次的任务, 它保证批处理任务的一个或多个Pod成功结束

CronJob介绍:(批处理任务)CronJob管理基于时间的Job,即:

• 在给定时间点只运行一次
• 周期性地在给定时间点运行
• 使用前提条件: 当前使用的Kubernetes集群,版本>= 1.8 (对CronJob)。对于先前版本的集群,版本<1.8, 启动API Server时, 通过传递选项- -runtime-config=batch/v2alpha1=true 可以开启batch/v2alpha1 PI

StatefulSet介绍(有状态服务)

• StatefulSet作为Controller为Pod提供唯一的标识。 它可以保证部署和scale的顺序StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),当然也有些有状态服务不方便部署到k8s中比如:Mysql(不稳定)。但是MongoDB就非常适合部署到K8s中的。
• 其应用场景包括:
• 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
• 稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service (即没有Cluster IP的Service)来实现
• 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基initcontainers来实现
• 有序收缩,有序删除(即从N-1到0)

Horizontal Pod Autoscaling(自动拓展,可以理解成控制器的附属品,控制控制器)

• 应用的资源使用率通常都有高峰和低谷的时候,如何削峰填谷,提高集群的整体资源利用率,让service中的Pod个数自动调整呢?这就有赖于Horizontal Pod Autoscaling了,顾名思义,使Pod水平自动缩放,需要给HPA提供资源收集的方案。

第二节 RS与RC与Deployment

2.1 RS与RC与Deployment关联

  1. RC (ReplicationController)主要的作用就是用来确保容器应用的副本数始终保持在用户定义的副本数。即如果有容器异常退出,会自动创建新的Pod来替代:而如果异常多出来的容器也会自动回收。它已经是过去式啦
  2. Kubernetes官方建议使用RS (ReplicaSet )替代RC (ReplicationController) 进行部署,RS 跟RC没有本质的不同,只是名字不一样,并且RS支持集合式的selector

2.2 RS创建模板的(案例)

  1. rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
spec:
  replicas: 3
  selector:    # 选择标签
    matchLabels:    # 匹配标签
      app: frontend   # 标签名
  template:    # 模板
    metadata:
      labels: # 定义标签
        app: frontend
    spec:
      containers:
      - name: myapp
        image: hub.qnhyn.com/library/myapp
        env:   # 注入环境变量
        - name: GET_HOST_FROM
          value: dns
        ports:
        - containerPort: 80
  1. 基础操作如下:

删除默认空间下所有pod

kubectl delete pod --all
kubectl create -f rs.yaml# RS创建的标签查看
kubectl get pod
kubectl explain rs# 查看pod的标签 上面rs.yaml定义的标签
kubectl get pod --show-labels# 修改一个pod的标签
kubectl label pod frontend-dxkrc app=qnhyn --overwrite=True# 删除RS
kubectl delete rs --all
  1. 修改标签后,RS标签为frontend的Pod变成两个,不满足三个的设定因此重新创建一个。而修改后的标签为qnhyn,它不在统计中。

2.3 Deployment模板的案例

5.3、k8s资源控制器学习

  1. vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:    # 选择标签
    matchLabels:    # 匹配标签
      app: nginx-deployment   # 标签名
  template:
    metadata:
      labels:
        app: nginx-deployment
    spec:
      containers:
      - name: nginx
        image: hub.qnhyn.com/library/myapp
        ports:
        - containerPort: 80
  1. 创建Deployment并观察
    加上–record参数可以记录命令,我们可以很方便的查看每次 revision 的变化
kubectl apply -f deployment.yaml --record ## 观察创建deployment
kubectl get deployment # deployment先创建rs
kubectl get rs # deployment通过rs创建pod
kubectl get pod
kubectl get pod -o wide # 访问服务curl 10.244.1.19 

2.4 Deployment实践用法

  1. 拓容
kubectl scale deployment nginx-deployment --replicas=10
  1. 如果集群支持horizontal pod autoscaling的话,还可以为Deployment设置自动扩展
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
  1. 滚动更新(下面镜像修改会触发rs的创建)
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
  1. 回滚(也是滚动操作的)
kubectl rollout undo deployment/nginx-deployment
  1. Deployment更新策略
    • Deployment可以保证在升级时只有一定数量的Pod是down的。默认的,它会确保至少有比期望的Pod数量少一个是up状态(最多一个不可用)
    • Deployment同时也可以确保只创建出超过期望数量的一定数量的Pod。默认的,它会确保最多比期望的Pod数量多一个的 Pod是up的(最多1个surge )
    • 未来的Kuberentes版本中,将从1-1变成25%-25%

通过这个命令可以看到 更新策略

kubectl describe deployments
  1. Rollover (多个rollout并行)
    • 假如您创建了一个有5个I niginx:1.7.9 replica的Deployment,但是当还只有3个nginx:1.7.9 I的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都创建完成后才开始改变航道
  2. 回退Deployment
    • 只要Deployment 的rollout 被触发就会创建一 个revision。 也就是说当且仅当Deployment的Pod template (如、spec. template)被更改,例如更新template中的label和容器镜像时,就会创建出一个新的revision。 其他的更新,比如扩容Deployment 不会创建revision,我们可以很方便的手动或者自动扩容。这意味着当您回退到历史revision时,只有Deployment 中的Pod template部分才会回退

设置新镜像

kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1# 查看更新的状态
kubectl rollout status deployments nginx-deployment
kubectl get pods# 查看历史版本记录
kubectl rollout history deployment/nginx-deployment# 回退到上一版本
kubectl rollout undo deployment/nginx-deployment# 回退到指定历史版本 使用 --revision参数指定某个历史版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2## 暂停deployment的更新 
kubectl rollout pause deployment/nginx-deployment# 您可以用kubectl rollout status 命令查看Deployment是否完成
kubect1 rollout status # 将返回一个0值的Exit Code
kubectl rollout status deploy/nginx
# 查看上一条命令的退出码echo $?
  1. 清理Policy
    • 您可以通过设置. spec . revisonHistoryLimit项来指定deployment最多保留多少revision史记录。默认的会保留所有的revision; 如果将该项设置为0那么Deployment就不允许回退了

第三节 资源管理器-DaemonSet、Job、CronJob

3.1 节点任务DaemonSet定义使用

  1. DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一 个 Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod
  2. vim deamonset-example.yaml
  3. metadata中的name和selector中的name一定要一样。否则可能创建不出Pod
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: deamonset-example
  labels:
    app: daemonset
spec:
  selector:
    matchLabels:
      name: deamonset-example
  template:
    metadata:
      labels:
        name: deamonset-example
    spec:
      containers:
      - name: daemonset-example
        image: hub.qnhyn.com/library/myapp
  1. 基本操作
kubectl create -f deamonset-example.yaml# 默认情况下, Pod不会部署到主节点上 默认副本为1
kubectl get DaemonSet
kubectl get pod -o wide# 删除一个pod
 kubectl delete pod deamonset-example-c24rb# 自动恢复pod
kubectl get pod -o wide
kubectl delete DaemonSet deamonset-example

3.2 批处理任务Job定义使用

  1. Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束
  2. 一些说明
    • spec.template格式同Pod
    • RestartPolicy仅支持Never或OnFailure
    • 单个Pod时,默认Pod成功运行后Job即结束
    • spec.completions 标志Job结束需要成功运行的Pod个数,默认为1
    • spec.parallelism 标志并行运行的Pod的个数,默认为1
    • spec.activeDeadlineSeconds 标志失败Pod的重试大时间,超过这个时间不会继续重试
  3. Perl语言圆周率计算(精确到2000位),永远不重启。vim job.yaml
apiVersion: batch/v1kind: Jobmetadata:
  name: pispec:
  template:
    metadata:
      name: pi
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  1. 基本操作
kubectl create -f job.yaml# 发现一个pi的pod 状态为完成
kubectl get pod# 查看job
kubectl get job# 通过日志查看输出
kubectl logs pi-xvrbg

3.3 CronJob定义使用

  1. CronJob管理基于时间的 Job,即:
    • 在给定时间点只运行一次
    • 周期性地在给定时间点运行
  2. 使用条件:当前使用的 Kubernetes 集群,版本 >= 1.8(对 CronJob)
  3. CronJob Spec字段详解
    • spec.template格式同Pod
    • RestartPolicy仅支持Never或OnFailure
    • 单个Pod时,默认Pod成功运行后Job即结束
    • .spec.completions 标志Job结束需要成功运行的Pod个数,默认为1 .
    • spec.parallelism 标志并行运行的Pod的个数,默认为1
    • spec.activeDeadlineSeconds 标志失败Pod的重试大时间,超过这个时间不会继续重试
  4. 其他字段说明
    • .spec.schedule :调度,必需字段,指定任务运行周期,格式同 Cron
    • .spec.jobTemplate :Job 模板,必需字段,指定需要运行的任务,格式同 Job
    • .spec.startingDeadlineSeconds :启动 Job 的期限(秒级别),该字段是可选的。如果为任何原因而错过了被调度的时间,那么错过执行时间的 Job 将被认为是失败的。如果没有指定,则没有期限
    • .spec.concurrencyPolicy :并发策略,该字段也是可选的。它指定了如何处理被 Cron Job 创建的 Job 的并发执行。只允许指定下面策略中的一种:
    • Allow (默认):允许并发运行 Job
    • Forbid :禁止并发运行,如果前一个还没有完成,则直接跳过下一个
    • Replace :取消当前正在运行的 Job,用一个新的来替换
    • 注意,当前策略只能应用于同一个 Cron Job 创建的 Job。如果存在多个 Cron Job,它们创建的 Job 之间总是允许并发运行。
    • .spec.suspend :挂起,该字段也是可选的。如果设置为 true,后续所有执行都会挂起。它对已经开始执行的 Job 不起作用。默认值为 false 。
    • .spec.successfulJobsHistoryLimit 和 .spec.failedJobsHistoryLimit :历史限制,是可选的字段。它们指定了可以保留多少完成和失败的 Job。默认情况下,它们分别设置为 3 和 1 。设置限制的值为0 ,相关类型的 Job 完成后将不会被保留。
apiVersion: batch/v1beta1kind: CronJobmetadata:
  name: hellospec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure
  1. 基本使用
vi cronjob.yaml
kubectl create -f cronjob.yaml# 查看定时任务
kubectl get cronjob# 一分钟后查看pod
kubectl get pod
kubectl get job# 查看输出
kubectl logs hello-1595068560-9lsr5# 删除定时任务
kubectl delete cronjob hello
  1. 由于CrondJob本身的一些限制,创建 Job 操作应该是幂等的
上一篇:容器、Docker与Kubernetes——什么是Kubernetes以及它是如何使得容器化基础设施


下一篇:使用Kubectl部署应用