Kubernetes 101
and Fun
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 1
About me
Mario-Leander Reimer
Chief Technologist, QAware GmbH
mario-leander.reimer@qaware.de
twitter://@LeanderReimer
http://github.com/lreimer
http://speakerdeck.com/lreimer
http://www.qaware.de
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 2
Code and article series are here ...
4 https://github.com/qaware/cloud-native-zwitscher/
4 http://www.qaware.de/fileadmin/userupload/QAware-Cloud-Native-
Artikelserie-JavaMagazin-1.pdf
4 http://www.qaware.de/fileadmin/userupload/QAware-Cloud-Native-
Artikelserie-JavaMagazin-2.pdf
4 http://www.qaware.de/fileadmin/userupload/QAware-Cloud-Native-
Artikelserie-JavaMagazin-3.pdf
4 http://www.qaware.de/fileadmin/userupload/QAware-Cloud-Native-
Artikelserie-JavaMagazin-4.pdf
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 3
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 4
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 5
Design principles for Cloud Native Applications
4 Design for Performance: responsive; concurrency; efficiency.
4 Design for Automation: automate dev tasks & ops tasks.
4 Design for Resiliency: fault-tolerant; self-healing.
4 Design for Elasticity: dynamically scale; be reactive.
4 Design for Delivery: short roundtrips; automated delivery.
4 Design for Diagnosability: cluster-wide logs, traces, metrics.
4 The Twelve-Factor App Principles (https://12factor.net)
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 6
Cloud Native Stack required!
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 7
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 8
Cloud Native Stack using Kubernetes.
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 9
Kubernetes 101
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 10
Local or Cloud setup of Kubernetes
echo "- Use Vagrant for local K8s setup"
export KUBERNETES_PROVIDER=vagrant
export NUM_NODES=1
echo "- The default provider is GCE"
export KUBERNETES_PROVIDER=gce
export KUBE_GCE_ZONE=europe-west1-d
export NUM_NODES=4
echo "- Another possible provider is AWS"
export KUBERNETES_PROVIDER=aws
export KUBE_AWS_ZONE=eu-central-1a
export NODE_SIZE=t2.small
curl -sS https://get.k8s.io | bash
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 11
Overview of Kubernetes Architecture
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 12
Main Kubernetes concepts
4 Services are an abstraction for a
logical set of Pods.
4 Pods are the smallest deployable units
of computing.
4 Deployments provide declarative
updates for Pods and RCs.
4 Replica Sets ensure specified number
of Pods are running.
4 Labels are key/value pairs attached to
objects used for identification.
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 13
Deployment definition as YAML
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: hello-world
spec:
replicas: 1
template:
metadata:
labels:
tier: web
spec:
containers:
- name: hello-world
image: "nginx"
ports:
- containerPort: 80
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 14
Service definition as YAML
apiVersion: v1
kind: Service
metadata:
name: hello-world
labels:
tier: web
spec:
# use NodePort here to be able to access the port on each node
# use LoadBalancer for external load-balanced IP if supported
type: NodePort
ports:
- port: 80
selector:
tier: web
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 15
Hello World with Kubernetes
$ kubectl cluster-info
$ kubectl get nodes
$ kubectl run hello-world --image=nginx --replicas=1 --port=80
$ kubectl expose deployment hello-world
$ kubectl get deployments,services,pods
$ kubectl describe pod [NAME]
$ kubectl delete deployment hello-world
$ kubectl create -f nginx.yml
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 16
Demo time.
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 17
The Cloud Native Zwitscher
Showcase
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 18
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 19
The source code.
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 20
Dockerize it!
4 Know your base image!!!
4 The Alpine image is too thin for
K8s + Spring.
4 You need Bash, DNS and Java.
4 Use a Server JRE.
4 Better build your own image.
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 21
Example Dockerfile for Zwitscher Service
FROM qaware-oss-docker-registry.bintray.io/base/alpine-k8s-ibmjava8:8.0-3.10
MAINTAINER QAware GmbH <qaware-oss@qaware.de>
RUN mkdir -p /opt/zwitscher-service
COPY build/libs/zwitscher-service-1.1.0.jar /opt/zwitscher-service/zwitscher-service.jar
COPY src/main/docker/zwitscher-service.* /opt/zwitscher-service/
RUN chmod 755 /opt/zwitscher-service/zwitscher-service.*
EXPOSE 8080
CMD /opt/zwitscher-service/zwitscher-service.sh
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 22
Build, test, tag and push Docker images.
...
$ docker built -t zwitscher-service:1.1.0 .
$ docker-compose up
...
$ docker tag zwitscher-service:1.1.0 
qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-service
...
$ docker push qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-service
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 23
Kubernetize: single or multi-container pods?
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 24
Possible variation using K8s infrastructure.
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 25
Define a deployment per container.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: zwitscher-service
spec:
replicas: 1
template:
metadata:
labels:
zwitscher: service
spec:
containers:
- name: zwitscher-service
image: "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-service:1.1.0"
ports:
- containerPort: 8080
env:
- name: EUREKA_HOST
value: zwitscher-eureka
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 26
Define a service per deployment.
apiVersion: v1
kind: Service
metadata:
name: zwitscher-service
labels:
zwitscher: service
spec:
# use NodePort here to be able to access the port on each node
# use LoadBalancer for external load-balanced IP if supported
type: NodePort
ports:
- port: 8080
selector:
zwitscher: service
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 27
Be careful using resource constraints.
resources:
# required resources for a Pod to be started
requests:
memory: "128Mi"
cpu: "250m"
# the Pod will be restarted if limits are exceeded
limits:
memory: "192Mi"
cpu: "500m"
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 28
Use liveness and readiness probes with Actuator.
livenessProbe:
httpGet:
path: /admin/health
port: 8080
initialDelaySeconds: 90
timeoutSeconds: 30
readinessProbe:
httpGet:
path: /admin/info
port: 8080
timeoutSeconds: 30
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 29
Use Retry mechanism for fail-fast behavior.
# bootstrap.yml
spring:
application:
name: zwitscher-service
cloud:
config:
enabled: true
failFast: true
retry:
initialInterval: 1500
maxInterval: 5000
maxAttempts: 5
multiplier: 1.5
discovery:
enabled: true
serviceId: ZWITSCHER-CONFIG
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 30
Deployment time!
$ kubectl create -f zwitscher-eureka/k8s-zwitscher-eureka.yml
$ kubectl create -f zwitscher-config/k8s-zwitscher-config.yml
$ kubectl create -f zwitscher-service/k8s-zwitscher-service.yml
$ kubectl create -f zwitscher-board/k8s-zwitscher-board.yml
$ kubectl create -f zwitscher-edge/k8s-zwitscher-edge.yml
$ kubectl create -f zwitscher-monitor/k8s-zwitscher-monitor.yml
$ kubectl get deployments,pods,services
$ kubectl delete -f k8s-zwitscher.yml
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 31
Let's have some fun!
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 32
The Kubepad in action
4 A MIDI controller
4 Display deployments and pods
4 Scale deployments
4 Written in fancy Kotlin
4 Also works for DC/OS
4 https://github.com/qaware/
kubepad
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 33
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 34
Q & A
| ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 35

Kubernetes 101 and Fun

  • 1.
    Kubernetes 101 and Fun |ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 1
  • 2.
    About me Mario-Leander Reimer ChiefTechnologist, QAware GmbH mario-leander.reimer@qaware.de twitter://@LeanderReimer http://github.com/lreimer http://speakerdeck.com/lreimer http://www.qaware.de | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 2
  • 3.
    Code and articleseries are here ... 4 https://github.com/qaware/cloud-native-zwitscher/ 4 http://www.qaware.de/fileadmin/userupload/QAware-Cloud-Native- Artikelserie-JavaMagazin-1.pdf 4 http://www.qaware.de/fileadmin/userupload/QAware-Cloud-Native- Artikelserie-JavaMagazin-2.pdf 4 http://www.qaware.de/fileadmin/userupload/QAware-Cloud-Native- Artikelserie-JavaMagazin-3.pdf 4 http://www.qaware.de/fileadmin/userupload/QAware-Cloud-Native- Artikelserie-JavaMagazin-4.pdf | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 3
  • 4.
    | ContainerCon Europe2016 | created with ☁ and ☕ by @LeanderReimer 4
  • 5.
    | ContainerCon Europe2016 | created with ☁ and ☕ by @LeanderReimer 5
  • 6.
    Design principles forCloud Native Applications 4 Design for Performance: responsive; concurrency; efficiency. 4 Design for Automation: automate dev tasks & ops tasks. 4 Design for Resiliency: fault-tolerant; self-healing. 4 Design for Elasticity: dynamically scale; be reactive. 4 Design for Delivery: short roundtrips; automated delivery. 4 Design for Diagnosability: cluster-wide logs, traces, metrics. 4 The Twelve-Factor App Principles (https://12factor.net) | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 6
  • 7.
    Cloud Native Stackrequired! | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 7
  • 8.
    | ContainerCon Europe2016 | created with ☁ and ☕ by @LeanderReimer 8
  • 9.
    Cloud Native Stackusing Kubernetes. | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 9
  • 10.
    Kubernetes 101 | ContainerConEurope 2016 | created with ☁ and ☕ by @LeanderReimer 10
  • 11.
    Local or Cloudsetup of Kubernetes echo "- Use Vagrant for local K8s setup" export KUBERNETES_PROVIDER=vagrant export NUM_NODES=1 echo "- The default provider is GCE" export KUBERNETES_PROVIDER=gce export KUBE_GCE_ZONE=europe-west1-d export NUM_NODES=4 echo "- Another possible provider is AWS" export KUBERNETES_PROVIDER=aws export KUBE_AWS_ZONE=eu-central-1a export NODE_SIZE=t2.small curl -sS https://get.k8s.io | bash | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 11
  • 12.
    Overview of KubernetesArchitecture | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 12
  • 13.
    Main Kubernetes concepts 4Services are an abstraction for a logical set of Pods. 4 Pods are the smallest deployable units of computing. 4 Deployments provide declarative updates for Pods and RCs. 4 Replica Sets ensure specified number of Pods are running. 4 Labels are key/value pairs attached to objects used for identification. | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 13
  • 14.
    Deployment definition asYAML apiVersion: extensions/v1beta1 kind: Deployment metadata: name: hello-world spec: replicas: 1 template: metadata: labels: tier: web spec: containers: - name: hello-world image: "nginx" ports: - containerPort: 80 | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 14
  • 15.
    Service definition asYAML apiVersion: v1 kind: Service metadata: name: hello-world labels: tier: web spec: # use NodePort here to be able to access the port on each node # use LoadBalancer for external load-balanced IP if supported type: NodePort ports: - port: 80 selector: tier: web | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 15
  • 16.
    Hello World withKubernetes $ kubectl cluster-info $ kubectl get nodes $ kubectl run hello-world --image=nginx --replicas=1 --port=80 $ kubectl expose deployment hello-world $ kubectl get deployments,services,pods $ kubectl describe pod [NAME] $ kubectl delete deployment hello-world $ kubectl create -f nginx.yml | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 16
  • 17.
    Demo time. | ContainerConEurope 2016 | created with ☁ and ☕ by @LeanderReimer 17
  • 18.
    The Cloud NativeZwitscher Showcase | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 18
  • 19.
    | ContainerCon Europe2016 | created with ☁ and ☕ by @LeanderReimer 19
  • 20.
    The source code. |ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 20
  • 21.
    Dockerize it! 4 Knowyour base image!!! 4 The Alpine image is too thin for K8s + Spring. 4 You need Bash, DNS and Java. 4 Use a Server JRE. 4 Better build your own image. | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 21
  • 22.
    Example Dockerfile forZwitscher Service FROM qaware-oss-docker-registry.bintray.io/base/alpine-k8s-ibmjava8:8.0-3.10 MAINTAINER QAware GmbH <qaware-oss@qaware.de> RUN mkdir -p /opt/zwitscher-service COPY build/libs/zwitscher-service-1.1.0.jar /opt/zwitscher-service/zwitscher-service.jar COPY src/main/docker/zwitscher-service.* /opt/zwitscher-service/ RUN chmod 755 /opt/zwitscher-service/zwitscher-service.* EXPOSE 8080 CMD /opt/zwitscher-service/zwitscher-service.sh | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 22
  • 23.
    Build, test, tagand push Docker images. ... $ docker built -t zwitscher-service:1.1.0 . $ docker-compose up ... $ docker tag zwitscher-service:1.1.0 qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-service ... $ docker push qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-service | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 23
  • 24.
    Kubernetize: single ormulti-container pods? | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 24
  • 25.
    Possible variation usingK8s infrastructure. | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 25
  • 26.
    Define a deploymentper container. apiVersion: extensions/v1beta1 kind: Deployment metadata: name: zwitscher-service spec: replicas: 1 template: metadata: labels: zwitscher: service spec: containers: - name: zwitscher-service image: "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-service:1.1.0" ports: - containerPort: 8080 env: - name: EUREKA_HOST value: zwitscher-eureka | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 26
  • 27.
    Define a serviceper deployment. apiVersion: v1 kind: Service metadata: name: zwitscher-service labels: zwitscher: service spec: # use NodePort here to be able to access the port on each node # use LoadBalancer for external load-balanced IP if supported type: NodePort ports: - port: 8080 selector: zwitscher: service | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 27
  • 28.
    Be careful usingresource constraints. resources: # required resources for a Pod to be started requests: memory: "128Mi" cpu: "250m" # the Pod will be restarted if limits are exceeded limits: memory: "192Mi" cpu: "500m" | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 28
  • 29.
    Use liveness andreadiness probes with Actuator. livenessProbe: httpGet: path: /admin/health port: 8080 initialDelaySeconds: 90 timeoutSeconds: 30 readinessProbe: httpGet: path: /admin/info port: 8080 timeoutSeconds: 30 | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 29
  • 30.
    Use Retry mechanismfor fail-fast behavior. # bootstrap.yml spring: application: name: zwitscher-service cloud: config: enabled: true failFast: true retry: initialInterval: 1500 maxInterval: 5000 maxAttempts: 5 multiplier: 1.5 discovery: enabled: true serviceId: ZWITSCHER-CONFIG | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 30
  • 31.
    Deployment time! $ kubectlcreate -f zwitscher-eureka/k8s-zwitscher-eureka.yml $ kubectl create -f zwitscher-config/k8s-zwitscher-config.yml $ kubectl create -f zwitscher-service/k8s-zwitscher-service.yml $ kubectl create -f zwitscher-board/k8s-zwitscher-board.yml $ kubectl create -f zwitscher-edge/k8s-zwitscher-edge.yml $ kubectl create -f zwitscher-monitor/k8s-zwitscher-monitor.yml $ kubectl get deployments,pods,services $ kubectl delete -f k8s-zwitscher.yml | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 31
  • 32.
    Let's have somefun! | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 32
  • 33.
    The Kubepad inaction 4 A MIDI controller 4 Display deployments and pods 4 Scale deployments 4 Written in fancy Kotlin 4 Also works for DC/OS 4 https://github.com/qaware/ kubepad | ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 33
  • 34.
    | ContainerCon Europe2016 | created with ☁ and ☕ by @LeanderReimer 34
  • 35.
    Q & A |ContainerCon Europe 2016 | created with ☁ and ☕ by @LeanderReimer 35