I'm running this on Mac OSX 10+!
Pre-req:
- VirtualBox (there are other alternatives)
- kubectl
- minikube
- jq
Install everything:
- Download and install VirtualBox
- Install kubectl
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/darwin/amd64/kubectl && chmod +x kubectl && mv ./kubectl /usr/local/bin/
- Install minikube (latest version as of writing this)
curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.24.1/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
- Install jq via brew
- Start the Kubernetes dashboard, minikube will start a new browser session to the dashboard!
minikube dashboard
- Create a namespace
kubectl create namespace mikejoh
- Run a image on the cluster, in this case David C's hello-world image. Starts three pods via the replica option
kubectl run dotnet --image=sharor/hello-world --replicas=3 -n mikejoh
- Describe all of the pods (three in this case)
kubectl describe pod $(kubectl get pods -n mikejoh -o json | jq '.items[].metadata.name' --raw-output) -n mikejoh
- Check the pods
kubectl get pods -n mikejoh
- Expose a replication controller, service or pod as a new Kubernetes Service
kubectl expose deployment dotnet --type=NodePort --port=5000 -n mikejoh
- Check the service
$ kubectl describe svc dotnet -n mikejoh
Name: dotnet
Namespace: mikejoh
Labels: run=dotnet
Annotations: <none>
Selector: run=dotnet
Type: NodePort
IP: 10.103.61.43
Port: <unset> 5000/TCP
TargetPort: 5000/TCP
NodePort: <unset> 32099/TCP
Endpoints: 172.17.0.4:5000,172.17.0.5:5000,172.17.0.6:5000
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
- Now try to reach the exposed service via the NodePort outputted above (port 32099 in this case).
curl -I http://192.168.99.100:32099
HTTP/1.1 200 OK
Date: Wed, 03 Jan 2018 16:03:55 GMT
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
Server: Kestrel
- If you delete your namespace you can extract the deployment as yaml and use it later on
kubectl get deployment dotnet -o yaml -n mikejoh > myapp-deployment.yml
- To target your own namespace instead of the default one each time you run a command (without the -n flag), you can run this
kubectl config set-context $(kubectl config current-context) --namespace=mikejoh
The flow of this excercise:
- An app that reads two environment variables, API_KEY and LANGUAGE, and outputs these when you browse to the container
- Dockerfile with ENV
...
ENV LANGUAGE English
ENV API_KEY 123-456-789
...
- These gets overridden by the env in the k8s deployment yml-file. We have now hardcoded the secrets in our deployment yml-file, that's not what we want, deployment files will also be shared in various ways.
...
env:
- name: LANGUAGE
value: Polish
- name: API_KEY
value: 333-444-555
...
- We'll create a secret and a ConfigMap within our k8s cluster and namespace
- We'll swap out the env values once more from CLI
- Since the pods have a cache, we need to delete the pod so that it'll be recreated and using the new values
- Apply a deployment
kubectl apply -f deployment.yml
- Create a generic secret
kubectl create secret generic apikey --from-literal=API_KEY=oneringtorulethemall
- Create a ConfigMap
kubectl create configmap language --from-literal=LANGUAGE=Orcish
- Change the deployment yml-file to reference the secrets and ConfigMaps
env:
- name: LANGUAGE
valueFrom:
configMapKeyRef:
name: language
key: LANGUAGE
- name: API_KEY
valueFrom:
secretKeyRef:
name: apikey
key: API_KEY