【kubernetes】关于云原生之k8s集群中pod的容器资源限制和三种探针

目录

一、关于pod容器的资源限制

1.1资源限制的单位

[CPU 资源单位](#CPU 资源单位)

[内存 资源单位](#内存 资源单位)

二、关于QOS服务质量(pod的调度和驱逐有限制)

2.1QoS服务质量分类

guaranteed验证

burstable验证

besteffort验证

2.2驱逐顺序

三、关于pod容器的三种探针

3.1健康检查:又称为探针(Probe)

3.2三种健康检查的方式

3.3实操验证

实操一:通过存活探针验证三大健康检查的方式

存活探针------exec健康检查方式

存活探针------tcpsocket健康检查方式

[​编辑 存活探针之httpget健康检查方式](#编辑 存活探针之httpget健康检查方式)

[实操二:验证启动探针、 就绪探针、存活探针的顺序](#实操二:验证启动探针、 就绪探针、存活探针的顺序)

实操三:验证就绪探针

[​编辑 实操四、验证启动和退出动作](#编辑 实操四、验证启动和退出动作)

四、总结:

三种探针

关于探针的3种探测方式

探针参数:


一、关于pod容器的资源限制

当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小,以及其他类型的资源。

当为 Pod 中的容器指定了 request 资源限制时,代表容器运行所需的最小资源量,调度器就使用该信息来决定将 Pod 调度到哪个节点上(也就是预选策略是根据requests设置的资源进行淘汰不符合要求的node节点)。当还为容器指定了 limit 资源时,kubelet 就会确保运行的容器不会使用超出所设的 limit 资源量。kubelet 还会为容器预留所设的 request 资源量, 供该容器使用。

如果 Pod 运行所在的节点具有足够的可用资源:容器可以使用超出所设置的 request 资源量,容器不可以使用超出所设置的 limit 资源量。

如果给容器设置了内存的 limit 值,但未设置内存的 request 值,Kubernetes 会自动为其设置与内存 limit 相匹配的 request 值。 类似的,如果给容器设置了 CPU 的 limit 值但未设置 CPU 的 request 值,则 Kubernetes 自动为其设置 CPU 的 request 值 并使之与 CPU 的 limit 值匹配。

++总结:requests表示创建pod时预留的资源,limits表示pod能够使用资源的最大值。requests值可以被超,limits值不能超过,如果是内存使用超过limits会触发oom然后杀掉进程,如果是cpu超过limits会压缩cpu的使用率。++

官网示例:https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
Pod 和 容器 的资源请求和限制

复制代码
spec.containers[].resources.requests.cpu		//定义创建容器时预分配的CPU资源
spec.containers[].resources.requests.memory		//定义创建容器时预分配的内存资源
spec.containers[].resources.limits.cpu			//定义 cpu 的资源上限 
spec.containers[].resources.limits.memory		//定义内存的资源上限

spec.containers[].resources.limits.hugepages-<size> 
spec.containers[].resources.requests.hugepages-<size>

1.1资源限制的单位

CPU 资源单位

CPU 资源的 request 和 limit 以 cpu 为单位。Kubernetes 中的一个 cpu 相当于1个 vCPU(1个超线程)。

Kubernetes 也支持带小数 CPU 的请求。spec.containers[].resources.requests.cpu 为 0.5 的容器能够获得一个 cpu 的一半 CPU 资源(类似于Cgroup对CPU资源的时间分片)。表达式 0.1 等价于表达式 100m(毫核),表示每 1000 毫秒内容器可以使用的 CPU 时间总量为 0.1*1000 毫秒。

Kubernetes 不允许设置精度小于 1m 的 CPU 资源。

内存 资源单位

内存的 request 和 limit 以字节为单位。可以以整数表示,或者以10为底数的指数的单位(E、P、T、G、M、K)来表示, 或者以2为底数的指数的单位(Ei、Pi、Ti、Gi、Mi、Ki)来表示。

如:1KB=10^3=1000,1MB=10^6=1000000=1000KB,1GB=10^9=1000000000=1000MB

1KiB=2^10=1024,1MiB=2^20=1048576=1024KiB

PS:在买硬盘的时候,操作系统报的数量要比产品标出或商家号称的小一些,主要原因是标出的是以 MB、GB为单位的,1GB 就是1,000,000,000Byte,而操作系统是以2进制为处理单位的,因此检查硬盘容量时是以MiB、GiB为单位,1GiB=2^30=1,073,741,824,相比较而言,1GiB要比1GB多出1,073,741,824-1,000,000,000=73,741,824Byte,所以检测实际结果要比标出的少一些。

总结:

cpu的单位可以是核个数如1.25,0.5等,可以是毫核如500m,1250m

memory的单位可以是128M或128Mi (分别是1000k=1M或1024Ki=1Mi)

二、关于QOS服务质量(pod的调度和驱逐有限制)

2.1QoS服务质量分类

  • Guaranteed:Pod 中的每个容器,包含初始化容器,必须指定内存、CPU 的 requests 和 limits,并且 requests 和 limits 要相等
  • Burstable:Pod 中至少一个容器具有内存 或 CPU requests
  • BestEffort:Pod 中的所有容器都没有指定内存 或 CPU 的 requests和 limits

guaranteed验证

只有一个容器,而且容器的req与limit设置值一致

只有1个容 器,而且只设置容器的limit设置值

有2个容**** 器,而且容器的req与limit设置值一致

burstable验证

只有1个容 器,而且只设置容器的requests设置值

besteffort验证

2.2驱逐顺序

++优先级:Guaranteed > Burstable > BestEffort++

  • Guaranteed (QoS) 的 Pod,其优先级最高,在其资源使用量不超过其 limits 的情况下,可以确保不被杀死
  • 在系统内存资源紧张,且集群中没有 QoS 为 Best-Effort 级别的其它 Pod 时,一旦 Burstable (QoS) 的Pod 使用的资源量超过了其 requests,这些 Pod 就容易被杀死
  • BestEffort (QoS) 的 Pod,其优先级最低,当系统内存资源紧张时,这些 Pod 底层容器中的进程是最先会被杀死的

验证内存超过limit限制 会触发oomkil杀掉容器

复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    myapp: nginx
  name: pod-demo7
spec:
  containers:
  - image: nginx:1.20
    imagePullPolicy: IfNotPresent
    name: pod-c1
    env:
    - name: WEB_ROOT_PASSWORD
      value: "password"
    ports:
    - containerPort: 80
    resources:
      requests:
        cpu: "0.5"
        memory: "128Mi"
      limits:
        cpu: "0.5"
        memory: "128Mi"
  - image: mysql
    imagePullPolicy: IfNotPresent
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "123123"
    name: mydb
    resources:
      requests:
        cpu: "0.5"
        memory: "128Mi"
      limits:
        cpu: "0.5"
        memory: "128Mi"
  restartPolicy: Always
复制代码
kubectl describe -n <命名空间> pods <资源名称>       
//查看Pod中的每个容器的资源限制的配置


kubectl describe node <node节点名称>                 
//查看node节点的资源总量、每个Pod的资源限制和节点的资源限制总量及比例

三、关于pod容器的三种探针

3.1健康检查:又称为探针(Probe)

探针是由kubelet对容器执行的定期诊断。

探针的三种规则:
●livenessProbe :判断容器是否正在运行。如果探测失败,则kubelet会杀死容器,并且容器将根据 restartPolicy 来设置 Pod 状态。 如果容器不提供存活探针,则默认状态为Success。

●readinessProbe :判断容器是否准备好接受请求。如果探测失败,端点控制器将从与 Pod 匹配的所有 service endpoints 中剔除删除该Pod的IP地址。 初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为Success。

●startupProbe(这个1.17版本增加的):判断容器内的应用程序是否已启动,主要针对于不能确定具体启动时间的应用。如果配置了 startupProbe 探测,则在 startupProbe 状态为 Success 之前,其他所有探针都处于无效状态,直到它成功后其他探针才起作用。 如果 startupProbe 失败,kubelet 将杀死容器,容器将根据 restartPolicy 来重启。如果容器没有配置 startupProbe, 则默认状态为 Success。
#注:以上规则可以同时定义。在readinessProbe检测成功之前,Pod的running状态是不会变成ready状态的。

3.2三种健康检查的方式

●exec :在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功。

●tcpSocket :对指定端口上的容器的IP地址进行TCP检查(三次握手)。如果端口打开,则诊断被认为是成功的。

●httpGet :对指定的端口和uri路径上的容器的IP地址执行HTTPGet请求。如果响应的状态码大于等于200且小于400,则诊断被认为是成功的

每次探测都将获得以下三种结果之一:
●成功(Success):表示容器通过了检测。
●失败(Failure):表示容器未通过检测。
●未知(Unknown):表示检测没有正常进行。

3.3实操验证

实操一:通过存活探针验证三大健康检查的方式

存活探针------exec健康检查方式

复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: demo1
  name: demo1
spec:
  containers:
  - name: nginx
    image: soscscs/myapp:v1
#args的作用相当于docker-compose文件中的CMD字段,可以设置容器启动命令
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 10
#设置存活探针,探测pod容器的运行状态,一旦探测失败,那么就会通过kubelet杀掉容器
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      failureThreshold: 2      #表示连续探测失败2次才为探测失败
      initialDelaySeconds: 2   #表示初始等待2秒后再才是启动存活探针
      periodSeconds: 2         #表示探测周期为2秒

存活探针------tcpsocket健康检查方式

复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: demo1
  name: demo1
spec:
  containers:
  - name: nginx
    image: soscscs/myapp:v1
    ports:
    - containerPort: 80
      name: http
#设置存活探针,探测pod容器的运行状态,一旦探测失败,那么就会通过kubelet杀掉容器
    livenessProbe:
      tcpSocket:
        port: http             #表示探测端口为pod的80端口  这里引用暴露端口的名称来代替80端口 
      failureThreshold: 2      #表示连续探测失败2次才为探测失败
      initialDelaySeconds: 2   #表示初始等待2秒后再才是启动存活探针
      periodSeconds: 2         #表示探测周期为2秒

错误验证

复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: demo1
  name: demo1
spec:
  containers:
  - name: nginx
    image: soscscs/myapp:v1
    ports:
    - containerPort: 80
      name: http
#设置存活探针,探测pod容器的运行状态,一旦探测失败,那么就会通过kubelet杀掉容器
    livenessProbe:
      tcpSocket:
        port: 8080             #该8080端口并未开放,模拟检查失败查看
      failureThreshold: 2      #表示连续探测失败2次才为探测失败
      initialDelaySeconds: 2   #表示初始等待2秒后再才是启动存活探针

存活探针之httpget健康检查方式

复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: demo1
  name: demo1
spec:
  containers:
  - name: nginx
    image: soscscs/myapp:v1
    ports:
    - containerPort: 80
      name: http
#设置存活探针,探测pod容器的运行状态,一旦探测失败,那么就会通过kubelet杀掉容器
    livenessProbe:
      httpGet:  #采用httpGet的方式 会像podip的指定端口发送http GET请求
        port: http
        path: /index.html      #做http健康检查的页面
      failureThreshold: 2      #表示连续探测失败2次才为探测失败
      initialDelaySeconds: 2   #表示初始等待2秒后再才是启动存活探针
      periodSeconds: 2         #表示探测周期为2秒

实操二:验证启动探针、 就绪探针、存活探针的顺序

复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: demo1
  name: demo1
spec:
  containers:
  - name: nginx
    image: soscscs/myapp:v1
    ports:
    - containerPort: 80
      name: http
#设置存活探针,探测pod容器的运行状态,一旦探测失败,那么就会通过kubelet杀掉容器
    livenessProbe:
      httpGet:  #采用httpGet的方式 会像podip的指定端口发送http GET请求
        port: http
        path: /index.html      #做http健康检查的页面
      failureThreshold: 2      #表示连续探测失败2次才为探测失败
      initialDelaySeconds: 2   #表示初始等待2秒后再才是启动存活探针
      periodSeconds: 8         #表示探测周期为8秒
#设置就绪探针,探测pod是否处于就绪状态,如果说探测失败则为未就绪状态,service会将其从关联的pod中删除,请求也不转发给该pod
    readinessProbe:
      httpGet:  #采用httpGet的方式 会像podip的指定端口发送http GET请求
        port: http
        path: /index.html      #做http健康检查的页面
      failureThreshold: 2      #表示连续探测失败2次才为探测失败
      initialDelaySeconds: 2   #表示初始等待2秒后再才是启动存活探针
      periodSeconds: 10        #表示探测周期为10秒
#启动探针,为了探测容器应用是否处于运行状态,只有启动探针探测成功以后,就绪探针和存活探针才有效
    startupProbe:
      httpGet:  #采用httpGet的方式 会像podip的指定端口发送http GET请求
        port: http
        path: /index1.html      #做http健康检查的页面
      failureThreshold: 3      #表示连续探测失败3次才为探测失败
      initialDelaySeconds: 2   #表示初始等待2秒后再才是启动存活探针
      periodSeconds: 15        #表示探测周期为15秒

可验证 就绪探针与存活探针 是在启动探针探测成功以后才会生效

实操三:验证就绪探针

复制代码
vim readiness-myapp.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp1
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10 
---
apiVersion: v1
kind: Pod
metadata:
  name: myapp2
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10 
---
apiVersion: v1
kind: Pod
metadata:
  name: myapp3
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10 
---
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  selector:
    app: myapp
  type: ClusterIP
  ports:
  - name: http
    port: 80
    targetPort: 80

现在恢复index页面

实操四、验证启动和退出动作

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: soscscs/myapp:v1
    lifecycle:   #此为关键字段
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the postStart handler >> /var/log/nginx/message"]      
      preStop:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the poststop handler >> /var/log/nginx/message"]
    volumeMounts:
    - name: message-log
      mountPath: /var/log/nginx/
      readOnly: false
  initContainers:
  - name: init-myservice
    image: soscscs/myapp:v1
    command: ["/bin/sh", "-c", "echo 'Hello initContainers'   >> /var/log/nginx/message"]
    volumeMounts:
    - name: message-log
      mountPath: /var/log/nginx/
      readOnly: false
  volumes:
  - name: message-log
    hostPath:
      path: /data/volumes/nginx/log/
      type: DirectoryOrCreate

Pod容器的启动动作和退出动作:lifecycle.postStart|preStop(lifecycle与image字段同一层级)
lifecycle.postStart 设置Pod容器启动时额外执行的操作,此操作不会作为容器pid=1的主进程
lifecycle.preStop 设置Pod容器被kubelet杀掉退出时执行的操作

kubelet杀掉有两种:要么kubelet delete 杀掉或者探针 探测失败

四、总结:

三种探针

  • 存活探针(livenessProbe):探测Pod容器是否在正常运行。如果探测失败则kubelet杀掉容器,并根据容器重启策略决定是否重启容器
  • 就绪探针(readinessProbe):探测Pod是否进入就绪状态(ready状态栏是否100%比例),并做好接收service转发来的请求准备。

如果探测失败则Pod变成未就绪状态(0/1 1/2),service就会删除相关联的Pod端点,并不再转发请求给处于未就绪状态的Pod

  • 启动探针(startupProbe):探测Pod容器内的应用进程是否启动成功。在启动探针探测成功之前,存活探针和就绪探针都会处于暂停状态,直到启动探针探测成功为止

如果探测失败则kubelet杀掉容器,并根据容器重启策略决定是否重启容器

关于探针的3种探测方式

  • exec:在容器里执行linux命令,如果命令返回码为0则认为探测成功,如果命令返回码为非0值则认为探测失败
  • httpGet:向PodIP和指定的端口及URL路径发送HTTP GET请求,如果HTTP响应状态码为2XX 3XX则认为探测成功,如果HTTP响应状态码为4XX 5XX则认为探测失败
  • tcpSocket:向PodIP和指定的端口发送TCP连接请求(三次握手),如果端口正确且TCP连接成功则认为探测成功,如果TCP连接失败则认为探测失败

探针参数:

  • initialDelaySeconds:指定容器启动后延迟探测的时间(单位为秒)
  • periodSeconds:指定每次探测的间隔时间
  • failureThreshold:指定判定探测失败的连续失败次数
  • timeoutSeconds:指定探测超时等待的时间

Pod容器的启动动作和退出动作:lifecycle.postStart|preStop(lifecycle与image字段同一层级)
lifecycle.postStart 设置Pod容器启动时额外执行的操作,此操作不会作为容器pid=1的主进程
lifecycle.preStop 设置Pod容器被kubelet杀掉退出时执行的操作

相关推荐
一方热衷.5 小时前
YOLO26-Seg ONNXruntime C++/python推理
开发语言·c++·python
靓仔建6 小时前
Vue3导入组件出错does not provide an export named ‘user_setting‘ (at index.vue:180:10)
开发语言·前端·typescript
HalvmånEver6 小时前
7.高并发内存池大页内存申请释放以及使用定长内存池脱离new
java·spring boot·spring
凤山老林6 小时前
SpringBoot 使用 H2 文本数据库构建轻量级应用
java·数据库·spring boot·后端
小夏卷编程6 小时前
Ubuntu 20.04.4 宝塔 docker showdoc v3.2 更新到v3.7.3
运维·docker·容器
JEECG低代码平台7 小时前
JeecgBoot低代码平台 Docker 部署 OnlyOffice 文档服务完整指南
低代码·docker·容器
赶路人儿7 小时前
UTC时间和时间戳介绍
java·开发语言
dreamread7 小时前
【SpringBoot整合系列】SpringBoot3.x整合Swagger
java·spring boot·后端
6+h7 小时前
【java】基本数据类型与包装类:拆箱装箱机制
java·开发语言·python
一直都在5727 小时前
Spring面经
java·后端·spring