第六章 管理Pod资源对象
1 管理Pod对象容器
1.1 镜像及其获取策略
apiVersion: v1 kind: Pod metadata: name: nginx pod spec: containers: - name: nginx image: nginx:latest imagePullPolicy: Always
容器的”imagePullPolicy“字段用于为其指定镜像获取策略,它的可用值包括如下:
- Always:镜像标签为“latest”或镜像不存在时总是从指定的仓库中获取镜像
- IfNotPresent:仅当本地镜像缺失方才从目标镜像下载镜像。
- Never:禁用从仓库下载镜像,即仅使用本地镜像
1.2 容器暴露端口
如下示例,指定暴露容器上TCP的80端口,并将之命名为http:
apiVersion: vl kind: Pod metadata: name: pod-example spec: containers: - name : myapp image : ikubernetes/myapp :vl ports : - name: http containerPort: 80 protocol: TCP
- containerPort<integre>:必选字段,指定在Pod对象的IP地址上暴露的容器端口
- name<string>:当前端口的名称,并且在当前Pod内必须唯一
- protocol:端口相关的协议,其值仅可为TCP或UDP,默认为TCP
1.3 容器化应用自定义命令和参数
容器的command字段能够指定不同于镜像默认运行的应用程序,并且可以同时使用args字段进行参数传递,他们将覆盖镜像中默认定义;
如果仅为容器定义了args字段,那么他将作为参数传递给镜像中默认指定的运行的应用程序;
如果仅为容器定义了command字段,那么它将覆盖镜像中定义的程序及参数, 并已无参数方式运行应用程序。
如下示例:
apiVersion: v1 kind: Pod metadata: name: pod-with-custom-command spec: containers: - name: myapp image: alpine:latest command : [”bin/sh”] args: ["- c","while true; do sleep 30 ; done"]
1.4 环境变量
apiVersion: v1 kind: Pod metadata : name: pod-with-env spec : containers : - name: filebeat image: ikubernetes/filebeat:S.6.5-alpine env : - name: REDIS HOST value: db.ilinux.io:6379 - name: LOG LEVEL value: info
2 标签与标签选择器
2.1 标签概述
标签是Kubernetes极具特色的功能之一,它能够附加于Kubernetes的任何资源对象之上,简单来说,标签就是“键值”类型的数据,他们可在资源创建时直接指定,也可以随时按需添加活动对象中,而后即可由标签选择器进行匹配度检查从而完成资源挑选。一个对象可拥有不止一个标签,而同一个标签也可以添加至多个资源之上。
常用标签示例:
- 版本标签:"releaes":"stable","release":"canary","release":"beta"
- 环境标签:"environment":"dev","environment":"qa","environment":"production"
- 应用标签:"app":"ui","app":"as",“app”:“pc”,"app":"sc"
- 架构层级标签:"tier":"frontend","tie":"backend","tie":"cache"
- 分区标签:"partition":"customerA","partition":"customerB","partition":"customerC"
- 品控级别标签:"track":"daily","track":"weekly"
2.2 管理资源标签
apiVersion: v1 kind: Pod metadata: name: pod-with-labels labels: env: qa tier: frontend spec : containers: - name: myapp image: ikubernetes/myapp:vl
使用--show-labels选项,可以获取资源标签信息
# kubectl get pods --show-labels
kubectl label命令可以直接管理活动对象的标签,按需对标签进行添加修改等操作,例如,为pod-example添加env=production标签
# kubectl label pods pod-example env=production
对已经附带了指定键名的标签,使用“kubectl label”为其设定新的值,需要使用“--overwrite”命令强制覆盖原有的值。例如,将pro-with-labels的env的值修改为“testing”
# kubectl label pods pod-with-labels env=testing --overwrite
2.3 标签选择器
标签选择器用于表达标签的查询条件或选择标准,Kubernetes API目前支持两个选择器,基于等值关系以及基于集合关系。
基于等值关系的标签选择器可用操作符有“=”、“!=”
例如:显示标签键名env的值不为qa,且标签键名tier的值为frontend的所有Pod对象:
# kubectl get pods -l "evn!=qa,tier=frontend"
基于集合关系的标签选择器支持in、notin和exists三种操作符,他们的使用格式及意义具体如下:
- KEY in (VALUE!,VALUE2,...):指定的键名存在于给定的列表中即满足条件
- KEY notin (VALUE!,VALUE2,...):指定的键名的值不存在给定的列表中即满足条件
- KEY:所有存在此键名标签的资源
- !KEY:所有不存在此键名标签的资源
例如:列出标签键名env的值为production和dev,且不存在键名为tier的标签的所有Pod对象
# kubectl get pods -l "env in (production,dev),!tier"
Kubernetes的诸多资源对象必须以标签选择器的方式关联到Pod资源对象,例如Service、Deployment和ReplicaSet类型的资源等,他们在spec字段中嵌套使用“selector”字段,通过“matchLabels”来指定标签选择器,有的甚至还支持使用“matchExpressions”构造复杂的标签选择机制。
- matchLabels:通过直接给定键值来对指定标签选择器
- matchExpressions:基于表达式指定的标签选择器列表
2.4 Pod节点选择器nodeSelector
Pod节点选择器是标签及标签选择器的一种应用,它能让Pod对象基于集群中工作节点的标签来挑选倾向运行的目标节点。
Pod对象的spec.nodeSelector可用于定义节点标签选择器,用户事先为特定部分的Node资源对象设定好标签,而后配置Pod对象通过节点标签选择器进行匹配检测,从而完成亲和情调度。
例如:为Node资源对象附加标签的方法和Pod资源相同,使用“kubectl label nodes”命令即可,例如,可为node01.ilinux.io节点设置“disktype=ssd”标签以标识其拥有SSD设备:
# kubectl label nodes node01.ilinux.io disktype=ssd
查看具有键名SSD的标签的Node资源
# kubectl label nodes -l 'disktype'
如果某Pod资源需要调度至这些具有SSD设备的节点之上,只需要为其使用spec.nodeSelector标签选择器即可。如下示例:
apiVersion: v1 kind: Pod metadata: name: pod-with-nodeselector labels: env: testing spec: containers: - name: myapp image: ikubernetes/myapp:vl nodeSelector: disktype: ssd
3 Pod对象的生命周期
Pod对象自从其创建开始至其终止退出的时间范围成为其生命周期。在这段时间中,Pod会处于多种不同的状态,并执行一些操作;其中,创建主容器(main container)为必须的操作,其他可选的操作还包括运行初始化容器(init container)、容器启动后钩子(post start hook)、容器的存活性探测(liveness probe),就绪性探测(readiness probe)以及容器终止前钩子(pre stop hook)等,这些操作是否执行则取决于Pod的定义。

3.1 生命周期钩子函数
Kubernetes为容器提供了两种生命周期钩子:
- postStart:于容器创建完成之后立即运行的钩子处理器,不过Kubernetes无法确保它一定会于容器中的ENTRYPOINT之前运行。
- preStop:于容器终止操作之前立即运行的钩子处理器,它以同步的方式调用,因此在其完成之前会阻塞删除容器的操作调用。
钩子处理器的实现方式有“Exec”和“HTTP”两种,前一种在钩子事件触发时直接在当前容器中运行由用户定义的命令,后一种则是在当前容器中向某URL发起HTTP请求。
postStart和preStop处理器定义在容器的spec.lifecycle嵌套字段中,其使用方法如下面的资源清单所示:
apiVersion: v1 kind: Pod metadata: name: lifecvcle-demo spec: contai ners : - name: lifecycle-demo-container image: ikubernetes/myapp:v1 lifecycle: postStart: exec: command: ["/bin/sh”, ”-c",”echo ‘lifecycle hooks handler’ > /usr/share/nginx/html/test.html”]
3.2 容器探测
kubelet可在活动容器上执行两种类型的检测:存活性检测(livenessProbe)和就绪性检测(readlinessProbe)。
- 存活性检测(livenessProbe):用于判定容器是否处于“运行Running”状态,一旦此类检测未通过,kubelet将杀死容器并根据其resstartPolicy决定是否将其重启;未定义存活性探测的容器的默认状态为“Success”。
- 就绪性检测(readlinessProbe):用于判断容器是否准备就绪并可对外提供服务;未通过检测的容器意味着其尚未准备就绪,端点控制器(如service对象)会将其IP从所有匹配到此Pod对象的Service对象的端点列表中移除;检测通过之后,会再次将其IP添加至端点列表中。
Kubernetes支持如下三种处理器用于容器探测:
- ExecAction:在容器中执行一个命令,并根据其返回的状态码进行判断的操作成为Exec探测,状态码为0标识成功,否则即为不健康状态。
- TCPSocketAction:通过与容器的某TCP端口尝试建立连接进行诊断,端口能够成功打开即为正常,否则为不健康状态。
- HTTPGetAction:通过向容器IP地址的某指定端口的指定path发起HTTP GET请求进行诊断,响应码为2xx或3xx即为成功,否则为失败。
3.2.1 Pod存活性探测
有不少应用程序长时间持续运行后会逐渐转为不可用状态,并且仅能通过重启操作恢复,Kubernetes的容器存活性探测机制可发现诸如此类的问题,并依据探测结果结合重启策略触发后续的行为。
3.2.1.1 设置exec探针
apiVersion: v1 kind: Pod metadata: labels: test: liveness-exec name: liveness-exec spec : containers : - name: liveness-exec demo image: busybox args: ["/bin/sh", "-c", "touch /tmp/healthy; sleep 60; rm -rf /tmp/healthy; sleep 600"] livenessProbe: exec: command: ["test", "-e", "/tmp/healthy"]
3.2.1.2 设置HTTP探测
httpGet探测可用字段包括如下几个:
- host<string>:请求的主机地址,默认为Pod IP;也可以在httpHeaders中使用“Host:”来定义。
- post<string>:请求的端口,必选字段
- httpHeaders<[]Object>:自定义的请求报文首部
- path<string>:请求的HTTP资源路径,即URL path
- scheme:建立连接使用的协议,仅可为HTTP和HTTPS,默认为HTTP
如下示例,它通过lifecycle中的postStart hook创建一个专用于httpGet测试的页面文件healthz:
apiVersion: v1 kind: Pod metadata: labels: test: liveness name: liveness-http spec : containers: - name: liveness-http-demo image: nginx:1.12-alpine ports : - name: http containerPort: 80 lifecycle: postStart: exec: command: [”/bin/sh”,”-c”,”echo Healthy > /usr/share/nginx/html/healthz”] livenessProbe: httpGet: path: /healthz port: http scheme: HTTP
3.2.1.3 设置TCP探针
tcpSocket包含如下两个属性:
- host<string>:请求连接的目标IP地址,默认为PodIP
- port<string>:请求连接的目标端口,必须字段
如下示例,向Pod IP的80/tcp端口发起连接请求,并根据连接建立的状态判断测试结果:
apiVersion: v1 kind: Pod metadata: labels: test: liveness name: liveness-tcp spec: containers: - name: liveness-tcp-demo image: nginx:l.12-alpine ports: - name: http containerPort: 80 livenessProbe : tcpSocket: port: http
3.2.1.4 存活性探测行为属性
- initialDelaySeconds<integer>:存储性探测延迟时长,即容器启动多久之后再开始第一次探测操作,显示为delay属性,默认为0秒,即容器启动后就立刻开始进行探测
- timeoutSeconds<integer>:存活性探测的超时时长,显示为timeout属性,默认为1s,最小值也为1s
- periodSeconds<integer>:存活性探测的频度,显示为period属性,默认为10s,最小值为1s,过高的频率会对Pod对象带来较大的额外开销,而过低的频率又会对错误的反应不及时
- successThreshold<integer>:处于失败状态时,探测操作至少连续多少次的成功才被认为是通过探测,显示为#success属性,默认值为1,最小值也为1.
- failureThreshold:处于成功状态时,探测操作至少连续多少次失败才被视为是检测不通过,显示为#failure属性,默认值为3,最小值为1
spec: containers: ...... livenessProbe: exec : command: [”test’\”-e”,”/tmp/healthy”] initialDelaySeconds: 5 timeoutSeconds: 2 periodSeconds: 5
3.2.2 Pod就绪性探测
与存活性探测机制相同,就绪性探测也支持Exec、HTTP GET和TCP Socket三种探测方式,且各自的定义机制也都相同。但与存活性探测触发的操作不同的是,探测失败时,就绪性探测不会杀死或重启容器以保证其健康性,而是通知其尚未就绪,并触发依赖于其就绪性的操作(例如,从Service对象中移除此Pod对象)已确保不会有客户端请求接入此Pod对象。
例如:如下示例,它会在Pod对象创建完成5秒钟后使用test -e/tmp/ready命令来探测容器的就绪性,命令执行成功即为就绪,探测周期为5秒钟:
apiVersion: v1 kind: Pod metadata: labels: test: readiness exec name: read工ness-exec spec: containers : - name: readiness-demo image: busybox args: [ “/bin/sh”,”-c”,”while true; do rm -f /tmp/ready; sleep 30; touch /tmp/ready; sleep 300; done”] readinessProbe: exec: command: ["test”, ”-e”,“/tmp/ready”] initialDelaySeconds: 5 periodSeconds: 5
3.3 容器的重启策略
容器程序发生崩溃或容器申请超出限制的资源等原因都可能会导致Pod对象的终止,此时是否应该重建该Pod对象则取决于其重启策略(restartPolicy)属性的定义。
- Always:但凡Pod对象终止就将其重启,此为默认设定
- OnFailure:仅在Pod对象出现错误时方才将其重启。
- Never:从不重启
4 资源需求及资源限制
4.1 资源限制
例如,运行一个Pod对象,它模拟内存泄漏操作不断地申请使用内存资源,直到超出limits属性中memory字段设定的值而导致“OOMKilled”为止
apiVersion: v1 kind: Pod metadata: name: memleak-pod labels: app: memleak spec : containers : - name: simmemleak image: saadali/simmemleak resources : requests: memory: “64Mi” cpu: “1” limits: memory: “64Mi” cpu: “1”
在Kubernetes系统上,1个单位的CPU相当于虚拟机上的1颗虚拟CPU或物理机上的一个超线程,它支持分数计量方式,一个核心(1 core)相当于1000个微核心,因此500m相当于是0.5个核心,即二分之一个核心。内存的计量方式与日常使用方式相同,默认单位是字节,也可以使用E、P、T、G、M和K作为单位后缀,或Ei、Pi、Ti、Gi、Mi和Ki形式的单位后缀。

浙公网安备 33010602011771号