Demo of Kubernetes Federation using Minikube & CoreDNS
-
Minikube >= v0.23.0: https://github.com/kubernetes/minikube/releases/tag/v0.23.0
-
Kubectl & kubefed >= v1.8: https://kubernetes.io/docs/tasks/federation/set-up-cluster-federation-kubefed/#getting-kubefed
cp ./kubefed /usr/local/bin/
The repo stores a few configuration files and the k8s yaml for a sample federated app
git clone https://github.com/emaildanwilson/minikube-federation
cd ./minikube-federationThis cluster will store the federation api/controller, etcd v2 and coredns.
minikube start -p minikubeetcd is used by a federation plugin to write dns records.
kubectl run etcd --image=quay.io/coreos/etcd:v2.3.7 --env="ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379" --env="ETCD_ADVERTISE_CLIENT_URLS=http://etcd.default:2379" --port=2379 --expose --context=minikubeservice "etcd" created
deployment "etcd" createdWe'll install and configure coredns using helm. coredns then reads from etcd as its dnszone configuration.
helm init --kube-context minikubeWait until helm version works.
Client: &version.Version{SemVer:"v2.6.1", GitCommit:"bbc1f71dc03afc5f00c6ac84b9308f8ecb4f39ac", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.6.1", GitCommit:"bbc1f71dc03afc5f00c6ac84b9308f8ecb4f39ac", GitTreeState:"clean"}Inspect the coredns-values.yaml file to see how coredns is configured to obtain dns records from etcd.
cat ./coredns-values.yamlInstall coredns using helm.
helm install --namespace default --name coredns --kube-context minikube -f ./coredns-values.yaml stable/corednsVerify that coredns is running
kubectl get svc,pods -l app=coredns-coredns --context=minikubeNAME READY STATUS RESTARTS AGE
coredns-coredns-5985d8488f-wm67q 1/1 Running 0 1m3.1 These clusters will be joined to federation and receive objects from the federation controllers.
On MacOSX you must use dind (docker in docker) to setup other cluster https://github.com/Mirantis/kubeadm-dind-cluster
minikube start -p us
minikube start -p europeOptional: Disable the dashboard on all clusters to save CPU
minikube addons disable dashboard -p minikube
minikube addons disable dashboard -p us
minikube addons disable dashboard -p europekubectl label node us failure-domain.beta.kubernetes.io/zone=us1 failure-domain.beta.kubernetes.io/region=us --context=us
kubectl label node europe failure-domain.beta.kubernetes.io/zone=europe1 failure-domain.beta.kubernetes.io/region=europe --context=europeThe uid is normally globally unique.
kubectl create configmap ingress-uid --from-literal=uid=us1 -n kube-system --context=us
kubectl create configmap ingress-uid --from-literal=uid=europe1 -n kube-system --context=europeNotice that the dns provider config is passed in from the local file coredns-provider.conf.
kubefed init myfed --host-cluster-context=minikube --dns-provider="coredns" --dns-zone-name="myzone." --api-server-service-type=NodePort --api-server-advertise-address=$(minikube ip -p minikube) --apiserver-enable-basic-auth=true --apiserver-enable-token-auth=true --apiserver-arg-overrides="--anonymous-auth=true,--v=4" --dns-provider-config="./coredns-provider.conf"Show the federation api and controller running on minikube
kubectl get pods --context=minikube -n federation-systemCheck the federation controller logs
kubectl logs -l module=federation-controller-manager --context=minikube -n federation-systemThey should look similar to this
controllermanager.go:93] v1.8.0
clustercontroller.go:63] Starting cluster controller
coredns.go:67] Using CoreDNS DNS provider
controllermanager.go:263] horizontalpodautoscalers controller disabled because API Server does not have required resources
servicecontroller.go:238] Starting federation service controller
dns.go:131] Starting federation service dns controller
controller.go:104] Starting federated sync controller for namespace resources
controller.go:104] Starting federated sync controller for replicaset resources
controller.go:104] Starting federated sync controller for secret resources
controller.go:104] Starting federated sync controller for configmap resources
controller.go:104] Starting federated sync controller for daemonset resources
controller.go:104] Starting federated sync controller for deployment resources
controllermanager.go:263] jobs controller disabled because API Server does not have required resources
ingress_controller.go:314] Starting Ingress Controller
ingress_controller.go:316] ... Starting Ingress Federated Informer
ingress_controller.go:318] ... Starting ConfigMap Federated Informerkubectl config use-context myfed
kubectl create ns defaultkubefed join us --host-cluster-context=minikube
kubefed join europe --host-cluster-context=minikubeThese labels are not required but can be used by the cluster selector or OPA policies.
kubectl label cluster us environment=test location=us pciCompliant=false
kubectl label cluster europe environment=prod location=europe pciCompliant=trueview the labels and make sure the clusters go to a Ready state
kubectl get clusters -L environment -L location -L pciCompliantNAME STATUS AGE ENVIRONMENT LOCATION PCICOMPLIANT
europe Ready 1m prod europe true
us Ready 1m test us false
Inspect the contents of hello.yaml.
A special annotation has been added to the service object to identify these endpoints to federation. This is required in order to tell the federation controller to add these records to etcd (which are then read by coredns)
Apply the yaml to the federation API.
kubectl apply -f ./hello.yaml --context=myfedcheck for objects in each cluster
kubectl get svc,rs,po,ing --context=us
kubectl get svc,rs,po,ing --context=europecheck for dns records
kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools --context=minikubeYou should see a command prompt of dnstools#
Execute a DNS query and exit
dnstools# nslookup hello.default.myfed.svc.myzone coredns-coredns.default
Server: 10.0.0.10
Address: 10.0.0.10#53
Name: hello.default.myfed.svc.myzone
Address: 192.168.99.101
Name: hello.default.myfed.svc.myzone
Address: 192.168.99.102
dnstools# exit
pod default/dnstools terminated (Error)Notice that both of the cluster endpoints are registered in DNS
kubectl scale rs/hello --replicas=3Check that the total count is now 3 across the clusters
kubectl get rs,po --context=us
kubectl get rs,po --context=europeInspect the contents of hello-selector.yaml.
Notice the additional annotation for federation.alpha.kubernetes.io/cluster-selector.
Apply the yaml to the federation API.
kubectl apply -f ./hello-selector.yamlverify that all replicas are now running in europe because that cluster has labels matching the selector
kubectl get rs,po --context=us
kubectl get rs,po --context=europeRemove federation components from the minikube context and delete the other minikube clusters.
kubectl delete ns federation-system --context=minikube
minikube stop -p minikube
minikube delete -p us
minikube delete -p europeOptional: nuke minikube cluster
minikube delete -p minikube