Pod控制器(二)Deployment、 DaemonSet、Job、CronJob

 

目录

1.Deployment控制器

1.1创建Deployment

1.2   更新策略

1.3   升级Deployment

1.4   金丝雀发布

1.5 回滚Deployment控制器下的应用发布

1.6    扩容和缩容

2.    DaemonSet控制器

2.1   创建DaemonSet资源对象

2.2  更新DaemonSet对象

3.  Job控制器

3.1   创建Job对象

3.2  并行式Job

4. CronJob控制器

4.1    创建CronJob对象

5.   小结


1.Deployment控制器

Deployment (简写为 deploy )是 Kubernetes 控制器的又一种实现,它构建于 ReplicaSet 控制器之上,可为 Pod ReplicaSet 资源提供声明式 更新。相比较而言, Pod ReplicaSet 是较低级别的资源,它们很少被直 接使用。 Deployment ReplicaSet Pod 的关系如图 5-7 所示。
Pod控制器(二)Deployment、 DaemonSet、Job、CronJob_第1张图片
 
Deployment 控制器资源的主要职责同样是为了保证 Pod 资源的健康运行,其大部分功能均可通过调用 ReplicaSet 控制器来实现,同时还增 添了部分特性。
 
事件和状态查看:必要时可以查看 Deployment 对象升级的详细进度和状态。
  • 回滚:升级操作完成后发现问题时,支持使用回滚机制将应用返回到前一个或由用户指定的历史记录中的版本上。
  • 版本记录:对Deployment对象的每一次操作都予以保存,以供后续可能执行的回滚操作使用。
  • 暂停和启动:对于每一次升级,都能够随时暂停和启动。
  • 多种自动更新方案:一是Recreate,即重建更新机制,全面停止、删除旧有的Pod后用新版本替代;另一个是RollingUpdate,即滚动升级机制,逐步替换旧有的Pod至新的版本

 

1.1创建Deployment

Deployment是标准的Kubernetes API资源,它建构于ReplicaSet资源之上,于是其spec字段中嵌套使用的字段包含了ReplicaSet控制器支持的replicasselectortemplateminReadySeconds,它也正是利用这些信息完成了其二级资源ReplicaSet对象的创建。下面是一个Deployment控制器资源的配置清单示例:

[root@master chapter5]# vim myapp-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80
          name: http

上面的内容显示出,除了控制器类型和名称之外,它与前面ReplicaSet 控制器示例中的内容几乎没有什么不同。下面在集群中创建 以了解它的工作方式:
[root@master chapter5]# kubectl apply -f myapp-deploy.yaml --record
deployment.apps/myapp-deploy created 
“kubectl get deployments” 命令可以列出创建的 Deployment 对象myapp-deploy 及其相关的信息。下面显示的字段中, UP-TO-DATE 表示 已经达到期望状态的 Pod 副本数量, AVAILABLE 则表示当前处于可用 状态的应用程序的数量:

[root@master ~]# kubectl get deployment myapp-deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
myapp-deploy   3/3     3            3           15h

Deployment 控制器会自动创建相关的 ReplicaSet 控制器资源,并以 “[DEPLOYMENT-NAME]-[POD-TEMPLATE-HASH-VALUE]” 格式为 其命名,其中的 hash 值由 Deployment 控制器自动生成。由 Deployment 建的 ReplicaSet 对象会自动使用相同的标签选择器,因此,可使用类似 如下的命令查看其相关的信息:

[root@master ~]# kubectl get replicasets -l app=myapp
NAME                      DESIRED   CURRENT   READY   AGE
myapp-deploy-7ffb5fd5ff   3         3         3       16h

 

相关的 Pod 对象的信息可以用相似的命令进行获取。下面的命令结果中, Pod 对象的名称遵循 ReplicaSet 控制器的命名格式,它以 ReplicaSet 控制器的名称为前缀,后跟 5 位随机字符:

[root@master ~]# kubectl get pods -l app=myapp
NAME                            READY   STATUS    RESTARTS   AGE
myapp-deploy-7ffb5fd5ff-f9d6s   1/1     Running   0          16h
myapp-deploy-7ffb5fd5ff-fgh9z   1/1     Running   0          16h
myapp-deploy-7ffb5fd5ff-wc526   1/1     Running   0          16h

由此印证了 Deployment 借助于 ReplicaSet 管理 Pod 资源的机制,于可以得知,其大部分管理操作与 ReplicaSet 相同。不过, Deployment ReplicaSet 所不具有的部分高级功能,这其中最著名的当数其自动滚 动更新的机制

 

1.2   更新策略

如前所述,ReplicaSet控制器的应用更新需要手动分成多步并以特定的次序进行,过程繁杂且容易出错,而Deployment却只需要由用户指定在Pod模板中要改动的内容,例如容器镜像文件的版本,余下的步骤可交由其自动完成。同样,更新应用程序的规模也只需要修改期望的副本数量,余下的事情交给Deployment控制器即可。

Deployment 控制器详细信息中包含了其更新策略的相关配置信息,如 myapp-deploy 控制器资源 “kubectl describe” 命令中输出的 StrategyType RollingUpdateStrategy 字段等:

[root@master ~]# kubectl describe deployments myapp-deploy
Name:                   myapp-deploy
Namespace:              default
CreationTimestamp:      Mon, 16 Nov 2020 18:32:37 +0800
Labels:                
Annotations:            deployment.kubernetes.io/revision: 1
                        kubernetes.io/change-cause: kubectl apply --filename=myapp-deploy.yaml --record=true
Selector:               app=myapp
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=myapp
  Containers:
   myapp:
    Image:        ikubernetes/myapp:v1
    Port:         80/TCP
    Host Port:    0/TCP
    Environment: 
    Mounts:      
  Volumes:       
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets: 
NewReplicaSet:   myapp-deploy-7ffb5fd5ff (3/3 replicas created)
Events:         

Deployment控制器支持两种更新策略:滚动更新(rolling update)和重新创建(recreate),默认为滚动更新。重新创建更新类似于前文中ReplicaSet的第一种更新方式,即首先删除现有的Pod对象,而后由控制器基于新模板重新创建出新版本资源对象。通常,只应该在应用的新旧版本不兼容(如依赖的后端数据库的schema不同且无法兼容)时运行时才会使用recreate策略,因为它会导致应用替换期间暂时不可用,好处在于它不存在中间状态,用户访问到的要么是应用的新版本,要么是旧版本。

 

滚动升级是默认的更新策略,它在删除一部分旧版本Pod资源的同时,补充创建一部分新版本的Pod对象进行应用升级,其优势是升级期 间,容器中应用提供的服务不会中断,但要求应用程序能够应对新旧版本同时工作的情形,例如新旧版本兼容同一个数据库方案等。不过,更新操作期间,不同客户端得到的响应内容可能会来自不同版本的应用。

Deployment 控制器的滚动更新操作并非在同一个 ReplicaSet 控制器对象下删除并创建 Pod 资源,而是将它们分置于两个不同的控制器之 下:旧控制器的 Pod 对象数量不断减少的同时,新控制器的 Pod 对象数量 不断增加,直到旧控制器不再拥有 Pod 对象,而新控制器的副本数量变 得完全符合期望值为止,如图 5-8 所示。
 

Pod控制器(二)Deployment、 DaemonSet、Job、CronJob_第2张图片

滚动更新时,应用升级期间还要确保可用的 Pod 对象数量不低于某阈值以确保可以持续处理客户端的服务请求,变动的方式和 Pod 对象的 数量范围将通过 spec.strategy.rollingUpdate.maxSurge spec.strategy.rollingUpdate.maxUnavailable 两个属性协同进行定义,它们 的功用如图 5-9 所示。
 
  • maxSurge:指定升级期间存在的总Pod对象数量最多可超出期望值的个数,其值可以是0或正整数,也可以是一个期望值的百分比;如,如果期望值为3,当前的属性值为1,则表示Pod对象的总数不能超4
  • maxUnavailable:升级期间正常可用的Pod副本数(包括新旧版本)最多不能低于期望数值的个数,其值可以是0或正整数,也可以是一个期望值的百分比;默认值为1,该值意味着如果期望值是3,则升级期间至少要有两个Pod对象处于正常提供服务的状态。

Pod控制器(二)Deployment、 DaemonSet、Job、CronJob_第3张图片

 
 
注意 maxSurge maxUnavailable 属性的值不可同时为 0 ,否 Pod 对象的副本数量在符合用户期望的数量后无法做出合理变动以进 行滚动更新操作。
 
 
Deployment 控制器也支持用户保留其滚动更新历史中的旧ReplicaSet 对象版本,如图 5-10 所示,这赋予了控制器进行应用回滚的能力:用户可按需回滚到指定的历史版本。控制器可保存的历史版本数量 “spec.revisionHistoryLimit” 属性进行定义。当然,也只有保存于 revision 历史中的 ReplicaSet 版本可用于回滚,因此,用户要习惯性地在 更新操作时指定保留旧版本。
Pod控制器(二)Deployment、 DaemonSet、Job、CronJob_第4张图片
 
 
 
注意 为了保存版本升级的历史,需要在创建 Deployment 对象时于命令中使用 “--record” 选项。
 
尽管滚动更新以节约系统资源著称,但它也存在一些劣势。直接改动现有环境,会使系统引入不确定性风险,而且升级过程出现问题后, 执行回滚操作也会较为缓慢。有鉴于此,金丝雀部署可能是较为理想的 实现方式,当然,如果不考虑系统资源的可用性,那么传统的蓝绿部署 也是不错的选择
 

 

1.3   升级Deployment

修改 Pod 模板相关的配置参数便能完成 Deployment 控制器资源的更新。由于是声明式配置,因此对 Deployment 控制器资源的修改尤其适合 使用 apply patch 命令来进行;当然,如果仅是修改容器镜像, “set image” 命令更为易用。
 
接下来通过更新此前创建的 Deployment 控制器 deploy-example 来了解更新操作过程的执行细节,为了使得升级过程更易于观测,这里先使 “kubectl patch” 命令为其 spec.minReadySeconds 字段定义一个等待时 长,例如 5s

[root@master ~]# kubectl patch deployments myapp-deploy -p '{"spec":{"minReadySeconds":5}}'
deployment.apps/myapp-deploy patched

patch 命令的补丁形式为 JSON 格式,以 -p 选项指定,上面命令中的 '{"spec" {"minReadySeconds" 5}}' 表示设置 spec.minReadySeconds 性的值。若要改变 myapp-deploy myapp 容器的镜像,也可使用 patch 令,如 '{"spec" {"containers" ["name" "myapp" "image""ikubernetes/myapp v2"}} 不过,修改容 器镜像有更为简单的专用命令 “set image”
 
 
注意 修改 Deployment 控制器的 minReadySeconds replicas strategy 等字段的值并不会触发 Pod 资源的更新操作,因为它们不属于模 板的内嵌字段,对现存的 Pod 对象不产生任何影响。
 
接着,使用 “ikubernetes/myapp v2” 镜像文件修改 Pod 模板中的myapp 容器,启动 Deployment 控制器的滚动更新过程:

[root@master ~]# kubectl set image deployments myapp-deploy myapp=ikubernetes/myapp:v2
deployment.apps/myapp-deploy image updated

“kubectl rollout status” 命令可用于打印滚动更新过程中的状态信息:

[root@master ~]# kubectl rollout status deployments myapp-deploy
Waiting for deployment "myapp-deploy" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "myapp-deploy" rollout to finish: 1 old replicas are pending termination...
deployment "myapp-deploy" successfully rolled out

另外,还可以使用 “kubectl get deployments--watch” 命令监控其更新过程中 Pod 对象的变动过程

[root@master ~]# kubectl get deployments myapp-deploy --watch
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
myapp-deploy   3/3     3            3           20h

滚动更新时, myapp-deploy 控制器会创建一个新的 ReplicaSet 控制器对象来管控新版本的 Pod 对象,升级完成后,旧版本的 ReplicaSet 会保留 在历史记录中,但其此前的管控 Pod 对象将会被删除。

[root@master ~]# kubectl get replicasets -l app=myapp
NAME                      DESIRED   CURRENT   READY   AGE
myapp-deploy-7ffb5fd5ff   0         0         0       20h
myapp-deploy-d79f57d9d    3         3         3       24m

myapp-deploy 控制器管控的 Pod 资源对象也将随之更新为以新版本ReplicaSet 名称“myapp-deploy-d79f57d9d ”为前缀的 Pod 副本,命令结果 如下所示:

[root@master ~]# kubectl get pods -l app=myapp
NAME                           READY   STATUS    RESTARTS   AGE
myapp-deploy-d79f57d9d-5ppns   1/1     Running   0          26m
myapp-deploy-d79f57d9d-vczft   1/1     Running   0          26m
myapp-deploy-d79f57d9d-w4xg6   1/1     Running   0          26m

由于已经处于 READY 状态,因此上面命令列出的任一 Pod 资源均可正常向用户提供相关服务,例如,在集群内任一能使用 kubectl 的节点访 myapp-deploy-79859f456c-29rqw 中的 Web 服务,命令如下:

[root@master ~]# curl $(kubectl get pods myapp-deploy-d79f57d9d-5ppns -o go-template={{.status.podIP}})
Hello MyApp | Version: v2 | Pod Name

 
 
 

1.4   金丝雀发布

Deployment 控制器还支持自定义控制更新过程中的滚动节奏,如 暂停 pause )或 继续 resume )更新操作,尤其是借助于前文讲 到的 maxSurge maxUnavailable 属性还能实现更为精巧的过程控制。比 如,待第一批新的 Pod 资源创建完成后立即暂停更新过程,此时,仅存 在一小部分新版本的应用,主体部分还是旧的版本。然后,再根据用户 特征精心筛选出小部分用户的请求路由至新版本的 Pod 应用,并持续观 察其是否能稳定地按期望的方式运行。确定没有问题后再继续完成余下 Pod 资源的滚动更新,否则立即回滚更新操作。这便是所谓的金丝雀发 布( Canary Release ),如图 5-11 所示。
Pod控制器(二)Deployment、 DaemonSet、Job、CronJob_第5张图片
 
为了尽可能地降低对现有系统及其容量的影响,金丝雀发布过程通常建议采用 先添加、再删除,且可用 Pod 资源对象总数不低于期望 的方式进行。首次添加的 Pod 对象数量取决于其接入的第一批请求的 规则及单个 Pod 的承载能力,视具体需求而定,为了能够更简单地说明 问题,接下来采用首批加 1 Pod 资源的方式。将 Deployment 控制器的 maxSurge 属性的值设置为 1 ,并将 maxUnavailable 属性的值设置为 0

[root@master ~]#  kubectl patch deployments myapp-deploy  -p '{"spec": {"strategy":{"rollingUpdate": {"maxSurge": 1, "maxUnavailable": 0}}}}'
deployment.apps/myapp-deploy patched

接下来,启动 myapp-deploy 控制器的更新过程,在修改相应容器的镜像版本后立即暂停更新进度,它会在启动第一批新版本 Pod 对象的创 建操作之后转为暂停状态。需要注意的是,这里之所以能够在第一批更 新启动后就暂停,有赖于此前为 maxReadySeconds 属性设置的时长,因 此用户要在更新命令启动后的此时长指定的时间范围内启动暂停操作, 其执行过程如图 5-12 所示。当然,对 kubectl 命令来说,也可以直接 “&&” 符号在 Shell 中连接两个命令:

[root@master ~]#  kubectl set image deployments myapp-deploy myapp=ikubernetes/myapp:v3  && kubectl rollout pause deployments myapp-deploy
deployment.apps/myapp-deploy image updated
deployment.apps/myapp-deploy paused

Pod控制器(二)Deployment、 DaemonSet、Job、CronJob_第6张图片
 
 
 
 
通过其状态查看命令可以看到,在创建完一个新版本的 Pod资源后滚动更新操作 暂停
[root@master ~]# kubectl rollout status deployments myapp-deploy
Waiting for deployment "myapp-deploy" rollout to finish: 1 out of 3 new replicas have been updated...
相关的 Pod 列表也可能显示旧版本的 ReplicaSet 的所有 Pod 副本仍在正常运行,新版本的 ReplicaSet 也包含一个 Pod 副本,但最多不超过期望 1 个, myapp-deploy 原有的期望值为 3 ,因此总数不超过 4 个。此时, 通过 Service Ingress 资源及相关路由策略等设定,即可将一部分用户的 流量引入到这些 Pod 之上进行发布验证。运行一段时间后,如果确认没 有问题,即可使用 “kubectl rollout resume” 命令继续此前的滚动更新过 程:

[root@master ~]# kubectl rollout resume deployments myapp-deploy
deployment.apps/myapp-deploy resumed

“kubectl rollout status” 命令监控到滚动更新过程完成后,即可通过myapp-deploy 控制器及其 ReplicaSet Pod 对象的相关信息来了解其结果 状态。
然而,如果 金丝雀 遇险甚至遭遇不幸,那么回滚操作便成了接下来的当紧任务。
 
 

1.5 回滚Deployment控制器下的应用发布

若因各种原因导致滚动更新无法正常进行,如镜像文件获取失败、 金丝雀” 遇险等,则应该将应用回滚到之前的版本,或者回滚到由用户指定的历史记录中的版本。 Deployment 控制器的回滚操作可使 “kubectl rollout undo” 命令完成,例如,下面的命令可将 myapp-deploy 回滚至此前的版本:
 

[root@master ~]# kubectl rollout undo deployments myapp-deploy
deployment.apps/myapp-deploy rolled back

等回滚完成后,验证 myapp-deploy ReplicaSet 控制器对象是否已恢复到指定的历史版本以确保其回滚正常完成。在 “kubectl rollout undo” 令上使用 “--to-revision” 选项指定 revision 号码即可回滚到历史特定版本, 例如,假设 myapp-deploy 包含如下的 revision 历史记录:
 

[root@master ~]# kubectl rollout history deployments myapp-deploy
deployment.apps/myapp-deploy
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=myapp-deploy.yaml --record=true
3         kubectl apply --filename=myapp-deploy.yaml --record=true
4         kubectl apply --filename=myapp-deploy.yaml --record=true

若要回滚到号码为 3 revision 记录,则使用如下命令即可完成:
[root@master ~]#  kubectl rollout undo deployments myapp-deploy --to-revision=3
deployment.apps/myapp-deploy rolled back
回滚操作中,其 revision 记录中的信息会发生变动,回滚操作会被当作一次滚动更新追加进历史记录中,而被回滚的条目则会被删除。需 要注意的是,如果此前的滚动更新过程处于 暂停 状态,那么回滚操作 就需要先将 Pod 模板的版本改回到之前的版本,然后 继续 更新,否 则,其将一直处于暂停状态而无法回滚。
 
 

1.6    扩容和缩容

通过修改 .spec.replicas 即可修改 Deployment 控制器中 Pod 资源的副本数量,它将实时作用于控制器并直接生效。 Deployment 控制器是声明式 配置, replicas 属性的值可直接修改资源配置文件,然后使用 “kubectl apply” 进行应用,也可以使用 “kubectl edit” 对其进行实时修改。而前一 种方式能够将修改结果予以长期留存。
另外, “kubectl scale” 是专用于扩展某些控制器类型的应用规模的命令,包括 Deployment Job 等。而 Deployment 通过 ReplicaSet 控制其 Pod 源,因此扩缩容的方式是相同的,除了命令直接作用的资源对象有所不 同之外,这里不再对其进行展开说明。
 
 

2.    DaemonSet控制器

DaemonSetPod控制器的又一种实现,用于在集群中的全部节点上同时运行一份指定的Pod资源副本,后续新加入集群的工作节点也会自动创建一个相关的Pod对象,当从集群移除节点时,此类Pod对象也将被自动回收而无须重建。管理员也可以使用节点选择器及节点标签指定仅在部分具有特定特征的节点上运行指定的Pod对象。

DaemonSet 是一种特殊的控制器,它有特定的应用场景,通常运行那些执行系统级操作任务的应用,其应用场景具体如下。
  • 运行集群存储的守护进程,如在各个节点上运行glusterdceph
  • 在各个节点上运行日志收集守护进程,如fluentdlogstash
  • 在各个节点上运行监控系统的代理守护进程,如Prometheus NodeExportercollectdDatadog agentNew Relic agentGanglia gmond等。
 
当然,既然是需要运行于集群内的每个节点或部分节点,于是很多场景中也可以把应用直接运行为工作节点上的系统级守护进程,不过, 这样一来就失去了运用 Kubernetes 管理所带来的便捷性。另外,也只有 必须将 Pod 对象运行于固定的几个节点并且需要先于其他 Pod 启动时,才 有必要使用 DaemonSet 控制器,否则就应该使用 Deployment 控制器。
 

2.1   创建DaemonSet资源对象

DaemonSet 控制器的 spec 字段中嵌套使用的字段同样主要包了前面讲到的 Pod 控制器资源支持的 selector template minReadySeconds ,并 且功能和用法基本相同,但它不支持使用 replicas ,毕竟 DaemonSet 并不 是基于期望的副本数来控制 Pod 资源数量,而是基于节点数量,但 template 是必选字段。
下面的资源清单文件( filebeat-ds.yaml )示例中定义了一个名为filebeat-ds DaemonSet 控制器,它将在每个节点上运行一个 filebeat 进程 以收集容器相关的日志数据:

[root@master chapter5]# vim filebeat-ds.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: filebeat-ds
  labels:
    app: filebeat
spec:
  selector:
    matchLabels:
      app: filebeat
  template:
    metadata:
      labels:
        app: filebeat
      name: filebeat
    spec:
      containers:
      - name: filebeat
        image: ikubernetes/filebeat:5.6.5-alpine
        env:
        - name: REDIS_HOST
          value: db.ikubernetes.io:6379
        - name: LOG_LEVEL
          value: info

通过清单文件创建 DaemonSet 资源的命令与其他资源的创建并无二致

[root@master chapter5]# kubectl apply -f filebeat-ds.yaml
daemonset.apps/filebeat-ds created

注意 Kubernetes 1.8 版本起, DaemonSet 也必须使用selector 来匹配 Pod 模板中指定的标签,而且它也支持 matchLabels matchExpressions 两种标签选择器。
 
与其他资源对象相同,用户也可以使用 “kubectl describe” 命令查看DaemonSet 对象的详细信息。下面命令的结果信息中, Node-Selector 段的值为空,表示它需要运行于集群中的每个节点之上。而当前集群的 节点数量为 2 ,因此,其期望的 Pod 副本数( Desired Number of Nodes Scheduled )为 2 ,而当前也已经成功创建了 2 个相关的 Pod 对象:

[root@master chapter5]# kubectl describe daemonsets filebeat-ds
Name:           filebeat-ds
Selector:       app=filebeat
Node-Selector: 
Labels:         app=filebeat
Annotations:    deprecated.daemonset.template.generation: 1
Desired Number of Nodes Scheduled: 2
Current Number of Nodes Scheduled: 2
Number of Nodes Scheduled with Up-to-date Pods: 2
Number of Nodes Scheduled with Available Pods: 2
Number of Nodes Misscheduled: 0
Pods Status:  2 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=filebeat
  Containers:
   filebeat:
    Image:      ikubernetes/filebeat:5.6.5-alpine
    Port:      
    Host Port: 
    Environment:
      REDIS_HOST:  db.ikubernetes.io:6379
      LOG_LEVEL:   info
    Mounts:       
  Volumes:        
Events:
  Type    Reason            Age    From                  Message
  ----    ------            ----   ----                  -------
  Normal  SuccessfulCreate  3m51s  daemonset-controller  Created pod: filebeat-ds-pqmmk
  Normal  SuccessfulCreate  3m51s  daemonset-controller  Created pod: filebeat-ds-q6vxt

根据 DaemonSet 资源本身的意义, filebeat-ds 控制器成功创建的 2 个Pod 对象应该分别运行于集群中的每个节点之上,这一点可以通过如下 命令进行验证:

[root@master chapter5]# kubectl get pods -l app=filebeat
NAME                READY   STATUS    RESTARTS   AGE
filebeat-ds-pqmmk   1/1     Running   0          7m44s
filebeat-ds-q6vxt   1/1     Running   0          7m44s

[root@master chapter5]# kubectl get pods -l app=filebeat -o wide
NAME                READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
filebeat-ds-pqmmk   1/1     Running   0          14m   10.244.1.20   node1             
filebeat-ds-q6vxt   1/1     Running   0          14m   10.244.2.25   node2             

 

 

 

2.2  更新DaemonSet对象

DaemonSetKubernetes 1.6版本起也开始支持更新机制,相关配置定义在spec.update-Strategy嵌套字段中。目前,它支持RollingUpdate(滚动更新)和OnDelete(删除时更新)两种更新策略,滚动更新为默认的更新策略,工作逻辑类似于Deployment控制,不过仅 支持使用maxUnavailabe属性定义最大不可用Pod资源副本数(默认值为1),而删除时更新的方式则是在删除相应节点的Pod资源后重建并更新为新版本。

例如,将此前创建的 filebeat-ds Pod 模板中的容器镜像升级为 “ikubernetes/filebeat 5.6.6-alpine” ,使用 “kubectl set image” 命令即可 实现:

[root@master ~]# kubectl set image daemonsets filebeat-ds filebeat=ikubernetes/filebeat:5.6.6-alpine
daemonset.apps/filebeat-ds image updated

由下面命令的返回结果可以看出, filebeat-ds 控制器 Pod 模板中的容器镜像文件已经完成更新,对滚动更新策略来说,它会自动触发更新操 作。用户也可以通过 filebeat-ds 控制器的详细信息中的 Events 字段等来了 解滚动更新的操作过程。由下面的命令结果可以看出,默认的滚动更新 策略是一次删除一个工作节点上的 Pod 资源,待其新版本 Pod 资源重建完 成后再开始操作另一个工作节点上的 Pod 资源:

[root@master ~]# kubectl describe daemonsets filebeat-ds

Events:
  Type    Reason            Age    From                  Message
  ----    ------            ----   ----                  -------
  Normal  SuccessfulCreate  27m    daemonset-controller  Created pod: filebeat-ds-pqmmk
  Normal  SuccessfulCreate  27m    daemonset-controller  Created pod: filebeat-ds-q6vxt
  Normal  SuccessfulDelete  4m44s  daemonset-controller  Deleted pod: filebeat-ds-pqmmk
  Normal  SuccessfulCreate  4m42s  daemonset-controller  Created pod: filebeat-ds-xdp5p
  Normal  SuccessfulDelete  2m40s  daemonset-controller  Deleted pod: filebeat-ds-xdp5p
  Normal  SuccessfulCreate  2m38s  daemonset-controller  Created pod: filebeat-ds-d6x2m
  Normal  SuccessfulDelete  2m20s  daemonset-controller  Deleted pod: filebeat-ds-q6vxt
  Normal  SuccessfulCreate  2m18s  daemonset-controller  Created pod: filebeat-ds-jw5p2

或者也可以在执行kubectl set image daemonsets filebeat-ds filebeat=ikubernetes/filebeat:5.6.6-alpine命令时重新打开一个终端查看镜像得更新情况

[root@master chapter5]# kubectl get pods -l app=filebeat  -w
NAME                READY   STATUS    RESTARTS   AGE
filebeat-ds-pqmmk   1/1     Running   0          21m
filebeat-ds-q6vxt   1/1     Running   0          21m
filebeat-ds-pqmmk   1/1     Terminating   0          22m
filebeat-ds-pqmmk   0/1     Terminating   0          22m
filebeat-ds-pqmmk   0/1     Terminating   0          22m
filebeat-ds-pqmmk   0/1     Terminating   0          22m
filebeat-ds-xdp5p   0/1     Pending       0          0s
filebeat-ds-xdp5p   0/1     Pending       0          0s
filebeat-ds-xdp5p   0/1     ContainerCreating   0          0s
filebeat-ds-xdp5p   0/1     ErrImagePull        0          14s
filebeat-ds-xdp5p   0/1     ImagePullBackOff    0          26s
filebeat-ds-xdp5p   0/1     ErrImagePull        0          50s
filebeat-ds-xdp5p   0/1     ImagePullBackOff    0          62s
filebeat-ds-xdp5p   0/1     ErrImagePull        0          82s
filebeat-ds-xdp5p   0/1     ImagePullBackOff    0          95s
filebeat-ds-xdp5p   0/1     Terminating         0          2m2s
filebeat-ds-xdp5p   0/1     Terminating         0          2m4s
filebeat-ds-xdp5p   0/1     Terminating         0          2m4s
filebeat-ds-d6x2m   0/1     Pending             0          0s
filebeat-ds-d6x2m   0/1     Pending             0          0s
filebeat-ds-d6x2m   0/1     ContainerCreating   0          0s
filebeat-ds-d6x2m   1/1     Running             0          18s
filebeat-ds-q6vxt   1/1     Terminating         0          24m
filebeat-ds-q6vxt   0/1     Terminating         0          24m
filebeat-ds-q6vxt   0/1     Terminating         0          25m
filebeat-ds-q6vxt   0/1     Terminating         0          25m
filebeat-ds-jw5p2   0/1     Pending             0          0s
filebeat-ds-jw5p2   0/1     Pending             0          0s
filebeat-ds-jw5p2   0/1     ContainerCreating   0          0s
filebeat-ds-jw5p2   1/1     Running             0          18s

查看 Pod 模板中的容器镜像是否升级为 “ikubernetes/filebeat 5.6.6-alpine“
[root@master ~]# kubectl get ds -o wide
NAME          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE   CONTAINERS   IMAGES                              SELECTOR
filebeat-ds   2         2         2       2            2                     31m   filebeat     ikubernetes/filebeat:5.6.6-alpine   app=filebeat
 
 

3.  Job控制器

Deployment DaemonSet 控制器管理的守护进程类的服务应用不同的是, Job 控制器用于调配 Pod 对象运行一次性任务,容器中的进程在 正常运行结束后不会对其进行重启,而是将 Pod 对象置 “Completed” (完成)状态。若容器中的进程因错误而终止,则需要 依配置确定重启与否,未运行完成的 Pod 对象因其所在的节点故障而意 外终止后会被重新调度。 Job 控制器的 Pod 对象的状态转换如图 5-13 示。
 
Pod控制器(二)Deployment、 DaemonSet、Job、CronJob_第7张图片
 
实践中,有的作业任务可能需要运行不止一次,用户可以配置它们以串行或并行的方式运行。总结起来,这种类型的 Job 控制器对象有两 种,具体如下。
  • 单工作队列(work queue)的串行式Job:即以多个一次性的作业方式串行执行多次作业,直至满足期望的次数,如图5-14所示;这次Job也可以理解为并行度为1的作业执行方式,在某个时刻仅存在一个Pod资源对象。
 
Pod控制器(二)Deployment、 DaemonSet、Job、CronJob_第8张图片
  • 多工作队列的并行式Job:这种方式可以设置工作队列数,即作业数,每个队列仅负责运行一个作业,如图5-15a所示;也可以用有限的工作队列运行较多的作业,即工作队列数少于总作业数,相当于运行多个串行作业队列。如图5-15b所示,工作队列数即为同时可运行的Pod源数。
Pod控制器(二)Deployment、 DaemonSet、Job、CronJob_第9张图片
 
 
Job 控制器常用于管理那些运行一段时间便可 完成 的任务,例如计算或备份操作。
 
 

3.1   创建Job对象

Job 控制器的 spec 字段内嵌的必要字段仅为 template ,它的使用方式与 Deployment 等控制器并无不同。 Job 会为其 Pod 对象自动添加 “job- name=JOB_NAME” “controller-uid=UID” 标签,并使用标签选择器完成 controller-uid 标签的关联。需要注意的是, Job 位于 API “batch/v1” 之内。下面的资源单文件( job-example.yaml )中定义了 一个 Job 控制器:

[root@master chapter5]# vim job-example.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: job-example
spec:
  template:
    metadata:
      labels:
        app: myjob
    spec:
      containers:
      - name: myjob
        image: alpine
        command: ["/bin/sh",  "-c", "sleep 120"]
      restartPolicy: Never

注意  Pod 模板中的 spec.restartPolicy 默认为 “Always” ,这对 Job 控制器来说并不适用,因此必须在 Pod 模板中显式设定 restartPolicy 性的值为 “Never” “OnFailure”
 
使用 “kubectl create” “kubectl apply” 命令完成创建后即可查看相关的任务状态:

[root@master chapter5]# kubectl apply -f job-example.yaml
job.batch/job-example created

[root@master ~]# kubectl get jobs job-example
NAME          COMPLETIONS   DURATION   AGE
job-example   1/1           2m6s       2m12s

两分钟后,待 sleep 命令执行完成并成功退出后, Pod 资源即转换为Completed 状态,并且不会再于 “kubectl get pods” 命令中出现,除非为其 使用选项 “--show-all” 或简单格式的 “-a”

[root@master ~]# kubectl get pods -l job-name=job-example
NAME                READY   STATUS      RESTARTS   AGE
job-example-hm6lg   0/1     Completed   0          10m

3.2  并行式Job

将并行度属性 .spec.parallelism 的值设置为 1 ,并设置总任务数 .spec.completion 属性便能够让 Job 控制器以串行方式运行多任务。下面 是一个串行运行 5 次任务的 Job 控制器示例:

[root@master chapter5]# vim job-multi.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: job-multi
spec:
  completions: 5
  parallelism: 2    #两路并行
  template:
    metadata:
      labels:
        app: myjob
    spec:
      containers:
      - name: myjob
        image: alpine
        command: ["/bin/sh",  "-c", "sleep 20"]
      restartPolicy: Never

 

[root@master chapter5]# kubectl apply -f job-multi.yaml
job.batch/job-multi created

 

 

在创建之后或者创建之前,可以于另一终端启动 Pod 资源的列出命令 “kubectl get pods-l job-name=job-multi--watch” 来监控其变动,以了解 其执行过程。

 

[root@master ~]# kubectl get pods -l job-name=job-multi -w
NAME              READY   STATUS              RESTARTS   AGE
job-multi-76vbf   1/1     Running             0          8s
job-multi-h9nmh   0/1     ContainerCreating   0          8s
job-multi-h9nmh   1/1     Running             0          8s
job-multi-76vbf   0/1     Completed           0          25s
job-multi-sd6ql   0/1     Pending             0          0s
job-multi-sd6ql   0/1     Pending             0          0s
job-multi-sd6ql   0/1     ContainerCreating   0          0s
job-multi-h9nmh   0/1     Completed           0          28s
job-multi-rl2n4   0/1     Pending             0          0s
job-multi-rl2n4   0/1     Pending             0          0s
job-multi-rl2n4   0/1     ContainerCreating   0          0s
job-multi-sd6ql   1/1     Running             0          5s
job-multi-rl2n4   1/1     Running             0          10s

spec.parallelism 能够定义作业执行的并行度,将其设置为 2 或者以上的值即可实现并行多队列作业运行。同时,如果 .spec.completions 使用 的是默认值 1 ,则表示并行度即作业总数,如图 5-15a 所示;而如果 .spec.completions 属性值设置为大于 .spec.parallelism 的属性值,则表示 使用多队列串行任务作业模式, 例如,某 Job 控制器配 置中的 spec 字段嵌套了如下属性,表示以 2 个队列并行的方式,总共运 5 次的作业:
spec:
  completions: 5
  parallelism: 2    #两路并行
 

4. CronJob控制器

CronJob 控制器用于管理 Job 控制器资源的运行时间。 Job 控制器定义的作业任务在其控制器资源创建之后便会立即执行,但 CronJob 可以以 类似于 Linux 操作系统的周期性任务作业计划( crontab )的方式控制其 运行的时间点及重复运行的方式,具体如下。
  • 在未来某时间点运行作业一次。
  • 在指定的时间点重复运行作业。
CronJob 对象支持使用的时间格式类似于 Crontab ,略有不同的是,CronJob 控制器在指定的时间点时, “” “*” 的意义相同,都表示任何可 用的有效值
 
 

4.1    创建CronJob对象

CronJob 控制器的 spec 字段可嵌套使用以下字段。
  • jobTemplateJob控制器模板,用于为CronJob控制器生成Job对象;必选字段。
    • jobTemplateJob控制器模板,用于为CronJob控制器生成Job对象;必选字段。
      • concurrencyPolicy:并发执行策略,可用值有“Allow”(允许)、“Forbid”(禁止)和“Replace”(替换),用于定义前一次作业运 行尚未完成时是否以及如何运行后一次的作业。
      • failedJobHistoryLimit:为失败的任务执行保留的历史记录数,默认为1
      • successfulJobsHistoryLimit:为成功的任务执行保留的历史记录数,默认为3
      • startingDeadlineSeconds:因各种原因缺乏执行作业的时间点所导致的启动作业错误的超时时长,会被记入错误历史记录。
      • suspend:是否挂起后续的任务执行,默认为false,对运行中的作业不会产生影响。
      下面是一个定义在资源清单文件( cronjob-example.yaml )中的CronJob 资源对象示例,它每隔 2 分钟运行一次由 jobTemplate 定义的简单 任务

      [root@master chapter5]# vim cronjob-example.yaml

      apiVersion: batch/v1beta1
      kind: CronJob
      metadata:
        name: cronjob-example
        labels:
          app: mycronjob
      spec:
        schedule: "*/2 * * * *"
        jobTemplate:
          metadata:
            labels:
              app: mycronjob-jobs
          spec:
            parallelism: 2
            template:
              spec:
                containers:
                - name: myjob
                  image: alpine
                  command:
                  - /bin/sh
                  - -c
                  - date; echo Hello from the Kubernetes cluster; sleep 10
                restartPolicy: OnFailure

      运行资源创建命令创建上述 CronJob 资源对象,而后再通过资源对象的相关信息了解运行状态。下面命令结果中的 SCHEDULE 是指其调 度时间点, SUSPEND 表示后续任务是否处于挂起状态,即暂停任务的 调度和运行, ACTIVE 表示活动状态的 Job 对象的数量,而 LAST SCHEDULE 则表示上次调度运行至此刻的时长:

      [root@master chapter5]# kubectl apply -f cronjob-example.yaml
      cronjob.batch/cronjob-example created
      [root@master chapter5]# kubectl get cronjobs cronjob-example
      NAME              SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
      cronjob-example   */2 * * * *   False     0                  15s

      5.   小结

      主要讲解了 Kubernetes Pod 控制器,它们是 工作负载 类资源的核心组成部分,是基于 Kubernetes 运行应用的最重要的资源类型之 一,具体如下。
      • 工作负载类型的控制器根据业务需求管控Pod资源的生命周期。
      • ReplicaSet可以确保守护进程型的Pod资源始终具有精确的、处于运行状态的副本数量,并支持Pod规模的伸缩机制;它是新一代的ReplicationController控制器,不过用户通常不应该直接使用ReplicaSet而是要使用Deployment
      • Deployment是建构在ReplicaSet上的更加抽象的工作负载型控制器,支持多种更新策略及发布机制。
      • Job控制器能够控制相应的作业任务得以正常完成并退出,支持并行式多任务。
      • CronJob控制器用于控制周期性作业任务,其功能类似于Linux操作系统上的Crontab
      • PodDisruptionBudget资源对象为Kubernetes系统上的容器化应用提供了高可用能力。

       

      #kubectl describe node node1命令参数得解释

       

      [root@master chapter5]# kubectl describe node node1
      Name:               node1
      Roles:             
      Labels:             beta.kubernetes.io/arch=amd64
                          beta.kubernetes.io/os=linux
                          kubernetes.io/arch=amd64
                          kubernetes.io/hostname=node1
                          kubernetes.io/os=linux
      Annotations:        flannel.alpha.coreos.com/backend-data: {"VtepMAC":"8a:5b:b5:cc:b2:0d"}
                          flannel.alpha.coreos.com/backend-type: vxlan
                          flannel.alpha.coreos.com/kube-subnet-manager: true
                          flannel.alpha.coreos.com/public-ip: 172.21.96.13
                          kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
                          node.alpha.kubernetes.io/ttl: 0
                          volumes.kubernetes.io/controller-managed-attach-detach: true
      CreationTimestamp:  Thu, 05 Nov 2020 17:46:59 +0800
      Taints:            
      Unschedulable:      false
      Lease:
        HolderIdentity:  node1
        AcquireTime:    
        RenewTime:       Wed, 18 Nov 2020 15:07:34 +0800
      Conditions:
        Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
        ----                 ------  -----------------                 ------------------                ------                       -------
        NetworkUnavailable  #网络压力   False   Thu, 05 Nov 2020 17:55:42 +0800   Thu, 05 Nov 2020 17:55:42 +0800   FlannelIsUp                  Flannel is running on this node
        MemoryPressure  #内存压力      False   Wed, 18 Nov 2020 15:05:29 +0800   Thu, 05 Nov 2020 17:46:59 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
        DiskPressure    #磁盘压力     False   Wed, 18 Nov 2020 15:05:29 +0800   Thu, 05 Nov 2020 17:46:59 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
        PIDPressure      #PID压力    False   Wed, 18 Nov 2020 15:05:29 +0800   Thu, 05 Nov 2020 17:46:59 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
        Ready     #就绪           True    Wed, 18 Nov 2020 15:05:29 +0800   Thu, 05 Nov 2020 17:55:51 +0800   KubeletReady                 kubelet is posting ready status
      Addresses:    #显示地址
        InternalIP:  172.21.96.13   #本地私网地址
        Hostname:    node1  #节点名称
      Capacity:   #容量
        cpu:                2   #当前节点有几个cpu
        ephemeral-storage:  51474024Ki   #有多少个临时存储空间可以用
        hugepages-1Gi:      0   #最大内存页  所谓内存页就是Linux节点在使用时一般时按照业面也使用得一般是4K  大于4K得就是页
        hugepages-2Mi:      0
        memory:             3915456Ki   #一共有多大
        pods:               110   #最多可容纳多少个pod
      Allocatable:    #可分配得资源
        cpu:                2  #可分配得CPU
        ephemeral-storage:  47438460440
        hugepages-1Gi:      0
        hugepages-2Mi:      0
        memory:             3813056Ki
        pods:               110
      System Info:   #
        Machine ID:                 735fbcd856b697dbc8d6deb1a11dd712
        System UUID:                AF0CC1A9-0B2D-4791-8DBE-233B5F9A610C
        Boot ID:                    1d136904-0fee-456e-8882-8182c4355a2f
        Kernel Version:             3.10.0-693.el7.x86_64
        OS Image:                   CentOS Linux 7 (Core)
        Operating System:           linux
        Architecture:               amd64
        Container Runtime Version:  docker://19.3.13
        Kubelet Version:            v1.19.3
        Kube-Proxy Version:         v1.19.3
      PodCIDR:                      10.244.1.0/24
      PodCIDRs:                     10.244.1.0/24
      Non-terminated Pods:          (14 in total)
        Namespace                   Name                             CPU Requests  CPU Limits  Memory Requests  Memory Limits  AGE
        ---------                   ----                             ------------  ----------  ---------------  -------------  ---
        default                     filebeat-ds-d6x2m                0 (0%)        0 (0%)      0 (0%)           0 (0%)         4h8m
        default                     liveness-http                    0 (0%)        0 (0%)      0 (0%)           0 (0%)         7d3h
        default                     myapp-deploy-77dcc456d9-5hpg7    0 (0%)        0 (0%)      0 (0%)           0 (0%)         23h
        default                     myapp-pod                        0 (0%)        0 (0%)      0 (0%)           0 (0%)         7d
        default                     rs-example-cwxgh                 0 (0%)        0 (0%)      0 (0%)           0 (0%)         46h
        default                     rs-example-jdp8k                 0 (0%)        0 (0%)      0 (0%)           0 (0%)         45h
        default                     rs-example-qnvjt                 0 (0%)        0 (0%)      0 (0%)           0 (0%)         45h
        develop                     pod-demo                         0 (0%)        0 (0%)      0 (0%)           0 (0%)         9d
        kube-system                 coredns-6c76c8bb89-425s2         100m (5%)     0 (0%)      70Mi (1%)        170Mi (4%)     12d
        kube-system                 kube-flannel-ds-pb69v            100m (5%)     100m (5%)   50Mi (1%)        50Mi (1%)      12d
        kube-system                 kube-proxy-2lx79                 0 (0%)        0 (0%)      0 (0%)           0 (0%)         12d
        prod                        myapp-rs-428nc                   0 (0%)        0 (0%)      0 (0%)           0 (0%)         2d3h
        prod                        myapp-rs-4nn8r                   0 (0%)        0 (0%)      0 (0%)           0 (0%)         2d3h
        prod                        pod-demo-2                       0 (0%)        0 (0%)      0 (0%)           0 (0%)         8d
      Allocated resources:    #已分配得资源
        (Total limits may be over 100 percent, i.e., overcommitted.)
        Resource           Requests    Limits
        --------           --------    ------
        cpu                200m (10%)  100m (5%)   #cpu
        memory             120Mi (3%)  220Mi (5%)   #内存
        ephemeral-storage  0 (0%)      0 (0%)
        hugepages-1Gi      0 (0%)      0 (0%)
        hugepages-2Mi      0 (0%)      0 (0%)
      Events:             

       

       

       

      你可能感兴趣的:(linux)