- User Guide
This guide walks through a small local demo that shows how Multikube works with two kind Kubernetes clusters. You will learn how to create backends, routes, polices and use cURL to verify routing and policy behavior.
This guide does not cover how to install multikube or multikubectl. Follow the installation docs first, then come back here.
Make sure these are already available:
kindkubectlcurl
You also need a running Multikube control plane and a working multikubectl config. Read the getting started guide to learn how to set it up.
If you are running multikube in Docker then you must join the multikube container to the kind network. Otherwise multikube will not be able to communicate with the kubernetes clusters. If multikube is already running then you can run this command to join multikube to the kind network:
docker network connect kind multikubeIf multikube is not setup and you want to run it with docker, use --network kind flag
docker run -d \
--name multikube \
--network kind \
-p 5743:5743 \
-p 6443:6443 \
-p 8443:8443 \
-v multikube-data:/.local/state/multikube \
multikube:latestCreate two clusters named demo-east and demo-west:
kind create cluster --name demo-east
kind create cluster --name demo-westkind adds both clusters to your kubeconfig automatically.
List the contexts to confirm they exist:
kubectl config get-contextsYou should see two contexts named: kind-demo-east and kind-demo-west
Create one namespace in each cluster so it is easy to see which cluster answered your request later.
kubectl --context kind-demo-east create namespace east-demo
kubectl --context kind-demo-west create namespace west-demoThe import command is very useful when you want to create multikube resources from a kubeconfig. It reads the provided kubeconfig and imports a context into multikube creating backend, certificate, ca and credentials resource.
A note on kind: Multikube accesses kind clusters through the docker network so we can't import the kubeconfig that kind created when creating the clusters. To create kubeconfigs that can be used from inside other docker containers we have to use the
--internalflag.
Create an internal kubeconfig file per cluster that we import into multikube later
kind get kubeconfig --internal --name demo-east > ~/.kube/demo-east.yaml
kind get kubeconfig --internal --name demo-west > ~/.kube/demo-west.yamlImport the two kind contexts and give them easy-to-remember backend names:
multikubectl import kind-demo-east --backend-name east-cluster --kubeconfig ~/.kube/demo-east.yaml
multikubectl import kind-demo-west --backend-name west-cluster --kubeconfig ~/.kube/demo-west.yamlIf you re-run the guide and the resources already exist, use
--forceto overwrite existing resources
List the imported backends:
multikubectl get backendsYou should see both east-cluster and west-cluster.
Create one route for each backend using the X-Cluster header:
multikubectl create route route-east \
--backend-ref east-cluster \
--header-name X-Cluster \
--header-value east
multikubectl create route route-west \
--backend-ref west-cluster \
--header-name X-Cluster \
--header-value westMultikube supports multiple routing mechanisms such as JWT, PathPrefix and Header
Verify that the routes exist:
multikubectl get routesIf routing compiled successfully, the routes should move to READY.
Create a token for a user in the demo-readonly group:
TOKEN=$(multikubectl create token \
--subject demo-user \
--group demo-readonly \
--ttl 1h)You can inspect the token variable with:
echo "${TOKEN}"We're going to create two policy resources. One allow policy for read-only access and one deny polcy for deletes. At the moment, multikubectl create policy creates empty shell policies. The command does not expose flags for building detailed rules. For this guide, use apply to create policies from yaml manifests.
---
version: policy/v1
meta:
name: demo-readonly
config:
name: demo-readonly
rules:
- effect: EFFECT_ALLOW
subjects:
- groups:
- demo-readonly
clusters:
- names:
- east-cluster
- west-cluster
resources:
- resource: namespaces
actions:
- ACTION_GET
- ACTION_LIST
---
version: policy/v1
meta:
name: demo-deny-delete
config:
name: demo-deny-delete
rules:
- effect: EFFECT_DENY
subjects:
- groups:
- demo-readonly
clusters:
- names:
- east-cluster
- west-cluster
resources:
- resource: namespaces
actions:
- ACTION_DELETECreate the two policies with this command
multikubectl apply -f demo-policies.yamlNow send requests through the Multikube proxy.
This request should return the east-demo namespace object from the east cluster:
curl -sk \
-H "Authorization: Bearer ${TOKEN}" \
-H "X-Cluster: east" \
https://127.0.0.1:8443/api/v1/namespaces/east-demoYou should see JSON containing east-demo.
This request should return the west-demo namespace object from the west cluster:
curl -sk \
-H "Authorization: Bearer ${TOKEN}" \
-H "X-Cluster: west" \
https://127.0.0.1:8443/api/v1/namespaces/west-demoYou should see JSON containing west-demo.
curl -sk \
-H "Authorization: Bearer ${TOKEN}" \
-H "X-Cluster: east" \
https://127.0.0.1:8443/api/v1/namespaces
curl -sk \
-H "Authorization: Bearer ${TOKEN}" \
-H "X-Cluster: west" \
https://127.0.0.1:8443/api/v1/namespacesThe two responses should both be valid Kubernetes API responses, but they should reflect different backend clusters.
Try to delete one of the namespaces:
curl -sk -i \
-X DELETE \
-H "Authorization: Bearer ${TOKEN}" \
-H "X-Cluster: east" \
https://127.0.0.1:8443/api/v1/namespaces/east-demoThe request should be denied.
In most setups you should see an HTTP 403 Forbidden response, because the deny policy matches before any allow rule can permit the request.
Policies are evaluated against the authenticated principal. If you omit the bearer token, the request should not be authorized.
curl -sk -i \
-H "X-Cluster: east" \
https://127.0.0.1:8443/api/v1/namespacesYou should get an authentication or authorization failure.
Delete the local kind clusters when you are done:
kind delete cluster --name demo-east
kind delete cluster --name demo-westIf you also want to remove the imported resources from Multikube, delete them with multikubectl:
multikubectl delete route route-east
multikubectl delete route route-west
multikubectl delete policy demo-readonly
multikubectl delete policy demo-deny-delete
multikubectl delete backend east-cluster
multikubectl delete backend west-cluster