6. 配置代理并发

Linkerd 数据平面的代理多线程的, 并且能够运行可变数量的工作线程, 以便它们的资源使用与应用程序工作负载相匹配。

当然,在 vacuum(真空) 中,当允许使用尽可能多的 CPU 内核时, 代理将表现出最佳的吞吐量和最低的延迟。 但是,在实践中,还需要考虑其他因素。

真实世界的 deployment 是一个负载测试, 在这个测试中,客户端和服务器除了用请求使代理饱和之外,没有其他工作要做。 相反,服务网格模型将代理实例部署为应用程序容器的 sidecar。 每个代理只处理进出它注入的 pod 的流量。 这意味着吞吐量延迟受应用程序工作负载的限制。 如果应用程序容器实例每秒只能处理这么多请求,那么代理可以处理更多的请求可能并不重要。 事实上,给代理提供比它需要的更多 CPU 核来跟上应用程序可能会损害整体性能, 因为应用程序可能不得不与代理竞争有限的系统资源。

因此,单个代理有效处理其流量比配置所有代理以处理最大可能负载更为重要。 调整代理资源使用的主要方法是限制代理用于转发流量的工作线程数。有多种方法可以做到这一点。

使用 proxy-cpu-limit Annotation

配置代理线程池的最简单方法是使用 config.linkerd.io/proxy-cpu-limit annotation。 此 annotation 配置代理注入器以设置一个环境变量,该变量控制代理将使用的 CPU 核数

使用 linkerd install CLI 命令 安装 Linkerd 时, --proxy-cpu-limit 参数会为 Linkerd 安装注入的所有代理全局设置此 annotation。例如,

linkerd install --proxy-cpu-limit 2 | kubectl apply -f -

对于更细粒度的配置,可以将 annotation 添加到 任何可注入的 Kubernetes 资源,例如 namespacepoddeployment

例如,以下将配置 my-deployment deployment 中的代理使用 1CPU 核

kind: Deployment
apiVersion: apps/v1
metadata:
  name: my-deployment
  # ...
spec:
  template:
    metadata:
      annotations:
        config.linkerd.io/proxy-cpu-limit: '1'
  # ...

使用 Kubernetes CPU 限制与请求

Kubernetes 提供 CPU 限制 和 CPU 请求 来配置分配给任何 pod容器的资源。 这些也可用于配置 Linkerd 代理CPU 使用率。 但是,根据 kubelet 的配置方式, 使用 Kubernetes 资源限制 而不是 proxy-cpu-limit annotation 可能并不理想。

kubelet 使用两种机制之一来强制执行 pod CPU 限制。 这由 --cpu-manager-policy kubelet 选项 决定。 使用默认的 CPU 管理器策略 none, kubelet 使用 CFS 配额 来强制执行 CPU 限制。 这意味着 Linux 内核被配置为限制属于给定进程的线程被调度的时间量。 或者,CPU 管理器策略可以设置为 static。 在这种情况下,kubelet 将使用 Linux cgroup 对满足特定条件的容器实施 CPU 限制。

proxy-cpu-limit annotation 配置的环境变量未设置时, 代理将运行与可用 CPU 核数相等的工作线程数。 这意味着使用默认的 noneCPU 管理器策略,代理可能会产生大量工作线程, 但 Linux 内核会限制它们的调度频率。 这比简单地减少工作线程的数量效率更低,就像 proxy-cpu-limit 所做的那样: 更多的时间花在上下文切换上,每个工作线程的运行频率将降低,这可能会影响延迟

另一方面,使用 cgroup cpusets 将限制进程可用的 CPU 核数。 从本质上讲,代理会认为系统的 CPU 核数比实际少。 这将导致与 proxy-cpu-limit annotation 类似的行为。

但是,值得注意的是,要使用此机制,必须满足某些条件:

  • kubelet 必须配置 static CPU 管理器策略
  • Pod 必须属于有 Guaranteed QoS class。 这意味着 pod 中的所有容器都必须同时具有内存CPUlimitrequest,并且每个的 limit 必须与 request 具有相同的值。
  • CPU limitCPU request 必须是大于或等于 1 的整数。

如果您不确定是否会全部满足这些条件,除了任何 Kubernetes CPU 限制请求之外, 最好使用 proxy-cpu-limit annotation

Using Helm

使用 Helm 时,如果不满足 上述基于 cgroupCPU 限制条件, 用户必须注意设置 proxy.cores Helm 变量和 proxy.cpu.limit 之外的变量。