Ajouter des services web à votre cluster K8s sous un seul et même certificat SSL
Aperçu
L'équilibreur de charge HTTP(S) met fin aux connexions SSL/TLS du client, puis répartit les requêtes entre vos pods. Lorsque vous configurez un équilibreur de charge HTTP(S) via [Ingress], vous pouvez le configurer pour qu'il présente au maximum dix certificats TLS au client.
L'équilibreur de charge utilise l'indication du nom du serveur SNI (Server Name Indication) pour déterminer le certificat à présenter au client, en fonction du nom de domaine figurant dans le handshake TLS. Si le client n'utilise pas SNI ou utilise un nom de domaine qui ne correspond pas au nom commun (CN) de l'un des certificats, l'équilibreur de charge utilise le premier certificat répertorié dans l'objet Ingress. Le diagramme suivant illustre l’équilibrage de charge qui envoie le trafic à différents backends, en fonction du nom de domaine utilisé dans la requête.
Pré-requis :
- un cluster Gke en 1.10.2 minimum
- un service déjà déployé comme dans l'article précédent avec Ghost
- un certificat TLS déjà fonctionnel avec cert-manager
- un nom de domaine accessible
Objectifs :
L'objectif principal sera de déployer un service comme Matomo depuis une image Docker sur le cluster GKE, tout en assurant sa sécurisation avec un certificat TLS propre.
Le second objectif sera de trouver une solution simple et facilement réutilisable pour d'autres services.
Le modèle
Voici le fichier deployment.yaml type et cible que nous voudrons pour ajouter un second service web à notre cluster K8s.
spec:
tls:
- hosts:
- storage.example.com
- example.com
secretName: letsencrypt-prod
rules:
- host: storage.example.com
http:
paths:
- backend:
serviceName: storage
servicePort: 80
- host: example.com
http:
paths:
- backend:
serviceName: storage
servicePort: 80
Pour nous ce sera donc Matomo (ex : Piwik). Voici comment procéder dans le détail avec un fichier deployment.yaml personnalisé, la documentation se situe sur ce repository d'une image Docker de Matomo.
L'action
Nous allons suivre les consignes données par le mainteneur du repo pour appliquer le service Matomo à notre cluster K8s. On commence par ne pas utiliser le fichier de Namespace, sinon votre application web ne pourra pas être sécurisé par notre certificat SSL étant donné que Cert-Manager ne saura aller trouver dans un autre namespace, l'application Matomo ou une autre.
Ensuite appliquons les fichiers en les renommant localement sur notre poste :
sudo nano 02-volume.yaml
Et le contenu suivant :
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: matomo-data-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Idem avec le deuxième fichier, pour nous le troisième (puisque nous avons supprimé 01-namespace),
sudo nano 03-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: matomo-deployment
namespace: matomo
spec:
replicas: 1
selector:
matchLabels:
app: matomo
template:
metadata:
name: matomo
labels:
app: matomo
spec:
containers:
# In production you should set a specific tag
- image: crazymax/matomo:latest
imagePullPolicy: Always
name: matomo
env:
# To use with ingress-nginx allow nginx RealIP for all IPs @see Issue #8
- name: REAL_IP_FROM
value: "0.0.0.0/0"
# resources:
# requests:
# memory: "128Mi"
# cpu: "100m"
# limits:
# memory: "256Mi"
# cpu: "500m"
ports:
- containerPort: 8000
name: web
volumeMounts:
- name: matomo-data
mountPath: /data
- image: crazymax/matomo:latest
imagePullPolicy: Always
name: matomo-cron
env:
- name: SIDECAR_CRON
value: "1"
- name: CRON_GEOIP
value: "0 4 * * *"
- name: CRON_ARCHIVE
value: "0 * * * *"
# resources:
# requests:
# memory: "128Mi"
# cpu: "150m"
# limits:
# memory: "256Mi"
# cpu: "500m"
volumeMounts:
- name: matomo-data
mountPath: /data
volumes:
- name: matomo-data
persistentVolumeClaim:
claimName: matomo-data-pvc
Puis le service avec sudo nano 04-service.yaml
apiVersion: v1
kind: Service
metadata:
name: matomo
spec:
ports:
- name: matomo
protocol: TCP
port: 8000
selector:
app: matomo
Et enfin l'ingress, que l'on va nommer matomo-ingress.yaml :
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: matomo-ingress
namespace: matomo
annotations:
ingress.kubernetes.io/ssl-redirect: "true"
kubernetes.io/tls-acme: "true"
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: matomo.gsagnard.fr
http:
paths:
- path: /
backend:
serviceName: matomo
servicePort: 8000
tls:
- hosts:
- matomo.gsagnard.fr
secretName: matomo-ingress-tls
On applique tous les fichiers avec la commande create -f ou apply -f :
kubectl apply -f matomo-ingress.yaml
Et dans la joie et l'allégresse au bout de quelques minutes de patience (si vous ne l'êtes pas rappelez-vous l'article précédent et la commande suivante) :
kubectl get certificate
kubectl describe certificate-xxxx-xx
Celle-ci vous permettra de découvrir en live, l'état de votre certificat SSL pour le sous-domaine matomo.mydomain.fr
...
dont voici le résultat :

Nous tâcherons d'en faire de même avec d'autres services web par la suite dans de nouvelles aventures.