Pod资源详解
# Pod资源
Pod资源是K8S集群中的最小资源调度单位,我们只能通过管理Pod来间接管理容器。
一个Pod中可以包含一个或多个容器,同个Pod中的多个容器的网络是共享的,可以通过lo(127.0.0.1)进行通信,同时存储资源也是共享挂载的。
# Pod生命周期
# 常见的Pod状态
# Pending - 挂起状态
- 请求创建Pod时,条件无法满足,调度不能完成。
- 比如:已经创建但没有能够运行它的节点,硬件资源不够的情况。
# Running - 运行状态
- Pod中的容器正常运行或存活检测正常。
# Failed - 失败状态
- 比如:拉取镜像失败。
# Succeeded - 成功状态
- 一般部署Job时会出现,表示Pod中的所有容器正常退出。
# Unknown - 未知状态
- 比如:节点的kubelet进程出现故障。
# 生命周期过程
# 1. Pod创建
- 创建请求提交给apiserver,apiserver将创建请求的目标状态保存在etcd中。
- 然后apiserver会请求scheduler进行资源调度挑选出合适的节点,同时将调度结果保存在etcd中。
- 随后目标节点接收到apiserver的创建请求,并拿到要创建的Pod的资源配置清单。
- 然后Node节点根据清单创建目标Pod,并将创建结果发回给apiserver,由apiserver将结果保存在etcd中。
# 2. Pod启动
- Pod启动时,需要先等init(初始化)容器完成初始化,初始化后才是真正的开始启动。
- init初始化容器,一般主容器启动之前,会先运行一个"初始化容器",用来初始化环境。
- 初始化容器可以有多个,他们可以串行执行,初始化容器初始化完之后,就会关闭退出。
# 3. Pod运行
- 在主容器刚启动时,会先执行启动后钩子(post start) 所指定的程序命令。
- 主容器运行过程中,可以对其进行容器探测,也就是健康状态检查。
- 通过
liveness probe
和readiness probe
- 通过
- 在主容器即将退出前,会先执行结束前钩子(post stop) 所指定的程序命令。
# 4. Pod结束
- 在Pod停止时,为了防止Pod内数据丢失,K8s会先向Pod内的所有容器发送中止信号,然后给一个宽限期,等待一个宽限期时间后如果容器还没有中止,就会强制中止这些容器(默认30秒,可以自行设定)。
- 主容器退出后,Pod就结束了。
# 容器探测
# 介绍
- 通过在容器中做探针用来获取判断数据,并将其作为判定容器其是否健康的标准。
# 探针类型
- ExecAction:直接执行命令,返回码为0表示存活。
- TCPSocketAction:直接向socket套接字发送TCP请求,连接成功表示存活。
- HTTPGetAction:直接向http的端口发送Get请求,返回200/301/302表示存活。
# 探测方式
# Pod资源配置清单
# HEAD头部字段
apiVersion: v1
kind: Pod
1
2
2
# pod.spec.containers <[]object>
- 容器配置 (必选),用于配置Pod的容器信息
# name <string>
- 容器名称 (必选),例如:"name: myapp"
# image <string>
- 容器镜像 (必选),例如:"image: busybox:latest"
# imagePullPolicy <string>
镜像拉取策略,资源一旦被创建,则该策略无法再被更新,只能删除原资源重新创建。
Always
(默认)- 总是去仓库下载,无论本地有或者没有。
- 如果镜像标签是latest则可以使用该策略,因为latest标签我们不知道是否有更新。
Never
- 总是不去仓库下载,如果本地有就用,没有就等待。
IfNotPresent
- 如果本地不存在则去仓库下载,通过镜像名+版本标签来判断。
- 如果镜像使用的是指定版本,则可以使用该策略。
# ports <[]object>
- 声明容器暴露的端口,它仅仅只是"声明"容器暴露的端口,并不会实际限制容器监听的端口。
- 反过来讲不管声不声明暴露的端口,只要容器里的进程在监听,那么这些在监听的端口实际上都是暴露的,当然只是在容器网络上暴露。
# - name <string>
- 端口名称
# - containerPort <integer>
- 容器端口 (必选)
# - protocol <string>
- 端口协议,需要大写,默认是TCP
# env <[]object>
- 用于指定容器的环境变量。
# - name <string>
- 指定变量名 (必选)
- 如果要分隔应该使用"_"下划线,而非使用"-"
- 建议变量名大写,以表明它是环境变量
# - value <string>
- 指定变量值
- 如果需要引用其他变量,则需要使用
$(变量名)
的格式
# - valueFrom <string>
- 引用资源对象的数据作为变量值。
configMapKeyRef <object>
- 引用configMap的数据- name <string> :指定要引用的configMap资源的名称
- key <string> :指定要引用的configMap资源的数据的键名(必选)
- optional <boolean> :指定Pod创建时configMap是否必须存在(可选)
secretKeyRef <object>
- 引用secret的数据- name <string> :指定要引用的secret资源的名称
- key <string> :指定要引用的secret资源的数据的键名(必选)
- optional <boolean> :指定Pod创建时secret是否必须存在(可选)
fieldRef <object>
- 引用当前Pod资源的字段- 例如:metadata.name、metadata.namespace、status.hostIP...
resourceFieldRef <object>
- 引用资源限制字段
# command & args
# command <[]string>
- 指定启动命令,对应Dockerfile中的Entrypoint
# args <[]string>
- 指定启动命令,对应Dockerfile中的Cmd
# command和args的引用逻辑
- 如果仅指定了command,则仅使用该command指定的命令,镜像本身的Cmd和Entrypoint被忽略。
- 如果即没指定command,又没指定args,则会使用镜像本身的命令。
- 如果仅指定了args,则会将args当做参数,将镜像本身的Entrypoint当做命令,镜像本身的Cmd被忽略。
- 如果即指定了command,又指定了args,则会将command当做命令,将args当做参数,镜像本身的Cmd和Entrypoint被忽略。
# 注意
- 启动命令不会运行在shell中,而是直接运行指定的命令程序,如果要运行在shell中可以用
/bin/sh -c [命令]
来指定以shell启动运行命令。
- 启动命令不会运行在shell中,而是直接运行指定的命令程序,如果要运行在shell中可以用
# livenessProbe <object>
- 存活性探测,用来判断主容器或主进程是否正常存活。
- 如果存活性探针检测到容器并非存活后,会对该Pod的容器进行重启。
- 它是由kubelet对容器进行健康检查的,所以探针的host参数要以节点级为中心进行配置,也就是说网络相关的探针不能使用127.0.0.1进行配置。
# - exec/tcpSocket/httpGet (探针配置三选一)
# exec <object>
- 通过执行指定的命令,来判断是否容器或进程是否存活。
- 如果执行命令的返回值为0,则判断为成功。返回值为非0,则判断为失败。
command <[]string>
- 指定执行的命令- 例如:command: ["test", "-e", "/tmp/healthy"]
- 通过执行指定的命令,来判断是否容器或进程是否存活。
# tcpSocket <object>
- 通过对指定Socket尝试TCP连接,来判断容器或进程是否存活。
- 连接成功则判断为成功,连接失败则判断为失败。
host <string>
- 指定尝试连接的Host,默认是Pod的IPport <string>
- 指定尝试连接的端口 (1-65535) (必选)- 可以直接指定端口号,也可以引用此前配置的容器声明暴露的端口的名称作为其值。
- 通过对指定Socket尝试TCP连接,来判断容器或进程是否存活。
# httpGet <object>
通过对指定URL进行请求,来判断容器或进程是否存活。
- 返回响应码为200/301/302则表示成功,返回响应码不为200/301/302则表示失败。
host <string>
- 指定请求的Host,默认是Pod的IPport <string>
- 指定尝试连接的端口 (1-65535) (必选)- 可以直接指定端口号,也可以引用此前配置的容器声明暴露的端口的名称作为其值。
path <string>
- 指定请求的URL路径,默认为"/"根路径。- 例如:
/health/check
- 例如:
scheme <string>
- 指定使用的HTTP协议,需要大写,HTTP(默认)或HTTPS最终会请求URL为
HOST:PORT[PATH]
,例如:httpGet: host: 10.1.0.3 port: 80 path: /index.html # 最终后会解析为: http://10.1.0.3:80/index.html
1
2
3
4
5
6
# - failureThreshold <integer>
失败次数阈值,指定判断是否是真失败的判断次数 (默认3次)。
只有失败达到指定次数,才会真的判断为失败,防止一时的波动造成的误报。
# - initialDelaySeconds <integer>
- 初始化延时探测时间,指定容器启动后,等待多少秒开始探测。
- 因为容器刚启动时还没有初始化完,如果此时就进行探测,探测结果会不准确,所以需要延时。
# - periodSeconds <integer>
- 周期间隔时长,指定间隔多少秒探测一次 (默认10秒)。
# - timeoutSeconds <integer>
- 探测超时时间,指定每次探测的超时时长 (默认1秒),如果探测超时则算一次失败。
# readinessProbe <object>
- 用来判断主容器中的主进程是否可以正常提供服务。
- 如果不做就绪性探测,那么Pod一启动,就可能被关联到某Service上去,然而此时Pod内的进程实际还没有启动完成。所以此时如果有请求被Service调度过来,就可能产生Pod无法正常提供服务的问题。
- 就绪性探测检测到容器无法正常提供服务后,并不会重启该容器,只会不再调度请求到出故障的Pod。
- 它是由kubelet对容器进行健康检查的,所以探针的host参数要以节点级为中心进行配置,也就是说网络相关的探针不能使用127.0.0.1进行配置。
- 配置参数和存活探测完全一致,参考上方livenessProbe即可。
# lifecycle <object>
- 用于控制Pod的生命周期策略。
# - postStart <object>
启动后钩子,在主容器刚启动时,会立即执行的操作,如果操作失败,则会中止并根据重启策略重启容器。
- 比容器命令执行稍慢些,所以容器命令不能强依赖于该钩子。
# exec <object> - 执行指定的命令
command <[]string>
# tcpSocket <object> - 对指定Socket发送TCP连接
host <string>
- 指定尝试连接的Host,默认是Pod的IPport <string>
- 指定尝试连接的端口 (1-65535) (必选)
# httpGet <object> - 对指定URL进行请求
host <string>
- 指定请求的Host,默认是Pod的IPport <string>
- 指定尝试连接的端口 (1-65535) (必选)path <string>
- 指定请求的URL路径,默认为"/"根路径。scheme <string>
- 指定使用的HTTP协议,HTTP(默认)或HTTPS
# - preStop <object>
中止前钩子,在主容器收到中止信号之后,在真正中止之前,会立即执行的操作
# exec <object> - 执行指定的命令
command <[]string>
# tcpSocket <object> - 对指定Socket发送TCP连接
host <string>
- 指定尝试连接的Host,默认是Pod的IPport <string>
- 指定尝试连接的端口 (1-65535) (必选)
# httpGet <object> - 对指定URL进行请求
host <string>
- 指定请求的Host,默认是Pod的IPport <string>
- 指定尝试连接的端口 (1-65535) (必选)path <string>
- 指定请求的URL路径,默认为"/"根路径。scheme <string>
- 指定使用的HTTP协议,HTTP(默认)或HTTPS
# pod.spec.imagePullSecrets <[]object>
私有仓库Secret,指定私有仓库用的认证信息Secret (可指定多个)。
# name <string>
- 私有仓库认证Secret名称
# pod.spec.nodeSelector <map[string]string>
节点标签选择器,用于限制Pod仅运行在哪个或哪类节点之上的,会影响资源的调度方式。
使用matchLabels方式定义,例如:
nodeSelector: - 标签名称: 标签值 ... ...
1
2
3
# pod.spec.restartPolicy <string>
- 定义Pod的容器重启策略。
Always
(默认)- 总是重启,一旦Pod内的某容器挂了,就重启该容器。
OnFailure
- 只有容器状态为错误时才重启,也就是命令正常执行退出则不会重启。
Never
- 总是不重启。
- 例如:容器执行"sleep 5",执行完后。
- 如果是Always策略,则直接重启。
- 如果是Onfailure策略,因为是正常退出所以不会重启,容器状态只会一直处于停止状态。
- 如果是Never策略,则无论如何都不会重启,容器状态只会一直处于停止状态。
- 容器重启逻辑
- 如果Pod中的容器挂了,则只会重启该容器。除非这个Node节点挂了或者Pod被删除了,才会重新调度。
- 同时容器的不断重启会给系统带来压力,所以容器的每一次重启失败是有间隔策略的。
- 比如:第1次重启是立即重启,第2次重启延时10秒,第2次重启20秒,第4次重启40秒,直到300秒,300秒是最长的等待时间,该延时时间会在一段时间之后重置。
# pod.spec.hostNetwork <boolean>
- 是否使用宿主机的网络名称空间,指定Pod是否直接使用宿主机的网络名称空间,使其他主机可以直接通过节点网络访问Pod。
- true - 使用
- false - 不使用 (默认)
- 在用DaemonSet管理系统级服务Pod时就可以使用该配置。