Comment configurer une entrée Nginx sur DigitalOcean Kubernetes à l’aide de Helm

L'auteur a sélectionné lesFree and Open Source Fund pour recevoir un don dans le cadre du programmeWrite for DOnations.

introduction

KubernetesIngresses vous offre un moyen flexible d'acheminer le trafic de l'extérieur de votre cluster vers les services Kubernetes internes. Les entréesResourcesont des objets dans Kubernetes qui définissent des règles de routage du trafic HTTP et HTTPS vers les services. Pour que ceux-ci fonctionnent, un IngressController doit être présent; son rôle est de mettre en œuvre les règles en acceptant le trafic (très probablement via un Load Balancer) et en l'acheminant vers les services appropriés. La plupart des contrôleurs d'ingénierie utilisent un seul équilibreur de charge global pour toutes les entrées, ce qui est plus efficace que la création d'un équilibreur de charge pour chaque service que vous souhaitez exposer.

Helm est un gestionnaire de packages pour gérer Kubernetes. L'utilisation de Helm Charts avec votre Kubernetes offre une possibilité de configuration et une gestion du cycle de vie permettant de mettre à jour, de restaurer et de supprimer une application Kubernetes.

Dans ce guide, vous allez configurer lesNginx Ingress Controllergérés par Kubernetes à l'aide de Helm. Vous créerez ensuite une ressource Ingress pour acheminer le trafic de vos domaines vers des exemples de services dorsaux Hello World. Une fois que vous avez configuré Ingress, vous installerezCert-Manager sur votre cluster pour pouvoir provisionner automatiquement les certificats Let’s Encrypt TLS pour sécuriser vos Ingresses.

Conditions préalables

  • Un cluster DigitalOcean Kubernetes avec votre configuration de connexion configurée commekubectl par défaut. Les instructions sur la façon de configurerkubectl sont affichées sous l'étapeConnect to your Cluster affichée lorsque vous créez votre cluster. Pour savoir comment créer un cluster Kubernetes sur DigitalOcean, consultezKubernetes Quickstart.

  • Le gestionnaire de paquets Helm installé sur votre ordinateur local et Tiller installé sur votre cluster. Effectuez les étapes 1 et 2 du didacticielHow To Install Software on Kubernetes Clusters with the Helm Package Manager.

  • Un nom de domaine entièrement enregistré avec deux enregistrements A disponibles. Ce tutoriel utiliserahw1.example.com ethw2.example.com partout. Vous pouvez acheter un nom de domaine surNamecheap, en obtenir un gratuitement surFreenom ou utiliser le registraire de domaine de votre choix.

[[step-1 -—- setting-up-hello-world-deployments]] == Étape 1 - Configuration des déploiements Hello World

Dans cette section, avant de déployer Nginx Ingress, vous déploierez une application Hello World appeléehello-kubernetes pour disposer de certains services vers lesquels vous acheminez le trafic. Pour vérifier que Nginx Ingress fonctionne correctement aux étapes suivantes, vous devrez le déployer deux fois, chaque fois avec un message de bienvenue différent qui s'affichera lorsque vous y accéderez à partir de votre navigateur.

Vous allez stocker la configuration de déploiement sur votre ordinateur local. La première configuration de déploiement sera dans un fichier nomméhello-kubernetes-first.yaml. Créez-le en utilisant un éditeur de texte:

nano hello-kubernetes-first.yaml

Ajoutez les lignes suivantes:

hello-kubernetes-first.yaml

apiVersion: v1
kind: Service
metadata:
  name: hello-kubernetes-first
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: hello-kubernetes-first
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes-first
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-kubernetes-first
  template:
    metadata:
      labels:
        app: hello-kubernetes-first
    spec:
      containers:
      - name: hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.5
        ports:
        - containerPort: 8080
        env:
        - name: MESSAGE
          value: Hello from the first deployment!

Cette configuration définit un déploiement et un service. Le déploiement se compose de trois répliques de l'imagepaulbouwer/hello-kubernetes:1.5 et d'une variable d'environnement nomméeMESSAGE - vous verrez sa valeur lorsque vous accédez à l'application. Le service ici est défini pour exposer le déploiement dans le cluster au port80.

Enregistrez et fermez le fichier.

Ensuite, créez cette première variante de l'applicationhello-kubernetes dans Kubernetes en exécutant la commande suivante:

kubectl create -f hello-kubernetes-first.yaml

Vous verrez le résultat suivant:

Outputservice/hello-kubernetes-first created
deployment.apps/hello-kubernetes-first created

Pour vérifier la création du service, exécutez la commande suivante:

kubectl get service hello-kubernetes-first

La sortie ressemblera à ceci:

OutputNAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
hello-kubernetes-first   ClusterIP   10.245.85.236           80:31623/TCP   35s

Vous verrez que le service nouvellement créé se voit attribuer un ClusterIP, ce qui signifie qu'il fonctionne correctement. Tout le trafic qui lui est envoyé sera transféré vers le déploiement sélectionné sur le port8080. Maintenant que vous avez déployé la première variante de l'applicationhello-kubernetes, vous allez travailler sur la seconde.

Ouvrez un fichier appeléhello-kubernetes-second.yaml pour le modifier:

nano hello-kubernetes-second.yaml

Ajoutez les lignes suivantes:

hello-kubernetes-second.yaml

apiVersion: v1
kind: Service
metadata:
  name: hello-kubernetes-second
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: hello-kubernetes-second
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes-second
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-kubernetes-second
  template:
    metadata:
      labels:
        app: hello-kubernetes-second
    spec:
      containers:
      - name: hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.5
        ports:
        - containerPort: 8080
        env:
        - name: MESSAGE
          value: Hello from the second deployment!

Enregistrez et fermez le fichier.

Cette variante a la même structure que la configuration précédente; les seules différences sont dans les noms de déploiement et de service, pour éviter les collisions, et le message.

Maintenant, créez-le dans Kubernetes avec la commande suivante:

kubectl create -f hello-kubernetes-second.yaml

La sortie sera:

Outputservice/hello-kubernetes-second created
deployment.apps/hello-kubernetes-second created

Vérifiez que le deuxième service est opérationnel en répertoriant tous vos services:

kubectl get service

Le résultat sera similaire à ceci:

OutputNAME                            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                      AGE
hello-kubernetes-first          ClusterIP      10.245.85.236              80:31623/TCP                 54s
hello-kubernetes-second         ClusterIP      10.245.99.130              80:30303/TCP                 12s
kubernetes                      ClusterIP      10.245.0.1                 443/TCP                      5m

Leshello-kubernetes-first ethello-kubernetes-second sont répertoriés, ce qui signifie que Kubernetes les a créés avec succès.

Vous avez créé deux déploiements de l'applicationhello-kubernetes avec les services associés. Chaque message a un ensemble de messages différent dans la spécification de déploiement, ce qui vous permet de les différencier lors des tests. À l’étape suivante, vous installerez le contrôleur Nginx Ingress Controller lui-même.

[[step-2 -—- Installing-the-kubernetes-nginx-ingress-controller]] == Étape 2 - Installation du contrôleur d'entrée Kubernetes Nginx

Vous allez maintenant installer lesNginx Ingress Controllermaintenus par Kubernetes à l'aide de Helm. Notez qu'il existe plusieursNginx Ingresses.

Le Nginx Ingress Controller comprend un pod et un service. Le pod exécute le Controller, qui interroge constamment le point de terminaison/ingresses sur le serveur API de votre cluster pour les mises à jour des ressources d'entrée disponibles. Le service est de type LoadBalancer, et comme vous le déployez sur un cluster DigitalOcean Kubernetes, le cluster créera automatiquement unDigitalOcean Load Balancer, à travers lequel tout le trafic externe sera acheminé vers le contrôleur. Le contrôleur acheminera ensuite le trafic vers les services appropriés, comme défini dans Ingress Resources.

Seul le service LoadBalancer connaît l'adresse IP de l'équilibreur de charge créé automatiquement. Certaines applications (telles queExternalDNS) ont besoin de connaître son adresse IP, mais ne peuvent lire que la configuration d'une entrée. Le contrôleur peut être configuré pour publier l'adresse IP sur chaque entrée en définissant le paramètrecontroller.publishService.enabled surtrue pendanthelm install. Il est recommandé d'activer ce paramètre pour prendre en charge les applications pouvant dépendre de l'adresse IP de Load Balancer.

Pour installer le contrôleur Nginx Ingress Controller sur votre cluster, exécutez la commande suivante:

helm install stable/nginx-ingress --name nginx-ingress --set controller.publishService.enabled=true

Cette commande installe Nginx Ingress Controller à partir du référentiel de graphiquesstable, nomme la version Helmnginx-ingress et définit le paramètrepublishService surtrue.

La sortie ressemblera à:

OutputNAME:   nginx-ingress
LAST DEPLOYED: ...
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME                      DATA  AGE
nginx-ingress-controller  1     0s

==> v1/Pod(related)
NAME                                            READY  STATUS             RESTARTS  AGE
nginx-ingress-controller-7658988787-npv28       0/1    ContainerCreating  0         0s
nginx-ingress-default-backend-7f5d59d759-26xq2  0/1    ContainerCreating  0         0s

==> v1/Service
NAME                           TYPE          CLUSTER-IP     EXTERNAL-IP  PORT(S)                     AGE
nginx-ingress-controller       LoadBalancer  10.245.9.107       80:31305/TCP,443:30519/TCP  0s
nginx-ingress-default-backend  ClusterIP     10.245.221.49         80/TCP                      0s

==> v1/ServiceAccount
NAME           SECRETS  AGE
nginx-ingress  1        0s

==> v1beta1/ClusterRole
NAME           AGE
nginx-ingress  0s

==> v1beta1/ClusterRoleBinding
NAME           AGE
nginx-ingress  0s

==> v1beta1/Deployment
NAME                           READY  UP-TO-DATE  AVAILABLE  AGE
nginx-ingress-controller       0/1    1           0          0s
nginx-ingress-default-backend  0/1    1           0          0s

==> v1beta1/Role
NAME           AGE
nginx-ingress  0s

==> v1beta1/RoleBinding
NAME           AGE
nginx-ingress  0s

NOTES:
...

Helm a consigné les ressources qu'il a créées dans Kubernetes lors de l'installation du diagramme.

Vous pouvez voir l’équilibreur de charge devenir disponible en exécutant:

kubectl get services -o wide -w nginx-ingress-controller

Vous avez installé la Nginx Ingress gérée par la communauté Kubernetes. Il acheminera le trafic HTTP et HTTPS de l'équilibreur de charge vers les services principaux appropriés, configurés dans Ingress Resources. À l'étape suivante, vous exposerez les déploiements de l'applicationhello-kubernetes à l'aide d'une ressource Ingress.

[[step-3 -—- exposing-the-app-using-an-ingress]] == Étape 3 - Exposition de l'application à l'aide d'une entrée

Vous allez maintenant créer une ressource Ingress et l'utiliser pour exposer les déploiements d'applicationshello-kubernetes dans les domaines souhaités. Vous pourrez ensuite le tester en y accédant depuis votre navigateur.

Vous stockerez l'entrée dans un fichier nomméhello-kubernetes-ingress.yaml. Créez-le en utilisant votre éditeur:

nano hello-kubernetes-ingress.yaml

Ajoutez les lignes suivantes à votre fichier:

hello-kubernetes-ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-kubernetes-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: hw1.example.com
    http:
      paths:
      - backend:
          serviceName: hello-kubernetes-first
          servicePort: 80
  - host: hw2.example.com
    http:
      paths:
      - backend:
          serviceName: hello-kubernetes-second
          servicePort: 80

Dans le code ci-dessus, vous définissez une ressource d'entrée avec le nomhello-kubernetes-ingress. Ensuite, vous spécifiez deux règles d'hôte, de sorte quehw1.example.com est acheminé vers le servicehello-kubernetes-first ethw2.example.com est acheminé vers le service à partir du deuxième déploiement (hello-kubernetes-second).

N'oubliez pas de remplacer les domaines en surbrillance par les vôtres, puis enregistrez et fermez le fichier.

Créez-le dans Kubernetes en exécutant la commande suivante:

kubectl create -f hello-kubernetes-ingress.yaml

Ensuite, vous devrez vous assurer que vos deux domaines sont dirigés vers l’équilibreur de charge via les enregistrements A. Cela se fait via votre fournisseur DNS. Pour configurer vos enregistrements DNS sur DigitalOcean, consultezHow to Manage DNS Records.

Vous pouvez maintenant accéder àhw1.example.com dans votre navigateur. Vous verrez ce qui suit:

Hello Kubernetes - First Deployment

La deuxième variante (hw2.example.com) affichera un message différent:

Hello Kubernetes - Second Deployment

Avec cela, vous avez vérifié que Ingress Controller achemine correctement les demandes. dans ce cas, de vos deux domaines vers deux services différents.

Vous avez créé et configuré une ressource Ingress pour servir les déploiements d'applicationshello-kubernetes sur vos domaines. À l’étape suivante, vous allez configurer Cert-Manager afin que vous puissiez sécuriser vos ressources Ingress avec des certificats TLS gratuits de Let’s Encrypt.

[[step-4 -—- secururing-the-ingress-using-cert-manager]] == Étape 4 - Sécurisation de l'entrée à l'aide de Cert-Manager

Pour sécuriser vos ressources Ingress, vous devez installer Cert-Manager, créer un ClusterIssuer pour la production et modifier la configuration de votre Ingress afin de tirer parti des certificats TLS. Les ClusterIssuers sont des ressources Cert-Manager dans Kubernetes qui fournissent des certificats TLS. Une fois installée et configurée, votre application s'exécutera derrière HTTPS.

Avant d'installer Cert-Manager sur votre cluster via Helm, vous appliquerez manuellement lesCRDs (définitions de ressources personnalisées) requises à partir du référentiel jetstack / cert-manager en exécutant la commande suivante:

kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml

Vous verrez la sortie suivante:

Outputcustomresourcedefinition.apiextensions.k8s.io/certificates.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/challenges.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/clusterissuers.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/issuers.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/orders.certmanager.k8s.io created

Cela montre que Kubernetes a appliqué les ressources personnalisées dont vous avez besoin pour cert-manager.

[.Remarque]##

Note: Si vous avez suivi ce didacticiel et les conditions préalables, vous n'avez pas créé d'espace de noms Kubernetes appelécert-manager, vous n'aurez donc pas à exécuter la commande dans ce bloc de notes. Cependant, si cet espace de noms existe sur votre cluster, vous devrez informer Cert-Manager de ne pas le valider avec la commande suivante:

kubectl label namespace cert-manager certmanager.k8s.io/disable-validation="true"

The Webhook component of Cert-Manager nécessite des certificats TLS pour communiquer en toute sécurité avec le serveur d'API Kubernetes. Pour que Cert-Manager génère des certificats pour la première fois, la validation des ressources doit être désactivée sur l'espace de noms dans lequel il est déployé. Sinon, il serait coincé dans une boucle infinie; impossible de contacter l'API et incapable de générer les certificats TLS.

La sortie sera:

Outputnamespace/cert-manager labeled

Ensuite, vous devrez ajouter lesJetstack Helm repository à Helm, qui héberge le graphique Cert-Manager. Pour ce faire, exécutez la commande suivante:

helm repo add jetstack https://charts.jetstack.io

Helm affichera la sortie suivante:

Output"jetstack" has been added to your repositories

Enfin, installez Cert-Manager dans l'espace de nomscert-manager:

helm install --name cert-manager --namespace cert-manager jetstack/cert-manager

Vous verrez la sortie suivante:

OutputNAME:   cert-manager
LAST DEPLOYED: ...
NAMESPACE: cert-manager
STATUS: DEPLOYED

RESOURCES:
==> v1/ClusterRole
NAME                                    AGE
cert-manager-edit                       3s
cert-manager-view                       3s
cert-manager-webhook:webhook-requester  3s

==> v1/Pod(related)
NAME                                     READY  STATUS             RESTARTS  AGE
cert-manager-5d669ffbd8-rb6tr            0/1    ContainerCreating  0         2s
cert-manager-cainjector-79b7fc64f-gqbtz  0/1    ContainerCreating  0         2s
cert-manager-webhook-6484955794-v56lx    0/1    ContainerCreating  0         2s

...

NOTES:
cert-manager has been deployed successfully!

In order to begin issuing certificates, you will need to set up a ClusterIssuer
or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).

More information on the different types of issuers and how to configure them
can be found in our documentation:

https://docs.cert-manager.io/en/latest/reference/issuers.html

For information on how to configure cert-manager to automatically provision
Certificates for Ingress resources, take a look at the `ingress-shim`
documentation:

https://docs.cert-manager.io/en/latest/reference/ingress-shim.html

La sortie montre que l'installation a réussi. Comme indiqué dans lesNOTES dans la sortie, vous devrez configurer un émetteur pour émettre des certificats TLS.

Vous allez maintenant en créer un qui émettra des certificats Let’s Encrypt, et vous stockerez sa configuration dans un fichier nomméproduction_issuer.yaml. Créez-le et ouvrez-le pour édition:

nano production_issuer.yaml

Ajoutez les lignes suivantes:

production_issuer.yaml

apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    # The ACME server URL
    server: https://acme-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: your_email_address
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-prod
    # Enable the HTTP-01 challenge provider
    http01: {}

Cette configuration définit un ClusterIssuer qui contacte Let’s Encrypt pour émettre des certificats. Vous devrez remplaceryour_email_address par votre adresse e-mail afin de recevoir d'éventuels avis urgents concernant la sécurité et l'expiration de vos certificats.

Enregistrez et fermez le fichier.

Déployez-le aveckubectl:

kubectl create -f production_issuer.yaml

Vous verrez la sortie suivante:

Outputclusterissuer.certmanager.k8s.io/letsencrypt-prod created

Avec Cert-Manager installé, vous êtes prêt à introduire les certificats dans la ressource Ingress définie à l’étape précédente. Ouvrezhello-kubernetes-ingress.yaml pour l'édition:

nano hello-kubernetes-ingress.yaml

Ajoutez les lignes en surbrillance:

hello-kubernetes-ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-kubernetes-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - hw1.example.com
    - hw2.example.com
    secretName: letsencrypt-prod
  rules:
  - host: hw1.example.com
    http:
      paths:
      - backend:
          serviceName: hello-kubernetes-first
          servicePort: 80
  - host: hw2.example.com
    http:
      paths:
      - backend:
          serviceName: hello-kubernetes-second
          servicePort: 80

Le bloctls sousspec définit dans quel Secret les certificats de vos sites (listés soushosts) stockeront leurs certificats, que le ClusterIssuerletsencrypt-prod émet. Cela doit être différent pour chaque entrée que vous créez.

N'oubliez pas de remplacer leshw1.example.com ethw2.example.com par vos propres domaines. Lorsque vous avez terminé, enregistrez et fermez le fichier.

Réappliquez cette configuration à votre cluster en exécutant la commande suivante:

kubectl apply -f hello-kubernetes-ingress.yaml

Vous verrez la sortie suivante:

Outputingress.extensions/hello-kubernetes-ingress configured

Vous devrez attendre quelques minutes pour que les serveurs Let’s Encrypt émettent un certificat pour vos domaines. En attendant, vous pouvez suivre sa progression en inspectant le résultat de la commande suivante:

kubectl describe certificate letsencrypt-prod

La fin de la sortie ressemblera à ceci:

OutputEvents:
  Type    Reason              Age   From          Message
  ----    ------              ----  ----          -------
  Normal  Generated           56s   cert-manager  Generated new private key
  Normal  GenerateSelfSigned  56s   cert-manager  Generated temporary self signed certificate
  Normal  OrderCreated        56s   cert-manager  Created Order resource "hello-kubernetes-1197334873"
  Normal  OrderComplete       31s   cert-manager  Order "hello-kubernetes-1197334873" completed successfully
  Normal  CertIssued          31s   cert-manager  Certificate issued successfully

Lorsque votre dernière ligne de sortie litCertificate issued successfully, vous pouvez quitter en appuyant surCTRL + C. Accédez à l'un de vos domaines dans votre navigateur pour le tester. Vous verrez le cadenas à gauche de la barre d'adresse dans votre navigateur, ce qui signifie que votre connexion est sécurisée.

Au cours de cette étape, vous avez installé Cert-Manager à l’aide de Helm et créé un outil Let Encrypt ClusterIssuer. Vous avez ensuite mis à jour votre ressource Ingress afin de tirer parti de l'émetteur pour générer des certificats TLS. En fin de compte, vous avez confirmé que HTTPS fonctionne correctement en accédant à l'un de vos domaines dans votre navigateur.

Conclusion

Vous avez maintenant configuré avec succès Nginx Ingress Controller et Cert-Manager sur votre cluster DigitalOcean Kubernetes à l'aide de Helm. Vous pouvez maintenant exposer vos applications sur Internet, dans vos domaines, en toute sécurité, à l’aide des certificats Let’S Encrypt TLS.

Pour plus d'informations sur le gestionnaire de packages Helm, lisez ceciintroduction article.