Skip to content

Instantly share code, notes, and snippets.

@ryanj
Last active June 9, 2020 17:17
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/9922a49e713d219806f730bffc1e2159 to your computer and use it in GitHub Desktop.
Save ryanj/9922a49e713d219806f730bffc1e2159 to your computer and use it in GitHub Desktop.
Containers, Kubernetes, and OpenShift at NorthEast PHP 2018 in Boston http://bit.ly/nephp18
<section data-transition='concave'>
<section id="at-NorthEastPHP">
<!--
<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>
-->
<h3>Containers,</h3>
<h2>Kubernetes,</h2>
<p><i>and</i></p>
<h1>OpenShift</h1>
<p><a href="http://2018.northeastphp.org/schedule.html">NorthEastPHP 2018</a></p>
<p><a href="http://sched.co/Fh5e">Wednesday, Sept 19, 9:00am-4:00pm</a></p>
<br/>
<h3 class='fragment grow'><a style='font-family:monospace;' href="http://bit.ly/nephp18">bit.ly/nephp18</a></h3>
<p>WiFi: "WayPHPMeet" php092018</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'>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 Kubernetes primitives or resource types?</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'><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'><a href="#/kubernetes-basics">Kubernetes Basics</a></li>
<li class='fragment'><a href="#/hands-on-with-openshift">Hands-On with OpenShift</a>
<ul style='list-style: none;'>
<li><Build, Iterate, Standardize</li>
</ul>
</li>
<li class='fragment'><a href="#/wrap-up">Wrap Up / Q&amp;A</a></li>
</ul>
</section>
<section id='kubernetes' data-markdown>
# Kubernetes
* [is](https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/): an ops tool; a collection of APIs for managing container-based workloads
* [is not](https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/#what-kubernetes-is-not): a PaaS
</section>
<section id='all-the-most-popular-platforms' data-background='black' data-markdown>
## 2017 Octoverse Report
> 🏆 Most-discussed project(s) on GitHub in 2017!
http://octoverse.github.com
[Kubernetes Community - Top of the Open Source Charts in 2017](https://kubernetes.io/blog/2018/04/25/open-source-charts-2017/)
</section>
<section id='openshift' data-markdown>
# OpenShift
* includes, extends, is a distribution of: Kubernetes
* adds: mult-tenanant security, PaaS features, a Template broker
</section>
<section id='more-info' data-markdown>
### More Information
* OpenShift Sources and Releases: http://github.com/openshift/origin/
* OpenShift Docs: https://docs.openshift.com/
* Kubernetes Docs: http://kubernetes.io/docs/home/
</section>
</section>
<section>
<section id='kubernetes-basics'>
<h1>Kubernetes Basics</h1>
<p>↓</p>
</section>
<section id='an-api' data-markdown>
Kubernetes provides&hellip;
# An API
API object primitives include the following attributes:
```
kind
apiVersion
metadata
spec
status
```
*mostly true
</section>
<section data-transition="linear" id='terminology' data-markdown>
### Basic K8s Terminology
1. [node](#/node)
2. [pod](#/po)
3. [service](#/svc)
4. [deployment](#/deploy)
5. [replicaSet](#/rs)
Introduction lifted from: [bit.ly/k8s-kubectl](http://bit.ly/k8s-kubectl)
</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>
<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 id='death-by-yaml'>
<a href="https://twitter.com/milosgajdos/status/1001932689195372549">https://twitter.com/milosgajdos/status/1001932689195372549</a>
</section>
<section data-markdown id='from-kubecon'>
Developing Locally with Kubernetes isn't easy
"[Local Dev with K8s](http://bit.ly/kubecon-dev)": [youtu.be/_W6O_pfA00s](http://youtu.be/_W6O_pfA00s)
</section>
</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>Follow along at:</p>
<p><code><a href="http://starter-guides-lab-infra.apps.nephp.openshiftworkshop.com/">bit.ly/2NWL6LO</a></code></p>
</div>
</section>
</section>
<section>
<section id='build'>
<h1>Build</h1>
<p class='fragment'>Build and deploy container images</p>
</section>
<section id='source-to-image-demo'>
<h2>Source</h2>
<p>to</p>
<h1>Image</h1>
<p class='fragment'>Combines source repos and operationally-maintained builder images to produce application images</p>
<p class='fragment'>Available as a standalone project, for use with Jenkins or other external builder processes: <a href="https://github.com/openshift/source-to-image">github.com/openshift/source-to-image</a></p>
</section>
<section id='add-to-project'>
<h2>Web Workflow: Create</h2>
<p class='fragment'>For this example, we will deploy a fork of the <code>silex-base</code> repo by clicking on "Add to Project" in the web console. Then, select a nodejs base image, name your webservice, and enter it's github source url</p>
<p class='fragment'>Optionally, explore the "Advanced routing, build, and deployment options" before starting your build with the "Create" button</p>
<p class="fragment">Example repo source: <a href="http://github.com/ryanj/silex-base/">github.com/ryanj/silex-base</a></p>
</section>
<section id='get-pods'>
<h2>Container Status</h2>
<p class='fragment'>The web console uses a socket stream to report status changes as they occur throughout the cluster</p>
<div class='fragment'>
<p>After the build task has completed, find the <code>NAME</code> of the pod where your image has been deployed:</p>
<pre><code contenteditable>oc get pods</code></pre>
</div>
<div class='fragment'>
<p>As with the core APIs, the CLI output is consistently formatted, following established patterns:</p>
<pre><code contenteditable>kubectl get pods</code></pre>
</div>
</section>
</section>
<section data-transition="linear">
<section id="iterate">
<h1>Iterate</h1>
<p class='fragment'>Iterate on container-based solutions</p>
</section>
<section id='oc-rsync'>
<h3>Developing on Docker</h3>
<p class='fragment'>Make a minor edit to your local repo's <code>index.html</code> file,</p>
<div class='fragment'>
<p>then test your changes <i>before you commit</i> by synching content into your hosted container:</p>
<pre><code contenteditable>oc rsync --exclude='.git' . PODNAME:</code></pre>
</div>
<div class='fragment'>
<p>Make sure to use a valid <code>PODNAME</code> from:</p>
<pre><code contenteditable>oc get pods</code></pre>
</div>
</section>
<section id="terminal" data-markdown>
## Terminal Access
* Available in the Web Console
* And on the CLI, with:
oc exec -it PODNAME -- bash
</section>
<section id='webhooks'>
<h2>WebHook Build Automation</h2>
<p class='fragment'>Set up a commit WebHook to automate image production</p>
<p class='fragment'>If you're running OpenShift locally in a VM, try using <a href="http://www.ultrahook.com/">ultrahook</a> to proxy webhook events to your laptop</p>
</section>
<section id='git-push-to-build-and-ship'>
<h2>ReBuild on Push</h2>
<p class='fragment'>Or, use GitHub's web-based editor to make a minor change</p>
<div class='fragment'><p>If you don't have a working webhook to automate the build process, it can also be started manually:</p>
<pre><code contenteditable>oc start-build silex-base</code></pre>
</div>
</section>
<section id='keys-and-configs' data-markdown>
## Configuration
[Environment Variables](https://docs.openshift.org/latest/dev_guide/environment_variables.html) are one way to add configuration settings to your images:
oc env dc/silex-base KEY=VALUE
</section>
<section id='logging' data-markdown>
## Logs
Centralized logging and metrics
</section>
<section id="deployment-strategies">
<h2>Deployment Strategies</h2>
<p class="fragment">Get more control of your container rollout and update processes by selecting appropriate <a href="https://docs.openshift.org/latest/dev_guide/deployments.html#strategies">deployment strategies</a> for your fleet of managed containers</p>
</section>
</section>
<section>
<section id='standardize' data-markdown>
# Standardize
</section>
<section data-markdown>
### Extend the base images
https://docs.openshift.org/latest/using_images/s2i_images/php.html
https://github.com/sclorg/s2i-php-container
</section>
<section id='open-service-broker-api'>
<h2>Open Service Broker API</h2>
<!--<p>↓</p>-->
<p class='fragment'><a href="http://bit.ly/k8s-catalog">bit.ly/k8s-catalog</a></p>
</section>
<section id='service-catalog-on-openshift'>
<h2>Service Catalog &amp; Brokers</h2>
<p>Expose and provision services</p>
<p><img style='width:100%;' src='https://github.com/ryanj/redisconf-2018/raw/master/static/catalog-options.png' alt='pluggable-broker-options' /></p>
</section>
<section id='installers'>
<h2>Templates as Installers</h2>
<div class='fragment'>
<p>Install a template into the current project, making it easier to reuse:</p>
<pre><code contenteditable>oc create -f template.json</code></pre>
</div>
<div class='fragment'>
<p>Create an application from an installed template, from a file, or from a url:</p>
<pre><code contenteditable>oc new-app -f template.json</code></pre>
</div>
</section>
<section id='composable-app-example'>
<h2>Multi-Service App Example</h2>
<p>Nodejs and MongoDB multi-service application example:</p>
<pre><code contenteditable>oc create -f https://raw.githubusercontent.com/ryanj/restify-mongodb-parks/master/restify-mongodb-parks-template.json</code></pre>
<p><a href="https://github.com/ryanj/restify-mongodb-parks/blob/master/restify-mongodb-parks-template.json">github.com/ryanj/restify-mongodb-parks</a></p>
</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 data-markdown>
### Free O'Reilly Ebook
[Deploying to OpenShift](https://www.openshift.com/deploying-to-openshift/) *NEW!*
</section>
<section data-transition="linear" id='kubernetes-terminology' data-markdown>
## K8s Terminology
1. [node](https://kubernetes.io/docs/concepts/architecture/nodes/)
2. [pod](https://kubernetes.io/docs/concepts/workloads/pods/pod/)
3. [deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)
4. [service](https://kubernetes.io/docs/concepts/services-networking/service/)
5. [replicaSet (rs)](https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/)
6. [persistent volume (pv)](https://kubernetes.io/docs/concepts/storage/persistent-volumes/)
7. [persistent volume claim (pvc)](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims)
</section>
<section data-transition="linear" id='openshift-terminology' data-markdown>
## OpenShift Terminology
1. [buildConfig (bc)](https://docs.openshift.org/latest/rest_api/apis-build.openshift.io/v1.BuildConfig.html)
2. [imageStream (is)](https://docs.openshift.org/latest/rest_api/apis-image.openshift.io/v1.ImageStream.html)
3. [deploymentConfig (dc)](https://docs.openshift.org/latest/rest_api/apis-apps.openshift.io/v1.DeploymentConfig.html)
4. [route](https://docs.openshift.org/latest/rest_api/apis-route.openshift.io/v1.Route.html)
5. [template](https://docs.openshift.org/latest/rest_api/oapi/v1.Template.html)
</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/)
for a local laptop install see [minikube](http://bit.ly/k8s-minikube) and/or [minishift](http://bit.ly/k8s-minishift)
</section>
<section id='thank-you'>
<h1>Thank You!</h1>
<p><img style="width:33%;" alt="RyanJ" src="https://tek.phparch.com/wp-content/uploads/sites/7/2018/05/ryan-jarvinen-headshot-e1525184794614-531x424.jpg" /></p>
<p><a href="https://twitter.com/ryanj">@RyanJ</a></p>
<br/>
<h4 class="fragment grow"><a href="http://bit.ly/nephp18">bit.ly/nephp18</a></h4>
</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