你所不了解的 coreDNS

简介: CoreDNS 是一个 DNS 服务器。基于 Go 语言开发。由于其灵活性,可以在多种不同的环境中使用。CoreDNS 已在 Apache 2 许可证版本获得许可,并且完全开源。其已成为 Kubernetes 1.13+ 以后版本的默认 DNS 服务。如今,当我们使用托管 Kubernetes 集群或为应用程序工作负载自行管理集群时,通常只需要关注应用程序本身,而无须过多关注 Kubernetes 提供的服务或如何利用它们。DNS 解析是任何应用程序的基本要求,因此我们需要确保它正常工作。

    CoreDNS 是一个 DNS 服务器。基于 Go 语言开发。由于其灵活性,可以在多种不同的环境中使用。CoreDNS 已在 Apache 2 许可证版本获得许可,并且完全开源。其已成为 Kubernetes 1.13+ 以后版本的默认 DNS 服务。如今,当我们使用托管 Kubernetes 集群或为应用程序工作负载自行管理集群时,通常只需要关注应用程序本身,而无须过多关注 Kubernetes 提供的服务或如何利用它们。DNS 解析是任何应用程序的基本要求,因此我们需要确保它正常工作。

    本文的将不深入探讨 coreDNS,而是解释 DNS 如何在 Kubernetes 中工作,coreDNS 包含什么以及 Corefile 如何使用插件。

    在讨论 coreDNS 之前,我们先来看一下 Kubernetes 是如何在集群中实现 DNS 交互的。假设有一个 Pod,即 Service A 想要与另一个 Pod Service B 进行通信。通常情况下,我们可以通过在 /etc/hosts 文件中将对方的地址信息更新上去来实现这一点,如下图所示。

    但在实际的业务场景中,我们所面临的并不是少量的服务交互。如果我们处理的是每分钟都在创建和销毁的数百个甚至上万个 Pod ,并且 Pod 之间也不停止的互访,那该怎么办?

    在这种情况下,我们不在 /etc/hosts 中创建条目(这不是合适的解决方案),而是将这些条目移动到集中式 DNS 服务器,即 10.10.0.10,如下图所示。现在,我们需要在 Pod 中的某个位置将这个 IP 指定为 nameserver,该位置恰好位于 /etc/resolv.conf 文件中。

    每次创建新 Pod 时,K8s 都会在 DNS 服务器 中更新新加入的 Pod 地址信息,并在新 Pod 的 /etc/resolv.conf 文件中更新相应的条目,当然,这些清单列表指向 DNS 服务器的 IP 地址,如下图所示:

    正如我上面所说,我们将 /etc/hosts 的条目更改为集中式 DNS 服务器。嗯,这是正确的,但有一部分是正确的。DNS 不会像我们在 Pods 中编辑 /etc/hosts 文件那样输入Pods(格式:<pod\u name><IP>)。相反,它通过将 Pod 的 IP 地址中的点替换为破折号来创建新的主机名,如主机名 “10-10-10-1(其格式为:<hostname><IP>)”。详情如下图所示:

    基于上述的解析,我们对 Pod 之间的交互有了简单的认知。然而,在实际的业务场景中,Pod 通过 K8s 集群中的服务进行通信,coreDNS 为这些服务设置记录(默认情况下,Pod 条目被禁用,但我们可以在 coreDNS 的 Ccorefile 中启用它们)。

    虽然 CoreDNS 和 Kube DNS 最终执行相同的任务,但在实现中存在一些影响资源消耗和性能的关键差异。我们可以在 coreDNS 官方文档中详细了解这一点。

    CoreDNS 自 1.9 版开始在 Kubernetes 中可用。它是一个快速灵活的 DNS 服务器。因此,意味着大家可以自由使用 DNS 数据,可以使用一系列插件来使用这些数据。如果某些功能不是现成的,我们可以通过编写插件来实现,毕竟,它是基于 Go 语言写的。

    我们将 CoreDNS 部署为集群中 Kube 系统命名空间中的一个部署对象,该集群中有一个名为 “kube dns” 的服务。它需要一个配置文件,我们将位于 /etc/coredns/corefile 的文件称之为 Corefile。

    其实,从本质上来讲,Corefile 由多种不同的插件组成,其往往主要用于错误处理、报告运行状况、监控指标、缓存等等。

    使 coreDNS 与 Kubernetes 协同工作的插件是 Kubernetes 插件。在 Kubernetes 插件中,设置了 Kubernetes 集群的顶级域(cluster.local)。此外,默认情况下,它会监视新服务。对于 Pod,我们需要通过在集群中创建 “pods Pod Mode” 条目,在 Kubernetes 插件下的 Corefile 中启用 “Pod Mode”。如果创建了一个新对象,它会在 coreDNS 服务器中添加服务记录或 Pod。

    Pods 的下一步是通过在 resolv.conf 文件中指定 nameserver来 指向用于 DNS 解析的 coreDNS IP 地址。但是,应该是什么地址呢?

    其实,我们不需要关心这个,因为 DNS 条目已经由 Kubelet 组件处理。

    当我们在集群中安装 coreDNS 时,我们将其作为服务公开,因此 Kubelet 将该服务的 IP 地址配置为 Pods 中的名称服务器。

    现在我们的问题是 Kubelet 是如何知道这一点的?

    当然,我们可以在 Kubelet 配置文件中看到 coreDNS 服务器的条目,如上图所示。

除此之外,我们还可以配置 Kubelet 并作为服务运行,并在该服务文件中传递 ClusterDns IP 信息。

    我们基于 Minikube 工具,来进行简要的阐述,其相关操作如下:


[administrator@JavaLangOutOfMemory ~] % minikube ssh
[administrator@JavaLangOutOfMemory ~] % cat /var/lib/kubelet/config.yaml

    我们来看一下完整的 config.yaml 文件信息,具体如下所示:


[administrator@JavaLangOutOfMemory ~] % cat /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
  anonymous:
    enabled: false
  webhook:
    cacheTTL: 0S
    enabled: true
  x509:
    clientCAFile: /var/lib/minikube/certs/ca.crt
authorization:
  mode: Webhook
  webhook:
    cacheAuthorizedTTL: 0S
    cacheUnAuthorizedTTL: 0S
clusterDNS:
- 10.10.0.10
clusterDomain: cluster.local
cpuManagerReconcilePeriod: 0s
evictionPressureTransitionPeriod: 0s
fileCheckFrequency: 0s
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 0s
imageMinimunGCAge: 0s
kind: KubeletConfiguration
nodeStatusReportFrequency: 0s
nodeStatusUpdateFrequency: 0s
rotateCertificates: ture
runtimeRequestTimeout: 0s
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 0s
syncFrequency: 0s
volumeStatsAggPeriod: 0s

    然而,在我们实际的项目中,很多企业仍未使用托管 Kubernetes 服务,因此,在此我将讨论自建的 Kubernetes 集群,我们可以通过对任何 K8s 节点执行 ssh 来检查 Kubelet 服务中的 clusterDns 条目。下面是我们在 K8s 集群中使用的服务文件,如下所示:


[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service
[Service]
ExecStart=/usr/bin/kubelet \
  --allow-privileged=true \
  --cloud-provider= \
  --cluster-dns=10.10.0.10  \
  --cluster-domain=cluster.local \
  --container-runtime=docker \
  --docker-endpoint=unix:///var/run/docker.sock \
  --network-plugin=cni \
  --cni-bin-dir=/opt/cni/bin \
  --cni-conf-dir=/etc/cni/net.d \
  --kubeconfig=/var/lib/kubelet/kubeconfig \
  --serialize-image-pulls=true \
  --tls-cert-file=/var/lib/kubernetes/kubernetes.pem \
  --tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \
  --system-reserved=memory=19227Mi \
  --fail-swap-on=true \
  --runtime-cgroups=/systemd/system.slice \
  --kubelet-cgroups=/systemd/system.slice \
  --pod-infra-container-image=<dockerregistry/imagename:tag \
  --log-dir=/var/log/kubernetes \
  --logtostderr=false \
  --v=2
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target

    接下来,我们再来看一下 Kubernetes DNS 记录的相关内容情况,具体如下所示。基于其格式规范:

    对于服务:svcname.namespace.type.rootDomain

    对于 Pod:hostname.namespace.type.rootDomain

    这里,我们举个简单的例子,如下所示:

    对于服务:test-service.default.svc.cluster.local

    对于 Pod:  10-10-10-1.default.pod.cluster.local

    在 Corefile 中,我们在集群中将 Corefile 作为配置映射传递,以便它与 coreDNS 的部署对象保持解耦我们可以在 “https://coredns.io/plugins/kubernetes/” 获得插件链列表。


.:53 {
        errors
        log
        health {
           lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
    }

    让我们再来看下 Kubernetes 插件,基于 Kubernetes 插件,CoreDNS 将会从 Kubernetes 集群中读取区域数据。它实现了为 Kubernetes 基于 DNS 的服务发现定义的规范。其格式为以下:


Kubernetes ZONE {
pods POD-MODE
           fallthrough ZONE
           ttl time_in_sec

    Kubernetes Plugin 块示例,具体可参考如下所示:


kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30

    在 Kubernetes 插件中,我们可以在 https://coredns.io/plugins/kubernetes/查看更多的选项以供选择。

    让我们再简要解析一下在上面的 Corefile 文件中核心参数含义及使用规范,具体如下所示:

    pods POD-MODE:设置处理基于 IP 的 Pod A 记录的模式,例如10-10-10-1.default.POD.cluster.local。在 A 10.10.10.1中,提供此选项是为了在直接连接到 Pod 时方便使用 SSL 证书。

    insecure:我们所使用的 Pod 模式的值,其往往会返回一个 Pod 记录。

    fallthrough[ZONES…]:如果插件授权的区域中的查询返回结果,或者返回查询的NXDOMAIN。当 DNS 没有所请求域的列表时,将创建 NXDOMAIN 响应。如果启用了 fallthrough,则插件不会在未找到记录时返回 NXDOMAIN ,而是将请求向下传递到插件链,该插件链可以包含另一个插件来处理查询。

    ttl:允许我们为响应设置自定义 ttl 。默认值为 5 秒。允许的最小 TTL 为 0 秒,最大 TTL 为 3600 秒。将 TTL 设置为 0 将阻止缓存记录。

    综上所述,我们阐述了 DNS 是如何在 Kubernetes 中发挥重要作用的。coreDNS 通过利用 Kubernetes 插件与 Kubernetes 进行协作。基于各种插件组合,我们可以根据自己的实际业务场景进行定制。基于上述所述,使得大家能够尽可能去接触到 coreDNS 世界奥妙,以助于大家在云原生生态中能够稳健翱翔。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
缓存 Prometheus Kubernetes
kubernetes 【网络组件】coredns【1】配置使用详解
kubernetes 【网络组件】coredns【1】配置使用详解
kubernetes 【网络组件】coredns【1】配置使用详解
|
Kubernetes API 调度
容器编排工具有哪些
容器编排工具有哪些
|
Prometheus Kubernetes 网络协议
k8s学习笔记之CoreDNS
k8s学习笔记之CoreDNS
|
存储 安全 Linux
Podman入门全指南:安装、配置与运行容器
Podman入门全指南:安装、配置与运行容器
7167 1
|
存储 监控 NoSQL
Redis中的LRU淘汰策略深入解析
Redis的内存管理关键在于处理数据增长与有限内存的矛盾,LRU策略被广泛用于此。LRU基于“不常访问的数据未来访问可能性小”的假设,淘汰最近最少使用的数据。Redis通过双向链表实现,但并非严格LRU,而是采样算法以平衡性能和精度。用户可通过调整`maxmemory-samples`等参数优化。尽管LRU简单高效,但无法区分数据重要性和访问频率,可能误淘汰重要数据。合理设置参数、结合其他策略、监控调优是优化LRU使用的关键。
336 1
|
存储 Shell Docker
docker 部署单节点的etcd以及 常用使用命令
在 Docker 中部署单节点的 etcd 以及一些常用命令的操作,可以按照以下步骤进行: ## 一、部署单节点 etcd 1. **拉取 etcd Docker 镜像**:您可以从 Docker Hub 拉取 etcd 的官方镜像。 ```shell docker pull quay.io/coreos/etcd:latest ``` 2. **启动 etcd 容器**:使用 `docker run` 命令来启动 etcd 容器。以下是一个示例命令,其中将容器的 2379 端口映射到主机的 2379 端口: ```shell docker run -d \
1689 1
|
存储 Kubernetes 应用服务中间件
k8s-配置与存储-持久化存储-NFS 挂载、StorageClass 存储类 动态创建NFS-PV案例
k8s-配置与存储-持久化存储-NFS 挂载、StorageClass 存储类 动态创建NFS-PV案例
945 0
|
SpringCloudAlibaba Dubbo 前端开发
【三】SpringCloud Alibaba之Nacos整合篇(作为配置中心)
【三】SpringCloud Alibaba之Nacos整合篇(作为配置中心)
861 0
|
Kubernetes Cloud Native 网络协议
云原生|kubernetes部署和运行维护中的错误汇总(不定时更新)
云原生|kubernetes部署和运行维护中的错误汇总(不定时更新)
3037 0
|
Kubernetes 数据安全/隐私保护 Docker
云原生|kubernetes|关于secret的一些使用
云原生|kubernetes|关于secret的一些使用
356 0