7. DOCKER ON MAC
• Let’s focus on running Docker on the Mac
• Remember Docker only runs on Linux x64
• How do I run it on the Mac?
• Need Virtual Machine to emulate a Linux host
• Virtual machine (VM) running Linux x64
• Docker engine running on VM
• Mac client to communicate with Docker engine on Linux VM
8. DOCKER FOR MAC VS DOCKER TOOLBOX
Docker for Mac Docker Toolbox
# VMs 1 Multiple
Underlying VM
Hypervisor.framework
(xhyve)
VirtualBox
Base OS Alpine Boot2Docker
(VM) Management Tool Docker.app docker-machine
(VM) Management UI GUI CLI
9. MAC DOCKER ARCHITECTURE
Mac OS X
Virtual Machine (VirtualBox)Docker client
docker (CLI)
Kinematic (GUI)
Docker Machine
Linux (Boot2Docker)
Container
1
Container
2
Kernel
Docker Engine
Docker
Daemon
API
docker
(CLI)
11. KUBERNETES BASICS
• Tool to orchestrate containers at scale and managing the application/service stack
• Master
• API Server and kubectl (client) – communicate and define the desired state
• Scheduler – schedule workload on nodes
• Replication – correct number of pod replicas
• Config – distributed config store
• Node (Slave)
• Kubelet – communicate with master and start workloads
• Kube-proxy – load balancer and direct traffic
• Pod – group of 1..n containers tied together for admin and networking
• Cluster = masters + nodes
13. HELLO WORLD ON GOOGLE CLOUD
(KUBERNETES)
http://kubernetes.io/docs/hellonode/
14. PRE-REQUISITES – SERVER SIDE
1. Go to https://console.cloud.google.com/
2. Create a GCP Project
3. Copy the GCP Project ID
15. PRE-REQUISITES – CLIENT (MAC) SIDE
# Install node and nvm (node version manager)
$ brew update
$ brew install nvm
$ # Add the following to ~/.bash_profile
$ # export NVM_DIR=~/.nvm
$ # source $(brew --prefix nvm)/nvm.sh
$ nvm install 7.0.0
16. PRE-REQUISITES – CLIENT (MAC) SIDE II
$ # Install docker
$ brew install docker-compose # should also install docker and
docker-machine
$ # Install google cloud sdk
$ brew cask install google-cloud-sdk
$ gcloud components install kubectl
$ # You may want to add the following:
$ EXPORT PATH=$PATH:/opt/homebrew-cask/Caskroom/google-cloud-
sdk/latest/google-cloud-sdk/bin/
$ # Set up Google Cloud environment
$ export PROJECT_ID="my-google-cloud-project-id"
17. AUTHENTICATION
# Set up your account with google cloud sdk
$ gcloud auth login my-registered-email
$ gcloud config set project my-google-cloud-project-
id
$ gcloud auth list
# Optional: env var set for convenience
$ export PROJECT_ID="my-google-cloud-project-id"
$ # Note: your project-id != project name
18. NODE.JS CODE
// Filename: server.js
var http = require('http');
var handleRequest = function(request, response) {
console.log('Received request for URL: ' + request.url);
response.writeHead(200);
response.end('Hello World!');
};
var www = http.createServer(handleRequest);
www.listen(8080);
19. RUN DOCKER-MACHINE ON LOCAL VM
$ # Before running any docker commands, run docker-machine
to create a VirtualBox instance
$ docker-machine create --driver virtualbox default
$ docker-machine env
$ eval "$(docker-machine env default)"
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
default * virtualbox Running tcp://192.168.99.100:2376 v1.12.0
24. PUSH IMAGE TO PRIVATE GOOGLE REGISTRY
$ docker images
$ gcloud docker -- push gcr.io/$PROJECT_ID/helloworld:v1
$ # If gcloud docker -- push doesn’t work, you probably
didn’t set your project id properly.
$ # project name != project id. For example
$ # project name = helloworld-kubernetes
$ # project id = helloworld-kubernetes-148321
26. PUSH IMAGE TO PRIVATE GOOGLE REGISTRY
$ docker images
$ gcloud docker -- push gcr.io/$PROJECT_ID/helloworld:v1
$ # If gcloud docker -- push doesn’t work, you probably
didn’t set your project id properly.
$ # project name != project id. For example
$ # project name = helloworld-kubernetes
$ # project id = helloworld-kubernetes-148321
30. GET CREDENTIALS FOR KUBECTL
• API Manager > Create
Credentials > Service
Account Key
• JSON Key type
• Download the json file
31. AUTH FOR KUBECTL
$ # If you run kubectl, you see an error message
$ kubectl version
error: google: could not find default credentials. See https://
developers.google.com/accounts/docs/application-default-credentials
for more information.
$ You need to authenticate with the crentials
$ export GOOGLE_APPLICATION_CREDENTIALS=~/helloworld-
kubernetes-abcde00000.json
$ gcloud auth application-default login
$ kubectl version # Should work now
32. RUN KUBERNETES NODE
$ # Create and run a Kubernetes pod
$ kubectl run helloworld --image=gcr.io/$PROJECT_ID/helloworld:v1 --
port=8080
deployment "helloworld" created
$ # Print deployments
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
helloworld 1 1 1 1 1m
$ # Print pods
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
helloworld-2696007752-golst 1/1 Running 0 5m
33. TEST WEBSITE
$ # Expose pod. By default a Kubernetes node is only
accessible by its internal IP address
$ kubectl expose deployment helloworld --
type="LoadBalancer"
$ kubectl get services helloworld
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
helloworld 10.3.247.187 104.198.6.146 8080/TCP 2m
$ curl 104.198.6.146:8080
Hello World!
34. SCALE WEBSITE
$ # Scale the pod to 4 replicas
$ kubectl scale deployment helloworld --replicas=4
$ # Get status
$ kubectl get deployment
$ kubectl get pods
35. CHANGE CODE AND UPDATE GCP
$ # Edit server.js
$ vi server.js
$ # Build and push changes
$ docker build -t gcr.io/$PROJECT_ID/helloworld:v2 .
$ gcloud docker -- push gcr.io/$PROJECT_ID/helloworld:v2
$ # Deploy changes
$ kubectl set image deployment/helloworld helloworld=gcr.io/$PROJECT_ID/helloworld:v2
$ deployment "helloworld" image updated
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
helloworld-2696007752-bergs 1/1 Terminating 0 15m
helloworld-2696007752-c87rs 1/1 Terminating 0 15m
helloworld-2696007752-golst 1/1 Terminating 0 14h
helloworld-2696007752-zwpi4 1/1 Terminating 0 15m
helloworld-2777403465-e802v 1/1 Running 0 11s
helloworld-2777403465-ksyxe 0/1 ContainerCreating 0 5s
helloworld-2777403465-rgq7f 1/1 Running 0 11s
helloworld-2777403465-six3e 1/1 Running 0 4s
$ kubectl get services helloworld
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
helloworld 10.3.247.187 104.198.6.146 8080/TCP 14h
$ curl 104.198.6.146:8080
Hello World 2!