Last active
October 25, 2017 15:23
-
-
Save ryanj/efe83c2a42aa16a81ccdadeaba470c5a to your computer and use it in GitHub Desktop.
Introduction to Kubernetes at All Things Open 2017 - http://bit.ly/ato-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="extended-session"> | |
<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> | |
<h2>Introduction to Kubernetes</h2> | |
<h4 class='fragment roll-in'><i>EXTENDED SESSION</i></h4> | |
<p><a href="https://allthingsopen.org/talk/introduction-to-kubernetes-extended-session/">Monday, October 23rd 1:30pm–3:15pm</a><br/> | |
<a href="https://allthingsopen.org/talk/introduction-to-kubernetes-extended-session/">Ballroom A #ATO2017</a></p> | |
<br/> | |
<h4 class='fragment grow'><a href="http://bit.ly/ato-k8s">bit.ly/ato-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:48%"/></p> | |
</section> | |
<section id='brought-to-you-by' data-background-transition="fade" data-background='black' data-markdown> | |
brought to you by | |
[![Red Hat logo](https://i.imgur.com/ArZFG3e.png "")](https://redhat.com) | |
</section> | |
</section> | |
<section data-transition='zoom'> | |
<section data-transition='convex' id='agenda'> | |
<h2>Workshop Agenda</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="#/why-k8s">Why Kubernetes?</a></li> | |
<li><a href="#/terminology">Learn five K8s Primitives</a></li> | |
</ul> | |
</li> | |
<li class='fragment'><a href="#/kubernetes-arch">Kubernetes Architecture</a> | |
<ul> | |
<li><a href="#/firedrills">Architecture Experiments</a></li> | |
</ul> | |
</li> | |
<li class='fragment'><a href="#/local-dev">Local Dev 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 pieces of k8s architecture?</li> | |
</ol> | |
</section> | |
</section> | |
<section> | |
<section data-transition='concave' id='workshop-setup' data-markdown> | |
## INTRODUCTION TO KUBERNETES | |
### Extended Session at #ATO2017 | |
##### Required Prep-Work | |
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>To verify <code>kubectl</code> availability, try running:</p> | |
<pre><code contenteditable>kubectl help</code></pre> | |
<p><i><a href="https://kubernetes.io/docs/tasks/tools/install-kubectl/">official <code>kubectl</code> setup notes</a></i></p> | |
</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>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> | |
<p><i><a href="https://github.com/kubernetes/minikube/releases">official <code>minikube</code> installation doc</a></i></p> | |
</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>Get a fresh start by deleting the VM with:</p> | |
<pre><code contenteditable>minikube delete</code></pre> | |
<h5>Advanced Challenge (Optional)</h5> | |
<p>Try the latest major release by starting your environment with:</p> | |
<pre><code contenteditable>minikube start --kubernetes-version v1.8.0 --bootstrapper kubeadm</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> | |
</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> Edit the 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 | |
* rkt | |
* oci | |
[https://coreos.com/blog/rkt-accepted-into-the-cncf.html](https://coreos.com/blog/rkt-accepted-into-the-cncf.html) | |
</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 $_</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 | |
resources: {} | |
ports: | |
- containerPort: 2015 | |
+ volumeMounts: | |
+ - mountPath: /var/www/html | |
+ name: src | |
+ volumes: | |
+ - name: src | |
+ hostPath: | |
+ path: /var/www/html | |
status: {} | |
``` | |
</section> | |
<section data-markdown> | |
### Preview | |
The resulting file should look like [this](https://raw.githubusercontent.com/ryanj/metrics-k8s/master/metrics-dev.yaml) | |
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 data-markdown> | |
### Test - Rollout | |
1. Verify that [your `docker-env` is configured correctly](#/docker) | |
2. Run a build `docker build . -t yourname/k8s-metrics:v1` | |
3. Update `metrics-review.yaml`, setting `image.name` to: `yourname/k8s-metrics:v1` | |
4. Apply the changes locally: `kubectl apply -f metrics-review.yaml` | |
5. Check your latest before promoting: `minikube service metrics-review` | |
</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 data-background-transition='zoom'> | |
Need support and upgraded dev workflows? Take a look at OpenShift! | |
</section> | |
</section> | |
<section> | |
<section id='wrap-up' data-markdown> | |
## Wrap Up | |
</section> | |
<section id='resources'> | |
<h2>Resources</h2> | |
<ol> | |
<li>more <a href="http://bit.ly/k8s-workshops">bit.ly/k8s-workshops</a></li> | |
<li><a href="https://kubernetes.io">kubernetes.io</a></li> | |
<li><a href="https://kubernetes.io/docs">K8s documentation</a></li> | |
<li><a href="https://manage.openshift.com/">Free hosting with Openshift Starter</a></li> | |
<li><a href="https://www.openshift.com/promotions/for-developers.html">ebook: OpenShift for Developers</a></li> | |
<li><a href="https://www.openshift.com/promotions/kubernetes">ebook: Kubernetes: Scheduling the Future at Cloud Scale</a></li> | |
<li><a href="https://www.openshift.com/promotions/docker-security.html">ebook: Docker Security: Using Containers Safely in Production</a></li> | |
<li><a href="https://www.openshift.com/promotions/microservices.html">ebook: Microservices vs. Service-Oriented Architecture</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 data-transition='concave' id='see-you-at-ATO'> | |
<h2><i>See you in Raleigh at #ATO2017!</i></h2> | |
<p>If you have successfully completed <a href="#/workshop-setup">the workshop setup instructions</a>, you should be ready to follow along</p> | |
<p>Additional instructions will be made available during the session</p> | |
<p><i><a href="https://allthingsopen.org/talk/introduction-to-kubernetes-extended-session/">Monday, October 23rd 1:30–3:15pm in Ballroom A</a></p> | |
<br/> | |
<h3 class='fragment grow'><a href="http://bit.ly/ato-k8s">bit.ly/ato-k8s</a></h3> | |
</section> | |
--> | |
<section> | |
<section id='thank-you'> | |
<h1>Thank You!</h1> | |
<p>Congratulations on completing the <i>#ATO2017</i></p> | |
<h4><b>Introduction to Kubernetes</b> extended session!</h4> | |
<br/> | |
<p><a href="http://gist-reveal.it/bit.ly/ato-k8s"><h5 class='fragment grow'>bit.ly/ato-k8s</h5></a></p> | |
<a href=""></h5></a> | |
</section> | |
</section> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment