即便Service有了IP,但是若集群上有1000+Service,使用IP地址去访问是不可能的事情,所以我们需要以Service的名称来访问服务。
由于k8s上的服务是动态管理的,随时有可能创建删除。如果使用传统的DNS解析那么每一次创建一个服务就得去手动管理其解析记录。
服务发现在it领域有很多种解决方法,如Zookeeper,Euraka,Consul等。如果使用这些方法的话服务注册和发现能很好解决,但名称解析依然无法联动,因而k8s没有使用这总服务发现机制,而是将传统的DNS服务直接提供了一个云原生解决方案,它支持从APIServer上动态加载相关的Service信息及端点信息,并自动生成资源记录。
这种DNS就成了k8s上服务注册和服务发现的动态总线:kubeDNS。
其实现方案上有3代:
第一代:SkyDNS
第二代:KubeDNS
第三代:CoreDNS
K8S的服务发现 在K8S中服务发现有两种方法,基于环境变量或基于DNS服务。
基于环境变量的服务发现 在k8s中基于环境变量的方法又有两种:
(1)Kubernetes Service环境变量 Kubernetes为每个Service资源生成包括以下形式的环境变量在内一系列环境变量,在同一名称空间中创建的Pod对象都会自动拥有这些变量:
1 2 {SVCNAME}_SERVICE_HOST {SVCNAME}_SERVICE_PORT
default名称空间:创建的demoapp Service,意味着default名称空间下的每个Pod内部会被自动注入 DEMOAPP_SERVICE_HOST:ClusterIP , DEMOAPP_SERVICE_PORT=80
#####(2)Docker Link形式的环境变量
Docker使用–link选项实现容器连接时所设置的环境变量形式,具体使用方式请参考Docker的相关文档。在创建Pod对象时,kubernetes也会把与此形式兼容的一系列环境变量注入到Pod对象中。
基于DNS的服务发现 基于DNS的服务发现,对于每个Service对象,都会具有以下3个类型的DNS资源记录。
1)根据ClusterIP的地址类型,为IPv4生成A记录,为IPv6生成AAAA记录; 1 2 3 4 5 6 <service>.<ns>.svc.<zone>. <ttl> IN A <cluster-ip> <service>.<ns>.svc.<zone>. <ttl> IN AAAA <cluster-ip> demoapp.default.svc.cluster.local.
验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 root@k8s-master01:~ NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE demoapp NodePort 10.111.8.128 <none> 80:31156/TCP 13d [root@demoapp-5f7d8f9847-jrfm6 /] Server: 10.96.0.10 Address: 10.96.0.10 Name: demoapp.default.svc.cluster.local Address: 10.111.8.128 root@k8s-master01:~ NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 13d root@k8s-master01:~ nameserver 10.96.0.10 search default.svc.cluster.local svc.cluster.local cluster.local options ndots:5 root@k8s-master01:~ Name: kube-dns Namespace: kube-system Labels: k8s-app=kube-dns kubernetes.io/cluster-service=true kubernetes.io/name=CoreDNS Annotations: prometheus.io/port: 9153 prometheus.io/scrape: true Selector: k8s-app=kube-dns Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10.96.0.10 IPs: 10.96.0.10 Port: dns 53/UDP TargetPort: 53/UDP Endpoints: 10.244.0.4:53,10.244.0.5:53 Port: dns-tcp 53/TCP TargetPort: 53/TCP Endpoints: 10.244.0.4:53,10.244.0.5:53 Port: metrics 9153/TCP TargetPort: 9153/TCP Endpoints: 10.244.0.4:9153,10.244.0.5:9153 Session Affinity: None Events: <none> root@k8s-master01:~ NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES coredns-57d4cbf879-p5c58 1/1 Running 1 13d 10.244.0.4 k8s-master01 <none> <none> coredns-57d4cbf879-rfdsk 1/1 Running 1 13d 10.244.0.5 k8s-master01 <none> <none>
2)为每个定义了名称的端口生成一个SRV记录,未命名的端口号则不具有该记录; 1 2 _<port>._<protocol>.<service>.<ns>.svc.<zone>. <ttl> IN SRV <weight> <priority> <port-number> <service>.<ns>.svc.<zone>.
3)对于每个给定的A记录或AAAA记录都要生成PTR记录, 1 2 3 <d>.<c>.<b>.<a>.in-addr.arpa. <ttl> IN PTR <service>.<ns>.svc.<zone>. h4.h3.h2.h1.g4.g3.g2.g1.f4.f3.f2.f1.e4.e3.e2.e1.d4.d3.d2.d1.c4.c3.c2.c1.b4.b3.b2.b1.a4.a3.a2.a1.ip6.arpa <ttl> IN PTR <service>.<ns>.svc.<zone>.
验证PTR记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 root@k8s-master01:~ NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE demoapp-svc ClusterIP 10.97.72.1 <none> 80/TCP 6d22h root@k8s-master01:~ *** Invalid option: A 1.72.97.10.in-addr.arpa name = demoapp-svc.default.svc.cluster.local. root@k8s-master01:~ 1.72.97.10.in-addr.arpa name = demoapp-svc.default.svc.cluster.local. root@k8s-master01:~ Server: 10.96.0.10 Address: 10.96.0.10 Name: demoapp-svc.default.svc.cluster.local Address: 10.97.72.1
前面在default名称空间中创建Service对象demoapp-svc的地址为10.97.72.1,且为TCP协议的80端口取名http,对于默认的cluster.local域名来说,此它会拥有如下3个DNS资源记录。
A记录:demoapp-svc.default.svc.cluster.local. 30 IN A 10.97.72.1;
SRV记录:_http._tcp.demoapp-svc.default.svc.cluster.local. 30 IN SRV 0 100 80 demoapp-svc.default.svc.cluster.local.
PTR记录:1.72.97.10.in-addr.arpa. 30 IN PTR demoapp-svc.default.svc.cluster.local.
CoreDNS配置 有时候我们需要对CoreDNS进行配置,对其增加一些解析的功能,CoreDNS在kube-system名称空间下,其配置文件也是由ConfigMap来提供的
1 2 3 root@k8s-master01:~ NAME DATA AGE coredns 1 13d
编辑coredns配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 root@k8s-master01:~ apiVersion: v1 data: Corefile: | .:53 { errors health { lameduck 5s } ready kubernetes cluster.local 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: "2021-06-28T10:53:46Z" name: coredns namespace: kube-system resourceVersion: "264" uid: a7bb8e7b-90f1-416f-bbcc-111f715a0171