# kubernetes in practice ---- ## The tools * kubectl: kubernetes command line client * helm: A package manager for kubernetes applications ---- ### kubectl ```bash kubectl <verb> [<class>] [<object>] ``` ``` $ kubectl get nodes NAME STATUS ROLES AGE VERSION master1 Ready controlplane,etcd 7d16h v1.18.6 worker1 Ready worker 7d16h v1.18.6 worker2 Ready worker 7d16h v1.18.6 worker3 Ready worker 7d16h v1.18.6 ``` --- ## Deployment To define a deployment we create a yaml that basically contains: * The name of the deployment * How many replicas we would like to have * The list of container and their names (usually 1) * Which image(s) will be used for the pods * Which ports will be exposed in the pod There are other parameters we'll see next ---- deployment.yaml ![](https://i.imgur.com/eOiUeaX.png) ---- ### Basic commands ```bash # Apply or update the deployment kubectl apply -f deployment.yaml # Check the pods kubectl get pods # Check the events and configuration of a deployment kubectl describe deployment <deployment_name> # Check the container logs in a pod kubectl logs -f <pod_name> # Check the events of a pod kubectl describe pod <pod_name> ``` ---- In this example we deploy a nginx with 3 replicas [![asciicast](https://asciinema.org/a/VYTq5YoGUOYvbxMi9TkvvHcNT.svg)](https://asciinema.org/a/VYTq5YoGUOYvbxMi9TkvvHcNT) ---- The next example we create a port-forward against one of the pods to check that is serving on port 80 ```bash kubectl port-forward <pod> [<local-port>:]<pod-port> ``` [![asciicast](https://asciinema.org/a/1dewOxdg8av8tBBbQjjwRkBky.svg)](https://asciinema.org/a/1dewOxdg8av8tBBbQjjwRkBky) ---- In the next example, we delete a pod. kubernetes is going to recreate it. And also delete the deployment ```bash kubectl delete pod <pod-name> kubectl delete deployment <deployment-name> ``` [![asciicast](https://asciinema.org/a/yEn7nVBp9w8Z5r8k09RsEFUR8.svg)](https://asciinema.org/a/yEn7nVBp9w8Z5r8k09RsEFUR8) ---- Now, we force the update of the image. This will restart all the pods ```bash kubectl rollout restart deployment <deployment-name> ``` [![asciicast](https://asciinema.org/a/FkfHrgVpZB3rEeLlwR4negJrL.svg)](https://asciinema.org/a/FkfHrgVpZB3rEeLlwR4negJrL) ---- In this example, we could access to the pod console ```bash kubectl exec -ti <pod-name> -- <command> ``` [![asciicast](https://asciinema.org/a/Yyn9uuo3niVR5SeUFcr8qaqLA.svg)](https://asciinema.org/a/Yyn9uuo3niVR5SeUFcr8qaqLA) --- ## Services In general, a service creates a load balancer for all the pods of a deployment We need to define: * The selector to define what pods will be under the load balancer. e.g. ```app: nginx``` * The exposed port * The kind of service. Most common ```NodePort``` ---- Service.yaml ![](https://i.imgur.com/EtXtq3I.png) ---- Example: create a service for the nginx and access to it. Note: the ip is not public for the deployer, we need to access to a pod to achieve this ip. ```bash kubectl apply -f service.yaml ``` [![asciicast](https://asciinema.org/a/nrJKceTHsbEqPmWorEFkP7Tcl.svg)](https://asciinema.org/a/nrJKceTHsbEqPmWorEFkP7Tcl) --- ## Configmaps & Secrets Sometimes it is interesting to setup env variables for the containers of a deployment. e.g. to predefine passwords. - configmaps: to store configuration, values, ... all are stored in plain text - secrets: to store apikeys,... all stored in base64 codification ---- Example: setup the env variable DEBUG deployment.yaml with a static value harcoded in the deployment.yaml ```yaml #... containers: - name: nginx #... env: - name: DEBUG # Name of the env variable value: "yes" ``` ---- Example: two new variables are defined, one from a configmap and the other from a secret ```yaml #... env: - name: API_URL # Name of the env variable valueFrom: configMapKeyRef: name: my-configurations # Name of the configmap key: EXTERNAL_API_URL # Name of the variable - name: API_KEY valueFrom: secretKeyRef: name: my-secrets # Name of the secret storage key: API_KEY # Name of the variable ``` ---- To define a configmap use this schema ```yaml apiVersion: v1 kind: ConfigMap metadata: name: my-configurations data: EXTERNAL_API_URL: "127.0.0.1" ``` And apply with ``` bash kubectl apply -f configmap.yaml ``` ---- To define a secret use this schema ```yaml apiVersion: v1 kind: Secret metadata: name: my-secrets data: API_KEY: "MTIzNAo=" #1234 in base64 ``` And apply with ``` bash kubectl apply -f secret.yaml ``` ---- Let's see an example [![asciicast](https://asciinema.org/a/DbM4Ku4rr31o2fbmdEyYWbzmv.svg)](https://asciinema.org/a/DbM4Ku4rr31o2fbmdEyYWbzmv) ---- We can "create" a file or path in the container from a configmap. Must define a: - the volume declaration (from a configmap) - and how k8s will mount it on the container ```yaml spec: containers: - name: nginx #... volumeMounts: - name: web-html # name of the volume # destination path/file mountPath: /usr/share/nginx/html/index.html # name of the variable from the configmap subPath: index.html volumes: - name: web-html # name of the volume configMap: name: web-html # name of the configmap ``` ---- [![asciicast](https://asciinema.org/a/FVhOC5HDFG0TpyiK9AV1fHxnf.svg)](https://asciinema.org/a/FVhOC5HDFG0TpyiK9AV1fHxnf) --- ## Auto health checking of applications Kubernetes knows if a container has crashed because the entrypoint has sent a signal But sometimes the applications simply stop working without any crash To check the health of an app k8s uses liveness probe ---- Example of checking if the nginx is returing the main page ```yaml containers: - name: nginx #... livenessProbe: httpGet: path: / port: 80 ``` ---- [![asciicast](https://asciinema.org/a/ZXVjxmFRTVGfmSEYS6NrNwufh.svg)](https://asciinema.org/a/ZXVjxmFRTVGfmSEYS6NrNwufh) ---- You could specify: - initialDelaySeconds: initial delay to start checking - periodSeconds: check interval - failureThreshold: how many failures before restarting the pod ```yaml containers: - name: nginx #... livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 10 periodSeconds: 5 failureThreshold: 30 ``` ---- But also use other probes - startupProbe: check when the pod is initialized - readinessProbe: check when the pod is ready to serve data, k8s prevent to send request before passing the probe ```yaml containers: - name: nginx #... readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 10 ``` ---- An also the tests could be: - http request (httpGet) - command execution (exec) - access to a port (tcpSocket) ```yaml containers: - name: nginx #... livenessProbe: exec: command: - cat - /tmp/healthy ``` --- ## Persistence Kubernetes allows mounting volumes to be used in pods. These volumes could be storages of any type (EBS, cinder, ...) we only need a plugin To use persistence, we use statefulsets instead of the deployment Statefulsets provide ordering and uniqueness ---- - The pod mounts a volume that claims a persistent volume. - The persistent volume claim determines the size and the storage class - The storage class indicates to the cloud provider the type of storage ![](https://i.imgur.com/kRdm7TN.png) ---- Diferences with deployments - k8s maintain static names for each pod - If the pod is deleted the persistent volume remains - When a pod is deleted, k8s will wait to create a new one until the last one frees the persistent volume. - If the statefulset is deleted the persistent volume remains ---- Part 1. statefulset.yaml ```yaml apiVersion: apps/v1 kind: StatefulSet #A statefulset is specified metadata: name: mysql spec: serviceName: mysql # statefulsets needs this replicas: 1 selector: matchLabels: app: mysql template: metadata: labels: app: mysql #... ---- Part 2. statefulset.yaml ```yaml spec: containers: - name: mysql image: mysql:latest ports: - containerPort: 3306 volumeMounts: - name: mysql-vol # Specify the name of the volume mountPath: /var/lib/mysql # Specify where mount this volumes: - name: mysql-vol # Specify the name of the volume persistentVolumeClaim: claimName: mysql-pv # Specify the name of the claim ``` ---- Part 3. statefulset.yaml ```yaml templates: #... volumeClaimTemplates: - metadata: name: mysql-vol spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 10Gi ``` ---- [![asciicast](https://asciinema.org/a/QfTmF8BH0wHZzz4w8gnNJdofg.svg)](https://asciinema.org/a/QfTmF8BH0wHZzz4w8gnNJdofg) ---- Ivan Lausuch Suse
{"tags":"Presentations","slideOptions":{"theme":"solarized"}}
    711 views
   owned this note