-
Service 是由 kube-proxy 组件,加上 iptables 来共同实现的。
-
Kube-proxy 通过监听 Service 对象的创建,创建出相应的 iptables 规则
- 如创建一个 3副本的 deployment,并暴露该 deployment 为一个 k8s Service
- kube-proxy 监听到该 Service 的创建,首先会创建一个 iptables,过滤 IP 包(目的 ip 是该 Service IP,目的端口是该 Service 端口),然后跳转到另一个 iptables 链 A
- 该 iptables 链有一组 iptables 规则(共三条,对应3个副本),进行随机跳转(各1/3概率选中),选中一条规则,跳转到另一条 iptables链(B 或 C 或 D)
- 假如上面选中了 iptables 链 B,该链对应了 Pod-1,包含一组操作,进行 DNAT,将上面的 Service IP + Port 替换为 Pod-1 IP + Pod-1 Port,实现真正的流量导向
-
在 Kubernetes 中,Service 和 Pod 都会被分配对应的 DNS A 记录(从域名解析 IP 的记录)。
- 对于 ClusterIP 模式的 Service 来说(比如我们上面的例子),它的 A 记录的格式是:…svc.cluster.local。当你访问这条 A 记录的时候,它解析到的就是该 Service 的 VIP 地址。
- 而对于指定了 clusterIP=None 的 Headless Service 来说,它的 A 记录的格式也是:…svc.cluster.local。但是,当你访问这条 A 记录的时候,它返回的是所有被代理的 Pod 的 IP 地址的集合。当然,如果你的客户端没办法解析这个集合的话,它可能会只会拿到第一个 Pod 的 IP 地址。
- 此外,对于 ClusterIP 模式的 Service 来说,它代理的 Pod 被自动分配的 A 记录的格式是:…pod.cluster.local。这条记录指向 Pod 的 IP 地址。
- 而对 Headless Service 来说,它代理的 Pod 被自动分配的 A 记录的格式是:…svc.cluster.local。这条记录也指向 Pod 的 IP 地址。
- 但如果你为 Pod 指定了 Headless Service,并且 Pod 本身声明了 hostname 和 subdomain 字段,那么这时候 Pod 的 A 记录就会变成:pod 的 hostname…svc.cluster.local