K8S 集群遇到负载不均衡的问题。

13 天前
 BenchWidth
服务器配置:5 台 4 核 8G Centos7 系统 ,3 台 8 核 16G ubuntu 20.24

kubelet:1.23.17

docker:26.1.3

使用 kubeadm 部署的集群

我部署的其他应用都够正常的调度到三台配置较高的 ubuntu 机器上,只有新部署的 spring cloud 服务不自动调度到配置较高的 ubuntu 机器上。直到那几台 centos7 服务器被挤爆了,k8s 也不会将服务器调度到其他机器上。

我没有设置污点也没有设置亲和性。

我把 5 台 centos7 服务器禁止调度之后,k8s 才会将服务部署到 ubuntu 服务器上
1550 次点击
所在节点    Kubernetes
19 条回复
BenchWidth
13 天前
补充:5 台 centos7 上有原始服务在运行,k8s 服务器信息获取正常,本来想的是在服务器上集群运行好之后再去手动关闭掉机器上的原始服务。
seers
13 天前
检查下 limit 和 require 吧,资源不够是不会调度过去的
zhoudaiyu
13 天前
用 podantiaffnity 试试
hallDrawnel
13 天前
去掉敏感信息贴下完整的 deployment yaml 描述
BenchWidth
13 天前
@hallDrawnel

apiVersion: apps/v1
kind: Deployment
metadata:
name:
namespace:
spec:
replicas: 1
selector:
matchLabels:
app:
template:
metadata:
labels:
app:
spec:
containers:
- name:
image:
ports:
- containerPort: 8090
---
apiVersion: v1
kind: Service
metadata:
name:
namespace:
spec:
selector:
app:
ports:
- protocol: TCP
port: 8090
targetPort: 8090
BenchWidth
13 天前
@seers 资源是肯定够的,内存、CPU 、磁盘都是充足的
Frankcox
13 天前
通过 NodeSelector 或者硬亲和强制指到节点上,看看是否 Pending
mightybruce
13 天前
k8s 调度本身是基于 linux 内核的完全公平调度器 CFS, 要想做到绝对均衡的调度是不可能的,想实现一些特定的调度可以用 K8s 调度框架来实现插件,
简单的做法就是给机器打上各种标签,然后用 nodeselector 就好了。
yanbo92
13 天前
有同样经历,我的调法是把 kube-scheduler 日志等级到 10 或者 11 ,看每个插件打分的结果来微调插件权重。可以参考这篇文章: https://midbai.com/post/scheduler-always-place-pod-on-the-same-node/
rbaloatiw
13 天前
@mightybruce #8
> k8s 调度本身是基于 linux 内核的完全公平调度器 CFS
这个说的应该不是 kube-scheduler 吧?

我也会使用 #9 的做法, 通过日志来查看每个插件的打分结果
assassing
13 天前
同样有这个困扰,默认调度策略似乎倾向于用满一台服务器再分配到下一台。我用的版本还是 1.22 ,不知道后面更新版本情况怎样?
yanbo92
13 天前
部分节点有原始服务在跑这个信息比较关键,其实默认那些调度插件只计算由 k8s 自己起的容器申请的资源,节点上有其他非 k8s 集群进程在吃资源,并不会被调度器考虑到。
ryan4yin
12 天前
#5 你 limits 跟 requests 都没配,这怎么让 k8s 调度,k8s 管理资源的核心逻辑是 HPA VPA 动态扩缩容,不是把旧的 Pod 删掉,在大机器上给你跑个新的。
建议找个 k8s 教程先学一学吧。
guanzhangzhang
12 天前
request 是资源请求占坑,limit 是 cgroup 限制
例如一个 1G 内存的 node
你可以部署多个没有 request 的 pod ,不配置 limits 则实际例如内存 oom 紧张时候 oom-killer 会根据 oom_score 得分去杀进程
同样 1G 内存的 node ,你 request 配置 400M 内存,你 replicas=3 只有两个能调度到该节点,实际内存使用 1M ,都是这样,request 是资源占坑。

limit 除去 cgroup 限制,还涉及到 pod Qos ,会生成 oom_score_adj
cinlen
12 天前
k8s 默认的调度器不是 load-aware 的,也就是说它感知不到你物理上的资源消耗。

它凭节点上的 pod requests 资源总和做决策,你的 pod 不写 resource.requests ,那在 k8s 调度器看来你的 pod 就不占资源。

你可以确认看看是不是:

1. 这 5 个 centos 节点的 pod requests 资源之和较少
2. 是不是你的架构是 3 master 5 worker ?然后有什么策略会让 workloads 优先考虑调度到 worker 。
hallDrawnel
12 天前
你的 limit 和 request 都没有啊,k8s 不知道怎么调度。再详细学习下这块。
assassing
8 天前
@yanbo92 #9 我的开发环境 K8s 版本 v1.22.3 ,一共三个工作节点,两个节点内存几乎满载,评分 NodeResourcesBalancedAllocation 都是 100 分,另外一个节点评分是 87 。然后两个满载节点 NodeResourcesFit 评分为 0 ,另外一个节点评分是 12 。这个最终合计评分 99 的节点内存使用率和调度率都只有 50%。所有 pod 都有设置一样的内存请求和内存限制。我想不通,于是想要把 NodeResourcesFit 优先级调高,结果只要启动参数加入 --config ,参数 --kubeconfig 就会失效,让人无能狂怒。请问你是怎么做的?
yanbo92
4 天前
@assassing #17
我的集群版本是 1.23.0, 这段配置大概是这样

```
spec:
containers:
- command:
- kube-scheduler
- --authentication-kubeconfig=/etc/kubernetes/scheduler.conf
- --authorization-kubeconfig=/etc/kubernetes/scheduler.conf
- --bind-address=127.0.0.1
- --kubeconfig=/etc/kubernetes/scheduler.conf
- --leader-elect=true
- --config=/etc/kubernetes/kube-scheduler-config.yaml
- --v=11
```
assassing
4 天前
@yanbo92 #18 是这样添加参数的。config.yaml 内容有误时,启动会报错,例如使用不支持的 v1 而不是 v1beta3 版本,这样可以确认 config.yaml 文件在启动时被读取了。config.yaml 内容无误时,启动报错,说没有配置 --kubeconfig 参数,token 认证失败。删除 --config 参数又正常启动,这两到底有什么冲突?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1070553

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX