kubernetes集群内部DNS解析原理、域名解析超时问题记录

kubernetes集群内部DNS解析原理

当kubernetes初始化完成后,在kube-system名称空间下会出现kube-dns的service服务与coredns的pod

$ kubectl get svc -n kube-system        
NAME       TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   241.254.0.10   <none>        53/UDP,53/TCP,9153/TCP   25d

$ kubectl get pod  -n kube-system -o wide| grep coredns 
coredns-7844787459-f7sb4         1/1     Running   0          25d   241.255.0.123     master   <none>           <none>
coredns-7844787459-rg9rz         1/1     Running   0          25d   241.255.0.124     master   <none>           <none>

CoreDNS是一个DNS解析的组件,作为集群内的DNS服务器,为集群内部提供域名解析服务。比如当集群内Pod要通过service名称访问后端pod时,就会用到coredns的解析服务。CoreDNS服务监视Kubernetes API,当使用kubectl命令向apiServer提交service请求时,CoreDNS会为每一个Service创建DNS记录用于域名解析。

DNS解析原理

当客户端Pod想要通过service name访问后端服务时,会先通过客户端pod自身的dns文件(/etc/resolv.conf)指向dns服务器,
DNS服务器将service name转换成对应ip,客户端Pod在通过ip请求后端服务

DNS配置策略

每个Pod所使用的DNS策略,是通过pod.spec.dnsPolicy字段设置的,共有4种DNS策略:

  • ClusterFirst:默认策略,表示使用集群内部的CoreDNS来做域名解析,Pod内/etc/resolv.conf文件中配置的nameserver是集群的DNS服务器,即kube-dns的地址。
  • Default:Pod直接继承集群node节点的域名解析配置,也就是,Pod会直接使用宿主机上的/etc/resolv.conf文件内容。
  • None:忽略k8s集群环境中的DNS设置,Pod会使用其dnsConfig字段所提供的DNS配置,dnsConfig字段的内容要在创建Pod时手动设置好。
  • ClusterFirstWithHostNet:宿主机与 Kubernetes 共存,这种情况下的POD,既能用宿主机的DNS服务,又能使用kube-dns的Dns服务,需要将hostNetwork打开。

ClusterFirst

apiVersion: v1
kind: Pod
metadata:
   name: mypod
   labels:
      app: mypod
spec:
   containers:
     - name: mynginx
       image: mynginx:v1
   dnsPolicy: ClusterFirst  #字段设置为ClusterFirst(该值为默认值,不设置也是该值)
#namserver指向kube-dns service地址
$ kubectl exec mypod -- cat /etc/resolv.conf 
nameserver 241.254.0.10
search default.svc.cluster.local svc.cluster.local cluster.local localdomain
options ndots:5

Default

apiVersion: v1
kind: Pod
metadata:
   name: mypod
   labels:
      app: mypod
spec:
   containers:
     - name: mynginx
       image: mynginx:v1
   dnsPolicy: Default
#pod内的resolv.conf与宿主机的resolv.conf一致
$ kubectl exec mypod -- cat /etc/resolv.conf 
nameserver 192.168.234.2
search localdomain

$ cat /etc/resolv.conf 
search localdomain
nameserver 192.168.234.2

None

apiVersion: v1
kind: Pod
metadata:
   name: mypod
   labels:
      app: mypod
spec:
   containers:
     - name: mynginx
       image: mynginx:v1
   dnsPolicy: None
   dnsConfig:
     nameservers: ["192.168.234.1","192.168.234.2"]  #最多可指定3个IP,当Pod的dnsPolicy设置为None时,列表必须至少包含一个IP地址
     searches:                                       #Pod中主机名查找的DNS搜索域列表
       - default.svc.cluster.local
       - svc.cluster.local
       - cluster.local
     options:
       - name: ndots
         value: "5"
#pod内resolv.conf文件为dnsConfig配置
$ kubectl exec mypod -- cat /etc/resolv.conf 
nameserver 192.168.234.1
nameserver 192.168.234.2
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

ClusterFirstWithHostNet

apiVersion: v1
kind: Pod
metadata:
   name: mypod
   labels:
      app: mypod
spec:
   containers:
     - name: mynginx
       image: mynginx:v1
   hostNetwork: true   #hostNetwork为true时,表示与宿主机共享网络空间
   dnsPolicy: ClusterFirst  #即使dnsPolicy设置为集群优先,由于hostNetwork: true也会强制将dnsPolicy设置为Default

#所以Pod内resolv.conf与宿主机相同
$ kubectl exec mypod -- cat /etc/resolv.conf 
nameserver 192.168.234.2
search localdomain
apiVersion: v1
kind: Pod
metadata:
   name: mypod
   labels:
      app: mypod
spec:
   containers:
     - name: mynginx
       image: mynginx:v1
   hostNetwork: true
   dnsPolicy: ClusterFirstWithHostNet
#只有dnsPolicy: ClusterFirstWithHostNet,此时pod既可以使用宿主机网络也可以使用kube-dns网络
$ kubectl exec -it mypod -- cat /etc/resolv.conf 
nameserver 241.254.0.10
search default.svc.cluster.local svc.cluster.local cluster.local localdomain
options ndots:5

DNS解析5s超时
参考链接:https://monkeywie.cn/2019/12/10/k8s-dns-lookup-timeout/
主要通过配置resolv.conf的single-request-reopen和single-request选项来避免

  • single-request-reopen (glibc>=2.9) 发送 A 类型请求和 AAAA 类型请求使用不同的源端口。这样两个请求在 conntrack 表中不占用同一个表项,从而避免冲突。
  • single-request (glibc>=2.10) 避免并发,改为串行发送 A 类型和AAAA类型请求,没有了并发,从而也避免了冲突。

修改/etc/resolv.conf文件,在最后加入一行文本:

options single-request-reopen
或者
options single-request

k8s部署pod可通过修改 pod 的 postStart hook 来设置

containers:
  - lifecycle:
      postStart:
        exec:
          command:
            - /bin/sh
            - -c
            - "/bin/echo 'options single-request-reopen' >> /etc/resolv.conf"

或者通过修改 pod 的 template.spec.dnsConfig 来设置

template:
  spec:
    dnsConfig:
      options:
        - name: single-request-reopen

注: 需要 k8s 版本>=1.9并且不支持alpine基础镜像的容器,因为apline底层使用的musl libc库并不支持这些 resolv.conf 选项,所以如果使用alpine基础镜像构建的应用,还是无法规避超时的问题

### Kubernetes集群域名解析 Kubernetes 是一种用于自动化部署、扩展和管理容器化应用程序的开源平台。在大型企业环境中,经常会部署多个 Kubernetes 集群以满足不同业务部门的需求,这种架构通常被称为多集群环境。 #### 多集群域名解析的重要性: 在多集群环境下,为了实现跨集群的服务发现和访问,需要一种机制来解析特定服务的 DNS 名称,并将请求路由到正确的集群内的服务实例。这是通过设置 DNS 记录和使用 DNS 代理或者 DNS 负载均衡工具来完成的。 例如,你可以为每个集群创建一个服务对应的 A 记录或 CNAME 记录,并指向该集群的入口网关或负载均衡器的 IP 地址。这使得外部系统可以通过统一的域名来访问任意集群中的服务,而无需关心服务实际运行在哪一个具体的集群内。 #### 实现步骤: 1. **配置 DNS 记录**:为集群中的所有服务配置 DNS 记录,如 `my-service.cluster1.example.com` 和 `my-service.cluster2.example.com` 分别对应两个不同的集群。 2. **使用 DNS 解析工具**:可以使用如 CoreDNS、Keepalived 或其他第三方 DNS 解析软件作为 DNS 服务器,并配置其解析规则。通过 DNS 解析工具,可以根据查询的主机名自动路由到正确的集群。 3. **设置 DNS 缓存**:为了避免多次查询相同的记录造成性能影响,可以利用本地缓存或分布式缓存技术,减少 DNS 查询次数。 4. **监控与维护**:定期检查 DNS 设置是否正常工作,以及服务的状态变化。在集群迁移或服务更新时,及时调整 DNS 记录以保证服务可用性和访问路径的一致性。 ### Gossip 协议 Gossip 协议是一种用于在分布式网络中高效传播信息的算法。它主要用于实现状态一致性(Stateful sets)、数据广播、故障检测等场景。Gossip 协议的核心思想是采用随机样本的方式传播消息,避免了全网同步传播可能导致的瓶颈问题和高复杂度。 #### Gossip 协议的关键特性: 1. **轻量级通信**:节点之间的通信是基于简单的信息交换,降低了网络资源的消耗。 2. **高容错性**:即使部分节点失效,其余节点仍能继续有效传播信息。 3. **随机选择对等节点**:每次仅与其他节点随机选择的部分对等节点交流信息,减少了大规模广播带来的开销。 4. **快速收敛**:当网络中存在大量信息变更时,Gossip 协议能够快速地收敛并达成一致状态。 #### 应用场景: - **状态一致性**:在分布式系统中,Gossip 协议可用于保持各个节点之间状态的一致性,比如在一致性哈希环中的节点间共享数据副本的位置。 - **故障检测**:通过周期性的询问其他节点,Gossip 协议可以在短时间内检测出网络中的故障节点,有助于系统的快速恢复和负载均衡。 - **数据广播**:在不需要精确控制消息传递顺序的情况下,Gossip 协议提供了一种高效的数据广播方案。 总的来说,Kubernetes 的多集群域名解析与 Gossip 协议分别解决的是多集群环境下的服务发现与分布式网络中的信息传播问题,两者都是现代分布式系统设计中不可或缺的技术手段。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值