Last active
October 29, 2017 15:58
-
-
Save ryanj/4eb2d828345d0431fb15934b8ae0be6a to your computer and use it in GitHub Desktop.
S1 Hands-On Introduction to Kubernetes at LISA 2017 in SF http://bit.ly/lisa17-k8s
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<section data-transition='concave'> | |
<section id="S1-Hands-On-Intro-to-Kubernetes"> | |
<a href="http://kubernetes.io/"><img src="https://cdn.rawgit.com/ryanj/1aed9676c69ab0073be0beb60ca77a9c/raw/74f82bdfb47f1addaca529e8ee63ed678356a62f/kubernetes-blueprint-logo.svg" alt="kubernetes" style='width:30%;'></a> | |
<h3><span style='font-weight:900;color:#1e90ff;'>S1</span> Hands-On Introduction to</h3> | |
<h1>Kubernetes</h1> | |
<p><a href="https://www.usenix.org/conference/lisa17/training-program/session/hands-intro-kubernetes">Sunday, October 29th 9:00 am–12:30 pm</a><br/> | |
at <a href="https://www.usenix.org/conference/lisa17">#LISA17</a> in SF</p> | |
<h4 class='fragment grow'><a href="http://bit.ly/lisa17-k8s">bit.ly/lisa17-k8s</a></h4> | |
</section> | |
<section data-background-transition='fade' data-background='black' id='presented-by-ryanj'> | |
<p>presented by <a href="http://twitter.com/ryanj/">@ryanj</a>, Developer Advocate at Red Hat</p> | |
<p class='fragment fade-up'><a href="http://twitter.com/ryanj/"><img alt="ryanj" src="http://ryanjarvinen.com/images/ryanj-mestrefungo-com.gif" style="width:50%"/></p> | |
</section> | |
</section> | |
<section data-transition='zoom'> | |
<section data-transition='convex' id='agenda'> | |
<h2>Administration</h2> | |
<ol> | |
<li class='fragment'><a href="#/agenda">Introduction</a> | |
<ul> | |
<li><a href="#/workshop-setup">Workshop Setup</a></li> | |
</ul> | |
</li> | |
<li class='fragment'><a href="#/kubernetes-basics">Kubernetes Basics</a> | |
<ul> | |
<li><a href="#/terminology">Learn five K8s Primitives</a></li> | |
</ul> | |
</li> | |
<li class='fragment'><a href="#/kubernetes-arch">Kubernetes Architecture</a></li> | |
<li class='fragment'><a href="#/local-dev">Local Development with Minikube</a></li> | |
<li class='fragment'><a href="#/wrap-up">Wrap-up</a></li> | |
</ol> | |
</section> | |
<section id='survey'> | |
<h3>Intro Survey / Who are you?</h3> | |
<ol> | |
<li class='fragment'>Are you doing anything with containers today?</li> | |
<li class='fragment'>Do you have any experience using Kubernetes?</li> | |
<li class='fragment'>Do you consider yourself to be basically proficient with the <code>kubectl</code> cli tool?</li> | |
<li class='fragment'>Can you name five basic primitives or resource types?</li> | |
<li class='fragment'>Can you name five architectural components provided by Kubernetes?</li> | |
</ol> | |
</section> | |
</section> | |
<section> | |
<section data-transition='concave' id='workshop-setup' data-markdown> | |
## LISA17 S1 Training Prep | |
Bring a laptop with the following items pre-installed: | |
1. [kubectl](#/kubectl) | |
2. [minikube](#/minikube) | |
3. [docker](#/docker) | |
4. [git](#/git) | |
</section> | |
<section id='kubectl'> | |
<h3>Install <code>kubectl</code></h3> | |
<p>Installation on linux/amd64:</p> | |
<pre><code contenteditable>curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/ | |
</code></pre> | |
<p>Installation on macOS:</p> | |
<pre><code contenteditable>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 && sudo mv kubectl /usr/local/bin/ | |
</code></pre> | |
<p>For other platforms, consult the official <a href="https://kubernetes.io/docs/tasks/tools/install-kubectl/"><code>kubectl</code> setup guide</a></p> | |
<br/> | |
<p>To verify <code>kubectl</code> availability, try running:</p> | |
<pre><code contenteditable>kubectl help</code></pre> | |
</section> | |
<section id='minikube'> | |
<h3>Install <code>minikube</code></h3> | |
<p>Installation on linux/amd64:</p> | |
<pre><code contenteditable>curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/</code></pre> | |
<p>Installation on macOS:</p> | |
<pre><code contenteditable>curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/</code></pre> | |
<p>For other platforms, see the <a href="https://github.com/kubernetes/minikube/releases"><code>minikube</code> release notes</a></i></p> | |
<p>Optionally, customize your cluster's memory or cpu allocation:</p> | |
<pre><code contenteditable>minikube config set memory 4096 | |
minikube config set cpus 2</code></pre> | |
<p>to verify <code>minikube</code> availability:</p> | |
<pre><code contenteditable>minikube version</code></pre> | |
</section> | |
<section id='minikube-basics' markdown> | |
<h2>Minikube Basics</h2> | |
<p><code>minikube</code> provides an easy way to run Kubernetes locally:</p> | |
<pre><code contenteditable>minikube start</code></pre> | |
<p>When you are done, halt the VM to free up system resources:</p> | |
<pre><code contenteditable>minikube stop</code></pre> | |
<p>Need a fresh start? Delete your VM instance with:</p> | |
<pre><code contenteditable>minikube delete</code></pre> | |
</section> | |
<section id='minikube-virt'> | |
<h3>Minikube troubleshooting</h3> | |
<h5>If your minikube environment does not boot correctly:</h5> | |
<ol> | |
<li>Minikube requires an OS virtualization back-end</li> | |
<li>Most OSes include some support for virtualization</li> | |
<li>You can use the <a href="https://github.com/kubernetes/minikube#quickstart"><code>--vm-driver</code></a> flag to select a specific virt provider</li> | |
</ol> | |
<pre><code contenteditable>minikube start --vm-driver=virtualbox</code></pre> | |
<p>Check the project <a href="https://github.com/kubernetes/minikube#requirements"><code>README</code></a> for more information about <a href="https://github.com/kubernetes/minikube/blob/master/docs/drivers.md">supported virtualization plugins</a></p> | |
<br/> | |
<p>Still stuck? Consider signing up for OpenShift Starter or GKE: bit.ly/k8s-gcloud | |
</section> | |
<section id='docker'> | |
<h3>Install docker</h3> | |
<p>Download and install a binary from <a href="https://store.docker.com/search?offering=community&type=edition">the docker store</a></p> | |
<p>Or, use a package manager to install:</p> | |
<pre><code contenteditable>brew install docker</code></pre> | |
<p>To verify <code>docker</code> availability:</p> | |
<pre><code contenteditable>docker version</code></pre> | |
<p>To <a href="https://github.com/kubernetes/minikube/blob/master/docs/reusing_the_docker_daemon.md">reference minikube's docker daemon from your host</a>, run:</p> | |
<pre><code contenteditable>eval $(minikube docker-env)</code></pre> | |
</section> | |
<section id='git'> | |
<h3>Install git</h3> | |
<p>Install <code>git</code> using the instructions here:</p> | |
<p><a href="https://git-scm.com/book/en/v2/Getting-Started-Installing-Git">https://git-scm.com/book/en/v2/Getting-Started-Installing-Git</a></p> | |
<p>To verify <code>git</code> availability, run:</p> | |
<pre><code contenteditable>git version</code></pre> | |
</section> | |
</section> | |
<section data-transition='zoom-in convex-out' id='ready'> | |
<h1><i>Ready?</i></h1> | |
<br/> | |
<div class='fragment fade-up'> | |
<p>Verify that your local Kubernetes environment is ready by running:<br/> | |
<pre><code contenteditable>kubectl version</code></pre> | |
<p>The output should include your <code>kubectl</code> version info, and the release version of the kubernetes API server (when available)</p> | |
</div> | |
</section> | |
<section data-transition="zoom" data-markdown> | |
# Let's Go! | |
</section> | |
<section> | |
<section id="kubernetes-basics"> | |
<a href="http://kubernetes.io/"><img src="https://pbs.twimg.com/profile_images/511909265720614913/21_d3cvM.png" alt="kubernetes" style='width:33%;'></a> | |
<h2>Kubernetes Command-Line Basics</h2> | |
<h3>with <a href="https://kubernetes.io/docs/user-guide/kubectl/"><code>kubectl</code></a></h3> | |
</section> | |
</section> | |
<section> | |
<section id='why-k8s'> | |
<h3>Why Kubernetes?</h3> | |
<p><img src="https://pbs.twimg.com/profile_images/511909265720614913/21_d3cvM.png" alt="kubernetes" style='width:30%;'></p> | |
</section> | |
<section id='k8s-is'> | |
<h3>Kubernetes is...</h3> | |
<ol> | |
<li class='fragment'>An open source platform for running container-based distributed solutions, featuring a modular, HA systems architecture</li> | |
<li class='fragment'>The best way to actively manage distributed solutions at scale, based on years of industry expertise (Google-scale experience)</li> | |
<li class='fragment'>An extensible distributed-solutions modeling language with a huge community following</li> | |
<li class='fragment'>A multi-vendor effort to eliminate cloud lock-in through the adoption of "cloud native" solutions (capable of runnning on any infrastructure)</li> | |
</ol> | |
</section> | |
<section id='an-api' data-markdown> | |
Kubernetes provides… | |
## An API | |
API object primitives include the following attributes: | |
``` | |
kind | |
apiVersion | |
metadata | |
spec | |
status | |
``` | |
*mostly true | |
</section> | |
<section data-transition="linear" id='terminology' data-markdown> | |
### Basic K8s Terminology | |
1. [node](#/node) | |
2. [pod](#/po) | |
3. [service](#/svc) | |
4. [deployment](#/deploy) | |
5. [replicaSet](#/rs) | |
</section> | |
</section> | |
<section> | |
<section data-transition="linear" id='node' data-markdown> | |
### Node | |
A node is a host machine (physical or virtual) where containerized processes run. | |
Node activity is managed via one or more Master instances. | |
</section> | |
<section> | |
<p>Try using <code>kubectl</code> to list resources by type:</p> | |
<pre><code contenteditable>kubectl get nodes</code></pre> | |
<p>Request the same info, but output the results as structured yaml:</p> | |
<pre><code contenteditable>kubectl get nodes -o yaml</code></pre> | |
<p>Fetch an individual resource by <code>type/id</code>, output as <code>json</code>:</p> | |
<pre><code contenteditable>kubectl get node/minikube -o json</code></pre> | |
<p>View human-readable API output:</p> | |
<pre><code contenteditable>kubectl describe node/minikube</code></pre> | |
</section> | |
<section data-markdown> | |
### Observations: | |
* Designed to exist on multiple machines (distributed system) | |
* high availability of nodes | |
* platform scale out | |
* The API ambidextriously supports both json and yaml | |
</section> | |
</section> | |
<section> | |
<section data-transition="linear" id='po' data-markdown> | |
### Pod | |
A group of one or more co-located containers. Pods represent your minimum increment of scale. | |
> "Pods Scale together, and they Fail together" @theSteve0 | |
</section> | |
<section> | |
<p>List resources by type:</p> | |
<pre><code contenteditable>kubectl get pods</code></pre> | |
<p>Create a new resource based on a json object specification:</p> | |
<pre><code contenteditable>curl https://raw.githubusercontent.com/ryanj/metrics-k8s/master/pod.json</code></pre> | |
<pre><code contenteditable>kubectl create -f https://raw.githubusercontent.com/ryanj/metrics-k8s/master/pod.json</code></pre> | |
<p>List resources by type:</p> | |
<pre><code contenteditable>kubectl get pods</code></pre> | |
<p>Fetch a resource by type and id, output the results as <code>yaml</code>:</p> | |
<pre><code contenteditable>kubectl get pod metrics-k8s -o yaml</code></pre> | |
<p>Notice any changes?</p> | |
</section> | |
<section data-markdown> | |
### Observations: | |
* pods are scheduled to be run on nodes | |
* asyncronous fulfilment of requests | |
* declarative specifications | |
* automatic health checks, lifecycle management for containers (processes) | |
</section> | |
</section> | |
<section> | |
<section data-transition="linear" id='svc' data-markdown> | |
### Service | |
Services (svc) establish a single endpoint for a collection of replicated pods, distributing inbound traffic based on label selectors | |
In our K8s modeling language they represent a load balancer. Their implementation often varies per cloud provider | |
</section> | |
<section id='services'> | |
<h3>Contacting your App</h3> | |
<p>Expose the pod by creating a new <code>service</code> (or "loadbalancer"):</p> | |
<pre><code contenteditable>kubectl expose pod/metrics-k8s --port 2015 --type=NodePort</code></pre> | |
<p>Contact your newly-exposed pod using the associated service id:</p> | |
<pre><code contenteditable>minikube service metrics-k8s</code></pre> | |
<p>Schedule a pod to be deleted:</p> | |
<pre><code contenteditable>kubectl delete pod metrics-k8s</code></pre> | |
<p>Contact the related service. What happens?:</p> | |
<pre><code contenteditable>minikube service metrics-k8s</code></pre> | |
<p>Delete the service:</p> | |
<pre><code contenteditable>kubectl delete service metrics-k8s</code></pre> | |
</section> | |
<section data-markdown> | |
### Observations: | |
* *"service"* basically means *"loadbalancer"* | |
* Pods and Services exist independently, have disjoint lifecycles | |
</section> | |
</section> | |
<section> | |
<section data-transition="linear" id='deploy' data-markdown> | |
### Deployment | |
A `deployment` helps you specify container runtime requirements (in terms of pods) | |
</section> | |
<section> | |
<p>Create a specification for your <code>deployment</code>:</p> | |
<pre><code contenteditable>kubectl run metrics-k8s --image=quay.io/ryanj/metrics-k8s \ | |
--expose --port=2015 --service-overrides='{ "spec": { "type": "NodePort" } }' \ | |
--dry-run -o yaml > deployment.yaml</code></pre> | |
<p>View the generated deployment spec file:</p> | |
<pre><code contenteditable>cat deployment.yaml</code></pre> | |
<p><i><b>Bug?:</b></i>You may need to edit this file, adding "<code>---</code>" (on it's own line) between resource 1 and resource 2 for a workaround.</p> | |
<p>Can you think of another way to fix this issue? json compatible?</p> | |
</section> | |
<section> | |
<p>Create a new resource based on your yaml specification:</p> | |
<pre><code contenteditable>kubectl create -f deployment.yaml</code></pre> | |
<p>List resources by type:</p> | |
<pre><code contenteditable>kubectl get po,svc</code></pre> | |
<p>Connect to your new deployment via the associated service id:</p> | |
<pre><code contenteditable>minikube service metrics-k8s</code></pre> | |
</section> | |
<section id='replication'> | |
<h2>Replication</h2> | |
<p>Scale up the <code>metrics-k8s</code> deployment to 3 replicas:</p> | |
<pre><code contenteditable>kubectl scale deploy/metrics-k8s --replicas=3</code></pre> | |
<p>List pods:</p> | |
<pre><code contenteditable>kubectl get po</code></pre> | |
</section> | |
<section> | |
<p>Edit <code>deploy/metrics-k8s</code>, setting <code>spec.replicas</code> to <code>5</code>:</p> | |
<pre><code contenteditable>kubectl edit deploy/metrics-k8s -o json</code></pre> | |
<p>Save and quit. What happens?</p> | |
<pre><code contenteditable>kubectl get pods</code></pre> | |
</section> | |
<section id='autorecovery'> | |
<h2>AutoRecovery</h2> | |
<p>Watch for changes to <code>pod</code> resources:</p> | |
<pre><code contenteditable>kubectl get pods --watch</code></pre> | |
<p>In another terminal, delete several pods by id:</p> | |
<pre><code contenteditable>kubectl delete pod $(kubectl get pods | grep ^metrics-k8s | cut -f1 -s -d' ' | head -n 3 | tr '\n' ' ')</code></pre> | |
<p>What happend? How many pods remain?</p> | |
<pre><code contenteditable>kubectl get pods</code></pre> | |
</section> | |
<section data-markdown> | |
### Observations: | |
* Use the `--dry-run` flag to generate new resource specifications | |
* A deployment spec contains a pod spec | |
</section> | |
</section> | |
<section> | |
<section data-transition="linear" id='rs' data-markdown> | |
### ReplicaSet | |
A `replicaset` provides replication and lifecycle management for a specific image release | |
</section> | |
<section> | |
<p>Watch deployments (leave this running until the 'cleanup' section):</p> | |
<pre><code contenteditable>kubectl get deploy --watch</code></pre> | |
<p>View the current state of your deployment:</p> | |
<pre><code contenteditable>minikube service metrics-k8s</code></pre> | |
</section> | |
<section> | |
<h3>Rollouts</h3> | |
<p>Update your deployment's image spec to rollout a new release:</p> | |
<pre><code contenteditable>kubectl set image deploy/metrics-k8s metrics-k8s=quay.io/ryanj/metrics-k8s:v1</code></pre> | |
<p>Reload your browser to view the state of your deployment</p> | |
<pre><code contenteditable>kubectl get rs,deploy</code></pre> | |
</section> | |
<section> | |
<h3>Rollbacks</h3> | |
<p>View the list of previous rollouts:</p> | |
<pre><code contenteditable>kubectl rollout history deploy/metrics-k8s</code></pre> | |
<p>Rollback to the previous state:</p> | |
<pre><code contenteditable>kubectl rollout undo deployment metrics-k8s</code></pre> | |
<p>Reload your browser to view the state of your deployment</p> | |
</section> | |
<section> | |
<h3>Cleanup</h3> | |
<p>Cleanup old resources if you don't plan to use them:</p> | |
<pre><code contenteditable>kubectl delete service,deployment metrics-k8s</code></pre> | |
<p>Close any remaining <code>--watch</code> listeners</p> | |
</section> | |
<section data-markdown> | |
### Observations: | |
* The API allows for watch operations (in addition to get, set, list) | |
* ReplicaSets provide lifecycle management for pod resources | |
* Deployments create ReplicaSets to manage pod replication per rollout (per change in podspec: image:tag, environment vars) | |
</section> | |
</section> | |
</section> | |
<section data-markdown> | |
##### break 1 | |
</section> | |
<section> | |
<section id="kubernetes-arch"> | |
<a href="https://github.com/kubernetes/minikube"><img style="width:30%;" src="https://raw.githubusercontent.com/kubernetes/minikube/master/logo/logo.png" /></a> | |
<h2>Kubernetes Architecture</h2> | |
<h3>adapted for <a href="https://github.com/kubernetes/minikube"><code>minikube</code></a></h3> | |
</section> | |
<section id='k8s-architecture-model'> | |
<h3>Kubernetes is designed ...</h3> | |
<ol> | |
<li class='fragment'>for managing distributed solutions at scale, based on years of industry expertise (Google-scale experience)</li> | |
<li class='fragment'>for high availabilty of the control plane and user workloads (when using pod replication), avoiding most single points of failure</li> | |
<li class='fragment'>with a modular control plane architecture, allowing many peices to be replaced without disrupting workload availability</li> | |
<li class='fragment'>to persist all of it's internal platform state within an etcd database</li> | |
</ol> | |
</section> | |
<section data-markdown> | |
## etcd | |
![etcd logo](https://raw.githubusercontent.com/coreos/etcd/master/logos/etcd-glyph-color.png) | |
* distributed key-value store | |
* implements the RAFT consensus protocol | |
</section> | |
<section data-markdown> | |
### CAP theorum | |
1. Consistency | |
2. Availability | |
3. Partition tolerance | |
[etcd is "CA"](https://coreos.com/etcd/docs/latest/learning/api_guarantees.html) | |
</section> | |
<section data-markdown> | |
## Degraded Performance | |
Fault tolerance sizing chart: | |
![etcd cluster sizing chart](http://cloudgeekz.com/wp-content/uploads/2016/10/etcd-fault-tolerance-table.png) | |
</section> | |
<section data-markdown> | |
### play.etcd.io | |
[play.etcd.io/play](http://play.etcd.io/play) | |
</section> | |
<section data-markdown> | |
## Kubernetes API | |
* gatekeeper for etcd (the only way to access the db) | |
* not required for pod uptime | |
</section> | |
<section data-markdown> | |
### API outage simulation | |
Example borrowed from [Brandon Philips' "Fire Drills" from OSCON 2016](https://github.com/philips/2016-OSCON-containers-at-scale-with-Kubernetes#fire-drills): | |
https://github.com/philips/2016-OSCON-containers-at-scale-with-Kubernetes#fire-drills | |
</section> | |
<section data-markdown> | |
Create a pod and a service. Verify that the service is responding. | |
``` | |
kubectl run metrics-k8s --image=quay.io/ryanj/metrics-k8s \ | |
--expose --port=2015 --service-overrides='{ "spec": { "type": "NodePort" } }' | |
``` | |
``` | |
minikube service metrics-k8s | |
``` | |
ssh into minikube, kill the control plane: | |
``` | |
minikube ssh | |
ps aux | grep "localkube" | |
sudo killall localkube | |
logout | |
``` | |
Use kubectl to list pods: | |
``` | |
kubectl get pods | |
The connection to the server mycluster.example.com was refused - did you specify the right host or port? | |
``` | |
The API server is down! | |
Reload your service. Are your pods still available? | |
</section> | |
<section data-markdown> | |
## Kubelet | |
Runs on each node, listens to the API for new items with a matching `NodeName` | |
</section> | |
<section data-markdown> | |
## Kubernetes Scheduler | |
Assigns workloads to Node machines | |
</section> | |
<section data-markdown> | |
## Bypass the Scheduler | |
Create two pods: | |
``` | |
kubectl create -f https://raw.githubusercontent.com/ryanj/metrics-k8s/master/pod.json | |
kubectl create -f https://gist.githubusercontent.com/ryanj/893e0ac5b3887674f883858299cb8b93/raw/0cf16fd5b1c4d2bb1fed115165807ce41a3b7e20/pod-scheduled.json | |
``` | |
View events: | |
``` | |
kubectl get events | |
``` | |
Did both pods get scheduled? run? | |
</section> | |
<section data-markdown> | |
## Kube DNS | |
</section> | |
<section data-markdown> | |
## Kube Proxy | |
</section> | |
<section data-markdown> | |
## CNI | |
* flannel | |
* canal | |
</section> | |
<section data-markdown> | |
## CRI | |
* containerd (docker) | |
* cri-o | |
* rkt | |
compatible with OCI image spec., runtime | |
</section> | |
<section id='k8s-controllers' data-markdown> | |
### K8s Controllers | |
Controllers work to regulate the declarative nature of the platform state, reconsiling imbalances via a basic control loop | |
https://kubernetes.io/docs/admin/kube-controller-manager/ | |
Kubernetes allows you to introduce your own custom controllers! | |
</section> | |
<section data-markdown> | |
### Architecture Diagram | |
![arch diagram](https://cdn.thenewstack.io/media/2016/08/Kubernetes-Architecture-1024x637.png) | |
</section> | |
<section data-markdown> | |
### Interaction Diagram | |
![interaction diagram](https://i1.wp.com/blog.docker.com/wp-content/uploads/swarm_kubernetes2.png?resize=1024) | |
[(copied from blog.docker.com)](https://blog.docker.com/2016/03/swarmweek-docker-swarm-exceeds-kubernetes-scale/) | |
</section> | |
</section> | |
<section data-markdown> | |
##### break 2 | |
</section> | |
<section data-transition='concave'> | |
<section id='local-dev'> | |
<a href="https://github.com/kubernetes/minikube"><img style="width:30%;" src="https://raw.githubusercontent.com/kubernetes/minikube/master/logo/logo.png" /></a> | |
<h2>Local Development</h2> | |
<p>with</p> | |
<h1><a href="https://github.com/kubernetes/minikube"><code>minikube</code></a></h1> | |
</section> | |
</section> | |
</section> | |
<section id='needs'> | |
<p>Kubernetes provides portable abstractions for working with distributed solitions:</p> | |
<ol> | |
<li class='fragment'>standardized packaging (containers, volumes, pods)</li> | |
<li class='fragment'>load balancing (services)</li> | |
<li class='fragment'>scaling automation (replica sets)</li> | |
</ol> | |
<br/> | |
<br/> | |
<h5 class='fragment' id="need-any-of-these-for-local-development-">Need any of these for local development?</h5> | |
</section> | |
<section id='why-local'> | |
<h3 id="why-run-k8s-locally-">Why run K8s locally?</h3> | |
<p>As web development is increasingly being carried out using container-based microservices:</p> | |
<ol> | |
<li class='fragment'>ability to offer reproducible development environments | |
<ul><li class='fragment'>reduce onboarding time for new devs</li></ul></li> | |
<li class='fragment'>minimize deltas between dev and prod environments | |
<ul><li class='fragment'>fewer surprises when promoting code leads to faster velocity</li></ul></li> | |
<li class='fragment'>decentralize your release pipeline, allow CI test suites to be run locally | |
<ul><li class='fragment'>provide functional / systems-integration feedback earlier in the dev lifecycle</li></ul></li> | |
<li class='fragment'>potenial for fully offline development | |
<ul><li class='fragment'><expanding brain meme></li></ul></li> | |
</ol> | |
</section> | |
</section> | |
<section> | |
<section id='checklist' data-markdown> | |
### Local Development Checklist: | |
1. [onboarding](#/onboarding) - show someone new how to run the `:latest` release | |
2. [preview changes](#/preview) - review changes and iterate on a solution | |
3. [test changes](#/test) - build and deploy | |
4. [promote changes](#/promote) - git push | |
</section> | |
</section> | |
<section> | |
<section data-background-transition='zoom' id='onboarding' data-markdown> | |
## Onboarding | |
</section> | |
<section> | |
<h3>Onboarding - Yesterday's Jam</h3> | |
<ol> | |
<li class='fragment'><code>git clone https://github.com/ryanj/metrics-k8s</code></li> | |
<li class='fragment'><code>cd metrics-k8s</code></li> | |
<li class='fragment'><code><span style="text-decoration: line-through;">npm install</span></code></li> | |
<li class='fragment'><code><span style="text-decoration: line-through;">npm start</span></code></li> | |
</ol> | |
</section> | |
<section data-markdown> | |
### Onboarding - Add K8s | |
Generate kubernetes `deployment` and `service` specifications, both named `metrics-review`: | |
```bash | |
kubectl run metrics-review --image=quay.io/ryanj/metrics-k8s \ | |
--expose --port=2015 --service-overrides='{ "spec": { "type": "NodePort" } }' \ | |
--dry-run -o yaml > metrics-review.yaml | |
``` | |
</section> | |
<section data-markdown> | |
### Onboarding - deploy :latest | |
Test your generated spec: | |
```bash | |
kubectl create -f metrics-review.yaml | |
``` | |
Minikube users will be able to open the resulting service in their browser by running: | |
```bash | |
minikube service metrics-review | |
``` | |
</section> | |
</section> | |
<section> | |
<section id='preview' data-markdown> | |
## Preview Changes | |
</section> | |
<section data-markdown> | |
## Preview - local files | |
First, share your local clone of `metrics-k8s` with minikube: | |
```bash | |
minikube mount $(pwd):/var/www/html | |
``` | |
</section> | |
<section data-markdown> | |
## Preview - hostPath | |
Next, produce a new deployment spec that includes (minimal) support for live development workflows: | |
1. `cp metrics-review.yaml metrics-dev.yaml` | |
2. replace `metrics-review` with `metrics-dev` (global) | |
2. Add a `hostPort` volume to access your local repo: | |
```diff | |
spec: | |
containers: | |
- image: quay.io/ryanj/metrics-k8s | |
name: metrics-dev | |
ports: | |
- containerPort: 2015 | |
resources: {} | |
+ volumeMounts: | |
+ - mountPath: /var/www/html | |
+ name: metrics-src | |
+ volumes: | |
+ - name: metrics-src | |
+ hostPath: | |
+ path: /var/www/html | |
status: {} | |
``` | |
</section> | |
<section data-markdown> | |
### Preview | |
The resulting file should look just like the included [metrics-dev.yaml](https://raw.githubusercontent.com/ryanj/metrics-k8s/master/metrics-dev.yaml) file from the `metrics-k8s` git repo. | |
Try launching it with: | |
```bash | |
kubectl create -f metrics-dev.yaml | |
``` | |
</section> | |
<section data-markdown> | |
### Preview | |
Verify that any changes written to your local repo become immediately visible when reloading your browser window: | |
1. view your latest | |
```bash | |
minikube service metrics-dev | |
``` | |
2. make a change to `index.html` | |
3. reload your browser | |
</section> | |
</section> | |
<section> | |
<section data-background-transition='zoom' id='test' data-markdown> | |
## Test | |
</section> | |
<section id="test-rollout"> | |
<h3>Test - Rollout</h3> | |
<ol> | |
<li>Verify that <a href="#/docker">your <code>docker-env</code> is configured for minikube</a></li> | |
<li>Run a build | |
<pre><code>docker build . -t yourname/metrics-k8s:v1</code></pre></li> | |
<li>Update <code>metrics-review.yaml</code>, setting the container <code>image</code> to: | |
<pre><code>yourname/metrics-k8s:v1</code></pre></li> | |
<li>Apply the changes locally: | |
<pre><code>kubectl apply -f metrics-review.yaml</code></pre></li> | |
<li>Check your latest before promoting: | |
<pre><code>minikube service metrics-review</code></pre></li> | |
</ol> | |
</section> | |
</section> | |
<section> | |
<section data-transition='zoom' id='promote' data-markdown> | |
## Promote Changes | |
</section> | |
<section data-markdown> | |
### Promoting Changes | |
1. `git push`? | |
2. send PR? | |
3. next steps TBD / handled by CI suite | |
</section> | |
</section> | |
<section> | |
<section id='wrap-up' data-markdown> | |
## Wrap Up | |
</section> | |
<section id='resources'> | |
<h2>Resources</h2> | |
<ol> | |
<li>Training materials to-go: <a href="http://bit.ly/k8s-workshops">bit.ly/k8s-workshops</a> <a href="https://www.slideshare.net/RyanJarvinen/handson-introduction-to-kubernetes-at-lisa17">(PDF)</a></li> | |
<li>Home: <a href="https://kubernetes.io">kubernetes.io</a></li> | |
<li>Docs: <a href="https://kubernetes.io/docs">K8s documentation</a></li> | |
<li>Community: <a href="https://github.com/kubernetes/community/blob/master/sig-list.md">K8s Special Interest Groups (SIGs)</a></li> | |
<li>eBook: <a href="https://www.openshift.com/promotions/kubernetes">Kubernetes: Scheduling the Future at Cloud Scale</a></li> | |
<li>eBook: <a href="https://www.openshift.com/promotions/docker-security.html">Docker Security: Using Containers Safely in Production</a></li> | |
<li>eBook: <a href="https://www.openshift.com/promotions/microservices.html">Microservices vs. Service-Oriented Architecture</a></li> | |
<li>eBook: <a href="https://www.openshift.com/promotions/for-developers.html">OpenShift for Developers</a></li> | |
</ol> | |
</section> | |
<section id='exit-survey'> | |
<h3>Exit Survey</h3> | |
<ol> | |
<li class='fragment'>Have you ever developed using containers?</li> | |
<li class='fragment'>Do you have any experience using Kubernetes?</li> | |
<li class='fragment'>Do you consider yourself to be basically proficient with the <code>kubectl</code> cli tool?</li> | |
<li class='fragment'>Can you name five basic primitives or resource types?</li> | |
<li class='fragment'>Can you name five pieces of k8s architecture?</li> | |
<li class='fragment'>Are you prepared to onboard a new web dev?</li> | |
</ol> | |
</section> | |
</section> | |
<section> | |
<section id='thank-you'> | |
<h1>Congratulations!</h1> | |
<p>on completing the</p> | |
<h2>[S1] Hands-on Intro to Kubernetes</h2> | |
<p>tutorial at #LISA17 in SF</p> | |
<br/> | |
<a href="http://bit.ly/lisa17-k8s"><h5 class='fragment grow'>bit.ly/lisa17-k8s</h5></a> | |
<br/> | |
<p><i>Please remember to complete your tutorial evaluation!</i></p> | |
</section> | |
</section> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment