resources:
limits:
cpu: 500m
ephemeral-storage: 10Gi
memory: 256Mi
requests:
cpu: 100m
ephemeral-storage: 5Gi
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个线程被打满,就绪检测和存活检测失败,导致应用重启.
获取上次是什么原因退出的. 如果是OOMKilled, 在lastStatus会表明是由于OOMKill.kubectl describe pods nginx-deployment-basic-64d58bb947-mhblp
## 结果看附录
如果不是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的情况, 这种情况比较特殊,但是也好排查,因为它的重启非常的有规律,一般是每隔几个小时/几天重启,如果几天不好排查,如果是几个小时,一般是好排查的,因为太有规律了.
附录
[root@iZbp11om21c05wzu8e4tx0Z .kube]# kubectl describe pods nginx-deployment-basic-6c795c954-hdqtc
Name: nginx-deployment-basic-6c795c954-hdqtc
Namespace: default
Priority: 0
Node: chenshun54106cc/172.16.254.106
Start Time: Fri, 02 Oct 2020 21:54:44 +0800
Labels: app=nginx
hello=world
pod-template-hash=6c795c954
Annotations: kubernetes.io/psp: ack.privileged
Status: Running
IP: 172.20.1.133
IPs:
IP: 172.20.1.133
Controlled By: ReplicaSet/nginx-deployment-basic-6c795c954
Containers:
nginx:
Container ID: docker://1f83193ba33eaced21e103f1d4e24af6e9ae2a06db7aacc32660b91de4c34a2f
Image: nginx:1.7.9
Image ID: docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Fri, 02 Oct 2020 21:55:12 +0800
Last State: Terminated
Reason: Completed
Exit Code: 0
Started: Fri, 02 Oct 2020 21:54:45 +0800
Finished: Fri, 02 Oct 2020 21:55:11 +0800
Ready: True
Restart Count: 1
Limits:
cpu: 500m
ephemeral-storage: 10Gi
memory: 256Mi
Requests:
cpu: 100m
ephemeral-storage: 5Gi
memory: 128Mi
Liveness: http-get http://:80/ delay=10s timeout=1s period=10s #success=1 #failure=3
Readiness: http-get http://:80/ delay=10s timeout=1s period=10s #success=1 #failure=3
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-k9mbl (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-k9mbl:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-k9mbl
Optional: false
QoS Class: Burstable
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 46s default-scheduler Successfully assigned default/nginx-deployment-basic-6c795c954-hdqtc to chenshun54106cc
Normal Pulled 20s (x2 over 46s) kubelet Container image "nginx:1.7.9" already present on machine
Warning Unhealthy 20s kubelet Liveness probe failed: Get http://172.20.1.133:80/: dial tcp 172.20.1.133:80: connect: connection refused
Normal Created 19s (x2 over 46s) kubelet Created container nginx
Normal Started 19s (x2 over 46s) kubelet Started container nginx