【Kubernetes】Pod 容器资源限制和三种探针

2024-06-02 16:44

本文主要是介绍【Kubernetes】Pod 容器资源限制和三种探针,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、pod 容器的资源限制

资源爆满导致node节点宕机,又因为deployment 控制器会将宕掉的服务转移到其他node节点的特性,从而导致集群中所有节点宕机,可以做资源限制来预防

资源限制

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

当为 Pod 中的容器指定了 request 资源时,调度器就使用该信息来决定将 Pod 调度到哪个节点上。当还为容器指定了 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 的使用率

官网示例如下:

Resource Management for Pods and Containers | Kubernetes

Pod 和 容器的资源请求和限制

spec.containers[].resources.requests.cpu                #定义创建容器时预分配的CPU资源
spec.containers[].resources.requests.memory         #定义创建容器时预分配的内存资源

#创建pod容器时需要预留你的资源量;

#示例:核数:0.5 或 500m核;内存:MI、GI (2为底的)、MG (10为底的)

spec.containers[].resources.limits.cpu                      #定义 cpu 的资源上限 
spec.containers[].resources.limits.memory               #定义内存的资源上限
#pod容器能够使用资源量的一个上限

#示例:4Gi内存上限(表示不允许超过上限值)
 
spec.containers[].resources.limits.hugepages-<size>
spec.containers[].resources.requests.hugepages-<size>

Kubernetes 中的资源单位

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 毫秒。
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,所以检测实际结果要比标出的少一些。

容器资源示例

官方文档

https://kubernetes.io/zh-cn/docs/concepts/configuration/manage-resources-containers/

以下 Pod 有两个容器,每个容器的请求为 0.25 cpu 和 64MiB 内存,每个容器的 limit 值为 0.5 cpu 和 128MiB 内存。那么可以认为该 Pod 的总的资源 request 为 0.5 cpu 和 128 MiB 内存,总的资源 limit 为 1 cpu 和 256MiB 内存。

apiVersion: v1
kind: Pod
metadata:name: frontend
spec:containers:- name: appimage: images.my-company.example/app:v4env:- name: MYSQL_ROOT_PASSWORDvalue: "password"resources:requests:memory: "64Mi"cpu: "250m" limits:memory: "128Mi"cpu: "500m"- name: log-aggregatorimage: images.my-company.example/log-aggregator:v6resources:requests:memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"

部署容器资源限制

mkdir /opt/pod/
cd /opt/pod/
vim /opt/pod/pod1.yaml
apiVersion: v1
kind: Pod
metadata:name: monor-nginx-mysql
spec:containers:- name: nginximage: nginxenv:- name: NGINX_ROOT_PASSWORDvalue: "password"resources:requests:memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"- name: mysqlimage: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalue: "abc123"resources:requests:memory: "64Mi"cpu: "0.25"limits:memory: "128Mi"cpu: "500m"
#创建资源
kubectl apply -f /opt/pod/pod1.yaml#查看pod
kubectl get pod#状态显示为 OOMKilled ,表示资源不足;

可以看到状态是OOMKilled,表示资源不足、需要修改资源大小

OOMKilled:资源不足被杀死

查看 monor-nginx-mysql 日志

#查看pod的日志; -c 指定目录查看
kubectl logs monor-nginx-mysql -c nginx
kubectl logs monor-nginx-mysql -c mysql
#发现是 mysql 资源不足

修改yaml 文件中 mysql 的配置

#删除pod
kubectl delete -f /opt/pod/pod1.yaml#修改yaml文件
vim /opt/pod/pod1.yaml...- name: mysqlimage: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalue: "abc123"#修改资源限制resources:requests:memory: "128Mi"cpu: "0.5"limits:memory: "1Gi"cpu: "1"
#创建资源
kubectl apply -f /opt/pod/pod1.yaml#查看pod 状态
kubectl get pod
#状态为Running ,创建成功

查看pod 的详细描述

#查看pod 的详细描述
kubectl describe pod monor-nginx-mysql#查看pod 所在node节点
kubectl get pod -o wide#查看该节点上monor-nginx-mysql的资源占用
kubectl describe nodes node01#由于当前虚拟机有2个CPU,所以Pod的CPU Limits一共占用了50%
Namespace                  Name                           CPU Requests  CPU Limits  Memory Requests  Memory Limits  AGE---------                  ----                           ------------  ----------  ---------------  -------------  ---default                    frontend                       500m (25%)    1 (50%)     128Mi (3%)       256Mi (6%)     16mkube-system                kube-flannel-ds-amd64-f4pbp    100m (5%)     100m (5%)   50Mi (1%)        50Mi (1%)      19hkube-system                kube-proxy-pj4wp               0 (0%)        0 (0%)      0 (0%)           0 (0%)         19h
Allocated resources:(Total limits may be over 100 percent, i.e., overcommitted.)Resource           Requests    Limits--------           --------    ------cpu                600m (30%)  1100m (55%)memory             178Mi (4%)  306Mi (7%)ephemeral-storage  0 (0%)      0 (0%)

#由于当前虚拟机有2个CPU,所以Pod的CPU Limits一共占用了50%

二、健康检查:又称为探针(Probe)★★★

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

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

探针会定期查看容器状态;一旦发现容器异常就会干掉它,然后重启

如果不想重启,设置重启策略为never

如果想要业务稳定,用always

0/2 表示pod 为故障,表示没有准备好,提供访问

2/1 pod 为故障重启

探针的三种规则

当pod 为notready是,该pod 会被endpoint踢出,不会被访问到

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状态的。

Probe 支持三种检查方法

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

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

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

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

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

官网示例:

https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

三、验证存货探针三大健康检查的方式

exec 健康检查方式

 示例1:exec方式

apiVersion: v1
kind: Pod
metadata:labels:test: livenessname: liveness-exec
spec:containers:- name: livenessimage: k8s.gcr.io/busyboxargs:  - /bin/sh- -c- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60livenessProbe:exec:command:- cat- /tmp/healthyfailureThreshold: 1 initialDelaySeconds: 5periodSeconds: 5

#initialDelaySeconds:指定 kubelet 在执行第一次探测前应该等待5秒,即第一次探测是在容器启动后的第6秒才开始执行;默认是 0 秒,最小值是 0

#periodSeconds:指定 kubelet 应该每 5 秒执行一次存活探测;默认是 10 秒,最小值是 1

#failureThreshold: 当探测失败时,Kubernetes 将放弃之前重试的次数;

存活探测情况下的放弃就意味着重新启动容器;

就绪探测情况下的放弃 Pod 会被打上未就绪的标签;默认值是 3。最小值是 1。

#timeoutSeconds:探测的超时后等待多少秒;默认值是 1 秒,最小值是 1。

(在 Kubernetes 1.20 版本之前,exec 探针会忽略 timeoutSeconds 探针会无限期地 持续运行,甚至可能超过所配置的限期,直到返回结果为止。)

在这个配置文件中可以看到, Pod 中只有一个容器。

kubelet 在执行第一次探测前需要等待 5 秒,kubelet 会每 5 秒执行一次存活探测。

kubelet 在容器内执行命令 cat /tmp/healthy 来进行探测。

如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的。

当到达第 31 秒时,这个命令返回非 0 值,kubelet 会杀死这个容器并重新启动它。

实践:exec方式

mkdir /opt/probe
cd /opt/probevim /opt/probe/exec.yaml
apiVersion: v1
kind: Pod
metadata:labels:test: livenessname: liveness-exec
spec:containers:- name: livenessimage: busyboximagePullPolicy: IfNotPresent#设置容器启动命令;作用相当于docker-compose 文件中的CMD字段args:- /bin/sh- -c#设置存活探针,探测 pod 容器的运行状态,一旦探测失败,就会通过kubelet杀掉容器- touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 15livenessProbe:exec:command:- cat- /tmp/healthy#连续探测失败两次才会判定,容器宕机failureThreshold: 2#容器启动后等待(延迟)5秒,后启动存活探针进行检测initialDelaySeconds: 5#探测周期为5秒periodSeconds: 5
kubectl apply -f /opt/probe/exec.yamlkubectl get pod -w
#会看到创建的pod running重启

kubectl describe pod liveness-exec
#可以看到探测失败;然后kubelet 会 kill杀掉容器,再根据重启策略重启容器

httpget 健康检查方式

示例2:httpGet方式

apiVersion: v1
kind: Pod
metadata:labels:test: livenessname: liveness-http
spec:containers:- name: livenessimage: k8s.gcr.io/livenessargs:- /serverlivenessProbe:httpGet:path: /healthzport: 8080httpHeaders:- name: Custom-Headervalue: AwesomeinitialDelaySeconds: 3periodSeconds: 3

在这个配置文件中,可以看到 Pod 也只有一个容器。

initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 3 秒。

periodSeconds 字段指定了 kubelet 每隔 3 秒执行一次存活探测。

kubelet 会向容器内运行的服务(服务会监听 8080 端口)发送一个 HTTP GET 请求来执行探测。如果服务器上 /healthz 路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。如果处理程序返回失败代码,则 kubelet 会杀死这个容器并且重新启动它。

任何大于或等于 200 并且小于 400 的返回代码标示成功,其它返回代码都标示失败

实践:httpGet方式

apiVersion: v1
kind: Pod
metadata:name: liveness-httpgetnamespace: default
spec:containers:- name: liveness-httpget-containerimage: soscscs/myapp:v1imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80#设置存活探针,探测pod容器的运行状态;一旦探测失败,就会通过kubelet杀掉容器livenessProbe:#采用httpGet的方式,会向podid的指定端口发送http GET请求httpGet:port: http#做http健康检查的页面path: /index.html#表示延迟1秒进行探测initialDelaySeconds: 1#每3秒探测一次periodSeconds: 3#超时时间为10秒timeoutSeconds: 10
kubectl apply -f /opt/probe/httpget.yamlkubectl get pods -w#姗迟index.html页面
kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html

kubectl describe pod liveness-httpget
#httpget 返回状态码为404,探测失败进行重启

这里的重启 不是停止容器再次重启,而是删除容器 再次启动!!!

tcpsocket健康检查方式

示例:tcpSocket方式

httpget http://IP:80/index.html  delay 延迟 =3  tomout=10s    period(频率)=3s   succes(成功)=1  faulure(失败)=3 机会      杀死容器

apiVersion: v1
kind: Pod
metadata:name: goproxylabels:app: goproxy
spec:containers:- name: goproxyimage: k8s.gcr.io/goproxy:0.1ports:- containerPort: 8080readinessProbe:tcpSocket:port: 8080initialDelaySeconds: 5periodSeconds: 10livenessProbe:tcpSocket:port: 8080initialDelaySeconds: 15periodSeconds: 20

这个例子同时使用 readinessProbe 和 livenessProbe 探测。

kubelet 会在容器启动 5 秒后发送第一个 readinessProbe 探测。

这会尝试连接 goproxy 容器的 8080 端口。

如果探测成功,kubelet 将继续每隔 10 秒运行一次检测。

除了 readinessProbe 探测,这个配置包括了一个 livenessProbe 探测。

kubelet 会在容器启动 15 秒后进行第一次 livenessProbe 探测。

就像 readinessProbe 探测一样,会尝试连接 goproxy 容器的 8080 端口。

如果 livenessProbe 探测失败,这个容器会被重新启动。

实践:tcpSocket方式

vim /opt/probe/tcpsocket.yamlapiVersion: v1
kind: Pod
metadata:name: probe-tcp
spec:containers:- name: nginximage: soscscs/myapp:v1livenessProbe:#第一次探测延迟5秒,第6秒才会开始initialDelaySeconds: 5timeoutSeconds: 1tcpSocket:port: 8080#每10秒探测1次periodSeconds: 10#允许失败2次failureThreshold: 2
kubectl apply -f /opt/probe/tcpsocket.yaml

kubectl exec -it probe-tcp  -- netstat -natp#查看pod详细描述信息
kubectl describe pod probe-tcp

四、就绪探针

vim /opt/probe/readiness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:name: readiness-httpgetnamespace: default
spec:containers:- name: readiness-httpget-containerimage: soscscs/myapp:v1imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index1.htmlinitialDelaySeconds: 1periodSeconds: 3#设置存活探针,探测pod容器的运行状态,探测失败就通过kubelet杀掉容器livenessProbe:httpGet:port: httppath: /index.htmlinitialDelaySeconds: 1periodSeconds: 3timeoutSeconds: 10

kubectl apply -f /opt/probe/readiness-httpget.yamlkubectl get pods
#会看到rediness探测失败,无法进入READY状态;有实例在运行,但是就绪失败kubectl describe pod readiness-httpget

#进入容器
kubectl exec -it readiness-httpget shcd /usr/share/nginx/html/
echo "readiness-httpget -- test1" > index1.html

kubectl exec -it readiness-httpget -- rm -rf /usr/share/nginx/html/index.htmlkubectl get pods -w

完成启动探针成功以后、就绪和存活探针才会生效
就绪探针与存活探针  是在启动探针探测成功以后才会生效

就绪检测2

#编辑yaml文件,自定义的文件名
vim /opt/probe/readiness-myapp.yaml
apiVersion: v1
kind: Pod
metadata:name: myapp1labels:app: myapp
spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10
---
apiVersion: v1
kind: Pod
metadata:name: myapp2labels:app: myapp
spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10
---
apiVersion: v1
kind: Pod
metadata:name: myapp3labels:app: myapp
spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10
---
apiVersion: v1
kind: Service
metadata:name: myapp
spec:selector:app: myapptype: ClusterIPports:- name: httpport: 80targetPort: 80
kubectl apply -f /opt/probe/readiness-myapp.yamlkubectl get pod -owide -wkubectl get pods,svc,endpoints -owide

删除页面,看效果

kubectl exec -it  myapp1 -- rm -rf /usr/share/nginx/html/index.htmlkubectl get pods,svc,endpoints -owide

readiness探测失败,Pod 无法进入READY状态,且端点控制器将该 Pod 的 IP 地址从 endpoints 中剔除

kubectl get pods -owide -w

恢复页面,查看内容

#恢复页面
kubectl exec -it myapp1 shecho 'nanjing nihao -- test2' > /usr/share/nginx/html/index.html
exit#再次查看
kubectl get pod -owidekubectl get pods,svc,endpoints -owide

启动、退出动作

vim /opt/probe/demo-pod02.yaml
apiVersion: v1
kind: Pod
metadata:name: lifecycle-demo
spec:containers:- name: lifecycle-demo-containerimage: soscscs/myapp:v1lifecycle:   #此为关键字段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-logmountPath: /var/log/nginx/readOnly: falseinitContainers:- name: init-myserviceimage: soscscs/myapp:v1command: ["/bin/sh", "-c", "echo 'Hello initContainers'   >> /var/log/nginx/message"]volumeMounts:- name: message-logmountPath: /var/log/nginx/readOnly: falsevolumes:- name: message-loghostPath:path: /data/volumes/nginx/log/type: DirectoryOrCreate
kubectl apply -f /opt/probe/demo-pod02.yamlkubectl get pods -owidekubectl exec -it lifecycle-demo -- cat /var/log/nginx/message

在 node02 节点上查看

在master上查看文件位置

#查看日志
cd /data/volume/nginx/log
ls
cat message
#日志中可以看到,是先初始化然后才探针

#由上可知,init Container先执行,然后当一个主容器启动后,Kubernetes 将立即发送 postStart 事件

删除 pod 后,再在 node02 节点上查看

#master上删除pod
kubectl delete pod lifecycle-demo#node02操作
cd /data/volumes/nginx/log/
cat message

#由上可知,当在容器被终结之前, Kubernetes 将发送一个 preStop 事件

验证启动探针、 就绪探针、存活探针的顺序

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

kubectl get pods -owide -w#查看日志
kubectl logs demo1

kubectl exec -it demo1 shecho 'monor' > /usr/share/nginx/html/index1.html
exitkubectl get pod -wkubevtl get pod -owide

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

五、pod的状态

1、pending:pod已经被系统认可了,但是内部的container还没有创建出来。

这里包含调度到node上的时间以及下载镜像的时间,会持续一小段时间。

2、Running:pod已经与node绑定了(调度成功),而且pod中所有的container已经创建出来,至少有一个容器在运行中,或者容器的进程正在启动或者重启状态。

这里需要注意pod虽然已经Running了,但是内部的container不一定完全可用。因此需要进一步检测container的状态。

3、Succeeded:这个状态很少出现,表明pod中的所有container已经成功的terminated了,而且不会再被拉起了。

4、Failed:pod中的所有容器都被terminated,至少一个container是非正常终止的。

(退出的时候返回了一个非0的值或者是被系统直接终止)

5、unknown:由于某些原因pod的状态获取不到,有可能是由于通信问题。 一般情况下pod最常见的就是前两种状态。而且当Running的时候,需要进一步关注container的状态

六、Container生命周期

1、Waiting:启动到运行中间的一个等待状态。

2、Running:运行状态。

3、Terminated:终止状态。 如果没有任何异常的情况下,container应该会从Waiting状态变为Running状态,这时容器可用。

但如果长时间处于Waiting状态,container会有一个字段reason表明它所处的状态和原因,如果这个原因很容易能标识这个容器再也无法启动起来时,例如ContainerCannotRun,整个服务启动就会迅速返回。(这里是一个失败状态返回的特性,不详细阐述)

总结

pod的生命周期是怎么完成的?

接受kubectl指令,先通过pause容器进行初始化,

初始化后完成后,满足串行的所有init后,进行创建容器

创建容器,启动start容器,

收到kubectl指令-->初始化容器(init container),生成文件(init可以有多个,但是不可以同时运行)-->创建容器成功-->start容器-->readnessProbe(就绪性特征):就绪检测--> liveness Probe (存活性探针):生存检测-->stop容器 


    Pause 阶段:当 Pod 中的容器被暂停时,Pod 会进入 Pause 阶段。这通常发生在节点上发生调度变化时,为了确保容器状态的一致性,Pod 会被暂停并且等待恢复。

    Init 阶段:如果 Pod 中定义了 Init 容器,那么在主容器启动之前,Init 容器会先启动并执行其初始化任务。Pod 进入 Init 阶段直到所有 Init 容器都成功完成。

    应用启动阶段:一旦所有的 Init 容器成功完成,主容器将会启动并开始执行应用程序。

    存活阶段:Pod 中的容器正在运行,并且没有出现致命错误,此时 Pod 处于存活状态。

    就绪阶段:Pod 中的容器已经准备好接收流量。如果 Pod 中的所有容器都已经就绪,那么整个 Pod 就处于就绪状态,可以开始接收请求。

pod 容器的资源限制

创建pod 容器时,需要预留的资源量;0.5=500m,内存:MI、GI(2进制为底),M、G(10进制为底)

pod 容器能够使用资源量的一个上限;例:4 Gi 内存上限,1 cpu上限(不允许超过上限制)

kubectl describe node 节点名称        查看pod 或者node 资源使用情况

pod容器的三种探针

存活探针

        判断容器运行是否正常;当探测失败时,会杀死容器(不是pod),根据容器定义的策略来决定是否重启pod

就绪探针

        判断pod是否能进入 ready 状态,做好接收请求的准备;如果探测失败会进入notready 状态,并且从service资源的endpoints中的剔除,service将不会再把访问请求转发给这个pod

启动探针

        判断容器内的应用是否启动成功,在探测成功,状态为access之前,其他探针都会处于失效状态

三种探测方式

exec

        通过command设置,在容器内执行linux 命令来进行探测,如果返回码为0,则表示探测成功;非0则为探测失败;

httpget

        通过http get,请求访问指定容器的端口和url路径,如果访问的状态码>=200且<=400(2xx、300等),则认为探测成功,超出表示探测失败

tcpsocket

        通过指定的端口,发送TCP连接,如果端口无误且tcp三次握手成功(TCP连接成功),则认为探测成功

探针参数:

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

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

命令

#删除所有pod

kubectl delete pod --all

#test -e 判断 目录是否存在

        command: ["test","-e","/tmp/live"]

#延迟1秒进行探测
      initialDelaySeconds: 1

cpu_cfs_quota


通过k8s 搭建xxx 服务

不明原因,导致创建pod一直处于 ContainerCreating 创建中

这篇关于【Kubernetes】Pod 容器资源限制和三种探针的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1024526

相关文章

一份LLM资源清单围观技术大佬的日常;手把手教你在美国搭建「百万卡」AI数据中心;为啥大模型做不好简单的数学计算? | ShowMeAI日报

👀日报&周刊合集 | 🎡ShowMeAI官网 | 🧡 点赞关注评论拜托啦! 1. 为啥大模型做不好简单的数学计算?从大模型高考数学成绩不及格说起 司南评测体系 OpenCompass 选取 7 个大模型 (6 个开源模型+ GPT-4o),组织参与了 2024 年高考「新课标I卷」的语文、数学、英语考试,然后由经验丰富的判卷老师评判得分。 结果如上图所

LeetCode11. 盛最多水的容器题解

LeetCode11. 盛最多水的容器题解 题目链接: https://leetcode.cn/problems/container-with-most-water 示例 思路 暴力解法 定住一个柱子不动,然后用其他柱子与其围住面积,取最大值。 代码如下: public int maxArea1(int[] height) {int n = height.length;int

加载资源文件失败

背景         自己以前装了一个海康的深度学习算法平台,试用期是一个月,过了一个月之后,因为没有有效注册码或者加密狗的支持了导致无法使用,于是打算卸载掉,在卸载一个软件的时候,无论是使用控制面板还是软件自带的卸载功能,总是卸载不掉,提示“加载资源文件失败”。该软体主要包括以下两部分: 用自带卸载功能卸载的时候分别提示如下:     用控制面板卸载的时候反应很慢,最后也是提示这个

亮相WOT全球技术创新大会,揭秘火山引擎边缘容器技术在泛CDN场景的应用与实践

2024年6月21日-22日,51CTO“WOT全球技术创新大会2024”在北京举办。火山引擎边缘计算架构师李志明受邀参与,以“边缘容器技术在泛CDN场景的应用和实践”为主题,与多位行业资深专家,共同探讨泛CDN行业技术架构以及云原生与边缘计算的发展和展望。 火山引擎边缘计算架构师李志明表示:为更好地解决传统泛CDN类业务运行中的问题,火山引擎边缘容器团队参考行业做法,结合实践经验,打造火山

二叉树三种遍历方式及其实现

一、基本概念 每个结点最多有两棵子树,左子树和右子树,次序不可以颠倒。 性质: 1、非空二叉树的第n层上至多有2^(n-1)个元素。 2、深度为h的二叉树至多有2^h-1个结点。 3、对任何一棵二叉树T,如果其终端结点数(即叶子结点数)为n0,度为2的结点数为n2,则n0 = n2 + 1。 满二叉树:所有终端都在同一层次,且非终端结点的度数为2。 在满二叉树中若其深度为h,则其所包含

Java格式化日期的三种方式

1)借助DateFormat类: public String toString(Date d) { SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”); return sdf.format(d); } 2)使用String.format()方法。 String.format()的用法类似于C语

段,页,段页,三种内存(RAM)管理机制分析

段,页,段页         是为实现虚拟内存而产生的技术。直接使用物理内存弊端:地址空间不隔离,内存使用效率低。 段 段:就是按照二进制文件的格式,在内存给进程分段(包括堆栈、数据段、代码段)。通过段寄存器中的段表来进行虚拟地址和物理地址的转换。 段实现的虚拟地址 = 段号+offset 物理地址:被分为很多个有编号的段,每个进程的虚拟地址都有段号,这样可以实现虚实地址之间的转换。其实所谓的地

云原生容器技术入门:Docker、K8s技术的基本原理和用途

🐇明明跟你说过:个人主页 🏅个人专栏:《未来已来:云原生之旅》🏅 🔖行路有良友,便是天堂🔖 目录 一、容器技术概述 1、什么是容器技术 2、容器技术的历史与发展 3、容器技术与虚拟机的比较 4、容器技术在云原生中的作用 二、Docker基础 1、Docker简介 2、Docker架构 3、Docker与工作原理 三、Kubernetes(k8s)基础 1、

Web容器启动时加载Spring分析

在应用程序web.xml中做了以下配置信息时,当启动Web容器时就会自动加载Spring容器。 [java]  view plain copy print ? <listener>          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

ApplicationContext 获取的三种方法

spring为ApplicationContext提供的3种实现分别 为:ClassPathXmlApplicationContext,FileSystemXmlApplicationContext和 XmlWebApplicationContext,其中XmlWebApplicationContext是专为Web工程定制的。使用举例如下:    1. FileSystemXmlApplicati