kubernetes(六)Pod健康检查和资源配置

一    Pod生命周期(接上)

整个拓扑结构

pod loap

(1)Docker容器中应用的运行要求

Kubernetes对'长时间运行'容器的要求: 主程序需要在'前台'一直执行 -->'pid=1的前台常驻进程'

前台是方便docker'进行管理'

***************  '错误的方式'  ***************

nohup start.sh &

原因: kubelet在创建'包含这个容器的Pod之后'运行完'该命令',即认为'Pod执行结束',将立即'销毁'该Pod

场景: Pod是以'Deployment方式'创建的,而'command启动'不是常驻进程,而pod的重启策略是'Alaways',就会陷入pod'无限循环'过程

***************  '正确的方式'  ***************

nginx前台: nginx -g 'daemon off'

http前台:  httpd -D FOREGROUND

(2)Pod Hook

重点小结

1)Pod Hook是由'kubelet发起的'

2)'重点掌握preStop',postStart用的不多,知道'提供这样一个能力'即可

postSTart场景:nginx'优雅退出'、'core dump'日志保存

3)Hook是'容器级别'的,一般用在'主容器'中

容器两种类型钩子函数 

钩子函数的常见两种实现方式

exec --> shell命令格式,容器'存在该命令'

HTTP --> 一般容器是'WebServer服务'

①    postStart

模拟: 配置'文件初始化','简化卷的挂载'

需求: 定义了一个' Nginx Pod',其中设置了 PostStart 钩子函数,即在'容器创建成功后','写入一句话'到 /usr/share/message 文件中

容器'启动之前'确实'做了'这么一件事

command --> 等价于 Dockerfile中的'ENTRYPOINT'

args    --> 等价于 CMD-->'如果没有ENTRYPOINT,默认'

官方文档

②    preStop

k8s默认删除容器和优雅退出的区别

场景: pod由于某些原因'无法删除',就'强制删除'

思考: 这种方式pod信息在etcd中'有残留',如何回收? --> '这个是重点'

当node中'pod数量'达到一定限额度,会把这些'垃圾pod信息回收掉'

1)nginx还有'很多连接正在处理',应该让nginx'优雅退出',让'nginx执行完'再退出

2)容器退出前'保存容器的状态'

上面定义的两个 Pod,一个是利用 preStop 来进行'优雅删除',另外一个是利用 preStop 来做一些'信息记录'的事情
apiVersion: v1
kind: Pod
metadata:
  name: hook-demo2
spec:
  containers:
  - name: hook-demo2
    image: nginx
    lifecycle:
      preStop:
        exec:
          command: ["/usr/sbin/nginx","-s","quit"]  'nginx优雅退出'

--- '容器退出前做状态保存持久化'

apiVersion: v1
kind: Pod
metadata:
  name: hook-demo3
spec:
  volumes:
  - name: message
    hostPath:
      path: /tmp
  containers:
  - name: hook-demo2
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: message
      mountPath: /usr/share/
    lifecycle:
      preStop:
        exec:
          command: ['/bin/sh', '-c', 'echo Hello from the preStop Handler > /usr/share/message']
备注: Hook 调用的日志'没有暴露'给 Pod,所以只能'通过 describe 命令'来获取,如果'有错误'将可以看到 'FailedPostStartHook' 或 'FailedPreStopHook' 这样的 event事件
后续补充这个:删除pod'是异步的',service下面的endpoint'还没有完全摘除',还会'接受流量',但是pod已经退出,所以'有一部分请求'会异常,会给preStop设计'sleep 10'再退出

二    Pod的健康检查

(1)为什么需要存活探针

如果没有探针,k8s无法知道'应用是否还活着',只要进程还在运行'例如:僵尸进程',k8s则认为'容器是健康的'

理解: '存活探针'更多的是从'业务应用侧'来考虑的,算是'服务可用性'的一个环节
readiness probe'可读性探针' '重要性 > ' liveness probe '存活探针'

排查问题: 可以去掉'liveness probe'进行排查

说明: libeness probe对于我们'排查问题不是特别友好',因为一旦'检测异常',就会'重启','不保留现场信息' -->'附加preSTop-->重启保留现场'

(2)存活探针的工作机理 

1)用'指定三种方式的一种'进入容器检测'容器中的应用'是否正常运行

2)如果'检测失败',则认为容器不健康,那么 kubelet 将根据 Pod 中设置的 'restartPolicy 重启策略'来判断,Pod '是否'要进行重启操作

3)如果容器配置中'没有配置 livenessProbe 存活探针',kubelet 将认为'存活探针'探测一直为'成功状态'

①    支持的配置方式

关注下面'参数'的'默认数值'

这种最常见,以运行中的容器'服务-->指的是应用'是否可用作为'容器存活的标准' --> '业界常用'

②  exec

用 exec 执行命令的方式来'检测容器的存活'  -->  主要是观察'容器是否重启'

httpGet:任何'200<= x <400'的状态码都会认定是'成功的'返回码,其他返回码都会被认为是'失败的返回码'
apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

descrble查看'Events'信息

kubectl 'describe' pods liveness-exec --> '核心信息的解读'

以下存活探针表示:容器启动后'delay=5s'再进行探测,如果1s'timeout=1s'内容器'没有给出回应'则记作探测失败,如果连续回应1次'success=1'则认为健康,后续每次'间隔5s(period=5s)'进行一次探测,在探测'连续失败3次(failure=3)'后重启容器

连续三次失败: 防止'误判'

思考:超时设置多少是'合理的'

③  initialDelaySeconds问题和startupProbe引入意义

官网文档

不错的解读

1)initialDelaySeconds'没有设置的现象'

'initialDelaySeconds'如果'没有设置',探针将在'启动时立即探测',通常会'导致探测失败',因为程序'还没准备好'开始接收请求

这种情况'很常见',看到容器在重启,使用'describe'会看到'容器退出码为137或者143'

备注: 'liverness 探针' 从'业务的角度'就是在容器运行一端时间类似'OOM'导致容器'重启'应用场景

2)initialDelaySeconds'设置不合理'

+++++++++++++++ '分割线'

引出 startupProbe探针,注意是'v1.16 版本引入alpha'的

startupProbe探针用法和'其它探针'用法一致

​kubectl explain pods.spec.containers.startupProbe --> '了解程序到底需要多长时间'

startupProbe:
  httpGet:
    path: /healthz
    port: 8080
  failureThreshold: 30  尽量'设置大点'-->检测30次失败'才认为失败'
  periodSeconds: 10

----------------------

解释:表示我们的'慢速容器最多'可以有'5分钟'(30个检查 * 10秒= 300s)来完成启动,才会执行'liverness和readiness',避免'频繁的重启'

后续:k8s1.18内置Sidecar控制pod中容器的启动顺序

控制pod内container执行顺序的几种姿势

(3)为什么需要就续探针

'场景引入'

问题1:在 Kubernetes 中启动 Pod,'显示明明 Pod 已经启动成功',且能访问里面的端口,但是却'返回错误信息',典型的应用'jenkins和gitlab'

问题2:还有就是在'执行滚动更新'时候,总会出现一段时间,Pod虽然'对外提供网络访问',但是'访问却发生 404',用用户体验'极差'

原因:都是因为 'Pod 已经成功启动',但是 Pod 的的容器中'应用程序还在启动中'导致

(4)就续探针的工作机理

休息片刻:kube-node-lease 'kubernetes集群节点租约状态'  'v1.13加入'

​
查看命名空间的' 所有资源 '

kubectl get all --namespace=wzj  

'​删除对应的ns',就会'删除所有的pod'

三    资源配置

(1)概念

1)注意'换算单位'

2)spec.containers[].resources.requests.cpu'影响pod的调度'

3)目前先从'容器声明周期'角度粗略的了解 -->'limit导致OOM,restartPolicy进行' -->后续'细讲'

4)资源配额是'针对容器',pod在物理上是不存在,是'逻辑'的概念,所以我们'真正限制'的是'容器的资源'

'limit = request' --> '优先级最高'

(2)应用

官网文档 

 Kubernetes v'1.14 或更高'版本,则可以指定大页'Huge Page'资源,大页是 'Linux 特有'的功能,节点内核在其中'分配的内存块'比默认页大小大得多

注意: CPU 资源是'可压缩资源',也就是容器'达到了这个设定的上限后',容器'性能会下降',但是'不会终止或退出'
apiVersion: v1
kind: Pod
metadata:
  name: resource
spec:
  containers:
  - name: resource
    image: nginx
    ports:
    - containerPort: 80
    resources:
      requests:
        memory: 50Mi
        cpu: 50m
      limits:
        memory: 100Mi
        cpu: 100m
操作系统查看容器'内存和cpu限制'

备注: 'memory'查看同'cpu'

 

(3)memory的换算

排错

 补充:    pod创建的过程

1)用户使用'create <--> apply' yaml创建pod,请求给apiseerver,apiserver将yaml中的属性信息(metadata)'写入etcd'

2)apiserver'触发watch机制'准备创建pod,信息转发给'调度器',调度器使用'调度算法'选择node,调度器将node信息给apiserver',apiserver将'绑定的node信息'写入etcd

3) apiserver又通过watch机制,Node'调用kubelet'指定pod信息,触发'docker run命令'创建容器创建完成之后'反馈给'kubelet,kubelet又将pod的'状态信息'给apiserver,apiserver又将'pod的状态'信息'写入etcd

图中有'三次write'

(1) pod'元信息'

(2) pod分配到'哪个node'

(3) 记录'pod状态'

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值