CoreDNS 插件的最新更改

简介

亚马逊弹性 Kubernetes 服务( 亚马逊 EKS )插件最初于 2021 年 12 月推出。在发布时,他们提供了一种为Amazon EKS集群安装和管理一组精选插件的机制。 CoreDNS 的插件 是我们发布的第一批插件之一,因为 DNS 在 Kubernetes 中起着至关重要的作用。2022 年 12 月增加了 对亚马逊 EKS 插件 的 高级配置支持 后,客户可以将自己的插件配置参数直接传递到亚马逊 EKS 应用程序编程接口 (API)。这允许客户在集群创建期间通过单个步骤安装和配置多个操作插件,例如CoreDNS。该功能是 容器路线图 上最受欢迎的功能之一 ,尤其是Core DNS核心文件的 自定义。

在过去的几个月中,“coredns” 插件进行了重大改进。我们仔细听取了 容器路线图 上的主要问题,实现了所需的功能并解决了这些问题。我们添加了 PodDisruptionBudget (PDB) 等新组件,实现了固执己见的默认设置(例如,使用运行状况插件进行容器运行状况检查),并增强了 JSON 配置架构,允许客户自定义插件的更多参数。

先决条件

要关注这篇博客文章,你需要:

  • 一个 亚马逊云科技 账户
  • 部署了 “coredns” 插件的亚马逊 EKS 集群
  • 亚马逊云科技 命令行界面 (CLI) 的最新版本
  • 与你的 E KS 集群版本兼容的 kubectl 命令行工具

草率排练

问题 #2033 请求在 EKS CoreDNS 插件配置架构上添加 topologySpreadConstraint 设置

版本 v1.9.3-eksbuild.5 将参数 topologySpreadConstraint 添加到插件配置架构中,该架构映射到 K8 的功能 Pod 拓扑分布约束。 您可以使用 拓扑分布约束 来控制 Pod 如何在 Amazon EKS 集群中的故障域(例如可用区、节点和其他用户定义的拓扑域)之间分布。这有助于实现高可用性以及高效的资源利用率。

亚马逊 EKS 插件 API 中的 configurationValues 参数以 JSON 或 YAML blob 的形式接受配置。配置 blob 需要符合底层插件配置 JSON 架构 ,该架构可通过新的 Amazon EKS DescribeAddonConfiguration API 获得。每个插件的 JSON 架构都是唯一的,随着我们实现新的可配置参数,它会随着时间的推移而发展。

使用 亚马逊云科技 命令行接口 (CLI) E KS 子命令 的 describe-addon-config urat ion 选项,我们会收到包含所有设置的插件 JSON 配置架构。我们使用 jq 实用程序来提高输出的可读性。

$ aws eks describe-addon-configuration --addon-name coredns --addon-version v1.10.1-eksbuild.2 \
  --query 'configurationSchema' --output text | jq .
{
  "$ref": "#/definitions/Coredns",
  "$schema": "http://json-schema.org/draft-06/schema#",
  "definitions": {
    "Coredns": {
      "additionalProperties": false,
      "properties": {
        "affinity": {
          "default": {
            "affinity": {
              "nodeAffinity": {
                "requiredDuringSchedulingIgnoredDuringExecution": {
                  "nodeSelectorTerms": [
                    {
                      "matchExpressions": [
                        {
                          "key": "kubernetes.io/os",
                          "operator": "In",
                          "values": [
                            "linux"
                          ]
                        },
                        {
                          "key": "kubernetes.io/arch",
                          "operator": "In",
                          "values": [
                            "amd64",
                            "arm64"
                          ]
                        }
                      ]
                    }
                  ]
                }
              },
…
    "Resources": {
      "additionalProperties": false,
      "properties": {
        "limits": {
          "$ref": "#/definitions/Limits"
        },
        "requests": {
          "$ref": "#/definitions/Limits"
        }
      },
      "title": "Resources",
      "type": "object"
    }
  }
}

下一个命令显示我们如何评估该属性是否存在于 JSON 配置架构中。

$ aws eks describe-addon-configuration --addon-name coredns --addon-version v1.10.1-eksbuild.2 \
  --query 'configurationSchema' --output text | jq . | grep -A3 topologySpreadConstraints
    "topologySpreadConstraints": {
      "description": "The coredns pod topology spread constraints",
      "type": "array"
    }
    
# check coredns deployment - it returns an empty output because it is not set by default 
$ kubectl get deploy -n kube-system coredns -o yaml | grep topologySpreadConstraints

现在让我们创建一个使用 topologyKey 应用拓扑结构的 YAML 博客:topology.kubernetes.io/zone。如果我们的集群仅跨越一个可用区,我们会使用 whenUnSatifable: ScheduleAnyway。

# initial add-on with default configuration
$ aws eks describe-addon --cluster-name demo-cluster-ebs-csi --addon-name coredns
{
    "addon": {
        "addonName": "coredns",
        "clusterName": "demo-cluster-ebs-csi",
        "status": "ACTIVE",
        "addonVersion": "v1.10.1-eksbuild.3",
        "health": {
            "issues": []
        },
        ...
    }
}

# add-on configuration YAML blog
$ cat topologySpreadConstraints.yaml
"topologySpreadConstraints":
  - maxSkew: 1
    topologyKey: topology.kubernetes.io/zone
    whenUnsatisfiable: ScheduleAnyway
    labelSelector:
      matchLabels:
        k8s-app: kube-dns
        
# apply change to add-on
$ 

{
    "update": {
        "id": "5523d967-a62b-37cc-a87c-8a4067919409",
        "status": "InProgress",
        "type": "AddonUpdate",
        "params": [
            {
                "type": "ConfigurationValues",
                "value": "\"topologySpreadConstraints\":\n  - maxSkew: 1\n    topologyKey: topology.kubernetes.io/zone\n    whenUnsatisfiable: ScheduleAnyway\n    labelSelector:\n      matchLabels:\n        k8s-app: kube-dns“
            }
        ],
        "createdAt": "2023-08-31T14:41:29.316000+02:00",
        "errors": []
    }
}

# check add-on configuration to see if it is in ACTIVE status
$ aws eks describe-addon --cluster-name demo-cluster-ebs-csi --addon-name coredns
{
    "addon": {
        "addonName": "coredns",
        "clusterName": "demo-cluster-ebs-csi",
        "status": "ACTIVE",
        "addonVersion": "v1.10.1-eksbuild.3",
        "health": {
            "issues": []
        },
…
        "tags": {},
        "configurationValues": "\"topologySpreadConstraints\":\n  - maxSkew: 1\n    topologyKey: topology.kubernetes.io/zone\n    whenUnsatisfiable: ScheduleAnyway\n    labelSelector:\n      matchLabels:\n        k8s-app: kube-dns“
    }
}

# check coredns deployment
$ kubectl get deploy -n kube-system coredns -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
…
  labels:
    eks.amazonaws.com/component: coredns
    k8s-app: kube-dns
    kubernetes.io/name: CoreDNS
  name: coredns
  namespace: kube-system
…
    spec:
…
      containers:
      - args:
        - -conf
        - /etc/coredns/Corefile
..
        name: coredns
…
      topologySpreadConstraints:
      - labelSelector:
          matchLabels:
            k8s-app: kube-dns
        maxSkew: 1
        topologyKey: topology.kubernetes.io/zone
        whenUnsatisfiable: ScheduleAnyway
…

问题 #1679 要求在 coredns 插件中添加 Pod 干扰预算 (PDB),并已在 v1.9.3-eksbuid.5 及更高版本中实现。

PDB 限制了在节点终止期间同时关闭的复制应用程序的 Pod 的数量,例如带有两个副本 Pod 的 coredns。PDB 使用 “最小可用” 或 “最大不可用”。两者都可以用整数或百分比表示。如果您将 minAvailable 设置为 x 或 x%,则 x 或 x% Pod 必须始终可用,即使在中断期间也是如此。maxUnavailablem指定可以不可用的 Pod 的数量或百分比。

PDB 最初是在 v1.9.3-eksbuild.5 中实现的,该版本的默认值为 minAvailable: 1。从 v1.10.1-eksbuild.2 开始,我们改进了逻辑:如果 coredns 部署有两个或更少的副本,那么我们会将 maxInvailable 设置为 1。否则,我们会将 minAvailable 设置为 2。

# "coredns" add-on v1.9.3-eksbuid.5 and v1.9.3-eksbuid.6
$ kubectl get pdb -n kube-system coredns
NAME    MIN AVAILABLE   MAX UNAVAILABLE  ALLOWED DISRUPTIONS   AGE
coredns 1               N/A              1                    13h

# "coredns" add-on v1.10.1-eksbuild.2 and v1.10.1-eksbuild.3
$ kubectl get pdb -n kube-system coredns
NAME    MIN AVAILABLE   MAX UNAVAILABLE  ALLOWED DISRUPTIONS   AGE
coredns N/A             1                1                     27h

从 v1.9.3-eksbuild.7 和 v1.10.1-eksbuild.4 开始,无论部署副本数量如何,PDB 的默认逻辑都只是 maxUbild.1。我们甚至通过扩展 JSON 配置架构使 PDB 用户可配置,如下所示:

"podDisruptionBudget": {
                  "type": "object",
                  "description": "podDisruptionBudget configurations",
                  "properties": {
                    "enabled": {
                      "type": "boolean",
                      "description": "the option to enable managed PDB",
                      "default": true
                    },
                    "minAvailable": {
                      "description": "minAvailable value for managed PDB, can be either string or integer; if it's string, should end with %",
                      "anyOf": [
                        {
                            "type": "string",
                            "pattern": ".*%$"
                        },
                        {
                            "type": "integer"
                        }
                    ]
                    },
                    "maxUnavailable": {
                      "description": "maxUnavailable value for managed PDB, can be either string or integer; if it's string, should end with %",
                      "anyOf": [
                        {
                            "type": "string",
                            "pattern": ".*%$"
                        },
                        {
                            "type": "integer"
                        }
                    ]
                    }
                  }
                }

现在,用户可以根据需要使用 minAvailable 或 maxUbailable 作为数字或百分比来调整 PDB。

问题 #2026 是要求在 CoreDNS 健康插件中默认添加 lameduck 选项,以最大限度地减少 DNS 解析故障。

lameduck 将关机延迟几秒钟,而生命值端点仍然可以接受 200 的回答。将 lameduck 添加到健康插件可最大限度地减少 CoreDNS 容器重启(即由于运行状况问题、节点终止等)或部署部署期间的 DNS 解析失败。这确实是以增加推出时间为代价的。对于像Amazon EKS这样的高可用性环境,这种权衡可能是可以接受的。

插件版本 v1.9.3-eksbuild.6 和 v1.10.1-eksbuild.3 实现了这种行为。

$ kubectl get configmap -n kube-system coredns -o yaml
apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
            lameduck 5s
          }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        forward . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2023-08-29T11:46:03Z"
  labels:
    eks.amazonaws.com/component: coredns
    k8s-app: kube-dns
  name: coredns
  namespace: kube-system

问题 #941 要求在探测 CoreDNS 就绪状态时使用 /ready 而不是 /health

从 CoreDNS v1.9.3-eksbuild.6 和 v1.10.1-eksbuild.3 开始,我们使用端口 8181 上的 /ready 路径使用 CoreDNS 上游就绪插件更改了 CoreDNS 容器的 ReadinessProbe。 正如上游 就绪插件 文档所解释的那样:

通过在端口 8181 上启用 HTTP 端点,当所有能够发出就绪信号的插件都这样做时,它会返回 200 OK。如果有些插件还没准备好,则端点会返回 503,其正文包含未准备就绪的插件列表。一旦插件发出已准备就绪的信号,就不会再次对其进行查询。

$ kubectl get deploy -n kube-system coredns -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
…
  name: coredns
  namespace: kube-system
…
      containers:
      - args:
        - -conf
        - /etc/coredns/Corefile
…
        name: coredns
…
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /ready
            port: 8181
            scheme: HTTP
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
…
The “ready” plugin is already part of the “coredns” ConfigMap:
$ kubectl get cm -n kube-system coredns -o yaml
apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
            lameduck 5s
          }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        forward . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2023-08-29T11:46:03Z"
  labels:
    eks.amazonaws.com/component: coredns
    k8s-app: kube-dns
  name: coredns
  namespace: kube-system

问题 #1879 要求为 EKS 管理的插件的 pod 设置标签

以 v1.9.3-eksbuild.6 和 v1.10.1-eksbuild.3 开头的 coredns 插件 JSON 配置架构允许添加和更改 pod 标签和注释。Pod 标签使用 podLabels 属性,没有默认值。Pod 注释使用 PodanNotations 属性,并附带上面的 “安全驱逐注释” 部分中提到的请勿驱逐注解。

# pod labels
$ aws eks describe-addon-configuration --addon-name coredns --addon-version v1.10.1-eksbuild.3 \
  --query 'configurationSchema' --output text | jq . | grep -A4 '\"podLabels\"'
        "podLabels": {
          "properties": {},
          "title": "The podLabels Schema",
          "type": "object"
        },

以下示例显示如何添加 pod 标签 foo: bar。在这里你可以看到,使用 YAML blob 和字符串配置值,如果它们不包含特殊字符,则不必使用双引号。

# YAML configuration blob
$ cat podLabels.yaml
podLabels:
  foo: bar
  
# apply changes
$ aws eks update-addon --cluster-name demo-cluster-ebs-csi --addon-name coredns \
  --configuration-values 'file://podLabels.yaml‘
{
    "update": {
        "id": "d49eb115-0edd-3b9f-8938-502f5a2cf54e",
        "status": "InProgress",
        "type": "AddonUpdate",
        "params": [
            {
                "type": "ConfigurationValues",
                "value": "podLabels:\n foo: bar"
            }
        ],
        "createdAt": "2023-09-01T09:08:56.905000+02:00",
        "errors": []
    }
}

# wait a while until the add-on is ACTIVE again
$ aws eks describe-addon --cluster-name demo-cluster-ebs-csi --addon-name coredns
{
    "addon": {
        "addonName": "coredns",
        "clusterName": "demo-cluster-ebs-csi",
        "status": "ACTIVE",
        "addonVersion": "v1.10.1-eksbuild.3",
        "health": {
            "issues": []
        },
...
        "tags": {},
        "configurationValues": "podLabels:\n foo: bar"
    }
}

# check deployment and pods for labels
 $ kubectl get deploy -n kube-system coredns -o yaml
apiVersion: apps/v1
kind: Deployment
...
  template:
    metadata:
      annotations:
        cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
        karpenter.sh/do-not-evict: "true"
      creationTimestamp: null
      labels:
        eks.amazonaws.com/component: coredns
        foo: bar
        k8s-app: kube-dns
        ...
          
$ kubectl get po -n kube-system -l=k8s-app=kube-dns -o custom-columns="POD-NAME":.metadata.name,"POD-LABELS":.metadata.labels
POD-NAME POD-LABELS
coredns-86bb7c8bf5-4rsxm map[eks.amazonaws.com/component:coredns foo:bar k8s-app:kube-dns pod-template-hash:86bb7c8bf5]
coredns-86bb7c8bf5-kj4s6 map[eks.amazonaws.com/component:coredns foo:bar k8s-app:kube-dns pod-template-hash:86bb7c8bf5]

更改插件配置值时的重要注意事项:先前的所有更改都将被覆盖。为了保留之前的配置更改,JSON 和 YAML 配置 blob 需要以合并形式包含所有必需的更改,例如:

# YAML configuration blob
$ cat coredns-conf.yaml
"podLabels":
  "foo": "bar"
"topologySpreadConstraints":
  - maxSkew: 1
    topologyKey: topology.kubernetes.io/zone
    whenUnsatisfiable: ScheduleAnyway
    labelSelector:
      matchLabels:
        k8s-app: kube-dns

要通过 PodanNotations 属性添加 pod 注释,请参阅以下示例:

# YAML configuration blob
$ cat podAnnotations.yaml $ cat podAnnotations.yaml
"podAnnotations":
   my.log-application.com/logs: "true"

# apply changes
$ aws eks update-addon --cluster-name demo-cluster-ebs-csi --addon-name coredns   --configuration-values 'file://podAnnotations.yaml'
{
    "update": {
        "id": "a31834cb-8b62-3568-b6db-a3c580303a41",
        "status": "InProgress",
        "type": "AddonUpdate",
        "params": [
            {
                "type": "ConfigurationValues",
                "value": "\"podAnnotations\":\n   my.log-application.com/logs: \"true\""
            }
        ],
        "createdAt": "2023-09-13T16:26:28.774000+02:00",
        "errors": []
    }
}

# wait a while until the add-on is ACTIVE again
$ aws eks describe-addon --cluster-name demo-cluster-ebs-csi --addon-name coredns
{
    "addon": {
        "addonName": "coredns",
        "clusterName": "demo-cluster-ebs-csi",
        "status": "ACTIVE",
        "addonVersion": "v1.10.1-eksbuild.3",
        "health": {
            "issues": []
        },
        ...
        "tags": {},
        "configurationValues": "\"podAnnotations\":\n my.log-application.com/logs: \"true\""
      
    }
}

# check deployment and pods for annotations
$ kubectl get deploy -n kube-system coredns -o yaml
apiVersion: apps/v1
kind: Deployment
...
  template:
    metadata:
      annotations:
        ...
        my.log-application.com/logs: "true"
        ...
        
$ kubectl get po -n kube-system -l=k8s-app=kube-dns -o custom-columns="POD-NAME":.metadata.name,"POD-ANNOTATIONS":.metadata.annotations
POD-NAME                   POD-ANNOTATIONS
coredns-758ffffbfb-j7kmx   map[my.log-application.com/logs:true]
coredns-758ffffbfb-w2qhg   map[my.log-application.com/logs:true]

呼吁采取行动

通过最近的更改,亚马逊云科技 可以更轻松地使用和自定义 coredns 插件以满足客户需求。使用 亚马逊 Elastic Kubernetes 服务 (EKS) 插件控制台或 亚马逊云科技 命令行接口 (CLI) “aws eks create-addon” 命令试一试。

正在清理

如果您不再需要任何示例资源,请不要忘记删除它们,以避免将来产生费用。

结论

在这篇文章中,我们向您展示了coredns插件中可用的新功能以及如何使用它们。您可以通过在 GitHub 上托管的 亚马逊云科技 容器路线图 上发表评论或打开问题来提供有关 Amazon coredns 插件 的反馈。

请继续关注我们围绕 CoreDNS 不断改进我们的功能。

Jens-Uwe Walther

Jens-Uwe Walther

Jens-Uwe Walther 是亚马逊网络服务容器高级专业技术客户经理,在德国耶拿拥有28年的信息技术专业经验。他对 Kubernetes 充满热情,并帮助客户在亚马逊 EKS 上构建容器解决方案。在业余时间,他喜欢弹吉他、拍照以及和妻子一起去荒野旅行。

Jeremy Cowan

杰里米·考恩

杰里米·考恩是亚马逊云科技的容器专业解决方案架构师,尽管他的家人认为他出售 “云空间”。在加入 亚马逊云科技 之前,Jeremy 曾在多家大型软件供应商工作,包括 VMware、微软和 IBM。当他不工作时,你通常可以在荒野的小路上找到,远离科技。


*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。