kubernetes学习笔记五(资源清单)

kubernetes学习笔记五(资源清单)

Scroll Down
tips:

1、k8s 拉取镜像的时候,如果标签没有指定特定的版本,默认使用latest标签,这种情况下,如果镜像拉取策略imagePullPolicy被设置为Always,那么他总是会去远程镜像仓库查找最新的镜像;如果镜像拉取策略imagePullPolicy被设置为IfNotPresent,如果本地有则不去远程下载;如果镜像拉取策略imagePullPolicy被设置为Never,永远不从远程下载镜像

2、Pause容器 全称infrastucture container(又叫infra)基础容器

1、k8s中的集群资源分类:

名称空间级别

比如:使用 kubeadm工具安装k8s默认会将系统组件放在kube-system名称空间下

# 当你使用命令
# kubectl get pod 

是获取不到关于系统的pod的信息,原因是命令 kubectl get pod 默认是通过-n default选项指定了默认名称空间,但是k8s系统组件的pod是被放在kube-system名称空间下,所以通过默认名称空间肯定是获取不到系统pod的信息的

集群级别

集群级别意味着,无论在什么名称空间下定义的资源,在整个集群下都是可见的。

元数据类型级别

元数据类别会给我们提供一个指标,通过指标进行操作。其实它可以归属于名称空间级别、集群级别,但是它有自身比较突出的特点,所以把它单独拿出来定义。

比如之前提到过的HPA( 根据CPU资源当前利用率进行平滑扩展,典型的元数据型 )

2、k8s 集群中的资源

k8s集群中所有的内容都被抽象成为资源,资源被实例化后则被叫做对象。实例化的含义其实就是被运行了、被执行了、被调用了。

名称空间级别

Role、RoleBinding 属于名称空间级别

工作负载型资源、服务发现及负载均衡型资源、配置与存储型资源、特殊类型的存储卷都属于名称空间级别资源。

工作负载型资源

Pod(k8s创建部署的最小单位,是一组容器的集合)、ReplicaSet(控制器,管理pod的创建,通过标签来控制pod的副本数)、Deployment(控制器,通过控制RS的创建来控制pod的创建)、StatefulSet(为了有状态服务特意创建的管理器)、DaemonSet(控制器,为了让所有的(或者特定的)Node节点上运行同一个Pod的副本)、Job、CronJob、( RC在v1.11版本被RS代替 )

服务发现及负载均衡型资源

Sevice、Ingress( 这两者都是为了把k8s资源给暴露出去 )

配置与存储型资源

Volume(卷存储,为了pod的持久化存储)、CSI(Container Storage Interface,符合 CSI 规定的第三方存储资源就可以被容器所调用)

特殊类型的存储卷

ConfigMap(使用它来存储一些配置文件,以达到热更新的状态)、Secret(用来存储密码、密钥等一些敏感的数据)、DownwardAPI(类似CSI,把外部环境的信息输出给容器)

集群级资源

Namespace、Node、Role、ClusterRole、RoleBinding、ClusterRoleBinding

元数据型资源

HPA、PodTemplate(pod模板)、LimitRange(资源限制)

根据一些指标来进行相关的操作

3、资源清单

在k8s中,一般使用yaml格式的文件来创建符合预期期望的pod,这样的yaml文件一般被称为资源清单

yaml语法:

yaml-1

yaml-2

yaml-3

\> 右尖括号 表示只有空白行才会被识别为换行,原来的换行符都会被转换成空格

4、常用字段解释

必须存在的属性

image.png

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  namespace: default
  labels:
    app: myapp
    version: v1
spec:
  containers:
    - name: app
      image: 镜像名称
    - name: test
      image: 镜像名称

主要对象

image.png

yaml资源清单主要对象2

yaml资源清单主要对象3

额外的参数项:

yaml资源清单额外参数项

① 为什么要写版本呢?

因为在k8s中,API Server提供集群管理的是Restful API 接口(包括认证授权、数据校验以及集群状态变更),而Restful风格的一般是通过get、push、put等操作对一个URL进行上传、下载等等,而这个URL后边携带有以下两个值:

url/组/版本

这也就意味着如果我们要调度对应的资源的时候,必须要指明对应向哪个组下的哪个版本调度对象(每一种类型的资源组、版本下是不一样的)

5、Pod生命周期

image.png

Init C(Init 容器)作用:

因为Init 容器具有与应用程序容器分离的单独镜像,所以它们启动相关代码具有如下优势:

◇ Init容器可以包含并运行实用工具。因为如果MainC容器需要用到某些文件、工具,但是这些工具MainC容器又不是一直都会用,就会导致MainC容器冗余,并且随着工具越来越多,MainC容器的稳定性也就得不到保障,所以我们就可以把这些工具写入到InitC容器,让它在初始化的时候就把MainC容器需要的文件提前创建出来,这样的话MainC容器就可以正常引用这些文件而又不包含这些文件。

◇ 应用程序镜像可以分离出创建和部署的角色,而没有必要联合它们构建一个单独的镜像。也就是说把主容器构建代码和部署/运行代码(持久化)给分离开来,因为只有代码构建好了才能运行部署,所以可以将构建代码的流程交给InitC去做,MainC去做运行部署/持久化

◇ InitC容器使用Linux NameSpace。所以相对应用程序容器来说具有不同的文件系统视图。因此,它们能够具有访问Secret的权限,而应用程序容器则不能。

它们必须在应用程序容器启动之前运行完成(也就是说如果init Container没有运行成功且正常退出,那应用程序容器是不会被创建的),而应用程序容器是并行运行的,所以Init容器能够提供一种简单的阻塞或延迟应用容器的启动的方法,直到满足了一组先决条件。

疑问:

1、是一个mainC(应用程序容器)对应一个initC容器嘛?如果是一一对应的关系,initC不能并行运行,pod的生命周期中是所有的initC正常退出了之后才会进行MainC的创建吗?mainC可以定义先后启动顺序,那么每个initC需要实现先后启动吗?

答:initC也是一个容器,一般用来执行一些初始化的命令、主容器创建前的前提准备等,不存在哪个initC容器对应哪个mainC容器的情况,initC容器都是在yaml配置文件中所定义的,initC的先后启动顺序取决于他们在配置文件中定义的先后,定义在前的就先创建执行,后创建的就后执行。是所有的initC都创建完成并成功退出之后,mainC才会开始创建

2、

对例子Secret那个特点进行提问:假设一个应用容器需要一个配置文件,但是mainC对该文件所在的文件夹不具有权限,因为该文件夹下还有一些别的重要文件,如果将该文件夹的权限赋予了mainC,那么mainC就可以调用该目录下的所有文件,这样安全性就得不到保证。

可以让initC获取到这个目录的权限,initC获取到这个目录权限之后,将mainC需要的文件从该目录获取到自身,然后写入到mainC,然后initC就退出了,这样mainC也没有那个目录的权限了

是不能直接将文件的权限赋予MainC吗?是只能获取到目录的权限之后才能对其下的文件进行操作吗?

3、

mainC是并行运行的,然后mainC也可以定义先后启动顺序。假设现在有mysql应用程序容器,有apache+php的启动容器,需要mysql先启动并初始化完成,apache+php才能去访问它。假设现在mysql先启动,apache+php后启动,但是mysql还没有初始化成功,apache+php已经初始化成功了,它要去访问mysql,这时候就会出现问题,他会认为mysql出了问题,就会根据pod的重启策略,重新拉起pod或是怎样,如果再来一次还是这种极端的情况,那就会返回出现问题。(这种情况说的可能有些极端)所以这种情况下,就可以为apache+php的应用容器创建一个initc容器去检测mysql是否初始化成功了,如果初始化成功了,那就正常退出,然后启动apache+php容器,这样就不会出现上述的问题了。

上述例子是观看视频时老师讲的例子,但是我个人存在一点疑问,首先initC启动不是先于MainC容器的嘛,是怎么做到先启动mysql容器,然后用initC容器来阻塞php+apache容器的呢?

后续想到,因为这里的mysql容器与php+apache容器不在一个 Pod中,所以可以先启动mysql所在的容器,而同时在php所在的Pod中可以定义一个init Container来阻塞php容器一段时间,待mysql所在Pod启动完成之后在启动php容器。

InitC容器注意事项

◇ 在拉起Pod的过程中,Init容器会在 网络和数据卷初始化成功之后 启动( 即辅助容器Pause创建成功之后 ),Init容器不能并行启动,只有上一个Init容器成功退出了,下一个Init容器才能开始启动。

◇ 如果Init容器启动失败,它将会根据init Pod的 restartPolicy 指定的策略进行重试,例 init Pod 的 restartPolicy 设置为了Always ,Init容器失败时将会使用restartPolicy策略,直至成功或是达到了重启上限

◇ 在所有的Init容器成功之前,应用程序 Pod 的 status 将不会变成Ready状态,Init 容器的端口也不会在Service中进行聚集( 即如果Init容器没有成功退出,应用容器服务肯定是有问题的,这时候就不会将Pod的端口聚集给svc,进而不能暴露给客户端 )

◇ 如果Pod重启,所有的Init容器必须重新执行

◇ 对Init容器spec的修改被限制在容器image字段,修改其他字段都不会生效。更改Init容器的image字段,等价于重启该Pod

这个意思就是
    对于Pod来说,是可以后期调整它的运行状态的,比如使用命令kubectl edit pod pod名称,这个命令其实就会以yaml资源清单的形式打开该Pod,单拿Init容器的字段来说,很多字段是不可修改的,而可修改的字段只有image字段,image字段被修改了才会改变init容器的状态,其他字段都不会影响init容器的状态。
image.png

◇ 应用容器MainC在yaml资源清单下的所有配置字段 Init容器都一样可以使用,除了readinessProbe(就绪检测)字段,initC本来就是用来做初始化操作的,执行完就成功退出了,给你个就绪检测这像话嘛!

◇ 在Pod中的每个app容器和Init容器的名称必须唯一,与任何其它容器共享同一个名称都会在验证时抛出错误。并且,在资源清单中定义init容器的时候,它使用的端口可以一致,比如都是80,因为init容器不能并行运行嘛,一个成功退出了其他的才能启动,当一个退出了端口肯定就已经解除占用了,所以定义的时候使用的端口可以一致。

Pod容器生命周期

首先kubectl创建pod的请求指令被交互到到API接口(API Server),这时Etcd数据库则会与ApiServer交互,将请求写进Etcd存储起来,而调度器Scheduler会与ApiServer交互根据调度算法选出最优节点,调度器scheduler也会与该节点上的kubelet进行交互,由Api Server将请求调度到worker节点的kubelet上,kubelet会去操作CRI,把传递过来的指令转换为容器能听懂的命令,进行pod的拉起和容器环境的创建与初始化。

也就是进入到了Pod的生命周期部分,即pod的创建部分,它首先会拉起一个pause容器(就是pod的辅助容器),然后进入到initC(init Container,初始化容器,如果有init容器,则会先创建所有的init容器,如果没有就去创建应用程序容器)的部分,但是init C仅仅是初始化容器部分,并不会随着pod的生命周期而存在,也就是初始化容器完成后initC就会退出。Pod能够具有多个容器,Pod也能够有一个或多个先于应用容器启动的Init容器。

可以有多个initC容器(通过资源清单配置文件定义的),但是它们不能并行同时进行,只有一个完成之后才可以进行下一个init C( 多个init容器时,启动的先后顺序取决于在资源清单中定义该init容器字段的前后顺序 )。

如果Pod的Init容器失败了,k8s就会不断地重启该Pod,直到Init 容器成功为止,因为init容器的restartPolicy默认为Always;如果inint 容器对应的restartPolicyNever,(默认为Always)它就不会重新启动

initC正常退出(返回状态码是0,如果没有正常退出,根据initC的重启策略重新执行initC进程)之后就进入到了主容器(MainC)(可以有一个或多个主容器)进程的运行了。

(MainC容器就是主容器,也就是运行应用程序的容器,)

主容器执行前可以允许执行一个start指令,退出之前也可以执行一个stop指令。同时还有一个readiness指令,一个liveness指令,分别是就绪检测、生存检测。(就绪检测、生存检测都是可选的)

那么就绪检测有什么用呢?

如果没有就绪检测,在这样的一种情况下可能会有问题:当我们创建了svc、创建了Deployment、拉起了pod,假如pod内的容器进程是nginx、tomcat、apache之类的软件,如果这些软件还没有初始化成功,但是pod状态已经显示为了running,此时如果客户端进行访问这个pod的话,肯定就会产生访问错误得问题,只有进程已经初始化成功,就绪了,容器的状态status才会显示为ready或者running,而所以就绪检测就是用来判断容器服务能否正常向外提供服务了,不仅仅是容器启动起来了。所以就绪检测作用就是,只有检测到应用程序pod进程初始化成功了才会将将流量导向到svc,才会将服务向外暴露,避免未初始化完成就向外暴露服务。

也就是说,当设定了就绪检测,那么没有完成readiness就绪检测之前容器的状态不会显示为ready或者running,

那么生存检测的机制有什么作用呢?

当容器内的诸如nginx等向外提供服务的进程变成了僵尸进程,因为进程也没有死掉,容器的状态也还依然是正常的running状态,此时访问nginx服务肯定也会出现问题,所以我们就需要一个机制当容器的服务不能正常提供访问的时候,我们应该重启容器还是怎么着,这就是liveness生存检测机制的作用。

liveness生存检测主容器的进程状态出现异常等情况的时候,根据重启策略对主容器进行重启或停止。

以上就构成了Pod的生命周期。

健康检查:

探针:

探针是由kubelet对容器执行的定期诊断,要执行诊断,kubelet调用由容器实现的Handler(处理程序),Handler处理程序有三种:

截止发文日,k8s目前一共有3种探针,分别是readinessProbelivenessProbestartupProbe;探测方式只有3种,分别是ExecAction,TCPSocketAction,HTTPGetAction;三种探针分别可以使用三种不同的探测方式

ExecAction:在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功,非0情况都认为诊断不成功

TCPSocketAction:对指定端口上的容器的IP地址进行TCP检查,如果端口打开,则诊断被认为是成功的。

HTTPGetAction:对指定的端口和路径上的容器的IP地址执行HTTP Get请求,如果相应的状态码大于等于200且小于400,( 状态码为2XX代表为成功,3XX为跳转,4XX就代表有一定问题,比如403权限问题,404页面丢了 )则诊断被认为是成功的

kubelet可以选择的探针有3种,前边提到过其中的2种:

readinessProbe:就绪检测,指示容器是否准备好为请求提供服务。只有readinessProbe检测成功后,应用程序容器(MainC)才能够宣布对外提供服务;如果就绪检测失败,端点控制器将从与Pod匹配的所有Service的端点中删除该Pod的地址,初始延迟之前的就绪状态默认为Failure

LivenessProbe:生存检测,livenessProbe会跟随应用程序容器的整个生命周期,从应用程序容器的启动到结束,它都会循环的对其进行生存检测。如果LivenessProbe检测为失败,kubelet就会杀死该容器,同时该容器将会受到 yaml资源清单重启策略的影响。

最新的一种是startupProbe:startupProbe指示容器中的应用是否已经启动,在v1.16版本被引入。如果使用了startupProbe,则所有的其他探针都会被禁用,直到此探针成功为止。如果startupProbe检测失败,kubelet将会杀死容器,该容器将会依照重启策略进行重启,如果容器没有使用startupProbe检测,容器的status默认为success

探针在资源清单中都是绑定在具体的应用程序容器下的,也就是说针对不同的应用程序容器可以使用不同的探针

那么何时该使用livenessProbe存活态探针?

如果容器中的进程能够在遇到问题或不健康的情况下自行崩溃,则不一定需要存活态探针livenessProbe; kubelet 将根据 Pod 的restartPolicy 自动执行修复操作。

如果你希望容器在探测失败时被杀死并重新启动,那么请指定一个存活态探针livenessProbe, 并指定restartPolicy 为 "Always" 或 "OnFailure"。

那么何时该使用readinessProbe就绪态探针?

如果仅要在探测成功时才开始向 Pod 发送请求流量,请指定就绪态探针。 在这种情况下,就绪态探针可能与存活态探针相同,但是使用了就绪态探针的存在意味着 Pod 在启动阶段不接收任何数据,并且只有在探针探测成功后才开始接收数据

如果你的容器需要加载大规模的数据、配置文件或者在启动期间执行迁移操作,可以添加一个 就绪态探针,因为这样的话就避免容器初始化完成之前就被接入了流量

如果你希望容器能够自行进入维护状态,也可以指定一个就绪态探针,检查某个特定于 就绪态 的因此不同于存活态探测的端点。

说明: 请注意,如果你只是想在 Pod 被删除时能够排空请求,则不一定需要使用就绪态探针; 在删除 Pod 时,Pod 会自动将自身置于未就绪状态,无论就绪态探针是否存在。 等待 Pod 中的容器停止期间,Pod 会一直处于未就绪状态。

那么何时该使用startupProbe启动探针?

对于所包含的容器需要较长时间才能启动就绪的 Pod 而言,启动探针是有用的。 你不再需要配置一个较长的存活态探测时间间隔,只需要设置另一个独立的配置选定, 对启动期间的容器执行探测,从而允许使用远远超出存活态时间间隔所允许的时长。

如果你的容器启动时间通常超出 initialDelaySeconds + failureThreshold × periodSeconds 总值,你应该设置一个启动探测,对存活态探针所使用的同一端点执行检查。 periodSeconds 的默认值是 30 秒。你应该将其 failureThreshold 设置得足够高, 以便容器有充足的时间完成启动,并且避免更改存活态探针所使用的默认值。 这一设置有助于减少死锁状况的发生。


这里引用一下极客运维圈的解释:

那么在什么时候会用startupProbe呢?
正常情况下,我们会在pod template中配置livenessProbe来探测应用程序是否正常运行,如果异常则会触发restartPolicy重启Pod(因为默认情况下restartPolicy设置的是always)。

如下:

livenessProbe:
  httpGet:
    path: /test
    prot: 80
  failureThreshold: 1
  initialDelay:10
  periodSeconds: 10

上面配置的意思是容器启动10s后每10s检查一次,允许失败的次数是1次。如果失败次数超过1则会触发restartPolicy。

但是有时候会存在特殊情况,比如服务A启动时间很慢,需要60s。这个时候如果还是用上面的探针就会进入死循环,因为上面的探针10s后就开始探测,这时候我们服务并没有起来,发现探测失败就会触发restartPolicy。这时候有的朋友可能会想到把initialDelay调成60s不就可以了?但是我们并不能保证这个服务每次起来都是60s,假如新的版本起来要70s,甚至更多的时间,我们就不好控制了。有的朋友可能还会想到把失败次数增加,比如下面配置:

livenessProbe:
  httpGet:
    path: /test
    prot: 80
  failureThreshold: 5
  initialDelay:60
  periodSeconds: 10

这在启动的时候是可以解决我们目前的问题,但是如果这个服务挂了呢?如果failureThreshold=1则10s后就会报警通知服务挂了,如果设置了failureThreshold=5,那么就需要5*10s=50s的时间,在现在大家追求快速发现、快速定位、快速响应的时代是不被允许的。

在这时候我们把startupProbelivenessProbe结合起来使用就可以很大程度上解决我们的问题。

如下:

livenessProbe:
  httpGet:
    path: /test
    prot: 80
  failureThreshold: 1
  initialDelay:10
  periodSeconds: 10
 
startupProbe:
  httpGet:
    path: /test
    prot: 80
  failureThreshold: 10
  initialDelay:10
  periodSeconds: 10

★★★★★ 上面的配置是只有startupProbe探测成功后再交给livenessProbe。我们startupProbe配置的是10*10s,也就是说只要应用能够在100s(10次*10秒)内启动都是OK的,而且应用挂掉了10s之内就会发现问题

有眼尖的朋友可能会说,这种还是不能确定具体时间,只能给出一个大概的范围。我个人认为对服务启动时间的影响因素太多了,有可能是应用本身,有可能是外部因素,比如主机性能等等。我们只有在最大程度上追求高效、稳定,但是我们不能保证100%稳定,像阿里这样的大企业对外宣称的也是5个9,6个9的稳定率,如果出问题了,不好意思你恰恰不在那几个9里面,所以我们自己要做好监控有效性,告警的及时性,响应的快速性,处理的高效性。


#  通过官方解释以及上边引用该文章的解释,博主个人理解什么情况下要使用startupProbe探针呢?
#
#  当容器的应用程序启动需要较长时间,且又为了避免该容器内应用程序挂掉后经较长时间才被定位到问题,
#  这时候就要使用liveinessProbe + startupProbe 搭配使用来尽可能灵活的解决问题,详细分析可见上边引用的部分,讲解的巨透彻!

每次探测都将获得以下三种结果之一:

成功:容器通过了诊断

失败:容器未通过诊断

未知:诊断失败,因此不会采取任何行动

如果容器探测不成功,就会被挂起,直到探测成功为止。

举例:

1、就绪检测:

readinessProbe-httpget

apiVersion: v1
kind: Pod
metadata:
  name: readiness-httpget-pod  # pod的名称
  namespace: default           # pod所在的名称空间
spec:
  containers:
  - name: readiness-httpget-container  # 容器的名称
    image: web/myapp:v1                # 镜像名称
    imagePullPolicy: IfNotPresent      # 镜像下载策略,IfNotPresent代表如果本地有就不去远端仓库下载
    readinessProbe:                    # 代表使用的探针是就绪检测
      httpGet:                         # 就绪检测的方式是httpGet
        port: 80
        path: /index.html
        initialDelaySeconds: 1         # 定义就绪检测的延迟,也就是容器启动1s之后再进行就绪检测
        periodSeconds: 3               # 就绪检测的检测间隔时间

2、存活检测:

这个存活检测的例子比较搞怪,首先当pod拉起的时候,对容器指定了要在其内执行的命令,即首先创建一个文件,之后休眠1分钟,然后删除该文件,再休眠6分钟;而该容器又指定了liveinessProbe检测,检测的类型为ExecAction检测,即检测指定命令在该容器内的返回状态码,检测的命令是检测该文件还在不在,在容器创建后1s开始检测,检测失败重新检测的时间是3s;因为该容器command指定1分钟后就会删除该文件,这时候liveinessProbe检测就会失败,这时候容器就会被杀掉,pod内没有了容器就会重启(因为pod默认重启策略为Always),然后循环创建文件、休眠、删除文件等上述步骤。

livenessProbe-exec

apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec-pod
  namespace: default
spec:
  containers:
  - name: liveness-exec-container
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","touch /tmp/live ; sleep 60; rm -rf /tmp/live; sleep3600"]
    livenessProbe:
      exec:
        command: ["test","-e","/tmp/live"]
      initialDelaySeconds: 1
      periodSeconds: 3

livenessProbe-httpget

apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget-pod
  namespace: default
spec:
  containers:
  - name: liveness-httpget-container
    image: hub.ishells.cn/library/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    livenessProbe:
      httpGet:
        port: http
        path: /index.html
      initialDelaySeconds: 1  # 容器创建1s后进行httpGet测试
      periodSeconds: 3       # 3s进行一次httpGet测试
      timeoutSeconds: 10     # http访问测试时的最大超时时间

livenessProbe-tcp

apiVersion: v1
kind: Pod
metadata:
  name: probe-tcp
spec:
  containers:
  - name: nginx
    image: hub.atguigu.com/library/myapp:v1
    livenessProbe:
      initialDelaySeconds: 5
      timeoutSeconds: 1
      tcpSocket:
        port: 80
      periodSeconds: 10

start command、stop command
生命周期中的启动、退出命令

apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: nginx
    lifecycle:   # 定义启动、推出命令的上级字段
      postStart:  # 定义启动命令
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the postStart handler >/usr/share/message"]
      preStop:     # 定义退出命令
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the poststop handler >/usr/share/message"]

Podhook

Podhook(钩子)是由Kubernetes管理的kubelet发起的,当容器中的进程启动前或者容器中的进程终止之前运行,这是包含在容器的生命周期之中。

可以同时为Pod中的所有容器都配置PodHook的类型包括两种:

exec:执行一段命令

HTTP:发送HTTP请求

PodSpec中有一个restartPolicy字段,可能的值为Always、OnFailure和Never。默认为Always。restartPolicy适用于Pod中的所有容器。restartPolicy仅指通过同一节点上的kubelet重新启动容器。失败的容器由kubelet以五分钟为上限的指数退避延迟(10秒,20秒,40秒...)重新启动,并在成功执行十分钟后重置。如Pod文档中所述,一旦绑定到一个节点,Pod将永远不会重新绑定到另一个节点

Pod的status字段是一个PodStatus对象,PodStatus中有一个phase字段。

Pod的相位(phase)是Pod在其生命周期中的简单宏观概述。该阶段并不是对容器或Pod的综合汇总,也不是为了做为综合状态机Pod相位的数量和含义是严格指定的。

除了本文档中列举的状态外,不应该再假定Pod有其他的phase值

pod phase(相位)

pod状态.png

挂起(Pending):Pod已被Kubernetes系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度Pod的时间和通过网络下载镜像的时间,这可能需要花点时间 (请求已被提交,但是资源还没有被创建,需要等待一段时间)

运行中(Running):该Pod已经绑定到了一个节点上,Pod中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态(状态显示running不代表pod服务已经可以被正常访问了,因为可能不是所有的容器都已经运行了,并且可能处于重启状态)

成功(Succeeded):Pod中的所有容器都被成功终止(返回状态码为0),并且不会再重启( 常用在job和crontab中,后面学到会详细记录 )

失败(Failed):Pod中的所有容器都已终止了,但是至少有一个容器是终止失败的状态。也就是说,容器以非0状态退出或者被系统终止未知(Unknown):因为某些原因无法取得Pod的状态,通常是因为与Pod所在主机通信失败

参考:
1、尚硅谷汪洋老师视频
2、https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/
3、https://my.oschina.net/u/4287160