K8s-服务发现、负载均衡、网络

Service

Service 是 Kubernetes 中的一种服务发现机制:

  • Pod 有自己的 IP 地址
  • Service 被赋予一个唯一的 dns name
  • Service 通过 label selector 选定一组 Pod
  • Service 实现负载均衡,可将请求均衡分发到选定这一组 Pod 中

Service基础

基本操作

apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
# 管理的Pod的label
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376

无label模式

apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376

因为该 Service 没有 selector,相应的 Endpoint 对象就无法自动创建。您可以手动创建一个 Endpoint 对象,以便将该 Service 映射到后端服务真实的 IP 地址和端口:

apiVersion: v1
kind: Endpoints
metadata:
name: my-service
subsets:
- addresses:
- ip: 192.0.2.42
ports:
- port: 9376

虚拟 IP 和服务代理

Kubernetes 集群中的每个节点都运行了一个 kube-proxy,负责为 Service(ExternalName 类型的除外)提供虚拟 IP 访问。

为何不使用 round-robin DNS

许多用户都对 Kubernetes 为何使用服务代理将接收到的请求转发给后端服务,而不是使用其他途径,例如:是否可以为 Service 配置一个 DNS 记录,将其解析到多个 A value(如果是 IPv6 则是 AAAA value),并依赖 round-robin(循环)解析?

Kubernetes 使用在 Service 中使用 proxy 的原因大致有如下几个:

  • 一直以来,DNS 软件都不确保严格检查 TTL(Time to live),并且在缓存的 dns 解析结果应该过期以后,仍然继续使用缓存中的记录
  • 某些应用程序只做一次 DNS 解析,并一直使用缓存下来的解析结果
  • 即使应用程序对 DNS 解析做了合适的处理,为 DNS 记录设置过短(或者 0)的 TTL 值,将给 DNS 服务器带来过大的负载

Iptables 代理模式

  • kube-proxy 监听 kubernetes master 以获得添加和移除 Service / Endpoint 的事件

  • kube-proxy 在其所在的节点(每个节点都有 kube-proxy)上为每一个 Service 安装 iptable 规则

  • iptables 将发送到 Service 的 ClusterIP / Port 的请求重定向到 Service 的后端 Pod 上

    • 对于 Service 中的每一个 Endpoint,kube-proxy 安装一个 iptable 规则
    • 默认情况下,kube-proxy 随机选择一个 Service 的后端 Pod

iptables proxy mode 的优点:

  • 更低的系统开销:在linux netfilter处理请求,无需在 userspace 和 kernel space之间切换
  • 更稳定

IPVS 代理模式

在 IPVS proxy mode 下:

  • kube-proxy监听K8s master以获得添加和移除 Service/Endpoint 事件
  • kube-proxy根据监听到的事件,调用netlink接口,创建IPVS规则;并将Service/Endpoint的变化同步到IPVS规则中
  • 当访问一个Service时,IPVS重定向到后端