Seguimos avanzando en la gestión de nuestro cluster con Kuberentes.

Resumen del artículo

Ingress Controller

Un Ingress es un objeto que nos va a permitir controlar muchos aspectos de nuestra red en nuestro cluster de Kubernetes. Podemos definirlo en nuestros servicios (tanto la comunicación interna como externa con salida a Internet). Nos permite hacer un balanceo de carga (load balancing), definir rutas HTTP y HTTPS, añadir SSL y definir nombres para cada servicio. Añadir un Ingress nos va además a ahorrar mucho dinero ya que no tendremos que darle un IP Pública a cada servicio, podemos definir una ruta hacia cada uno de ellos y que todos salgan desde la IP Pública del controlador.
Al crear un Ingress tenemos 2 pasos.

  1. El primero es levantar el Deployment del Ingress Controller y sus archivos de configuración.
  2. El segundo es el crear el YAML del servicio tipo LoadBalancer o NodePort y especificar el Ingress.

Hay gran cantidad de controladores (Ingress Controller) que podemos levantar. Pero sus características son diferentes. Debemos elegir el más adecuado a las necesidades de nuestro proyecto. Los más recomendados en general son Traefik, Istio o NGINX. Aquí podemos ver la lista oficial de todos los controladores.
Ingress en Kubernetes 0

¿Entonces que diferencia hay entre el LoadBalancer Service y un Ingress?

Recordamos que en la entrada de primeros pasos con Kuberentes vimos los tipos de Services. Y como un Service LoadBalancer es un paso más allá de un Service NodePort ya que nos hace la carga balanceada y nos aporta una IP Pública para no tener que recordar el puerto ni la IP de cada Nodo. Esta carga balanceada la hace un propio controlador de cada Cloud automáticamente. En el caso de Google Cloud, la carga balanceada se encarga el GCP LoadBalancer.
Y es perfecto utilizar el propio LoadBalancer de nuestro proveedor Cloud cuando una aplicación es simple y no necesita configuración extra de rutas o cuando solo tenemos esa aplicación en el cluster. Nos ahorramos el tener que levantar un controlador y configurarlo. Pero según nuestro proyecto avance, necesitaremos más características que dejándolas automáticas, las podremos realizar, pero tendremos que utilizar varios LoadBalancer de nuestro proveedor Cloud con el coste que ello conlleva y su configuración manual de cada uno de ellos.
Un Ingress es un servicio. Por lo tanto va a utilizar los tipos de servicios que ya hemos visto. Podemos utilizar un Ingress como un servicio de tipo NodePort o lo más normal es utilizarlo como un LoadBalancer. Al utilizarlo como LoadBalancer vamos a tener todos los beneficios que nos aporta nuestro proveedor Cloud más todos los beneficios y configuraciones que podremos realizar que nos aporta nuestro controlador de Ingress.

Tipos de rutas a especificar

Podemos especificar 3 tipos de rutas principalmente.

  1. La ruta simple. Igual que un loadbalancer simple. Le asignamos una IP Pública a un servicio y a un contenedor. Podemos acceder a la aplicación de ese contenedor desde Internet gracias a la IP Pública en el puerto que especifiquemos.
  2. La ruta de sub directorio. Tenemos varios servicios y contenedores con aplicaciones diferentes. Podemos especificar que cada aplicación responda a un sub directorio del propio dominio.
  3. La ruta de sub dominios. Tenemos varios servicios y contenedores con aplicaciones diferentes. Podemos especificar que cada aplicación responda a un sub dominio del propio dominio.

 

Ingress en Kubernetes 1
Pulsa para ampliar.

Escribir Ingress

Ya hemos visto los distintos tipos de Ingress básicos que podemos crear. Pero tenemos que escribirlos.
En todos estos tipos vamos a tener que especificar que utilice el controlador que hemos desplegado. Para especificarlo tan solo tenemos que mencionarlo en anotaciones, debajo del nombre del Ingress. El resto es igual, da igual el controlador que utilices, tan solo tienes que cambiar la anotación y funcionará igual.
1. La ruta simple.
Esta ruta va directamente a la IP Pública del LoadBalancer de nuestro Ingress. No es el más usual ya que no tiene ninguna regla y lo que queremos con un Ingress es poder especificar nuestras rutas con las reglas.
En el archivo especificamos el Nombre del servicio de nuestra aplicación y el puerto con el que queremos que salga a Internet.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-simple
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  backend:
   serviceName: nombre-de-nuestro-service
   servicePort: 80

2. La ruta sub directorio (path).
En este tipo de Ingress ya especificamos reglas. Lo que queremos es que el trafico que acceda a específicamente un directorio de nuestra web redirigirlo hacia ese servicio. Tambien si utilizamos la

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-varios-directorios
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: midominio.com
    http:
      paths:
      - path: /nuestro-reloj
        backend:
          serviceName: nombre-de-nuestro-service-uno
          servicePort: 80
      - path: /aplicacion-de-calculadora
        backend:
          serviceName: nombre-de-nuestro-service-dos
          servicePort: 80

3. La ruta sub dominios (host).

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-varios-dominios
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: reloj.midominio.com
    http:
      paths:
      - backend:
          serviceName: nombre-de-nuestro-service-uno
          servicePort: 80
  - host: calculadora.midominio.com
    http:
      paths:
      - backend:
          serviceName: nombre-de-nuestro-service-dos
          servicePort: 80

En realidad podemos mezclar estos tipos y crear un Ingress que responda al un dominio, a un sub directorio y a un sub dominio. Podemos hacer una ruta simple que este en un dominio específico. Las opciones son muy amplias.
Más información en la página oficial de Kubernetes sobre Ingress.

Levantar Ingress

Lo primero que tenemos que hacer es leer la documentación del controlador que vayamos a utilizar. Es muy importante ya que la instalación cambia de un controlador a otro.

Traefik

En mi caso he elegido Traefik, así que vamos a su documentación oficial. Y en User Guides tenemos una guía especifica para Kubernetes Ingress.
He cogido todos los archivos necesarios y los guardado en un repositorio público. Actualmente la versión recomendada (más estable) es la V1.7. Lo primero que tenemos que hacer es clonar el repositorio donde he guardado todos los archivos. En el README tenemos una pequeña introducción de las partes del Traefik y los archivos.

git clone https://github.com/RedxLus/traefik-simple-kubernetes.git

Y es obligatorio cambiar el Ingress de la Panel de control para que podamos acceder desde nuestro dominio o sub dominio. Por ello simplemente con nano lo editamos.

nano traefik-simple-kubernetes/V1.7/traefik-Ingress-dashboard.yaml

Y también podemos cambiar algo de la configuración de Traefik si queremos. No es obligatorio y podemos dejarlo tan y como está.

nano traefik-simple-kubernetes/V1.7/traefik-configmap.yaml

Ahora ya solo queda levantarlo. Por ello ejecutamos un kubectl apply a todos los archivos.

kubectl apply -f traefik-simple-kubernetes/V1.7/

Por ultimo vamos a apuntar la IP Pública (externa) de nuestro Ingress Traefik. Con ella y el dominio que hemos modificado antes podremos ver y acceder al panel.

kubectl get service release-name-traefik -n kube-system -w

Ingress en Kubernetes 2

Traefik con Helm

También lo podemos instalar utilizando HELM. Es un gestor de paquetes. Pero no es recomendado para utilizarlo en producción. Actualmente están trabajando en la versión de Helm 3 que soluciona esos problemas de seguridad, pero por ahora si queréis usar Helm en producción tenéis que aplicar estos pasos extra de mano de Bitnami.
Aun así, si queremos usarlo lo primero es instalar todo el entorno de Helm. Por ello vamos a utilizar este script que nos automatiza la instalación.

curl https://raw.githubusercontent.com/jonbcampos/kubernetes-series/master/helm/scripts/add_helm.sh | sh

Y vamos a activar el rol de administrador del cluster para que tenga acceso y no haya problemas con los permisos.

kubectl create clusterrolebinding add-on-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default

Una vez ya tenemos Helm totalmente funcional vamos a utilízalo para ejecutar Traefik como Ingress Controller. Tan solo tenemos que utilizar el siguiente comando.

helm install stable/traefik --name traefik-pruebas

Con el comando anterior tendremos Traefik sin configurar. Pero nosotros queremos que tenga varias modificaciones extra. Para ello al comando anterior se le puede meter un archivo de configuración, da igual el nombre, nosotros lo vamos a llamar traefik-helm-config.yml. Así que vamos a borrar todos los componentes del comando anterior (helm delete --purge traefik-pruebas) y a meter volver a ejecutar el comando con la configuración.
Este es el archivo de configuración que uso yo: https://gitlab.com/luisdieguezbarrio/opensource-hosting/raw/master/traefik-helm-config.yml  como podéis ver, utiliza una versión especifica (se puede cambiar, para ver las versiones disponibles es aquí en chart versions), también usa un correo (poned el vuestro y no tiene porque ser gmail) y utiliza la dashboard con un sub dominio, que puede ser un dominio.

wget https://gitlab.com/luisdieguezbarrio/opensource-hosting/raw/master/traefik-helm-config.yml

Debemos editar ese archivo a nuestro gusto. Una vez lo tengamos ya podemos ejecutar de nuevo Helm para instalar Traefik y todos sus componentes.

helm install --name traefik --namespace kube-system --values traefik-helm-config.yml stable/traefik

Y con esto ya tendríamos Traefik como Ingress Controller usando Helm.

Ejemplo práctico

Vamos a utilizar 2 aplicaciones con sus 2 servicios para luego escribir 1 Ingress para que cada una vaya a su propio subdominio.
La primera aplicación y su Service es de una web que muestra un reloj. La segunda aplicación y su Service es de una web que muestra una calculadora. Levantamos todas las aplicaciones y sus servicios:

kubectl apply -f https://raw.githubusercontent.com/RedxLus/traefik-simple-kubernetes/master/tests/deploy-and-service-reloj-y-caluladora.yaml

Podemos ver que se han levantado correctamente ambos:

kubectl get po,service

Ahora el Ingress. Si te das cuenta es el mismo que usamos de ejemplo anteriormente al explicar los tipos de Ingress. Solo tienes que cambiar el dominio por el tuyo, crear los subdominios y añadir la IP Pública del Traefik en el panel de control de tu Hosting

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-calculadora-reloj
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: reloj.midominio.com
    http:
      paths:
      - backend:
          serviceName: reloj
          servicePort: 80
  - host: calculadora.midominio.com
    http:
      paths:
      - backend:
          serviceName: calculadora
          servicePort: 80

Ingress en Kubernetes 3
En el repositorio de Traefik Simple Kubernetes he subido varios ejemplos más de Deployments con sus Services y las bases de los Ingress.