• k8s——Pod进阶(资源限制和探针)


    一、资源限制

      1.1 资源限制的定义

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

      官方示例:https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/icon-default.png?t=N7T8https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/

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

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

      1.3 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资源。 

      1.4 内存资源单位

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

      1.5 实验操作

      1.5.1 OOM资源不足被干掉

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: ky-web-db
    5. spec:
    6. containers:
    7. - name: web
    8. image: nginx
    9. env:
    10. - name: WEB_ROOT_PASSWORD
    11. value: "password"
    12. resources:
    13. requests:
    14. memory: "64Mi"
    15. cpu: "250m"
    16. limits:
    17. memory: "128Mi"
    18. cpu: "500m"
    19. - name: db
    20. image: mysql
    21. env:
    22. - name: MYSQL_ROOT_PASSWORD
    23. value: "abc123"
    24. resources:
    25. requests:
    26. memory: "64Mi"
    27. cpu: "0.25"
    28. limits:
    29. memory: "128Mi"
    30. cpu: "500m"

    资源不足第一个进程被杀死,注意如果节点上有资源会拉取节点资源创建,可先把节点关闭

    查看日志信息,db因资源不足被干掉

        1.5.2 资源充足

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: ky-web-db
    5. spec:
    6. containers:
    7. - name: web
    8. image: nginx
    9. env:
    10. - name: WEB_ROOT_PASSWORD
    11. value: "password"
    12. resources:
    13. requests:
    14. memory: "64Mi"
    15. cpu: "250m"
    16. limits:
    17. memory: "128Mi"
    18. cpu: "500m"
    19. - name: db
    20. image: mysql
    21. env:
    22. - name: MYSQL_ROOT_PASSWORD
    23. value: "abc123"
    24. resources:
    25. requests:
    26. memory: "64Mi"
    27. cpu: "0.5"
    28. limits:
    29. memory: "1Gi"
    30. cpu: "1"

    给足资源后,状态为running 

    查看日志信息后,调度给了node01

      查看node01详细信息,可以看到资源详细情况 

    二、探针

      2.1 探针的定义

        健康检查:又称为探针(Probe) ,探针是由kubelet对容器执行的定期诊断。 

      2.2 探针的规则

    • 存活探针(livenessProbe):判断容器是否运行正常,如果探测失败则杀死容器(不是pod),容器根据容器策略决定是否重启
    • 就绪探针(readinessProbe):判断pod是否能进入ready状态,做好接受请求的准备。如果探针失败会进入not ready状态且从service自愿的endpoints中剔除,service将不会再把访问请求转发给pod
    • 启动探针(startupProbe):判断容器内的应用是否启动成功,在检测成功状态为success真会玩,其他的探针都会处于失效状态

      2.3 Probe三种检查方式

    • exec:通过command设置,执行在容器内执行的linux命令来进行探测,如果返回码为0,则为探测成功,非0就为探测失败
    • httpget:通过http get请求访问制定容器端口和url路径,如果访问状态吗为>=200且<=400(2xx 300),则认为探测成功
    • tcpsocket:通过制定的端口发送TCP连接,如果端口无误且三次握手成功(TCP连接成功),则认为探测成功

      2.4 探测的结果

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

      2.5 实验部署

      2.5.1 exec方式——liveness

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. labels:
    5. test: liveness
    6. name: liveness-exec
    7. spec:
    8. containers:
    9. - name: liveness
    10. image: busybox
    11. imagePullPolicy: IfNotPresent
    12. args: ###启动容器参数
    13. - /bin/sh
    14. - -c
    15. - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60
    16. livenessProbe: #定义了容器的就绪探针
    17. exec: #在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功。
    18. command: #指定了执行的命令
    19. - cat
    20. - /tmp/healthy
    21. failureThreshold: 1 #就绪探针在连续失败一次后被视为失败
    22. initialDelaySeconds: 5 #延迟5秒启动容器
    23. periodSeconds: 5 #每隔5秒探测一次

    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60

    创建一个名为 /tmp/healthy 的文件,暂停执行脚本,等待 30 秒钟,删除后,再次暂停执行脚本,等待额外的 60 秒钟

    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会杀死这个容器并重新启动它。

    探针失败 

    /tmp/healthy文件不存在,探测失败 

      2.5.2 httpGet方式

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: liveness-httpget
    5. namespace: default
    6. spec:
    7. containers:
    8. - name: liveness-httpget-container
    9. image: soscscs/myapp:v1 #soscscs:nginx1.12
    10. imagePullPolicy: IfNotPresent #拉取策略
    11. ports:
    12. - name: http
    13. containerPort: 80
    14. livenessProbe: #探针
    15. httpGet:
    16. port: http
    17. path: /index.html
    18. initialDelaySeconds: 1 #延迟1秒开始探测
    19. periodSeconds: 3 #每3秒探测一次
    20. timeoutSeconds: 10 #超时时间10

    删除index.html页面,报错404,探针失败

    httpget:通过http get请求访问制定容器端口和url路径,如果访问状态吗为>=200且<=400(2xx 300),则认为探测成功

    当我们删除页面后会404报错,然后就会探测失败,最后会重启 

      2.5.3 tcpSocket方式

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: xzq-tcp-live
    5. spec:
    6. containers:
    7. - name: nginx
    8. image: soscscs/myapp:v1
    9. livenessProbe:
    10. initialDelaySeconds: 5 #第一次探测延迟5秒,第6秒开始
    11. timeoutSeconds: 1
    12. tcpSocket:
    13. port: 8080
    14. periodSeconds: 10 #每10秒探测一次
    15. failureThreshold: 2 #允许2次失败

      2.5.4 就绪检测——readiness

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: readiness-httpget
    5. namespace: default
    6. spec:
    7. containers:
    8. - name: readiness-httpget-container
    9. image: soscscs/myapp:v1
    10. imagePullPolicy: IfNotPresent
    11. ports:
    12. - name: http
    13. containerPort: 80
    14. readinessProbe:
    15. httpGet:
    16. port: 80
    17. path: /index1.html
    18. initialDelaySeconds: 1
    19. periodSeconds: 3
    20. livenessProbe:
    21. httpGet:
    22. port: http
    23. path: /index.html
    24. initialDelaySeconds: 1
    25. periodSeconds: 3
    26. timeoutSeconds: 10

    有实例在运行,但是就绪失败

     探针http,404报错

    bash可能是权限不足,用sh进入写一个页面

    kubectl describe pod readiness-httpget

       2.5.5 就绪检测2——readiness

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: myapp1
    5. labels:
    6. app: myapp
    7. spec:
    8. containers:
    9. - name: myapp
    10. image: soscscs/myapp:v1
    11. ports:
    12. - name: http
    13. containerPort: 80
    14. readinessProbe:
    15. httpGet:
    16. port: 80
    17. path: /index.html
    18. initialDelaySeconds: 5
    19. periodSeconds: 5
    20. timeoutSeconds: 10
    21. ---
    22. apiVersion: v1
    23. kind: Pod
    24. metadata:
    25. name: myapp2
    26. labels:
    27. app: myapp
    28. spec:
    29. containers:
    30. - name: myapp
    31. image: soscscs/myapp:v1
    32. ports:
    33. - name: http
    34. containerPort: 80
    35. readinessProbe:
    36. httpGet:
    37. port: 80
    38. path: /index.html
    39. initialDelaySeconds: 5
    40. periodSeconds: 5
    41. timeoutSeconds: 10
    42. ---
    43. apiVersion: v1
    44. kind: Pod
    45. metadata:
    46. name: myapp3
    47. labels:
    48. app: myapp
    49. spec:
    50. containers:
    51. - name: myapp
    52. image: soscscs/myapp:v1
    53. ports:
    54. - name: http
    55. containerPort: 80
    56. readinessProbe:
    57. httpGet:
    58. port: 80
    59. path: /index.html
    60. initialDelaySeconds: 5
    61. periodSeconds: 5
    62. timeoutSeconds: 10
    63. ---
    64. apiVersion: v1
    65. kind: Service
    66. metadata:
    67. name: myapp
    68. spec:
    69. selector:
    70. app: myapp
    71. type: ClusterIP
    72. ports:
    73. - name: http
    74. port: 80
    75. targetPort: 80

     查看集群中服务、pod和端点的信息

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

      2.5.6 启动、退出动作

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: lifecycle-demo
    5. spec:
    6. containers:
    7. - name: lifecycle-demo-container
    8. image: soscscs/myapp:v1
    9. lifecycle: #此为关键字段,定义容器的生命周期
    10. postStart: #容器启动后立即执行的操作
    11. exec: #允许容器启动后执行特定的命令
    12. command: ["/bin/sh", "-c", "echo Hello from the postStart handler >> /var/log/nginx/message"]
    13. preStop: #容器停止后立即执行的命令
    14. exec:
    15. command: ["/bin/sh", "-c", "echo Hello from the poststop handler >> /var/log/nginx/message"]
    16. volumeMounts: #将存储卷挂载到容器指定路径上
    17. - name: message-log #存储卷名字
    18. mountPath: /var/log/nginx/
    19. readOnly: false #可以读和写
    20. initContainers:
    21. - name: init-myservice
    22. image: soscscs/myapp:v1
    23. command: ["/bin/sh", "-c", "echo 'Hello initContainers' >> /var/log/nginx/message"]
    24. volumeMounts:
    25. - name: message-log
    26. mountPath: /var/log/nginx/
    27. readOnly: false
    28. volumes:
    29. - name: message-log
    30. hostPath: #hostPath类型,将存储卷挂载到主机上
    31. path: /data/volumes/nginx/log/ #主机路径
    32. type: DirectoryOrCreate #类型为目录,如无目录,会自动创建

    创建后去node01查看日志

    进入到日志路径下,日志瞎看到先初始化后才探针 

    在node01下删除pod 

    关闭探针=关闭生命周期 

    cat message

  • 相关阅读:
    微信小程序开发09 开放数据:微信生态帮助业务快速落地
    手把手教你:LLama2原始权重转HF模型
    JAVA之springMVC
    undo log
    Linux常用命令字典篇
    k8s部署springboot服务
    【译】使用保留大小写的查找和替换来保存您的命名方式
    单元测试一(实践)-云计算2023.11-云南农业大学
    2022年CCF推荐国际学术会议和期刊(人工智能领域)
    【Docker】实现JMeter分布式压测
  • 原文地址:https://blog.csdn.net/sea_bunch/article/details/139327254