Skip to content

Instantly share code, notes, and snippets.

@ryanj
Last active July 31, 2018 20:30
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save ryanj/1bd1f8430c459def7bc398ab520b0f9a to your computer and use it in GitHub Desktop.
Save ryanj/1bd1f8430c459def7bc398ab520b0f9a to your computer and use it in GitHub Desktop.
K8s basics with kubectl at #SCaLE16X http://bit.ly/scale-k8s
<section data-transition='concave'>
<section id="local-development-with-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>
<h2>Kubernetes Basics</h2>
<p>with</p>
<h1><code>kubectl</code></h1>
<p>
<a href="https://www.socallinuxexpo.org/scale/16x/presentations/hands-intro-kubernetes-kubectl">Thursday, March 8th 13:30-16:30 in Room 211</a><br/>
at <a href="https://www.socallinuxexpo.org/scale/16x/presentations/hands-intro-kubernetes-kubectl">#SCaLE16x</a> in Pasadena, CA</p>
<h4 class='fragment grow'><a href="http://bit.ly/scale-k8s">bit.ly/scale-k8s</a></h4>
</section>
<section data-transition='concave' 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 id='brought-to-you-by' 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='convex'>
<section id='introduction'>
<h1>Introduction</h1>
</section>
<section id='survey'>
<h3>Intro Survey / Who are you?</h3>
<ol>
<li class='fragment'>do you have any experience using containers?</li>
<li class='fragment'>Ready? have you completed the laptop setup tasks?</li>
<li class='fragment'>do you have any experience using Kubernetes?</li>
<li class='fragment'>do you consider yourself to be 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'>do you have a plan for iterative web development using containers?</li>
</ol>
</section>
</section>
<section>
<section data-transition='convex' id='overview'>
<h2>Workshop Overview</h2>
<ol>
<li class='fragment'><a href="#/introduction">Introduction</a>
<ul>
<li><a href="#/laptop-setup">Laptop Setup</a></li>
</ul>
</li>
<li class='fragment'><a href="#/kubernetes-fundamentals">What is Kubernetes?</a></li>
<li class='fragment'><a href="#/kubernetes-for-OpsEng">Kubernetes for OpsEng</a></li>
<li class='fragment'><a href="#/kubernetes-for-DevOps">Kubernetes for DevOps</a></li>
</ol>
</section>
</section>
<section>
<section data-transition='concave' id='laptop-setup' data-markdown>
## Laptop Setup
bring a laptop with the following:
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-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='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>
</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 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>
<section id='kubernetes-fundamentals'>
<h1>Kubernetes Fundamentals</h1>
<p>↓</p>
</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 id='etcd-io'>
### Play with etcd
[play.etcd.io/play](http://play.etcd.io/play)
</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>
### 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>
## 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 "kube-apiserver"
sudo killall kube-apiserver
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
Review the difference between these two pod specs, before launching each:
```
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? were both 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
each compatible with the 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 data-markdown id='premise'>
### Premise
> Model your solutions using containers and Kubernetes, and your code will be portable to any cloud
</section>
</section>
<section>
<section id='kubernetes-for-OpsEng'>
<h1>Kubernetes for OpsEng</h1>
<p>↓</p>
</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 data-markdown>
</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 id='kubernetes-for-DevOps'>
<h1>Kubernetes for Developers</h1>
<p>↓</p>
</section>
<section data-markdown id='from-kubecon'>
> The following section is a repeat of a talk I gave at KubeCon in Austin...
"[Local Dev with K8s](http://bit.ly/kubecon-dev)": [youtu.be/_W6O_pfA00s](http://youtu.be/_W6O_pfA00s)
</section>
<section data-background='black' data-markdown id="the-community-is-terrible-at">
The Kubernetes Community is Terrible at Pitching Kubernetes to Developers
</section>
<section data-background='black' data-transition='zoom' id='why' data-markdown>
## Why?
</section>
<section data-markdown id='kubernetes-is-an-ops-tool'>
# Kubernetes
(an ops tool)
</section>
<section data-transition='fade-out' id='prescription'>
<img data-src="https://i.imgur.com/XlhSc6W.jpg"/>
</section>
<section data-transition='fade-in zoom-out' id='prescription-k8s'>
<img data-src="https://i.imgur.com/7BVLtPU.jpg"/>
</section>
<section data-transition='zoom-in convex-out' id='for-operations'>
<p>When used as directed, provides relief for the following:</p>
<ol>
<li class='fragment'>standardized terminology &amp; packaging - containers, volumes, podspecs, charts</li>
<li class='fragment'>load balancing - services</li>
<li class='fragment'>scaling automation - replica sets</li>
<li class='fragment'>delivery automation - deployments</li>
<li class='fragment'>high availability - automated health checking and replacement</li>
<li class='fragment'>distributed scheduling and resource management - RBAC, namespaces, labels, federation</li>
<li class='fragment'>???</li>
</ol>
</section>
<section data-transition='zoom' id='k8s-logo'>
<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>
</section>
<section data-background='black' data-markdown id='meanwhile'>
meanwhile...
</section>
<section id='what'>
<p>What is an App?</p>
<ol>
<li class='fragment'><span style='text-decoration:line-through;'>repo code</span></li>
<li class='fragment'><span style='text-decoration:line-through;'>docker image</span></li>
<li class='fragment'>kubernetes spec files</li>
<li class='fragment'>charts</li>
<li class='fragment'>kubectl get all -l app=myapp -n mynamespace</li>
</ol>
<p class='fragment'><a href="https://docs.google.com/document/d/1EVy0wRJRm5nogkHl38fNKbFrhERmSL_CLNE4cxcsc_M/edit">Proposal: Label Recommendations</a></p>
</section>
<section data-transition='zoom' id='how' data-markdown>
### How should we be talking to Developers about
# Kubernetes?
</section>
<section data-background='black' id='why-k8s'>
<blockquote>
Q: Why Kubernetes?
</blockquote>
<div class='fragment' style='clear:both;'>
<blockquote>
A: Development Velocity
</blockquote>
</div>
</section>
<section data-transition="convex" id='welcome-to-Austin'>
<img data-src="http://mediad.publicbroadcasting.net/p/kut/files/201609/4764611735_3a22b13c0b_b.jpg" />
</section>
<section data-transition="concave" id='a-case-study'>
<h3>A Case Study: Enterprise Records, Inc.</h3>
<img class='fragment fade-up' data-src="https://i.imgur.com/KpTVDt4.jpg" />
</section>
<section data-transition="convex" id='pitching-k8s'>
<img data-src="https://i.imgur.com/NEMK0xw.gif" />
<p>The Ops team has heard great things about Kubernetes, and is interested in giving it a try - but they're having difficulty convincing other teams of the value</p>
</section>
<section id='focus-on-delivery'>
<p>Product team needs:</p>
<h1 class='fragment zoom'>More</h1>
<img class='fragment fade-up' data-src="https://i.imgur.com/q9rPpDn.gif" />
<p class='fragment zoom'>(always more)</p>
</section>
<section data-transition="zoom" id='dont-let-k8s-get-in-the-way'>
<img data-src="https://i.imgur.com/Bvq78UI.gif" />
<p>The web team is confused by all the new terminology, and is under a lot of pressure to focus on delivering new tracks to customers</p>
</section>
<section id='define-a-path-to-productivity'>
<img data-src="https://i.imgur.com/jGm2JJ0.gif" />
</section>
<section id='convince-the-team'>
<p>Convincing the team (minimal onboarding):</p>
<ol>
<li class='fragment'><a href="#/the-easy-part">Getting started is easy</a></li>
<li class='fragment'><a href="#/sharing">Share what you know (and model your I/O)</a></li>
<li class='fragment'><a href="#/choose-the-right-tools">Choose the right toolchain</a></li>
</ol>
</section>
<section id='the-easy-part' data-markdown>
# 1. The Easy Part
is
minikube start
</section>
<section data-markdown id='no-excuses'>
* Staging down?
* Ops not Ready?
No Excuses!
</section>
<section data-transition="zoom" data-markdown id='kubernetes-all-the-things'>
# !!Everyone get a K8s!!
</section>
<section data-transition='zoom' id='k8s-delivery'>
<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>
</section>
<section id='minikube-for-all'>
<h2>Minikube</h2>
<p><a href="https://github.com/kubernetes/minikube"><img style="width:30%;" src="https://raw.githubusercontent.com/kubernetes/minikube/master/logo/logo.png" /></a></p>
<ul>
<li><a href="https://github.com/kubernetes/minikube">Minikube Docs</a></li>
<li><a href="http://bit.ly/k8s-minikube">bit.ly/k8s-minikube</a></li>
</ul>
</section>
<section id='sharing' data-markdown>
# 2. Share What You Know
and model your I/O
</section>
<section id='dry-run' data-markdown>
### Share What You Know `--dry-run`
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 id='create'>
### Share What You Know `--dry-run`
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 data-markdown id='i-o'>
## Model Your I/O
</section>
<section data-markdown id='example'>
### Example Repo
Create a local clone of this `metrics-k8s` repo:
```bash
git clone http://github.com/ryanj/metrics-k8s
```
</section>
<section data-markdown id='minikube-mount'>
### Preview - local files
Next, share your local repo contents with minikube:
```bash
cd metrics-k8s
minikube mount $(pwd):/var/www/html
```
</section>
<section data-markdown id='hostpath'>
### Preview - hostPath
Then, 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 id='kubectl-create'>
### Share what you know
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 id='rollout-test'>
### Share what you know - Rollout Testing
Eval this
```bash
minikube docker-env
```
to send newly-built images to minikube's docker daemon:
```bash
docker build .
```
</section>
<section data-markdown id='the-hard-part'>
# 3. The Hard Part
Keeping it simple, and choosing the right tools for the job
</section>
<section>
<img data-src="https://i.imgur.com/ogR1pSy.gif" />
</section>
<section>
<h4>The future is already here — it's just not very evenly distributed. (W.Gibson)</h4>
</section>
<!--
<section data-markdown>
### Pizza As A Service
https://twitter.com/jeffbarr/status/888169783044194304
*how much of your pipeline should be independently reproducible by developers?*
</section>
-->
<section id='adoption-path'>
<p>Typical container adoption path:</p>
<ol>
<li class='fragment'>docker</li>
<li class='fragment'>volumes, PVs</li>
<li class='fragment'>minikube</li>
<li class='fragment'>k8s modeling and scalability via spec files, pods, and other abstractions</li>
<li class='fragment'>charts, openshift templates, or hand-rolled manifest / spec templating</li>
<li class='fragment'>monocular, kubeapps, ServiceCatalog</li>
<li class='fragment'>PaaS?</li>
</ol>
</section>
<section id='draft'>
<h2>Draft</h2>
<p class='fragment'>Make it easy to get started</p>
<p><a href="https://draft.sh">draft.sh</a></p>
</section>
<section id='charts'>
<h2>Charts</h2>
<p class='fragment'>Share what you know</p>
<p><a href="https://github.com/kubernetes/charts">github.com/kubernetes/charts</a></p>
</section>
<section id='helm-tiller'>
<h2>Helm & Tiller</h2>
<p class='fragment'>Share more</p>
<p><a href="https://github.com/kubernetes/helm">github.com/kubernetes/helm</a></p>
</section>
<section id='brigade'>
<h2>Brigade and Kashti</h2>
<p class='fragment'>Build more</p>
<p><a href="http://brigade.sh/">brigade.sh</a></p>
</section>
<section id='fabric8'>
<h2>Fabric8</h2>
<p class='fragment'>Build more</p>
<p><a href="https://fabric8.io">fabric8.io</a></p>
</section>
<section id='telepresence'>
<h2>Telepresence</h2>
<p class='fragment'>Access more</p>
<p><a href="http://telepresence.io">telepresence.io</a></p>
</section>
<section id='minishift-oc'>
<h2>minishift and oc</h2>
<p class='fragment'>Security Enhanced Kubernetes</p>
<p><a href="https://github.com/minishift/minishift">github.com/minishift/minishift</a></p>
<p><a href="https://github.com/openshift/origin">github.com/openshift/origin</a></p>
</section>
<!--
<section data-markdown>
Bugs are more expesive to fix when discovered later
![https://www.whitesourcesoftware.com/wp-content/uploads/2015/10/graph2.jpg](cost of development)
Making the entire pipeline reproducible allows integration bugs to be found during local dev, lowering overall development costs, increasing velocity
https://www.nist.gov/sites/default/files/documents/director/planning/report02-3.pdf#table5-1
</section>
-->
<section id='easy'>
<img data-src="https://i.imgur.com/uJ67uFz.gif" />
<p>Easy, right?</p>
</section>
</section>
<section>
<section data-markdown id='learn-more'>
## More Learning Opportunities
1. Kubernetes.io Tutorials https://kubernetes.io/docs/tutorials/
2. Katacoda https://katacoda.com/courses/kubernetes
4. RyanJ's K8s-workshops http://bit.ly/k8s-workshops
3. Interactive learning for OpenShift: http://learn.openshift.com
</section>
<section id='next-steps'>
<p>Include the whole team:</p>
<ul>
<li class='fragment'>Developers: Want to get ahead? Model your I/O, and Share What You Know!</li>
<li class='fragment'>Architects: Figure out who owns manifest creation, maintanence, and distribution</li>
<li class='fragment'>QA folks: look forward to saying: "can't repro - works fine on my Kubernetes"</li>
<li class='fragment'>Ops: provide cloud resources grants to teams, make sure prod has enough IaaS, ensure platform uptime, upgrades, logging, and metrics</li>
<li class='fragment'>Security &amp; Compliance: RBAC, config and secrets management; Secret rotation policies; Monitor for CVEs and apply security patches from upstream</li>
</ul>
</section>
<section id='sig-apps'>
<p><a href="https://www.youtube.com/watch?v=vyYHfumJ-AM&list=PL69nYSiGNLP2LMq7vznITnpd2Fk1YIZF3"><img style="width:60%;" src="https://i.imgur.com/vibeqs6.png"/></a></p>
<p>Join the community on Slack in #kubernetes-users, and in #SIG-Apps!</p>
<p>Share What You Know: Help us develop a range of solutions that expose and/or hide kubernetes in appropriate ways</p>
</section>
<section id='deliver-consistently'>
<img data-src="https://i.imgur.com/GPNWcjN.gif" alt="delivering consistently" />
<p>Learn to deliver consistently using containers</p>
</section>
<section id='choose-the-right-tools'>
<img src="https://i.imgur.com/qvzFSaU.gif" />
<p>Choose the right tools for the job</p>
</section>
<section id='get-back-to-shipping-product'>
<img data-src="https://i.imgur.com/VgVLCPG.gif" alt="whole band" />
<p>then get back to making gold records</p>
</section>
</section>
<section id='thank-you'>
<h1>Thank You!</h1>
<p><a href="https://twitter.com/ryanj">@RyanJ</a></p>
<p><a href="https://bit.ly/scale-k8s">bit.ly/scale-k8s</a></p>
</section>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment