Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ericavonb/a8ebc21687d2b01f78abb6c96f040a25 to your computer and use it in GitHub Desktop.
Save ericavonb/a8ebc21687d2b01f78abb6c96f040a25 to your computer and use it in GitHub Desktop.
Kubenetes Zone "Hands-On Intro to Kubernetes" Workshop, TX http://bit.ly/wwg-k8s
<section>
<section id="kubernetes-hands-on">
<h1>Intro to Kubernetes</h1>
<h2>Workshop</h2>
<br/>
<p>TECH(K)NOW DAY - London, UK - Tue 9 Oct 2018</p>
<p><a href="http://bit.ly/wwg-k8s">bit.ly/wwg-k8s</a></p>
</section>
<section data-state='blackout' data-background-color="#000000" id='presented-by'>
<p>Hi! I'm Erica von Buelow.</p>
<img alt="EvB" src="https://avatars0.githubusercontent.com/u/1477450?s=460&v=4" style="width:300px" />
<p><a href="https://twitter.com/evonbuelow/">@evonbuelow</a></p>
<p>Software Engineer, Red Hat</p>
<p>OpenShift, Auth N/Z</p>
</section>
<section id='coreos'>
<img alt="go-gopher-nyc" src="https://secure.meetupstatic.com/photos/event/4/1/0/e/600_440836654.jpeg" style="width:300px" />
<p>Thank you to TECH(K)NOW DAYs, the CNCF, and Red Hat for sponsoring.<p>
</section>
</section>
<section>
<section id='introduction'>
<h1>Introduction</h1>
</section>
<section id='overview'>
<h2>Workshop Overview</h2>
<ol>
<li class='fragment'><a href="#/introduction">Introduction</a>
<ul>
<li><a href="#/workshop-setup">Workshop Setup</a></li>
</ul>
</li>
<li class='fragment'><a href="#/kubernetes-basics">Kubernetes Basics</a>
<ul>
<li><a href="#/containers-overview">Overview of containers</a></li>
<li><a href="#/why-k8s">Why Kubernetes?</a></li>
<li><a href="#/terminology">Learn five K8s Primitives</a></li>
</ul>
</li>
<li class='fragment'><a href="#/kubernetes-arch">Kubernetes Architecture</a>
<ul>
<li><a href="#/firedrills">Architecture Experiments</a></li>
</ul>
</li>
<li class='fragment'><a href="#/wrap-up">Wrap-up</a></li>
</ol>
</section>
<section id='survey'>
<h3>Intro Survey / Who are you?</h3>
<ol>
<li class='fragment'>Doing anything with containers today?</li>
<li class='fragment'>Do you have any experience using Kubernetes?</li>
<li class='fragment'>Do you consider yourself to be proficient with the <code>kubectl</code> cli tool?</li>
<li class='fragment'>Can you name five basic primitives or resource types?</li>
<li class='fragment'>Can you name five pieces of k8s architecture?</li>
</ol>
<p><img alt="go gopher" src="https://i.stack.imgur.com/c3uSy.png" style="width:50%" /></p>
</section>
</section>
<section>
<section id='workshop-setup' data-markdown>
## Workshop Setup
Bring a laptop with the following:
1. [kubectl](#/kubectl)
2. [minikube](#/minikube)
3. [docker](#/docker)
4. [Optional tooling for advanced users](#/go)
Or, [use GKE for a managed Kuberentes environment](http://cloud.google.com):
[http://cloud.google.com](http://cloud.google.com)
</section>
<section id='kubectl'>
<h3>install kubectl</h3>
<p>linux amd64:</p>
<pre><code contenteditable>curl -LO https://storage.googleapis.com/kubernetes-release/release/\
$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl \
&& chmod +x kubectl \
&& sudo mv kubectl /usr/local/bin/
</code></pre>
<p>osx amd64:</p>
<pre><code contenteditable>curl -LO https://storage.googleapis.com/kubernetes-release/release/\
$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl \
&& chmod +x kubectl \
&& sudo mv kubectl /usr/local/bin/
</code></pre>
<p>To verify <code>kubectl</code> availability:</p>
<pre><code contenteditable>kubectl version</code></pre>
<p><a href="https://kubernetes.io/docs/tasks/kubectl/install/">official <code>kubectl</code> setup notes</a></p>
</section>
<section id='minikube'>
<h3>install minikube</h3>
<p>linux/amd64:</p>
<pre><code contenteditable>curl -Lo minikube \
https://storage.googleapis.com/minikube/releases/v0.30.0/minikube-linux-amd64 \
&& chmod +x minikube \
&& sudo mv minikube /usr/local/bin/</code></pre>
<p>osx:</p>
<pre><code contenteditable>curl -Lo minikube \
https://storage.googleapis.com/minikube/releases/v0.30.0/minikube-darwin-amd64 \
&& chmod +x minikube \
&& sudo mv minikube /usr/local/bin/</code></pre>
<p>to verify <code>minikube</code> availability:</p>
<pre><code contenteditable>minikube start</code></pre>
<p><a href="https://github.com/kubernetes/minikube/releases">official <code>minikube</code> setup notes</a></p>
</section>
<section id='minikube-virt'>
<h4>minikube troubleshooting</h4>
<p>If your minikube environment does not boot correctly:</p>
<ol>
<li>Minikube requires an OS virtualization back-end</li>
<li>Most OSes include some support for virtualization</li>
<li>You can use the <a href="https://github.com/kubernetes/minikube#quickstart"><code>--vm-driver</code></a> flag to select a specific virt provider</li>
</ol>
<pre><code contenteditable>minikube start --vm-driver=virtualbox</code></pre>
<p>Check the project <a href="https://github.com/kubernetes/minikube#requirements"><code>README</code></a> for more information about <a href="https://github.com/kubernetes/minikube#requirements">supported virtualization options</a></p>
</section>
<section id='minikube-crio'>
<h5><b>ADVANCED CHALLENGE OPTION</b></h5>
<h3>cri-o powered minikube (optional)</h3>
<p>To start <code>minikube</code> with <code>cri-o</code> enabled, try:</p>
<pre><code contenteditable>$ minikube start \
--network-plugin=cni \
--container-runtime=cri-o \
--bootstrapper=kubeadm</code></pre>
<p>to verify:</p>
<pre><code contenteditable>minikube ssh
$ docker ps # expect no containers here
$ podman ps # lists running containers</code></pre>
</section>
<section id='docker'>
<h3>install the docker cli</h3>
<p>Download and install binary from <a href="https://store.docker.com/search?offering=community&type=edition">"the docker store"</a></p>
<p>Or, use a package manager to install:</p>
<pre><code contenteditable>brew install docker</code></pre>
<p>To verify <code>docker</code> availability:</p>
<pre><code contenteditable>docker version</code></pre>
<p>To <a href="https://github.com/kubernetes/minikube#reusing-the-docker-daemon">reference minikube's docker daemon from your host</a>, run:</p>
<pre><code contenteditable>eval $(minikube docker-env)</code></pre>
</section>
<section id='ready' data-markdown>
# *Ready?*
</section>
</section>
<section>
<section id='kubernetes-basics' data-markdown>
# Kubernetes Basics
</section>
<section id="containers-overview">
<h3> Overview of Containers </h3>
<img alt="BOXPARK Shoreditch" src="https://suitcasemag.com/wp-content/uploads/2015/05/boxpark-shoreditch.jpg" style="width:500px" />
<p>A container provides the ability to run an isolated process that has its own resources in a shared environment.<p>
</section>
<section id='why-k8s'>
<h3>Why Kubernetes?</h3>
<p><img src="https://pbs.twimg.com/profile_images/511909265720614913/21_d3cvM.png" alt="kubernetes" style='width:30%;'></p>
</section>
<section id='k8s-is'>
<h3>Kubernetes is...</h3>
<ol>
<li class='fragment'>The best way to manage distributed solutions at scale, based on years of industry expertise (Google-scale experience)</li>
<li class='fragment'>Agreement on a basis for open source container-driven distributed solution delivery, featuring a modular, HA architecture, and an extensible distributed solutions modeling language</li>
<li class='fragment'>An extensible modeling language with a huge community following</li>
</ol>
</section>
<section id='an-api' data-markdown>
## An API
API object primitives include the following attributes:
1. kind
2. apiVersion
3. metadata
4. spec
5. 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 (svc)
Establishes a single endpoint for a collection of replicated pods, distributing inbound traffic based on label selectors.
* Think about Services as a set of pods reachable from a common endpoint.
* It's up to the controller to make that happen.
* How it does that depends on the platform and can vary 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"* gives you something like a *"loadbalancer"* in front of your containers
* Pods and Services exist independently, have disjoint lifecycles
</section>
</section>
<section>
<section data-transition="linear" id='deploy' data-markdown>
### Deployment
A `deployment` helps you specify container runtime requirements (in terms of pods)
</section>
<section>
<p>Create a specification for your <code>deployment</code>:</p>
<pre><code contenteditable>kubectl run metrics-k8s --image=quay.io/ryanj/metrics-k8s \
--expose --port=2015 --service-overrides='{ "spec": { "type": "NodePort" } }' \
--dry-run -o yaml > deployment.yaml</code></pre>
<p>View the generated deployment spec file:</p>
<pre><code contenteditable>cat deployment.yaml</code></pre>
<p><i><b>Bug!:</b></i> Edit the file, adding "<code>---</code>" (on it's own line) between resource 1 and resource 2 for a workaround.</p>
<p>Can you think of another way to fix this issue? json compatible?</p>
</section>
<section>
<p>Create a new resource based on your yaml specification:</p>
<pre><code contenteditable>kubectl create -f deployment.yaml</code></pre>
<p>List resources by type:</p>
<pre><code contenteditable>kubectl get po,svc</code></pre>
<p>Connect to your new deployment via the associated service id:</p>
<pre><code contenteditable>minikube service metrics-k8s</code></pre>
</section>
<section id='replication'>
<h2>Replication</h2>
<p>Scale up the <code>metrics-k8s</code> deployment to 3 replicas:</p>
<pre><code contenteditable>kubectl scale deploy/metrics-k8s --replicas=3</code></pre>
<p>List pods:</p>
<pre><code contenteditable>kubectl get po</code></pre>
</section>
<section>
<p>Edit <code>deploy/metrics-k8s</code>, setting <code>spec.replicas</code> to <code>5</code>:</p>
<pre><code contenteditable>kubectl edit deploy/metrics-k8s -o json</code></pre>
<p>Save and quit. What happens?</p>
<pre><code contenteditable>kubectl get pods</code></pre>
</section>
<section id='autorecovery'>
<h2>AutoRecovery</h2>
<p>Watch for changes to <code>pod</code> resources:</p>
<pre><code contenteditable>kubectl get pods --watch</code></pre>
<p>In another terminal, delete several pods by id:</p>
<pre><code contenteditable>kubectl delete pod \
$(kubectl get pods | grep ^metrics-k8s | cut -f1 -s -d' ' | head -n 3 | tr '\n' ' ')</code></pre>
<p>What happend? How many pods remain?</p>
<pre><code contenteditable>kubectl get pods</code></pre>
</section>
<section data-markdown>
### Observations:
* Use the `--dry-run` flag to generate new resource specifications
* A deployment spec contains a pod spec
</section>
</section>
<section>
<section data-transition="linear" id='rs' data-markdown>
### ReplicaSet
A `replicaset` provides replication and lifecycle management for a specific image release
</section>
<section>
<p>Watch deployments (leave this running until the 'cleanup' section):</p>
<pre><code contenteditable>kubectl get deploy --watch</code></pre>
<p>View the current state of your deployment:</p>
<pre><code contenteditable>minikube service metrics-k8s</code></pre>
</section>
<section>
<h3>Rollouts</h3>
<p>Update your deployment's image spec to rollout a new release:</p>
<pre><code contenteditable>kubectl set image deploy/metrics-k8s metrics-k8s=quay.io/ryanj/metrics-k8s:v1</code></pre>
<p>Reload your browser to view the state of your deployment</p>
<pre><code contenteditable>kubectl get rs,deploy</code></pre>
</section>
<section>
<h3>Rollbacks</h3>
<p>View the list of previous rollouts:</p>
<pre><code contenteditable>kubectl rollout history deploy/metrics-k8s</code></pre>
<p>Rollback to the previous state:</p>
<pre><code contenteditable>kubectl rollout undo deployment metrics-k8s</code></pre>
<p>Reload your browser to view the state of your deployment</p>
</section>
<section>
<h3>Cleanup</h3>
<p>Cleanup old resources if you don't plan to use them:</p>
<pre><code contenteditable>kubectl delete service,deployment metrics-k8s</code></pre>
<p>Close any remaining <code>--watch</code> listeners</p>
</section>
<section data-markdown>
### Observations:
* The API allows for watch operations (in addition to get, set, list)
* ReplicaSets provide lifecycle management for pod resources
* Deployments create ReplicaSets to manage pod replication per rollout (per change in podspec: image:tag, environment vars)
</section>
</section>
<section>
<section id='kubernetes-arch' data-markdown>
# Kubernetes Architecture
</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>
### CAP theorem
1. Consistency
2. Availability
3. Partition tolerance
[etcd is "CA"](https://coreos.com/etcd/docs/latest/learning/api_guarantees.html)
</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>
### play.etcd.io
[play.etcd.io/play](http://play.etcd.io/play)
</section>
<section data-markdown>
## Kubernetes API
* gatekeeper for etcd (the only way to access the db)
* not required for pod uptime
</section>
<section data-markdown>
### API outage simulation
Example borrowed from [Brandon Philips' "Fire Drills" from OSCON 2016](https://github.com/philips/2016-OSCON-containers-at-scale-with-Kubernetes#fire-drills):
https://github.com/philips/2016-OSCON-containers-at-scale-with-Kubernetes#fire-drills
</section>
<section data-markdown>
Create a pod and a service (repeat our deployment drill). Verify that the service is responding.
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>
## Replace 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
* cri-o
* rkt
* oci
</section>
<section id='k8s-controllers' data-markdown>
### K8s Controllers
Controllers work to regulate the declarative nature of the platform state, reconciling 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='kubernetes-extensibility' data-markdown>
# Kubernetes Extensibility
</section>
<section id="what-is-an-SRE">
<h3>What is an SRE?</h3>
<p><a href="https://landing.google.com/sre/book.html"><img src="https://landing.google.com/sre/images/book-2x.png" alt="Site Reliability Engineering" style="width: 25%;"></a></p>
<p><i>"how Google runs production systems"</i></p>
<ol>
<li><a href="https://landing.google.com/sre/book.html">Google's SRE book - free to read online</a></li>
<li><a href="https://medium.com/@jerub/googles-approach-4bcdc0533c0a">SRE blog post series on Medium</a></li>
</ol>
</section>
<section id='what-are-operators'>
<h3>What are Operators?</h3>
<p class='fragment'>Kube Operators establish a pattern for introducing higher-order interfaces that represent the logical domain expertise (and perhaps the ideal product output) of a Kubernetes SRE</p>
<p class='fragment'><a href="https://coreos.com/blog/introducing-operators.html">blog post: "Introducing Operators"</a></p>
</section>
<section id='k8s-tpr' data-markdown>
### Custom Resource Definitions (CRDs)
CRDs allow you to establish new k8s primitives, extending the capabilities of the platform by allowing you to add your own terminology to the modeling language
https://kubernetes.io/docs/user-guide/customresources/
</section>
<section id='best-practices' data-markdown>
### Writing Operators
Get started with the [operator-sdk](https://github.com/operator-framework/operator-sdk). </section>
</section>
<section>
<section id='operator-examples' data-markdown>
## Operator Examples
</section>
<section id='etcd-operator' data-markdown>
### Etcd
blog post: https://coreos.com/blog/introducing-the-etcd-operator.html
sources: https://github.com/coreos/etcd-operator
demo video: https://www.youtube.com/watch?v=n4GYyo1V3wY
</section>
<section id='prometheus' data-markdown>
### Prometheus
blog post: https://coreos.com/blog/the-prometheus-operator.html
sources: https://github.com/coreos/prometheus-operator
demo video: https://www.youtube.com/watch?v=GYSKEd9FePk
</section>
<section id='kube-cert-manager' data-markdown>
### And so many more!
[operator-framework/awesome-operators](https://github.com/operator-framework/awesome-operators)
Learn more about operators and the Operator Framework: [https://coreos.com/operators/](https://coreos.com/operators/)
</section>
<!--
<section id='' data-markdown>
###
</section>
<section id='' data-markdown>
###
</section>
-->
</section>
</section>
<section>
<section id='wrap-up' data-markdown>
## Wrap Up
</section>
<section id='exit-interview'>
<h3>Exit Interview</h3>
<ol>
<li class='fragment'>Can you name five Kubernetes primitives?</li>
<li class='fragment'>Do you consider yourself to be proficient with kubernetes and the kubectl cli tool?</li>
<li class='fragment'>Did this workshop provide enough hands-on experience with Kubernetes?</li>
<li class='fragment'>Can you name five architectural components?</li>
</ol>
<section id='coreos-jobs' data-markdown>
### Red Hat is hiring!
[redhat.com/en/jobs](https://www.redhat.com/en/jobs)
</section>
</section>
<section>
<section id='thank-you'>
<h1>Thank You!</h1>
<p>for joining us for this</p>
<h1>Intro to Kubernetes Workshop</h1>
<p>NYC</p>
<br/>
<a href="http://bit.ly/k8s-zone"><h5 class='fragment grow'>bit.ly/wwg-k8s</h5></a>
</section>
</section>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment