Last active
December 24, 2024 00:43
-
-
Save ryanj/1bd1f8430c459def7bc398ab520b0f9a to your computer and use it in GitHub Desktop.
K8s basics with kubectl at #SCaLE16X http://bit.ly/scale-k8s
This file contains hidden or 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="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%"/></a></p> | |
</section> | |
<section id='brought-to-you-by' data-background='black' data-markdown> | |
brought to you by | |
[](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 | |
 | |
* 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: | |
 | |
</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 | |
 | |
</section> | |
<section data-markdown> | |
### Interaction Diagram | |
 | |
[(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… | |
# 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 & 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 | |
 | |
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 & 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