MicroK8s on Google Cloud Platform
How cool is this!?
Setup
PROJECT=[[YOUR-PROJECT]]
INSTANCE=[[YOUR-INSTANCE]] # Perhaps 'microk8s'
ZONE=[[YOUR-ZONE]]gcloud compute instances create ${INSTANCE} \
--machine-type=custom-2-8192 \
--preemptible \
--tags=microk8s \
--image-family=ubuntu-minimal-1904 \
--image-project=ubuntu-os-cloud \
--zone=${ZONE} \
--project=${PROJECT} \
--metadata=startup-script='
!# /bin/bash
sudo snap install microk8s --classic --channel=1.15/stable
'
NB Use whichever Ubuntu version you prefer. I really wanted Ubuntu Core but I think
-minimial-
is likely as good as. Ubuntu comes with snap preinstalled.
If you want to save time prefixing microk8s.kubectl
commands with sudo
, you may add your user to the instance’s microk8s
group with:
gcloud compute ssh ${INSTANCE} \
--zone=${ZONE} \
--project=${PROJECT} \
--command="sudo usermod -a -G microk8s $(whoami)"
Then:
gcloud compute ssh ${INSTANCE} \
--zone=${ZONE} \
--project=${PROJECT}
Kubernetes
microk8s.kubectl cluster-info
Kubernetes master is running at https://127.0.0.1:16443
Heapster is running at ...
Grafana is running at ...
InfluxDB is running at ...microk8s.kubectl get nodes
NAME STATUS ROLES AGE VERSION
microk8s Ready <none> 5m v1.15.0
Then:
microk8s.kubectl run nginx --image=docker.io/nginx --port=80microk8s.kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-5d756c54b9-hm97d 1/1 Running 0 48smicrok8s.kubectl scale deployment/nginx --replicas=3microk8s.kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-5d756c54b9-gh5m6 1/1 Running 0 7s
nginx-5d756c54b9-hm97d 1/1 Running 0 71s
nginx-5d756c54b9-j869t 1/1 Running 0 7smicrok8s.kubectl expose deployment/nginx --type=NodePortmicrok8s.kubectl describe service/nginx
Name: nginx
Namespace: default
Labels: run=nginx
Annotations: <none>
Selector: run=nginx
Type: NodePort
IP: 10.152.183.77
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 32592/TCP
Endpoints: 10.1.1.10:80,10.1.1.11:80,10.1.1.12:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
And, of course:
# Programmatically grab the NodePort value (#32592 above)
PORT=$(\
microk8s.kubectl get service/nginx \
--output=jsonpath="{.spec.ports[0].nodePort}")curl http://localhost:${PORT}
Returns:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
Or, if you’d prefer:
gcloud compute ssh ${INSTANCE} \
--ssh-flag="-L ${PORT}:localhost:${PORT}" \
--zone=${ZONE} \
--project=${PROJECT}
NB Because you must run the
gcloud
command from your local workstation, you won’t have${PORT}
set. So you must replace${PORT}
with the value (32592
in my case) or set the variable’s value locally.NB There’s no requirement that the remote ${PORT} value be mapped to same port on your workstation; you could also use
80:localhost:${PORT}
to access the Nginx service on:80
.
And then you can access the service from your local workstation:
google-chrome http://localhost:${PORT}
Conclusion
As a Googler, I’m spoiled by Kubernetes Engine *but* sometimes you just want the simplest possible cluster *or* you want to develop|deploy locally. MicroK8s is excellent.
Follow-up
Securely accessing the remote cluster locally.
The API server is available on :16443
. If we can create a local kubernetes config file *and* we can port-forward to :16443
, then we can access the cluster remotely:
gcloud compute ssh ${INSTANCE} \
--zone=${ZONE} \
--project=${PROJECT} \
--ssh-flag="-L 16443:localhost:16443"
Then, from another terminal (while the above ssh port-forward is running), we can copy the microk8s
config file (
gcloud compute scp \
${INSTANCE}:/var/snap/microk8s/current/credentials/client.config \
${PWD} \
--zone=${ZONE} \
--project=${PROJECT}
And then, either use KUBECONFIG
:
KUBECONFIG=${PWD}/client.config
kubectl get pods
Or, explicitly referencing the config on each command:
kubectl --kubeconfig=${PWD}/client.config get pods
For completeness, Google’s Cloud SDK (gcloud
) andkubectl
are both available as Snaps if your local workstation also uses Snap.