2018-01-26 00:18

Algunas notas sobre Kubernetes

Logo Kubernetes

Sistema para orquestación de cluster. Esto no es un tutorial, son notas sueltas (personales) tomadas del tutorial oficial.

1. Crear un cluster

Kubernetes coordina un cluster para trabajar como una unica unidad. Para ello, las apps necesitan ser empaquetadas en forma de containers.

2 Recursos:

  • Master: Coordinación y gestión el cluster
  • Nodes: Son los workers del cluster (puede ser vm o nodo físico)

Cada nodo tiene un Kubelet, un agente que coordina el nodo y maneja la comunicación con el Master.

Cada nodo debe poder realizar operaciones de containers, usando Docker o rkt (Debe tenerlo instalado).

Para debug se recomienda utilizar Minikube. Instala un cluster y facilita la configuracion de kubernetes (Instalarlo a mano era complejo).

Tutorial interactivo

Testear la version de minikube

minikube version

Iniciar un cluster usando minikube

minikube start

Linea de comandos de Kubernetes: kubectl.

Version de kubectl (Para verificar que esta instalado):

kubectl version

Ver información de cluster

kubectl cluster-info

Ver nodos del cluster

kubectl get nodes

2. Crear deploys con kubectl

Una vez instalado Kubernetes, se deben crear aplicaciones en containers para ser ejecutadas sobre el cluster. Para esto se definen instruccion que el master ejecuta sobre los nodos.

Kubernetes Deployment Controller monitoriza las instancias y si se caen, las regenera nuevamente.

Tutorial interactivo

Correr un ejemplo

kubectl run kubernetes-bootcamp \
    --image=docker.io/jocatalin/kubernetes-bootcamp:v1 \
    --port=8080

Ver la app en ejecucion

kubectl get deployments

Generar un entrypoint al cluster (temporal para pruebas)

kubectl proxy

3. Explorar la App

Un Pod es un conjunto de containers que ejecutan aplicaciones y sus recursos asociados.

Los Pods son creados por Kubernetes al realizar el deploy de la app. Se crean siempre en un nodo.

Operaciones mas usadas de kubectl:

kubectl get
kubectl describe
kubectl logs
kubectl exec

Tutorial interactivo

Listar pods

kubectl get pods

Para obtener información detallada de los Pods

kubectl describe pods

Para acceder a los Pods, que funcionan en una red aislada y privada, se utiliza el proxy:

kubectl proxy

Dicho proxy expone temporalmente la red y permite la comunicación con el host. Esto se utiliza para acceder a la API de los Pods y realizar consultas de forma directa (Por ejemplo, usando el comando curl).

Para diversas operaciones con los pods, es necesario obtener el nombre que Kubernetes le asigno al mismo. Un comando para hacer esto es:

export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')

Para ver los logs:

kubectl logs $POD_NAME

Todo lo que los proceso envien a stdout es expuesto como logs del pod.

Ejecutar comandos en un pod:

kubectl exec $POD_NAME env

Abrir una consola en un POD:

kubectl exec -ti $POD_NAME bash

4. Usar un servicio para exponer la App

Los Pods pueden ser reemplazados si es necesario. Desde que cada Pod tiene una IP unica, las aplicaciones no deberian conocer dichas IPs para poder conectarse a los Pods, porque estos puede "morir".

Los servicios en kubernetes proveen una abstraccion que permite establecer politicas de acceso sobre un conjunto lógico de Pods.

Los servicios permiten que a los pods se les adjunten labels, con diferentes objetivos (taggear versiones, separar versiones para test, debug y produccion).

Tutorial interactivo

Listar servicios expuestos:

kubectl get services

Exponer un servicio:

kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080

Ver detalles de servicios:

kubectl describe services/kubernetes-bootcamp

Ver que puerto fue abierto externamente:

export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
echo NODE_PORT=$NODE_PORT

Una vez expuesto, se puede consultar el servicio directamente con:

curl host01:$NODE_PORT

Consultar los pods que estan etiquetados con un label particular:

kubectl get pods -l run=kubernetes-bootcamp

El label en el caso anterior es run=kubernetes-bootcamp. Funciona identicamente para consultar servicios:

kubectl get services -l run=kubernetes-bootcamp

Obtener el nombre del POD

export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')
echo Name of the Pod: $POD_NAME

Aplicar un nuevo label a un Pod:

kubectl label pod $POD_NAME app=v1

Consultar el label recien aplicado:

kubectl describe pods $POD_NAME
kubectl get pods -l app=v1

Borrar un servicio:

kubectl delete service -l run=kubernetes-bootcamp

5. Multiples instancias de una App

Escalar es incrementar el numero de instancias o pods para poder manejar incrementos de trafico en la aplicación. Los services manejan el trafico hacia los pods mendiante un load-balancer.

Tutorial interactivo

Escalar (scale up) un deployment llamado kubernetes-bootcamp a 4 replicas:

kubectl scale deployments/kubernetes-bootcamp --replicas=4

Ver los deployments:

kubectl get deployments

Controlar los pods (Tiene que haber 4):

kubectl get pods -o wide

Ver el deployment de forma mas detallada:

kubectl describe deployments/kubernetes-bootcamp

Ver el servicio:

kubectl describe services/kubernetes-bootcamp

Recuperar el nodo:

export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
echo NODE_PORT=$NODE_PORT

Ejecutar varias veces:

curl host01:$NODE_PORT

Deberian responder diferentes pods de la misma app.

Ejecutar ahora solo 2 replicas (Scale down):

kubectl scale deployments/kubernetes-bootcamp --replicas=2

Confirmar el cambio:

kubectl get deployments

6. Realizando actualizaciones progresivas

La idea es lograr actualizaciones sin que se experimente una caida del servicio, esto permite poder actualizar las aplicaciones de forma mas seguida.

Kubernetes permite esto mediante las Rolling Updates. Esto permite actualizar sin tener downtimes y ademas puede ser revertido en caso de problemas (rollbacks).

Tutorial interactivo

Ver imagen actual de los pods (Campo image):

kubectl describe pods

Actualizar la image:

kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2

Ver información de los Pods:

kubectl get pods

No actualiza los viejos pods, sino que termina los anteirores y crea pods nuevos.

Verificar que la app actualizo:

kubectl describe services/kubernetes-bootcamp
export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
echo NODE_PORT=$NODE_PORT
curl host01:$NODE_PORT

Tambien puede verificarse el exito mediante:

kubectl rollout status deployments/kubernetes-bootcamp

Deployar una version "con errores":

kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v10

Ver problemas:

kubectl get deployments
kubectl get pods
kubectl describe pods

Rollback:

kubectl rollout undo deployments/kubernetes-bootcamp
kubectl get pods
kubectl describe pods

Dudas

  • ¿Un cluster kubernetes sirve para deploy de una app unica o muchas apps pueden convivir en el?

Se pueden hacer deploys de varias apps y se iran acomodando en los recursos que el cluster tenga disponibles.

  • ¿Un Pod es equivalente a un container?

Un pod es un container de una aplicación en particular gestionado por kubernetes

Troubleshooting

  • Al querer ejecutar minikube start se obtiene el error "Error starting host: Error getting state for host: machine does not exist".

El error completo es:

$ minikube start
Starting local Kubernetes v1.9.0 cluster...
Starting VM...
E0428 17:06:43.557255   18070 start.go:159] Error starting host: Error getting state for host: machine does not exist.

 Retrying.
E0428 17:06:43.557517   18070 start.go:165] Error starting host:  Error getting state for host: machine does not exist
================================================================================
An error has occurred. Would you like to opt in to sending anonymized crash
information to minikube to help prevent future errors?
To opt out of these messages, run the command:
        minikube config set WantReportErrorPrompt false
================================================================================
Please enter your response [Y/n]: n

Esto me pasó a mi por borrar en algun momento la vm de Virtualbox que crea minikube. La forma mas facil de recuperarse de este error es:

$ minikube delete
$ minikube start