k8s pod常见必坑指南 k8s 调度
一 pod常见必坑指南原文:https://baijiahao.baidu.com/s?id=1667476081684280685&wfr=spider&for=pc1内存的过量使用会给你带来更多的麻烦。达到 CPU limit 时只会导致 CPU 使用受限,达到 Memory limit 将会导致 Pod 被杀死。你听说过 OOMkill 吗?是的,它正是我们要说的内存不足时自
k8s调度是基于pod 的 request值
一 pod常见必坑指南
原文:https://baijiahao.baidu.com/s?id=1667476081684280685&wfr=spider&for=pc
1
内存的过量使用会给你带来更多的麻烦。达到 CPU limit 时只会导致 CPU 使用受限,达到 Memory limit 将会导致 Pod 被杀死。你听说过 OOMkill 吗?是的,它正是我们要说的内存不足时自动杀死进程的机制。如果你想尽量减少这种情况的发生,那就不要过度使用内存,而应该使用“Guaranteed QoS”模式,将 Memory Request 值设为等于 Memory limit 值(就像下面的示例一样)。关于这个话题,你可以从 Henning Jacobs(Zalando)的这个演讲中获得更多信息[1]。
Burstable QoS 模式下的资源设置(很可能导致 OOMKill 机制更频繁地被触发):
resources:requests:memory: "128Mi"cpu: "500m"limits:memory: "256Mi"cpu: 2
Guaranteed QoS 模式的资源设置:
resources:requests:memory: "128Mi"cpu: 2limits:memory: "128Mi"cpu: 2
在这个方面,Prometheus、DataDog 和许多其他的监控系统可以帮助你。它们从 metrics-server 上获取这些指标信息并存储起来,然后你就可以对其进行查询和绘制图形。
VerticalPodAutoscaler[2] 工具可以帮助你自动化这一手动过程:包括及时查看 CPU/内存的使用情况,以及基于使用情况设置新的 request 和 limit 的值。
2
有时候,不配置任何一个探针比错误地配置探针要好。如上所述,如果将 liveness 探针配置成和 readiness 探针一样,那么你将遇到大麻烦。作为开始,建议你仅仅配置 readiness 探针,因为 liveness 探针很危险。
如果一个和其它 pod 有共享依赖项的 pod 被关闭,那么你必须保证针对这个 pod 的任何一个探针都不能失败,否则将导致所有 Pod 的级联失败。那你就是在搬起石头砸自己的脚了。
3
K8s 社区正在广泛使用 cluster-autoscaler 集群自动伸缩器,它运行在你的集群中,并且已经和大多数主要的公共云提供商的 API 实现了集成,理解所有这些约束,可以帮助你在上述情况下实现自动向外扩展。它还能够帮助你确定在不影响设置的约束条件下方便地实现自动向内收缩,以节省你的计算成本。
4
你不能指望 K8s 调度器自动为你的 pod 强加一个反亲和性设置。相反,你应该明确地定义它们(如下例)。
// omitted for brevity labels: app: zk// omitted for brevity affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: "app"operator: In values: - zk topologyKey: "kubernetes.io/hostname"
你需要像上面这样设置 pod 的反亲和性,它将确保 pod 被调度到不同的节点上(注意:这个设置是在调度时检查,而不是在执行时检查,因此需要设置成 requiredDuringSchedulingIgnoredDuringExecution 类型)。
5
没有 poddisruptionbudget
你是在 K8s 上运行生产环境的工作负载。你的节点和集群必须不时地升级或停用。而 PodDisruptionBudget(pdb)就是一种被集群管理员和集群用户广泛用来确保服务质量的 API。
请确保你创建了 pdb,以避免由于节点停用过多而导致不必要的服务中断。
apiVersion: policy/v1beta1kind: PodDisruptionBudgetmetadata: name: zk-pdbspec: minAvailable: 2 selector: matchLabels: app: zookeeper
作为集群用户,你可以这样告诉集群管理员:“嘿,我这里有个 zookeeper 服务,不管你想做什么,我希望至少保证两个副本始终可用。”
关于这个话题,我在这篇博文中作了深入地讨论[4]。
6
将 K8s 服务的 externalTrafficPolicy 值设置为 Local (即 externalTrafficPolicy: Local)将不会导致在每个节点上打开该 NodePort 服务,它只会在 pod 实际运行的节点上打开。如果你使用一个能够对 endpoint 进行状态检查的外部负载平衡器(如 AWS ELB 所做的),它就仅仅将流量发送到它应该发送到的节点,从而改进延迟、降低计算开销和出口成本,并提高健全性。
7
附送一个问题:使用 latest 标签
这是一个经典的问题。但是最近我发现自己不经常看到这种问题了,可能因为我们太多人都在这上面栽过跟头,所以我们不再使用:latest 这个标签了。
AWS ECR 现在支持标签不变性,这个很棒的特性绝对值得你去查看。
二 理解为什么 requests和limits
- 尊敬的开发人员,请在你的工作负载中设置 Request 和 Limit;
- 尊敬的集群管理员,设置命名空间配额会强制命名空间中的所有工作负载的容器中使用该 Request 和 Limit。
配额是正确共享资源的必要条件。如果有人告诉你可以无限制地使用任何共享服务,别听他的,拒绝背锅。
https://zhuanlan.zhihu.com/p/114765307
三 具体操作 设置 requests和limits
3.1 设置 namespace 整体限制
https://blog.csdn.net/sinron_wu/article/details/106518824
# 创建namespace
[root@kmaster ~]# kubectl create namespace test
# 编辑ResourceQuota定义文档
[root@kmaster ~]# vim quota-test.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: quota-test
namespace: test
spec:
hard:
requests.cpu: "2"
requests.memory: 2Gi
limits.cpu: "4"
limits.memory: 4Gi
requests.nvidia.com/gpu: 4
pods: "3"
services: "6"
# 创建ResourceQuota
[root@kmaster ~]# kubectl apply -f quota-test.yaml
# 查看
[root@kmaster ~]# kubectl get quota -n test
NAME CREATED AT
quota-test 2020-05-26T10:31:10Z
[root@kmaster ~]# kubectl describe quota quota-test -n test
Name: quota-test
Namespace: test
Resource Used Hard
-------- ---- ----
limits.cpu 0 4
limits.memory 0 4Gi
pods 0 3
requests.cpu 0 2
requests.memory 0 2Gi
requests.nvidia.com/gpu 0 4
services 0 6
3.2 设置namespace 里面每个pod 不推荐管理员硬性设置
https://www.cnblogs.com/wxm-pythoncoder/p/14303352.html
apiVersion: v1
kind: LimitRange
metadata:
name: example
spec:
limits:
- type: Pod
min:
cpu: 50m
memory: 5Mi
max:
cpu: 1
memory: 1Gi
- type: Container
defaultRequest:
cpu: 100m
memory: 10Mi
default:
cpu: 200m
memory: 100Mi
min:
cpu: 50m
memory: 5Mi
max:
cpu: 1
memory: 1Gi
maxLimitRequestRatio:
cpu: 4
memory: 10
- type: PersistentVolumeClaim
min:
storage: 1Gi
max:
storage: 10Gi
最后还是要监控:
三 监控集群中pod的资源使用量
kubelet自身包含一个cAdvisor的agent,它会收集整个节点上容器的消耗情况,之后将信息汇报给Heapster的组件
更多推荐
所有评论(0)