K8S的服务注册

本文主要用来介绍K8S的服务注册和发现,算是笔者对这部分知识的一个学习笔记。

一、服务注册

K8S的服务注册_第1张图片

每个 Kubernetes 服务都会自动注册到集群 DNS 之中。注册过程大致如下:

1.Service创建的时候会向 API Server 用 POST 方式提交一个新的 Service 定义;
这个请求需要经过认证、鉴权以及其它的准入策略检查过程之后才会放行;
2. CoreDns 会为Service创建一个dns记录,
Service 得到一个 ClusterIP(虚拟 IP 地址),并保存到集群数据仓库;
3.在集群范围内传播 Service 配置;
除此之外kube-proxy会主动获取这部分数据,并存储在Node上面的iptables中。

备注

K8S的服务注册_第2张图片

     Kubernetes 使用 DNS 作为服务注册表。为了满足这一需要,每个 Kubernetes 集群都会在 kube-system 命名空间中用 Pod 的形式运行一个 DNS 服务,通常称之为集群 DNS。集群 DNS 服务得知该 Service 的创建,据此创建必要的 DNS A 记录。

集群 DNS 使用的是 CoreDNS,以 Kubernetes 原生应用的形式运行。CoreDNS 实现了一个控制器,会对 API Server 进行监听,一旦发现有新建的 Service 对象,就创建一个从 Service 名称映射到 ClusterIP 的域名记录。这样 Service 就不必自行向 DNS 进行注册,CoreDNS 控制器会关注新创建的 Service 对象,并实现后续的 DNS 过程。

     DNS 中注册的名称就是 metadata.name,而 ClusterIP 则由 Kubernetes 自行分配,参考下面的例子:

K8S的服务注册_第3张图片

二、服务发现

K8S的服务注册_第4张图片

第一步:服务获取ClusterIP

要使用服务发现功能,每个 Pod 都需要知道集群 DNS 的位置才能使用它。因此每个 Pod 中的每个容器的 /etc/resolv.conf 文件都被配置为使用集群 DNS 进行解析。

假设它们本地的 DNS 解析缓存中没有这个记录,则需要把查询提交到集群 DNS 服务器,会得到对应服务的 ClusterIP(VIP)不过此时的IP是一个虚IP,需要通过后面的Service Network来继续。

第二步:Service Network的转发到对应的Pod

一个 Pod 得到了 Service 的 ClusterIP 之后,就尝试向这个 IP 发送流量。然而 ClusterIP 所在的网络被称为 Service Network,这个网络有点特别——没有路由指向它。

因为没有路由,所有容器把发现这种地址的流量都发送到了缺省网关(名为 CBR0 的网桥)。这些流量会被转发给 Pod 所在节点的网卡上。节点的网络栈也同样没有路由能到达 Service Network,所以只能发送到自己的缺省网关。路由到节点缺省网关的数据包会通过 Node 内核,并通过捕获目标为 Service 网络的报文,通过Node上面的iptables中的记录信息,转发给 Pod IP。

每个新 Service 对象的配置,其中包含它的 ClusterIP 以及 Endpoints 对象(其中包含健康 Pod 的列表),都会被发送给 每个节点上的 kube-proxy 进程。kube-proxy 会创建 iptables 或者 IPVS 规则,告知节点捕获目标为 Service ClusterIP 的流量,并根据 Endpoints 对象的内容转发给对应的 Pod。也就是说每次节点内核处理到目标为 Service 网络的数据包时,都会对数据包的 Header 进行改写,把目标 IP 改为 Service Endpoints 对象中的健康 Pod 的 IP。


参考文档:

https://nigelpoulton.com/demystifying-kubernetes-service-discovery/

https://blog.fleeto.us/post/demystifying-kubernetes-service-discovery/

你可能感兴趣的:(网络,网关,java,kubernetes,zookeeper)