docs,README: document multi-cluster services

This commit is contained in:
Lucas Servén Marín
2019-05-08 17:10:09 +02:00
parent 90e68c7735
commit 545bc4186f
4 changed files with 166 additions and 10 deletions

View File

@@ -0,0 +1,57 @@
# Multi-cluster Services
Just as Kilo can connect a Kubernetes cluster to external services over WireGuard, it can connect multiple independent Kubernetes clusters.
This enables clusters to provide services to other clusters over a secure connection.
For example, a cluster on AWS with access to GPUs could run a machine learning service that could be consumed by workloads running in a another location, e.g. an on-prem cluster without GPUs.
Unlike services exposed via Ingresses or NodePort Services, multi-cluster services can remain private and internal to the clusters.
*Note*: clusters connected with Kilo must have non-overlapping pod and service CIDRs.
Consider two clusters, `cluster1` with:
* kubeconfig: `KUBECONFIG1`
* pod CIDR: $PODCIDR1`
* service CIDR: $SERVICECIDR1`
* a node named: `$NODE1`
and `cluster2` with:
* kubeconfig: `KUBECONFIG2`
* pod CIDR: $PODCIDR2`
* service CIDR: $SERVICECIDR2`
* a node named: `$NODE2`
In order to give `cluster2` access to a service running on `cluster1`, start by peering the nodes:
```shell
# Register cluster1 as a peer of cluster2.
kgctl --kubeconfig $KUBECONFIG1 showconf node $NODE1 --as-peer -o yaml --allowed-ips $PODCIDR1,$SERVICECIDR1 | kubectl --kubeconfig KUBECONFIG2 apply -f -
# Register cluster2 as a peer of cluster1.
kgctl --kubeconfig $KUBECONFIG2 showconf node $NODE2 --as-peer -o yaml --allowed-ips $PODCIDR2,$SERVICECIDR2 | kubectl --kubeconfig KUBECONFIG1 apply -f -
```
Now, `cluster2` has access to Pods and Services on `cluster1`, and vice-versa.
However, as it stands the external Services can only be accessed by using their clusterIPs directly; in other words, they are not Kubernetes-native.
We can change that by creating a Kubernetes Service in `cluster2` to mirror the Service in `cluster1`:
```
cat <<'EOF' | kubectl --kubeconfig $KUBECONFIG2 apply -f -
apiVersion: v1
kind: Service
metadata:
name: important-service
spec:
ports:
- port: 80
---
apiVersion: v1
kind: Endpoints
metadata:
name: important-service
subsets:
- addresses:
- ip: $CLUSTERIP # The cluster IP of the important service on cluster1.
ports:
- port: 80
EOF
```
Now, `important-service` can be used on `cluster2` just like any other Kubernetes Service.

View File

@@ -16,7 +16,7 @@ metadata:
name: squat
spec:
allowedIPs:
- 10.4.1.1/32
- 10.5.0.1/32 # Example IP address on the peer's interface.
publicKey: GY5aT1N9dTR/nJnT1N2f4ClZWVj0jOAld0r8ysWLyjg=
persistentKeepalive: 10
```
@@ -66,3 +66,42 @@ For example, try connecting to the API server:
```shell
curl -k https://10.0.27.179:6443
```
Likewise, the cluster now also has layer 3 access to the newly added peer.
From any node or Pod on the cluster, one can now ping the peer:
```shell
ping 10.5.0.1
```
If the peer exposes a layer 4 service, for example an HTTP service, then one could also make requests against that endpoint from the cluster:
```shell
curl http://10.5.0.1
```
Kubernetes Services can be created to provide better discoverability to cluster workloads for services exposed by peers, for example:
```shell
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: important-service
spec:
ports:
- port: 80
---
apiVersion: v1
kind: Endpoints
metadata:
name: important-service
subsets:
- addresses:
- ip: 10.5.0.1
ports:
- port: 80
EOF
```
[See the multi-cluster services docs for more details on connecting clusters to external services](./docs/multi-cluster-services.md).