欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

三、kubernetes之pod控制器

程序员文章站 2024-03-22 22:39:10
...

Pod控制器的作用
上一文中直接创建的Pod是不受Pod控制器管理,也就很难实现K8S的一些特性。

kubelet是K8s集群节点代理程序,它在每个工作节点上都运行着一个实例。当工作节点发生故障时,kubelet也将不可用,pod无法再由kubelet重启。此时Pod的存活性一般由工作节点之外的Pod控制器来保证。

在K8S中理想的工作模式应当是Pod控制器管理Pod,保障Pod资源能按用户所定义的要求工作着。

Pod控制器类型详解
ReplicaSet(简写rs)
是replicationController的改善款,能保障Pod正常工作(出现故障后重启或重建)、保障Pod的正常数量(多退少补),并支持Pod扩缩容。
ReplicaSet 支持集合式的 selector(ReplicationController 仅支持等式)

有三个主要组成模块:

  1. replicas:指定用户期望的副本数
  2. selector:标签选择器,判定哪些Pod接受管理控制
  3. template:Pod资源模板,用于创建新的Pod,该模板定义方式参见pod资源定义

创建ReplicaSet
ngx-relicatSet-yaml内容如下

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: ngx-rs
    tier: frontend
spec:
  replicas: 3   ##指定总共需要3个pod
  selector:     ##通过label选择接受管理的pod
    matchLabels:
      tier: frontend
  template:    ##依据此模板生成Pod
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: ngxv2
        image: 192.168.80.146:5000/my_ngx:v2

将此文件提交给kubernetes集群, 生成相应的pod管理器ReplicaSet及其管理的Pod

[aaa@qq.com k8s-yaml]# kubectl create -f ngx-relicatSet-yaml

查看Pod管理器的状态

[aaa@qq.com k8s-yaml]# kubectl get rs frontend
NAME       DESIRED   CURRENT   READY     AGE
frontend   3         3         3         10m
[aaa@qq.com k8s-yaml]# kubectl describe rs/frontend
Name:         frontend
Namespace:    default
Selector:     tier=frontend
Labels:       app=ngx-rs
              tier=frontend
Annotations:  <none>
Replicas:     3 current / 3 desired
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  tier=frontend
  Containers:
   ngxv2:
    Image:        192.168.80.146:5000/my_ngx:v2
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From                   Message
  ----    ------            ----  ----                   -------
  Normal  SuccessfulCreate  13m   replicaset-controller  Created pod: frontend-6z7wn
  Normal  SuccessfulCreate  13m   replicaset-controller  Created pod: frontend-dp9xv
  Normal  SuccessfulCreate  11m   replicaset-controller  Created pod: frontend-v8dkp

验证非模板创建的Pod和Pod管理器的关系
之前已经创建了管理器replicaSet(frontend),现在建立一个Pod1(label符合管理器的selectot),观察Pod1情况。
Pod1的yaml清单如下:

apiVersion: v1
kind: Pod
metadata:
  name: pod1
  labels:
    tier: frontend  ##此label符合管理器replicaSet中的selector要求,故会受控制
spec:
  containers:
  - name: hello1
    image: 192.168.80.146:5000/my_ngx:v2  

新的Pod将被ReplicaSet获取,并接受管理;因为Pod数量将超过其所需,故将终止新的Pod1。

[aaa@qq.com k8s-yaml]# kubectl get pod -w
NAME             READY     STATUS        RESTARTS   AGE
frontend-6z7wn   1/1       Running       0          24m
frontend-dp9xv   1/1       Running       0          24m
frontend-v8dkp   1/1       Running       0          23m
pod1             0/1       Terminating   0          5s

注意:如果是先创建Pod1,再创建ReplicaSet;那么Pod1会保留运作,创建ReplicaSet时就只依据模板生成两个Pod

从ReplicaSet中删除一个Pod
方法就是修改Pod的label;管理器会自动新建一个Pod替代。

[aaa@qq.com k8s-yaml]# kubectl label pods frontend-6z7wn tier=test --overwrite  
pod/frontend-6z7wn labeled
[aaa@qq.com k8s-yaml]# kubectl get  pods --show-labels            
NAME             READY     STATUS              RESTARTS   AGE       LABELS
frontend-6z7wn   1/1       Running             0          2h        tier=test
frontend-c9h5l   0/1       ContainerCreating   0          5s        tier=frontend
frontend-dp9xv   1/1       Running             0          2h        tier=frontend
frontend-v8dkp   1/1       Running             0          2h        tier=frontend

修改副本集数量
只需更新清单文件中.spec.replicas字段即可扩展或缩小ReplicaSet 。

[aaa@qq.com k8s-yaml]# kubectl apply -f ngx-relicatSet-yaml 
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
replicaset.apps/frontend configured
[aaa@qq.com k8s-yaml]# kubectl get  pods --show-labels      
NAME             READY     STATUS    RESTARTS   AGE       LABELS
frontend-6z7wn   1/1       Running   0          2h        tier=test
frontend-dp9xv   1/1       Running   0          2h        tier=frontend
frontend-v8dkp   1/1       Running   0          2h        tier=frontend

除非需要自定义更新编排或根本不需要更新,否则我们建议使用Deployment;而不是直接使用ReplicaSet。

Deployment
建立在ReplicaSet控制器之上,通过控制RepilicaSet实现对Pod的管理;为Pod和ReplicaSet提供声明式更新。

可以Deployment中描述了所需的状态,Deployment控制器会逐渐将实际状态更新为所需状态。通过定义Deployment以创建新的ReplicaSet,或者删除现有的Deployment并使用新的Deployment接管所有资源。

创建Deployment

一个deployment清单

apiVersion: apps/v1
kind: Deployment
metadata:
   name: ngx-deployment  ##定义一个名为ngx-deployment的deployment
   labels:
      app: ngx
spec:
   replicas: 3   ##定义有三个Pod
   selector:
      matchLabels:  ##定义找到label为app:ngx的pod
         app: ngx
   template:   ##定义pod的模板
      metadata:
         labels:
           app: ngx ##定义pod的label为app:ngx
      spec:
         containers:
         - name: ngxv2
           image: 192.168.80.146:5000/my_ngx:v2

创建此deployment

[aaa@qq.com k8s-yaml]# kubectl apply -f ngx-deployment.yaml 
deployment.apps/ngx-deployment created
[aaa@qq.com k8s-yaml]# kubectl get deployments
NAME             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
ngx-deployment   3         3         3            3           28s
[aaa@qq.com k8s-yaml]# kubectl get rs
NAME                        DESIRED   CURRENT   READY     AGE
ngx-deployment-559486d8fd   3         3         3         12m
[aaa@qq.com k8s-yaml]# kubectl get pods
NAME                              READY     STATUS    RESTARTS   AGE
ngx-deployment-559486d8fd-4c49k   1/1       Running   0          13m
ngx-deployment-559486d8fd-hfht7   1/1       Running   0          13m
ngx-deployment-559486d8fd-pk967   1/1       Running   0          13m

由deployment创建的rs其名字,以deployment的名字为头部。

更新Pod中容器

当且仅当deployment的pod模板(即.spec.template)更改时,才会触发Deployment的滚动更新
例如修改pod中容器版本,由v2降为v1

[aaa@qq.com k8s-yaml]# kubectl edit deployment.v1.apps/ngx-deployment  
"/tmp/kubectl-edit-ltme5.yaml" 69L, 2277C written

注意:不会改变ngx-deployment.yaml,而是生成一个新的临时文件进行kubectl应用

观察滚动更新进度

[aaa@qq.com k8s-yaml]# kubectl rollout status deployment.v1.apps/ngx-deployment
Waiting for deployment "ngx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...

Waiting for deployment "ngx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "ngx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "ngx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "ngx-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "ngx-deployment" successfully rolled out

观察更新后的变化,旧的rs被保留但只运行新的rs和新的pod

[aaa@qq.com k8s-yaml]# kubectl get rs
NAME                        DESIRED   CURRENT   READY     AGE
ngx-deployment-559486d8fd   0         0         0         35m
ngx-deployment-58d847f49c   3         3         3         13m
[aaa@qq.com k8s-yaml]# kubectl get deployment
NAME             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
ngx-deployment   3         3         3            3           35m
[aaa@qq.com k8s-yaml]# kubectl get pods
NAME                              READY     STATUS    RESTARTS   AGE
ngx-deployment-58d847f49c-fjsgr   1/1       Running   0          15m
ngx-deployment-58d847f49c-sjqrq   1/1       Running   0          15m
ngx-deployment-58d847f49c-znw5d   1/1       Running   0          15m

deployment可以确保在更新时只有一定数量的Pod可能会关闭。默认情况下,它确保最多不可用所需数量的25% 还确保在所需数量的Pod之上只能创建一定数量的Pod。默认情况下,它确保最多比所需数量的Pod多25%

例如,如果仔细查看上面的部署,您将看到它首先创建了一个新的Pod,然后删除了一些旧的Pod并创建了新的Pod。在有足够数量的新Pod出现之前,它不会杀死旧的Pod,并且在足够数量的旧Pod被杀之前不会创建新的Pod。它确保可用Pod的数量至少为2,并且Pod的总数最多为4

回滚更新

首先查看之前滚动更新的历史,和具体更新内容

[aaa@qq.com k8s-yaml]# kubectl rollout history deployment.v1.apps/ngx-deployment
deployments "ngx-deployment"
REVISION  CHANGE-CAUSE
3         <none>
4         <none>
[aaa@qq.com k8s-yaml]# kubectl rollout history deployment.v1.apps/ngx-deployment --revision=3
deployments "ngx-deployment" with revision #3
Pod Template:
  Labels:       app=ngx
        pod-template-hash=1150428498
  Containers:
   ngxv2:
    Image:      192.168.80.146:5000/my_ngx:v2
    Port:       <none>
    Host Port:  <none>
    Environment:        <none>
    Mounts:     <none>
  Volumes:      <none>
[aaa@qq.com k8s-yaml]# kubectl rollout history deployment.v1.apps/ngx-deployment --revision=4
deployments "ngx-deployment" with revision #4
Pod Template:
  Labels:       app=ngx
        pod-template-hash=1484039057
  Containers:
   ngxv2:
    Image:      192.168.80.146:5000/my_ngx:v1
    Port:       <none>
    Host Port:  <none>
    Environment:        <none>
    Mounts:     <none>
  Volumes:      <none>

回滚至指定版本

[aaa@qq.com k8s-yaml]# kubectl rollout undo deployment.v1.apps/ngx-deployment --to-revision=3
deployment.apps/ngx-deployment

扩展更新

命令扩展部署
kubectl scale deployment.v1.apps/ngx-deployment --replicas=6
启用自动扩缩
kubectl autoscale deployment.v1.apps/nginx-deployment --min=5 --max=10 --cpu-percent=80

暂停和恢复deployment

可以暂停deployment,然后恢复它。在暂停期间,对deployment的更新将不会被立马执行,需等待恢复deployment。

kubectl rollout pause deployment.v1.apps/ngx-deployment
kubectl set image deployment.v1.apps/ngx-deployment nginx=nginx:1.9.1
kubectl rollout resume deployment.v1.apps/ngx-deployment

deployment其他常用字段说明
.spec.revisionHistoryLimit以指定要保留此部署的旧ReplicaSet数。其余的将在后台进行垃圾收集。默认情况下,它是10。将此字段显式设置为0将导致清理部署的所有历史记录,从而部署将无法回滚。

.spec.strategy指定用于替换旧Pod的策略;Recreate则所有现有的Pod都会在创建新的Pod之前被杀死;RollingUpdate则滚动更新Pod,可以指定maxUnavailable并maxSurge控制滚动更新过程。
maxUnavailable,更新过程中为最多不可用数量,该值可以是绝对数(例如,5)或所需Pod的百分比(例如,10%
maxSurge,更新过程中可以创建的最大Pod数。该值可以是绝对数(例如,5)或所需Pod的百分比(例如,10%)

deployment管理多个rs控制,但只保证一个rs存在工作状态,其他的存在冷备状态。其灰度更新的逻辑顺序如下:
三、kubernetes之pod控制器

DaemonSet
确保所有节点(或指定的一些节点)都运行一个指定Pod。新加入的节点也会自动运行指定的pod;节点退出则所有Pod被回收;删除一个DaemonSet,那他创建的Pod也会清空。
常用语节点级的应用例如:

  1. 运行集群存储 daemon,例如在每个节点上运行 glusterd、ceph。
  2. 在每个节点上运行日志收集daemon,例如fluentd、logstash。
  3. 在每个节点上运行监控 daemon,例如 Prometheus Node、Exporter、collectd

两个模块:
selector:标签选择器,判定哪些Pod接受管理控制
template:Pod资源模板,用于创建新的Pod,该模板定义方式参见pod资源定义

仅在某些节点运行Pod

  1. 指定 .spec.template.spec.nodeSelector字段,DaemonSet Controller 将在能够与 Node
    Selector 匹配的节点上创建 Pod。
  2. 指定 .spec.template.spec.affinity字段, DaemonSet Controller 将在能够与 Node Affinity
    匹配的节点上创建 Pod。

如果根本就没有指定,则 DaemonSet Controller 将在所有节点上创建 Pod。

Job:用于管理执行一次性任务的Pod,正常完成任务就Pod正常退出,不会发生自我修复

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

Cronjob:在给定时间点只运行一次或周期性地运行任务的Pod

StatefullSet:适用于管理有状态的Pod,有一段初始化的过程。以redis集群举例,将从节点升为主节点的操作脚本化,而重建有状态Pod需要先完成脚本化的工作