Proxy IPVS

IPVS

References

System Control Configuration

  • /proc/sys/net/ipv4/conf/all/route_localnet ---> 1

  • /proc/sys/net/bridge/bridge-nf-call-iptables ---> 1

  • /proc/sys/net/ipv4/vs/conntrack ---> 1

  • /proc/sys/net/ipv4/vs/conn_reuse_mode ---> 0

  • /proc/sys/net/ipv4/vs/expire_nodest_conn ---> 1

  • /proc/sys/net/ipv4/vs/expire_quiescent_template ---> 1

  • /proc/sys/net/ipv4/ip_forward ---> 1

  • StrictARP

    • /proc/sys/net/ipv4/conf/all/arp_ignore ---> 1

  • /proc/sys/net/ipv4/conf/all/arp_announce ---> 2

Sync Services

Basic Chains & Jump

Cluster IP Handling

Create Virtual Server

使用 Service 的 ClusterIP、Port 等信息,创建 VirtualServer,通过 netlink 来查询、创建、更新、删除 VirtualServer。

External IP Handling

VirtualServer 通过 netlink 接口创建 libipvs.Service 与处理 ClusterIP 类型服务时相同。需要注意,如果开启特性 ExternalPolicyForExternalIP,并且当前处理的 Service 的 Endpoint 只存在与当前 Node,那么使用 KUBE-EXTERNAL-IP-LOCAL 存储 Entry 值。

Query Destinations

在同步 Endpoints 前,需要获取当前服务的全部 RealServer,可通过 netlink 根据 VirtualServer 获取其对应的 Destination 列表,再根据 Destination 转化为 RealServer

func toRealServer(dst *libipvs.Destination) (*RealServer, error) {
    if dst == nil {
        return nil, errors.New("ipvs destination should not be empty")
    }
    return &RealServer{
        Address:      dst.Address,
        Port:         dst.Port,
        Weight:       dst.Weight,
        ActiveConn:   dst.ActiveConnections,
        InactiveConn: dst.InactiveConnections,
    }, nil
}

Synchronize Endpoints

处理过程比较简单,先处理 newEndpoints 中新增或更新的 Endpoint。处理完毕后,将处理删除的 Endpoints,被移除的 IP 及 Port 可通过 curEndpoints.Difference(newEndpoints) 获取。遍历删除列表,如果 IP、Port 已存在于 termination list,则不需要任何处理;如果不存在,将该 IP、Port 存入 termination list,同时存入的还有其对应的 netlink 创建的 Server。

Load Balancer Handling

Node Port

找到本地地址,并根据当前 Service 使用的 NodePort 情况,创建监听的端口。遍历时,如果遇到零地址段,则退出循环,因为这意味着本机全部 IP 都要监听该 NodePort。 创建 Entry 结构时,与当前 Service 的协议相关,如果为 SCTP 协议,类型为:HashIPPort。如果当前 Service 不是 Node Only,则只需要添加至 KUBE-NODE-PORT-protocol 中即可。

Synchronize IPSet

在之前的处理中,在 ipsetList 中各种类型的 IPSet 上,添加了各自的 IP、端口信息,在这个方法中将其应用。utilipset.Interface 实现是基于 ipset 命令集的,ListEntries 方法中传入的 Name 是内部的 utilipset.IPSet 中 Name 域,注意区分。

IPTables Rules

在之前的处理中 RealServer 已创建完毕,但是,每个 Node 只创建了一个 dummy 类型的网络设备 kube-ipvs0,那么,需要通过 iptables 及 ipset 配置,将流量合理引导。 首先创建的是如下的 NAT 规则,因为使用 -A 选择,下图中顺序即规则顺序,现在需要添加规则,从系统内置链中跳转至不同 Chain 中处理。

跳转规则如下所示

最后更新于