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.
- El primero es levantar el Deployment del Ingress Controller y sus archivos de configuración.
- 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.
¿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.
- 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.
- 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.
- 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.
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
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
En el repositorio de Traefik Simple Kubernetes he subido varios ejemplos más de Deployments con sus Services y las bases de los Ingress.