DEV Community

opmlee
opmlee

Posted on

云原生 EgressGateway:适用于 Calico,Flannel,Weave 和 Spiderpool 等 CNI 的出口网关

Calico 是一套开源的网络和网络安全解决方案,也是作为 Kubernetes 容器网络解决方案 (CNI: Container Network Interface) 的一种实现。

当前痛点

在多个集群互相访问,企业管理员希望规范化跨集群网络请求。如下图集群 B 中的 Pod 为一组应用,管理员希望右侧同一业务组的 Pod 出集群的流量都使用特定 IP。

img

EgressGateway 解决方式

👋 针对上述的需求,我们使用 https://github.com/spidernet-io/egressgateway 来解决这个问题。EgressGateway 是一个开源的云原生出口网关,兼容如下 CalicoFlannelWeaveSpiderpool 的 CNI 网络方案。EgressGateway 有如下特性:

  • 支持通过 EgressPolicy 配置不通租户的的 Egress 策略
  • 支持通过 EgressClusterPolicy 集群级 Egress 策略;
  • 支持 IPv4/IPv6 双栈;
  • 拥有低内核兼容性;
  • 自动检测集群内部流量;
  • 支持设置租户/集群默认 EgressGateway。

如果你想了解更多详情,请访问 EgressGateway https://spidernet-io.github.io/egressgateway/dev/ 文档站。

img

实现原理

在数据面,我们通过实施了如下 datapath 来实现 EgressGateway 的功能。左侧节点被 EgressPolicy 策略命中的 Pod 流量,会通过 iptabels, route, ipset 规则并通过 vxlan 转发到网关节点,然后从网关节点将源 IP 转为 Egress IP 离开集群。

Egress-Gateway-Datapath.png

安装实施

  1. 将 Calico 的的 FELIX_CHAININSERTMODE 设置为 Append
   kubectl set env daemonset -n kube-system calico-node FELIX_CHAININSERTMODE=Append
Enter fullscreen mode Exit fullscreen mode
  1. 安装 EgressGateway。
   helm repo add egressgateway https://spidernet-io.github.io/egressgateway/
   helm repo update

   helm install egressgateway egressgateway/egressgateway \
        -n kube-system \
        --set feature.tunnelIpv4Subnet="192.200.0.1/16" \ # 选择一个没有被使用的虚拟子网
        --wait --debug
Enter fullscreen mode Exit fullscreen mode
  1. 验证 EgressGateway 都已经启动并就绪。
   $ kubectl get pod -n kube-system | grep egressgateway
   egressgateway-agent-29lt5                  1/1     Running   0          9h
   egressgateway-agent-94n8k                  1/1     Running   0          9h
   egressgateway-agent-klkhf                  1/1     Running   0          9h
   egressgateway-controller-5754f6658-7pn4z   1/1     Running   0          9h
Enter fullscreen mode Exit fullscreen mode
  1. 选择一个或者多个节点作为出口网关。我们通过给 node 打上特点的 label 来标识这些节点。
   kubectl get node -o wide
   kubectl label node $NODE_NAME egressgateway="true"
Enter fullscreen mode Exit fullscreen mode
  1. 创建 EgressGateway 实例。在创建 EgressGateway 时,我们在 spec.nodeSelector 中将指定网关节点为上面打 label 的节点,并为这些网关分配了可用的 spec.ippools 的地址。
   cat <<EOF | kubectl apply -f -
   apiVersion: egressgateway.spidernet.io/v1beta1
   kind: EgressGateway
   metadata:
     name: default
   spec:
     ippools:
       ipv4:
       - "172.22.0.100-172.22.0.110"
     nodeSelector:
       selector:
         matchLabels:
           egressgateway: "true"
   EOF
Enter fullscreen mode Exit fullscreen mode
  1. 执行下面命令检查刚才创建的网关,我们可以在 status 中看到已经选择的 2 个节点已经就绪。稍后我们可以通过创建 EgressPolicy CR 来选择可使用的 EgressGateway,并通过 label 匹配业务 Pod,使业务流量通过网关节点离开集群。
   $ kubectl get EgressGateway default -o yaml
   apiVersion: egressgateway.spidernet.io/v1beta1
   kind: EgressGateway
   metadata:
     name: default
     uid: 7ce835e2-2075-4d26-ba63-eacd841aadfe
   spec:
     ippools:
       ipv4:
       - 172.22.0.100-172.22.0.110
       ipv4DefaultEIP: 172.22.0.110
     nodeSelector:
       selector:
         matchLabels:
           egressgateway: "true"
   status:
     nodeList:
     - name: egressgateway-worker1
       status: Ready
     - name: egressgateway-worker2
       status: Ready
Enter fullscreen mode Exit fullscreen mode
  1. 在开始之前我们先在集群外的任意机器,启动一个容器模拟被访问的外部服务。
   docker run -d --net=host ghcr.io/spidernet-io/egressgateway-nettools:latest /usr/bin/nettools-server -protocol web -webPort 8080
Enter fullscreen mode Exit fullscreen mode
  1. 我们在集群内部创建一个 Deployment,用于模拟需要访问外部使用统一 Egress IP 的业务应用。
   kubectl create deployment visitor --image nginx
Enter fullscreen mode Exit fullscreen mode
  1. 此时我们创建一个 EgressPolicy,来为其实施 Egress 策略。我们通过 spec.egressGatewayName 制定了上面创建的 EgressGateway 名称。
   cat <<EOF | kubectl apply -f -
   apiVersion: egressgateway.spidernet.io/v1beta1
   kind: EgressPolicy
   metadata:
    name: test
    namespace: default
   spec:
    egressGatewayName: default
    appliedTo:
     podSelector:
      matchLabels:
       app: "visitor"
   EOF
Enter fullscreen mode Exit fullscreen mode
  1. 通过 kubectl exec 进我们创建的业务应用,执行测试。

    kubectl exec -it visitor-6764bb48cc-29vq9 bash
    $ curl 10.6.1.92:8080
    Remote IP: 172.22.0.110
    

    🎉 通过结果看到,我们的 Egress IP 已经变为了 EgressGateway 池中配置的 IP。当然也可以在创建 EgressPolicy 指定使用的 Egress IP。

总结

在本文中我们分析了 Calico 网络下的 Egress IP 网络需求,并通过 EgressGateway 来解决这个问题,同时对 EgressGateway 的网络原理做了阐述,最后我们介绍了 EgressGateway 的更多功能。

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more