优化网站公司外包,成都设计公司工装,兰州网页设计培训,百度关键词搜索推广一、概述在 Kubernetes 中#xff0c;服务发现有几种方式#xff1a;基于环境变量的方式基于内部域名的方式基本上#xff0c;使用环境变量的方式很少#xff0c;主要还是使用内部域名这种服务发现的方式。其中#xff0c;基于内部域名的方式#xff0c;涉及到 Kubernete…一、概述在 Kubernetes 中服务发现有几种方式基于环境变量的方式基于内部域名的方式基本上使用环境变量的方式很少主要还是使用内部域名这种服务发现的方式。其中基于内部域名的方式涉及到 Kubernetes 内部域名的解析而 kubedns是 Kubernetes 官方的 DNS 解析组件。从 1.11 版本开始kubeadm 已经使用第三方的 CoreDNS 替换官方的 kubedns 作为 Kubernetes 集群的内部域名解析组件。Kubernetes 中的域名是如何解析的在 Kubernetes 中比如服务 a 访问服务 b对于同一个 Namespace下可以直接在 pod 中通过 curl b 来访问。对于跨 Namespace 的情况服务名后边对应 Namespace即可。比如 curl b.default。那么使用者这里边会有几个问题服务名是什么为什么同一个 Namespace 下直接访问服务名即可不同 Namespace 下需要带上 Namespace 才行为什么内部的域名可以做解析原理是什么DNS 如何解析依赖容器内 resolv 文件的配置cat /etc/resolv.conf nameserver 10.10.0.3 search default.svc.cluster.local svc.cluster.local cluster.local options ndots:5这个文件中配置的 DNS Server一般就是 K8S 中kubedns 的 Service 的 ClusterIP这个IP是虚拟IP无法ping但可以访问。service 是否可以ping取决于 svc使用iptables 以及ipvs的区别。如果pod使用dns策略为clusterfirst的时候 要经过 kubedns 的虚拟IP 10.10.0.3 进行解析不论是 Kubernetes 内部域名还是外部的域名。二、pod DNS策略Kubernetes 中 Pod 的 DNS 策略有四种类型。DefaultPod 继承所在主机上的 DNS 配置ClusterFirstK8s 的默认设置先在 K8s 集群配置的 coreDNS 中查询查不到的再去继承自主机的上游 nameserver 中查询dnsPolicy: ClusterFirstClusterFirstWithHostNet对于网络配置为 hostNetwork 的 Pod 而言其 DNS 配置规则与 ClusterFirst 一致None忽略 K8s 环境的 DNS 配置只认 Pod 的 dnsConfig 设置。dnsPolicy: None dnsConfig: nameservers: - 114.114.114.114 searches: - default.svc.cluster.local options: - name: ndots value: 5 ###默认为5三、CoreDns解析规则在部署 pod 的时候 kubelet 在起容器的时候会将其 DNS 解析配置初始化成集群内的配置。因此在每个pod里面都会有/etc/resolv.conf文件通过修改其中的配置可以更改DNS的查询规则如下启动一个pod查看/etc/resolv.conf配置[rootmypod /]# cat etc/resolv.conf search default.svc.test.com svc.test.com test.com nameserver 169.254.25.10 ####我的环境中使用了nodelocaldns,这个地址是nodelocaldns的地址 options ndots:5 [rootmypod /]# #在集群中 pod 之间互相用 svc name 访问的时候会根据 resolv.conf 文件的 DNS 配置来解析域名nameserver集群中的DNS服务器IP一般来说就是CoreDNS的ClusterIPsearch需要搜索的域默认情况下会从该pod所属的namespace开始逐级补充#解析域名的时候将要访问的域名依次带入 search 域进行 DNS 查询。 #例如在pod 中访问一个域名为 nginx 的服务其进行的 DNS 域名查询的顺序是 nginx.default.svc.test.com. - nginx.svc.test.com. - nginx.test.com. #按照上述顺序直到查到为止options ndots触发上面的search的域名点数’.在K8S中默认为5上限15例如test.com这个域名的ndots是1test.com.这个域名的ndots才是2需要注意所有域名其实都有一个根域.因此test.com的全称应该是test.com.。如果dnots 指定查询的域名包含的点 “.” 小于 5则先走 search 域再用绝对域名如果查询的域名包含点数大于或等于 5则先用绝对域名再走 search 域。#例如当ndots大于等于5时访问的是 a.b.c.e.f.g 那么域名查找的顺序如下 a.b.c.e.f.g. - a.b.c.e.f.g.default.svc.test.com. - a.b.c.e.f.g.svc.test.com. - a.b.c.e.f.g.test.com. #例如当ndots小于5时访问的是 a.b.c.e. 那么域名查找的顺序如下 a.b.c.e.default.svc.test.com. - a.b.c.e.svc.test.com. - a.b.c.e.test.com. - a.b.c.e. 四、pod之间通信通过svc的方式通信在 K8s 中Pod 之间通过 svc 访问的时候会经过 DNS 域名解析再拿到 ip 通信。而 K8s 的域名全称为service-name.namespace.svc.test.com通常只需将 svc name 当成域名就能访问到 pod。1:使用deploy启动一个nginx的podsvc名称为nginx-svc,如下 --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: app: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: docker.io/library/nginx:latest imagePullPolicy: IfNotPresent ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-svc spec: selector: app: nginx ports: - port: 80 protocol: TCP targetPort: 80 type: ClusterIP 查看pod中/etc/resolv.conf配置如下 rootnginx-5977dc5756-lcmwq:/# cat etc/resolv.conf search default.svc.test.com svc.test.com test.com nameserver 169.254.25.10 options ndots:5 rootnginx-5977dc5756-lcmwq:/# 2:使用另外一个pod访问nginx-svc这个域名如下 [rootmaster yaml]# kubectl exec -it mypod bash kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. [rootmypod /]# ping nginx-svc PING nginx-svc.default.svc.test.com (10.10.23.221) 56(84) bytes of data. 64 bytes from nginx-svc.default.svc.test.com (10.10.23.221): icmp_seq1 ttl64 time0.152 ms 64 bytes from nginx-svc.default.svc.test.com (10.10.23.221): icmp_seq2 ttl64 time0.143 ms 64 bytes from nginx-svc.default.svc.test.com (10.10.23.221): icmp_seq3 ttl64 time0.114 ms ^C --- nginx-svc.default.svc.test.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev 0.114/0.136/0.152/0.018 ms [rootmypod /]# ############################# 返回的nginx-svc的地址为10.10.23.221此地址为nginx-svc的地址如下 [rootmaster yaml]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-svc ClusterIP 10.10.23.221 none 80/TCP 2d17h [rootmaster yaml]# ############################# 如果要访问其他ns的svc需要带上ns name即可如下 [rootmaster yaml]# kubectl exec -it mypod bash kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. [rootmypod /]# ping harbor-core ping: harbor-core: Name or service not known ###不添加ns的话无法解析habor-core [rootmypod /]# ping harbor-core.harbor PING harbor-core.harbor.svc.test.com (10.10.30.184) 56(84) bytes of data. 64 bytes from harbor-core.harbor.svc.test.com (10.10.30.184): icmp_seq1 ttl64 time0.095 ms 64 bytes from harbor-core.harbor.svc.test.com (10.10.30.184): icmp_seq2 ttl64 time0.130 ms 64 bytes from harbor-core.harbor.svc.test.com (10.10.30.184): icmp_seq3 ttl64 time0.165 ms ^C --- harbor-core.harbor.svc.test.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2001ms rtt min/avg/max/mdev 0.095/0.130/0.165/0.028 ms [rootmypod /]#通过hostname和subdomain通信在 K8s 中如果不指定 pod 的 hostname其默认为 pod.metadata.name通过 spec.hostname 字段可以自定义另外还可以给 pod 设置 subdomain通过 spec.subdomain 字段。如下#启动pod如下 --- apiVersion: v1 kind: Pod metadata: name: nginx labels: app: web spec: hostname: nginx ####设置hostnam为nginx subdomain: subdomain-test #### containers: - name: nginx image: docker.io/library/nginx:latest imagePullPolicy: IfNotPresent dnsPolicy: None dnsConfig: nameservers: - 114.114.114.114 searches: - default.svc.test.com options: - name: ndots value: 5 ###默认为5 --- apiVersion: v1 kind: Service metadata: name: subdomain-test spec: selector: app: web ports: - port: 80 targetPort: 80 protocol: TCP #启动pod查看/etc/hosts文件 [rootmaster yaml]# kubectl get po -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 0 6s 10.10.92.25 node3 none none [rootmaster yaml]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE subdomain-test ClusterIP 10.10.7.174 none 80/TCP 15s [rootk8s-master ~]# dig 10.96.0.10 nginx.subdomain-test.default.svc.cluster.local ; DiG 9.11.36-RedHat-9.11.36-14.el8_10 10.96.0.10 nginx.subdomain-test.default.svc.cluster.local ; (1 server found) ;; global options: cmd ;; Got answer: ;; WARNING: .local is reserved for Multicast DNS ;; You are currently testing what happens when an mDNS query is leaked to DNS ;; -HEADER- opcode: QUERY, status: NOERROR, id: 50420 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; WARNING: recursion requested but not available ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ; COOKIE: 793a61ce1b4aae71 (echoed) ;; QUESTION SECTION: ;nginx.subdomain-test.default.svc.cluster.local. IN A ;; ANSWER SECTION: nginx.subdomain-test.default.svc.cluster.local. 30 IN A 10.244.169.187 ;; Query time: 1 msec ;; SERVER: 10.96.0.10#53(10.96.0.10) ;; WHEN: 五 11月 29 03:51:09 EST 2024 ;; MSG SIZE rcvd: 149 #通过其他pod 访问nginx.subdomain,如下 [rootmaster yaml]# kubectl exec -it mypod bash kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. [rootmypod /]# [rootmypod /]# [rootmypod /]# ping nginx.subdomain-test PING nginx.subdomain-test.default.svc.test.com (10.10.92.25) 56(84) bytes of data. 64 bytes from nginx.subdomain-test.default.svc.test.com (10.10.92.25): icmp_seq1 ttl62 time1.91 ms 64 bytes from nginx.subdomain-test.default.svc.test.com (10.10.92.25): icmp_seq2 ttl62 time0.902 ms 64 bytes from nginx.subdomain-test.default.svc.test.com (10.10.92.25): icmp_seq3 ttl62 time1.01 ms ^C --- nginx.subdomain-test.default.svc.test.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev 0.902/1.278/1.914/0.452 ms #如上返回的地址为pod本身的ip地址 五、CoreDns Corefile 文件CoreDNS 实现了应用的插件化用户可以选择所需的插件编译到可执行文件中CoreDNS 的配置文件是 Corefile 形式的以下是CoreDns的configmap的配置[rootmaster yaml]# kubectl -n kube-system get cm coredns -o yaml apiVersion: v1 data: Corefile: | .:53 { errors health { lameduck 5s } ready kubernetes test.com in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa ttl 30 } prometheus :9153 forward . /etc/resolv.conf { max_concurrent 1000 } cache 30 loop reload loadbalance } kind: ConfigMap metadata: creationTimestamp: 2023-12-08T17:18:27Z name: coredns namespace: kube-system resourceVersion: 224 uid: ccf7598d-8b5c-48db-9230-7a539d6c7e98 [rootmaster yaml]#配置文件分析#第一部分 errors health { lameduck 5s } coredns内部插件错误日志以及健康监测等其他插件可以参考https://coredns.io/plugins/kubernetes/ #第二部分 kubernetes test.com in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa ttl 30 } #指明 test.com 后缀的域名都是 kubernetes 内部域名coredns 会监听 service 的变化来维护域名关系test.com 相关域名都在这里解析。 #ttl 30设置标准的DNS域名TTL默认值为 5 秒。允许的最小 TTL 为 0 秒最大值为 3600 秒。将 TTL 设置为 0 将防止记录被缓存。 #pods insecure总是从请求中返回带有 IP 的 A 记录不检查 k8s即查询域名1-2-3-4.ns.pod.cluster.local.的时候不论是否存在一个IP地址为1.2.3.4的pod都返回这个结果给客户端。如果与通配符 SSL 证书一起被恶意使用此选项很容易被滥用。提供此选项是为了向后兼容 kube-dns。 #fallthrough in-addr.arpa ip6.arpa正常情况下一个客户端对CoreDNS发起了一个DNS查询如果该记录不存在那么就会直接返回一个NXDOMAIN的响应。 #第三部分 forward . /etc/resolv.conf { max_concurrent 1000 } #指 coredns 中没有找到记录则去 /etc/resolv.conf 中的 nameserver 请求解析而 coredns 容器中的 /etc/resolv.conf 是继承自宿主机的。实际是如果不是 k8s 内部域名就会去默认的 dns 服务器请求解析并返回给 coredns 的请求者。 #第四部分 prometheus :9153 cache 30 loop reload loadbalance #prometheusCoreDNS 的监控地址为 http://localhost:9153/metrics 满足 Prometheus 的格式。 #cache允许缓存 #loop如果找到循环则检测简单的转发循环并停止 CoreDNS 进程。 #reload允许 Corefile 的配置自动更新。在更改 ConfigMap 后两分钟修改生效 #loadbalance这是一个循环 DNS 负载均衡器可以在答案中随机化 AAAAA 和 MX 记录的顺序。 #第五部分 #当某个域名服务不在集群内部时为了让pod可以访问可以在corefile中添加host选项如下 hosts { 192.168.10.10 edu.com fallthrough }案例添加外部解析在 Kubernetes 1.28 版本中如果您想要通过 CoreDNS 的 ConfigMap 添加外部指定主机名的解析可以使用 CoreDNS 的hosts插件。以下是如何配置 CoreDNS 的 ConfigMap 以添加hosts字段的示例获取当前 CoreDNS ConfigMap 您可以通过以下命令获取当前的 CoreDNS ConfigMap 配置kubectl get cm coredns -n kube-system -o yaml coredns-configmap.yaml编辑 CoreDNS ConfigMap 使用编辑器打开coredns-configmap.yaml文件您将看到 CoreDNS 的配置文件Corefile。在这个文件中您可以添加hosts插件的配置。添加 hosts 插件配置 在Corefile中添加hosts部分例如如果您想要将域名git.k8s.local解析到 IP 地址10.151.30.11可以添加如下配置apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system data: Corefile: | .:53 { errors health { lameduck 5s } ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa } hosts { 10.151.30.11 git.k8s.local fallthrough } prometheus :9153 forward . /etc/resolv.conf { max_concurrent 1000 } cache 30 loop reload loadbalance }在这个配置中hosts插件被用来指定特定的 IP 地址和主机名映射。fallthrough指令表示如果请求的域名不在hosts部分定义则请求将被转发到下一个插件处理。应用更改 保存更改后的coredns-configmap.yaml文件并使用以下命令应用更改kubectl apply -f coredns-configmap.yaml重启 CoreDNS Pod 更改 ConfigMap 后您需要重启 CoreDNS Pod 以使更改生效。可以通过以下命令删除现有的 CoreDNS Podkubectl delete pod -n kube-system -l k8s-appkube-dns这将触发 CoreDNS Pod 的重启新的 Pod 将使用更新后的 ConfigMap 配置。通过以上步骤您可以在 Kubernetes 1.28 版本中通过 CoreDNS 的 ConfigMap 添加外部指定主机名的解析。这种方法允许您自定义 DNS 解析规则以满足集群内外的域名解析需求。验证[rootk8s-master ~]# dig 10.96.0.10 git.k8s.local ; DiG 9.11.36-RedHat-9.11.36-14.el8_10 10.96.0.10 git.k8s.local ; (1 server found) ;; global options: cmd ;; Got answer: ;; WARNING: .local is reserved for Multicast DNS ;; You are currently testing what happens when an mDNS query is leaked to DNS ;; -HEADER- opcode: QUERY, status: NOERROR, id: 51965 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; WARNING: recursion requested but not available ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ; COOKIE: e37b3a494b869230 (echoed) ;; QUESTION SECTION: ;git.k8s.local. IN A ;; ANSWER SECTION: git.k8s.local. 30 IN A 10.151.30.11 ;; Query time: 1 msec ;; SERVER: 10.96.0.10#53(10.96.0.10) ;; WHEN: 五 11月 29 04:04:09 EST 2024 ;; MSG SIZE rcvd: 83