在集群中自动扩缩 DNS 服务

本页介绍了如何在 Kubernetes 集群中启用和配置 DNS 服务的自动扩缩。

开始之前

  • 你需要有一个 Kubernetes 集群,并且必须配置 kubectl 命令行工具,以便与集群通信。建议在本教程中使用至少有两个节点,且不作为控制平面主机的集群。如果尚未拥有集群,则可以使用 minikube 创建一个,或者使用以下 Kubernetes 演练场之一

    要查看版本,请输入 kubectl version

  • 本指南假定你的节点使用 AMD64 或 Intel 64 CPU 架构。

  • 确保 Kubernetes DNS 已启用。

确定 DNS 水平自动扩缩是否已启用

在 kube-system 命名空间中列出集群中的 Deployment

kubectl get deployment --namespace=kube-system

输出类似于:

NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
...
kube-dns-autoscaler    1/1     1            1           ...
...

如果在输出中看到 "kube-dns-autoscaler",则表示 DNS 水平自动扩缩已启用,你可以跳到调整自动扩缩参数

获取 DNS Deployment 的名称

在 kube-system 命名空间中列出集群中的 DNS Deployment

kubectl get deployment -l k8s-app=kube-dns --namespace=kube-system

输出类似于:

NAME      READY   UP-TO-DATE   AVAILABLE   AGE
...
coredns   2/2     2            2           ...
...

如果没有看到 DNS 服务的 Deployment,也可以按名称查找它

kubectl get deployment --namespace=kube-system

并查找名为 corednskube-dns 的 Deployment。

你的扩缩目标是

Deployment/<your-deployment-name>

其中 <your-deployment-name> 是你的 DNS Deployment 的名称。例如,如果 DNS 的 Deployment 名称是 coredns,则扩缩目标是 Deployment/coredns。

启用 DNS 水平自动扩缩

本节中,你将创建一个新的 Deployment。该 Deployment 中的 Pod 基于 cluster-proportional-autoscaler-amd64 镜像运行容器。

创建一个名为 dns-horizontal-autoscaler.yaml 的文件,其内容如下:

kind: ServiceAccount
apiVersion: v1
metadata:
  name: kube-dns-autoscaler
  namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: system:kube-dns-autoscaler
rules:
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["list", "watch"]
  - apiGroups: [""]
    resources: ["replicationcontrollers/scale"]
    verbs: ["get", "update"]
  - apiGroups: ["apps"]
    resources: ["deployments/scale", "replicasets/scale"]
    verbs: ["get", "update"]
# Remove the configmaps rule once below issue is fixed:
# kubernetes-incubator/cluster-proportional-autoscaler#16
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "create"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: system:kube-dns-autoscaler
subjects:
  - kind: ServiceAccount
    name: kube-dns-autoscaler
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: system:kube-dns-autoscaler
  apiGroup: rbac.authorization.k8s.io

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kube-dns-autoscaler
  namespace: kube-system
  labels:
    k8s-app: kube-dns-autoscaler
    kubernetes.io/cluster-service: "true"
spec:
  selector:
    matchLabels:
      k8s-app: kube-dns-autoscaler
  template:
    metadata:
      labels:
        k8s-app: kube-dns-autoscaler
    spec:
      priorityClassName: system-cluster-critical
      securityContext:
        seccompProfile:
          type: RuntimeDefault
        supplementalGroups: [ 65534 ]
        fsGroup: 65534
      nodeSelector:
        kubernetes.io/os: linux
      containers:
      - name: autoscaler
        image: registry.k8s.io/cpa/cluster-proportional-autoscaler:1.8.4
        resources:
            requests:
                cpu: "20m"
                memory: "10Mi"
        command:
          - /cluster-proportional-autoscaler
          - --namespace=kube-system
          - --configmap=kube-dns-autoscaler
          # Should keep target in sync with cluster/addons/dns/kube-dns.yaml.base
          - --target=<SCALE_TARGET>
          # When cluster is using large nodes(with more cores), "coresPerReplica" should dominate.
          # If using small nodes, "nodesPerReplica" should dominate.
          - --default-params={"linear":{"coresPerReplica":256,"nodesPerReplica":16,"preventSinglePointFailure":true,"includeUnschedulableNodes":true}}
          - --logtostderr=true
          - --v=2
      tolerations:
      - key: "CriticalAddonsOnly"
        operator: "Exists"
      serviceAccountName: kube-dns-autoscaler

在文件中,将 <SCALE_TARGET> 替换为你的扩缩目标。

进入包含配置文件的目录,然后输入此命令创建 Deployment

kubectl apply -f dns-horizontal-autoscaler.yaml

成功命令的输出是

deployment.apps/kube-dns-autoscaler created

DNS 水平自动扩缩现已启用。

调整 DNS 自动扩缩参数

验证 kube-dns-autoscaler ConfigMap 是否存在

kubectl get configmap --namespace=kube-system

输出类似于:

NAME                  DATA      AGE
...
kube-dns-autoscaler   1         ...
...

修改 ConfigMap 中的数据

kubectl edit configmap kube-dns-autoscaler --namespace=kube-system

查找此行:

linear: '{"coresPerReplica":256,"min":1,"nodesPerReplica":16}'

根据你的需要修改字段。"min" 字段表示 DNS 后端的最少数量。实际的后端数量使用以下公式计算:

replicas = max( ceil( cores × 1/coresPerReplica ) , ceil( nodes × 1/nodesPerReplica ) )

请注意,coresPerReplicanodesPerReplica 的值都是浮点数。

其思想是,当集群使用拥有许多核心的节点时,coresPerReplica 起主导作用。当集群使用核心较少的节点时,nodesPerReplica 起主导作用。

还有其他支持的扩缩模式。有关详细信息,请参见 cluster-proportional-autoscaler

禁用 DNS 水平自动扩缩

有几种调整 DNS 水平自动扩缩的选项。使用哪个选项取决于不同的情况。

选项 1:将 kube-dns-autoscaler Deployment 扩缩到 0 个副本

此选项适用于所有情况。输入此命令:

kubectl scale deployment --replicas=0 kube-dns-autoscaler --namespace=kube-system

输出是

deployment.apps/kube-dns-autoscaler scaled

验证副本数为零

kubectl get rs --namespace=kube-system

输出在 DESIRED 和 CURRENT 列中显示 0

NAME                                  DESIRED   CURRENT   READY   AGE
...
kube-dns-autoscaler-6b59789fc8        0         0         0       ...
...

选项 2:删除 kube-dns-autoscaler Deployment

如果 kube-dns-autoscaler 在你自己的控制之下,此选项有效,这意味着没有人会重新创建它

kubectl delete deployment kube-dns-autoscaler --namespace=kube-system

输出是

deployment.apps "kube-dns-autoscaler" deleted

选项 3:从主节点删除 kube-dns-autoscaler 清单文件

如果 kube-dns-autoscaler 在(已弃用的)Addon Manager 控制之下,并且你有主节点的写入权限,此选项有效。

登录到主节点并删除相应的清单文件。此 kube-dns-autoscaler 的常见路径是:

/etc/kubernetes/addons/dns-horizontal-autoscaler/dns-horizontal-autoscaler.yaml

清单文件删除后,Addon Manager 将删除 kube-dns-autoscaler Deployment。

理解 DNS 水平自动扩缩的工作原理

  • cluster-proportional-autoscaler 应用与 DNS 服务分开部署。

  • 自动扩缩器 Pod 运行一个客户端,该客户端轮询 Kubernetes API 服务器以获取集群中的节点和核心数量。

  • 根据当前可调度的节点和核心以及给定的扩缩参数,计算出所需的副本数量并应用于 DNS 后端。

  • 通过 ConfigMap 向自动扩缩器提供扩缩参数和数据点,它在每个轮询间隔刷新其参数表,以与最新的所需扩缩参数保持同步。

  • 对扩缩参数的更改无需重建或重新启动自动扩缩器 Pod 即可生效。

  • 自动扩缩器提供控制器接口以支持两种控制模式:线性阶梯

接下来

最后修改于太平洋标准时间 2024 年 1 月 25 日下午 3:51:修复 dns-horizontal-autoscaling 页面中的 Deployment 和 ConfigMap 名称 (7e2f696572)