Como lanzar un paquete (Chart) de Helm sin instalar Tiller

Uno de los detalles más interesantes que me he encontrado al usar K3s (https://k3s.io/) es la manera de desplegar Traefik, en el cual utiliza un esquema (chart) de Helm (nota: en Kubernetes el comando a ejecutar es sudo kubectl, pero en k3s kubectl está integrado para que use menos recursos)..

$ sudo k3s kubectl get pods -A
NAMESPACE        NAME                              READY   STATUS      RESTARTS   AGE
...
kube-system      helm-install-traefik-ksqsj        0/1     Completed   0          10m
kube-system      traefik-9cfbf55b6-5cds5           1/1     Running     0          9m28s
$ sudo k3s kubectl get jobs -A
NAMESPACE      NAME                        COMPLETIONS   DURATION   AGE
kube-system    helm-install-traefik        1/1           50s        12m

Nos encontramos que helm no está instalado, pero si vemos un job que ejecuta el cliente de helm para que podamos disponer de su potencia sin la necesidad de tener corriendo tiller (el servidor de helm) que por supuesto utiliza recursos y de esta manera nos los ahorramos, pero ¿Como funciona?

Klipper Helm

Lo primero que vemos es el uso de un job (tarea que habitualmente se ejecuta una única vez en forma de contenedor) basado en la imagen “rancher/klipper-helm” (https://github.com/rancher/klipper-helm) que ejecuta un entorno helm con solamente descargarlo y ejecutar un único script: https://raw.githubusercontent.com/rancher/klipper-helm/master/entry

Como requisito si va a requerir una cuenta de sistema con permisos de administrador en el espacio de kube-system, para traefik es:

$ sudo k3s kubectl get clusterrolebinding helm-kube-system-traefik -o yaml
...
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: helm-traefik
  namespace: kube-system

Lo que debemos tener en cuenta es la necesidad de crear la cuenta de servicio y al terminar la tarea de instalación con helm eliminarla ya que no será necesaria hasta otra operación de eliminación o actualización.
Como ejemplo vamos a crear una tarea para instalar un servicio weave-scope utilizando el chart helm (https://github.com/helm/charts/tree/master/stable/weave-scope)

Creación del servicio

Creamos un espacio de trabajo para aislar el nuevo servicio (namespace en kubernetes, proyecto en Openshift) que llamaremos helm-weave-scope:

$ sudo k3s kubectl create namespace helm-weave-scope
namespace/helm-weave-scope created

Creamos una nueva cuenta de sistema y le asignamos los permisos de administrado:

$ sudo k3s kubectl create serviceaccount helm-installer-weave-scope -n helm-weave-scope
serviceaccount/helm-installer-weave-scope created
$ sudo k3s kubectl create clusterrolebinding helm-installer-weave-scope --clusterrole=cluster-admin --serviceaccount=helm-weave-scope:helm-installer-weave-scope
clusterrolebinding.rbac.authorization.k8s.io/helm-installer-weave-scope created

Nuestro siguiente paso es crear la tarea, para ello la creamos en el fichero tarea.yml:

---
apiVersion: batch/v1
kind: Job
metadata:
  name: helm-install-weave-scope
  namespace: helm-weave-scope
spec:
  backoffLimit: 1000
  completions: 1
  parallelism: 1
  template:
    metadata:
      labels:
        jobname: helm-install-weave-scope
    spec:
      containers:
      - args:
        - install
        - --namespace
        - helm-weave-scope
        - --name
        - helm-weave-scope
        - --set-string
        - service.type=LoadBalancer
        - stable/weave-scope 
        env:
        - name: NAME
          value: helm-weave-scope
        image: rancher/klipper-helm:v0.1.5
        name: helm-weave-scope
      serviceAccount: helm-installer-weave-scope
      serviceAccountName: helm-installer-weave-scope
      restartPolicy: OnFailure

La ejecución

Y lo lanzamos con:

$ sudo k3s kubectl apply -f tarea.yml
job.batch/helm-install-weave-scope created

Lo que va a lanzar todos los procesos que el chart tenga:

# k3s kubectl get pods -A -w
NAMESPACE          NAME                                   READY   STATUS      RESTARTS   AGE
helm-weave-scope   helm-install-weave-scope-vhwk2         1/1     Running     0          9s
helm-weave-scope   weave-scope-agent-helm-weave-scope-lrfs2   0/1     Pending     0          0s
helm-weave-scope   weave-scope-agent-helm-weave-scope-drl8v   0/1     Pending     0          0s
helm-weave-scope   weave-scope-agent-helm-weave-scope-lrfs2   0/1     Pending     0          0s
helm-weave-scope   weave-scope-agent-helm-weave-scope-drl8v   0/1     Pending     0          0s
helm-weave-scope   weave-scope-frontend-helm-weave-scope-844c4b9f6f-d22mn   0/1     Pending     0          0s
helm-weave-scope   weave-scope-frontend-helm-weave-scope-844c4b9f6f-d22mn   0/1     Pending     0          0s
helm-weave-scope   weave-scope-agent-helm-weave-scope-lrfs2                 0/1     ContainerCreating   0          1s
helm-weave-scope   weave-scope-agent-helm-weave-scope-drl8v                 0/1     ContainerCreating   0          1s
helm-weave-scope   weave-scope-frontend-helm-weave-scope-844c4b9f6f-d22mn   0/1     ContainerCreating   0          1s
helm-weave-scope   helm-install-weave-scope-vhwk2                           0/1     Completed           0          10s
helm-weave-scope   weave-scope-agent-helm-weave-scope-lrfs2                 1/1     Running             0          13s
helm-weave-scope   weave-scope-agent-helm-weave-scope-drl8v                 1/1     Running             0          20s
helm-weave-scope   weave-scope-frontend-helm-weave-scope-844c4b9f6f-d22mn   1/1     Running             0          20s

El resultado

Podemos observar la correcta instalación de la aplicación sin la necesidad de instalar Helm ni tiller corriendo en el sistema:

# k3s kubectl get services -A -w
NAMESPACE          NAME                           TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                                     AGE
helm-weave-scope   helm-weave-scope-weave-scope   LoadBalancer   10.43.182.173   192.168.8.242   80:32567/TCP                                7m5s
Como lanzar un paquete (Chart) de Helm sin instalar Tiller 1

Actualización

Con la llegada de Helm v3 no se hace necesario Tiller y su uso es mucho más sencillo. Para explicar su funcionamiento, se explica como se hizo un Chart para PowerDNS en Helm v3 para desplegar PowerDNS sobre Kubernetes, esto también evita el uso de Klipper evitando jobs no requeridos.

Volver arriba