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 :

Un certificat propre et sécurisé pour votre sous-domaine

et :

Piwik - aka Matomo

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