Ce document décrit la mise en place du Reverse Proxy HTTP Traefik dans le Kubernetes de l’usine.

  • L’utilisation de Traefik permet d’exposer, en dehors du cluster, des services déployés dans le cluster.

Ce document vient dans la continuité de celui de Patrick Easters pour remplacer la création des certificats via openssl par une création des certificats via letsencrypt.

Dans la section A, j’explique comment créer les certificats (des services exposés en dehors du cluster) via letsencrypt.

Dans la section B, j’explique comment déployer Traefik dans le K8s (en utilisant les certificats créés).

Dans la section C, j’explique comment exposer un service du cluster via Traefik.

A. Gestion des Certificats

La gestion des certificats est réalisée via cert-manager.

Cert-manager permet d’obtenir des certificats à partir d’une autorité de certification (AC) en utilisant le protocole ACME. Le protocole ACME permet au propriétaire d’un domaine de prouver (via des challenges) à une autorité de certification qu’il en est le propriétaire pour ensuite demander la création d’un certificat pour ce domaine.

Le challenge utilisé ci-dessous est le challenge HTTP-01. Celui-ci consiste à prouver qu’on est propriétaire d’un domaine en postant un fichier, à un endroit déterminé, sur un site web.

Installation de cert-manager

Cert-manager s’installe très simplement via un package helm.

Configuration d’un Issuer

La première étape consiste à configurer l’AC (via un objet Issuer).

kind: Issuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    # The ACME server URL
    server: https://acme-v01.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: xxx.xxx@xxx.com
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-prod
    # Enable the HTTP-01 challenge provider
    http01: {}

Création des Certificats

La seconde étape consiste à enregistrer les domaines des certificats à créer par l’Issuer (via un objet Certificate).

  • Le certificat créé est enregistré dans le secret traefik-cert (utilisé par la configuration Traefik)
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: traefik-cert
spec:
  secretName: traefik-cert
  issuerRef:
    name: letsencrypt-prod
  commonName: meltingpoc.k8.wildwidewest.xyz
  dnsNames: 
    - autres domaines ...
  acme:
    config:
    - http01:
        ingressClass: traefik
      domains:
      - meltingpoc.k8.wildwidewest.xyz
      - autres domaines ...

Validation de l’installation

La validation de l’installation se fait par appel de la commande ‘describe’ sur le certificat créé.

kubectl describe certificate traefik-cert

Le résultat contient :

  • Le statut du certificat créé
  • Les domaines associés
  • Les challenges associés
Name:         traefik-cert
API Version:  certmanager.k8s.io/v1alpha1
Kind:         Certificate
Spec:
  Acme:
    Config:
      Domains:
        meltingpoc.k8.wildwidewest.xyz
      Http 01:
        Ingress:        
        Ingress Class:  traefik
  Common Name:          meltingpoc.k8.wildwidewest.xyz
  Issuer Ref:
    Name:       letsencrypt-prod
  Secret Name:  traefik-cert
Status:
  Acme:
    Authorizations:
      Account:  https://acme-v01.api.letsencrypt.org/acme/reg/31604239
      Domain:   meltingpoc.k8.wildwidewest.xyz
      Uri:      https://acme-v01.api.letsencrypt.org/acme/challenge/b6GbJ994fElrSl1kPe1eXhUHXUp4I2N899-GxOcWCsI/3908551707
  Conditions:
    Last Transition Time:  2018-03-21T20:31:50Z
    Message:               Certificate issued successfully
    Reason:                CertIssueSuccess
    Status:                True
    Type:                  Ready
Events:                    <none>

B. Déploiement de Traefik

Configuration de Traefik

Le fichier de configuration de Traefik (fichier traefik.toml) est déployé via un configmap K8s.

kubectl create configmap traefik-conf --from-file=traefik.toml

Ce fichier configure

  • Un endpoints https
  • Un endpoint http qui redirige tous les requêtes vers l’endpoint https
defaultEntryPoints = ["http", "https"]
[entryPoints]
  [entryPoints.http]
   address = ":80"
     [entryPoints.http.redirect]
      entryPoint = "https"
     [entryPoints.https]
      address = ":443"
     [entryPoints.https.tls]
       [[entryPoints.https.tls.certificates]]
        CertFile = "/ssl/tls.crt"
        KeyFile = "/ssl/tls.key"

Déploiement du DaemonSet

Traefik est déployé comme un DaemonSet K8s. Ceci assure que chaque noeud du cluster exécute une instance du Pod Traefik.

kubectl create -f traefik-ds.yaml

Ci-dessous un extrait de la configuration utilisée

  • La configuration du DaemonSet référence les certificats créés via cert-manager (secret traefik-cert) ainsi que la configuration de Traefik (configmap traefik-conf)
---
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      hostNetwork: true
      volumes:
      - name: ssl
        secret:
          secretName: traefik-cert
      - name: config
        configMap:
          name: traefik-conf
      containers:
      - image: Traefik:1.4-alpine
        name: traefik-ingress-lb
        volumeMounts:
        - mountPath: "/ssl"
          name: "ssl"
        - mountPath: "/config"
          name: "config"
...
        args:
        - -d
        - --web
        - --web.address=:8081
        - --kubernetes
        - --configfile=/config/Traefik.toml

C. Exposition des services

L’exposition des services K8s en dehors du cluster se fait via des objets Ingress.

Le fragment ci-dessous enregistre le service inky-jaguar-api-gateway-chart au niveau du Reverse Proxy Traefik.

kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: Traefik
    Traefik.frontend.rule.type: PathPrefixStrip
  name: inky-jaguar-api-gateway-chart
spec:
  rules:
  - host: meltingpoc.k8.wildwidewest.xyz
    http:
      paths:
      - backend:
          serviceName: inky-jaguar-api-gateway-chart
          servicePort: http
        path: /
  tls:
  - secretName: meltingpoc-tls