Introducción
En los próximos posts hablaremos sobre Kubernetes, el orquestador de aplicaciones contenerizadas que anda en boca de todos.
Prerrequisitos
Partimos de un conjunto de tres máquinas virtuales basadas en Ubuntu 16.04 en las que debemos instalar Docker. Las versiones compatibles de Docker las puedes consultar aquí.
Una de las máquinas tendrá el rol de Master del cluster, es decir, acogerá el servicio etcd y el controlplane. Esta máquina la hemos desplegado con 1vcpu y 1Gb de ram. En esta instalación no dispondremos de alta disponibilidad del cluster puesto que harían falta al menos 3 nodos con el rol Master para que el cluster pudiese funcionar en HA.
Las otras dos máquinas tendrán el rol de Worker, es decir, serán las encargadas de correr nuestras aplicaciones. Estas máquinas se han desplegado con 2vcpu y 4Gb de ram cada una. Es importante que los nodos worker no tengan activada la swap. Así que sólo para estos dos nodos la desactivaremos.
A continuación, el proceso de instalación de los requisitos para las tres máquinas:
# Instalamos paquetes necesarios gtk@k8s-master:~$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common # Descargamos y agregamos la clave pública del repositorio de docker gtk@k8s-master:~$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - OK # Agregamos el repositorio gtk@k8s-master:~$ sudo add-apt-repository "deb https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" gtk@k8s-master:~$ sudo apt-get update # Instalamos docker gtk@k8s-master:~$ sudo apt install docker-ce Leyendo lista de paquetes... Hecho Creando árbol de dependencias Leyendo la información de estado... Hecho Se instalarán los siguientes paquetes adicionales: aufs-tools cgroupfs-mount containerd.io docker-ce-cli libltdl7 pigz Paquetes sugeridos: mountall Se instalarán los siguientes paquetes NUEVOS: aufs-tools cgroupfs-mount containerd.io docker-ce docker-ce-cli libltdl7 pigz 0 actualizados, 7 nuevos se instalarán, 0 para eliminar y 0 no actualizados. Se necesita descargar 50,5 MB de archivos. Se utilizarán 243 MB de espacio de disco adicional después de esta operación. ¿Desea continuar? s Des:1 http://es.archive.ubuntu.com/ubuntu xenial/universe amd64 pigz amd64 2.3.1-2 Des:2 http://es.archive.ubuntu.com/ubuntu xenial/universe amd64 aufs-tools amd64 1:3.2+20130722-1.1ubuntu1 Des:3 https://download.docker.com/linux/ubuntu xenial/stable amd64 containerd.io amd64 1.2.5-1 Des:4 http://es.archive.ubuntu.com/ubuntu xenial/universe amd64 cgroupfs-mount all 1.2 Des:5 http://es.archive.ubuntu.com/ubuntu xenial/main amd64 libltdl7 amd64 2.4.6-0.1 Des:6 https://download.docker.com/linux/ubuntu xenial/stable amd64 docker-ce-cli amd64 5:18.09.2~3-0~ubuntu-xenial Des:7 https://download.docker.com/linux/ubuntu xenial/stable amd64 docker-ce amd64 5:18.09.2~3-0~ubuntu-xenial Descargados 50,5 MB en 2s (21,3 MB/s) Seleccionando el paquete pigz previamente no seleccionado. (Leyendo la base de datos ... 93106 ficheros o directorios instalados actualmente.) Preparando para desempaquetar .../pigz_2.3.1-2_amd64.deb ... Desempaquetando pigz (2.3.1-2) ... Seleccionando el paquete aufs-tools previamente no seleccionado. Preparando para desempaquetar .../aufs-tools_1%3a3.2+20130722-1.1ubuntu1_amd64.deb ... Desempaquetando aufs-tools (1:3.2+20130722-1.1ubuntu1) ... Seleccionando el paquete cgroupfs-mount previamente no seleccionado. Preparando para desempaquetar .../cgroupfs-mount_1.2_all.deb ... Desempaquetando cgroupfs-mount (1.2) ... Seleccionando el paquete containerd.io previamente no seleccionado. Preparando para desempaquetar .../containerd.io_1.2.5-1_amd64.deb ... Desempaquetando containerd.io (1.2.5-1) ... Seleccionando el paquete docker-ce-cli previamente no seleccionado. Preparando para desempaquetar .../docker-ce-cli_5%3a18.09.2~3-0~ubuntu-xenial_amd64.deb ... Desempaquetando docker-ce-cli (5:18.09.2~3-0~ubuntu-xenial) ... Seleccionando el paquete docker-ce previamente no seleccionado. Preparando para desempaquetar .../docker-ce_5%3a18.09.2~3-0~ubuntu-xenial_amd64.deb ... Desempaquetando docker-ce (5:18.09.2~3-0~ubuntu-xenial) ... Seleccionando el paquete libltdl7:amd64 previamente no seleccionado. Preparando para desempaquetar .../libltdl7_2.4.6-0.1_amd64.deb ... Desempaquetando libltdl7:amd64 (2.4.6-0.1) ... Procesando disparadores para man-db (2.7.5-1) ... Procesando disparadores para libc-bin (2.23-0ubuntu11) ... Procesando disparadores para ureadahead (0.100.0-19) ... Procesando disparadores para systemd (229-4ubuntu21.21) ... Configurando pigz (2.3.1-2) ... Configurando aufs-tools (1:3.2+20130722-1.1ubuntu1) ... Configurando cgroupfs-mount (1.2) ... Configurando containerd.io (1.2.5-1) ... Configurando docker-ce-cli (5:18.09.2~3-0~ubuntu-xenial) ... Configurando docker-ce (5:18.09.2~3-0~ubuntu-xenial) ... update-alternatives: utilizando /usr/bin/dockerd-ce para proveer /usr/bin/dockerd (dockerd) en modo automático Configurando libltdl7:amd64 (2.4.6-0.1) ... Procesando disparadores para libc-bin (2.23-0ubuntu11) ... Procesando disparadores para systemd (229-4ubuntu21.21) ... Procesando disparadores para ureadahead (0.100.0-19) ... # Agregamos nuestro usuario al grupo docker gtk@k8s-master:~$ sudo adduser gtk docker Añadiendo al usuario `gtk` al grupo `docker` ... Adding user gtk to group docker Hecho. # Comprobamos la versión instalada gtk@k8s-master:~$ docker version Client: Version: 18.09.2 API version: 1.39 Go version: go1.10.6 Git commit: 6247962 Built: Sun Feb 10 04:13:50 2019 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 18.09.2 API version: 1.39 (minimum version 1.12) Go version: go1.10.6 Git commit: 6247962 Built: Sun Feb 10 03:42:13 2019 OS/Arch: linux/amd64 Experimental: false # Ajustamos parámetros necesarios en el sysctl.cnf gtk@k8s-master:~$ sudo sysctl -p net.bridge.bridge-nf-call-iptables = 1 # Solo para los nodos worker, desactivamos la swap gtk@k8s-node01:~$ sudo swapoff -a gtk@k8s-node01:~$ sudo vim /etc/fstab # Comentamos la línea del punto de montaje de la swap # Por ejemplo: # UUID=b081f8c7-116c-4133-8adb-3a4cfdc50179 none swap sw 0 0
Por último, y muy importante, tenemos que copiar nuestra clave pública a los distintos nodos del cluster para poder operarlo sin contraseña. Esto lo realizaremos de la siguiente forma:
➜ gtk@ops:~$ ssh-copy-id gtk@k8s-master.gtk.local The authenticity of host 'k8s-master.gtk.local (172.26.13.254)' can't be established. ECDSA key fingerprint is SHA256:DFMuTCXt3Mu0EQRKzkQAf5m3Sm8/QgjRkMYobrMle94. Are you sure you want to continue connecting (yes/no)? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys gtk@k8s-master.gtk.local's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'gtk@k8s-master.gtk.local'" and check to make sure that only the key(s) you wanted were added. ➜ gtk@ops:~$ ssh-copy-id gtk@k8s-node01.gtk.local The authenticity of host 'k8s-node01.gtk.local (172.26.13.248)' can't be established. ECDSA key fingerprint is SHA256:7qiwY7jaOS4wSgDfHdthxin4PWDmD80HeurK/hU0SUg. Are you sure you want to continue connecting (yes/no)? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys gtk@k8s-node01.gtk.local's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'gtk@k8s-node01.gtk.local'" and check to make sure that only the key(s) you wanted were added. ➜ gtk@ops:~$ ssh-copy-id gtk@k8s-node02.gtk.local The authenticity of host 'k8s-node02.gtk.local (172.26.13.250)' can't be established. ECDSA key fingerprint is SHA256:dSkTBY0GUaaaDLKXo85ZLXfGYrr+GR+U0wcROOBNhLA. Are you sure you want to continue connecting (yes/no)? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys gtk@k8s-node02.gtk.local's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'gtk@k8s-node02.gtk.local'" and check to make sure that only the key(s) you wanted were added.
Ya estamos listos para instalar el cluster.
Instalación de RKE
RKE son las siglas de Rancher Kubernetes Engine, una herramienta libre para desplegar clusters de Kubernetes certificados de la compañía Rancher. RKE nos permitirá instalar versiones 1.11, 1.12 y 1.13 de Kubernetes de forma fácil y cómoda. En próximos posts hablaremos de otras herramientas como Kubespray o kops, esta última específica para AWS.
Procedemos a instalar el binario de rke de la siguiente forma:
# Descargamos el binario desde su web en Github gtk@ops:~$ wget https://github.com/rancher/rke/releases/download/v0.2.2/rke_linux-amd64 gtk@ops:~$ mv rke_linux-amd64 rke gtk@ops:~$ chmod +x rke gtk@ops:~$ sudo mv rke /usr/local/bin/ gtk@ops:~$ rke --version gtk@ops:~$ rke version v0.2.2
Ya disponemos del binario para poder instalar el cluster, ahora configuraremos las características del mismo mediante el comando rke config:
# Configuramos el cluster con 3 nodos, uno de ellos master y otros dos workers. gtk@ops:~$ rke config Cluster Level SSH Private Key Path : Number of Hosts : 3 SSH Address of host (1) : k8s-master.gtk.local SSH Port of host (1) : SSH Private Key Path of host (k8s-master.gtk.local) : You have entered empty SSH key path, trying fetch from SSH key parameter SSH Private Key of host (k8s-master.gtk.local) : You have entered empty SSH key, defaulting to cluster level SSH key: ~/.ssh/id_rsa SSH User of host (k8s-master.gtk.local) : gtk Is host (k8s-master.gtk.local) a Control Plane host (y/n)? : y Is host (k8s-master.gtk.local) a Worker host (y/n)? : n Is host (k8s-master.gtk.local) an etcd host (y/n)? : y Override Hostname of host (k8s-master.gtk.local) : Internal IP of host (k8s-master.gtk.local) : Docker socket path on host (k8s-master.gtk.local) : SSH Address of host (2) : k8s-node01.gtk.local SSH Port of host (2) : SSH Private Key Path of host (k8s-node01.gtk.local) : You have entered empty SSH key path, trying fetch from SSH key parameter SSH Private Key of host (k8s-node01.gtk.local) : You have entered empty SSH key, defaulting to cluster level SSH key: ~/.ssh/id_rsa SSH User of host (k8s-node01.gtk.local) : gtk Is host (k8s-node01.gtk.local) a Control Plane host (y/n)? : n Is host (k8s-node01.gtk.local) a Worker host (y/n)? : y Is host (k8s-node01.gtk.local) an etcd host (y/n)? : n Override Hostname of host (k8s-node01.gtk.local) : Internal IP of host (k8s-node01.gtk.local) : Docker socket path on host (k8s-node01.gtk.local) : SSH Address of host (3) : k8s-node02.gtk.local SSH Port of host (3) : SSH Private Key Path of host (k8s-node02.gtk.local) : You have entered empty SSH key path, trying fetch from SSH key parameter SSH Private Key of host (k8s-node02.gtk.local) : You have entered empty SSH key, defaulting to cluster level SSH key: ~/.ssh/id_rsa SSH User of host (k8s-node02.gtk.local) : gtk Is host (k8s-node02.gtk.local) a Control Plane host (y/n)? : n Is host (k8s-node02.gtk.local) a Worker host (y/n)? : y Is host (k8s-node02.gtk.local) an etcd host (y/n)? : n Override Hostname of host (k8s-node02.gtk.local) : Internal IP of host (k8s-node02.gtk.local) : Docker socket path on host (k8s-node02.gtk.local) : Network Plugin Type (flannel, calico, weave, canal) : calico Authentication Strategy : Authorization Mode (rbac, none) : Kubernetes Docker image : Cluster domain : k8s-gtk.local Service Cluster IP Range : Enable PodSecurityPolicy : y Cluster Network CIDR : Cluster DNS Service IP : Add addon manifest URLs or YAML files :
Después de este wizard que nos permite configurar el cluster a nuestro gusto, podemos revisar la configuración que ha generado antes de provisionarlo en el fichero YAML cluster.yml generado en el directorio desde donde lanzamos el comando de configuración.
Una vez revisado el fichero y comprobado que todo está bajo control procederemos a lanzar el provisionamiento:
# Utilizo el modificador --ssh-agent-auth para utilizar mi clave pública cargada en el entorno mediante ssh-agent. ➜ gtk@ops:~$ rke up --ssh-agent-auth INFO Initiating Kubernetes cluster INFO Generating admin certificates and kubeconfig INFO Successfully Deployed state file at INFO Building Kubernetes cluster ... ... INFO Setting up nginx ingress controller INFO Saving ConfigMap for addon rke-ingress-controller to Kubernetes INFO Successfully saved ConfigMap for addon rke-ingress-controller to Kubernetes INFO Executing deploy job rke-ingress-controller INFO ingress controller nginx deployed successfully INFO Setting up user addons INFO no user addons defined INFO Finished building Kubernetes cluster successfully
Y con esto hemos desplegado el cluster al que aún no podemos acceder, porque nos falta una herramienta por instalar: kubectl
Kubectl
Kubectl es el cli para correr comandos contra un cluster Kubernetes. Esta herramienta busca en tu directorio de usuario en la ruta ~/.kube/ un fichero config con las credenciales de acceso al cluster. Nosotros al instalar mediante rke tenemos este fichero en nuestro directorio de trabajo bajo el nombre de kube_config_cluster.yml.
Podemos instalar kubectl de la siguiente forma:
# Instalando kubectl desde el repositorio de Google gtk@ops:~$ sudo apt-get update && sudo apt-get install -y apt-transport-https gtk@ops:~$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - gtk@ops:~$ echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list gtk@ops:~$ sudo apt-get update gtk@ops:~$ sudo apt-get install -y kubectl
Una vez instalado el cli de Kubernetes, podemos revisar el estado del cluster:
gtk@ops:~$ kubectl --kubeconfig kube_config_cluster.yml get nodes NAME STATUS ROLES AGE VERSION k8s-master.gtk.local Ready controlplane,etcd 7m49s v1.13.5 k8s-node01.gtk.local Ready worker 7m44s v1.13.5 k8s-node02.gtk.local Ready worker 7m44s v1.13.5
Como veis, nos aparece el nombre, estado, roles, tiempo de uptime y versión de nuestro cluster recién desplegado. Tenemos una cheat sheet de kubectl aquí.
Si queremos utilizar el comando kubectl sin el modificador –kubeconfig kube_config_cluster.yml basta con mover este archivo y renombrarlo como config al directorio ~/.kube/ y se utilizaría esta configuración de acceso por defecto.
En el siguiente post desplegaremos una par de aplicaciones en nuestro cluster, tanto stateless como stateful y revisaremos las distintas formas de desplegar, escalar y gestionar nuestras aplicaciones contenerizadas en un cluster Kubernetes 1.13.5.
muy muy buena guia, me ha servido de muchisimo, ¡muchas gracias!
falta que adaptes el link de kubernetes para que parezca un poco mas actualizado y ya perfecto
Hola. Precisamente estamos trabajando en un nuevo post actualizado para las nuevas versiones de 2.4.x de Rancher. ¡Muchas gracias por el feedback!