Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/anthonycorletti/cross-gke-cluster-networking
Tutorial for setting up cross cluster networking using internal load balancers
https://github.com/anthonycorletti/cross-gke-cluster-networking
containers google-cloud kubernetes networking shell
Last synced: 18 days ago
JSON representation
Tutorial for setting up cross cluster networking using internal load balancers
- Host: GitHub
- URL: https://github.com/anthonycorletti/cross-gke-cluster-networking
- Owner: anthonycorletti
- Created: 2017-02-01T04:10:16.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2018-11-03T18:58:18.000Z (over 6 years ago)
- Last Synced: 2024-11-20T23:28:05.053Z (3 months ago)
- Topics: containers, google-cloud, kubernetes, networking, shell
- Language: Shell
- Homepage:
- Size: 4.88 KB
- Stars: 4
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Cross Kubernetes Networking with GKE
This tutorial attempts to document the steps necessary to expose Kubernetes services between two GKE clusters over internal IP addresses.
## Overview
Each cluster will utilize the following components:
* c1 - GKE cluster running in us-west1-a
* c2 - GKE cluster running in us-west1-b
* c1-gw-1 - multi-nic VM running the nginx ingress controller. Serves as the service proxy and gateway for c1
* c1-gw-2 - multi-nic VM running the nginx ingress controller. Serves as the service proxy for c1
* c2-gw-1 - multi-nic VM running the nginx ingress controller. Serves as the service proxy and gateway for c2
* c2-gw-2 - multi-nic VM running the nginx ingress controller. Serves as the service proxy for c2
* c1-ilb - c1 internal load balancer (backends: c1-gw-1, c1-gw-2)
* c2-ilb - c2 internal load balancer (backends: c2-gw-1, c2-gw-2)### Network Layout
* shared (10.210.200.0/24)
* c1-gw-1
* c1-gw-2
* c2-gw-1
* c2-gw-2
* c1-ilb
* c2-ilb
* cluster-1 (10.138.0.0/20)
* c1
* c1-gw-1
* c1-gw-2
* cluster-2 (10.138.0.0/20)
* c2
* c2-gw-1
* c2-gw-2## Prerequisites
Internal load balancing is limited to a specific region. Networks can span zones, but not regions.
```
gcloud config set compute/region us-west1
```### Create the networks
```
gcloud compute networks create shared --mode custom
``````
gcloud compute networks subnets create services \
--network shared \
--region us-west1 \
--range 10.210.200.0/24
``````
gcloud compute networks create cluster-1
``````
gcloud compute networks create cluster-2
``````
for network in shared cluster-1 cluster-2; do
gcloud compute firewall-rules create "${network}-allow-all" \
--network $network \
--allow all \
--source-ranges 0.0.0.0/0
done
```### Create GKE Clusters
```
gcloud container clusters create c1 \
--cluster-ipv4-cidr 10.120.0.0/16 \
--network cluster-1 \
--zone us-west1-a
``````
gcloud container clusters create c2 \
--cluster-ipv4-cidr 10.120.0.0/16 \
--network cluster-2 \
--zone us-west1-b
```### Create Gateway Instances
Each gateway instances will provide NAT between each GKE cluster and run the nginx ingress controller to provide a service proxy over internal IP addresses.
#### c1 gateways (us-west1-a)
Before provisioning the gateway machines we need to gather the following:
* cluster credentials used to create a kubeconfig for each cluster. The kubeconfig is used by the nginx ingress controller to connect the GKE master and sync service information.
```
gcloud container clusters get-credentials c1 \
--zone us-west1-a
``````
C1_SERVER=$(gcloud container clusters describe c1 \
--format 'value(endpoint)')
``````
C1_CERTIFICATE_AUTHORITY_DATA=$(gcloud container clusters describe c1 \
--format 'value(masterAuth.clusterCaCertificate)')
``````
C1_CLIENT_CERTIFICATE_DATA=$(gcloud container clusters describe c1 \
--format 'value(masterAuth.clientCertificate)')
``````
C1_CLIENT_KEY_DATA=$(gcloud container clusters describe c1 \
--format 'value(masterAuth.clientKey)')
``````
kubectl config set-cluster gke --kubeconfig c1-kubeconfig
``````
kubectl config set clusters.gke.server \
"https://${C1_SERVER}" \
--kubeconfig c1-kubeconfig
``````
kubectl config set clusters.gke.certificate-authority-data \
${C1_CERTIFICATE_AUTHORITY_DATA} \
--kubeconfig c1-kubeconfig
``````
kubectl config set-credentials ingress-controller --kubeconfig c1-kubeconfig
``````
kubectl config set users.ingress-controller.client-certificate-data \
${C1_CLIENT_CERTIFICATE_DATA} \
--kubeconfig c1-kubeconfig
``````
kubectl config set users.ingress-controller.client-key-data \
${C1_CLIENT_KEY_DATA} \
--kubeconfig c1-kubeconfig
``````
kubectl config set-context ingress-controller \
--cluster=gke \
--user=ingress-controller \
--kubeconfig c1-kubeconfig
``````
kubectl config use-context ingress-controller \
--kubeconfig c1-kubeconfig
``````
gcloud alpha compute instances create c1-gw-1 \
--can-ip-forward \
--image-family ubuntu-1604-lts \
--image-project ubuntu-os-cloud \
--metadata-from-file "startup-script=startup.sh","pod=nginx-ingress-controller.yaml","kubeconfig=c1-kubeconfig" \
--network-interface "subnet=https://www.googleapis.com/compute/v1/projects/hightowerlabs/regions/us-west1/subnetworks/services" \
--network-interface "subnet=cluster-1" \
--zone us-west1-a
``````
gcloud alpha compute instances create c1-gw-2 \
--can-ip-forward \
--image-family ubuntu-1604-lts \
--image-project ubuntu-os-cloud \
--metadata-from-file "startup-script=startup.sh","pod=nginx-ingress-controller.yaml","kubeconfig=c1-kubeconfig" \
--network-interface "subnet=https://www.googleapis.com/compute/v1/projects/hightowerlabs/regions/us-west1/subnetworks/services" \
--network-interface "subnet=cluster-1" \
--zone us-west1-a
```#### c2 gateways (us-west1-b)
```
gcloud container clusters get-credentials c2 \
--zone us-west1-b
``````
C2_SERVER=$(gcloud container clusters describe c2 \
--zone us-west1-b \
--format 'value(endpoint)')
``````
C2_CERTIFICATE_AUTHORITY_DATA=$(gcloud container clusters describe c2 \
--zone us-west1-b \
--format 'value(masterAuth.clusterCaCertificate)')
``````
C2_CLIENT_CERTIFICATE_DATA=$(gcloud container clusters describe c2 \
--zone us-west1-b \
--format 'value(masterAuth.clientCertificate)')
``````
C2_CLIENT_KEY_DATA=$(gcloud container clusters describe c2 \
--zone us-west1-b \
--format 'value(masterAuth.clientKey)')
``````
kubectl config set-cluster gke --kubeconfig c2-kubeconfig
``````
kubectl config set clusters.gke.server \
"https://${C2_SERVER}" \
--kubeconfig c2-kubeconfig
``````
kubectl config set clusters.gke.certificate-authority-data \
${C2_CERTIFICATE_AUTHORITY_DATA} \
--kubeconfig c2-kubeconfig
``````
kubectl config set-credentials ingress-controller --kubeconfig c2-kubeconfig
``````
kubectl config set users.ingress-controller.client-certificate-data \
${C2_CLIENT_CERTIFICATE_DATA} \
--kubeconfig c2-kubeconfig
``````
kubectl config set users.ingress-controller.client-key-data \
${C2_CLIENT_KEY_DATA} \
--kubeconfig c2-kubeconfig
``````
kubectl config set-context ingress-controller \
--cluster=gke \
--user=ingress-controller \
--kubeconfig c2-kubeconfig
``````
kubectl config use-context ingress-controller \
--kubeconfig c2-kubeconfig
``````
gcloud alpha compute instances create c2-gw-1 \
--can-ip-forward \
--image-family ubuntu-1604-lts \
--image-project ubuntu-os-cloud \
--metadata-from-file "startup-script=startup.sh","pod=nginx-ingress-controller.yaml","kubeconfig=c2-kubeconfig" \
--network-interface "subnet=https://www.googleapis.com/compute/v1/projects/hightowerlabs/regions/us-west1/subnetworks/services" \
--network-interface "subnet=cluster-2" \
--zone us-west1-b
``````
gcloud alpha compute instances create c2-gw-2 \
--can-ip-forward \
--image-family ubuntu-1604-lts \
--image-project ubuntu-os-cloud \
--metadata-from-file "startup-script=startup.sh","pod=nginx-ingress-controller.yaml","kubeconfig=c2-kubeconfig" \
--network-interface "subnet=https://www.googleapis.com/compute/v1/projects/hightowerlabs/regions/us-west1/subnetworks/services" \
--network-interface "subnet=cluster-2" \
--zone us-west1-b
```### Create Instance Groups
```
gcloud compute instance-groups unmanaged create c1-gw-instance-group \
--zone us-west1-a
``````
gcloud compute instance-groups unmanaged add-instances c1-gw-instance-group \
--instances c1-gw-1,c1-gw-2 \
--zone us-west1-a
``````
gcloud compute instance-groups unmanaged create c2-gw-instance-group \
--zone us-west1-b
``````
gcloud compute instance-groups unmanaged add-instances c2-gw-instance-group \
--instances c2-gw-1,c2-gw-2 \
--zone us-west1-b
```### Create Internal Load Balancer
```
gcloud compute health-checks create tcp ingress-controller-health-check --port 80
``````
gcloud compute backend-services create c1-backend-services \
--health-checks ingress-controller-health-check \
--load-balancing-scheme internal \
--region us-west1
``````
gcloud compute backend-services add-backend c1-backend-services \
--instance-group c1-gw-instance-group \
--instance-group-zone us-west1-a \
--region us-west1
``````
gcloud compute forwarding-rules create c1-forwarding-rules \
--backend-service c1-backend-services \
--load-balancing-scheme internal \
--network shared \
--ports 80 \
--region us-west1 \
--subnet services
```#### c2
```
gcloud compute backend-services create c2-backend-services \
--health-checks ingress-controller-health-check \
--load-balancing-scheme internal \
--region us-west1
``````
gcloud compute backend-services add-backend c2-backend-services \
--instance-group c2-gw-instance-group \
--instance-group-zone us-west1-b \
--region us-west1
``````
gcloud compute forwarding-rules create c2-forwarding-rules \
--backend-service c2-backend-services \
--load-balancing-scheme internal \
--network shared \
--ports 80 \
--region us-west1 \
--subnet services
```### Add routes
```
gcloud compute routes create c1-service-route \
--network cluster-1 \
--next-hop-instance c1-gw-1 \
--next-hop-instance-zone us-west1-a \
--destination-range 10.210.200.0/24
``````
gcloud compute routes create c2-service-route \
--network cluster-2 \
--next-hop-instance c2-gw-1 \
--next-hop-instance-zone us-west1-b \
--destination-range 10.210.200.0/24
```### Kubernetes
In this section we need to install an example service in each cluster so we can
test the ability to communication between clusters.Fetch the credentials for `c1`:
```
gcloud container clusters get-credentials c1 \
--zone us-west1-a
```Create the echoserver deployment:
```
kubectl run echoheaders \
--image=gcr.io/google_containers/echoserver:1.4 \
--replicas=1 \
--port=8080
```Expose the echoserver using a service. This is required before creating an ingress
config:```
kubectl expose deployment echoheaders --port=80 --target-port=8080 --name=echoheaders-x
```
```
kubectl expose deployment echoheaders --port=80 --target-port=8080 --name=echoheaders-y
```Create the ingress controller config. This will cause the nginx ingress controller running on
the gateway machines to pick up the echoserver backends and start routing HTTP requests to them.```
kubectl create -f echomap-ingress.yaml
```### Testing the nginx ingress controller
```
gcloud compute ssh c1-gw-1
``````
curl -H "Host: foo.bar.com" http://127.0.0.1/foo
``````
CLIENT VALUES:
client_address=10.138.0.5
command=GET
real path=/foo
query=nil
request_version=1.1
request_uri=http://foo.bar.com:8080/fooSERVER VALUES:
server_version=nginx: 1.10.0 - lua: 10001HEADERS RECEIVED:
accept=*/*
connection=close
host=foo.bar.com
user-agent=curl/7.50.1
x-forwarded-for=127.0.0.1
x-forwarded-host=foo.bar.com
x-forwarded-port=80
x-forwarded-proto=http
x-real-ip=127.0.0.1
BODY:
-no body in request-
```Test using the internal IP address:
```
curl -H "Host: foo.bar.com" http://c1-gw-1/foo
```#### Testing from a pod
```
kubectl run --tty -i ubuntu --image=ubuntu /bin/bash
```Once on the pod, install curl and hit the `c1-gw-1` service gateway:
```
apt-get update
``````
apt-get install curl
```Hit the `c1-gw-1` gateway from the pod:
> 10.210.200.2 is the internal IP address of c1-gw-1 on the shared network
```
curl -H "Host: foo.bar.com" http://10.210.200.2/foo
``````
CLIENT VALUES:
client_address=10.138.0.5
command=GET
real path=/foo
query=nil
request_version=1.1
request_uri=http://foo.bar.com:8080/fooSERVER VALUES:
server_version=nginx: 1.10.0 - lua: 10001HEADERS RECEIVED:
accept=*/*
connection=close
host=foo.bar.com
user-agent=curl/7.47.0
x-forwarded-for=10.120.1.4
x-forwarded-host=foo.bar.com
x-forwarded-port=80
x-forwarded-proto=http
x-real-ip=10.120.1.4
BODY:
-no body in request-
```Hit the c1 internal load balancer (c1-forwarding-rules) from the pod:
> 10.210.200.6 is the IP address assigned to the ILB
```
curl -H "Host: foo.bar.com" http://10.210.200.6/foo
```
```
CLIENT VALUES:
client_address=10.138.0.5
command=GET
real path=/foo
query=nil
request_version=1.1
request_uri=http://foo.bar.com:8080/fooSERVER VALUES:
server_version=nginx: 1.10.0 - lua: 10001HEADERS RECEIVED:
accept=*/*
connection=close
host=foo.bar.com
user-agent=curl/7.47.0
x-forwarded-for=10.120.1.4
x-forwarded-host=foo.bar.com
x-forwarded-port=80
x-forwarded-proto=http
x-real-ip=10.120.1.4
BODY:
-no body in request-
```## Testing Cross Cluster Communication
This is where I could not get things to work. The following flow does not seem to work as expected. I think there is something wrong with the gateway to gateway communication over the shared network.
```
pod (c1) <-> c1-gw-1 <-> c2-gw-1 <-> pod (c2)
```This flow also does not work:
```
pod (c1) <-> c2 ILB (c2-forwarding-rules)
```What's odd is that communication between c1-gw-1 and c2-gw-1 works, but not pod (c1) and pod (c2).
### Reproduce the issue
Set up the echoserver on c2:
```
gcloud container clusters get-credentials c2 \
--zone us-west1-b
``````
kubectl run echoheaders \
--image=gcr.io/google_containers/echoserver:1.4 \
--replicas=1 \
--port=8080
``````
kubectl expose deployment echoheaders --port=80 --target-port=8080 --name=echoheaders-x
``````
kubectl expose deployment echoheaders --port=80 --target-port=8080 --name=echoheaders-y
``````
kubectl create -f echomap-ingress.yaml
```### Test between c1-gw-1 and c2-gw-1
```
gcloud compute ssh c1-gw-1
``````
curl -H "Host: foo.bar.com" http://c2-gw-1/foo
```
```
CLIENT VALUES:
client_address=10.138.0.5
command=GET
real path=/foo
query=nil
request_version=1.1
request_uri=http://foo.bar.com:8080/fooSERVER VALUES:
server_version=nginx: 1.10.0 - lua: 10001HEADERS RECEIVED:
accept=*/*
connection=close
host=foo.bar.com
user-agent=curl/7.50.1
x-forwarded-for=10.210.200.2
x-forwarded-host=foo.bar.com
x-forwarded-port=80
x-forwarded-proto=http
x-real-ip=10.210.200.2
BODY:
-no body in request-
```### Test between pod (c1) <-> c2-gw-1
```
gcloud container clusters get-credentials c1 \
--zone us-west1-a
``````
kubectl run --tty -i ubuntu --image=ubuntu /bin/bash
```
> or just use the ubuntu pod from earlier```
curl -H "Host: foo.bar.com" http://10.210.200.7/foo
```> 10.210.200.7 is the IP address assigned to the ILB (c2-forwarding-rules)