kubernetes: 服务发现

什么是服务发现:
服务发现有三个角色,服务提供者、服务消费者和服务中介。服务中介是联系服务提供者和服务消费者的桥梁。服务提供者将自己提供的服务地址注册到服务中介,服务消费者从服务中介那里查找自己想要的服务的地址,然后享受这个服务。服务中介提供多个服务,每个服务对应多个服务提供者。
服务中介就是一个字典,字典里有很多key/value键值对,key是服务名称,value是服务提供者的地址列表。服务注册就是调用字典的Put方法塞东西,服务查找就是调用字典的Get方法拿东西。

当服务提供者节点挂掉时,要求服务能够及时取消注册,比便及时通知消费者重新获取服务地址。

当服务提供者新加入时,要求服务中介能及时告知服务消费者,你要不要尝试一下新的服务。
kubernetes: 服务发现_第1张图片
服务发现模型:
1.基于客户端的服务发现
2.基于服务端的服务发现,我们重点看这个
k8s中怎么使用服务发现
kubernetes的服务发现经过了三个阶段
1.环境变量
Kubernetes 采用了环境变量的方法,每个 Pod 启动的时候,会通过环境变量设置所有服务的 IP 和 port 信息,这样 Pod 中的应用可以通过读取环境变量来获取依赖服务的地址信息,这种方法使用起来相对简单,但是有一个很大的问题就是依赖的服务必须在 Pod 启动之前就存在,不然是不会被注入到环境变量中的。

KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=test-pod
HOME=/root
NGINX_SERVICE_PORT_5000_TCP_ADDR=10.107.225.42
NGINX_SERVICE_PORT_5000_TCP_PORT=5000
NGINX_SERVICE_PORT_5000_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NGINX_SERVICE_SERVICE_HOST=10.107.225.42
NGINX_SERVICE_PORT_5000_TCP=tcp://10.107.225.42:5000
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
NGINX_SERVICE_SERVICE_PORT=5000
NGINX_SERVICE_PORT=tcp://10.107.225.42:5000
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
...

2.kube-dns
由于上面环境变量这种方式的局限性,我们需要一种更加智能的方案,其实我们可以自己想学一种比较理想的方案:那就是可以直接使用 Service 的名称,因为 Service 的名称不会变化,我们不需要去关心分配的ClusterIP的地址,因为这个地址并不是固定不变的,所以如果我们直接使用 Service 的名字,然后对应的ClusterIP地址的转换能够自动完成就很好了。我们知道名字和 IP 直接的转换是不是和我们平时访问的网站非常类似啊?他们之间的转换功能通过DNS就可以解决了,同样的,Kubernetes也提供了DNS的方案来解决上面的服务发现的问题。
kubernetes: 服务发现_第2张图片
kube-dns Pod,其中包含了4个containers
第一个容器 etcd ,它的用途是保存DNS规则。
第二个容器 kube2sky ,作用是写入DNS规则。
第三个容器是 skydns ,提供DNS解析服务。
最后一个容器是 healthz ,提供健康检查功能。
有了Pod之后,还需要创建一个Service以便集群中的其他Pod访问DNS查询服务。通过skydns-svc.yaml创建Service
域名格式
具体为:..svc.
具体的解析工作是由pod中的/etc/resolv.conf 完成的
在这里插入图片描述
3.core-dns
coredns是一个dns服务器。它是用go写的。

coredns不同于其他dns服务器,例如(所有优秀的)bind、knot、powerdns和unbound(技术上是一个解析器,但仍然值得一提),因为它非常灵活,而且几乎所有的功能都外包到插件中。
目前默认的coredns安装中包含了大约30个插件,但是也有一大堆外部插件,您可以编译成coredns来扩展其功能。

coredns是由插件驱动的。
从Kubernetes 1.11开始,可使用CoreDNS作为Kubernetes的DNS插件进入GA状态,Kubernetes推荐使用CoreDNS作为集群内的DNS服务。
Kubernetes推荐使用CoreDNS作为集群内的DNS服务。 CoreDNS从2017年初就成为了CNCF的的孵化项目,CoreDNS的特点就是十分灵活和可扩展的插件机制,各种插件实现不同的功能,如重定向、定制DNS记录、记录日志等等。下图描述了CoreDNS的整体架构:
kubernetes: 服务发现_第3张图片
使用coredns需要设置参数
kubeadm init --feature-gates=CoreDNS=true
项目地址:
https://github.com/coredns
部署:
根据官方支持的platform选择对应的安装部署
https://github.com/coredns/deployment
如图是在k8s上部署
kubernetes: 服务发现_第4张图片
测试可用性:
在cfss namespace下面部署了一个 acrm服务,则 服务的servername 为acrm.cfss.svc.cluster.local
我们在pod中ping测试,可以看到能正常解析服务
在这里插入图片描述
我们发现解析出来的地址和 svc的clusterip地址一致
在这里插入图片描述
我们在看一下 pod /etc/resolv.conf配置
nameserver地址是 整个集群的DNS入口地址
在这里插入图片描述
在这里插入图片描述
kubernetes: 服务发现_第5张图片
endpoints地址对应两个 coredns pod地址
在这里插入图片描述
kubernetes: 服务发现_第6张图片
search 表示:它的多个参数指明域名查询顺序。当要查询没有域名的主机,主机将在由search声明的域中分别查找。domain和search不能共存;如果同时存在,后面出现的将会被使用。
coredns 配置,plugin编写参考手册:
https://coredns.io/manual/toc/

参考资料
https://v1-12.docs.kubernetes.io/zh/docs/tasks/administer-cluster/coredns/
https://coredns.io/manual/toc/
https://blog.frognew.com/2018/10/using-coredns-for-kubernetes-service-discovery.html

你可能感兴趣的:(kubernetes)