【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

相关文章

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

poj 2135 有流量限制的最小费用最大流

题意: 农场里有n块地,其中约翰的家在1号地,二n号地有个很大的仓库。 农场有M条道路(双向),道路i连接着ai号地和bi号地,长度为ci。 约翰希望按照从家里出发,经过若干块地后到达仓库,然后再返回家中的顺序带朋友参观。 如果要求往返不能经过同一条路两次,求参观路线总长度的最小值。 解析: 如果只考虑去或者回的情况,问题只不过是无向图中两点之间的最短路问题。 但是现在要去要回

poj 3422 有流量限制的最小费用流 反用求最大 + 拆点

题意: 给一个n*n(50 * 50) 的数字迷宫,从左上点开始走,走到右下点。 每次只能往右移一格,或者往下移一格。 每个格子,第一次到达时可以获得格子对应的数字作为奖励,再次到达则没有奖励。 问走k次这个迷宫,最大能获得多少奖励。 解析: 拆点,拿样例来说明: 3 2 1 2 3 0 2 1 1 4 2 3*3的数字迷宫,走两次最大能获得多少奖励。 将每个点拆成两个

poj 2195 bfs+有流量限制的最小费用流

题意: 给一张n * m(100 * 100)的图,图中” . " 代表空地, “ M ” 代表人, “ H ” 代表家。 现在,要你安排每个人从他所在的地方移动到家里,每移动一格的消耗是1,求最小的消耗。 人可以移动到家的那一格但是不进去。 解析: 先用bfs搞出每个M与每个H的距离。 然后就是网络流的建图过程了,先抽象出源点s和汇点t。 令源点与每个人相连,容量为1,费用为

poj 3068 有流量限制的最小费用网络流

题意: m条有向边连接了n个仓库,每条边都有一定费用。 将两种危险品从0运到n-1,除了起点和终点外,危险品不能放在一起,也不能走相同的路径。 求最小的费用是多少。 解析: 抽象出一个源点s一个汇点t,源点与0相连,费用为0,容量为2。 汇点与n - 1相连,费用为0,容量为2。 每条边之间也相连,费用为每条边的费用,容量为1。 建图完毕之后,求一条流量为2的最小费用流就行了

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

什么是Kubernetes PodSecurityPolicy?

@TOC 💖The Begin💖点点关注,收藏不迷路💖 1、什么是PodSecurityPolicy? PodSecurityPolicy(PSP)是Kubernetes中的一个安全特性,用于在Pod创建前进行安全策略检查,限制Pod的资源使用、运行权限等,提升集群安全性。 2、为什么需要它? 默认情况下,Kubernetes允许用户自由创建Pod,可能带来安全风险。

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

容器编排平台Kubernetes简介

目录 什么是K8s 为什么需要K8s 什么是容器(Contianer) K8s能做什么? K8s的架构原理  控制平面(Control plane)         kube-apiserver         etcd         kube-scheduler         kube-controller-manager         cloud-controlle

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟