Skip to content

Instantly share code, notes, and snippets.

@ryanj
Last active October 4, 2018 07:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ryanj/362b5653cd93828b1205ea1c5c8110da to your computer and use it in GitHub Desktop.
Save ryanj/362b5653cd93828b1205ea1c5c8110da to your computer and use it in GitHub Desktop.
OpenShift Workshop at #OpenStackSummit http://bit.ly/workstack
<section data-transition='concave'>
<section id="openshift-workshop-at-openstack-summit">
<!--
<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&hellip;</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;'>&amp;</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&nbsp;&nbsp;</span><a href="#/introduction">Introduction</a>
<!-- <ul style='list-style: none;'>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#/agenda">Agenda</a> &#10004;</li>
</ul>
-->
</li>
<li class='fragment'><span style="font-family:monospace;">9:30&nbsp;&nbsp;</span><a href="#/kubernetes-concepts">Kubernetes Concepts and Theory</a></li>
<li class='fragment'><span style="font-family:monospace;">10:30&nbsp;</span><a href="#/hands-on-with-openshift">Hands-On with OpenShift</a></li>
<li class='fragment'><span style="font-family:monospace;">12:30&nbsp;</span>Lunch</li>
<li class='fragment'><span style="font-family:monospace;">1:00&nbsp;&nbsp;</span><a href="#/openshift-on-openstack">OpenShift on OpenStack</a></li>
<li class='fragment'><span style="font-family:monospace;">2:00&nbsp;&nbsp;</span><a href="#/open-service-broker-api">Open Service Broker API</a></li>
<li class='fragment'><span style="font-family:monospace;">3:00&nbsp;&nbsp;</span><a href="#/extending-kubernetes">Extending Kubernetes</a></li>
<li class='fragment'><span style="font-family:monospace;">3:30&nbsp;&nbsp;</span><a href="#/wrap-up">Wrap Up / Q&amp;A</a></li>
</ul>
</section>
</section>
<section>
<section id='openshift-vs-openstack' data-markdown>
## OpenStack &#10084; Kubernetes &#10084; 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) &rarr; distributed hardware</p>
<p class='fragment'>CaaS (Kubernetes) &rarr; distributed OS kernel</p>
<p class='fragment'>PaaS (OpenShift) &rarr; 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&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>
</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 &map; [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&amp;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 &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>
-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment