V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
BenchWidth
V2EX  ›  Kubernetes

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

  •  1
     
  •   BenchWidth · 11 天前 · 1516 次点击
    服务器配置: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 服务器上
    第 1 条附言  ·  10 天前
    负载不均衡的问题已经解决了:我按照#8 提供的地址去看了一下 scheduler 的调度日志,发现三台 ubuntu 机器的 NodeResourcesFit 评分非常低,搜索了一些资料也没说是什么问题,我就索性把 ubuntu 节点给重置了然后重启 docker 和 kubelet ,重新加入集群。发现 NodeResourcesFit 评分正常了,容器也能被调度到 ubuntu 节点上。

    关于我为什么没有写 limit 和 request 是因为服务器资源挺充足的,想让 pod 能够大限度的获取服务器资源。所以就没有对 limit 和 request ,这样也不会影响到 scheduler 对节点服务器的评分。
    19 条回复    2024-09-14 14:24:30 +08:00
    BenchWidth
        1
    BenchWidth  
    OP
       11 天前
    补充:5 台 centos7 上有原始服务在运行,k8s 服务器信息获取正常,本来想的是在服务器上集群运行好之后再去手动关闭掉机器上的原始服务。
    seers
        2
    seers  
       11 天前 via Android
    检查下 limit 和 require 吧,资源不够是不会调度过去的
    zhoudaiyu
        3
    zhoudaiyu  
       11 天前
    用 podantiaffnity 试试
    hallDrawnel
        4
    hallDrawnel  
       11 天前
    去掉敏感信息贴下完整的 deployment yaml 描述
    BenchWidth
        5
    BenchWidth  
    OP
       11 天前
    @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
        6
    BenchWidth  
    OP
       11 天前
    @seers 资源是肯定够的,内存、CPU 、磁盘都是充足的
    Frankcox
        7
    Frankcox  
       11 天前
    通过 NodeSelector 或者硬亲和强制指到节点上,看看是否 Pending
    mightybruce
        8
    mightybruce  
       11 天前
    k8s 调度本身是基于 linux 内核的完全公平调度器 CFS, 要想做到绝对均衡的调度是不可能的,想实现一些特定的调度可以用 K8s 调度框架来实现插件,
    简单的做法就是给机器打上各种标签,然后用 nodeselector 就好了。
    yanbo92
        9
    yanbo92  
       11 天前
    有同样经历,我的调法是把 kube-scheduler 日志等级到 10 或者 11 ,看每个插件打分的结果来微调插件权重。可以参考这篇文章: https://midbai.com/post/scheduler-always-place-pod-on-the-same-node/
    rbaloatiw
        10
    rbaloatiw  
       11 天前
    @mightybruce #8
    > k8s 调度本身是基于 linux 内核的完全公平调度器 CFS
    这个说的应该不是 kube-scheduler 吧?

    我也会使用 #9 的做法, 通过日志来查看每个插件的打分结果
    assassing
        11
    assassing  
       11 天前
    同样有这个困扰,默认调度策略似乎倾向于用满一台服务器再分配到下一台。我用的版本还是 1.22 ,不知道后面更新版本情况怎样?
    yanbo92
        12
    yanbo92  
       11 天前 via iPhone
    部分节点有原始服务在跑这个信息比较关键,其实默认那些调度插件只计算由 k8s 自己起的容器申请的资源,节点上有其他非 k8s 集群进程在吃资源,并不会被调度器考虑到。
    ryan4yin
        13
    ryan4yin  
       10 天前
    #5 你 limits 跟 requests 都没配,这怎么让 k8s 调度,k8s 管理资源的核心逻辑是 HPA VPA 动态扩缩容,不是把旧的 Pod 删掉,在大机器上给你跑个新的。
    建议找个 k8s 教程先学一学吧。
    guanzhangzhang
        14
    guanzhangzhang  
       10 天前
    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
        15
    cinlen  
       10 天前
    k8s 默认的调度器不是 load-aware 的,也就是说它感知不到你物理上的资源消耗。

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

    你可以确认看看是不是:

    1. 这 5 个 centos 节点的 pod requests 资源之和较少
    2. 是不是你的架构是 3 master 5 worker ?然后有什么策略会让 workloads 优先考虑调度到 worker 。
    hallDrawnel
        16
    hallDrawnel  
       10 天前
    你的 limit 和 request 都没有啊,k8s 不知道怎么调度。再详细学习下这块。
    assassing
        17
    assassing  
       6 天前
    @yanbo92 #9 我的开发环境 K8s 版本 v1.22.3 ,一共三个工作节点,两个节点内存几乎满载,评分 NodeResourcesBalancedAllocation 都是 100 分,另外一个节点评分是 87 。然后两个满载节点 NodeResourcesFit 评分为 0 ,另外一个节点评分是 12 。这个最终合计评分 99 的节点内存使用率和调度率都只有 50%。所有 pod 都有设置一样的内存请求和内存限制。我想不通,于是想要把 NodeResourcesFit 优先级调高,结果只要启动参数加入 --config ,参数 --kubeconfig 就会失效,让人无能狂怒。请问你是怎么做的?
    yanbo92
        18
    yanbo92  
       2 天前
    @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
        19
    assassing  
       2 天前
    @yanbo92 #18 是这样添加参数的。config.yaml 内容有误时,启动会报错,例如使用不支持的 v1 而不是 v1beta3 版本,这样可以确认 config.yaml 文件在启动时被读取了。config.yaml 内容无误时,启动报错,说没有配置 --kubeconfig 参数,token 认证失败。删除 --config 参数又正常启动,这两到底有什么冲突?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   997 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 19:19 · PVG 03:19 · LAX 12:19 · JFK 15:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.