BinBashFR
    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups

    Une page de maintenance pour ingress k8s avec Caddy v2

    Technos
    caddy kubernetes
    1
    1
    185
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • remi
      remi last edited by

      Besoin : une page de maintenance pour des services hébergés sur un cluster kubernetes.
      Contraintes pour cette page de maintenance :

      • être stateless
      • avoir la possibilité de donner une raison à la maintenance en cours

      Je voulais tester Caddy v2 depuis un petit moment, ca a été l’occasion pour ce besoin.

      L’idée retenue :

      • Un serveur caddy en reverse proxy d’un minio qui héberge les données de ma page de maintenance (html, css et un simple js).
      • Il a une route /reason qui me permettra de changer la raison de la maintenance.
      • Tous les uris non connus sont renvoyés vers mon index.html pour que la page de maintenance fonctionne pour tous les uris (et ne pas chercher n’importe quoi via le reverse proxy).
      • L’ingress controller Nginx utilise cette page de maintenance en default-backend.

      Configurer le Minio (ou votre s3)

      • Je créé un nouveau bucket pour héberger le contenu de la page de maintenance : mc mb minio/maintenance
      • Je copie le contenu de ma page de maintenance : mc cp --recursive data/ minio/maintenance
      • Je donne un accès publique à ces fichiers : mc policy set download minio/maintenance

      Si vous avez à votre disposition un backend HTTP x ou y, la suite de cet exemple fonctionnera.

      Caddy

      La configuration Caddy en json est disponible sur ce gist.
      Attention : l’api Caddy est exposée sur toutes les interfaces. A adapter selon votre besoin. Il y a peut-être moyen de faire plus simple avec Caddy, je découvre tout juste 🙂

      Tester en local avec Docker

      Pour tester en local sur votre machine, vous pouvez utiliser tout simplement cette commande :

      docker run  -p 10080:80 -p 2019:2019 -v $PWD/caddy.json:/caddy.json -it caddy caddy run -config /caddy.json
      

      En pointant votre navigateur sur http://localhost:10080, Caddy devrait servir les pages de votre backend. Pour mon exemple, ca ressemble à ca :
      maintenance_1.png

      Je peux modifier la raison de la maintenance avec un curl :

       curl \
              localhost:2019/config/apps/http/servers/maintenance/routes/0/handle/0/body \
              -X POST \
              -H "Content-Type: application/json" \
              -d '"<b>Le cluster Etcd du K8S est HS :(</b>"'
      

      maintenance_2.png

      Cette petite magie fonctionne grace au JS trouvé ici. J’ai dans ma page HTML :

      <div w3-include-html="/reason" class="reason"></div>
      

      Le JS charge donc la raison de ma maintenance via la route Caddy /reason qui sert le contenu envoyé par le POST Json.

      Pour information, il est aussi possible de changer la configuration et de forcer le rechargement :

      curl localhost:2019/load \
        -X POST \
        -H "Content-Type: application/json" \
        -d @caddy.json
      

      Déployer sur un kubernetes

      Rien de particulier à rajouter à ce niveau là. A vous d’adapter pour exposer en toute sécurité et selon votre besoin l’api Caddy.

      apiVersion: v1
      kind: Service
      metadata:
        name: maintenance
      spec:
        ports:
        - name: http
          port: 80
          protocol: TCP
          targetPort: http
        - name: api
          port: 2019
          protocol: TCP
          targetPort: api
        sessionAffinity: None
        type: ClusterIP
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: maintenance
      spec:
        replicas: 1
        selector:
          matchLabels:
            name: maintenance
        template:
          metadata:
            labels:
              name: maintenance
          spec:
            containers:
            - image: caddy:v2.2.1
              command:
                - caddy
                - run
                - -config
                - /etc/caddy/caddy.json
              name: maintenance
              ports:
              - containerPort: 80
                name: http
                protocol: TCP
              - containerPort: 2109
                name: api
                protocol: TCP
              resources:
                limits:
                  cpu: 200m
                  memory: 200Mi
                requests:
                  cpu: 100m
                  memory: 64Mi
              volumeMounts:
              - name: maintenance-config
                mountPath: /etc/caddy/caddy.json
                subPath: caddy.json
              securityContext:
                capabilities:
                  drop:
                  - ALL
                  add:
                  - NET_BIND_SERVICE
              livenessProbe:
                httpGet:
                  path: /
                  port: 80
                initialDelaySeconds: 10
                periodSeconds: 60
            volumes:
            - name: maintenance-config
              configMap:
                name: maintenance-config
      

      Changer le default-backend de votre ingress

      Sur l’ingress devant votre service, rajoutez l’annotation suivante pour utiliser cette page de maintenance si les endpoints du service défini dans l’ingress sont HS :

      nginx.ingress.kubernetes.io/default-backend: maintenance
      

      A savoir qu’il est également possible de renvoyer certaines erreurs http sur cette page de maintenance avec l’annotation nginx.ingress.kubernetes.io/custom-http-errors.

      Plus d’information dans la documentation.

      Vous pouvez tester le bon fonctionnement de la page de maintenance avec un scale à 0 des pods du service derrière cet ingress.

      Bref 🙂 Tout ceci est là pour vous inspirer et sera à adapter en fonction de votre stratégie de mise à jour, déploiement … Bon tests !

      1 Reply Last reply Reply Quote 0
      • First post
        Last post