K8s中Pod4中DNS解析策略

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: K8s中Pod4中DNS解析策略

在kubernetes中,有以下4中DNS策略,可以通过dnsPolicy指定:

  • Default: Pod从运行所在的节点继承名称解析配置,就是该 Pod 的 DNS 配置会跟宿主机完全一致。。Default 不是默认的 DNS 策略。如果未明确指定dnsPolicy,则使用 ClusterFirst。
  • ClusterFirst: 它会预先把 kube-dns(或 CoreDNS)的信息当作预设参数写入到该 Pod 内的 DNS 配置。不过ClusterFirst 还有一个冲突,如果你的 Pod 设置了 HostNetwork=true,则 ClusterFirst 就会被强制转换成 Default。
  • ClusterFirstWithHostNet: 对于与 hostNetwork(网络接口使用的是宿主机的) 一起运行的 Pod,应显式设置其DNS策略 ClusterFirstWithHostNet,他将同时解决default和ClusterFirst的DNS解析。如果不加上dnsPolicy: ClusterFirstWithHostNet ,Pod默认使用所在宿主主机使用的DNS,这样也会导致容器内不能通过service name 访问k8s集群中其他Pod。
  • None: 表示会清除 Pod 预设的 DNS 配置,当 dnsPolicy 设置成这个值之后,Kubernetes 不会为 Pod 预先载入任何自身逻辑判断得到的 DNS 配置。因此若要将 dnsPolicy 的值设为 None,为了避免 Pod 里面没有配置任何 DNS参数,至少需要在dnsConfig中设置nameservers的参数。

在 Kubernetes 1.11 及其以后版本中,推荐使用 CoreDNS, kubeadm 默认会安装 CoreDNS。当Pod向CoreDNS发起DNS解析请求时,CoreDNS先会自己尝试解析,如果无法解析该域名,会将DNS请求交给CoreDNS的Pod所在的宿主机,让宿主机尝试解析。

本次实验kubernetes集群中coredns service的地址是10.247.3.10。

kubectl get svc -n kube-system
NAME      TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                  AGE
coredns   ClusterIP   10.247.3.10   <none>        53/UDP,53/TCP,8080/TCP   13d

宿主机的/etc/resolv.conf文件如下:

[root@cr7-k8s-85091-ydy99 ~]# cat /etc/resolv.conf
# Generated by NetworkManager
search openstacklocal
nameserver 100.125.1.250
nameserver 100.125.64.250
options single-request-reopen

CluterFirst

CluterFirst是kubernetes集群中默认的DNS策略,这里是一个普通的Pod yaml文件,没有指定dnsPolicy。

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always

创建Pod后,进入该Pod查看/etc/resolv.conf配置,可以看到nameserver为CoreDNS的service的地址。

/ # cat /etc/resolv.conf
nameserver 10.247.3.10
search default.svc.cluster.local svc.cluster.local cluster.local openstacklocal
options single-request-reopen timeout:2 ndots:5
如果在Pod的yaml文件中指定了DNS参数,会和默认的ClusterFirst的配置叠加:
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always
  dnsConfig:
    nameservers:
      - 1.2.3.4
    searches:
      - ns1.svc.cluster-domain.example
      - my.dns.search.suffix
    options:
      - name: ndots
        value: "2"
      - name: edns0
/ # cat /etc/resolv.conf
nameserver 10.247.3.10
nameserver 1.2.3.4
search default.svc.cluster.local svc.cluster.local cluster.local openstacklocal ns1.svc.cluster-domain.example my.dns.search.suffix
options timeout:2 ndots:2 edns0 single-request-reopen

Default

dnsPolicy为Default模式时,Pod使用的是宿主机的DNS配置:

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always
  dnsPolicy: Default
/ # cat /etc/resolv.conf
nameserver 100.125.1.250
nameserver 100.125.64.250
search openstacklocal
options single-request-reopen timeout:2

ClusterFirstWithHostNet

当Pod使用了hostNetwork模式时,Pod使用的是宿主机的网卡:

#进入pod后查看
/ # ifconfig
......
eth0      Link encap:Ethernet  HWaddr FA:16:3E:6D:14:9B
          inet addr:192.168.0.8  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::f816:3eff:fe6d:149b/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:44239432 errors:0 dropped:0 overruns:0 frame:0
          TX packets:47841007 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:19884749467 (18.5 GiB)  TX bytes:34713001649 (32.3 GiB)
......   

当Pod使用hostNetwork模式,并且未指定dnsPolicy为ClusterFirstWithHostNet时,Pod会使用的宿主机的DNS:

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always
  hostNetwork: true

此时Pod无法通过域名访问Kubernetes集群内部:

#hostNetwork模式如果不指定dnsPolicy则使用default模式,使用的宿主机的DNS
/ # cat /etc/resolv.conf
nameserver 100.125.1.250
nameserver 100.125.64.250
search openstacklocal
options single-request-reopen timeout:2
 
#pod可以通过域名访问外网,但是无法通过域名访问kubernetes集群内部
/ # ping baidu.com
PING baidu.com (39.156.69.79): 56 data bytes
64 bytes from 39.156.69.79: seq=0 ttl=49 time=29.193 ms
64 bytes from 39.156.69.79: seq=1 ttl=49 time=29.104 ms
^C
--- baidu.com ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 29.104/29.148/29.193 ms
/ # ping nginx
ping: bad address 'nginx'

如果Pod在hostNetwork模式下要通过域名的方式访问kubernetes集群内的服务,需要指定dnsPolicy为ClusterFirstWithHostNet:

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always
  hostNetwork: true
  dnsPolicy: ClusterFirstWithHostNet 

此时查看Pod的DNS配置,可以看到nameserver使用的是CoreDNS:

#ClusterFirstWithHostNet模式DNS使用的是coredns的地址,
/ # cat /etc/resolv.conf
nameserver 10.247.3.10
search default.svc.cluster.local svc.cluster.local cluster.local openstacklocal
options single-request-reopen timeout:2 ndots:5
 
#可以通过域名访问外网,也通过域名访问集群内部
/ # nslookup baidu.com
Server:    10.247.3.10
Address 1: 10.247.3.10 coredns.kube-system.svc.cluster.local
 
Name:      baidu.com
Address 1: 39.156.69.79
Address 2: 220.181.38.148
/ #
/ # nslookup nginx
Server:    10.247.3.10
Address 1: 10.247.3.10 coredns.kube-system.svc.cluster.local
 
Name:      nginx
Address 1: 10.247.60.222 nginx.default.svc.cluster.local
/ #

None

当设置dnsPolicy为None时,不会使用Kubernetes集群和宿主机的 DNS 策略,但是必须自己配置dnsConfig。

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always
  dnsPolicy: None
  dnsConfig:
    nameservers:
      - 1.2.3.4
/ # cat /etc/resolv.conf
nameserver 1.2.3.4
options single-request-reopen timeout:2

StatefulSet 和 Service

  • StatefulSet Pod 具有唯一的标识,该标识包括顺序标识、稳定的网络标识和稳定的存储。该标识和 Pod 是绑定的,不管它被调度在哪个节点上。
  • StatefulSet 中的每个 Pod 根据 StatefulSet 的名称和 Pod 的序号派生出它的主机名。组合主机名的格式为$(StatefulSet 名称)-$(序号)。下例将会创建三个名称分别为 web-0、web-1、web-2 的 Pod。StatefulSet 可以使用 Headless Service(无头服务)控制它的 Pod 的网络域。管理域的这个服务的格式为: $(服务名称).$(命名空间).svc.cluster.local,其中 cluster.local 是集群域。一旦每个 Pod 创建成功,就会得到一个匹配的 DNS 子域,格式为:$(pod 名称).$(所属服务的 DNS 域名),其中所属服务由 StatefulSet 的 serviceName 域来设定。

  • 通过域名去访问Headless Service负载的Pod是不走iptables的,通过域名去访问ClusterIP负载的Pod要走Iptables。
  • 下面给出一些选择集群域、服务名、StatefulSet 名、及其怎样影响 StatefulSet 的 Pod 上的 DNS 名称的示例:
Cluster Domain Service (ns/name) StatefulSet (ns/name) StatefulSet Domain Pod DNS Pod Hostname
cluster.local default/nginx default/web nginx.default.svc.cluster.local web-{0..N-1}.nginx.default.svc.cluster.local web-{0..N-1}
cluster.local foo/nginx foo/web nginx.foo.svc.cluster.local web-{0..N-1}.nginx.foo.svc.cluster.local web-{0..N-1}
kube.local foo/nginx foo/web nginx.foo.svc.kube.local web-{0..N-1}.nginx.foo.svc.kube.local web-{0..N-1}

Headless Service

首先我们将StatefulSet和Headless Service结合使用,(通常情况下是这么做的):

apiVersion: v1
kind: Service
metadata:
  name: headless-nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx 
  serviceName: headless-nginx
  replicas: 3 
  template:
    metadata:
      labels:
        app: nginx 
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
          name: web

查看创建的StatefulSet的Pod,命名是有规律的按照0,1,2的顺序递增。

root@master01:~/yaml/service# kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP               NODE       NOMINATED NODE   READINESS GATES
web-0                    1/1     Running   0          6s      192.168.5.59     worker01   <none>           <none>
web-1                    1/1     Running   0          5s      192.168.30.117   worker02   <none>           <none>
web-2                    1/1     Running   0          3s      192.168.5.58     worker01   <none>           <none>

查看创建的Headless Service,可以看到ClusterIP为None:

root@master01:~/yaml/service# kubectl get svc
NAME              TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)   AGE
headless-nginx    ClusterIP      None             <none>          80/TCP    15m

找一个相同namespace的Pod来解析该Headless Service:

root@master01:~/yaml/service# kubectl exec busybox1 -- nslookup headless-nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
 
#解析出来的ip地址为3个StatefulSet的pod的ip
Name:      headless-nginx
Address 1: 192.168.30.117 web-1.headless-nginx.default.svc.cluster.local
Address 2: 192.168.5.59 web-0.headless-nginx.default.svc.cluster.local
Address 3: 192.168.5.58 web-2.headless-nginx.default.svc.cluster.local

查看default命名空间下的Pod的/etc/resolv.conf配置:

root@master01:~/yaml/service# kubectl exec busybox1 -- cat /etc/resolv.conf           
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

在不同的 namespace 下的 Pod 通过 Service 访问的时候,需要在 Service name 后面加上 .<namespace名字>。

root@master01:~/yaml/service# kubectl exec busybox2 -n kube-system  -- nslookup  headless-nginx.default  
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
 
Name:      headless-nginx.default.svc.cluster.local
Address 1: 192.168.5.58 web-2.headless-nginx.default.svc.cluster.local
Address 2: 192.168.5.59 web-0.headless-nginx.default.svc.cluster.local
Address 3: 192.168.30.117 web-1.headless-nginx.default.svc.cluster.local

查看kube-system命名空间下的Pod的/etc/resolv.conf配置:

root@master01:~/yaml/service# kubectl exec busybox2 -n kube-system  -- cat /etc/resolv.conf             nameserver 10.96.0.10
search kube-system.svc.cluster.local svc.cluster.local cluster.local 
options ndots:5

ClusterIP Service

现在我们将StatefulSet和ClusterIP Service结合使用:

apiVersion: v1
kind: Service
metadata:
  name: clusterip-nginx
  labels:
    app: nginx
#ClusterIP不为None则表示该Service有ClusterIP    
spec:
  ports:
  - port: 80
    name: web
  selector:
    app: nginx

查看创建的Service:

root@master01:~/yaml/service# kubectl get svc
NAME              TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)   AGE
clusterip-nginx   ClusterIP      10.110.176.201   <none>          80/TCP    13s

此时用Pod解析域名只能得到ClusterIP地址,无法得到Pod的IP地址:

oot@master01:~/yaml/service# kubectl exec busybox1 -- nslookup clusterip-nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
 
Name:      clusterip-nginx
Address 1: 10.110.176.201 clusterip-nginx.default.svc.cluster.local

Pod 的 hostname 与 subdomain

在 Kubernetes 中,如果不指定 Pod 的 hostname,其默认为 pod.metadata.name,通过 spec.hostname 字段可以自定义;另外还可以给 Pod 设置 subdomain,通过 spec.subdomain 字段。比如下面这个例子:

创建一个Nginx Pod,指定Pod的hostname和subdomain:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    name: nginx
spec:
  hostname: domain-test
  subdomain: subdomain-test
  containers:
  - image: nginx
    name: nginx
---
apiVersion: v1
kind: Service
metadata:
  name: subdomain-test
spec:
  selector:
    name: nginx
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP

可以查看这个 Pod 的 hostname 和 hosts 文件:

[root@localhost ~]# kubectl get po -o wide
NAME                           READY   STATUS    RESTARTS   AGE     IP             NODE           NOMINATED NODE   READINESS GATES
busybox-5bbb5d7ff7-dh68j       1/1     Running   0          112m    10.244.1.246   172-16-105-2   <none>           <none>
nginx                          1/1     Running   0          2m      10.244.1.253   172-16-105-2   <none>           <none>
[root@localhost ~]# kubectl exec -it nginx bash
root@domain-test:/# cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.244.1.253  domain-test.subdomain-test.default.svc.cluster.local  domain-test
root@domain-test:/#

在 busybox 容器中通过域名访问这个Pod:

[root@localhost ~]# kubectl exec -it busybox-5bbb5d7ff7-dh68j sh
/ # wget domain-test.subdomain-test
Connecting to domain-test.subdomain-test (10.244.1.253:80)
saving to 'index.html'
index.html           100% |*****************************************************|   612  0:00:00 ETA
'index.html' saved
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
打赏
0
1
1
0
81
分享
相关文章
域名解析的终极指南:从基础到进阶,彻底搞懂 DNS 记录
域名解析是网站运行的基础,正确配置DNS记录至关重要。本文从基础到进阶全面解析DNS知识,涵盖A、AAAA、CNAME、MX、TXT、CAA等常见记录类型及其应用场景。通过学习,你将了解DNS的工作原理,掌握如何优化域名配置,确保网站与邮件服务高效运行。无论搭建个人博客还是企业官网,本文都能助你轻松搞定域名解析!
66 0
机器学习:强化学习中的探索策略全解析
在机器学习的广阔领域中,强化学习(Reinforcement Learning, RL)无疑是一个充满魅力的子领域。它通过智能体与环境的交互,学习如何在特定的任务中做出最优决策。然而,在这个过程中,探索(exploration)和利用(exploitation)的平衡成为了智能体成功的关键。本文将深入探讨强化学习中的探索策略,包括其重要性、常用方法以及代码示例来论证这些策略的效果。
深入学习 DNS 域名解析
在平时工作中相信大家都离不开 DNS 解析,因为 DNS 解析是互联网访问的第一步,无论是使用笔记本浏览器访问网络还是打开手机APP的时候,访问网络资源的第一步必然要经过DNS解析流程。
【飞天技术沙龙】云解析 DNS 上海站《多云+IDC 融合场景下的 DNS 最佳实践》圆满落幕
【飞天技术沙龙】云解析 DNS 上海站《多云+IDC 融合场景下的 DNS 最佳实践》圆满落幕
入门级容器技术解析:Docker和K8s的区别与关系
本文介绍了容器技术的发展历程及其重要组成部分Docker和Kubernetes。从传统物理机到虚拟机,再到容器化,每一步都旨在更高效地利用服务器资源并简化应用部署。容器技术通过隔离环境、减少依赖冲突和提高可移植性,解决了传统部署方式中的诸多问题。Docker作为容器化平台,专注于创建和管理容器;而Kubernetes则是一个强大的容器编排系统,用于自动化部署、扩展和管理容器化应用。两者相辅相成,共同推动了现代云原生应用的快速发展。
725 11
深入解析Linux操作系统的内核优化策略
本文旨在探讨Linux操作系统内核的优化策略,包括内核参数调整、内存管理、CPU调度以及文件系统性能提升等方面。通过对这些关键领域的分析,我们可以理解如何有效地提高Linux系统的性能和稳定性,从而为用户提供更加流畅和高效的计算体验。
173 24
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
在数字化时代,利用DNS实现地理位置路由成为提升用户体验的有效策略
在数字化时代,利用DNS实现地理位置路由成为提升用户体验的有效策略。通过解析用户请求的来源IP地址,DNS服务器可判断其地理位置,并返回最近或最合适的服务器IP,从而优化网络路由,减少延迟,提高访问速度。示例代码展示了如何基于IP地址判断地理位置并分配相应服务器IP,实际应用中需结合专业地理数据库和动态调整机制,以应对复杂网络环境带来的挑战。
116 6
K8s业务迁移最佳实践: 灵活管理资源备份与调整策略,实现高效简便的应用恢复
在当今快速变化的云原生领域,Kubernetes(K8s)集群的运维面临着诸多挑战,其中灾备与业务迁移尤为关键。ACK备份中心支持丰富的资源调整策略,在数据恢复阶段即可自动适配目标集群环境,确保业务无缝重启。

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等