Instalación de Kubernetes en Ubuntu con Ansible

2
11724

En este tutorial comprobaremos como instalar Kubernetes de forma sencilla con Ansible.

Índice de contenidos

1. Introducción

Una de las cosas más importantes a la hora de tener una aplicación en producción es que esta esté disponible siempre para los usuarios. Kubernetes nos ofrece una buena infraestructura para aumentar la disponibilidad de nuestra aplicación.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro Retina 15′ (2.5 Ghz Intel Core I7, 16GB DDR3).
  • Sistema Operativo: Mac OS El Capitán 10.11.2
  • Virtual Box
  • Vagrant 1.8.1
  • Ansible 1.9.3

3. Preparación y configuración del entorno

En tutoriales anteriores ya se ha explicado como instalar Vagrant y Ansible (ver aquí), así que partimos de que ambas herramientas ya están instaladas.

Recordamos que Vagrant es una herramienta que nos permite gestionar máquinas virtuales (usando en nuestro caso VirtualBox por debajo) y que Ansible nos permite automatizar tareas en host remotos via ssh. Vagrant y ansible están muy bien integrados, de forma que utilizaremos Vagrant para crear el entorno con un sistema operativo Ubuntu en el cual instalaremos y jugaremos con Kubernetes. Para ello nos creamos un directorio dónde se encontrará nuestro Vagrantfile, fichero de configuración de Vagrant. Para que se genere el fichero por defecto ejecutamos el comando vagrant init.

Consola comando vagrant init

Nuestro fichero Vagrantfile debe quedar de la siguiente manera:

Vagrantfile

Analicemos que realizará este fichero de configuración:

  • config.vm.box = «ubuntu/trusty64» : en este apartado indicamos la box que va a utilizar vagrant para crear la máquina virtual.
  • config.vm.network «forwarded_port», guest: 8080, host: 8080 : aquí redireccionamos el puerto de la máquina anfitrión a la máquina virtual de forma que cuando se llame al puerto 8080 de la máquina real esto será redireccionado al puerto 8080 de la máquina virtual. Esto nos sirve para ver la interfaz gráfica de Kubernetes.
  • config.vm.network «private_network», ip: «192.168.90.20» : en este apartado indicamos la ip que tendrá la máquina virtual.
  • v.memory = 4096 : en este apartado la memoria que va a tenr la máquina virtual.
  • Por último definimos el provisionamiento que Vagrant va a realizar en la máquina una vez esté levantada. Para ello uso el ya mencionado Ansible, pero notad que no le especifico en ningún lugar el inventory. Esto está hecho a propósito ya que Vagrant te lo genera automáticamente si no lo creas tú.

Ahora tenemos que crear el directorio Ansible dónde vamos a tener la siguiente estructura:

  • infraestructure.yml: es el playbook principal que se encarga de instalar kubernetes.
  • roles/docker/tasks/docker_install.yml : aquí se encuentran las tareas propias de la instalación docker.
  • roles/docker/tasks/docker_prerequisites.yml : aquí están las tareas que necesitan ser ejecutadas para que se instale docker.
  • roles/docker/tasks/docker_setup.yml : aquí están tareas propias de la configuración.
  • roles/docker/tasks/main.yml : aquí se encuentran las tareas que se van a ejecutar en el rol de docker.
  • roles/kubernetes/files/config-default.sh : es el fichero de configuración dónde se especifican las propiedades del cluster.
  • roles/kubernetes/meta/main.yml : en este fichero se encuentran las dependencias del rol kubernetes.
  • roles/kubernetes/tasks/main.yml : aquí definimos las tareas que se van a ejecutar en el rol kubernetes.
  • roles/kubernetes/vars/main.yml : por ultimo definimos las variables propias del rol aquí.

3.1 Kubernetes

A continuación veremos el contenido del rol Kubernetes.

roles/kubernetes/files/config-default.sh

El fichero config-default se crea por defecto cuando descargas la versión de Kubernetes (se encuentra dentro del directorio kubernetes/cluster/ubuntu). Este fichero se encarga de establecer la configuración por defecto del cluster, como el número de nodos, sus respectivas ip y el número de minions y de maestros del cluster. Las propiedades que hemos modificado del fichero son:

  • export nodes=${nodes:-«root@127.0.0.1»}: Con esta propiedad le indicamos los nodos que va a tener nuestro cluster. Como este es un ejemplo muy sencillo, tenemos un cluster de un único nodo, pero si tuviéramos más deberían de ir las ip aquí separadas por espacios.
  • role={roles:-«ai»}: Aquí se separan los nodos por espacio y van en el mismo orden en el que hemos definido las ips en la propiedad anterior. a significa master, mientras que i significa minion de forma que estamos indicando que nuestro único nodo es master y minion a la vez.
  • export NUM_NODES=${NUM_NODES:-1}: con esta propiedad indicamos que el número de minions que tiene nuestro cluster es 1.

En el siguiente fichero están descritas las tareas que se van a realizar en el playbook Kubernetes:

roles/kubernetes/tasks/main.yml

Los pasos que sigue este playbook son:

  • Las dos primeras tareas son necesarias para arrancar el servicio de Kubernetes. Este servicio necesita de acceso por ssh, y como lo estamos automatizando con Ansible, no queremos que se detenga la ejecución. Para ello creamos una par clave pública/privada que identifica a la máquina, y añadimos la clave pública al fichero authorized_keys.
  • Nos descargamos la última release de Kubernetes y la descomprimimos en la variable {{kubernetes.path}}, que se encuentra en el fichero roles/kubernetes/defaults/main.yml.
  • Una vez hecho eso, para el arranque del cluster necesitamos un certificado para que el master del cluster pueda actuar como un servidor https. Para ello generamos un certificado general y lo usamos para firmar los certifcicados de la máquina con el script make-ca-cert.sh que se encuentra en el directorio saltabse, que está comprimido por defecto. Lo descomprimimos y lo movemos al directorio correspondiente.
  • Ya estaríamos listos para levantar el cluster, pero necesitamos la configuración que tenemos en el fichero config-default.sh dónde indicamos que solo se nos cree un nodo en la máquina virtual que sea master y minion a la vez.
  • Dejando lo mejor para el final, ejecutamos el comando para levantar el cluster. Comprobamos como antes del comando tenemos que indicarle previamente el provider a utilizar, ubuntu en nuestro caso. En esta tarea usamos la gestión de errores que nos ofrece Ansible. Esta característica está explicada en este tutorial.

Ahora vemos el fichero defaults/main.yml que contiene las variables por defecto que se van a utilizar en el rol:

roles/kubernetes/defaults/main.yml

Por último, en el fichero main.yml del directorio meta dentro del rol, tenemos las dependencias que tiene el este rol. En el tutorial mencionado anteriormente también hablo sobre la gestión de dependencias de los roles de ansible.

roles/kubernetes/meta/main.yml

3.2. Docker

Nos queda crear las tareas pertenecientes al rol docker, que instalarán la última versión de Docker.

roles/docker/tasks/main.yml

Como bien dice, estos ficheros contienen las tareas encargadas de los prerequisitos de la instalacción, la configuración y la instalación propiamente dicha.

roles/docker/tasks/docker_prerequisites.yml

roles/docker/tasks/docker_setup.yml

roles/docker/tasks/docker_install.yml

Con esto ya tendríamos preparado el entorno y la configuración.

4. Comprobación

Una vez realizada la configuración, basta con ejecutar el comando vagrant up para comprobar como se despliega. Una vez termine vagrant, comprobamos como accediendo a la url localhost:8080 tenemos la indicaciones del api rest. El dashboard viene deshabilitado por defecto, pero veremos como habilitarlo en el próximo tutorial.

5. Conclusiones

Comprobamos una vez más como gracias a Ansible crear una infraestructura compleja como instalar Kubernetes en ubuntu puede ser hecho con un solo comando. Puedes ver los ficheros creados en el tutorial en mi repositorio de github.

6. Referencias

  • Documentación de Kubernetes para instalación de Ubuntu.

2 Comentarios

  1. Buenas Juan Antonio.

    Me ha parecido muy interesante el tutorial, de hecho lo he estado siguiendo para instalarlo en mi entorno y tengo algunas puntualizaciones respecto al fichero roles/kubernetes/tasks/main.yml.
    Primero en Fedora 23 con ansible 2.0.2.0 o con ansible 1.9.6 falla al descomprimir los archivos de kubernetes. El fallo está relacionado con https://github.com/ansible/ansible-modules-core/issues/2936, para solucionarlo he tenido que descomprimir con tar los archivos en vez de usar el módulo.
    Otro problema que me he encontrado es que a la hora de ejecutar una orden la comprobación para ver si hay errores falla. Tanto a la hora de mover la carpeta como a la hora de iniciar el cluster añades un not en la clausula y hace que falle.

    Te copio aquí mi fichero:

    # file: roles/kubernetes/tasks/main.yml

    – name: Create ssh key for this machine (Necesary to start kubernetes)
    user: name=root generate_ssh_key=yes
    register: user_var

    – name: Add key to authorized keys
    shell: «cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys»

    – name: Download Kubernetes release bundle
    get_url: >
    url=»https://github.com/GoogleCloudPlatform/kubernetes/releases/download/v1.2.0/kubernetes.tar.gz»
    dest=»{{kubernetes.temporal_path}}/kubernetes.tar.gz»

    – name: Untar the kubernetes bundle
    command: tar zxvf «{{kubernetes.temporal_path}}/kubernetes.tar.gz» -C {{kubernetes.path}}

    – name: Untar saltbase bundle to configure the cluster.
    command: tar zxvf «{{kubernetes.path}}/kubernetes/server/kubernetes-salt.tar.gz» -C {{kubernetes.path}}/kubernetes/cluster

    – name: move saltbase directory outside the unarchive directory
    shell: mv {{kubernetes.path}}/kubernetes/cluster/kubernetes/saltbase {{kubernetes.path}}/kubernetes/cluster
    register: result
    failed_when: «‘Directory not empty’ in result.stderr and ‘true’ in result.failed»

    – name: Delete empty directory
    file: >-
    path={{kubernetes.path}}/kubernetes/cluster/kubernetes
    state=absent

    – name: Setup default configuration
    copy: >
    src=config-default.sh
    dest={{kubernetes.path}}/kubernetes/cluster/ubuntu
    mode=»0755″
    force=yes

    – name: Start cluster
    shell: KUBERNETES_PROVIDER=ubuntu ./kube-up.sh chdir={{kubernetes.path}}/kubernetes/cluster
    register: result
    failed_when: «‘Text file busy’ in result.stdout and ‘true’ in result.failed»

    – name: Add kube-system namespace
    shell: ./kubectl create -f /opt/kubernetes/cluster/ubuntu/namespace.yaml chdir=/opt/kubernetes/cluster/ubuntu/binaries
    ignore_errors: yes

    Un saludo y gracias por el tutorial.

Dejar respuesta

Please enter your comment!
Please enter your name here