概览

架构说明

配置步骤

建立两个 GKE 集群,并开启 Dataplane V2

创建 Deployment

创建 K8S Service,设置 load-balancer-type 为 Internal

创建 Zonal NEG(GCE_VM_IP)

给 NEG 添加后端的 endpoint(GKE Cluster1 node: VM instance)

创建健康检查

创建 backend-services

往 backend-services 里面添加 backend

创建 forwarding-rules

创建第二个 NEG(GCE_VM_IP)

给 NEG 添加后端的 endpoint(GKE Cluster2 node: VM instance)

往之前创建的 backend services 里面添加第二个 NEG

修改 cilium ebpf 规则

同理把规则添加到另一个集群中

测试验证


概览

通常用户希望通过内部的负载均衡器来访问 GKE 的后端服务,这在一个集群中,可以直接通过 K8S 原生的方式来实现。但需求如果是跨集群,我们可以采用一些 workaround 来演示这一过程。本实验通过 Internal TCP/UDP load balancer (ILB) 转发流量到不同的 GKE 集群,采用 Dataplane V2 的集群来演示。

架构说明

ILB 控制平面配置说明

端到端数据转发平面说明

Client IP (CIP) - 客户端 IP 地址

Virtual IP (VIP) - Internal Load Balancer 服务虚拟 IP 地址

Node IP (NIP) - GKE Node IP 地址

Pods IP (PIP) - Pod IP 地址

1. 客户端发起请求,源地址是 CIP,目的地址是 VIP。

2. GCP 底层 SDN 网络根据配置,将数据包转发到 GKE Node。

3. GKE Node 上 Cilium 组件需要将目的地址进行翻译,VIP->PIP,并保留源地址 CIP 不变

4. Pod 收到请求并处理,回包源地址为 PIP,目的地址为 CIP

5. GCP 底层 SDN 网络负责将数据包转发回客户端

配置步骤

建立两个 GKE 集群,并开启 Dataplane V2

gcloud beta container clusters create "dpv2-test-1" \\

--project "flius-vpc-2" \\

--zone "us-central1-c" \\

--cluster-version "1.24.9-gke.2000" \\

--image-type "UBUNTU_CONTAINERD" \\

--num-nodes "1" \\

--enable-ip-alias \\

--network "projects/flius-vpc-2/global/networks/v6vpc" \\

--subnetwork "projects/flius-vpc-2/regions/us-central1/subnetworks/v6subnet" \\

--enable-dataplane-v2 \\

--enable-l4-ilb-subsetting \\

--node-locations "us-central1-c"

gcloud beta container --project "flius-vpc-2" clusters create "dpv2-test-2" \\

--zone "us-central1-c" \\

--cluster-version "1.24.9-gke.2000" \\

--image-type "UBUNTU_CONTAINERD" \\

--num-nodes "1" \\

--enable-ip-alias \\

--network "projects/flius-vpc-2/global/networks/v6vpc" \\

--subnetwork "projects/flius-vpc-2/regions/us-central1/subnetworks/v6subnet" \\

--enable-dataplane-v2 \\

--enable-l4-ilb-subsetting \\

--node-locations "us-central1-c" 

创建 Deployment

apiVersion: apps/v1

kind: Deployment

metadata:

  name: ilb-deployment

spec:

  replicas: 3

  selector:

    matchLabels:

      app: ilb-deployment

  template:

    metadata:

      labels:

        app: ilb-deployment

    spec:

      containers:

      - name: hello-app

        image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0

创建 K8S Service,设置 load-balancer-type 为 Internal

apiVersion: v1

kind: Service

metadata:

  name: ilb-svc

  annotations:

    networking.gke.io/load-balancer-type: "Internal"

spec:

  type: LoadBalancer

  externalTrafficPolicy: Local

  selector:

    app: ilb-deployment

  ports:

  - name: tcp-port

    protocol: TCP

    port: 8080

    targetPort: 8080

创建 Zonal NEG(GCE_VM_IP)

gcloud compute network-endpoint-groups create gke-standalone-neg-2 \\

    --network-endpoint-type=gce-vm-ip \\

    --zone=us-central1-c \\

    --network=v6vpc \\

    --subnet=v6subnet

给 NEG 添加后端的 endpoint(GKE Cluster1 node: VM instance)

gcloud compute network-endpoint-groups update gke-standalone-neg-2 \\

    --zone=us-central1-\\

    --add-endpoint='instance=gke-dpv2-test-default-pool-d37121bc-c2rg'

创建健康检查

gcloud compute health-checks create http hc-http-8080 \\

    --region=us-central1 \\

    --port=8080

创建 backend-services

gcloud compute backend-services update gke-neg-ilb-2 \\

    --region=us-central1 \\

    --health-checks=hc-http-8080 \\

    --health-checks-region=us-central1

往 backend-services 里面添加 backend

gcloud compute backend-services add-backend gke-neg-ilb-2 \\

    --region=us-central1 \\

    --network-endpoint-group=gke-standalone-neg-2 \\

    --network-endpoint-group-zone=us-central1-c

创建 forwarding-rules

gcloud compute forwarding-rules create fr-ilb-2 \\

    --region=us-central1 \\

    --load-balancing-scheme=internal \\

    --network=v6vpc \\

    --subnet=v6subnet \\

    --address=10.0.0.102 \\

    --ip-protocol=TCP \\

    --ports=ALL \\

    --backend-service=gke-neg-ilb-2 \\

    --backend-service-region=us-central1

创建第二个 NEG(GCE_VM_IP)

gcloud compute network-endpoint-groups create gke-standalone-neg-3 \\

    --network-endpoint-type=gce-vm-ip \\

    --zone=us-central1-c \\

    --network=v6vpc \\

    --subnet=v6subnet

给 NEG 添加后端的 endpoint(GKE Cluster2 node: VM instance)

gcloud compute network-endpoint-groups update gke-standalone-neg-3 \\

    --zone=us-central1-\\

    --add-endpoint='instance=gke-dpv2-test-3-default-pool-06dc969f-l194'

往之前创建的 backend services 里面添加第二个 NEG

gcloud compute backend-services add-backend gke-neg-ilb-2 \\

    --region=us-central1 \\

    --network-endpoint-group=gke-standalone-neg-3 \\

    --network-endpoint-group-zone=us-central1-c

修改 cilium ebpf 规则

# 在kube-system namespace下,找到并进入anetd pod

kubectl exec -it anetd-tmhhp -n kube-system -- bash


# 增加ebpf规则,frontend为ilb ip:port,backends为pod ip:port

cilium service update --id=30 --frontend=10.0.0.102:8080 --backends=10.56.0.11:8080 --k8s-load-balancer

同理,把规则添加到另一个集群中

kubectl exec -it anetd-x4lg7 -n kube-system -- bash


# 相同的frontend,添加本集群的pod ip:port

cilium service update --id=30 --frontend=10.0.0.102:8080 --backends=10.152.0.7:8080 --k8s-load-balancer

测试验证

curl 10.0.0.102:8080

Hello, world!

Version: 1.0.0

Hostname: ilb-deployment-f4c6c8b46-g4h7w

可以发现访问 ILB 的 IP:PORT,可以负载均衡到不同 GKE Cluster 的 pod。

后续可以通过开发一个 operator 来实现 cilium service 的自动更新。

相关推荐