kubernetes----资源清单4

kubernetes----资源清单4

资源清单

K8s中所有的内容都抽象为资源,资源实例化之后,叫做对象
简单来说K8S,将多台机器整合成一个平台,控制节点和计算节点
在k8s中,一般使用yaml格式的文件来创建符合我们预期期望的pod,这样的yaml文件我们一般称为资源清单

集群资源分类

名称空间级别

默认系统组件会安装在kube-system名称空间下,默认是default名称空间
工作负载型资源(workload):Pod,ReplicaSet,Deployment,StatefulSet,DaemonSet,Job,CronJob(ReplicationController在v1.11版本被废弃)

  • Pod,一个Pod是K8S中的最小部署单元,一个Pod可以拥有一个或多个容器,运行在node节点上
  • 只要有POD就会启动PAUSE容器,PAUSE网络栈是lo环回口
  • POD同一个POD里面的容器端口不可以冲突
  • 一个或多个容器的集合,一组容器一个单元
  • 一个pod共享网络命名空间,也可以共享存储,实现数据共享
  • 数据不会持久
  • RplicationController,RC已经被RS替换了
  • ReplicaSet,RS,RS是调度器,管理POD创建,通过标签选择控制POD副本数量
  • Deployment,DP-->RS-->Pod,控制RS创建,去创建POD,会更新和回滚
  • 更新,新建RS,在RS下创建POD,新创建一个POD,就会删除旧RS下在一个POD,达到滚动更新的状态
  • 回滚,启动一个RS,启动版本的POD,在DP中,升级后不会删除旧版本的RS,仅被停用
  • StatefulSet,有状态服务的管理器
  • DaemonSet ,在每个节点运行一个POD的主键
  • 只要有需要,每个node节点都会运行,可以指定某些NODE不会运行POD,打标志污点,默认所有的都会运行一个
  • 每个NODE会创建一个守护进程,比如创建容器收集日志或监控等,可以把很多POD放一起,也可以分开
  • Job 批处理任务,仅执行一次,保证批处理任务一个或多个结束
  • 如果脚本执行错误,是没有办法执行正常退出的,JOB会判断脚本是否是正常即出,直到正常退出为止,或指定次数
  • CronJob,批处理任务

服务发现及负载均衡型资源(ServiceDiscovery LoadBalance):Service,Ingress(简单来说就是将服务暴露出去)

  • Service,四层
  • Ingress,七层

配置与存储型资源:Volume(存储卷)、CSI(容器存储接口,可以扩展各种各样的第三方存储卷)

  • Volume,给POD提供持久化数据的能力
  • CSI,容器存储接口,只要存储资源符合K8S中的CSI规划,那K8S就可以调用此存储资源

特殊类型的存储卷:ConfigMap(当配置中心来使用的资源类型)、Secret(保存敏感数据)、DownwardAPI(把外部环境中的信息输出给容器)

  • ConfigMap,存储配置文件,达到热更新的一种状态
  • Secret,加密存储方案,可以保存密码文件,密钥等
  • DownwardAPI,通过下载文件接口,调用存储资源

集群级别

不管在什么名称空间,在其他名称空间都可以看的到,一旦定义后,在全集群中都可见或调用

集群级资源:Namespace,Node,Role,ClusterRole,RoleBinding,ClusterRoleBinding

  • Namespace,名称空间
  • Node,工作节点
  • Role,角色
  • ClusterRole,
  • RoleBinding,
  • ClusterRoleBinding

元数据型

比如,HPA,根据CPU的利用率,简单来说主是通过某个指标进行操作
元数据型资源:HPA,PodTemplate,LimitRange

  • HPA,基于RS定义,例,CPU利用率大于80%,进行扩容,最大10个,最小2个POD,HPA会一直监控资源利用率,设置一定的阀值,水平扩展

YAML

YAML是一个可读性高,用来表达数据序列的格式。
是一种标记语言,但为了强调这种语言以数据做中心,而不是以标记语言为重点
基本语法
缩进时不允许使用TAB键,只允许使用空格
缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
#标识注释,从这个字符一直到行尾,都会被解释器忽略

YAML支持的数据结构
对象:键值对的集合,又称为映射(mapping)/ 哈希(hashed)/ 字典(dictionary)
数组:一组按次序排列的值,又称为序列(sequence)/ 列表(list)
纯量(scalars):单个的、不可再分的值

常用字段解释

参数名 字段类型 说明
version String 这里是指的是K8S API的版本,目前基本上是v1,可以用kubectl api versions命令查询
kind String 这里指的是yaml文件定义的资源类型和角色,比如:Pod
metadata object 元数据对象,固走值就写metadata
metadata.name string 元数据对象的名字,这里由我们编写,比如命名Pod的名字
metadata.namespace string 元数据对象的命名空间,由我们自身定义
Sped Object 详细定义对象,固定值就写Spec
spec.containers[] list 这里是Spec对象的容器列表定义,是个列表
spec.containers[].name String 这里定义容器的名字
spec.containers.image String 这里定义要用到的镜像名称混子了没行
spec.containers[].name String 定义容器的名字
spec.containers[].image String 定义要用到的镜像名称
spec.containers[].imagePullPolicy String 定义鏡像拉取策略,有Always,Never.INotPresent三个值可选(1)Aways:意思是每次都尝试重新拉取镜像(2)Never:表示仅使用本地镜像(3)INotPresent:如果本地有镜像就使用本地镜像,没有就拉取在线镜像。上面三个值都没设置的话,默认是Always.
spec.containers[].command[] List 指定容器启动命令,因为是数组可以指定多个,不指走则使用镜像打包时使用的启动命令。
spec.containers[].args[] List 指定容器启动命令参数,因为是数组可以指定多个。
spec.containers[].workingDir String 指定容器的工作目录
spec.containers[].volumeMounts[] List 指定容器内部的存储卷配置
spec.containers[].volumeMounts[].name String 指定可以被容器挂载的存储卷的名称
spec.containers[].volumeMounts[].mountPath String 指定可以被容器挂载的存储卷的路径
spec.containers[].volumeMounts[].readOnly String 设置存储卷路径的读写模式,ture或者false,string 默认为读写模式
spec.containers[].ports[] List 指定容器需要用到的端口列表
spec.containers[].ports[].name String 指定端口名称
spec.containers[].ports[].containerPort String 指定容器需要监听的端口号
spec.containers[].ports[].hostPort String 指定容器所在主机需要监听的端口号,默认跟上面containerPort相同,注意设置了hostPort司一台主机无法启动该容器的相同副本(因为主机的端口号不能相同,这样会冲突)
spec.containers[].ports[].protoco String 指定端口协议,支持TCP和UDP,默认值为ТСР
spec.containers[].env[] List 指定容器运行前需设置的环境变量列表
spec.containers[].env[].name String 指定环境变量名称
spec.containers[].env[].value String 指定环境变量值
spec.containers[].resources Object 指定资源限制和资源请求的值(这里开始就是设置容器的资源上限)
spec.containers[].resources.limits Object 指定设置容器运行时资源的运行上限
spec.containers[].resources.limits.cpu Object 指定CPU的限制,单位为core数,将用于String docker run --cpu-shares參数(这里前面文章Pod资源限制有讲过)
spec.containers[].resources.limits.memory String 指定MEM内存的限制,单位为MIB,GiB
spec.containers[].resources.requests Object 指定容器启动和调度时的限制设置
spec.containers[].resources.requests.cpu String CPU请求,单位为core数,容器启动时初始化可用数量
spec.containers[].resources.requests.memon String 内存请求,单位为MIB,GiB,容器启动的初始化可用数量
spec.restartPolicy String 定义Pod的重启策略,可选值为Aways,OnFailure,默认值为Always. 1.Always:Pod一旦终止运行,则无论容器是如何终止的,kubelet服务都将重启它。2.0nFailure:只有Pod以非零退出码终止时,kubelet才会重启该容器。如果容器正常结束(退出码为0),则kubelet将不会重启它3.Never:Pod终止后,kubelet将退出码报告给Master,不会重启该Pod.
spec.nodeselector Object 定义Node的Label过滤标签,以key:value格式指定
spec.imagePullSecrets Object 定义pul镜像时使用secret名称,以name:secretkey格式指定
spec.hostNetwork Boolean 定义是否使用主机网络模式,默认值为false,设置true表示使用宿主Boolean机网络,不使用docker网桥,同时设置了true将无法在同一台宿主机上启动第二个副本

资源清单格式

apiversion:group/apiversion	#如果没有给定group名称,那么默认为core,可以使用kubect1 api-versions#获取当前k8s版本上所有的apiVersion版本信息(每个版本可能不同)
kind:	#资源类别
metadata:	#资源元数据
    name
	namespace
	lables
	annotations	#主要目的是方便用户阅读查找
spec:	#期望的状态(disired state)
status:	#当前状态,本字段有Kubernetes自身维护,用户不能去定义

获取apiversion版本信息

kubectl api-versions 

获取资源的apiversion版本信息及字段设置帮助文档

kubectl explain pod
KIND:     Pod
VERSION:  v1

kubectl  explain pod.apiVersion
KIND:     Pod
VERSION:  v1

kubectl explain ingress
KIND:     Ingress
VERSION:  networking.k8s.io/v1

字段配置格式

apiVersion	<string>	#表示字符串类型
kind	<string>
metadata	<Object>	#表示需要嵌套多层字段
labels <map[string]string>	#表示由k:v组成的映射
finalizers	<[]string>	#表示字串列表
ownerReferences	<[]Object>	#表示对象列表
hostPID	<boolean>	#布尔类型
priority	<integer>	#整形
name	<string>	-required-	#如果类型后面接-required-,表示为必值字段
spec	<Object>		#
status	<Object>

示例:通过定义清单文件创建POD

编写POD文件一个POD运行两个容器
vim pods-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: app-pod
  labels:
    app: app
    version: v1
spec:
  containers:
  - name: appname
    image: nginx
  - name: apptest
    image: nginx
	
创建POD
kubectl apply -f pods-demo.yaml
会发现容器名称为apptest启动失败

排错思路
查看POD状态
kubectl get pods
查看容器中的信息,查看状态和事件
kubectl describe pod
查看容器中的日志信息,多个容器需要加-c,指定容器名称
kubectl log app-pod -c apptest	#可以看到是端口冲突
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: ipv6 not available
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/03/19 05:11:17 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/03/19 05:11:17 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/03/19 05:11:17 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/03/19 05:11:17 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/03/19 05:11:17 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/03/19 05:11:17 [emerg] 1#1: still could not bind()
nginx: [emerg] still could not bind()

查看pods详细信息,看POD运行在哪个节点上
kubectl get pods -o wide
实时刷新POD状态
kubectl get pods -w

解决方法
删除第二个容器,或者修改容器端口,一个POD中端口不可以冲突

容器生命周期

例:一个POD中运行两个容器,如果两个容器存在,容器中运行的进程或已中断,由于某种故障未退出,POD处于RUNNING状态,这时服务是不可用的,但对于POD来说是可用,那如何让POD初始化如何去做


POD创建和死亡的过程

容器环境初始化
在POD创建中,基础容器PAUSE会自动被创建
POD生命周期内部
进行INIT C的一个过程,运行POD中的容器,前提条件容器中有文件存在,才可以运行,可以通过INIT C来生成,INIT C只是用于初始化,初始化完成后会死亡,可有多个INIT C,也可以没有,每一个INIT C运行之后,下一个INIT C才可以构建,不可以并行运行,线级过程,在POD创建中,基础容器PAUSE会自动被创建,才进行INIT C,在主容器运行过程中,会有一个START和STOP操作,运行之前,可以让它执行指令,退出同理
readiness就绪检测
例deployment管理4个POD,若某个POD状态RUNNING才可以对外访问,若POD当前是RUNNING状态,里面进程还未启动,会影响用户体验,可以检测让POD中的进程正常启动才变更RUNNING状态
liveness生存检测,主容器的生存周期
在主容器,运行一个NGINX进程,若NGINX僵尸进程,也就相当于服务挂了,若NGINX进程还存在,那么容器也在运行,容器运行那边POD也就存在,POD存在,就表示,用户访问会调度到此服务,当发现容器内部不能对外进行访问的时间,应该如何处理,重启,重建POD
当主容器中的进程与liveness检测不一致,不能工作时,可以重启或删除等操作,可定义策略

init 容器

Pod能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的Init容器

Init容器与普通的容器非常像,除了如下两点:

  • Init容器总是运行到成功完成为止
  • 每个Init容器都必须在下一个Init容器启动之前成功完成(mainC如果退出那么POD就退出了)

如果Pod的Init容器失败,Kubernetes会不断地重启该Pod,直到Init容器成功为止。然而,如果Pod对应的restartPolicy为Never,它不会重新启动,与重启策略有关系,默认是一般重启

init 容器的作用

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

  • 它们可以包含并运行实用工具,但是出于安全考虑,是不建议在应用程序容器镜像中包含这些实用工具的(需要有一些文件创建和数据的梳理,会造成冗余,保证工具的稳定性,可以写入到INITC中)
  • 它们可以包含使用工具和定制化代码来安装,但是不能出现在应用程序镜像中。例如,创建镜像没必要FROM另一个镜像,只需要在安装过程中使用类似sed,awk,python或dig这样的工具。(主要指的是冗余性)
  • 应用程序镜像可以分离出创建和部署的角色,而没有必要联合它们构建一个单独的镜像。(在主容器运行中,构建代码,运行代码,注意流程,构建代码可以给INIT C)
  • Init容器使用Linux Namespace,所以相对应用程序容器来说具有不同的文件系统视图。因此,它们能够具有访问Secret的权限,而应用程序容器则不能(让INIT去获取文件给主容器,给完之后在退出)
  • 它们必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以Init容器能够提供了一种简单的阻塞或延迟应用容器的启动的方法,直到满足了一组先决条件。(例,一个POD两个容器,A容器nginx+php,B容器MYSQL,A容器启动较快,会导致用户A容器提供服务,B容器还未启动,导致后端服务未启动成功和正在启动中,可以在A容器的INITC中加入检测B容器是否启动正常,等待B容器启动成功,在启动A容器)

示例,创建一个POD,一个容器,有两个INITC,当满足INITC条件才会启动主容器,INITC是顺序执行的

[root@k8s-master test]# cat init-damo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod 
  labels: 
    app: myapp 
spec:
  containers:
  - name: myapp-container 
    image: busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600'] 
  initContainers: 
  - name: init-myservice
    image: busybox
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;'] 
  - name: init-mydb 
    image: busybox 
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']

创建POD
kubectl apply -f init-damo.yaml

发现POD状态一直不成功,INITC两个没有处理完
[root@k8s-master test]# kubectl get pods
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:0/2   0          2m57s

[root@k8s-master test]# kubectl describe pods myapp-pod
Init Containers:
  init-myservice:
    Ready:          False	#查看此INIT状态是失败的
	
创建一个myservice文件,第一个INITC,模拟后端服务的条件
[root@k8s-master test]# cat myservice.yaml 
kind: Service 
apiVersion: v1 
metadata: 
  name: myservice 
spec: 
  ports: 
  - protocol: TCP 
    port: 80 
    targetPort: 9376

创建svc
kubectl apply -f myservice.yaml
[root@k8s-master test]# kubectl get pods 
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:1/2   0          17m

[root@k8s-master test]# kubectl describe pods myapp-po
Init Containers:
  init-myservice:
    Ready:          True	#启动成功
	
创建一个myservice文件,第一个INITC,模拟后端服务的条件
[root@k8s-master test]# cat mydb.yaml 
kind: Service 
apiVersion: v1 
metadata: 
  name: mydb 
spec: 
  ports: 
  - protocol: TCP 
    port: 80 
    targetPort: 9377 

创建第二个SVC
kubectl apply -f mydb.yaml

查看POD日志
[root@k8s-master test]# kubectl logs myapp-pod
The app is running!

查看pod状态
[root@k8s-master test]# kubectl get pods 
NAME        READY   STATUS    RESTARTS   AGE
myapp-pod   1/1     Running   0          25m

特殊说明

  • 在Pod启动过程中,Init容器会按顺序在网络和数据卷初始化之后启动(在PAUSE中完成的,每一个启动的是PAUSE,对它操作基本于无)。每个容器必须在下一个容器启动之前成功退出(如果有两个INIT容器,第一个容器执行完成后退出码非0,就不会执行第二个)
  • 如果由于运行时或失败退出,将导致容器启动失败,它会根据Pod的restartPolicy指定的策略进行重试。然而,如果Pod的restartPolicy设置为Always,Init容器失败时会使用RestartPolicy策略
  • 在所有的Init容器没有成功之前,Pod将不会变成Ready状态。Init容器的端口将不会在Service中进行聚集。正在初始化中的Pod处于Pending状态,但应该会将Initializing状态设置为true口
  • 如果Pod重启,所有Init容器必须重新执行(类似幂等,每次执行的结果都一致)
  • 对Init容器spec的修改被限制在容器image字段,修改其他字段都不会生效。更改Init容器的image字段,等价于重启该Pod
  • Init容器具有应用容器的所有字段。除了readinessProbe,因为Init容器无法定义不同于完成(completion)的就绪(readiness)之外的其他状态。这会在验证过程中强制执行(INIT字段与completion字段基本一致,INIT作用就是就绪检测,所以没必须在进行就绪检测,而且执行完就退出了)
  • 在Pod中的每个app和Init容器的名称必须唯一;与任何其它容器共享同一个名称,会在验证时抛出错误(例 同一组INIT C 端口是可以相同的,第一个运行完就会退出,不会有冲突)

容器探针

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

  • ExecAction:在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功
  • TCPSocketAction:对指定端口上的容器的IP地址进行TCP检查。如果端口打开,则诊断被认为是成功的
  • HTTPGetAction:对指定的端口和路径上的容器的IP地址执行HTTP Get请求。如果响应的状态码大于等于200且小于400,则诊断被认为是成功的

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

成功:容器通过了诊断
失败:容器未通过诊断
未知:诊断失败,因此不会采取任何行动

  • livenessProbe:指示容器是否正在运行。如果存活探测失败,则kubelet会杀死容器,并且容器将受到其重启策略的影响。如果容器不提供存活探针,则默认状态为Success (容器的生命周期,检测应用程序和资源是否可用)
  • readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与Pod匹配的所有Service的端点中删除该Pod的IP地址。初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为Success(就绪检测成功,MAINC才可以对外进行访问)

示例就绪检测

检测/usr/share/nginx/html/index1.html文件,若文件可以被访问,则让该POD启动,反之一直被探测,直到能被访问为止
[root@k8s-master test]# cat read.yaml 
apiVersion: v1 
kind: Pod 
metadata: 
  name: readiness-httpget-pod 
  namespace: default 
spec: 
  containers: 
  - name: readiness-httpget-container 
    image: wangyanglinux/myapp:v1
    imagePullPolicy: IfNotPresent 	#如果镜像本地存在,不重新下载远程镜像
    readinessProbe: 
      httpGet: 
        port: 80 
        path: /index1.html 
      initialDelaySeconds: 1 	#延迟时间,1秒后启动
      periodSeconds: 3	#3秒后重试,周期时间
	  
创建pod
kubectl apply -f read.yaml 

[root@k8s-master test]# kubectl get pods -w
NAME                    READY   STATUS    RESTARTS   AGE
readiness-httpget-pod   0/1     Running   0          29s

[root@k8s-master ~]# kubectl describe pods readiness-httpget-pod
  Warning  Unhealthy  22s (x21 over 82s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 404
 
进入容器创建index1.html检测文件
[root@k8s-master ~]# kubectl exec readiness-httpget-pod -it -- /bin/sh
/ # cd /usr/share/nginx/
/usr/share/nginx # ls
html
/usr/share/nginx # cd html/
/usr/share/nginx/html # ls
50x.html    index.html
/usr/share/nginx/html # echo 1 > index1.html
/usr/share/nginx/html # 

[root@k8s-master test]# kubectl get pods -w
NAME                    READY   STATUS    RESTARTS   AGE
readiness-httpget-pod   1/1     Running   0          4m14s

示例存活检测,可基于文件是否存在的机制

创建一个文件,60秒后删除,简单来说此POD可以存活60秒后重启,当然不一定是60秒,还有延时时间和重试时间
[root@k8s-master test]# cat live-exec.yaml 
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; sleep 3600"] 
    livenessProbe: 
      exec: 
        command: ["test","-e","/tmp/live"] 
      initialDelaySeconds: 1 
      periodSeconds: 

创建pod
kubectl apply -f live-exec.yaml 

可以看到重启次数,和当前存活多长时间
[root@k8s-master test]# kubectl get pods -w
NAME                READY   STATUS    RESTARTS   AGE
liveness-exec-pod   1/1     Running   0          7s
liveness-exec-pod   1/1     Running   1          100s
liveness-exec-pod   1/1     Running   2          3m19s
liveness-exec-pod   1/1     Running   3          4m58s
liveness-exec-pod   1/1     Running   4          6m37s
liveness-exec-pod   1/1     Running   5          8m16s
liveness-exec-pod   1/1     Running   6          9m55s
liveness-exec-pod   0/1     CrashLoopBackOff   6          11m
liveness-exec-pod   1/1     Running            7          14m
liveness-exec-pod   0/1     CrashLoopBackOff   7          16m

示例 生存检测,基于httpget方法,状态码的方法

[root@k8s-master test]# cat live-http.yaml 
apiVersion: v1 
kind: Pod 
metadata: 
  name: liveness-httpget-pod 
  namespace: default 
spec:
  containers: 
  - name: liveness-httpget-container 
    image: wangyanglinux/myapp:v1
    imagePullPolicy: IfNotPresent 
    ports: 
    - name: http 
      containerPort: 80 
    livenessProbe: 
      httpGet: 
        port: http 
        path: /index.html 
      initialDelaySeconds: 1 	#延时1秒后监控
      periodSeconds: 3 	#3秒监控一次
      timeoutSeconds: 10 	#延时统计最大延迟时间

创建pods
[root@k8s-master test]# kubectl apply -f live-http.yaml 
pod/liveness-httpget-pod created
[root@k8s-master test]# kubectl get pods
NAME                   READY   STATUS             RESTARTS   AGE
liveness-exec-pod      0/1     CrashLoopBackOff   7          16m
liveness-httpget-pod   1/1     Running            0          3s
[root@k8s-master test]# kubectl get pods -o wide
NAME                   READY   STATUS             RESTARTS   AGE   IP            NODE            NOMINATED NODE   READINESS GATES
liveness-exec-pod      0/1     CrashLoopBackOff   7          16m   10.20.36.72   192.168.10.82   <none>           <none>
liveness-httpget-pod   1/1     Running            0          10s   10.20.36.71   192.168.10.82   <none>           <none>
[root@k8s-master test]# curl 10.20.36.71
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

[root@k8s-master test]# kubectl exec liveness-httpget-pod -it -- /bin/sh
/ # rm -f /usr/share/nginx/html/index.html

可以看到这里POD已经重启了
[root@k8s-master test]# kubectl get pods
NAME                   READY   STATUS             RESTARTS   AGE
liveness-exec-pod      0/1     CrashLoopBackOff   7          19m
liveness-httpget-pod   1/1     Running            1          2m29s

示例使用TCP端口的方式

镜像是80端口,改成8080验证效果
[root@k8s-master test]# cat live-tcp.yaml 
apiVersion: v1 
kind: Pod 
metadata: 
  name: probe-tcp 
spec: 
  containers: 
  - name: nginx 
    image: wangyanglinux/myapp:v1
    livenessProbe: 
      initialDelaySeconds: 5 
      timeoutSeconds: 1 
      tcpSocket: 
        port: 8080
      periodSeconds: 3
	  
创建pods
kubectl apply -f live-tcp.yaml 

可以看到一直重启
[root@k8s-master test]# kubectl get pods -w
NAME        READY   STATUS    RESTARTS   AGE
probe-tcp   1/1     Running   1          16s

示例将检测机制整理到一起

删除default名称空间下的POD
kubectl delete pods --all

创建pod
[root@k8s-master test]# kubectl apply -f live-http2.yaml 
pod/liveness-httpget-pod created
可以看到状态是running,但ready还没有准备好
[root@k8s-master test]# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
liveness-httpget-pod   0/1     Running   0          4s
进入POD中的窗口创建index1.html文件
[root@k8s-master test]# kubectl exec liveness-httpget-pod -it -- /bin/sh
/ # cd /usr/share/nginx/html/
/usr/share/nginx/html # ls
50x.html    index.html
/usr/share/nginx/html # echo 1 > index1.html
查看POD ready 已经正常了
[root@k8s-master test]# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
liveness-httpget-pod   1/1     Running   0          55s
在进入容器中删除index.html文件
[root@k8s-master test]# kubectl exec liveness-httpget-pod -it -- rm -f /usr/share/nginx/html/index.html
可以查看到已经重启过POD了
[root@k8s-master test]# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
liveness-httpget-pod   0/1     Running   1          2m44s

Pod hook

Pod hook(钩子)是由Kubernetes管理的kubelet发起的,当容器中的进程启动前或者容器中的进程终止之前运行,这是包含在容器的生命周期之中。可以同时为Pod中的所有容器都配置hook
Hook的类型包括两种:

  • exec:执行一段命令
  • HТТP:发送HTTP请求

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

Pod phase

Pod的status字段是一个PodStatus对象,PodStatus中有一个phase字段。
Pod的相位(phase)是Pod在其生命周期中的简单宏观概述。该阶段并不是对容器或Pod的综合汇总,也不是为了做为综合状态机
Pod相位的数量和含义是严格指定的。除了本文档中列举的状态外,不应该再假定Pod有其他的phase值

POD当前的一个反馈

状态 说明
挂起(Pending) Pod已被Kubernetes系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度Pod的时间和通过网络下载镜像的时间,这可能需要花点时间
运行中(Running) 该Pod已经绑定到了一个节点上,Pod中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态
成功(Succeeded) Pod中的所有容器都被成功终止,并且不会再重启
失败(Failed) Pod中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止(POD只要有一个容器不正常状态退出,那状态就是失败)
未知(Unknown) 因为某些原因无法取得Pod的状态,通常是因为与Pod所在主机通信失败

示例start stop

[root@k8s-master test]# cat post.yaml 
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: ["/usr/sbin/nginx", "-s", "quit"]
          command: ["/bin/sh", "-c", "echo Hello from the postStop handler > /usr/share/message"] 

[root@k8s-master test]# kubectl apply -f post.yaml 
pod/lifecycle-demo created
[root@k8s-master test]# kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
lifecycle-demo   1/1     Running   0          4s

查看POD中poststart执行没有
[root@k8s-master test]# kubectl exec lifecycle-demo -it -- /bin/bash
root@lifecycle-demo:/# cat /usr/share/message 
Hello from the postStart handler

状态

POD中只有一个容器并且下在运行,容器成功退出

记录事件完成
如果 restartPolicy 为:
Always:重启容器;Pod phase 仍为 Running
OnFailure:Pod phase 变成 Succeeded
Never:Pod phase 变成 Succeeded

Pod 中只有一个容器并且正在运行。容器退出失败

记录失败事件
如果 restartPolicy 为:
Always:重启容器;Pod phase 仍为 Running
OnFailure:重启容器;Pod phase 仍为 Running
Never:Pod phase 变成 Failed

Pod 中有两个容器并且正在运行。容器1退出失败

记录失败事件
如果 restartPolicy 为:
Always:重启容器;Pod phase 仍为 Running
OnFailure:重启容器;Pod phase 仍为 Running
Never:不重启容器;Pod phase 仍为 Running

如果有容器1没有处于运行状态,并且容器2退出:

记录失败事件
如果 restartPolicy 为:
Always:重启容器; Pod phase 仍为 Running
OnFailure:重启容器; Pod phase 仍为 Running
Never:Pod phase 变成 Failed

Pod 中只有一个容器并处于运行状态。容器运行时内存超出限制

容器以失败状态终止
记录 OOM 事件
如果 restartPolicy 为 :
Always:重启容器;Pod phase 仍为 Running
OnFailure:重启容器;Pod phase 仍为 Running

小结

了解容器的生命周期,POD创建和死亡的过程
INITC顺序执行
存活检测,文件存在的方式,或者脚本的成功执行状态码
生存检测,HTTPGET,TCP端口的方式
容器启动与退出动作

原文地址:https://www.cnblogs.com/fina/p/14699450.html