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

021.掌握Pod-Pod调度策略

程序员文章站 2022-05-22 19:02:12
一 Pod生命周期管理 1.1 Pod生命周期 Pod在整个生命周期过程中被系统定义了如下各种状态。 状态值 描述 Pending API Server已经创建该Pod,且Pod内还有一个或多个容器的镜像没有创建,包括正在下载镜像的过程。 Running Pod内所有容器均已创建,且至少有一个容器处 ......

一 pod生命周期管理

1.1 pod生命周期

pod在整个生命周期过程中被系统定义了如下各种状态。
状态值
描述
pending
api server已经创建该pod,且pod内还有一个或多个容器的镜像没有创建,包括正在下载镜像的过程。
running
pod内所有容器均已创建,且至少有一个容器处于运行状态、正在启动状态或正在重启状态。
succeeded
pod内所有容器均成功执行退出,且不会重启。
failed
pod内所有容器均已退出,但至少有一个容器退出为失败状态。
unknown
由于某种原因无法获取该pod状态,可能由于网络通信不畅导致。

1.2 pod重启策略

pod重启策略(restartpolicy)应用于pod内的所有容器,并且仅在pod所处的node上由kubelet进行判断和重启操作。当某个容器异常退出或者健康检查失败时,kubelet将根据restartpolicy的设置来进行相应操作。
pod的重启策略包括always、onfailure和never,默认值为always。
  • always:当容器失效时,由kubelet自动重启该容器;
  • onfailure:当容器终止运行且退出码不为0时,由kubelet自动重启该容器;
  • never:不论容器运行状态如何,kubelet都不会重启该容器。

       kubelet重启失效容器的时间间隔以sync-frequency乘以2n来计算,例如1/2/4/8倍等,最长延时5min,并且在成功重启后的10min后重置该时间。

pod的重启策略与控制方式关联,当前可用于管理pod的控制器包括replicationcontroller、job、daemonset及直接管理kubelet管理(静态pod)。
不同控制器的重启策略限制如下:
  • rc和daemonset:必须设置为always,需要保证该容器持续运行;
  • job:onfailure或never,确保容器执行完成后不再重启;
  • kubelet:在pod失效时重启,不论将restartpolicy设置为何值,也不会对pod进行健康检查。

pod包含的容器数
pod当前的状态
发生事件
pod的结果状态
restartpolicy=always
restartpolicy=onfailure
restartpolicy=never
包含1个容器
running
容器成功退出
running
succeeded
succeeded
包含1个容器
running
容器失败退出
running
running
failed
包括两个容器
running
1个容器失败退出
running
running
running
包括两个容器
running
容器被oom杀掉
running
running
failed

1.3 pod健康检查

对pod的健康检查可以通过两类探针来检查:livenessprobe和readinessprobe。
livenessprobe探针:用于判断容器是否存活(running状态),如果livenessprobe探针探测到容器不健康,则kubelet将杀掉该容器,并根据容器的重启策略做相应处理。若一个容器不包含livenessprobe探针,kubelet认为该容器的livenessprobe探针返回值用于是“success”。
readineeprobe探针:用于判断容器是否启动完成(ready状态)。如果readinessprobe探针探测到失败,则pod的状态将被修改。endpoint controller将从service的endpoint中删除包含该容器所在pod的eenpoint。
kubelet定期执行livenessprobe探针来诊断容器的健康状态,通常有以下三种方式:
  • execaction:在容器内执行一个命令,若返回码为0,则表明容器健康。
示例:通过执行"cat /tmp/health"命令判断一个容器运行是否正常。容器初始化并创建该文件,10s后删除该文件,15s秒通过命令判断,由于该文件已被删除,因此判断该容器fail,导致kubelet杀掉该容器并重启。
  1 [root@uk8s-m-01 study]# vi dapi-liveness.yaml
  2 apiversion: v1
  3 kind: pod
  4 metadata:
  5   name: dapi-liveness-pod
  6   labels:
  7     test: liveness-exec
  8 spec:
  9   containers:
 10     - name: dapi-liveness
 11       image: busybox
 12       args:
 13       - /bin/sh
 14       - -c
 15       - echo ok > /tmp/health; sleep 10; rm -rf /tmp/health; sleep 600
 16       livenessprobe:
 17         exec:
 18           command:
 19           - cat
 20           - /tmp/health
 21 
 22 [root@uk8s-m-01 study]# kubectl describe pod dapi-liveness-pod
021.掌握Pod-Pod调度策略
  • tcpsocketaction:通过容器的ip地址和端口号执行tcp检查,若能建立tcp连接,则表明容器健康。
示例:
  1 [root@uk8s-m-01 study]# vi dapi-tcpsocket.yaml
  2 apiversion: v1
  3 kind: pod
  4 metadata:
  5   name: dapi-healthcheck-tcp
  6 spec:
  7   containers:
  8     - name: nginx
  9       image: nginx
 10       ports:
 11       - containerport: 80
 12       livenessprobe:
 13         tcpsocket:
 14           port: 80
 15         initialdelayseconds: 30
 16         timeoutseconds: 1
 17 
 18 [root@uk8s-m-01 study]# kubectl create -f dapi-tcpsocket.yaml
提示:对于每种探测方式,都需要设置如下两个参数,其包含的含义如下:
initialdelayseconds:启动容器后进行首次健康检查的等待时间,单位为s;
timeoutseconds:健康检查发送请求后等待响应的超时时间,单位为s,当超时发生时,kubelet会认为容器已经无法提供服务,将会重启该容器。

二 pod调度

kubernetes中,pod通常是容器的载体,一般需要通过deployment、daemonset、rc、job等对象来完成一组pod的调度与自动控制功能。

2.1 depolyment/rc自动调度

deployment或rc的主要功能之一就是自动部署一个容器应用的多份副本,以及持续监控副本的数量,在集群内始终维持用户指定的副本数量。
示例:
  1 [root@uk8s-m-01 study]# vi nginx-deployment.yaml
  2 apiversion: apps/v1beta1
  3 kind: deployment
  4 metadata:
  5   name: nginx-deployment-01
  6 spec:
  7   replicas: 3
  8   template:
  9     metadata:
 10       labels:
 11         app: nginx
 12     spec:
 13       containers:
 14       - name: nginx
 15         image: nginx:1.7.9
 16         ports:
 17         - containerport: 80
 18 
 19 [root@uk8s-m-01 study]# kubectl get deployments
 20 name                  ready   up-to-date   available   age
 21 nginx-deployment-01   3/3     3            3           30s
 22 [root@uk8s-m-01 study]# kubectl get rs
 23 name                             desired   current   ready   age
 24 nginx-deployment-01-5754944d6c   3         3         3       75s
 25 [root@uk8s-m-01 study]# kubectl get pod | grep nginx
 26 nginx-deployment-01-5754944d6c-hmcpg   1/1     running     0          84s
 27 nginx-deployment-01-5754944d6c-mcj8q   1/1     running     0          84s
 28 nginx-deployment-01-5754944d6c-p42mh   1/1     running     0          84s

2.2 nodeselector定向调度

当需要手动指定将pod调度到特定node上,可以通过node的标签(label)和pod的nodeselector属性相匹配。
# kubectl label nodes <node-name> <label-key>=<label-value>
node节点创建对应的label后,可通过在定义pod的时候加上nodeselector的设置实现指定的调度。
示例:
  1 [root@uk8s-m-01 study]# kubectl label nodes 172.24.9.14 speed=io
  2 node/172.24.9.14 labeled
  3 [root@uk8s-m-01 study]# vi nginx-master-controller.yaml
  4 kind: replicationcontroller
  5 metadata:
  6   name: nginx-master
  7   labels:
  8     name: nginx-master
  9 spec:
 10   replicas: 1
 11   selector:
 12     name: nginx-master
 13   template:
 14     metadata:
 15       labels:
 16         name: nginx-master
 17     spec:
 18       containers:
 19       - name: master
 20         image: nginx:1.7.9
 21         ports:
 22         - containerport: 80
 23       nodeselector:
 24         speed: io
 25 
 26 [root@uk8s-m-01 study]# kubectl create -f nginx-master-controller.yaml
 27 [root@uk8s-m-01 study]# kubectl get pods -o wide
 28 name                ready   status    restarts    age    ip            node
 29 nginx-master-7fjgj  1/1     running   0           82s    172.24.9.71   172.24.9.14
提示:可以将集群中具有不同特点的node贴上不同的标签,实现在部署时就可以根据应用的需求设置nodeselector来进行指定node范围的调度。
注意:若在定义pod中指定了nodeselector条件,但集群中不存在符合该标签的node,即使集群有其他可供使用的node,pod也无法被成功调度。

2.3 nodeaffinity亲和性调度

亲和性调度机制极大的扩展了pod的调度能力,主要增强功能如下:
  1. 更具表达力,即更精细的力度控制;
  2. 可以使用软限制、优先采用等限制方式,即调度器在无法满足优先需求的情况下,会使用其他次条件进行满足;
  3. 可以依据节点上正在运行的其他pod的标签来进行限制,而非节点本身的标签,从而实现pod之间的亲和或互斥关系。
目前有两种节点亲和力表达:
requiredduringschedulingignoredduringexecution:硬规则,必须满足指定的规则,调度器才可以调度pod至node上(类似nodeselector,语法不同)。
preferredduringschedulingignoredduringexecution:软规则,优先调度至满足的node的节点,但不强求,多个优先级规则还可以设置权重值。
ignoredduringexecution指:如果一个pod所在的节点在pod运行期间标签发生了变化,不再符合该pod的节点亲和性需求,则系统将忽略node上label的变化,该pod能继续在该节点运行。
示例:
条件1:只运行在amd64的节点上;尽量运行在ssd节点上。
  1 [root@uk8s-m-01 study]# vi nodeaffinity-pod.yaml
  2 apiversion: v1
  3 kind: pod
  4 metadata:
  5   name: with-node-affinity
  6 spec:
  7   affinity:
  8     nodeaffinity:
  9       requiredduringschedulingignoredduringexecution:
 10         nodeselectorterms:
 11         - matchexpressions:
 12           - key: kubernetes.io/arch
 13             operator: in
 14             values:
 15             - amd64
 16       preferredduringschedulingignoredduringexecution:
 17       - weight: 1
 18         preference:
 19           matchexpressions:
 20           - key: disk-type
 21             operator: in
 22             values:
 23             - ssd
 24   containers:
 25   - name: with-node-affinity
 26     image: gcr.azk8s.cn/google_containers/pause:2.0
nodeaffinity操作语法;in、notin、exists、doesnotexist、gt、lt。notin和doesnotexist可以实现互斥功能。
nodeaffinity规则设置注意事项:
  • 若同时定义nodeselector和nodeaffinity,则必须两个条件都满足,pod才能最终运行指定在node上;;
  • 若nodeaffinity指定多个nodeselectorterms,则只需要其中一个能够匹配成功即可;
  • 若nodeselectorterms中有多个matchexpressions,则一个节点必须满足所有matchexpressions才能运行该pod。

2.4 podaffinity亲和性调度

podaffinity根据节点上正在运行的pod标签而不是node标签来判断和调度,要求对节点和pod两个条件进行匹配。
规则描述为:若在具有标签x的node上运行了一个或多个符合条件y的pod,则pod应该(或者不应该)运行在这个node上。
x通常为node节点的机架、区域等概念,pod是属于某个命名空间,所以条件y表达的是一个或全部命名空间中的一个label selector。
pod亲和性定义与podspec的affinity字段下的podaffinity字段里,互斥性定义于同一层次的podantiaffinity子字段中。
举例:
  1 [root@uk8s-m-01 study]# vi nginx-flag.yaml	#创建名为pod-flag,带有两个标签的pod
  2 apiversion: v1
  3 kind: pod
  4 metadata:
  5   name: pod-affinity
  6 spec:
  7   affinity:
  8     podaffinity:
  9       requiredduringschedulingignoredduringexecution:
 10       - labelselector:
 11           matchexpressions:
 12           - key: security
 13             operator: in
 14             values:
 15             - s1
 16         topologykey: kubernetes.io/hostname
 17   containers:
 18   - name: with-pod-affinity
 19     image: gcr.azk8s.cn/google_containers/pause:2.0
  1 [root@uk8s-m-01 study]# vi nginx-affinity-in.yaml	#创建定义标签security=s1,对应如上pod “pod-flag”。
  2 apiversion: v1
  3 kind: pod
  4 metadata:
  5   name: pod-affinity
  6 spec:
  7   affinity:
  8     podaffinity:
  9       requiredduringschedulingignoredduringexecution:
 10       - labelselector:
 11           matchexpressions:
 12           - key: security
 13             operator: in
 14             values:
 15             - s1
 16         topologykey: kubernetes.io/hostname
 17   containers:
 18   - name: with-pod-affinity
 19     image: gcr.azk8s.cn/google_containers/pause:2.0
 20 
 21 [root@uk8s-m-01 study]# kubectl create -f nginx-affinity-in.yaml
 22 [root@uk8s-m-01 study]# kubectl get pods -o wide
021.掌握Pod-Pod调度策略
提示:由上pod亲和力可知,两个pod处于同一个node上。
  1 [root@uk8s-m-01 study]# vi nginx-affinity-out.yaml	#创建不能与参照目标pod运行在同一个node上的调度策略
  2 apiversion: v1
  3 kind: pod
  4 metadata:
  5   name: anti-affinity
  6 spec:
  7   affinity:
  8     podaffinity:
  9       requiredduringschedulingignoredduringexecution:
 10       - labelselector:
 11           matchexpressions:
 12           - key: security
 13             operator: in
 14             values:
 15             - s1
 16         topologykey: failure-domain.beta.kubernetes.io/zone
 17     podantiaffinity:
 18       requiredduringschedulingignoredduringexecution:
 19       - labelselector:
 20           matchexpressions:
 21           - key: security
 22             operator: in
 23             values:
 24             - nginx
 25         topologykey: kubernetes.io/hostname
 26   containers:
 27   - name: anti-affinity
 28     image: gcr.azk8s.cn/google_containers/pause:2.0
 29 
 30 [root@uk8s-m-01 study]# kubectl get pods -o wide	#验证

2.5 taints和tolerations(污点和容忍)

taint:使node拒绝特定pod运行;
toleration:为pod的属性,表示pod能容忍(运行)标注了taint的node。
taint语法:$ kubectl taint node node1 key=value:noschedule
解释:为node1加上一个taint,该taint的键为key,值为value,taint的效果为noschedule。即除非特定声明可以容忍此taint,否则不会调度至node1上。
toleration示例:
  1 tolerations:
  2 - key: "key"
  3   operator: "equal"
  4   value: "value"
  5   effect: "noschedule"
  1 tolerations:
  2 - key: "key"
  3   operator: "exists"
  4   effect: "noschedule"
注意:pod的toleration声明中的key和effect需要与taint的设置保持一致,并且满足以下条件:
  • operator的值是exists(无须指定value);
  • operator的值是equal并且value相等;
  • 空的key配合exists操作符能够匹配所有的键和值;
  • 空的effect匹配所有的effect。
若不指定operator,则默认值为equal。
taint说明:系统允许在同一个node上设置多个taint,也可以在pod上设置多个toleration。kubernetes调度器处理多个taint和toleration的逻辑顺序:首先列出节点中所有的taint,然后忽略pod的toleration能够匹配的部分,剩下的没有忽略掉的taint就是对pod的效果。以下是几种特殊情况:
若剩余的taint中存在effect=noschedule,则调度器不会把该pod调度到这一节点上;
若剩余的taint中没有noschedule效果,但有prefernoschedule效果,则调度器会尝试不把这个pod指派到此节点;
若剩余taint的效果有noschedule,并且这个pod已经在该节点上运行,则会被驱逐,若没有在该节点上运行,也不会再被调度到该节点上。
示例:
  1 $ kubectl taint node node1 key=value1:noschedule
  2 $ kubectl taint node node1 key=value1:noexecute
  3 $ kubectl taint node node1 key=value2:noschedule
  4 tolerations:
  5 - key: "key1"
  6   operator: "equal"
  7   value: "value"
  8   effect: "noschedule"
  9 tolerations:
 10 - key: "key1"
 11   operator: "equal"
 12   value: "value1"
 13   effect: "noexecute"
释义:此pod声明了两个容忍,且能匹配node1的taint,但是由于没有能匹配第三个taint的toleration,因此此pod依旧不能调度至此node。若该pod已经在node1上运行了,那么在运行时设置了第3个taint,它还能继续在node1上运行,这是因为pod可以容忍前两个taint。
通常,若node加上effect=noexecute的taint,那么该node上正在运行的所有无对应toleration的pod都会被立刻驱逐,而具有相应toleration的pod则永远不会被驱逐。同时,系统可以给具有noexecute效果的toleration加入一个可选的tolerationseconds字段,表明pod可以在taint添加到node之后还能在此node运行多久。
  1 tolerations:
  2 - key: "key1"
  3   operator: "equal"
  4   value: "value"
  5   effect: "noschedule"
  6   tolerationseconds: 3600
释义:若pod正在运行,所在节点被加入一个匹配的taint,则这个pod会持续在该节点运行3600s后被驱逐。若在此期限内,taint被移除,则不会触发驱逐事件。
taints和tolerations常用场景:
  • 独占节点:
给特定的节点运行特定应用。
$ kubectl taint nodes 【nodename】 dedicated=groupname:noschedule
同时在pod中设置对应的toleration配合,带有合适toleration的pod允许同时使用其他节点一样使用有taint的节点。
  • 具有特殊硬件设备的节点
集群中部分特殊硬件(如安装了gpu),则可以把不需要占用gpu的pod禁止在此node上调度。
  1 $ kubectl taint nodes 【nodename】 special=true:noschedule
  2 $ kubectl taint nodes 【nodename】 special=true:prefernoschedule
  • 定义pod驱逐行为
noexecute的taint对节点上正在运行的pod有以下影响:
    1. 没有设置toleration的pod会被立刻驱逐;
    2. 配置了对应toleration的pod,若没有为tolerationseconds赋值,则会一直保留在此节点中;
    3. 配置了对应toleration的pod,且为tolerationseconds赋值,则在指定时间后驱逐。

    2.6 daemonset

    daemonset是在每个node上调度一个pod的资源对象,用于管理集群中每个node仅运行一份pod的副本实例。
    021.掌握Pod-Pod调度策略
    常见场景:
    在每个node上运行一个glusterfs存储的daemon进程;
    在每个node上运行一个日志采集程序,例如fluentd;
    在每个node上运行一个性能监控程序,采集该node的运行性能数据,例如prometheus。
    示例:
      1 [root@uk8s-m-01 study]# vi fluentd-ds.yaml
      2 apiversion: extensions/v1beta1
      3 kind: daemonset
      4 metadata:
      5   name: fluentd-cloud-logging
      6   namespace: kube-system
      7   labels:
      8     k8s-app: fluentd-cloud-logging
      9 spec:
     10   template:
     11     metadata:
     12       namespace: kube-system
     13       labels:
     14         k8s-app: fluentd-cloud-logging
     15     spec:
     16       containers:
     17       - name: fluentd-cloud-logging
     18         image: gcr.azk8s.cn/google_containers/fluentd-elasticsearch:1.17
     19         resources:
     20           limits:
     21             cpu: 100m
     22             memory: 200mi
     23         env:
     24         - name: fluentd_args
     25           value: -q
     26         volumemounts:
     27         - name: varlog
     28           mountpath: /var/log
     29           readonly: false
     30         - name: containers
     31           mountpath: /var/lib/docker/containers
     32           readonly: false
     33       volumes:
     34       - name: containers
     35         hostpath:
     36           path: /var/lib/docker/containers
     37       - name: varlog
     38         hostpath:
     39           path: /var/log
    021.掌握Pod-Pod调度策略

    2.7 job批处理调度

    021.掌握Pod-Pod调度策略
    通过kubernetes job资源对象可以定义并启动一个批处理任务,批处理任务通过并行(或者串行)启动多个计算进程去处理一批工作项。根据批处理方式不同,批处理任务可以分为如下几种模式:
    job template expansion模式:一个job对象对应一个待处理的work item,有几个work item就产生几个独立的job。通常适合work item数量少、每个work item要处理的数据量比较大的场景。
    queue with pod per work item模式:采用一个任务队列存放work item,一个job对象作为消费者去完成这些work item。此模式下,job会启动n个pod,每个pod都对应一个work item。
    queue with variable pod count模式:采用一个任务队列存放work item,一个job对象作为消费者去完成这些work item,但此模式下job启动的数量是可变的。
    kubernetes将job氛围以下三类:
    • non-parallel jobs
    通常一个job只启动一个pod,除非pod异常,才会重启该pod,一旦此pod正常结束,job将结束。
    • parallel jobs with a fixed completion count
    并行job会启动多个pod,此时需要设定job的.spec.completions参数为一个正数,当正常结束的pod数量达至此参数设定的值后,job结束。同时.spec.parallelism参数用来控制并行度,即同时启动几个job来处理work item。
    • parallel jobs with a work queue
    任务队列方式的并行job需要一个独立的queue,work item都在一个queue中存放,不能设置job的.spec.completions参数,此时job具有以下特性:
      1. 每个pod都能独立判断和决定是否还有任务项需要处理;
      2. 如果某个pod正常结束,则job不会再启动新的pod;
      3. 如果一个pod成功结束,则此时应该不存在其他pod还在工作的情况。它们应该都处于即将结束、退出的状态;
      4. 如果所有pod都结束了,且至少有一个pod成功结束,则整个jod成功结束。

      2.8 cronjob定时任务

      表达式:minutes hours dayofmonth month dayofweek year
      minutes:可出现","、"_"、"*"、"/",有效范围为0~59的整数;
      hours:出现","、"_"、"*"、"/",有效范围为0~23的整数;
      dayofmonth:出现","、"_"、"*"、"/"、"l"、"w"、"c",有效范围为0~31的整数;
      month:可出现","、"_"、"*"、"/",有效范围为1~12的整数或jan~dec;
      dayofweek:出现","、"_"、"*"、"/"、"l"、"w"、"c"、"#",有效范围为1~7的整数或sun~sat;
      *: 表示匹配该域的任意值, 假如在minutes域使用“*”, 则表示每分钟都会触发事件。
      /: 表示从起始时间开始触发, 然后每隔固定时间触发一次,例如在minutes域设置为5/20, 则意味着第1次触发在第5min时, 接下来每20min触发一次, 将在第25min、 第45min等时刻分别触发。
      示例:*/1 * * * * #每隔1min执行一次任务
        1 [root@uk8s-m-01 study]# vi cron.yaml
        2 apiversion: batch/v2alpha1
        3 kind: cronjob
        4 metadata:
        5   name: hello
        6 spec:
        7   schedule: "*/1 * * * *"
        8   jobtemplate:
        9     spec:
       10       template:
       11         spec:
       12           containers:
       13           - name: hello
       14             image: busybox
       15             args:
       16             - /bin/sh
       17             - -c
       18             - date; echo hello from the kubernetes cluster
       19           restartpolicy: onfailure
        1 [root@master study]# kubectl create -f cron.yaml
        2 [root@master study]# kubectl get cronjob hello
        3 name    schedule      suspend   active   last schedule   age
        4 hello   */1 * * * *   false     0        <none>          29s
        5 [root@master study]# kubectl get pods
        6 name                     ready   status      restarts   age
        7 hello-1573378080-zvvm5   0/1     completed   0          68s
        8 hello-1573378140-9pmwz   0/1     completed   0          8s
        9 [root@node1 ~]# docker logs c7					#node节点查看日志
       10 sun nov 10 09:31:13 utc 2019
       11 hello from the kubernetes cluster
       12 [root@master study]# kubectl get jobs				#查看任务
       13 name               completions   duration   age
       14 hello-1573378500   1/1           8s         3m7s
       15 hello-1573378560   1/1           4s         2m7s
       16 hello-1573378620   1/1           6s         67s
       17 hello-1573378680   1/1           4s         7s
       18 [root@master study]# kubectl get pods -o wide | grep hello-1573378680	#以job任务查看对应的pod
       19 [root@master study]# kubectl delete cj hello			#删除cronjob

      2.9 初始化容器

      在很多应用场景中, 应用在启动之前都需要进行如下初始化操作。
      • 等待其他关联组件正确运行( 例如数据库或某个后台服务) 。
      • 基于环境变量或配置模板生成配置文件。
      • 从远程数据库获取本地所需配置, 或者将自身注册到某个*数据库中。
      • 下载相关依赖包, 或者对系统进行一些预配置操作。
      示例:以nginx应用为例, 在启动nginx之前, 通过初始化容器busybox为nginx创建一个index.html主页文件。同时init container和nginx设置了一个共享的volume, 以供nginx访问init container设置的index.html文件。
        1 [root@uk8s-m-01 study]# vi nginx-init-containers.yaml
        2 apiversion: v1
        3 kind: pod
        4 metadata:
        5   name: nginx
        6   annotations:
        7 spec:
        8   initcontainers:
        9   - name: install
       10     image: busybox
       11     command:
       12     - wget
       13     - "-o"
       14     - "/work-dir/index.html"
       15     - http://kubernetes.io
       16     volumemounts:
       17     - name: workdir
       18       mountpath: "/work-dir"
       19   containers:
       20   - name: nginx
       21     image: nginx:1.7.9
       22     ports:
       23     - containerport: 80
       24     volumemounts:
       25     - name: workdir
       26       mountpath: /usr/share/nginx/html
       27   dnspolicy: default
       28   volumes:
       29   - name: workdir
       30     emptydir: {}
        1 [root@uk8s-m-01 study]# kubectl get pods
        2 name    ready   status     restarts   age
        3 nginx   0/1     init:0/1   0          2s
        4 [root@uk8s-m-01 study]# kubectl get pods
        5 name    ready   status    restarts   age
        6 nginx   1/1     running   0          13s
        7 [root@uk8s-m-01 study]# kubectl describe pod nginx		#查看事件可知会先创建init容器,名为install
      init容器与应用容器的区别如下。
      (1) init container的运行方式与应用容器不同, 它们必须先于应用容器执行完成, 当设置了多个init container时, 将按顺序逐个运行, 并且只有前一个init container运行成功后才能运行后一个init container。 当所有init container都成功运行后, kubernetes才会初始化pod的各种信息, 并开始创建和运行应用容器。
      (2) 在init container的定义中也可以设置资源限制、 volume的使用和安全策略, 等等。 但资源限制的设置与应用容器略有不同。
      • 如果多个init container都定义了资源请求/资源限制, 则取最大的值作为所有init container的资源请求值/资源限制值。
      • pod的有效(effective) 资源请求值/资源限制值取以下二者中的较大值。
        • 所有应用容器的资源请求值/资源限制值之和。
        • init container的有效资源请求值/资源限制值。
      • 调度算法将基于pod的有效资源请求值/资源限制值进行计算,即init container可以为初始化操作预留系统资源, 即使后续应用容器无须使用这些资源。
      • pod的有效qos等级适用于init container和应用容器。
      • 资源配额和限制将根据pod的有效资源请求值/资源限制值计算生效。
      • pod级别的cgroup将基于pod的有效资源请求/限制, 与调度机制
      一致。
      (3) init container不能设置readinessprobe探针, 因为必须在它们成功运行后才能继续运行在pod中定义的普通容器。在pod重新启动时, init container将会重新运行, 常见的pod重启场景如下。
      • init container的镜像被更新时, init container将会重新运行, 导致pod重启。 仅更新应用容器的镜像只会使得应用容器被重启。
      • pod的infrastructure容器更新时, pod将会重启。
      • 若pod中的所有应用容器都终止了, 并且restartpolicy=always, 则pod会重启。