本文介绍: CoreDNS作为现阶段k8s默认DNS服务以及服务发现的重要一环,其内置kubernetes插件可谓是举足轻重。本文主要讲解介绍CoreDNS内置核心插件kubernetes使用方式和适用场景。CoreDNS的kubernetes插件的具体实现遵循k8s官方提供的标准指南,这也是它能够替代kubedns成为kubebernetes中默认的DNS的重要原因

CoreDNS作为现阶段k8s的默认DNS服务以及服务发现的重要一环,其内置kubernetes插件可谓是举足轻重。本文主要讲解介绍CoreDNS内置核心插件kubernetes使用方式和适用场景

CoreDNS的kubernetes插件的具体实现遵循k8s官方提供的标准指南Kubernetes DNS-Based Service Discovery Specification,这也是它能够替代kubedns成为kubebernetes中默认的DNS的重要原因

虽然 Kubernetes 中的服务发现可以通过其他协议机制提供(如consul等服务注册发现中心),但DNS是非常常用的一种协议,同时考虑到K8S中的东西流量互访主要也是通过域名实现,因此K8S官方非常推荐使用DNS插件实现K8S中的服务发现

This document is a specification for DNS-based Kubernetes service discovery. While service discovery in Kubernetes may be provided via other protocols and mechanisms, DNS is very commonly used and is a highly recommended addon. The actual DNS service itself need not be provided by the default Kube-DNS implementation. This document is intended to provide a baseline for commonality between implementations.

在开始介绍kubernetes插件之前,我们需要先了解一些K8S中的基础DNS知识

1 K8S中的DNS服务

众所周知,在K8S中,IP是随时会发生变化的,变化最频繁的就是Pod IPCluster IP也并不是一定不会发生变化,EXTERNAL-IP虽然可以手动指定静态IP保持不变,但是主要面向的是集群外部的服务;因此在K8S集群中,最好的服务之间相互访问方式就是通过域名

1.1 DNS创建规则

在K8S集群中,Kubernetes 为 Service 和 Pod 创建 DNS 记录

前面我们介绍了K8S中的每个SVC都会有一个对应域名,域名的组成格式$service_name.$namespace_name.svc.$cluster_name,同时也会给这个SVC下的所有Pod都创建一个$pod_name.$service_name.$namespace_name.svc.$cluster_name的这种域名,这个域名的解析结果就是Pod IP。

Pod域名有两个比较明显的特征

1.2 DNS策略配置

DNS 策略可以逐个 Pod 来设定。目前 Kubernetes 支持以下特定 Pod 的 DNS 策略。 这些策略可以在 Pod 规约中的 dnsPolicy 字段设置

说明 下面主要介绍ClusterFirst模式

1.3 DNS解析规则

DNS 查询参照 Pod 中的 /etc/resolv.conf 配置,kubelet 会为每个 Pod 生成文件。因此在每个pod里面都有一个类似下面这样的 /etc/resolv.conf文件通过修改其中的配置可以更改DNS的查询规则

 nameserver 10.32.0.10
 search <namespace&gt;.svc.cluster.local svc.cluster.local cluster.local
 options ndots:5

这里的配置有几个需要注意的点:

这是一个比较通用的案例我们再来看一个比较特殊的配置

 # 首先进入一个pod查看里面的DNS解析配置
 [root@tiny-calico-master-88-1 tiny-calico]# kubectl exec -it -n ngx-system ngx-ex-deploy-6bf6c99d95-5qh2w /bin/bash
 kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
 [root@ngx-ex-deploy-6bf6c99d95-5qh2w /]# cat /etc/resolv.conf
 nameserver 10.88.0.10
 search ngx-system.svc.cali-cluster.tclocal svc.cali-cluster.tclocal cali-cluster.tclocal k8s.tcinternal
 options ndots:5
 [root@ngx-ex-deploy-6bf6c99d95-5qh2w /]# exit

这个pod里面/etc/resolv.conf配置文件有两个和前面不同的地方:

 # 再查看K8S集群中的coredns的configmap 
 [root@tiny-calico-master-88-1 tiny-calico]# kubectl get configmaps -n kube-system coredns -oyaml
 apiVersion: v1
 data:
   Corefile: |
     .:53 {
         errors
         health {
            lameduck 5s
         }
         ready
         kubernetes cali-cluster.tclocal in-addr.arpa ip6.arpa {
            pods insecure
            fallthrough in-addr.arpa ip6.arpa
            ttl 30
         }
         prometheus :9153
         forward . 10.31.100.100 {
            max_concurrent 1000
         }
         cache 30
         loop
         reload
         loadbalance
     }
 kind: ConfigMap
 metadata:
   creationTimestamp: "2022-05-06T05:19:08Z"
   name: coredns
   namespace: kube-system
   resourceVersion: "3986029"
   uid: 54f5f803-a5ab-4c77-b149-f02229bcad0a
 # 最后查看宿主机节点上面的DNS解析配置
 [root@tiny-calico-master-88-1 tiny-calico]# cat /etc/resolv.conf
 # Generated by NetworkManager
 search k8s.tcinternal
 nameserver 10.31.254.253

1.4 DNS解析流程

温馨提示阅读部分内容时候要特别注意域名结尾是否一个点
.

当ndots小于options ndots

前面我们说过options ndots的值默认情况下是1,在K8S中为5,为了效果明显,我们这里使用K8S中的5作为示例

这里同样是在一个命名空间demo-ns中有两个SVC,分别为demo-svc1demo-svc2,那么他们/etc/resolv.conf应该是下面这样的:

 nameserver 10.32.0.10
 search demo-ns.svc.cluster.local svc.cluster.local cluster.local
 options ndots:5

我们demo-svc1直接请求域名demo-svc2,此时ndots为1,小于配置中的5,因此会触发上面的search规则,这时第一个解析的域名就是demo-svc2.demo-ns.svc.cluster.local,当解析不出来的时候继续下面的demo-svc2.svc.cluster.localdemo-svc2.cluster.local最后才是直接去解析demo-svc2.

注意上面的规则用于任何一个域名,也就是当我们试图在pod中去访问一个外部域名如tinychen.com时候也会依次进行上述查询

当ndots大于等于options ndots

我们在demo-svc1中直接请求域名demo-svc2.demo-ns.svc.cluster.local,此时的ndots为4,还是触发上面的search规则

请求域名demo-svc2.demo-ns.svc.cluster.local.,ndots为5,等于配置中的5,因此不会触发上面的search规则,直接去解析demo-svc2.demo-ns.svc.cluster.local.这个域名并返回结果

如果我们请求更长的域名如POD域名pod-1.demo-svc2.demo-ns.svc.cluster.local.,此时的ndots为6,大于配置中的5,因此也不会触发上面的search规则,会直接查询域名并返回解析

小结

通过上面的分析我们不难得出下面几点结论:

2 kubernetes插件

kubernetes插件的主要作用就是用来连接k8s集群的apiserver并对外提供符合规范的域名解析服务,该插件在每个配置块中仅能使用一次,但在一个coredns实例中可以存在多个配置块,也就意味着一个coredns实例实际上是可以连接多个k8s集群并对外提供域名解析的。

接下来我们详细看一下kubernetes插件的各种具体配置,下面的这个是官方给出的一个配置文件示例

 kubernetes [ZONES...] {
     endpoint URL
     tls CERT KEY CACERT
     kubeconfig KUBECONFIG [CONTEXT]
     namespaces NAMESPACE...
     namespace_labels EXPRESSION
     labels EXPRESSION
     pods POD-MODE
     endpoint_pod_names
     ttl TTL
     noendpoints
     fallthrough [ZONES...]
     ignore empty_service
 }

注意这里
labels匹配的是
service中的
labels,而前面的
labels匹配的是
namespace中的
labels。这两个
labels的配置写法可以和使用
kubectl命令中的
-l参数完全一致。

如果要使用多个labels匹配规则,注意不要使用空格,而是对应表达式进行匹配:

-l, —selector=”: Selector (label query) to filter on, supports ‘=’, ‘==’, and ‘!=’.(e.g. -l key1=value1,key2=value2)

3 一些其他问题

3.1 延迟启动

当CoreDNS启用了kubernetes插件之后,CoreDNS实例启动的时候延迟5s的时间再对外提供服务,这5s内CoreDNS会尝试和K8S的apiserver建立连接并同步信息

如果5s内CoreDNS还是无法和k8s的apiserver完成信息同步工作,那么会开始对外提供服务,并且继续尝试同步信息,但是在成功apiserver建立连接并同步信息之前,所有k8s相关的域名查询都会返回SERVFAIL

3.2 连接中断

如果在CoreDNS实例正常运行的时候,突然和k8s的apiserver断开连接,并且一直没有恢复,那么此时的CoreDNS实例是依旧正常运行的,对应的K8S集群域名也是能够正常解析的,但是解析出来的endpoint信息就有可能不是最新的。

如果此时再对CoreDNS实例进行重启操作,那么具体的过程就和上面讲述的延迟启动一样,最后会导致所有k8s相关的域名查询都会返回SERVFAIL

3.3 配置检查

kubernetes的健康状态暴露ready插件中,如果出现配置错误可以通过请求ready插件暴露接口发现,但是如果出现连接异常这种情况,ready接口是无法探测出来的。

原文地址:https://blog.csdn.net/ygq13572549874/article/details/134819264

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_47458.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注