Kubernetes 的自定义 DNS 条目

在集群域或外部使用 CoreDNS 创建自定义 DNS 条目。

如我们在 前一篇文章 中所述,CoreDNS 可在 Kubernetes 集群中用于替代 Kube-DNS 进行服务发现。由于 CoreDNS 架构的灵活性,CoreDNS 能够实现一些有意义的用例。在本篇博客中,我们将演示如何解决一个常见问题 - 为你的服务创建自定义 DNS 条目。

这里有几种不同的可能性

CoreDNS 可以解决所有这些用例。我们从第一种非常常见的情况开始。在这种情况下,你希望能够为给定服务使用相同的名称,无论是在集群内还是外部访问该服务。例如,在使用绑定到该名称的 TLS 证书时,这一点很有用。

假设我们有一个服务,foo.default.svc.cluster.local,它作为 foo.example.com 供外部客户端使用。也就是说,在集群外部进行查找时,foo.example.com 将解析到负载均衡器 VIP - 服务的外部 IP 地址。在集群内部,它将解析为相同的内容,因此在此内部使用此名称将导致流量转发 - 通过外部 IP 从集群外部转出,然后又转入。相反,我们希望它解析为内部 ClusterIP,避免转发。

为在 CoreDNS 中实现此目的,我们将使用 rewrite 插件。此插件可以在将查询向下发送到链中的任何后端进行应答之前修改查询。回想一下在上一篇博客中使用的 Corefile(CoreDNS 配置文件)

.:53 {
    errors
    log
    health
    kubernetes cluster.local 10.0.0.0/24
    forward . /etc/resolv.conf
    cache 30
}

为获得所需的行为,我们只需要添加一条重写规则,将 foo.example.com 映射到 foo.default.svc.cluster.local

.:53 {
    errors
    log
    health
    rewrite name foo.example.com foo.default.svc.cluster.local
    kubernetes cluster.local 10.0.0.0/24
    forward . /etc/resolv.conf
    cache 30
}

通过 kubectl editkubectl apply 将其添加到 ConfigMap 后,我们必须让 CoreDNS 知道 Corefile 已更改。你可以向它发送一个 SIGUSR1 以通知它以正常方式重新加载 - 也就是说,不会中断服务

$ kubectl exec -n kube-system coredns-980047985-g2748 -- kill -SIGUSR1 1

运行我们的测试 pod,我们可以看到该方法有效

$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
If you don't see a command prompt, try pressing enter.
/ # host foo
foo.default.svc.cluster.local has address 10.0.0.72
/ # host foo.example.com
foo.example.com has address 10.0.0.72
/ # host bar.example.com
Host bar.example.com not found: 3(NXDOMAIN)
/ #

这就解决了第一个问题。

第二个问题也一样容易解决。这里,我们只需要能够在与集群所在域不同的区域中提供 DNS 条目。由于 CoreDNS 是一个通用的 DNS 服务器,除了 kubernetes 插件外,还有很多其他方式可以提供区域。为了简便,我们将使用 file 插件和另一个 ConfigMap 条目来满足此用例。但是,你可以使用 etcd 插件将服务直接存储在 etcd 实例中,也可以使用 auto 插件管理一组区域(与 git-sync 一起使用时非常好)。

要创建新的区域,我们需要修改我们一直在使用的 coredns.yaml,以便在 pod 中创建附加文件。为此,我们必须通过向 Corefile 添加 file 行,以及为区域文件添加另一个键 example.db 来编辑 ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        errors
        log
        health
        rewrite name foo.example.com foo.default.svc.cluster.local
        kubernetes cluster.local 10.0.0.0/24
        file /etc/coredns/example.db example.org
        forward . /etc/resolv.conf
        cache 30
    }    
  example.db: |
    ; example.org test file
    example.org.            IN      SOA     sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600
    example.org.            IN      NS      b.iana-servers.net.
    example.org.            IN      NS      a.iana-servers.net.
    example.org.            IN      A       127.0.0.1
    a.b.c.w.example.org.    IN      TXT     "Not a wildcard"
    cname.example.org.      IN      CNAME   www.example.net.

    service.example.org.    IN      SRV     8080 10 10 example.org.    

我们还需要编辑 Pod 模板规范的 volumes 部分

      volumes:
        - name: config-volume
          configMap:
            name: coredns
            items:
            - key: Corefile
              path: Corefile
            - key: example.db
              path: example.db

一旦我们使用 kubectl apply -f 应用此修改,就会创建一个新的 CoreDNS pod,因为卷中的文件是新的。以后对该文件的更改将不需要创建新的 pod,而只需要像之前一样 graceful restart。我们来看一下

$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
If you don't see a command prompt, try pressing enter.
/ # host foo
foo.default.svc.cluster.local has address 10.0.0.72
/ # host foo.example.com
foo.example.com has address 10.0.0.72
/ # host example.org
example.org has address 127.0.0.1
/ #

完美!现在,我们可以编辑该 ConfigMap,并随时发送 SIGUSR1 来添加 example.org 条目。当然,正如前面提到的,我们还可以使用 etcd 后端,避免修改 ConfigMap 和发送信号的麻烦。

这会给我们带来最后一个问题。可以使用 kubernetes 插件中对 fallthrough 的新支持来解决该问题。此功能已添加到最近发布的 CoreDNS 版本 007 中 - 我们将尽快发布另一篇博文,说明如何使用它。

John Belamaric
发表于:并标记为使用 879 个单词的 自定义发现DNS文档kube-dnsKubernetes服务