当前位置: 首页 > news >正文

锋云科技网站建设苏州seo怎么做

锋云科技网站建设,苏州seo怎么做,免费招人的平台,wordpress输网址采集目录 文章目录目录本节实战前言1、环境变量2、DNS1.DNS 解析过程2.根域名服务器3.顶级域名服务器4.权威性域名服务器5.dig 域名3、CoreDNS1.CoreDNS 扩展配置#xff08;1#xff09;开开启日志服务#xff08;2#xff09;特定域名使用自定义 DNS 服务器#xff08;31开开启日志服务2特定域名使用自定义 DNS 服务器3自定义 Hosts4集群外部访问集群内服务5统一域名访问服务6禁止对对 IPv6类型的 AAAA 记录查询返回2.使用4、Pod 的 DNS 策略5、Pod 的 DNS 配置关于我最后本节实战 实战名称 实战coredns测试(测试成功)-2023.2.18 实战Pod的DNS策略-2023.2.18(测试成功) 实战Pod的DNS设置-2023.2.18(测试成功) 前言 上面我们讲解了 Service 的用法我们可以通过 Service 生成的 ClusterIP(VIP) 来访问 Pod 提供的服务。但是在使用的时候还有一个问题我们怎么知道某个应用的 VIP 呢比如我们有两个应用一个是 api 应用一个是 db 应用两个应用都是通过 Deployment 进行管理的并且都通过 Service 暴露出了端口提供服务。api 需要连接到 db 这个应用我们只知道 db 应用的名称和 db 对应的 Service 的名称但是并不知道它的 VIP 地址我们前面的 Service 课程中是不是学习到我们通过 ClusterIP 就可以访问到后面的 Pod 服务如果我们知道了 VIP 的地址是不是就行了 注意在实际工作应用中我们很少去把访问地址用ip固定下来。我们要解决这种问题一般有2种方法。 第一种环境变量。 第二种DNS。 1、环境变量 为了解决上面的问题在之前的版本中Kubernetes 采用了环境变量的方法每个 Pod 启动的时候会通过环境变量设置所有服务的 IP 和 port 信息这样 Pod 中的应用可以通过读取环境变量来获取依赖服务的地址信息这种方法使用起来相对简单但是有一个很大的问题就是依赖的服务必须在 Pod 启动之前就存在不然是不会被注入到环境变量中的。 实战环境变量测试(测试成功)-2023.2.13 实验环境 实验环境 1、win10,vmwrokstation虚机 2、k8s集群3台centos7.6 1810虚机1个master节点,2个node节点k8s versionv1.22.2containerd://1.5.5实验软件无 比如我们首先创建一个 Nginx 服务 #test-nginx.yaml apiVersion: apps/v1 kind: Deployment metadata:name: nginx-deploy spec:replicas: 2selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.7.9ports:- containerPort: 80 --- apiVersion: v1 kind: Service metadata:name: nginx-servicelabels:name: nginx-service spec:ports:- port: 5000targetPort: 80selector:app: nginx创建上面的服务并查看 [rootmaster1 ~]#kubectl apply -f test-nginx.yaml deployment.apps/nginx-deploy created service/nginx-service created[rootmaster1 ~]#kubectl get po NAME READY STATUS RESTARTS AGE nginx-deploy-7759cfdc55-8wqjs 1/1 Running 0 87s nginx-deploy-7759cfdc55-99ttd 1/1 Running 0 57s [rootmaster1 ~]#kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 none 443/TCP 70d nginx-service ClusterIP 10.107.211.179 none 5000/TCP 119s [rootmaster1 ~]#kubectl get ep NAME ENDPOINTS AGE kubernetes 172.29.9.61:6443 70d nginx-service 10.244.1.60:80,10.244.2.56:80 2m28s我们可以看到两个 Pod 和一个名为 nginx-service 的服务创建成功了该 Service 监听的端口是 5000同时它会把流量转发给它代理的所有 Pod我们这里就是拥有 app: nginx 标签的两个 Pod。 现在我们再来创建一个普通的 Pod观察下该 Pod 中的环境变量是否包含上面的 nginx-service 的服务信息 #test-pod.yaml apiVersion: v1 kind: Pod metadata:name: test-pod spec:containers:- name: test-service-podimage: busybox:1.28.3command: [/bin/sh, -c, env]然后创建该测试的 Pod [rootmaster1 ~]#kubectl apply -f test-pod.yaml pod/test-pod created等 Pod 创建完成后我们查看日志信息 [rootmaster1 ~]#kubectl get po NAME READY STATUS RESTARTS AGE …… test-pod 0/1 CrashLoopBackOff 2 (17s ago) 49s [rootmaster1 ~]#kubectl logs test-pod KUBERNETES_PORTtcp://10.96.0.1:443 KUBERNETES_SERVICE_PORT443 HOSTNAMEtest-pod SHLVL1 HOME/root NGINX_SERVICE_PORT_5000_TCP_ADDR10.107.211.179 NGINX_SERVICE_PORT_5000_TCP_PORT5000 NGINX_SERVICE_PORT_5000_TCP_PROTOtcp KUBERNETES_PORT_443_TCP_ADDR10.96.0.1 PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin NGINX_SERVICE_SERVICE_HOST10.107.211.179 #Host KUBERNETES_PORT_443_TCP_PORT443 NGINX_SERVICE_PORT_5000_TCPtcp://10.107.211.179:5000 KUBERNETES_PORT_443_TCP_PROTOtcp NGINX_SERVICE_PORTtcp://10.107.211.179:5000 NGINX_SERVICE_SERVICE_PORT5000 #Port KUBERNETES_PORT_443_TCPtcp://10.96.0.1:443 KUBERNETES_SERVICE_PORT_HTTPS443 KUBERNETES_SERVICE_HOST10.96.0.1 PWD/我们可以看到打印了很多环境变量信息其中就包括我们刚刚创建的 nginx-service 这个服务有 HOST、PORT、PROTO、ADDR 等也包括其他已经存在的 Service 的环境变量。现在如果我们需要在这个 Pod 里面访问 nginx-service 的服务我们是不是可以直接通过 NGINX_SERVICE_SERVICE_HOST 和 NGINX_SERVICE_SERVICE_PORT 就可以了。但是如果这个 Pod 启动起来的时候 nginx-service 服务还没启动起来在环境变量中我们是无法获取到这些信息的。**当然我们可以通过 **initContainer之类的方法来确保 nginx-service 启动后再启动 Pod但是这种方法毕竟增加了 Pod 启动的复杂性所以这不是最优的方法局限性太多了。 实验结束。 2、DNS DNS 其实就是一个分布式的树状命名系统它就像一个去中心化的分布式数据库存储着从域名到 IP 地址的映射。当一台主机想要通过域名访问某个服务的内容时需要先通过当前域名获取对应的 IP 地址这时就需要通过一个 DNS 解析器负责域名的解析。 1.DNS 解析过程 所有 DNS 服务器都属于以下四个类别之一递归解析器、根域名服务器、顶级域名服务器和权威性域名服务器。在典型 DNS 查找中当没有正在进行的高速缓存时这四个 DNS 服务器协同工作来完成将指定域的 IP 地址提供给客户端的任务客户端通常是一个存根解析器 - 内置于操作系统的简单解析器。 DNS 解析器 - 该解析器可被视为被要求去图书馆的某个地方查找特定图书的图书馆员。DNS 解析器是一种服务器旨在通过 Web 浏览器等应用程序接收客户端计算机的查询。然后解析器一般负责发出其他请求以便满足客户端的DNS 查询。 根域名服务器 - 根域名服务器是将人类可读的主机名解析为 IP 地址的第一步可将其视为指向不同书架的图书馆中的索引。 TLD 域名服务器 - 顶级域服务器TLD可被视为图书馆中的特定书架此域名服务器是搜索特定 IP 地址的下一步其托管主机名的最后一部分比如在 example.com 中TLD 服务器为 com 。 权威性域名服务器 - 可将这个最终域名服务器视为书架上的字典其中特定名称可被转换成其定义。权威性域名服务器是域名服务器查询中的最后一站。如果权威性域名服务器能够访问请求的记录则其会将已请求主机名的 IP 地址返回到发出初始请求的 DNS 解析器图书管理员。 下面我们简单介绍下 DNS 查找 IP 地址的步骤不考虑缓存。DNS 服务器根据域名的层级进行分级查询需要明确的是每一级域名都有自己的 NSName Server 的缩写记录NS 记录指向该级域名的域名服务器。 用户在 Web 浏览器中键入 example.com 查询传输到 Internet 中并被 DNS 解析器接收。接着解析器向 DNS 根域名服务器 . 发起查询请求。然后根服务器返回其域信息的顶级域 DNS 服务器例如 .com 或 .net的 NS 记录和 A 记录给该解析器。例 如在访问 example.com 时我们的请求指向 .com TLD 服务器。然后解析器向 .com TLD 服务器发出请求。TLD 服务器随后返回域名 example.com 的权威性域名服务器 NS 记录和 A 记录。最后解析器将查询发送到域的域名服务器。example.com 的 IP 地址从权威性域名服务器返回到解析器。然后 DNS 解析器使用最初请求的域的 IP 地址响应 Web 浏览器。浏览器向该 IP 地址发出 HTTP 请求。位于该 IP 的服务器返回将在浏览器中呈现的网页。 DNS 查找经过前面 8 个步骤返回 example.com 的 IP 地址后浏览器便能发出对该网页的请求。 2.根域名服务器 每个 DNS 解析器都知道 13 个 DNS 根域名服务器它们是 DNS 解析器搜寻 DNS 记录的第一站根服务器接受解析器的查询根域名服务器根据该域的扩展名.com、 .net 、.org 等将解析器定向到 TLD 域名服务器进行响应。一个普遍的误解是世界上只有 13 台根服务器。实际上根服务器有许多但只有 13 个 IP 地址用于查询不同的根服务器网络。DNS 原始架构的限制要求根区域中最多只能有 13 个服务器地址。在 Internet 面世之初这 13 个 IP 地址的每一个都只有一台服务器其中大多数位于美国。如今这 13 个 IP 地址中的每一个都有多个服务器这些服务器使用Anycast 路由基于负荷和距离分发请求。目前地球上每座有人生活的大陆上都分布着 600 多台 DNS 根服务器。 每个 DNS 解析器都在其软件中内置了 13 个 IP 根服务器地址的列表每次发起 DNS 查找时解析器的第一个通信就是与这 13 个 IP 地址之一进行的。 DNS 的管理通过使用不同的受管理分区或区域的层次结构构造其根区域位于该层次结构的最顶部。根服务器是在根区域中运行的 DNS 域名服务器这些服务器可以直接回答针对根区域内存储或缓存的记录的查询还可以将其他请求引向相应的顶级域 (TLD) 服务器。TLD 服务器是 DNS 层次结构中比根服务器低一级的 DNS 服务器组它们是解析 DNS 查询的必要部分。 需要注意的是其实每个域名后面都有一个根域名因为对于所有域名都是一样的所以平时是省略的。如www.baidu.com真正的域名是 www.baidu.com.root 简写为 www.baidu.com. 因为根域名 .root 对于所有域名都是一样的所以平时是省略的。 在未缓存的 DNS 查询期间每当用户在浏览器中输入网址该操作都会触发 DNS 查找并且所有 DNS 查找都从根区域开始。查找到达根区域后将沿 DNS 系统的层次结构向下移动首先到达 TLD 服务器然后到达特定域可能还有子域的服务器直到最终到达权威性名服务器以查到正确的域名其中包含要搜索的网站的 IP 地址然后该 IP 地址被返回给客户端。 3.顶级域名服务器 顶级TLD域名服务器维护共享通用域扩展名的所有域名的信息例如 .com 、.net 或 url 中最后一个点之后的任何内容。例如.com 顶级域名服务器包含以 .com 结尾的每个网站的信息。如果用户正在搜索 google.com 则在收到来自根域名服务器的响应后递归解析器将向 .com 顶级域名服务器发送查询后者将通过针对该域的权威权威性域名服务器 性域名服务器进行响应。 TLD 域名服务器的管理由 **Internet 编号分配机构IANA**加以处理其为 ICANN 的一个分支机构IANA 将 TLD 服务器分为两个主要组 通用顶级域这些是非特定国家/地区的域一些最知名的通用 TLD 包括 .com 、.org 、.net、 .edu 和.gov 。国家/地区代码顶级域这些包括特定于某个国家/地区或州的任何域。例如 .uk、 .us 、.ru 等。 4.权威性域名服务器 当域名解析器收到来自 TLD 域名服务器的响应时该响应会将解析器定向到权威性域名服务器权威性域名服务器通常是解析器查找找 IP 地址过程中的最后一 地址过程中的最后一步。权威名称服务器包含特定于其服务域名的信息例如 google.com并且它可为解析器提供在 DNS A 记录中找到的服务器的 IP 地址或者如果该域具有 CNAME 记录别名它将为解析器提供一个别名域这时解析器将必须执行全新 DNS 查找以便从权威性域名服务器获取记录通常为包含 IP 地址的 A 记录。 5.dig 域名 上面我们了解了用于处理域名解析的 DNS 服务器是树形的只是在树的组织和每一层的职责上有一些不同。DNS 解析器从根域名服务器查找到顶级域名服务器的 IP 地址又从顶级域名服务器查找到权威域名服务器的 IP 地址最终从权威域名服务器查出了对应服务的 IP 地址。 我们可以使用 dig 命令来追踪下我们的网站 youdianzhishi.com 域名对应的 IP 地址是如何被解析出来的可以看到首先会向预置的 13 个根域名服务器发出请求获取顶级域名的地址。 [rootmaster1 ~]#dig -t A youdianzhishi.com trace; DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.13 -t A youdianzhishi.com trace ;; global options: cmd #13个 . 1236 IN NS h.root-servers.net. . 1236 IN NS k.root-servers.net. . 1236 IN NS b.root-servers.net. . 1236 IN NS e.root-servers.net. . 1236 IN NS f.root-servers.net. . 1236 IN NS l.root-servers.net. . 1236 IN NS m.root-servers.net. . 1236 IN NS g.root-servers.net. . 1236 IN NS a.root-servers.net. . 1236 IN NS c.root-servers.net. . 1236 IN NS j.root-servers.net. . 1236 IN NS i.root-servers.net. . 1236 IN NS d.root-servers.net. ;; Received 239 bytes from 223.6.6.6#53(223.6.6.6) in 7 ms根域名服务器是 DNS 中最高级别的域名服务器域名的格式从上面返回的结果可以看到是 .root-servers.net 每个根域名服务器中只存储了顶级域服务器的 IP 地址。在这里我们获取到了以下的 13 条 NS 记录也就是 13 台 com.顶级域名 DNS 服务器 com. 172800 IN NS a.gtld-servers.net. com. 172800 IN NS b.gtld-servers.net. com. 172800 IN NS c.gtld-servers.net. com. 172800 IN NS d.gtld-servers.net. com. 172800 IN NS e.gtld-servers.net. com. 172800 IN NS f.gtld-servers.net. com. 172800 IN NS g.gtld-servers.net. com. 172800 IN NS h.gtld-servers.net. com. 172800 IN NS i.gtld-servers.net. com. 172800 IN NS j.gtld-servers.net. com. 172800 IN NS k.gtld-servers.net. com. 172800 IN NS l.gtld-servers.net. com. 172800 IN NS m.gtld-servers.net. com. 86400 IN DS 30909 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CF C41A5766 com. 86400 IN RRSIG DS 8 1 86400 20230226050000 20230213040000 951 . s0yeGeBN9LjndJ3ujWwwm6MyMmqkO0D686rIFImHwssxgvkCLBIg4UR nerOWYVP8SwT9Gmlzzx2yKsXo8pm9ldXxk31pfZsW7lakQFH2gYh7K3X nxVgnJzBDjfYuBvvwz8BvVuUf2CprlFFX2MxSbP3M1qjAcDYc/OuE6D 8QLEyPbV6mO5BZ5biBknsC/YBp3wSVpLOwrAJSi7cvbHEIYyMd5Y3f3f acaKEduQrjztO45rjq4vPQUeq4Qv2aTWs2RymCNT3nae0u8Ow3VStW6 mg51C0KdWbgaQwz9OlqDUX3KVfCZ1c45TJnA8uV1F/9SKtSn17tmy/x Zy51SQ ;; Received 1177 bytes from 199.7.91.13#53(d.root-servers.net) in 187 ms当 DNS 解析器从根域名服务器中查询到了顶级域名 .com 服务器的地址之后就可以访问这些顶级域名服务器其中的一台g.gtld-servers.net 获取权威 DNS 的服务器的地址了 youdianzhishi.com. 172800 IN NS dns21.hichina.com. youdianzhishi.com. 172800 IN NS dns22.hichina.com. CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - CK0Q2D6NI4I7EQH8NA30NS61O48UL8G5 NS SOA RRSIG DNSKEY NSEC3PARAM CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20230219052251 20230212041251 36739 com. LMcgMQFLQOrC5eZ8lT/w3zfy938o3HvnXbZ79glQ3tceud7s3FSaxbFl E6faNre/oHe273TfuUur69LMn456aELFsigub9aprgTzSVMLLR1uLo9S ikIpps4OSakJD/sxrIQR1KG4gzfi0j6Uu1h8NZwbNJFBxEe2jnajl3 OSAQkcRYrubFQYXbxh0mmdur0UcZ0plNBsBltSbCf9MHw U5N4GVFN782MDPPH68294PMTF8CN0JN2.com. 86400 IN NSEC3 1 1 0 - U5N4UBHTCVO3DI2VRP6OTQOLFFDDKVBF NS DS RRSIG U5N4GVFN782MDPPH68294PMTF8CN0JN2.com. 86400 IN RRSIG NSEC3 8 2 86400 20230219065636 20230212054636 36739 com. JVI8Vw3zv6ujeKX/oL6/co5sXE3SZuXVO4IlApPbEW5Ferq45HDl4nbn ZMzEliC4zOT97cQFp5fa32IWmV0VPKr/xjvYrX1SL4GUKO2VSOUk7Bx MpQASWFCtCJwWvS9jcTRAgtAiLAp7rbFhPcsFdE4S2emftR76KksxDYJ UflGkVUy7nVPMfLA6pt86XjIJDkMojYPaGWddtalVyKfVA ;; Received 955 bytes from 192.42.93.30#53(g.gtld-servers.net) in 267 ms 这里的权威 DNS 服务是我在域名提供商进行配置的当有客户端请求 youdianzhishi.com 域名对应的 IP 地址时其实会从我使用的 DNS 服务商阿里云处请求服务的 IP 地址youdianzhishi.com. 600 IN A 39.106.22.102 ;; Received 62 bytes from 39.96.153.38#53(dns22.hichina.com) in 32 ms 最终DNS 解析器从 dns21.hichina.com 服务中获取了我们网站的 IP 地址浏览器或者其他设备就能够通过该 IP向服务器获取请求的内容了。 [rootmaster1 ~]#3、CoreDNS 到这里我们其实能够发现 DNS 就是一种最早的服务发现的手段虽然服务器的 IP 地址可能会变动但是通过相对不会变动的域名我们总是可以找到提供对应服务的服务器。 在微服务架构中服务注册的方式大体上有两种一种是使用 Zookeeper 和 etcd 等配置管理中心另一种就是使用DNS 服务。由于上面我们介绍的环境变量这种方式的局限性我们需要一种更加智能的方案其实我们可以自己思考一种比较理想的方案那就是可以直接使用 Service 的名称因为 Service 的名称不会变化我们不需要去关心分配的ClusterIP 的地址因为这个地址并不是固定不变的所以如果我们直接使用 Service 的名字然后对应的ClusterIP 地址的转换能够自动完成就很好了。我们知道名字和 IP 直接的转换是不是和我们平时访问的网站非常类似啊他们之间的转换功能通过 DNS 就可以解决了同样的Kubernetes 也提供了 DNS 的方案来解决上面的服务发现的问题。 CoreDNS 其实就是一个 DNS 服务而 DNS 作为一种常见的服务发现手段所以很多开源项目以及工程师都会使用CoreDNS 为集群提供服务发现的功能Kubernetes 就在集群中使用 CoreDNS 解决服务发现的问题。CoreDNS 是基于Go 编写的 HTTP/2 Web 服务器 Caddy 构建的其大多数功能都是由插件来实现的插件和服务本身都使用了 Caddy提供的一些功能。 DNS 服务不是一个独立的系统服务而是作为一种 addon 插件而存在现在比较推荐的两个插件kube-dns 和 CoreDNS实际上在比较新点的版本中已经默认是 CoreDNS 了因为 kube-dns 默认一个 Pod 中需要3个容器配合使用CoreDNS 只需要一个容器即可我们在前面使用 kubeadm 搭建集群的时候直接安装的就是 CoreDNS 插件 [rootmaster1 ~]# kubectl get pods -n kube-system -l k8s-appkube-dns -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES coredns-7b884d5cb7-6jzn6 1/1 Running 1 (61d ago) 71d 10.244.0.6 master1 none none coredns-7b884d5cb7-gcszd 1/1 Running 1 (61d ago) 71d 10.244.0.7 master1 none none[rootmaster1 ~]#kubectl get po coredns-7b884d5cb7-6jzn6 -oyaml -nkube-system …… containers:- args:- -conf- /etc/coredns/Corefileimage: registry.aliyuncs.com/k8sxio/coredns:v1.9.3 ……volumeMounts:- mountPath: /etc/corednsname: config-volume #注意readOnly: true- mountPath: /var/run/secrets/kubernetes.io/serviceaccountname: kube-api-access-dvl9wreadOnly: true …… volumes:- configMap:defaultMode: 420items:- key: Corefilepath: Corefilename: coredns #注意name: config-volume- name: kube-api-access-dvl9wprojected:defaultMode: 420sources:- serviceAccountToken:expirationSeconds: 3607path: token- configMap:items:- key: ca.crtpath: ca.crtname: kube-root-ca.crt- downwardAPI:items:- fieldRef:apiVersion: v1fieldPath: metadata.namespacepath: namespace ……CoreDNS 内部采用插件机制所有功能都是插件形式编写用户也可以扩展自己的插件以下是 Kubernetes 部署CoreDNS 时的默认配置 ➜ ~ kubectl get cm coredns -n kube-system -o yaml apiVersion: v1 data:Corefile: | #注意你可以认为下面{}里的每一行相当于一个插件.:53 {errors # 启用错误记录health # 启用健康检查检查端点8080:healthreadykubernetes cluster.local in-addr.arpa ip6.arpa { # 处理 k8s 域名解析提供集群内服务解析能力基于服务和 Pod 的 IP 来应答 DNS 查询pods insecure ## 为了与 kube-dns 向后兼容还可以使用 pods verified 选项可以使得仅在相同名字空间中存在具有匹配 IP 的 Pod 时才返回 A 记录。fallthrough in-addr.arpa ip6.arpattl 30}prometheus :9153 # 启用 metrics 指标9153:metricsforward . /etc/resolv.conf # 默认情况下任何不属于 Kubernetes 集群内部的域名其 DNS 请求都将指向 forward 指定的DNS 服务器地址这里面第一个 “.” 代表所有域名后面 “/etc/resolv.conf” 表示使用宿主机的域名解析服务器。cache 30 # 启用缓存所有内容限制为 30s 的TTL (all的解析都有一个缓存的)loop # 环路检测如果检测到环路则停止 CoreDNS。reload # 允许自动重新加载已更改的 Corefile编辑 ConfigMap 配置后需要等待一段时间生效loadbalance # 负载均衡默认 round_robin} kind: ConfigMap metadata:creationTimestamp: 2019-11-08T11:59:49Zname: corednsnamespace: kube-systemresourceVersion: 188selfLink: /api/v1/namespaces/kube-system/configmaps/corednsuid: 21966186-c2d9-467a-b87f-d061c5c9e4d7每个 {} 代表一个 zone,格式是 “Zone:port{}”, 其中.代表默认zone{} 内的每个名称代表插件的名称只有配置的插件才会启用当解析域名时会先匹配 zone都未匹配会执行默认 zone然后 zone 内的插件从上到下依次执行(这个顺序并不是配置文件内谁在前面的顺序而是core/dnsserver/zdirectives.go内的顺序)匹配后返回处理执行过的插件从下到上依次处理返回逻辑不再执行下一个插件。 1.CoreDNS 扩展配置 我们可以根据自己的实际需求针对不同场景来扩展 CoreDNS 的配置。 1开开启日志服务 如果需将 CoreDNS 每次域名解析的日志打印出来我们可以开启 Log 插件只需要在 Corefile 里加上 log 即可示例配置如下 Corefile: | #注意你可以认为下面{}里的每一行相当于一个插件.:53 {errorslog #启用log插件healthreadykubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpattl 30}prometheus :9153forward . /etc/resolv.confcache 30loopreloadloadbalance}2特定域名使用自定义 DNS 服务器 如果 example.com 类型后缀的域名需要使用自建 DNS 服务器比如 10.10.0.10进行解析的话我们可为域名配置一个单独的服务块示例配置如下 Corefile: |.:53 {# 省略......}example.com:53 {errorscache 30forward . 10.10.0.10prefer_udp}3自定义 Hosts 如果需要为特定域名指定 hosts 映射如为 www.example.com 指定 IP 为 127.0.0.1 那么可以使用 Hosts 插件来配置示例配置如下 Corefile: |.:53 {errorshealth {lameduck 15s}readyhosts { # 使用 hosts 插件127.0.0.1 www.example.comfallthrough}kubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpattl 30}prometheus :9153forward . /etc/resolv.conf {prefer_udp}cache 30loopreloadloadbalance}4集群外部访问集群内服务 如果你希望在集群外的进程能够访问到集群内的服务可以通过将节点的 /etc/resolv.conf 文件内 nameserver配置为集群 kube-dns 的 ClusterIP 地址来达到目的但不推荐该方式。如果你使用的是云服务器在内网场景下可以将集群内的服务通过内网 SLB 进行暴露然后通过云服务商提供的解析服务添加 A 记录到该 SLB 的内网 IP 进行解析比如阿里云的 PrivateZone 服务。 5统一域名访问服务 我们可以实现在公网、内网和集群内部通过统一域名 foo.example.com 访问你的服务原理如下 集群内的服务 foo.default.svc.cluster.local 通过公网 SLB 进行了暴露且有域名 foo.example.com解析到该公网 SLB 的 IP。集群内服务 foo.default.svc.cluster.local 通过内网 SLB 进行了暴露且通过云解析 PrivateZone比如在阿里云在 VPC 内网中将 foo.example.com 解析到该内网 SLB 的 IP。在集群内部可以通过 Rewrite 插件将 foo.example.com CNAME 到foo.default.svc.cluster.local。 Corefile: |.:53 {errorshealth {lameduck 15s}readyrewrite stop {name regex foo.example.com foo.default.svc.cluster.localanswer name foo.default.svc.cluster.local foo.example.com}kubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpattl 30}prometheus :9153forward . /etc/resolv.conf {prefer_udp}cache 30loopreloadloadbalance}6禁止对对 IPv6类型的 AAAA 记录查询返回 如果 K8s 节点没有禁用 IPV6 的话容器内进程请求 CoreDNS 时的默认行为是同时发起 IPV4 和 IPV6 解析而通常我们只需要用到 IPV4当容器请求某个域名时CoreDNS 解析不到 IPV6 记录就会 forward 到 upstream 去解析如果到 upstream 需要经过较长时间(比如跨公网跨机房专线)就会拖慢整个解析流程的速度业务层面就会感知DNS 解析慢。 CoreDNS 有一个 template 的插件可以用它来禁用 IPV6 的解析只需要给 CoreDNS 加上如下的配置: Corefile: |.:53 {errorshealth {lameduck 15s}# 新增以下一行Template插件其它数据请保持不变。template IN AAAA .# ......}该配置的含义是在 CoreDNS 中将 AAAA 记录类型拦截返回域名不存在以减少不必要的网络通信。 2.使用 CoreDNS 的 Service 地址一般情况下是固定的类似于 kubernetes 这个 Service 地址一般就是第一个 IP 地址 10.96.0.1CoreDNS 的 Service 地址就是 10.96.0.10。该 IP 被分配后kubelet 会将使用 --cluster-dnsdns-service-ip 参数配置的 DNS 传递给每个容器。DNS 名称也需要域名本地域可以使用参数--cluster-domain default-local-domain 在 kubelet 中配置 ➜ ~ cat /var/lib/kubelet/config.yaml ...... clusterDNS: - 10.96.0.10 clusterDomain: cluster.local #当然这个可以改但一般是不会去修改的是约定俗成的。 ......注意点1 当我们去启动一个容器的时候它会把这里的clusterDNS地址给写入到我们容器的nameserver里面去那么当我们容器里面的namesrver是这个地址然后去做域名解析的时候是不是都会进入到这个10.96.0.10里面去而这个地址刚好是我们core dns的地址。所以最终解析还是进入到这个coredns里面来做的。 [rootmaster1 ~]#kubectl get svc -nkube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 none 53/UDP,53/TCP,9153/TCP 49d metrics-server ClusterIP 10.106.125.106 none 443/TCP 27d注意点2 文件/var/lib/kubelet/config.yaml里的clusterDomain: cluster.local就相当于在我们k8s集群里面就是我们service的一个域名后缀。all的以dns的形式访问service的时候它的一个后缀都是cluster.local。 我们前面说了如果我们建立的 Service 如果支持域名形式进行解析就可以解决我们的服务发现的功能那么利用 kubedns 可以将 Service 生成怎样的 DNS 记录呢 普通的 Service会生成 servicename.namespace.svc.cluster.local 的域名会解析到 Service 对应的 ClusterIP 上在 Pod 之间的调用可以简写成 servicename.namespace如果处于同一个命名空间下面甚至可以只写成 servicename 即可访问。 假如说我们有个svc叫做nginx-service那么该service在dns里的域名可以按如下来写nginx-service.default.svc.cluster.localnginx-service.default.svcnginx-service.default如果你的Pod和nigx-service在同一个namesapce也可以写成nginx-serviceHeadless Service无头服务就是把 clusterIP 设置为 None 的会被解析为指定 Pod 的 IP 列表同样还可以通过 podname.servicename.namespace.svc.cluster.local 访问到具体的某一个 Pod。 主服务 注意kubernetes这个service这个是谁创建的 [rootmaster1 ~]#kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 none 443/TCP 42d nginx-service ClusterIP 10.98.166.23 none 5000/TCP 5m57s这个kubernetes主服务(service)是系统自己创建的这个service是必须要有的不能随便被删除的。相当与是我们集群内部的一些应用他们要通过这个service去访问apiserver这个其实就是去关联到我们的apiserver而已。 我们可以去describe看下 [rootmaster1 ~]#kubectl describe svc kubernetes Name: kubernetes Namespace: default Labels: componentapiserverproviderkubernetes Annotations: none Selector: none Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10.96.0.1 IPs: 10.96.0.1 Port: https 443/TCP TargetPort: 6443/TCP Endpoints: 172.29.9.51:6443 #care Session Affinity: None Events: none可以看到这里的Endpoints其实就是到我们的apiserver那里去的。 其实就是给我们集群内部的一些pod去使用这个apiserver的因为一般来说 我们不太可能在集群内部去写上这个172.29.9.51:6443地址。 实战coredns测试(测试成功)-2023.2.18 实验环境 实验环境 1、win10,vmwrokstation虚机 2、k8s集群3台centos7.6 1810虚机1个master节点,2个node节点k8s versionv1.22.2containerd://1.5.5实验软件无 接下来我们来使用一个简单 Pod 来测试下 CoreDNS 的使用。 # dns-utils.yaml apiVersion: v1 kind: Pod metadata:name: dnsutils spec:containers:- name: dnsutilsimage: cnych/jessie-dnsutils:1.3 #当然这里使用busybox镜像也是可以的。command:- sleep- infinityimagePullPolicy: IfNotPresentrestartPolicy: Always直接应用上面的资源清单即可 [rootmaster1 ~]#kubectl apply -f dns-utils.yaml [rootmaster1 ~]#kubectl get pods dnsutils NAME READY STATUS RESTARTS AGE dnsutils 1/1 Running 0 115s一旦 Pod 处于运行状态我们就可以在该环境里执行 nslookup 命令如果你看到类似下列的内容则表示 DNS 是正常运行的。 [rootmaster1 ~]#kubectl exec -it dnsutils -- nslookup kubernetes.default Server: 10.96.0.10 Address: 10.96.0.10#53Name: kubernetes.default.svc.cluster.local Address: 10.96.0.1[rootmaster1 ~]#如果 nslookup 命令执行失败可以先检查下本地的 DNS 配置查看 resolv.conf 文件的内容 正常该文件内容如下所示 [rootmaster1 ~]#kubectl exec -it dnsutils -- cat /etc/resolv.conf search default.svc.cluster.local svc.cluster.local cluster.local nameserver 10.96.0.10 options ndots:5可以看到 nameserver 的地址 10.96.0.10该 IP 地址即是在安装 CoreDNS 插件的时候集群分配的一个固定的IP 地址我们可以通过下面的命令进行查看 [rootmaster1 ~]# kubectl get svc kube-dns -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 none 53/UDP,53/TCP,9153/TCP 75d也就是说我们这个 Pod 现在默认的 nameserver 就是 kube-dns 的地址。 现在我们来访问下前面我们创建的nginx-service 服务先在 Pod 中添加 wget 命令 [rootmaster1 ~]# kubectl exec -it dnsutils -- /bin/bash rootdnsutils:/# apt-get install wget -y注意这个debian镜像下载速度太慢了……不如使用busybox镜像。 然后我们去访问下 nginx-service 服务 rootdnsutils:/# wget -q -O- nginx-service.default.svc.cluster.local rootdnsutils:/#但是上面我们使用 wget 命令去访问 nginx-service 服务域名的时候被 hang 住了没有得到期望的结果这是因为上面我们建立 Service 的时候暴露的端口是 5000 rootdnsutils:/# wget -q -O- nginx-service.default.svc.cluster.local:5000 !DOCTYPE html html head titleWelcome to nginx!/title stylebody {width: 35em;margin: 0 auto;font-family: Tahoma, Verdana, Arial, sans-serif;} /style /head body h1Welcome to nginx!/h1 pIf you see this page, the nginx web server is successfully installed and working. Further configuration is required./ppFor online documentation and support please refer to a hrefhttp://nginx.org/nginx.org/a.br/ Commercial support is available at a hrefhttp://nginx.com/nginx.com/a./ppemThank you for using nginx./em/p /body /html rootdnsutils:/#加上 5000 端口就正常访问到服务。 需要注意的是 我这里的测试现象有点不一样。 dnsutils镜像 busybox镜像 再试一试访问nginx-service.default.svc、 nginxservice.default、 nginx-service 不出意外这些域名都可以正常访问到期望的结果。 rootdnsutils:/# wget -q -O- nginx-service.default.svc.cluster.local:5000 !DOCTYPE html html head titleWelcome to nginx!/title stylebody {width: 35em;margin: 0 auto;font-family: Tahoma, Verdana, Arial, sans-serif;} /style /head body h1Welcome to nginx!/h1 pIf you see this page, the nginx web server is successfully installed and working. Further configuration is required./ppFor online documentation and support please refer to a hrefhttp://nginx.org/nginx.org/a.br/ Commercial support is available at a hrefhttp://nginx.com/nginx.com/a./ppemThank you for using nginx./em/p /body /html rootdnsutils:/# wget -q -O- nginx-service.default.svc:5000 !DOCTYPE html html head titleWelcome to nginx!/title stylebody {width: 35em;margin: 0 auto;font-family: Tahoma, Verdana, Arial, sans-serif;} /style /head body h1Welcome to nginx!/h1 pIf you see this page, the nginx web server is successfully installed and working. Further configuration is required./ppFor online documentation and support please refer to a hrefhttp://nginx.org/nginx.org/a.br/ Commercial support is available at a hrefhttp://nginx.com/nginx.com/a./ppemThank you for using nginx./em/p /body /html rootdnsutils:/# wget -q -O- nginx-service.default:5000 !DOCTYPE html html head titleWelcome to nginx!/title stylebody {width: 35em;margin: 0 auto;font-family: Tahoma, Verdana, Arial, sans-serif;} /style /head body h1Welcome to nginx!/h1 pIf you see this page, the nginx web server is successfully installed and working. Further configuration is required./ppFor online documentation and support please refer to a hrefhttp://nginx.org/nginx.org/a.br/ Commercial support is available at a hrefhttp://nginx.com/nginx.com/a./ppemThank you for using nginx./em/p /body /html rootdnsutils:/# wget -q -O- nginx-service:5000 !DOCTYPE html html head titleWelcome to nginx!/title stylebody {width: 35em;margin: 0 auto;font-family: Tahoma, Verdana, Arial, sans-serif;} /style /head body h1Welcome to nginx!/h1 pIf you see this page, the nginx web server is successfully installed and working. Further configuration is required./ppFor online documentation and support please refer to a hrefhttp://nginx.org/nginx.org/a.br/ Commercial support is available at a hrefhttp://nginx.com/nginx.com/a./ppemThank you for using nginx./em/p /body /html rootdnsutils:/#到这里我们是不是就实现了在集群内部通过 Service 的域名形式进行互相通信了大家下去试着看看访问不同namespace 下面的服务呢 我们再来总结一下在 Kubernetes 集群内部域名的全称是 servicename.namespace.svc.cluster.local服务名就是 K8s 的 Service 名称比如当我们执行 curl s 的时候必须就有一个名为 s 的 Service 对象在容器内部会根据 /etc/resolve.conf 进行解析使用 nameserver 10.96.0.10 进行解析然后用字符串 s 依次带入 search 域进行查找分别是s.default.svc.cluster.local -- s.svc.cluster.local --s.cluster.local直到找到为止。 所以我们执行 curl s或者执行 curl s.default都可以完成 DNS 请求这 2 个不同的操作会分别进行不同的 DNS 查找步骤 // curl s可以一次性找到s default.svc.cluster.local s.default.svc.cluster.local// curl s.default第一次找不到s.default default.svc.cluster.local s.default.default.svc.cluster.local // 第二次查找可以找到s.default svc.cluster.local s.default.svc.cluster.local那么问题来了 curl s 要比 curl s.default 效率高吗 能简写就简写能帮我们省略几次dns解析过程。 答案是肯定的因为 curl s.default 多经过了一次 DNS 查询当执行 curl s.default 也就使用了带有命名空间的内部域名时容器的第一个 DNS 请求是 // s.default default.svc.cluster.local s.default.default.svc.cluster.local当请求不到 DNS 结果时使用下面的搜索域 // s.default svc.cluster.local s.default.svc.cluster.local进行请求此时才可以得到正确的 DNS 解析。 ndots测试 其实 /etc/resolv.conf 这个文件并不止包含 nameserver 和 search 域还包含了非常重要的一项 ndots 上面我们没有提及这个配置项。 / # cat /etc/resolv.conf search default.svc.cluster.local svc.cluster.local cluster.local nameserver 10.96.0.10 options ndots:5 / #ndots:5 表示如果查询的域名包含的点 . 不到 5 个那么进行 DNS 查找将使用非完全限定名称或者叫非绝对域名如果你查询的域名包含点数大于等于 5那么 DNS 查询默认会使用绝对域名进行查询。 比如我们请求的域名是 a.b.c.d.e这个域名中有 4 个点那么容器中进行 DNS 请求时会使用非绝对域名进行查找使用非绝对域名会按照 /etc/resolv.conf 中的 search 域走一遍追加匹配 a.b.c.d.e.default.svc.cluster.local. a.b.c.d.e.svc.cluster.local. a.b.c.d.e.cluster.local.直到找到为止如果走完了 search 域还找不到则使用 a.b.c.d.e. 作为绝对域名进行 DNS 查找。 我们通过抓包分析一个具体案例由于 CoreDNS 容器往往不具备 bash所以无法通过 kubectl exec 的方式进入容器内抓包我们可以给 CoreDNS 添加上 log 插件来记录解析日志。 [rootmaster1 ~]#kubectl get cm coredns -n kube-system -o yaml apiVersion: v1 data:Corefile: |.:53 {errorshealth {lameduck 5s}readykubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpattl 30}prometheus :9153forward . /etc/resolv.conf {max_concurrent 1000}cache 30loopreloadloadbalance} kind: ConfigMap metadata:creationTimestamp: 2022-12-04T22:25:08Zname: corednsnamespace: kube-systemresourceVersion: 248uid: 13ed16b1-cb31-492a-944c-a30a03e177e6 [rootmaster1 ~]#kubectl edit cm coredns -n kube-system ……log …… [rootmaster1 ~]#kubectl get cm coredns -n kube-system -o yaml apiVersion: v1 data:Corefile: |.:53 {errorsloghealth {lameduck 5s}readykubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpattl 30}prometheus :9153forward . /etc/resolv.conf {max_concurrent 1000}cache 30loopreloadloadbalance} kind: ConfigMap metadata:creationTimestamp: 2022-12-04T22:25:08Zname: corednsnamespace: kube-systemresourceVersion: 938524uid: 13ed16b1-cb31-492a-944c-a30a03e177e6[rootmaster1 ~]# kubectl get pods -n kube-system -l k8s-appkube-dns -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES coredns-7b884d5cb7-6jzn6 1/1 Running 2 (3d21h ago) 75d 10.244.0.11 master1 none none coredns-7b884d5cb7-gcszd 1/1 Running 2 (3d21h ago) 75d 10.244.0.10 master1 none none由于 CoreDNS 的 Pod 存在多个那么 DNS 请求可能会均分到所有 DNS 服务的容器上我们如果只查看单个 DNS服务容器抓到的包可能就不全了所以我们可以指定特定的一个 Pod 来进行 DNS 解析 1.域名中点数少于 5 个的情况比如对域名 a.b.c.d.ccccc 进行 DNS 解析请求 rootdnsutils:/# nslookup a.b.c.d.ccccc 10.244.0.11 Server: 10.244.0.11 Address: 10.244.0.11#53** server cant find a.b.c.d.ccccc: NXDOMAINrootdnsutils:/#对应 CoreDNS Pod 10.244.0.11 这个 Pod的日志如下所示 [rootmaster1 ~]#kubectl logs -f coredns-7b884d5cb7-6jzn6 -nkube-system .:53 [INFO] plugin/reload: Running configuration SHA512 591cf328cccc12bc490481273e738df59329c62c0b729d94e8b61db9961c2fa5f046dd37f1cf888b953814040d180f52594972691cd6ff41be96639138a43908 CoreDNS-1.9.3 linux/amd64, go1.18.2, 45b0a11 [INFO] Reloading [INFO] plugin/health: Going into lameduck mode for 5s [INFO] plugin/reload: Running configuration SHA512 f00fdccfaa4735680a8e1c1039784634259e55a73b0d1f92bb0bb09000f01852501d2fda805465f42467cb636637a06efa4674610b45b3d569a999ff1d701fb4 [INFO] Reloading complete [INFO] 127.0.0.1:38447 - 39263 HINFO IN 1756676467130346557.5690313054789561260. udp 57 false 512 NXDOMAIN qr,rd,ra 132 0.016539258s [INFO] 10.244.2.57:48637 - 28949 A IN a.b.c.d.ccccc.default.svc.cluster.local. udp 57 false 512 NXDOMAIN qr,aa,rd 150 0.000185532s [INFO] 10.244.2.57:35202 - 14814 A IN a.b.c.d.ccccc.svc.cluster.local. udp 49 false 512 NXDOMAIN qr,aa,rd 142 0.000130307s [INFO] 10.244.2.57:48540 - 23439 A IN a.b.c.d.ccccc.cluster.local. udp 45 false 512 NXDOMAIN qr,aa,rd 138 0.000111244s [INFO] 10.244.2.57:49119 - 6131 A IN a.b.c.d.ccccc. udp 31 false 512 NXDOMAIN qr,rd,ra 106 0.01328048s从上面的日志可以看出当点数少于 5 个的时候先加上搜索域去进行解析的解析失败后切换到下一个搜索域继续最后再加一个 . 进行解析 a.b.c.d.ccccc. 。 我们可以再请求一个正常的域名验证下 rootdnsutils:/# nslookup youdianzhishi.com 10.244.0.11 Server: 10.244.0.11 Address: 10.244.0.11#53Non-authoritative answer: Name: youdianzhishi.com Address: 39.106.22.102rootdnsutils:/#对应 CoreDNS 的日志为 [INFO] 10.244.2.57:47078 - 53361 A IN youdianzhishi.com.default.svc.cluster.local. udp 61 false 512 NXDOMAIN qr,aa,rd 154 0.00021077s [INFO] 10.244.2.57:46364 - 24256 A IN youdianzhishi.com.svc.cluster.local. udp 53 false 512 NXDOMAIN qr,aa,rd 146 0.000187543s [INFO] 10.244.2.57:54366 - 41723 A IN youdianzhishi.com.cluster.local. udp 49 false 512 NXDOMAIN qr,aa,rd 142 0.00014864s [INFO] 10.244.2.57:50899 - 11617 A IN youdianzhishi.com. udp 35 false 512 NOERROR qr,rd,ra 68 0.00974118s可以看到仍然是先走 search 域最后再添加的一个 . 进行解析也就是绝对域名这样来看肯定就存在浪费请求的情况当然我们在请求的时候直接手动在域名后面加上一个 . 直接变成绝对域名解析也是可以避免走 search 域的 rootdnsutils:/# nslookup youdianzhishi.com. 10.244.0.11 Server: 10.244.0.11 Address: 10.244.0.11#53Non-authoritative answer: Name: youdianzhishi.com Address: 39.106.22.102rootdnsutils:/#对应的 CoreDNS 日志 2.域名中点数/5 个的情况比如对域名 a.b.c.d.e.ccccc 进行 DNS 解析请求 rootdnsutils:/# nslookup a.b.c.d.e.ccccc.10.244.0.11 Server: 10.96.0.10 Address: 10.96.0.10#53** server cant find a.b.c.d.e.ccccc.10.244.0.11: NXDOMAINrootdnsutils:/#对应 CoreDNS 的日志如下所示 [INFO] 10.244.2.57:58995 - 3245 A IN a.b.c.d.e.ccccc.10.244.0.11. udp 45 false 512 NXDOMAIN qr,rd,ra 120 0.145085181s可以看到现在没有进行 search 域匹配了。 上面我们提到了可以在请求的域名末尾加一个 . 来对 DNS 请求进行优化但是我们平时在使用的时候没有这种习惯在Kubernetes 中默认设置了 ndots 值为 5是因为Kubernetes 认为内部域名最长为 5要保证内部域名的请求优先走集群内部的 DNS而不是将内部域名的 DNS 解析请求有打到外网的机会所以 Kubernetes 设置 ndots为 5 是一个比较合理的行为。 但是我们也可以自己去定制这个长度为自己的业务 Pod 单独配置 ndots 即可如下所示 # dns-demo.yaml apiVersion: v1 kind: Pod metadata:name: dns-demo spec:containers:- name: dnsutilsimage: cnych/jessie-dnsutils:1.3 #当然这里使用busybox镜像也是可以的。command:- sleep- infinityimagePullPolicy: IfNotPresentrestartPolicy: AlwaysdnsConfig:options:- name: ndotsvalue: 1创建该 Pod 后我们可以查看下对应的 /etc/resolv.conf 文件 [rootmaster1 ~]#kubectl apply -f dns-demo.yaml [rootmaster1 ~]#kubectl exec -it dns-demo -- /bin/bash rootdns-demo:/# cat /etc/resolv.conf search default.svc.cluster.local svc.cluster.local cluster.local nameserver 10.96.0.10 options ndots:1 rootdns-demo:/#可以看到对应的 ndots 值现在是 1 了。现在我们来做一次 dns 解析再观察下对应的 CoreDNS 日志 rootdns-demo:/# nslookup youdianzhishi.com 10.244.0.11 Server: 10.244.0.11 Address: 10.244.0.11#53Non-authoritative answer: Name: youdianzhishi.com Address: 39.106.22.102rootdns-demo:/#对应的 CoreDNS 日志 [INFO] 10.244.2.59:45260 - 45830 A IN youdianzhishi.com. udp 35 false 512 NOERROR qr,aa,rd,ra 68 0.000116046s可以看到直接就是绝对域名的形式进行解析了所以这种方法也是可以对解析过程进行优化的。 进入容器网络命名空间进行抓包 ⚠️ 补充说明 我们这里是给 CoreDNS 添加的一个 log 插件来观察的解析日志在实际的工作中可能我们可能也需要对一些应用进行抓包观察可能单纯通过日志没办法获取相关信息而该应用镜像中又不包含抓包需要的 tcpdump 命令这个时候应该如何来进行抓包呢 我们这里还是以 CoreDNS 为例要抓去 DNS 容器的包就需要先进入到该容器的网络中去。 [rootmaster1 ~]#kubectl get pods -n kube-system -l k8s-appkube-dns -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES coredns-7b884d5cb7-6jzn6 1/1 Running 2 (3d22h ago) 75d 10.244.0.11 master1 none none coredns-7b884d5cb7-gcszd 1/1 Running 2 (3d22h ago) 75d 10.244.0.10 master1 none none比如 coredns-7b884d5cb7-6jzn6 Pod 位于节点 master1我们可以先进入该节点使用 crictl命令找到该 Pod 对应的容器 ID [rootmaster1 ~]#crictl ps CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD 19ece1f877db4 5185b96f0becf 3 days ago Running coredns 2 55840d6e4467c coredns-7b884d5cb7-6jzn6 ……我们这里对应的容器 ID 就是 19ece1f877db4 通过下面的命令找到它的 Pid [rootmaster1 ~]# crictl inspect -o go-template --template {{.info.pid}} 19ece1f877db4 15106然后进入该容器的网络 Namespace 中去 [rootmaster1 ~]# nsenter -n -t 15106 [rootmaster1 ~]#然后使用 tcpdump 命令抓取 DNS 网络包 [rootmaster1 ~]# nsenter -n -t 15106 [rootmaster1 ~]#tcpdump -i eth0 udp dst port 53 -bash: tcpdump: command not found [rootmaster1 ~]#ip a 1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever 2: eth0if9: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1450 qdisc noqueue state UP group defaultlink/ether e2:9c:cd:3f:c9:b9 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 10.244.0.11/24 brd 10.244.0.255 scope global eth0valid_lft forever preferred_lft foreverinet6 fe80::e09c:cdff:fe3f:c9b9/64 scope linkvalid_lft forever preferred_lft forever [rootmaster1 ~]#注意这里有报错了的 是因为自己宿主机上没有安装tcpdump命令 [rootmaster1 ~]#yum install -y tcpdump …… Installed:tcpdump.x86_64 14:4.9.2-4.el7_7.1Dependency Installed:libpcap.x86_64 14:1.5.3-13.el7_9Complete! ……再次执行命令 [rootmaster1 ~]# nsenter -n -t 15106 [rootmaster1 ~]#tcpdump -i eth0 udp dst port 53 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes同样在上面的容器中进行 youdianzhishi.com 域名查找 rootdnsutils:/# nslookup youdianzhishi.com 10.244.0.11 Server: 10.244.0.11 Address: 10.244.0.11#53Non-authoritative answer: Name: youdianzhishi.com Address: 39.106.22.102rootdnsutils:/#此时就可以看到对应的数据包 [rootmaster1 ~]#tcpdump -i eth0 udp dst port 53 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 10:45:11.129972 IP 10.244.2.57.40860 master1.domain: 33074 A? youdianzhishi.com.default.svc.cluster.local. (61) 10:45:11.130457 IP master1.44571 public2.alidns.com.domain: 48878 PTR? 11.0.244.10.in-addr.arpa. (42) 10:45:11.131554 IP 10.244.2.57.40965 master1.domain: 44300 A? youdianzhishi.com.svc.cluster.local. (53) 10:45:11.133338 IP 10.244.2.57.34133 master1.domain: 33419 A? youdianzhishi.com.cluster.local. (49) 10:45:11.134212 IP 10.244.2.57.47873 master1.domain: 17847 A? youdianzhishi.com. (35) 10:45:11.134430 IP master1.41844 public2.alidns.com.domain: 15306 [1au] A? youdianzhishi.com. (46) 10:45:11.225248 IP master1.48344 public2.alidns.com.domain: 30197 PTR? 57.2.244.10.in-addr.arpa. (42) 10:45:11.294293 IP master1.39999 public2.alidns.com.domain: 18521 PTR? 6.6.6.223.in-addr.arpa. (40)当然也可以利用 kubectl-debug 这样的工具进行辅助调试但是进入容器网络命名空间进行抓包是最基本的知识点需要我们掌握。 测试结束。 4、Pod 的 DNS 策略 DNS 策略可以单独对 Pod 进行设定目前 Kubernetes 支持以下特定 Pod 的 DNS 策略。这些策略可以在 Pod 规范中的 dnsPolicy 字段设置 Default: 有人说 Default 的方式是使用宿主机的方式这种说法并不准确。这种方式其实是让 kubelet 来决定使用何种 DNS 策略。而 kubelet 默认的方式就是使用宿主机的 /etc/resolv.conf可能这就是有人说使用宿主机的 DNS 策略的方式吧。但是kubelet 是可以灵活来配置使用什么文件来进行DNS策略的我们完全可以使用 kubelet 的参数 –resolv-conf/etc/resolv.conf 来决定你的 DNS 解析文件地址。 ClusterFirst: 这种方式表示 Pod 内的 DNS 使用集群中配置的 DNS 服务简单来说就是使用 Kubernetes 中 kubedns 或 coredns 服务进行域名解析。如果解析不成功才会使用宿主机的 DNS 配置进行解析。 ClusterFirstWithHostNet在某些场景下我们的 Pod 是用 HostNetwork 模式启动的一旦用 HostNetwork 模式表示这个 Pod 中的所有容器都要使用宿主机的 /etc/resolv.conf 配置进行 DNS 查询但如果你还想继续使用 Kubernetes 的DNS服务那就将 dnsPolicy 设置为 ClusterFirstWithHostNet。 None: 表示空的 DNS 设置这种方式一般用于想要自定义 DNS 配置的场景往往需要和 dnsConfig 配合一起使用达到自定义 DNS 的目的。(下面会讲到的) 注意Default 并不是默认的 DNS 策略如果未明确指定 dnsPolicy则使用 ClusterFirst。 实战Pod的DNS策略-2023.2.18(测试成功) 实验环境 实验环境 1、win10,vmwrokstation虚机 2、k8s集群3台centos7.6 1810虚机1个master节点,2个node节点k8s versionv1.22.2containerd://1.5.5实验软件(无) 下面的示例显示了一个 Pod其 DNS 策略设置为 ClusterFirstWithHostNet因为它已将 hostNetwork 设置为 true。 编写资源清单文件 #pod.yaml apiVersion: v1 kind: Pod metadata:name: busyboxnamespace: default spec:containers:- image: busybox:1.28.3command:- sleep- 3600imagePullPolicy: IfNotPresentname: busyboxrestartPolicy: AlwayshostNetwork: truednsPolicy: ClusterFirstWithHostNet部署并进入到pod查看nameserver [rootmaster1 ~]#kubectl apply -f pod.yaml pod/busybox created [rootmaster1 ~]#kubectl get po NAME READY STATUS RESTARTS AGE busybox 1/1 Running 0 7s[rootmaster1 ~]#kubectl exec busybox -- cat /etc/resolv.conf search default.svc.cluster.local svc.cluster.local cluster.local nameserver 10.96.0.10 options ndots:5 [rootmaster1 ~]#kubectl get svc kube-dns -nkube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 none 53/UDP,53/TCP,9153/TCP 51d可以看到当pod里使用了hostNetwork模式且dnsPolicy配置为ClusterFirstWithHostNet的之后此时容器里的nameserver使用的是Kubernetes 的DNS服务。 把dnsPolicy配置为ClusterFirst 但此时若把dnsPolicy配置为ClusterFirst按理说此时的容器里的nameserver应该使用的是宿主机的/etc/resolv.conf 配置进行 DNS 查询我们来测试下 #pod.yaml apiVersion: v1 kind: Pod metadata:name: busybox #这里改个名称namespace: default spec:containers:- image: busybox:1.28.3command:- sleep- 3600imagePullPolicy: IfNotPresentname: busyboxrestartPolicy: AlwayshostNetwork: truednsPolicy: ClusterFirst #将上面的ClusterFirstWithHostNet修改为ClusterFirst。修改完后重新部署并观察现象 [rootmaster1 ~]#kubectl apply -f pod.yaml pod/busybox1 created [rootmaster1 ~]#kubectl get po busybox NAME READY STATUS RESTARTS AGE busybox 1/1 Running 0 7s [rootmaster1 ~]#kubectl exec busybox -- cat /etc/resolv.conf nameserver 223.6.6.6 [rootmaster1 ~]#可以发现此时的容器里的nameserver应该使用的是宿主机的/etc/resolv.conf 配置进行 DNS 查询符合预期效果测试结束。 ⚠️ 注意查看kube-proxy pod的DNS策略 我们的k8s集群的kube-proxy组件它开启了hostNetwork:true但是它的的dnsPolicy却是ClusterFirst难道这里的kube-proxy pod不使用coredns服务吗而是直接使用的宿主机的dns服务这个自己有些疑问—是的 实验结束。 5、Pod 的 DNS 配置 Pod 的 DNS 配置可让用户对 Pod 的 DNS 设置进行更多控制。dnsConfig 字段是可选的它可以与任何 dnsPolicy 设置一起使用。 但是当 Pod 的 dnsPolicy 设置为 “None” 时必须指定 dnsConfig 字段。 用户可以在 dnsConfig 字段中可以指定以下属性 nameservers将用作于 Pod 的 DNS 服务器的 IP 地址列表。 最多可以指定 3 个 IP 地址。当 Pod 的 dnsPolicy 设置为 “None” 时列表必须至少包含一个 IP 地址否则此属性是可选的。所列出的服务器将合并到从指定的 DNS 策略生成的基本名称服务器并删除重复的地址。searches用于在 Pod 中查找主机名的 DNS 搜索域的列表。此属性是可选的。 指定此属性时所提供的列表将合并到根据所选 DNS 策略生成的基本搜索域名中。重复的域名将被删除Kubernetes 最多允许 6 个搜索域。options可选的对象列表其中每个对象可能具有 **name 属性必需**和 value 属性可选。此属性中的内容将合并到从指定的 DNS 策略生成的选项。重复的条目将被删除。 实战Pod的DNS设置-2023.2.18(测试成功) 实验环境 实验环境 1、win10,vmwrokstation虚机 2、k8s集群3台centos7.6 1810虚机1个master节点,2个node节点k8s versionv1.22.2containerd://1.5.5实验软件(无) 部署pod资源 以下是具有自定义 DNS 设置的 Pod 示例 #dnsconfig.yaml apiVersion: v1 kind: Pod metadata:namespace: defaultname: dns-example spec:containers:- name: testimage: nginxdnsPolicy: NonednsConfig:nameservers:- 1.2.3.4searches:- ns1.svc.cluster-domain.example- my.dns.search.suffixoptions:- name: ndotsvalue: 2- name: edns0创建上面的 Pod 后容器 test 会在其 /etc/resolv.conf 文件中获取以下内容 [rootmaster1 ~]#kubectl apply -f dnsconfig.yaml pod/dns-example created [rootmaster1 ~]#kubectl get po ]NAME READY STATUS RESTARTS AGE dns-example 1/1 Running 0 40s [rootmaster1 ~]#kubectl exec dns-example -- cat /etc/resolv.conf search ns1.svc.cluster-domain.example my.dns.search.suffix nameserver 1.2.3.4 options ndots:2 edns0 [rootmaster1 ~]#实验结束。 关于我 我的博客主旨 排版美观语言精炼文档即手册步骤明细拒绝埋坑提供源码本人实战文档都是亲测成功的各位小伙伴在实际操作过程中如有什么疑问可随时联系本人帮您解决问题让我们一起进步 微信二维码 x2675263825 舍得 qq2675263825。 微信公众号 《云原生架构师实战》 博客 www.onlyyou520.com csdn https://blog.csdn.net/weixin_39246554?spm1010.2135.3001.5421 知乎 https://www.zhihu.com/people/foryouone 最后 好了关于本次就到这里了感谢大家阅读最后祝大家生活快乐每天都过的有意义哦我们下期见
http://www.hkea.cn/news/14350402/

相关文章:

  • 怎样建网站得花多少钱qq手机版
  • 买个网站域名要多少钱dw制作wap网站怎么做
  • 版式网站有哪些百度网盟推广官方网站
  • 宜春市城乡规划建设局网站渭南建设网
  • python网站开发工程师win10系统优化软件哪个好
  • 企业网站免费建设工具重庆市建筑工程信息官方网站
  • 自适应网站设计规范苏州注册公司网上申请入口
  • 国内常见响应式网站wordpress addaction
  • 网站推广策划的思路包括哪些内容请公司建网站
  • 无锡seo网站推广费用安卓开发者官网
  • 手机上自己做网站吗网站建设 加盟
  • 怎么做娱乐网站免费咨询网站
  • wordpress仿站抓取软件如何设计旅游网站的域名
  • 公司怎么注册网站免费视频拍摄和剪辑怎么学
  • 海口网站建设方案咨询frp做网站
  • 建设网站的一般过程做游戏的php网站有哪些
  • 做机电预算的网站网站备案 公司名称关联性
  • 导出wordpress用户seo培训网
  • 代做毕设网站可信么注册公司需要几个人员
  • 免费建站的网站能做影视网站吗网站建设项目运营岗
  • 制作网站规划书哈尔滨做设计和网站的公司吗
  • 哪个网站做服装定制好wordpress密码忘
  • 小说阅读网站建设市场需求分析如何创建手机网站
  • 架设销售网站成都百度
  • 做网站平台的公司有哪些ios开发网站app
  • 网站怎样自动文字排版网页设计的注意事项
  • 北京保障性住房建设投资中心网站网站开发亿玛酷适合5
  • 培训行业门户网站建设重庆知名网站制作公司
  • 做医美设计的网站你喜欢的公司网站
  • 电子商务网站建设课设学生体会网站开发项目计划