Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@ryanj
Last active October 25, 2017 15:23
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ryanj/efe83c2a42aa16a81ccdadeaba470c5a to your computer and use it in GitHub Desktop.
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
<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&hellip;
## 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'>&lt;expanding brain meme&gt;</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