k8s—pod进阶(资源限制,健康检查)

网友投稿 257 2022-09-11

k8s—pod进阶(资源限制,健康检查)

一、资源限制

​​当定义 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 值匹配​​

​​官网示例:​​​​作为容器调度时资源分配的判断依赖。​​​​只有当前节点上可分配的资源量 >= request 时才允许将容器调度到该节点。​​​​request参数不限制容器的最大可使用资源​​​​limit​​​​容器能使用资源的最大值​​​​设置为0表示对使用的资源不做限制, 可无限的使用​​​​request 和 limit 关系​​​​request能保证pod有足够的资源来运行, 而limit则是防止某个pod无限制的使用资源, 导致其他pod崩溃. 两者的关系必须满足:0 <= request <= limit​​​​如果limit=0表示不对资源进行限制, 这时可以小于request。​​​​目前CPU支持设置request和limit,memory只支持设置request, limit必须强制等于request, 这样确保容器不会因为内存的使用量超过request但是没有超过limit的情况下被意外kill掉。​​

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

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

2、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 毫秒​​

3、内存资源单位

​​内存的 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​​

4、示例

1.示例1

apiVersion: v1kind: Podmetadata: name: frontendspec: containers: - name: app image: images.my-company.example/app:v4 env: - name: MYSQL_ROOT_PASSWORD value: "password" resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" - name: log-aggregator image: images.my-company.example/log-aggregator:v6 resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"

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

2.示例2

vim pod2.yamlapiVersion: v1kind: Podmetadata: name: frontendspec: containers: - name: web image: nginx env: - name: WEB_ROOT_PASSWORD value: "password" resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" - name: wp image: wordpress resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"kubectl apply -f pod2.yamlkubectl describe pod frontendkubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESfrontend 2/2 Running 5 15m 10.244.2.4 node02 kubectl describe nodes node02 #由于当前虚拟机有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%) 16m kube-system kube-flannel-ds-amd64-f4pbp 100m (5%) 100m (5%) 50Mi (1%) 50Mi (1%) 19h kube-system kube-proxy-pj4wp 0 (0%) 0 (0%) 0 (0%) 0 (0%) 19hAllocated 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%)

二、健康检查(探针 Probe)

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

1、探针的三种规则:

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

​​​livenessProbe:存活检测。探测失败,kubelet会杀死容器,且容器服从其重启策略。不设该字段,默认SuccessreadinessProbe:就绪探测。探测失败,端点控制器将从与pod匹配的所有svc端点中删除pod的ip地址。startupProbe:探测容器内应用是否已启动。如果启用startupProbe,则禁用其他探测,知道它成功为止。探测失败,kubelet将杀死容器,容器服从重启策略​​​

2、Probe支持三种检查方法

​​​exec:在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功​​​​​​tcpSocket:对指定端口上的容器的IP地址进行TCP检查(三次握手)。如果端口打开,则诊断被认为是成功的​​​​​​容器启动多少秒后开始执行探测​​​​periodSeconds∶探测的周期频率,每多少秒执行一次探测​​​​failureThreshold∶探测失败后,允许再试几次​​​​timeoutSeconds ∶ 探测等待超时的时间​

5、示例

1.示例1:exec方式

vim demo2.yaml==========================================================apiVersion: v1kind: Podmetadata: labels: test: liveness name: liveness-execspec: containers: - name: liveness image: busybox args: - /bin/sh - -c - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60 livenessProbe: exec: command: - cat - /tmp/healthy failureThreshold: 1 initialDelaySeconds: 5 periodSeconds: 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会杀死这个容器并重新启动它。==========================================================kubectl apply -f demo2.yaml#查看在探测失败后重新拉取容器kubectl describe pod liveness-exec

2.示例2:demo3.yaml==========================================================apiVersion: v1kind: Podmetadata: name: liveness- namespace: defaultspec: containers: - name: liveness- image: nginx imagePullPolicy: IfNotPresent ports: - name: nginx containerPort: 80 livenessProbe: port: nginx #指定端口,这里使用的是之前的ports里的name,也可以直接写端口 path: /index.html #指定路径 initialDelaySeconds: 1 periodSeconds: 3 timeoutSeconds: 10==========================================================在这个配置文件中, 可以看到 Pod 也只有一个容器。initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 3秒。periodSeconds 字段指定了 kubelet 每隔 3 秒执行一次存活探测。 timeoutSeconds字段指定了超时等待时间为10S,kubelet 会向容器内运行的服务(服务会监听 80端口)发送一个HTTP GET 请求来执行探测。如果服务器上/index.html路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。如果处理程序返回失败代码,则 kubelet 会杀死这个容器并且重新启动它。任何大于或等于 200 并且小于 400 的返回代码标示成功,其它返回代码都标示失败。==========================================================#加载yaml文件kubectl create -f demo3.yaml #进入容器删除网页文件进行测试kubectl exec -it liveness--- rm -rf /usr/share/nginx/html/index.html#查看pod的详细参数kubectl get pods kubectl describe pod liveness-demo4.yaml==========================================================apiVersion: v1kind: Podmetadata: name: probe-tcpspec: containers: - name: tcpnginx image: nginx ports: - containerPort: 80 readinessProbe: tcpSocket: port: 80 initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: tcpSocket: port: 80 initialDelaySeconds: 15 periodSeconds: 20==========================================================#加载yaml文件kubectl create -f demo4.yaml #查看pod的信息kubectl get pod kubectl describe pod probe-tcp

4.示例4:就绪检测

vim readiness-v1kind: Podmetadata: name: readiness- namespace: defaultspec: containers: - name: readiness- image: soscscs/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: containerPort: 80 readinessProbe: port: 80 path: /index1.html initialDelaySeconds: 1 periodSeconds: 3 livenessProbe: port: path: /index.html initialDelaySeconds: 1 periodSeconds: 3 timeoutSeconds: 10kubectl create -f readiness-get pods NAME READY STATUS RESTARTS AGEreadiness- 0/1 Running 0 18skubectl exec -it readiness-sh # cd /usr/share/nginx/html/ # ls50x.html index.html # echo 123 > index1.html # exitkubectl get pods NAME READY STATUS RESTARTS AGEreadiness- 1/1 Running 0 2m31skubectl exec -it readiness--- rm -rf /usr/share/nginx/html/index.htmlkubectl get pods -wNAME READY STATUS RESTARTS AGEreadiness- 1/1 Running 0 4m10sreadiness- 0/1 Running 1 4m15s

5.示例5:就绪检测2

vim readiness-myapp.yamlapiVersion: v1kind: Podmetadata: name: myapp1 labels: app: myappspec: containers: - name: myapp image: soscscs/myapp:v1 ports: - name: containerPort: 80 readinessProbe: port: 80 path: /index.html initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 10 ---apiVersion: v1kind: Podmetadata: name: myapp2 labels: app: myappspec: containers: - name: myapp image: soscscs/myapp:v1 ports: - name: containerPort: 80 readinessProbe: port: 80 path: /index.html initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 10 ---apiVersion: v1kind: Podmetadata: name: myapp3 labels: app: myappspec: containers: - name: myapp image: soscscs/myapp:v1 ports: - name: containerPort: 80 readinessProbe: port: 80 path: /index.html initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 10 ---apiVersion: v1kind: Servicemetadata: name: myappspec: selector: app: myapp type: ClusterIP ports: - name: port: 80 targetPort: 80kubectl create -f readiness-myapp.yamlkubectl get pods,svc,endpoints -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESpod/myapp1 1/1 Running 0 3m42s 10.244.2.13 node02 pod/myapp2 1/1 Running 0 3m42s 10.244.1.15 node01 pod/myapp3 1/1 Running 0 3m42s 10.244.2.14 node02 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR......service/myapp ClusterIP 10.96.138.13 80/TCP 3m42s app=myappNAME ENDPOINTS AGE......endpoints/myapp 10.244.1.15:80,10.244.2.13:80,10.244.2.14:80 3m42skubectl exec -it pod/myapp1 -- rm -rf /usr/share/nginx/html/index.html//readiness探测失败,Pod 无法进入READY状态,且端点控制器将从 endpoints 中剔除删除该 Pod 的 IP 地址kubectl get pods,svc,endpoints -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESpod/myapp1 0/1 Running 0 5m17s 10.244.2.13 node02 pod/myapp2 1/1 Running 0 5m17s 10.244.1.15 node01 pod/myapp3 1/1 Running 0 5m17s 10.244.2.14 node02 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR......service/myapp ClusterIP 10.96.138.13 80/TCP 5m17s app=myappNAME ENDPOINTS AGE......endpoints/myapp 10.244.1.15:80,10.244.2.14:80 5m17s

三、容器启动、退出动作

======启动、退出动作======vim post.yamlapiVersion: v1kind: Podmetadata: name: lifecycle-demospec: 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: DirectoryOrCreatekubectl create -f post.yamlkubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESlifecycle-demo 1/1 Running 0 2m8s 10.244.2.28 node02 kubectl exec -it lifecycle-demo -- cat /var/log/nginx/messageHello initContainersHello from the postStart handler//在 node02 节点上查看[root@node02 ~]# cd /data/volumes/nginx/log/[root@node02 log]# lsaccess.log error.log message[root@node02 log]# cat message Hello initContainersHello from the postStart handler#由上可知,init Container先执行,然后当一个主容器启动后,Kubernetes 将立即发送 postStart 事件。//删除 pod 后,再在 node02 节点上查看kubectl delete pod lifecycle-demo[root@node02 log]# cat message Hello initContainersHello from the postStart handlerHello from the poststop handler#由上可知,当在容器被终结之前, Kubernetes 将发送一个 preStop 事件。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:k8s存储卷+PV与PVC
下一篇:“顶流”李佳琦的IP营销路!
相关文章

 发表评论

暂时没有评论,来抢沙发吧~