1. resources:
  2. limits:
  3. cpu: 500m
  4. ephemeral-storage: 10Gi
  5. memory: 256Mi
  6. requests:
  7. cpu: 100m
  8. ephemeral-storage: 5Gi
  9. memory: 128Mi

对应k8s的应用来说一般都是需要指定资源的大小的. 需要根据具体的业务来对最大和最小来进行限制.

如果不做限制会是什么样

未迁移容器以前,我们一般是采用在ECS部署Tomcat来部署应用,如果一个应用的代码有问题,那么它可能会占满该机器的CPU/内存,导致部署在该机器上的其他本来正常的应用变得不正常,如果迁移以后未设置限制,那么效果等同于在ECS上部署Tomcat,依旧会影响到这个Node节点上的其他Pod应用.

如果要做限制存在哪些方面的考量

  • 具体的CPU设置需要根据应用来进行设置,最小可以设置到到100m(0.1C),最大设置到2C, 因为一般我们的应用都是内存型,这样的设置即可以兼顾不耗CPU的应用,也能够让耗CPU的应用有够的CPU可用,如果是核心业务可以考虑设置到0.5C-3C.
    • 如果对于应用的稳定(不重启)有极高的要求,可以考虑使用CPU进行相对隔离,即最小的CPU设置的大一点,避免一个机器上部署多个节点,同时也要和亲和性结合起来
    • 应用的CPU可以设置的高一点,但是不能设置的太少,如果太少,会导致应用启动运行特别慢,有一次我意外的最大的CPU设置在0.1C,结果导致内网的下载下载不动,即使下载下来来,因为CPU的限制也让zip包的解压特别特别慢.
  • 内存的设置就有更高的要求. 需要考量的方面比较多(从JAVA应用考量),如果设置的少了,会导致频繁的应用重启,应用存在稳定性的问题(这里可以监控POD重启,如果重启即告警)。如果设置的多了,应用不会重启,又会造成资源的浪费.
    • 对应常规的Java应用,设置最小内存是迁移前的Xmx内存. 最大内存设置成Xmx+400上线,留出来的这部分作为堆外内存和容器内部其他的经常使用,如果核心消耗在堆外,那么还应该留出更多的堆外内存给它使用
    • 对于非常规的Java应用,例如需要使用Node作图等消耗内存的应用,除了Xmx的配置依旧需要以外,还需要额外的留出大部分内存给其他额外的进程使用,如果不留够足够的内存,会导致应用被OOMKill掉. 具体留出多少需要和业务进行沟通.
    • 到了这一步还是不够的,由于Java应用的特殊性,jdk并不能自动识别他是跑在容器上,还是跑在ECS上,因此需要对Xmx和Xms做出限制,防止Java应用以为自己跑在ECS上而不断的申请内存导致被操作系统Kill掉

如果进行了这样的限制还是有应用不断的重启怎么办.

  • 首先需要获取到上次重启的原因是什么. 我目前遇到的可能原因有2种
    • 应用由于OOM直接被操作系统干掉,会产生OOMKill日志(dmesg -T)
    • 由于tomcat 200个线程被打满,就绪检测和存活检测失败,导致应用重启.
      1. kubectl describe pods nginx-deployment-basic-64d58bb947-mhblp
      2. ## 结果看附录
      获取上次是什么原因退出的. 如果是OOMKilled, 在lastStatus会表明是由于OOMKill.
      如果不是OOMKill,那么可以在事件中看为什么. 一般来是是存活检测的问题

      Liveness probe failed: Get http://172.20.1.133:80/: dial tcp 172.20.1.133:80: connect: connection refused

如果不是OOMKill, 对于Java应用情况有2中

  • Tomcat 200线程池满,导致处理不了存活检测导致容器被重启
  • 由于Java进程已经被OOMKill了,导致存活检测时直接出现链接拒绝

以上2种情况在实际的运行过程中都有出现过. 解决方案无非是:

  • 线程满了,加Tomcat,后续在看看是哪些地方慢在解决问题. 我们以前遇到一个发送钉钉消息,导致Tomcat线程不释放,很快就导致应用告警,然后挂掉重启.
  • 根据上边的描述,做内存调整.

实际运行过程中,还存在代码有问题导致,系统OOM的情况, 这种情况比较特殊,但是也好排查,因为它的重启非常的有规律,一般是每隔几个小时/几天重启,如果几天不好排查,如果是几个小时,一般是好排查的,因为太有规律了.

附录

  1. [root@iZbp11om21c05wzu8e4tx0Z .kube]# kubectl describe pods nginx-deployment-basic-6c795c954-hdqtc
  2. Name: nginx-deployment-basic-6c795c954-hdqtc
  3. Namespace: default
  4. Priority: 0
  5. Node: chenshun54106cc/172.16.254.106
  6. Start Time: Fri, 02 Oct 2020 21:54:44 +0800
  7. Labels: app=nginx
  8. hello=world
  9. pod-template-hash=6c795c954
  10. Annotations: kubernetes.io/psp: ack.privileged
  11. Status: Running
  12. IP: 172.20.1.133
  13. IPs:
  14. IP: 172.20.1.133
  15. Controlled By: ReplicaSet/nginx-deployment-basic-6c795c954
  16. Containers:
  17. nginx:
  18. Container ID: docker://1f83193ba33eaced21e103f1d4e24af6e9ae2a06db7aacc32660b91de4c34a2f
  19. Image: nginx:1.7.9
  20. Image ID: docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
  21. Port: 80/TCP
  22. Host Port: 0/TCP
  23. State: Running
  24. Started: Fri, 02 Oct 2020 21:55:12 +0800
  25. Last State: Terminated
  26. Reason: Completed
  27. Exit Code: 0
  28. Started: Fri, 02 Oct 2020 21:54:45 +0800
  29. Finished: Fri, 02 Oct 2020 21:55:11 +0800
  30. Ready: True
  31. Restart Count: 1
  32. Limits:
  33. cpu: 500m
  34. ephemeral-storage: 10Gi
  35. memory: 256Mi
  36. Requests:
  37. cpu: 100m
  38. ephemeral-storage: 5Gi
  39. memory: 128Mi
  40. Liveness: http-get http://:80/ delay=10s timeout=1s period=10s #success=1 #failure=3
  41. Readiness: http-get http://:80/ delay=10s timeout=1s period=10s #success=1 #failure=3
  42. Environment: <none>
  43. Mounts:
  44. /var/run/secrets/kubernetes.io/serviceaccount from default-token-k9mbl (ro)
  45. Conditions:
  46. Type Status
  47. Initialized True
  48. Ready True
  49. ContainersReady True
  50. PodScheduled True
  51. Volumes:
  52. default-token-k9mbl:
  53. Type: Secret (a volume populated by a Secret)
  54. SecretName: default-token-k9mbl
  55. Optional: false
  56. QoS Class: Burstable
  57. Node-Selectors: <none>
  58. Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
  59. node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
  60. Events:
  61. Type Reason Age From Message
  62. ---- ------ ---- ---- -------
  63. Normal Scheduled 46s default-scheduler Successfully assigned default/nginx-deployment-basic-6c795c954-hdqtc to chenshun54106cc
  64. Normal Pulled 20s (x2 over 46s) kubelet Container image "nginx:1.7.9" already present on machine
  65. Warning Unhealthy 20s kubelet Liveness probe failed: Get http://172.20.1.133:80/: dial tcp 172.20.1.133:80: connect: connection refused
  66. Normal Created 19s (x2 over 46s) kubelet Created container nginx
  67. Normal Started 19s (x2 over 46s) kubelet Started container nginx