Forked from ryanj/openshift-workshop-at-openstack-summit.html
Last active
October 4, 2018 07:42
-
-
Save ahosam/4f8f261da093e8336cbace5ce60c1cf6 to your computer and use it in GitHub Desktop.
Container - Docker WorkShop http://bit.ly/workstack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<section data-transition='concave'> | |
<section id="Container Docker WorkShop"> | |
<!-- | |
<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> | |
--> | |
<p><i>Hands-on Training:</i></p> | |
<h1>OpenShift WorkShop</h1> | |
<p> | |
<span style="font-style: italic;position: relative;right: 20px;bottom: 85px;">at</span> <a href="https://www.openstack.org/summit/vancouver-2018/summit-schedule/events/21662/rsvp-required-containers-kubernetes-and-openshift-red-hat-openshift-on-openstack-hands-on-training"><img src="https://www.openstack.org/themes/openstack/static/images/summit-logo-small-white.svg" alt="OpenStack Summit" style='width:50%;'></a> | |
</p> | |
<p> | |
<h3 class='fragment grow'><a style='font-family:monospace;' href="http://bit.ly/workstack">bit.ly/workstack</a></h3> | |
<a href="https://www.openstack.org/summit/vancouver-2018/summit-schedule/events/21662/rsvp-required-containers-kubernetes-and-openshift-red-hat-openshift-on-openstack-hands-on-training">Sunday, May 20, 9:00am-4:00pm</a><br/> | |
<a href="https://www.openstack.org/summit/vancouver-2018/summit-schedule/events/21662/rsvp-required-containers-kubernetes-and-openshift-red-hat-openshift-on-openstack-hands-on-training">Vancouver Convention Centre West - Level Two - Room 213-214</a> | |
</p> | |
</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>presented by…</p> | |
<div class='fragment fade-right' style='width:45%; float:left;'> | |
<p><a href="http://twitter.com/ryanj/"><img alt="ryanj" src="http://ryanjarvinen.com/images/ryanj-mestrefungo-com.gif" style="width:70%" /></p> | |
<p><a href="http://twitter.com/ryanj/">Ryan Jarvinen @ryanj</a></p> | |
</div> | |
<div class='fragment fade-up' style='width:10%;float:left;margin-top: 13%;font-size: 250%;font-weight: bold;'>&</div> | |
<div class='fragment fade-left' style='width:45%; float:left;'> | |
<p><a href="http://twitter.com/joshixisjosh9"><img alt="Josh Wood" src="https://pbs.twimg.com/profile_images/488431660459753472/xCeVbtJV_400x400.jpeg" style="width:70%"/></p> | |
<p><a href="http://twitter.com/joshixisjosh9">Josh Wood @joshixisjosh9</a></p> | |
</div> | |
<br/> | |
<!-- | |
<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%"/><br/>@ryanj</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'>how many times have you attended OpenStack Summit?</li> | |
<li class='fragment'>do you have any experience using containers?</li> | |
<li class='fragment'>have you completed all of 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>oc</code> or <code>kubectl</code> cli tools?</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='agenda'> | |
<h2>Workshop Agenda</h2> | |
<ul style='list-style: none;'> | |
<li class='fragment'><span style="font-family:monospace;">9:00 </span><a href="#/introduction">Introduction</a> | |
<!-- <ul style='list-style: none;'> | |
<li> <a href="#/agenda">Agenda</a> ✔</li> | |
</ul> | |
--> | |
</li> | |
<li class='fragment'><span style="font-family:monospace;">9:30 </span><a href="#/kubernetes-concepts">Kubernetes Concepts and Theory</a></li> | |
<li class='fragment'><span style="font-family:monospace;">10:30 </span><a href="#/hands-on-with-openshift">Hands-On with OpenShift</a></li> | |
<li class='fragment'><span style="font-family:monospace;">12:30 </span>Lunch</li> | |
<li class='fragment'><span style="font-family:monospace;">1:00 </span><a href="#/openshift-on-openstack">OpenShift on OpenStack</a></li> | |
<li class='fragment'><span style="font-family:monospace;">2:00 </span><a href="#/open-service-broker-api">Open Service Broker API</a></li> | |
<li class='fragment'><span style="font-family:monospace;">3:00 </span><a href="#/extending-kubernetes">Extending Kubernetes</a></li> | |
<li class='fragment'><span style="font-family:monospace;">3:30 </span><a href="#/wrap-up">Wrap Up / Q&A</a></li> | |
</ul> | |
</section> | |
</section> | |
<section> | |
<section id='openshift-vs-openstack' data-markdown> | |
## OpenStack ❤ Kubernetes ❤ OpenShift | |
</section> | |
<section id='different-approaches'> | |
<p>Similar goals: </p> | |
<ul class='fragment'> | |
<li><em>Distributed Systems</em> management vs. <em>Distributed Solutions</em> management</li> | |
</ul> | |
<p class='fragment'>Different Approaches:</p> | |
<ul> | |
<li class='fragment'><p><strong>OpenStack:</strong> Expose cluster resources (infrastructure) via API endpoints</p> | |
</li> | |
<li class='fragment'><p><strong>Kubernetes:</strong> API endpoints are used to model operational requirements (declaratively). Cluster resources are obscured, presented in aggregate, and are managed indirectly via automation</p> | |
</li> | |
</ul> | |
</section> | |
<section id='openshift-plus-openstack'> | |
<h3>Choose the right tool for the task</h3> | |
<p class='fragment'>IaaS (OpenStack) → distributed hardware</p> | |
<p class='fragment'>CaaS (Kubernetes) → distributed OS kernel</p> | |
<p class='fragment'>PaaS (OpenShift) → distributed OS distro</p> | |
</section> | |
</section> | |
<section> | |
<section id='kubernetes-concepts'> | |
<h1>Kubernetes Concepts and Theory</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 simulations | |
Example borrowed from [Brandon Philips' "Fire Drills" from OSCON 2016](https://github.com/philips/2016-OSCON-containers-at-scale-with-Kubernetes#fire-drills): | |
https://github.com/philips/2016-OSCON-containers-at-scale-with-Kubernetes#fire-drills | |
</section> | |
<section data-markdown> | |
Create a pod and a service. Verify that the service is responding. | |
``` | |
kubectl run metrics-k8s --image=quay.io/ryanj/metrics-k8s \ | |
--expose --port=2015 --service-overrides='{ "spec": { "type": "NodePort" } }' | |
``` | |
``` | |
minikube service metrics-k8s | |
``` | |
ssh into minikube, kill the control plane: | |
``` | |
minikube ssh | |
ps aux | grep "localkube" | |
sudo killall localkube | |
logout | |
``` | |
Use kubectl to list pods: | |
``` | |
kubectl get pods | |
The connection to the server mycluster.example.com was refused - did you specify the right host or port? | |
``` | |
The API server is down! | |
Reload your service. Are your pods still available? | |
</section> | |
<section data-markdown> | |
## Kubelet | |
Runs on each node, listens to the API for new items with a matching `NodeName` | |
</section> | |
<section data-markdown> | |
## Kubernetes Scheduler | |
Assigns workloads to Node machines | |
</section> | |
<section data-markdown> | |
## Bypass the Scheduler | |
Create two pods: | |
``` | |
kubectl create -f https://raw.githubusercontent.com/ryanj/metrics-k8s/master/pod.json | |
kubectl create -f https://gist.githubusercontent.com/ryanj/893e0ac5b3887674f883858299cb8b93/raw/0cf16fd5b1c4d2bb1fed115165807ce41a3b7e20/pod-scheduled.json | |
``` | |
View events: | |
``` | |
kubectl get events | |
``` | |
Did both pods get scheduled? run? | |
</section> | |
<section data-markdown> | |
## Kube DNS | |
</section> | |
<section data-markdown> | |
## Kube Proxy | |
</section> | |
<section data-markdown> | |
## CNI | |
* flannel | |
* canal | |
</section> | |
<section data-markdown> | |
## CRI | |
* containerd (docker) | |
* cri-o | |
* rkt | |
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> | |
<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> | |
</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 data-transition="linear" id='rs' data-markdown> | |
### ReplicaSet | |
to learn about ReplicaSets through command-line examples, finish this scenario at: bit.ly/k8s-kubectl#/rs | |
</section> | |
<section data-transition='zoom'> | |
<section data-transition="convex" id='hands-on-with-openshift'> | |
<h1>Hands-On with OpenShift</h1> | |
<p>↓</p> | |
</section> | |
<section data-transition='zoom-in convex-out' id='ready'> | |
<h1><i>Ready?</i></h1> | |
</section> | |
<section data-background-transition="zoom"> | |
<h1>Let's Go!</h1> | |
<br/> | |
<div class='fragment fade-up'> | |
<p>Today's hands-on workshop is available at:</p> | |
<p><code><a href="http://content-workshop.apps.openstack.openshiftworkshop.com">http://content-workshop.apps.openstack.openshiftworkshop.com</a></code></p> | |
</div> | |
</section> | |
</section> | |
<section data-transition='zoom-in convex-out' data-background="black" id='lunch'> | |
<h1>Lunch</h1> | |
</section> | |
<section> | |
<section id='openshift-on-openstack'> | |
<h1>OpenShift on OpenStack</h1> | |
</section> | |
<section id='openshift-commons-on-openstack'> | |
<h4>OpenShift Commons Presentation:</h4> | |
<h3>OpenShift on OpenStack</h3> | |
<p>by <a href="https://www.openstack.org/summit/vancouver-2018/summit-schedule/speakers/14606">Ramon Rodriguez</a> of Red Hat</p> | |
<p><a href="https://www.youtube.com/watch?v=1DV0gk0V9iI">youtu.be/1DV0gk0V9iI</a></p> | |
</section> | |
<section id='openshift-on-openstack-at-summit'> | |
<h4>OpenStack Conference Session</h4> | |
<h2>OpenShift on OpenStack and Bare Metal</h2> | |
<p>by <a href="https://www.openstack.org/summit/vancouver-2018/summit-schedule/speakers/14606">Ramon Rodriguez</a> of Red Hat</p> | |
<p><a href="https://www.openstack.org/summit/vancouver-2018/summit-schedule/events/21818/openshift-on-openstack-and-bare-metal">www.openstack.org/summit/vancouver-2018/summit-schedule/events/21818/openshift-on-openstack-and-bare-metal</a></p> | |
</section> | |
</section> | |
<section> | |
<section id='open-service-broker-api'> | |
<h1>Open Service Broker API</h1> | |
<!--<p>↓</p>--> | |
<p class='fragment'><a href="http://bit.ly/k8s-catalog">bit.ly/k8s-catalog</a></p> | |
</section> | |
</section> | |
<section> | |
<section id='extending-kubernetes'> | |
<h1>Extending Kubernetes</h1> | |
<!--<p>↓</p>--> | |
<!--<p><a href="http://bit.ly/operatorpattern">bit.ly/operatorpattern</a></p>--> | |
</section> | |
<section id="extensibility" data-markdown> | |
### More Ways to Extend the Platform | |
* [Custom Resource Definitions](https://kubernetes.io/docs/concepts/api-extension/custom-resources/) | |
* [custom controllers](https://github.com/kubernetes/sample-controller) | |
* CRDs+Controllers ↦ [Operators](https://coreos.com/blog/introducing-operator-framework) | |
* https://github.com/spotahome/redis-operator | |
* https://github.com/jw-s/redis-operator | |
* https://coreos.com/blog/introducing-operator-framework | |
</section> | |
</section> | |
<section> | |
<section id='wrap-up'> | |
<h1>Wrap Up</h1> | |
</section> | |
<section data-background-color='black' data-markdown id='q-and-a'> | |
# Q&A | |
</section> | |
</section> | |
<section> | |
<section data-markdown> | |
## Resources | |
</section> | |
<section data-markdown> | |
### Kubernetes SIGs | |
[Kubernetes Special Interest Groups (SIGs)](https://github.com/kubernetes/community/blob/master/sig-list.md) | |
</section> | |
<section id='openshift-commons-on-openstack-1'> | |
<h4>OpenShift Commons Presentation:</h4> | |
<h3>OpenShift on OpenStack</h3> | |
<p>by <a href="https://www.openstack.org/summit/vancouver-2018/summit-schedule/speakers/14606">Ramon Rodriguez</a> of Red Hat</p> | |
<p><a href="https://www.youtube.com/watch?v=1DV0gk0V9iI">youtu.be/1DV0gk0V9iI</a></p> | |
</section> | |
<section id='openshift-on-openstack-at-summit-1'> | |
<h4>OpenStack Conference Session</h4> | |
<h2>OpenShift on OpenStack and Bare Metal</h2> | |
<p>by <a href="https://www.openstack.org/summit/vancouver-2018/summit-schedule/speakers/14606">Ramon Rodriguez</a> of Red Hat</p> | |
<p><a href="https://www.openstack.org/summit/vancouver-2018/summit-schedule/events/21818/openshift-on-openstack-and-bare-metal">www.openstack.org/summit/vancouver-2018/summit-schedule/events/21818/openshift-on-openstack-and-bare-metal</a></p> | |
</section> | |
</section> | |
<section id='try-openshift' data-markdown> | |
### More Ways to Try OpenShift | |
* [OpenShift Learning Portal](http://learn.openshift.com) | |
* [OpenShift Origin](https://github.com/openshift/origin) (and [minishift](https://github.com/minishift/minishift)) | |
* [OpenShift Online (Starter and Pro plans available)](https://www.openshift.com/products/online/) | |
* [OpenShift Dedicated (operated on AWS, GCE, and Azure)](https://www.openshift.com/products/dedicated/) | |
* [OpenShift Container (supported on RHEL, CoreOS)](https://www.openshift.com/products/container-platform/) | |
</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/workstack">bit.ly/workstack</a></p> | |
</section> | |
<!-- | |
<section> | |
<section id='kubernetes-for-OpsEng'> | |
<h1>Kubernetes for OpsEng</h1> | |
<p>↓</p> | |
</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 | |
![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 & 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> | |
--> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment