Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[2016.10 Meetup #6] [TALK #1] Miguel Duarte - Hands-on introduction to Kubernetes container orchestration

[2016.10 Meetup #6] [TALK #1] Miguel Duarte - Hands-on introduction to Kubernetes container orchestration

Docker brought containers to the masses, packaging all the bits and pieces necessary to run an application into a neat package deployable anywhere.
Kubernetes builds on that, aims to abstract away the infrastructure necessary to run complex applications. It allows horizontal scaling, load balancing, rolling upgrades, canary releases, allocating containers to machines automatically and much more. All that while being cloud provider agnostic (drivers exist for all major cloud providers). While some intro slides will be present this talk will be hands-on. A sample multi container app will be deployed and we will go trough some of Kubernetes most compelling features (live if Murphy allows, video otherwise :). The cookbook will be available on Github after the talk.

You can find the demoed scripts at https://github.com/malduarte/hello-kubernetes.

DevOps Lisbon

October 17, 2016
Tweet

More Decks by DevOps Lisbon

Other Decks in Technology

Transcript

  1. APP APP Libs Kernel Hardware APP APP Libs Kernel Hardware

    Libs Container CPU Memory Network Isolation
  2. APP APP Libs Kernel Hardware APP APP Libs Linux Hardware

    Libs Container CPU Memory Network Isolation
  3. APP APP Libs Kernel Hardware APP APP Libs Linux Hardware

    Libs Container CPU Memory Network Isolation
  4. Hello world! 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 DevopsLx2016!'); }; var www = http.createServer(handleRequest); www.listen(6969); Dockerfile FROM node:4.4 EXPOSE 6969 COPY server.js . CMD node server.js
  5. https://www.youtube.com/watch?v=wy3L7XUq-g0 dotScale 2015 - John Wilkes Cluster management at Google

    with Borg https://www.gcppodcast.com/post/episode-46-borg-and-k8s-with-john-wilkes/
  6. master etcd api scheduler controller-manager Kubernetes control plane Node proxy

    kubelet Kubelet communication between master and nodes.
  7. master etcd api scheduler controller-manager Kubernetes control plane Node proxy

    container engine kubelet container runtime container where PODS are deployed. Usually docker
  8. master etcd api scheduler controller-manager Kubernetes control plane Node proxy

    docker kubelet pod-1 pod-2 POD logical host where applications are run.
  9. master etcd api scheduler controller-manager Kubernetes control plane Node proxy

    docker kubelet pod-1 pod-2 Node proxy docker kubelet pod-1 pod-2 Node proxy docker kubelet pod-1 pod-2
  10. "Bringing Pokémon GO to life on Google Cloud" Thursday, September

    29, 2016 https://cloudplatform.googleblog.com/2016/09/bringing- Pokemon-GO-to-life-on-Google-Cloud.html
  11. S

  12. Install K8S binary $export K8S_VERSION=v1.4.1 # linux/darwin $export GOOS=darwin #

    one of 386/amd64/arm/arm64/ppc64le $export GOARCH=amd64 $export BASEURL=https://storage.googleapis.com/kubernetes-release/release $curl -Lo kubectl ${BASEURL}/${K8S_VERSION}/bin/${GOOS}/${GOARCH}/kubectl % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 63.3M 100 63.3M 0 0 2361k 0 0:00:27 0:00:27 --:--:-- 2337k
  13. minikube Local cluster • prerequisites : VT-x/AMD-v virtualisation enabled •

    latest virtualbox or xhyve hypervisor
 $ curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.11.0/minikube- darwin-amd64 $ chmod +x minikube $ ./minikube start $ ./minikube start Starting local Kubernetes cluster... Kubectl is now configured to use the cluster. $ ./kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system kube-addon-manager-minikube 1/1 Running 1 1h kube-system kubernetes-dashboard-gzzfz 1/1 Running 1 1h
  14. Build and Test the container $ docker build -t devopslx_2016:v1

    . Sending build context to Docker daemon 150.2 MB Step 1 : FROM node:4.4 ---> 93b396996a16 Step 2 : EXPOSE 6969 ---> Using cache ---> f5530af625b2 Step 3 : COPY server.js . ---> Using cache ---> 03153fda531d Step 4 : CMD node server.js ---> Using cache ---> 23fe9393d1d7 Successfully built 23fe9393d1d7 $ docker run -d -p 6969:6969 --name hello_devops_2016 devopslx_2016:v1 6a3be7e8b925f35b6d0ef1cbbefdf856da5f2d409500ca631a7515e398644a30 $ curl http://$(./minikube ip):6969 Hello DevopsLx2016!
  15. Running # in another terminal (this will open a proxy

    on port 8001) $./kubectl proxy Starting to serve on 127.0.0.1:8001 $ ./kubectl run hellodevopslx --image=devopslx_2016:v1 --port=6969 deployment "hellodevopslx" created $ ./kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hellodevopslx 1 1 1 1 11s $ ./kubectl get pod NAME READY STATUS RESTARTS AGE hellodevopslx-4264871600-c80th 1/1 Running 0 47s
  16. Accessing via API service $ ./kubectl get pod NAME READY

    STATUS RESTARTS AGE hellodevopslx-4264871600-c80th 1/1 Running 0 47s $ export POD_NAME="hellodevopslx-4264871600-c80th" $ for i in `seq 1 10`; do echo $(curl -s http://localhost:8001/api/v1/proxy/namespaces/ default/pods/$POD_NAME/$i) ; done Hello DevopsLx2016! Hello DevopsLx2016! Hello DevopsLx2016! (…) $ kubectl logs $POD_NAME Received request for URL: /1 Received request for URL: /2 Received request for URL: /3 (…)
  17. $ ./kubectl get services NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes

    10.0.0.1 <none> 443/TCP 2h $ ./kubectl expose deployment/hellodevopslx --type="NodePort" --port 6969 service "hellodevopslx" exposed $ ./kubectl get services NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE hellodevopslx 10.0.0.220 <nodes> 6969/TCP 8s kubernetes 10.0.0.1 <none> 443/TCP 2h $ ./kubectl describe services/hellodevopslx (…) NodePort: <unset> 32499/TCP (…) $ export NODE_PORT=32499 $ curl http://$(./minikube ip):$NODE_PORT Hello DevopsLx2016! Exposing We need to use "NodePort" because we're using a local cluster. In a real cluster, we should use "LoadBalancer"
  18. Labelling $ ./kubectl label pod $POD_NAME app=v1 pod "hellodevopslx-4264871600-c80th" labeled

    $ ./kubectl describe pod $POD_NAME Name: hellodevopslx-4264871600-c80th Namespace: default Node: minikube/192.168.64.2 Start Time: Sun, 16 Oct 2016 16:38:44 +0100 Labels: app=v1 pod-template-hash=4264871600 run=hellodevopslx Status: Running IP: 172.17.0.3 (…) $ ./kubectl get pods -l app=v1 NAME READY STATUS RESTARTS AGE hellodevopslx-4264871600-c80th 1/1 Running 0 42m
  19. Scaling $ ./kubectl scale deployments/hellodevopslx --replicas=4 deployment "hellodevopslx" scaled $

    ./kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hellodevopslx 4 4 4 4 47m Scale to 4 replicas! Check that the cluster has scaled
  20. Upgrading // new version to print the ip address of

    the network interfaces // This will be needed to prove that load is being spread to multiple containers var http = require('http'); var os = require('os'); var interfaces = os.networkInterfaces(); var addresses = []; for (var k in interfaces) { for (var k2 in interfaces[k]) { var address = interfaces[k][k2]; if (address.family === 'IPv4' && !address.internal) { addresses.push(address.address); } } } var handleRequest = function (request, response) { console.log('Received request for URL: ' + request.url); response.writeHead(200); response.end('from: ' + JSON.stringify(addresses, null, 2) + ' Hello DevopsLx2016 V2!'); }; var www = http.createServer(handleRequest); www.listen(6969);
  21. $ cp server_with_ip.js server.js $ docker build -t devopslx_2016:v2 .

    Sending build context to Docker daemon 150.2 MB Step 1 : FROM node:4.4 ---> 93b396996a16 Step 2 : EXPOSE 6969 ---> Using cache ---> f5530af625b2 Step 3 : COPY server.js . ---> d9f5332d5380 Removing intermediate container b2b6d55c7ac7 Step 4 : CMD node server.js ---> Running in 93089935d3c5 ---> 0fde770af7e3 Removing intermediate container 93089935d3c5 Successfully built 0fde770af7e3 ./kubectl set image deployments/hellodevopslx hellodevopslx=devopslx_2016:v2 deployment "hellodevopslx" image updated Building a new release Deploying a new release
  22. Load balancing $. curl http://$(./minikube ip):$NODE_PORT from: [ "172.17.0.7" ]

    Hello DevopsLx2016 V2! $ curl http://$(./minikube ip):$NODE_PORT from: [ "172.17.0.9" ] Hello DevopsLx2016 V2! $ curl http://$(./minikube ip):$NODE_PORT from: [ "172.17.0.7" ] Hello DevopsLx2016 V2!