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
Iniciar un cluster usando minikube
Linea de comandos de Kubernetes: kubectl
.
Version de kubectl (Para verificar que esta instalado):
Ver información de cluster
Ver nodos del cluster
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
Generar un entrypoint al cluster (temporal para pruebas)
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
Para obtener información detallada de los Pods
Para acceder a los Pods, que funcionan en una red aislada y privada, se utiliza
el 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:
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:
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:
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:
Controlar los pods (Tiene que haber 4):
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:
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:
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):
Actualizar la image:
kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2
Ver información de los 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