关于容器:Koordinator-最佳实践系列精细化-CPU-编排

2次阅读

共计 5903 个字符,预计需要花费 15 分钟才能阅读完成。

介绍

在云原生环境中,集群提供者经常将不同类型的工作负载部署在同一个集群中,利用不同业务的不同峰值成果,实现资源分时复用,防止资源节约。然而,不同类型负载之间混合部署经常会导致资源竞争和互相烦扰。最为典型的场景便是在线和离线负载的混合部署。当离线较多的占用计算资源时,在线负载的响应工夫就会受到影响;当在线长时间较多的占用计算资源时,离线负载的工作实现工夫不能失去保障。这种景象属于 Noisy Neighbor 问题。

依据混合部署的水平、资源类型的不同,解决该问题有许多不同的思路。Quota 治理可从整个集群维度限度负载的资源使用量,Koordinator 在这方面提供了多层次弹性 Quota 治理性能 [1]。单机维度上看,CPU、内存、磁盘 IO,网络资源都有可能被不同负载共享。Koordinator 在 CPU、内存上曾经提供了一些资源隔离和保障的能力,磁盘 IO 和网络资源方面的相干能力正在建设中。

本文次要介绍当不同类型工作负载混合部署在同一个节点上时,Koordinator 如何帮忙负载之间(在线和在线、在线和离线)协同地共享 CPU 资源。

问题形容

CPU 资源 Noisy Neighbor 的实质是不同的负载之间无协同地共享 CPU 资源。

  1. Kubernetes 默认的资源模型利用 cgroup(cfs quota)从 CPU 工夫使用量上来限度不同负载对于 CPU 资源的拜访。这种状况下,一些负载就可能会被操作系统调度器切换所在的 CPU 核。因为不同 CPU 核查不同物理地位的内存拜访工夫不同,切换大概率会导致更长的内存拜访工夫,从而影响负载性能。
  2. 在 NUMA 架构中,SMT 线程(逻辑核)共享物理核的执行单元和 L2 缓存。当同一个物理核中有多种工作负载时,不同工作负载间就会产生资源争抢,导致负载性能降落。

Kubernetes 在单机侧提供了拓扑管理器和 CPU 管理器来尝试解决上述问题。然而,该性能只有在 Pod 曾经调度到机器上之后才会尝试失效。这样就有可能导致 Pod 会被调度到 CPU 资源满足然而 CPU 拓扑不满足负载要求的状况。

解决方案

面向利用的 CPU 编排 QoS 语义

针对上述问题和有余,Koordinator 设计了面向利用的 QoS 语义和 CPU 编排协定,如下图所示。

LS(Latency Sensitive)利用于典型的微服务负载,Koordinator 将其与其它的提早敏感型负载隔离保障其性能。LSR(Latency Sensitive Reserved)相似于 Kubernetes 的 Guaranteed,在 LS 的根底上减少了利用要求预留绑核的语义。LSE(Latency Sensitive Exclusive)则常见于中间件等对 CPU 特地敏感的利用,Koordinator 除了满足其相似于 LSR 要求绑核的语义外,还确保其所被调配的 CPU 不与任何其它负载共享。

另外,为进步资源利用率,BE 负载可与 LSR 和 LS 共享 CPU。为了确保与 BE 共享的提早敏感型利用不受其烦扰,Koordinator 提供了如烦扰检测、BE 压抑等策略。本文重点不在此,读者可关注后续文章。

丰盛的 CPU 编排策略

对于 LSE 类型的利用,当机器是超线程架构时,只能保障负载独占逻辑核。这样当同一个物理核中有其它负载时,利用性能仍会受烦扰。为此,Koordinator 反对用户在 Pod Annotation 上配置丰盛的 CPU 编排策略来进步性能。

CPU 编排策略分为 CPU 绑定策略和 CPU 独占策略。CPU 绑定策略决定利用所被调配逻辑核在物理核间的散布,可采纳物理核间打散或者重叠。重叠(FullPCPU)的形式指为利用调配残缺的物理内核,能够无效地缓解 Noisy Neighbor 问题。打散(SpreadByPCPU)则次要利用于一些具备多种不同峰谷个性的提早敏感型利用,能够让应用程序在特定工夫充沛应用 CPU。CPU 独占策略决定利用所被调配逻辑核的独占级别,可尽量避开曾经同独占策略申请的物理核或 NUMANode。

加强的 CPU 调度能力

Koordinator 反对配置 NUMA 的调配策略,决定在调度时如何抉择称心的 NUMA 节点。MostAllocated 示意从可用资源起码的 NUMA 节点调配,能够尽可能减少碎片,为后续的负载留下更大的调配空间。然而,这种形式可能会导致依赖 Barrier 的并行代码性能收到影响。DistributeEvenly 示意在 NUMA 节点上平均分配 CPU,能够进步上述并行代码的性能。LeastAllocated 示意从可用资源最多的 NUMA 节点调配。

另外,Koordinator 对 CPU 的调配逻辑是在核心调度器实现的。这样就会有一个全局的视角,防止了 Kubernetes 单机计划可能导致的 CPU 资源量满足然而拓扑不满足的困境。

最佳实际

由上文可知,Koordinator 精细化 CPU 编排能力可能显著进步多利用混合部署场景下 CPU 敏感型工作负载的性能。为了让读者可能更分明地应用和直观感触 Koordinator 的精细化 CPU 编排能力,本文将在线利用采纳不同形式部署到集群中,察看压测中服务的提早,来判断 CPU 编排能力的成果。

本文会在同一个机器上部署多个在线利用,压测 10 分钟,以充沛模仿生产实践中可能呈现的 CPU 核切换场景。对于在线利用和离线利用混合部署的状况,Koordinator 提供了如烦扰检测、BE 压抑等策略。本文重点不在此,读者可关注后续文章中的实际。

本次试验采纳以下指标,评估利用不同部署形式下 Nginx 利用的性能体现:

  • 响应工夫 RT(Response Time)分位值 RT 是在线利用通常关注的性能指标,RT 越低代表在线服务性能越好。RT 指标通过收集 wrk 压测完结后打印的信息取得,在试验中反映了 Nginx 利用响应 wrk 申请所破费的工夫。例如 RT-p50 示意 Nginx 响应前 50% wrk 申请最大所破费的工夫(中位数),RT-p90 示意 Nginx 响应前 90% wrk 申请最大所破费的工夫。
  • 每秒申请数 RPS(Request Per Second)RPS 是在线利用每秒服务的申请数量,服务接受的 RPS 越多代表在线服务的性能越好。

试验后果如下:

  • 比照 B 和 A,能够发现采纳 LSE QoS 绑核之后,服务响应工夫 P99 显著减小,很好地加重了长尾景象
  • 比照 C 和 B,能够发现采纳 LSR QoS 绑核且容许逻辑核占用更多物理核资源之后,在服务响应工夫更好的状况下能够接受更多的申请

综上,在线服务部署在同一机器的场景下,采纳 koordinator 精细化 CPU 编排可能无效克制 Noisy Neighbor 问题,缩小 CPU 核切换带来的性能降落。

环境

首先,要先筹备一个 Kubernetes 集群并装置 Koordinator[2]。本文抉择一个 Kubernetes 集群的两个节点来做试验,其中一个节点作为测试机,将运行 Nginx 在线服务器;另一节点作为压测机,将运行客户端的 wrk,向 Nginx 申请 Web 服务,制作压测申请。

在线利用

1. 应用 ColocationProfile[3] 为利用注入精细化 CPU 编排协定

B 组精细化 CPU 编排协定:

apiVersion: config.koordinator.sh/v1alpha1
kind: ClusterColocationProfile
metadata:
  name: colocation-profile-example
spec:
  selector:
    matchLabels:
      app: nginx
  # 采纳 LSE QoS
  qosClass: LSE
  annotations:
  # 采纳物理核间重叠
    scheduling.koordinator.sh/resource-spec: '{"preferredCPUBindPolicy":"FullPCPUs"}'
  priorityClassName: koord-prod

C 组 CPU 精细化编排协定:

apiVersion: config.koordinator.sh/v1alpha1
kind: ClusterColocationProfile
metadata:
  name: colocation-profile-example
spec:
  selector:
    matchLabels:
      app: nginx
  # 采纳 LSR QoS
  qosClass: LSR
  annotations:
  # 采纳物理核间打散且独占物理核
    scheduling.koordinator.sh/resource-spec: '{"preferredCPUBindPolicy":"SpreadByPCPUs","preferredCPUExclusivePolicy":"PCPULevel"}'
  priorityClassName: koord-prod

2. 在线服务本文选用 Nginx 在线服务器,Pod YAML 如下:

---
# nginx 利用配置
apiVersion: v1
data:
  config: |-
    user  nginx;
    worker_processes  4; # Nginx 的 Worker 个数,影响 Nginx Server 的并发。events {worker_connections  1024;  # 默认值为 1024。}

    http {
        server {
            listen  8000;

            gzip off;
            gzip_min_length 32;
            gzip_http_version 1.0;
            gzip_comp_level 3;
            gzip_types *;
        }
    }

    #daemon off;
kind: ConfigMap
metadata:
  name: nginx-conf-0
---
# Nginx 实例,作为在线类型服务利用。apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx
  name: nginx-0
  namespace: default
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - "${node_name}"    
  schedulerName: koord-scheduler
  priorityClassName: koord-prod
  containers:
    - image: 'koordinatorsh/nginx:v1.18-koord-exmaple'
      imagePullPolicy: IfNotPresent
      name: nginx
      ports:
        - containerPort: 8000
          hostPort: 8000 # 压测申请拜访的端口。protocol: TCP
      resources:
        limits:
          cpu: '4'
          memory: 8Gi
        requests:
          cpu: '4'
          memory: 8Gi
      volumeMounts:
        - mountPath: /apps/nginx/conf
          name: config
  hostNetwork: true
  restartPolicy: Never
  volumes:
    - configMap:
        items:
          - key: config
            path: nginx.conf
        name: nginx-conf-0
      name: config

3. 执行以下命令,部署 Nginx 利用

kubectl apply -f nginx-0.yaml

4. 执行以下命令,查看 Nginx 利用的 Pod 状态

kubectl get pod -l app=nginx -o wide

能够看到输入如下,示意 Nginx 利用曾经在测试机上失常运行

NAME      READY   STATUS    RESTARTS   AGE     IP           NODE                    NOMINATED NODE   READINESS GATES
nginx-0   1/1     Running   0          2m46s   10.0.0.246   cn-beijing.10.0.0.246   <none>           <none>

5. 在压测机上,执行以下命令,部署压测工具 wrk

wget -O wrk-4.2.0.tar.gz https://github.com/wg/wrk/archive/refs/tags/4.2.0.tar.gz && tar -xvf wrk-4.2.0.tar.gz
cd wrk-4.2.0 && make && chmod +x ./wrk

压测

1. 应用压测工具 wrk,向 Nginx 利用发动压测申请。

# node_ip 填写测试机的 IP 地址,用于 wrk 向测试机发动压测;8000 是 Nginx 裸露到测试机的端口。taskset -c 32-45 ./wrk -t120 -c400 -d600s --latency http://${node_ip}:8000/

2. 期待 wrk 运行完结后,获取 wrk 的压测后果,wrk 输入格局如下所示。反复屡次测试,以取得绝对稳固的后果。

Running 10m test @ http://192.168.0.186:8000/
  120 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     3.29ms    2.49ms 352.52ms   91.07%
    Req/Sec     0.96k   321.04     3.28k    62.00%
  Latency Distribution
     50%    2.60ms
     75%    3.94ms
     90%    5.55ms
     99%   12.40ms
  68800242 requests in 10.00m, 54.46GB read
Requests/sec: 114648.19
Transfer/sec:     92.93MB

总结

在 Kubernetes 集群中,不同业务负载之间可能存在 CPU、内存等资源的争抢,影响业务的性能和稳定性。面对 Noisy Neighbor 景象,用户能够应用 Koordinator 为利用配置更精密的 CPU 编排策略,使得不同利用能够协同的共享 CPU 资源。咱们通过试验阐明,Koordinator 的精细化 CPU 编排能力能无效克制 CPU 资源的争抢,改善利用性能。

相干链接:

[1] 多层次弹性 Quota 治理性能

https://koordinator.sh/docs/user-manuals/multi-hierarchy-elas…

[2] 装置 Koordinator

https://koordinator.sh/docs/installation/

[3] ColocationProfile

https://koordinator.sh/docs/user-manuals/colocation-profile/

作者:乔普、申信

点击立刻收费试用云产品 开启云上实际之旅!

原文链接

本文为阿里云原创内容,未经容许不得转载。

正文完
 0