Nota: Este post ha sido importado de mi blog de geeks.ms. Es posible que algo no se vea del todo "correctamente". En cualquier caso puedes acceder a la versión original aquí
¡Buenas! En esta entrada voy a resumir los pasos seguidos para añadir soporte SSL a un cluster Kubernetes. En mi caso lo tengo desplgado en ACS pero eso es irrelevante.
Lo único que si usas ACS y quieres usar una IP determinada, recuerda que la IP pública que vayas a usar debe estar creada anteriormente. Si no, por más que la especifiques dentro de la configuración del servicio (usando loadBalancerIP), Kubernetes no va a poder levantar el servicio.
En este caso se usa un solo servicio de tipo LoadBalancer de Kubernetes, es decir hay una única IP de acceso desde el exterior. Mi clúster contiene varios servicios (varias APIs REST) y se seleccionan mediante el path:
- http://ip-cluster/api1/
- http://ip-cluster/api2/
- …
El servicio de tipo LoadBalancer que expone la “ip-cluster” es un contenedor de nginx. Así la mayor parte del trabajo se reduce en “dar soporte SSL a nginx”.
Parte 1: Preparar la configuración del nginx
Lo primero que hice fue seguir los pasos de este post (https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-nginx-in-ubuntu-16-04). En concreto:
- Creé el certificado SSL y el fichero del grupo Diffie-Hellman, según las instrucciones del “Step 1”
- La diferencia con la sentencia del post enlazado es que en el post están configurando un nginx existente y generan los ficheros directamente en el directorio donde está nginx. Yo tengo que configurar un contenedor en k8s, así que ya llegaremos a eso. Por eso genero los ficheros en mi directorio local.
- Nota: Por experiencias anteriores evité usar cygwin para generar esos ficheros. Usa una distro de Linux o bien usa bash for Windows que funciona perfectamente.
- El siguiente paso fue crearme los ficheros ssl-params.conf y self-signed.conf con el mismo contenido que se menciona en el post en el “Step 2”. Esos ficheros contienen la configuración para que nginx soporte SSL.
- Finalmente edité mi fichero de configuración de nginx y agregué las siguientes líneas dentro de la sección server (para que nginx escuche por el 443 para SSL):
listen 443 ssl; include ./self-signed.conf; include ./ssl-params.conf;
Parte 2: Configurar Kubernetes
En este punto tengo los ficheros dhparam.pem, nginx-selfsigned.key y nginx-selfsigned.crt (creados a partir del “Step 1” del post anterior) y los ficheros ssl-params.conf y _self-signed.conf (_creados a partir del “Step 2” del post anterior).
El primer paso es crear config-maps de Kubernetes para poder montar esos ficheros en el contenedor de nginx. Para ello podemos usar los siguientes comandos:
kubectl create configmap ssl-files --from-file=nginx-selfsigned.crt --from-file=dhparam.pem kubectl create configmap self-cert-key --from-file=nginx-selfsigned.key kubectl create configmap config-files --from-file=nginx.conf --from-file=self-signed.conf --from-file=ssl-params.conf
El siguiente paso es configurar el servicio de nginx. En mi caso este servicio se llama frontend. Y su yaml es como sigue:
apiVersion: v1 kind: Service metadata: labels: app: myapp component: frontend name: frontend spec: ports: - port: 80 name: tcp-80 targetPort: 8080 - port: 443 name: tcp-443 targetPort: 443 selector: app: myapp component: frontend type: LoadBalancer loadBalancerIP: x.x.x.x
Lo importante ahí es ver que tengo definidos tanto los puertos 80 como el 443. Por defecto mi nginx escuchaba por el 8080 (de ahí el port forwarding de 80 a 8080 definido). Para el puerto 443 no hay port forwarding porque en el fichero nginx.conf, he configurado directamente el 443 como el puerto de SSL.
Vayamos ahora a la configuración del deployment en kubernetes. Es en este punto donde vamos a usar volúmenes para desplegar los distintos ficheros de los config-maps en el directorio destino del contenedor (pongo solo la parte referente a los volúmenes):
volumeMounts: - name: config mountPath: /etc/nginx - name: certs mountPath: /etc/ssl/certs/ - name: ssl-private mountPath: /etc/ssl/private/ volumes: - name: config configMap: name: config-files items: - key: nginx.conf path: nginx.conf - key: self-signed.conf path: self-signed.conf - key: ssl-params.conf path: ssl-params.conf - name: certs configMap: name: ssl-files items: - key: dhparam.pem path: dhparam.pem - key: nginx-selfsigned.crt path: nginx-selfsigned.crt - name: ssl-private configMap: name: self-cert-key items: - key: nginx-selfsigned.key path: nginx-selfsigned.key
Desplegamos cada uno de los ficheros a su path indicado_._
¡Y listos! Con esto nuestro contenedor nginx ya estará preparado para aceptar conexiones SSL. 🙂