Requisitos
- Nociones básicas de Kubernetes.
- Tener Kubernetes instalado.
- Haber creado un clúster.
Todos estos requisitos están explicados en un anterior artículo.
Helm es un gestor de paquetes de Kubernetes, una herramienta para ayudarnos a desplegar aplicaciones. Los beneficios principales son los siguientes:
- Manejo de la complejidad a través de los _Charts_.
- Actualizaciones sencillas
- Fácil portabilidad
- Sistema de manejo de los _rollbacks_
Conceptos importantes
Hay tres conceptos fundamentales en Helm:
- _Charts_: distintos archivos de configuración YAML y ciertas plantillas que definen para instanciar una aplicación de K8s.
- _config_: como su propio nombre indica, información de configuración que puede ser juntado con un _chart_ para crear una _release_.
- _Release_: una instancia de un _chart_ con una cierta _config_
Arquitectura
La arquitectura de Helm tiene fundamentalmente dos partes, la del lado del cliente y la del lado del servidor:
Cliente Helm
Es la línea de comandos desde donde ejecutamos las ordenes para que éstas sean ejecutadas por el servidor, como puede ser mandar _charts_ para que se instalen, pedir información o desinstalar una _release_.
Tiller
Es la parte del servidor, en este caso la que se ejecuta en un clúster de K8s y la que se comunica con la API de K8s. Se encarga de estar pendiente de las peticiones del cliente, instalar distintos _charts_ y demás acciones pedidas por el cliente.
Estructura de un _Chart_
package-name/
charts/
templates/
Chart.yaml
LICENSE
README.md
requirements.yaml
values.yaml
- charts/: directorio de Charts que son dependencias del Chart que estamos definiendo.
- templates/: directorio que contiene plantillas de las cuales, combinadas con los valores de values.yaml genera los archivos de manifiesto válidos para Kubernetes.
- Chart.yaml: archivo de configuración con información general sobre el paquete como el nombre o la versión.
- LICENSE (opcional): archivo de texto plano que contiene información sobre la licencia que se distribuye dicho paquete (p.e.: MIT, GNU GPL v3,…).
- README.md (opcional): archivo Markdown con información de interés (similar a README de un repositorio git).
- requirements.yaml (opcional): archivo de dependencias del Chart.
- values.yaml: valores de configuración por defecto para el uso por las plantillas (que están en templates/).
Instalación de Helm
Como se ha dicho anteriormente, se supone que se han instalado Docker y Kubernetes en la máquina a trabajar. En nuestro ejemplo vamos a trabajar sobre un sistema GNU/Linux, específicamente la versión 18.04 de Ubuntu. Se recomienda al menos 2Gb de RAM y 10Gb de disco duro.
Antes de comenzar hay que tener un clúster de Kubernetes para instalar Tiller. Podemos comprobar si está bien configurado ejecutando:
# kubectl cluster-info
La respuesta debería ser parecida a ésta:
Kubernetes master is running at https://URL_VPS:6443
KubeDNS is running at https://URL_VPS:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Si existe algún error, es que K8s no está bien configurado. Se recomiendan seguir los pasos de este artículo hasta el apartado “Común” (este inclusive).
Si no ha habido ningún error, debemos ver si el Context es el adecuado con los siguientes comandos:
# kubectl config get-contextsCURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
El asterisco en este caso nos indica que estamos conectados al clúster _kubernetes-admin@kubernetes_. Se puede cambiar entre clústers con:
# kubectl config use-context NOMBRE_CONTEXTO
Ahora ya podemos instalar Helm. Las instrucciones de instalación son prácticamente las mismas en otros sistemas ya que en el repositorio en GitHub de Helm se puede encontrar un script que facilita la instalación:
# cd /tmp
# curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > instalacionHelm.sh
Damos permisos de ejecución al script descargado y ejecutamos el script:
# chmod u+x instalacionHelm.sh
# ./instalacionHelm.sh
Si todo se ha ejecutado con normalidad y sin errores, deberíamos tener ya Helm instalado, mostrando una pantalla similar a la siguiente:
Downloading https://get.helm.sh/helm-v2.15.1-linux-amd64.tar.gz
Preparing to install helm and tiller into /usr/local/bin
helm installed into /usr/local/bin/helm
tiller installed into /usr/local/bin/tiller
Run 'helm init' to configure helm.
Ahora toca configurar Tiller. Para ello vamos a crear un _serviceaccount_ para que funcione correctamente:
# kubectl -n kube-system create serviceaccount tiller
Si se ha ejecutado sin errores, hay que añadirlo al _cluster-admin_:
# kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller
Después de instalarlo, podemos iniciarlo para que termine de configurarse (crear carpetas de configuración, añadir repositorio por defecto,…) con la siguiente orden:
# helm init --service-account tiller
Creating /root/.helm
Creating /root/.helm/repository
Creating /root/.helm/repository/cache
Creating /root/.helm/repository/local
Creating /root/.helm/plugins
Creating /root/.helm/starters
Creating /root/.helm/cache/archive
Creating /root/.helm/repository/repositories.yaml
Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com
Adding local repo with URL: http://127.0.0.1:8879/charts
$HELM_HOME has been configured at /root/.helm.
Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
To prevent this, run `helm init` with the --tiller-tls-verify flag.
For more information on securing your installation see:
https://docs.helm.sh/using_helm/#securing-your-helm-installation
Ejemplo: Instalación de nginx
Veamos como es el del despliegue de un servidor web básico (nginx) usando Helm. Esto nos ayudará a entender cómo funcionan los _Charts_ y los repositorios de éstos.
Por defecto, helm pone por defecto un repositorio creado por ellos. En primer lugar, vamos a actualizarlo:
# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Skip local chart repository
...Successfully got an update from the "stable" chart repository
Update Complete.
Para buscar un _Chart_ podemos usar la instrucción helm search, la cual si no le añadimos ningún parámetro nos devolverá una lista de todos los _charts_ del repositorio (el de por defecto). Como nosotros queremos instalar _nginx_, ejecutamos:
# helm search nginx
NAME CHART VERSION APP VERSION DESCRIPTION
stable/nginx-ingress 1.24.4 0.26.1 An nginx Ingress controller that uses ConfigMap to store ...
stable/nginx-ldapauth-proxy 0.1.3 1.13.5 nginx proxy with ldapauth
stable/nginx-lego 0.3.1 Chart for nginx-ingress-controller and kube-lego
stable/gcloud-endpoints 0.1.2 1 DEPRECATED Develop, deploy, protect and monitor your APIs...
Como se puede ver ninguno de los _charts_ disponibles es el de _nginx_. Esto se debe a que no existe en el repositorio por defecto y por eso no lo encuentra. Para solucionar este problema, vamos a buscarlo en otro repositorio, más concretamente el repo de Bitnami.
Primero hay que añadir el repositorio a nuestra lista local de repos:
# helm repo add bitnami https://charts.bitnami.com/bitnami
Podemos imprimir una lista de los paquetes disponibles en este repositorio fácilmente:
# helm search bitnami
Como queremos el paquete de _nginx_ en concreto:
# helm search bitnami/nginx
NAME CHART VERSION APP VERSION DESCRIPTION
bitnami/nginx 4.3.10 1.16.1 Chart for the nginx server
bitnami/nginx-ingress-controller 5.0.10 0.26.1 Chart for the nginx Ingress controller
Vemos que el primer paquete es el que nos interesa, dado que es el del servidor. Para instalarlo:
# helm install bitnami/nginx --name miservidor
Y ésta es la salida que debería dar:
NAME: miservidor
LAST DEPLOYED: Sat Oct 26 16:55:41 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
miservidor-nginx 0/1 1 0 1s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
miservidor-nginx-7f6b9459c7-gfpf8 0/1 Pending 0 0s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
miservidor-nginx LoadBalancer 10.107.125.197 80:31658/TCP 1s
NOTES:
Get the NGINX URL:
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
Watch the status with: 'kubectl get svc --namespace default -w miservidor-nginx'
export SERVICE_IP=$(kubectl get svc --namespace default miservidor-nginx --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")
echo "NGINX URL: http://$SERVICE_IP/"
Es posible que al ejecutar este comando diga que no existe un tiller listo para ejecutar la tarea. Si es así y ejecutando `kubectl get pods –namespace kube-system` existe un pod que empieza por _tiller-deploy-_ con estado Pendiente, se puede solucionar para que se ejecute del siguiente modo:
# kubectl taint nodes --all node-role.kubernetes.io/master-
Vemos que nos especifica los recursos que ha creado (los que, si hubiéramos visto el _chart_ de ngnix estaban declarados) de Kubernetes. Podemos comprobarlo directamente en `kubectl`:
# kubectl get podsNAME READY STATUS RESTARTS AGE
miservidor-nginx-7f6b9459c7-gfpf8 0/1 Pending 0 3m36s
# kubectl get servicesNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 92m
miservidor-nginx LoadBalancer 10.107.125.197 URL 80:31658/TCP 4m2s
Si accedemos a URL desde un navegador web, veremos la típica pantalla de inicio de nginx:
Otras órdenes útiles de Helm:
- Listar todos los _charts_ instalados:
# helm list
- Eliminar por completo un _chart_ y todos sus archivos:
# helm delete --purge miservidor
- Ayuda:
# helm help