Pro Yearly is on sale from $80 to $50! »

Getting started with Kubernetes

Getting started with Kubernetes

Kubernetes is a very powerful container orchestration platform that is quickly gaining traction and gives you lots of benefits in deploying, running and scaling your microservice web application. But it has also a steep learning curve. In this talk I will introduce you to Kubernetes, why you would want to use it and all the tooling around Kubernetes with the help of practical examples.

8e82eb7e128a14a16d642ae55227339b?s=128

Bastian Hofmann

February 16, 2018
Tweet

Transcript

  1. Introduction to Kubernetes @BastianHofmann

  2. None
  3. None
  4. None
  5. Container orchestration platform

  6. Run and scale your services in isolated containers

  7. Very Powerful

  8. Large community

  9. Lot’s of large company backers

  10. No vendor lock in

  11. Runs on

  12. AWS

  13. Azure

  14. Google Cloud Platform

  15. Bare metal

  16. Your laptop

  17. Minikube

  18. Included in Docker Desktop Clients

  19. Learning curve

  20. This talk is supposed to get you started

  21. I’m going to explain the basics

  22. I’ll start with deploying a simple PHP Web App

  23. look into some more ways to use Kubernetes

  24. and cover things like Logging, Monitoring, Security, …

  25. But first

  26. Why containers?

  27. Decouple Ops and Dev

  28. Make things …

  29. Easier to deploy

  30. Easier to upgrade system dependencies

  31. Easier to scale

  32. Easier to develop

  33. More performant than Virtual Machines

  34. OK, sold

  35. Let’s define some core concepts first

  36. Kubernetes Cluster

  37. Image • A docker image built from a Dockerfile that

    contains everything a service needs to run
  38. • A container runs a docker image. • Only 1

    process can run inside of a container Container
  39. Pod • A group of 1 or more containers •

    Same port space • Ports are not accessible from outside of the pod
  40. Replica Set • Defines and manages how many instances of

    a pod should run
  41. Deployment • Manages updates and rollbacks of replica sets

  42. Service • Makes a port of a pod accessible to

    other pods
  43. Ingress • Makes a service accessible to the outside of

    Kubernetes
  44. Node • A physical server • Containers get distributed automatically

  45. ConfigMaps & Secrets • Configuration that can be mounted inside

    of a container
  46. Volumes • Volumes can be mounted into a container to

    access a ConfigMap, Secret or a folder on the host
  47. Namespaces • Dedicated environment to deploy services in

  48. Example

  49. PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER PHP Application

    POD
  50. PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER PHP Application

    POD ReplicaSet: 2 instances PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER PHP Application POD
  51. PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER ReplicaSet: 2

    instances PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER CONFIG WEB :80 PHP Application POD PHP Application POD
  52. PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER ReplicaSet: 2

    instances PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER CONFIG WEB :80 https://php-app.k8s.foo.com:443/ PHP Application POD PHP Application POD
  53. To interact with Kubernetes

  54. Tooling

  55. kubectl

  56. $ kubectl get pods

  57. NAME READY STATUS RESTARTS AGE kubernetes-dashboard-5b5bf59977-t9xb9 1/1 Running 2 9d

    nginx-ingress-controller-5549f5597c-97kcw 0/1 Running 2 9d nginx-ingress-default-backend-564d9d9477-tmnnr 1/1 Running 4 9d mysql-556c9b5bcb-5jdrt 1/1 Running 1 8d symfony-demo-5b75f5fc6-c7wr9 1/1 Running 0 8d symfony-demo-5b75f5fc6-jg8n4 1/1 Running 23 8d
  58. REST API

  59. $ kubectl proxy --port=8080 $ curl http://localhost:8080/api/v1/namespaces/default/pods { "kind": "PodList",

    "apiVersion": "v1", "metadata": { "selfLink": "/api/v1/namespaces/default/pods", "resourceVersion": "336834" }, "items": [ { "metadata": { "name": "kubernetes-dashboard-5b5bf59977-t9xb9", "generateName": "kubernetes-dashboard-5b5bf59977-", …
  60. kubernetes- dashboard https://github.com/kubernetes/dashboard

  61. None
  62. Helm The package manager for Kubernetes https://helm.sh/

  63. $ helm install stable/wordpress

  64. Practical example

  65. Preparations

  66. Install Docker Client

  67. $ brew cask install docker

  68. None
  69. Install helm

  70. $ brew install kubernetes-helm

  71. $ helm init

  72. Install kubernetes-dashboard

  73. ingress: enabled: true hosts: - kubernetes-dashboard.local.k8s

  74. $ helm install stable/kubernetes-dashboard -f kubernetes-dashboard.yaml

  75. Install nginx-ingress-controller

  76. rbac: create: true controller: hostNetwork: true

  77. $ helm install stable/nginx-ingress -f ingress-controller.yaml

  78. Let’s deploy the symphony demo app

  79. https://github.com/symfony/demo

  80. First the Dockerfile

  81. PHP

  82. Copy our code

  83. Build the project

  84. Composer install

  85. yarn install

  86. https://docs.docker.com/develop/develop-images/ multistage-build/

  87. FROM kkarczmarczyk/node-yarn:latest WORKDIR /var/www/html COPY package.json /var/www/html/ COPY yarn.lock /var/www/html/

    RUN yarn install
  88. FROM php:7.2-apache WORKDIR /var/www/html # install packages RUN apt-get update

    -y && \ apt-get install -y --no-install-recommends \ curl git openssl \ less vim wget unzip rsync git mysql-client \ libcurl4-openssl-dev libfreetype6 libjpeg62-turbo libpng-dev libjpeg-dev libxml2-dev libxpm4 \ libicu-dev coreutils openssh-client libsqlite3-dev && \ apt-get clean && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/*
  89. # install php extensions RUN docker-php-ext-configure gd --with-jpeg-dir=/usr/ local/ &&

    \ docker-php-ext-install -j$(nproc) iconv intl pdo_sqlite curl json xml mbstring zip bcmath soap pdo_mysql gd # apache config RUN /usr/sbin/a2enmod rewrite && /usr/sbin/a2enmod headers && /usr/sbin/a2enmod expires COPY ./container/apache.conf /etc/apache2/sites- available/000-default.conf
  90. ENV COMPOSER_HOME /tmp ENV COMPOSER_VERSION 1.6.3 RUN curl -s -f

    -L -o /tmp/installer.php https:// raw.githubusercontent.com/composer/getcomposer.org/ b107d959a5924af895807021fcef4ffec5a76aa9/web/installer \ && php -r " \ \$signature = '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fd fdd586475ca9813a858088ffbc1f233e9b180f061'; \ \$hash = hash('SHA384', file_get_contents('/tmp/ installer.php')); \ if (!hash_equals(\$signature, \$hash)) { \ unlink('/tmp/installer.php'); \ echo 'Integrity check failed, installer is either corrupt or worse.' . PHP_EOL; \ exit(1); \ }" \ && php /tmp/installer.php --no-ansi --install-dir=/usr/ bin --filename=composer --version=${COMPOSER_VERSION} \ && composer --ansi --version --no-interaction \ && rm -rf /tmp/* /tmp/.htaccess
  91. COPY composer.* /var/www/html/ RUN composer install COPY --from=0 /var/www/html/node_modules/ /var/www/html/

    node_modules/ COPY . /var/www/html/ RUN chown -R www-data:www-data /var/www/html && composer dump-autoload
  92. Command it runs

  93. apache2 -DFOREGROUND

  94. Build the image

  95. docker build -t symfony-demo:2.0.0 .

  96. Since it’s all local we don’t need to push it

    to a registry
  97. Now we have to tell Kubernetes what to do with

    the image
  98. Resources are defined in YAML or JSON

  99. Deployment

  100. kind: Deployment apiVersion: extensions/v1beta1 metadata: name: symfony-demo spec: revisionHistoryLimit: 3

    template: metadata: labels: app: symfony-demo spec: containers: - name: symfony-demo image: symfony-demo:1.0.0 imagePullPolicy: Never ports: - containerPort: 80
  101. containers: - name: symfony-demo image: symfony-demo:latest imagePullPolicy: Never ports: -

    containerPort: 80 livenessProbe: httpGet: path: / port: 80 timeoutSeconds: 1 initialDelaySeconds: 10 readinessProbe: httpGet: path: / port: 80 timeoutSeconds: 1
  102. Many more options configurable

  103. •Setting environment variables •Mounting volumes •Requesting resources •Defining upgrade strategies

    •Defining command •Configure networking •Configure affinities •LifeCycle events •…
  104. Service

  105. kind: Service apiVersion: v1 metadata: name: symfony-demo spec: ports: -

    name: http port: 80 targetPort: 80 protocol: TCP selector: app: symfony-demo
  106. Ingress

  107. kind: Ingress apiVersion: extensions/v1beta1 metadata: name: symfony-demo spec: rules: -

    host: symfony-demo.local.k8s http: paths: - path: / backend: serviceName: symfony-demo servicePort: 80
  108. Creating everything

  109. kubectl apply -f deployment/webapp.yaml

  110. None
  111. Rolling Deployments

  112. kind: Deployment apiVersion: extensions/v1beta1 metadata: name: symfony-demo spec: revisionHistoryLimit: 3

    template: metadata: labels: app: symfony-demo spec: containers: - name: symfony-demo image: symfony-demo:1.1.0 imagePullPolicy: Never ports: - containerPort: 80
  113. kubectl apply -f deployment/webapp.yaml

  114. These are the basics

  115. Let’s talk about some other interesting and important aspects

  116. There are other types of deploying things into Kubernetes

  117. DaemonSets

  118. Ensure that a pod runs once on every node

  119. Log collection daemon

  120. Monitoring agent

  121. Service mesh containers

  122. Basically works like deployments

  123. But roll out strategy is different

  124. https://kubernetes.io/docs/tasks/manage-daemon/update- daemon-set/

  125. apiVersion: extensions/v1beta1 kind: DaemonSet metadata: name: kubernetes-ingress-nginx labels: k8s-app: kubernetes-ingress-nginx

    spec: updateStrategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 minReadySeconds: 5 template: …
  126. CronJobs

  127. Regularly repeating jobs

  128. apiVersion: batch/v1beta1 kind: CronJob metadata: name: cron-job spec: schedule: "*/1

    * * * *" jobTemplate: spec: template: spec: containers: - name: cron-job image: your-cron-job restartPolicy: OnFailure
  129. How does Kubernetes work internally

  130. Service Discovery

  131. Within a pod

  132. Shared port namespace

  133. Everything behaves like localhost

  134. Between pods

  135. You have to expose ports with services

  136. kind: Service apiVersion: v1 metadata: name: symfony-demo spec: ports: -

    name: http port: 80 targetPort: 80 protocol: TCP selector: app: symfony-demo
  137. Every service has a virtual IP address

  138. $ kubectl get service symfony-demo NAME TYPE CLUSTER-IP PORT(S) AGE

    symfony-demo ClusterIP 10.106.119.24 80/TCP 6d
  139. Discoverable in other containers by

  140. Environment Variables

  141. SYMFONY_DEMO_SERVICE_HOST=10.106.119.24 SYMFONY_DEMO_SERVICE_PORT=80

  142. DNS

  143. $ nslookup symfony-demo Server: 10.0.0.10 Address 1: 10.0.0.10 Name: symfony-demo

    Address 1: 10.106.119.24
  144. $ curl http://symfony-demo

  145. Alternatively

  146. Service Mesh

  147. LinkerD https://linkerd.io/

  148. Istio https://istio.io/

  149. Conduit https://conduit.io/

  150. Runs as

  151. DaemonSet

  152. Sidecar container

  153. PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER PHP Application

    POD
  154. PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER PHP Application

    POD NODEJS LINKERD STATSD Other service POD NODEJS LINKERD STATSD Other service POD
  155. PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER PHP Application

    POD NODEJS LINKERD STATSD Other service POD NODEJS LINKERD STATSD Other service POD
  156. PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER PHP Application

    POD NODEJS LINKERD STATSD Other service POD NODEJS LINKERD STATSD Other service POD
  157. Benefits

  158. Advanced routing

  159. Prefer service in current namespace, fall back to default namespace

  160. Advanced monitoring

  161. None
  162. Profiling

  163. Zipkin https://zipkin.io/

  164. None
  165. Accessing Kubernetes from the outside

  166. Port forwarding through kubectl

  167. $ kubectl port-forward $POD_NAME 8080:80

  168. The ingress controller

  169. Nginx

  170. haproxy

  171. Istio

  172. A controller listens to all ingresses and routes traffic from

    the outside to the correct service
  173. kind: Ingress apiVersion: extensions/v1beta1 metadata: name: symfony-demo spec: rules: -

    host: symfony-demo.local.k8s http: paths: - path: / backend: serviceName: symfony-demo servicePort: 80
  174. What about data?

  175. Storage

  176. Volumes

  177. https://kubernetes.io/docs/concepts/storage/volumes/

  178. apiVersion: v1 kind: Pod metadata: name: test-pd spec: containers: -

    image: k8s.gcr.io/test-webserver name: test-container volumeMounts: - mountPath: /cache name: cache-volume volumes: - name: cache-volume emptyDir: {}
  179. Persistent Storage

  180. You define a Persistent Volume, e.g. NFS

  181. Each pod can specify a Persistent Volume Claim

  182. And then mount the Claim into a Volume in a

    container
  183. https://kubernetes.io/docs/concepts/storage/persistent- volumes/

  184. Configuration

  185. Less data, so either than Persistent Volumes

  186. ConfigMap

  187. Key/Value Store

  188. kind: ConfigMap apiVersion: v1 metadata: name: special-config data: special-key: value

    bool-value: true
  189. Can be accessed in a pod through environment variables

  190. spec: containers: - name: test-container image: k8s.gcr.io/busybox command: [ "/bin/sh",

    "-c", "env" ] env: - name: SPECIAL_KEY valueFrom: configMapKeyRef: name: special-config key: special-key
  191. spec: containers: - name: test-container image: k8s.gcr.io/busybox command: [ "/bin/sh",

    "-c", "env" ] envFrom: - configMapRef: name: special-config
  192. Can be accessed through volumes

  193. spec: containers: - name: test-container image: k8s.gcr.io/busybox command: [ "/bin/sh",

    "-c", "ls /etc/config/" ] volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: special-config
  194. https://kubernetes.io/docs/tasks/configure-pod-container/ configure-pod-configmap/

  195. Secret

  196. Storage for sensitive information

  197. https://kubernetes.io/docs/concepts/configuration/secret

  198. How about complex init processes

  199. Init Containers

  200. Run a process in a container before the pod starts

  201. Use cases

  202. Database Migrations

  203. Multiple containers need the same sources

  204. PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER PHP Application

    POD
  205. PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER PHP Application

    POD INIT
  206. PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER PHP Application

    POD INIT The only image that contains the source code
  207. PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER PHP Application

    POD INIT emptyDir Volume Mounts
  208. PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER PHP Application

    POD INIT emptyDir Volume Copies source
  209. PHP-FPM NGINX LINKERD STATSD MEM CACHED MONGO ROUTER PHP Application

    POD INIT emptyDir Volume with source Mounts and uses
  210. Figuring out what’s going on inside Kubernetes

  211. Monitoring

  212. Heapster

  213. https://github.com/kubernetes/heapster

  214. Takes metrics from Kubernetes and stores them in a monitoring

    solution
  215. InfluxDB

  216. Prometheus

  217. Grafana for displaying the data

  218. None
  219. None
  220. https://blog.kublr.com/how-to-utilize-the-heapster-influxdb- grafana-stack-in-kubernetes-for-monitoring- pods-4a553f4d36c9

  221. Logging

  222. kubectl logs

  223. $ kubectl logs symfony-demo-5b75f5fc6-c7wr9

  224. Log to stdout & stderr

  225. Automatically written to disk

  226. DaemonSet Log collector

  227. • Logstash • Fluentd • Filebeat

  228. Central log management

  229. None
  230. https://www.elastic.co/blog/shipping-kubernetes-logs-to- elasticsearch-with-filebeat

  231. Scaling

  232. Manual Scaling

  233. kubectl scale --replicas=3 deployment/my-app

  234. AutoScaling

  235. None
  236. https://kubernetes.io/docs/user-guide/horizontal-pod- autoscaling/

  237. Keeping services secure

  238. Docker Container Security

  239. https://kubernetes.io/docs/tasks/configure-pod-container/ security-context/

  240. Role Based Access Control

  241. Users

  242. ServiceAccounts

  243. https://kubernetes.io/docs/admin/authorization/rbac/

  244. Summary

  245. Powerful

  246. Helpful

  247. Fast paced development

  248. https://gravitational.com/blog/kubernetes-release-cycle/

  249. Keep up to date

  250. Documentation

  251. https://kubernetes.io/docs/

  252. KubeCons

  253. https://www.youtube.com/channel/UCvqbFHwN- nwalWPjPUKpvTA

  254. http://speakerdeck.com/u/bastianhofmann

  255. http://twitter.com/BastianHofmann http://lanyrd.com/people/BastianHofmann http://speakerdeck.com/u/bastianhofmann mail@bastianhofmann.de