Kékéli Sergio Afanou
Kékéli Sergio Afanou
A cloud passionate. Father, Son, brother and most of all: a Jesus lover!

Déployer une application Django évolutive et sécurisée avec Kubernetes

Déployer une application Django évolutive et sécurisée avec Kubernetes

Introduction

Dans ce tutoriel, nous allons déployer une application de sondages Django conteneurisée sur un cluster Kubernetes.

Django est un framework Web puissant qui vous permet de déployer rapidement votre application Python à partir de zéro. Il comprend un certain nombre de fonctionnalités pratiques, notamment object relational map, l’authentification des utilisateurs et une interface d’administration personnalisable pour votre application. Il comprend également un système de cache et aide à concevoir des applications optimisées avec un gestionnaire d’URL et template systems.

Dans le tutoriel Building a Django and Gunicorn Application with Docker nous avons changé Application de sondages du tutoriel Django selon la méthodologie Twelve Factors pour la construction d’un web évolutif - applications optimisées pour le cloud. Le conteneur a été mis à l’échelle et sécurisé à l’aide d’un proxy inverse Nginx et d’un certificat TLS signé Let’s Encrypt (décrit dans le module du didacticiel Scaling and secure a Django application with Docker, Nginx, and Let’s Encrypt). Dans ce dernier tutoriel de la série De conteneurs à Kubernetes avec Django, nous allons vous montrer comment déployer une application Django modernisée polls sur le cluster Kubernetes.

Kubernetes est un puissant système d’orchestration de conteneurs open source qui permet d’automatiser le déploiement, la mise à l’échelle et la gestion des applications conteneurisées. Les objets Kubernetes tels que ConfigMaps et Secrets vous permettent de centraliser la configuration et de la détacher des conteneurs, tandis que les contrôleurs tels que Deployments rechargent automatiquement les conteneurs inactifs et vous permettent de mettre rapidement à l’échelle les répliques de conteneurs. Le chiffrement TLS est activé à l’aide de l’objet Ingress et du contrôleur open source ingress-nginx. Le module complémentaire Kubernetes cert-manager valide et émet des certificats à l’aide de l’autorité de certification gratuite Let’s Encrypt.

Pré requis

Pour ce tutoriel, vous aurez besoin des éléments suivants :

  • Cluster Kubernetes version 1.15 ou ultérieure avec contrôle d’accès basé sur les rôles (RBAC) activé. Notre exemple utilisera un cluster DigitalOcean Kubernetes, mais vous pouvez créer un cluster en utilisant une autre méthode.
  • L’outil de ligne de commande kubectl installé sur votre machine locale et configuré pour se connecter à votre cluster. Vous trouverez plus d’informations sur l’installation de kubectl dans la documentation officielle. Si vous utilisez un cluster DigitalOcean Kubernetes, veuillez vous référer au guide Connexion à un cluster DigitalOcean Kubernetes pour apprendre comment se connecter au cluster avec kubectl.
  • Nom de domaine enregistré. Dans ce tutoriel, nous utiliserons le nom votre_domaine.com. Vous pouvez obtenir un domaine gratuit auprès de Freenom ou enregistrer un nom de domaine de votre choix.
  • Le contrôleur ingress-nginx et le gestionnaire de certificats TLS cert-manager doivent être installés dans votre cluster et configuré pour utiliser des certificats TLS. Pour savoir comment installer et configurer Ingress à l’aide de cert-manager, consultez le guide [Configuring Nginx Ingress with Cert-Manager on a DigitalOcean Kubernetes Cluster] (https://www.digitalocean.com/community/tutorials/how-to-set -up-an-nginx-ingress-with-cert-manager-on-digitalocean-kubernetes).
  • Enregistrement DNS “A” pour “votre_domaine.com” pointant vers l’adresse IP publique de l’équilibreur de charge Ingress. Si vous utilisez DigitalOcean pour gérer les enregistrements DNS de votre domaine, le guide [Gestion des enregistrements DNS] (https://www.digitalocean.com/docs/networking/dns/how-to/manage-records/) vous aidera à apprendre comment pour créer des ‘enregistrements de classe A’.
  • Un magasin d’objets S3, tel que l’espace DigitalOcean, pour stocker les fichiers statiques du projet Django et un ensemble de clés pour accéder à cet espace. Pour savoir comment créer un espace, consultez le document Comment créer des espaces. Pour savoir comment créer des clés d’accès, consultez l’article Partager l’accès à l’espace avec des clés d’accès (https://www.digitalocean.com/docs/spaces/how-to/administrative-access/#access-keys). Avec des modifications mineures, vous pouvez utiliser n’importe quel service de stockage pris en charge par le plug-in django-storages.
  • Instance de serveur PostgreSQL, base de données et utilisateur pour l’application Django. Avec des modifications mineures, vous pouvez utiliser n’importe quelle base de données supportée par Django.
    • La base de données PostgreSQL doit être nommée polls (vous pouvez utiliser n’importe quel autre nom mémorable à entrer dans les fichiers de configuration ci-dessous). Ce tutoriel utilisera sammy comme nom d’utilisateur de la base de données Django. Pour obtenir des instructions sur la façon de procéder, consultez l’étape 1 de Construire une application Django et Gunicorn avec Docker. Ces étapes doivent être effectuées sur l’ordinateur local.
    • Ce tutoriel utilise Managed PostgreSQL Cluster de DigitalOcean. Pour savoir comment créer un cluster, consultez la documentation de la base de données gérée par DigitalOcean.
    • Vous pouvez également installer et exécuter votre propre instance PostgreSQL. Pour obtenir des instructions sur l’installation et l’administration de PostgreSQL sur un serveur Ubuntu, consultez le guide [Installation et utilisation de PostgreSQL sur Ubuntu 18.04] (https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql -sur -ubuntu-18-04).
  • Compte Docker Hub et référentiel public. Vous trouverez plus d’informations sur leur création dans la section Référentiels de la documentation Docker.
  • Système Docker installé sur la machine locale. Pour plus d’informations, consultez le guide [Installation et utilisation de Docker sur Ubuntu 18.04] (https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker

Étape 1 - Clonage et configuration de l’application

Dans cette étape, nous allons cloner le code de l’application à partir de GitHub et configurer des paramètres tels que les informations d’identification de la base de données et les clés de stockage d’objets.

Le code de l’application et le Dockerfile se trouvent dans la branche “polls-docker” du [dépôt GitHub de l’application Django Tutorial Polls] (https://github.com/do-community/django-polls/tree/polls-docker). Ce référentiel contient le code de l’application Polls utilisé comme exemple dans la documentation de Django, qui montre comment créer une application de sondage à partir de rien.

La branche polls-docker contient la version hébergée par Docker de l’application Polls. Pour plus d’informations sur les modifications apportées à l’application Polls pour fonctionner efficacement dans un environnement conteneurisé, consultez le guide [Building a Django and Gunicorn Application with Docker] (https://www.digitalocean.com/community/tutorials/how-to - construire-une-application-django-et-gunicorn-avec-docker).

Tout d’abord, utilisez git pour cloner la branche polls-docker de la branche Django Tutorial Polls App GitHub repository sur votre machine locale :

git clone --single-branch --branch polls-docker https://github.com/do-community/django-polls.git

Accédez au répertoire django-polls :

cd django-polls

Ce répertoire contient le code Python de l’application Django, un Dockerfile que Docker utilisera pour construire l’image du conteneur et un fichier env contenant une liste de variables d’environnement à transmettre à l’environnement d’exécution du conteneur. Vérifiez le Dockerfile :

cat Dockerfile


OutputFROM python:3.7.4-alpine3.10

ADD django-polls/requirements.txt /app/requirements.txt

RUN set -ex \
    && apk add --no-cache --virtual .build-deps postgresql-dev build-base \
    && python -m venv /env \
    && /env/bin/pip install --upgrade pip \
    && /env/bin/pip install --no-cache-dir -r /app/requirements.txt \
    && runDeps="$(scanelf --needed --nobanner --recursive /env \
        | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
        | sort -u \
        | xargs -r apk info --installed \
        | sort -u)" \
    && apk add --virtual rundeps $runDeps \
    && apk del .build-deps

ADD django-polls /app
WORKDIR /app

ENV VIRTUAL_ENV /env
ENV PATH /env/bin:$PATH

EXPOSE 8000

CMD ["gunicorn", "--bind", ":8000", "--workers", "3", "mysite.wsgi"]

Le Dockerfile est basé sur l’image Docker Python 3.7.4, qui installe les packages Python requis pour Django et Gunicorn conformément aux exigences de django-polls/. txt. Il supprime ensuite certains fichiers de construction inutiles, copie le code de l’application dans l’image et définit l’option d’exécution PATH. Déclare enfin que le port 8000 sera utilisé pour accepter les connexions de conteneur entrantes et démarre gunicorn avec trois éléments de travail écoutant sur le port 8000.

Pour plus d’informations sur chaque étape du Dockerfile, consultez l’étape 6 de Building a Django and Gunicorn Application with Docker.

Construisez maintenant l’image avec docker build :

docker build -t polls .

Nommons l’image polls en utilisant le drapeau -t et passons dans le répertoire courant comme contexte de construction un ensemble de fichiers pour référence lors de la construction de l’image.

Une fois que Docker a créé et balisé l’image, répertoriez les images disponibles à l’aide de docker images :

docker images

Vous devriez voir l’image polls :

OutputREPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
polls               latest              80ec4f33aae1        2 weeks ago         197MB
python              3.7.4-alpine3.10    f309434dea3a        8 months ago        98.7MB

Avant de démarrer un conteneur Django, nous devons configurer son environnement à l’aide du fichier env présent dans le répertoire courant. Ce fichier est transmis à la commande docker run, qui est utilisée pour démarrer le conteneur, après quoi Docker injectera les variables d’environnement configurées dans l’environnement d’exécution du conteneur.

Ouvrez le fichier env avec nano ou votre éditeur préféré :

nano env

django-polls/env

DJANGO_SECRET_KEY=
DEBUG=True
DJANGO_ALLOWED_HOSTS=
DATABASE_ENGINE=postgresql_psycopg2
DATABASE_NAME=polls
DATABASE_USERNAME=
DATABASE_PASSWORD=
DATABASE_HOST=
DATABASE_PORT=
STATIC_ACCESS_KEY_ID=
STATIC_SECRET_KEY=
STATIC_BUCKET_NAME=
STATIC_ENDPOINT_URL=
DJANGO_LOGLEVEL=info

Remplissez les valeurs manquantes pour les clés suivantes :

  • DJANGO_SECRET_KEY : spécifie une valeur unique et imprévisible, comme décrit dans la documentation Django. Une méthode pour générer cette clé est présentée dans la section Changing Application Settings du guide Django Scalable App.
  • DJANGO_ALLOWED_HOSTS : Cette variable sécurise l’application et empêche les attaques via les en-têtes d’hôte HTTP. À des fins de test, définissez * comme caractère générique correspondant à tous les hôtes. Dans un environnement de production, la valeur “votre_domaine.com” doit être utilisée. Pour plus d’informations sur ce paramètre Django, consultez la section Core Settings de la documentation Django.
  • DATABASE_USERNAME : spécifie l’utilisateur de la base de données PostgreSQL créé lors des étapes préliminaires.
  • DATABASE_NAME : spécifie polls ou le nom de la base de données créée lors des étapes préliminaires.
  • DATABASE_PASSWORD : définit le mot de passe de l’utilisateur de la base de données PostgreSQL créé lors des étapes préliminaires.
  • DATABASE_HOST : spécifie le nom d’hôte de la base de données.
  • DATABASE_PORT : spécifiez le port de votre base de données.
  • STATIC_ACCESS_KEY_ID : Spécifiez la clé d’accès de votre espace ou magasin d’objets.
  • STATIC_SECRET_KEY : Spécifiez la clé secrète de votre espace ou de votre magasin d’objets.
  • STATIC_BUCKET_NAME : spécifiez le nom de votre compartiment de magasin d’espace ou d’objets.
  • STATIC_ENDPOINT_URL : spécifiez l’URL de l’espace correspondant ou du point de terminaison du magasin d’objets, tel que https://your_space_name.nyc3.digitaloceanspaces.com si votre espace se trouve dans la zone nyc3.

Une fois l’édition terminée, enregistrez et fermez le fichier.

Dans l’étape suivante, nous exécuterons le conteneur configuré sur site et créerons le schéma de base de données. Nous vérifierons également les ressources statiques telles que les feuilles de style et les images dans le magasin d’objets.

Étape 2 - Création du schéma de base de données et téléchargement des ressources dans le magasin d’objets

Après avoir construit et configuré le conteneur, utilisez docker run pour remplacer la commande CMD donnée dans le Dockerfile et créez le schéma de base de données à l’aide des commandes manage.py makemigrations et manage.py migrate :

docker run --env-file env polls sh -c "python manage.py makemigrations && python manage.py migrate"

Nous exécutons l’image de conteneur polls:latest, transmettons la variable d’environnement que nous venons de modifier et remplaçons la commande Dockerfile par sh -c "python manage.py makemigrations && python manage.py migrate" qui créera le schéma de la base de données défini par le code d’application.

Si vous exécutez ces commandes pour la première fois, vous devriez voir ce qui suit :

OutputNo changes detected
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying polls.0001_initial... OK
  Applying sessions.0001_initial... OK

Cela signifie que le schéma de base de données a été créé avec succès.

La prochaine fois que vous exécuterez la commande migrate, Django n’effectuera aucune opération à moins que le schéma de la base de données ait changé.

Nous allons ensuite démarrer une autre instance de conteneur d’application et utiliser un shell interactif à l’intérieur pour créer un utilisateur administratif pour le projet Django.

docker run -i -t --env-file env polls sh

Vous obtiendrez une chaîne shell dans un conteneur en cours d’exécution que vous pourrez utiliser pour créer un utilisateur Django :

python manage.py createsuperuser

Entrez le nom d’utilisateur, l’adresse e-mail et le mot de passe de l’utilisateur, et après avoir créé l’utilisateur, appuyez sur CTRL + D pour quitter le conteneur et le supprimer.

Enfin, nous allons créer les fichiers statiques de l’application et les charger dans l’espace DigitalOcean à l’aide de collectstatic. Veuillez noter que le processus peut prendre du temps.

docker run --env-file env polls sh -c "python manage.py collectstatic --noinput"

Après avoir créé et téléchargé les fichiers, vous obtiendrez la sortie suivante.

Output121 static files copied.

Maintenant, nous pouvons exécuter l’application :

docker run --env-file env -p 80:8000 polls


Output[2019-10-17 21:23:36 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2019-10-17 21:23:36 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
[2019-10-17 21:23:36 +0000] [1] [INFO] Using worker: sync
[2019-10-17 21:23:36 +0000] [7] [INFO] Booting worker with pid: 7
[2019-10-17 21:23:36 +0000] [8] [INFO] Booting worker with pid: 8
[2019-10-17 21:23:36 +0000] [9] [INFO] Booting worker with pid: 9

Nous allons exécuter la commande par défaut définie dans le Dockerfile gunicorn --bind :8000 --workers 3 mysite.wsgi:application et ouvrir le port de conteneur 8000 pour faire correspondre le port 80 sur la machine locale avec le port 8000 du conteneur ` sondages`.

Vous devriez maintenant pouvoir ouvrir l’application polls dans votre navigateur en tapant http://localhost dans la barre d’adresse. Étant donné que l’itinéraire pour le chemin / n’est pas défini, vous obtiendrez très probablement une erreur 404 Page Not Found.

Entrez http://localhost/polls dans la barre d’adresse pour voir l’interface de l’application Polls :

Интерфейс приложения «Опросы»

Pour ouvrir l’interface d’administration, entrez l’adresse http://localhost/admin. Vous devriez voir la fenêtre d’authentification de l’administrateur de l’application Polls :

Страница аутентификации администратора приложения

Entrez le nom d’utilisateur et le mot de passe de l’administrateur que vous avez créés avec la commande createsuperuser.

Une fois authentifié, vous pourrez accéder à l’interface d’administration de l’application Polls :

Основной интерфейс администратора приложения

Notez que les actifs statiques de l’application admin et polls proviennent directement du magasin d’objets. Consultez le Testing Space Static File Delivery.

Une fois que vous avez terminé d’explorer les données, appuyez sur CTRL + C dans la fenêtre du terminal où le conteneur Docker est en cours d’exécution pour supprimer le conteneur.

Une fois que l’image Docker de l’application Django a été testée, les actifs statiques seront récupérés dans le magasin d’objets et le schéma de la base de données sera configuré et prêt à pousser l’image de l’application Django vers un registre d’images tel que Docker Hub.

Étape 3 - Hébergement de l’image de l’application Django sur Docker Hub

Pour déployer une application sur Kubernetes, vous devez télécharger l’image de l’application dans un registre tel que Docker Hub. Kubernetes extrait l’image de l’application du référentiel, puis la déploie sur le cluster.

Vous pouvez utiliser un registre Docker privé, tel que le DigitalOcean Container Registry, qui est actuellement en préversion gratuite, ou un registre Docker public tel que comme Docker Hub. Docker Hub vous permet également de créer des référentiels Docker privés. Le référentiel public permet à quiconque de voir et d’extraire des images de conteneur, tandis que le référentiel privé n’autorise l’accès qu’à vous et aux membres de votre équipe.

Dans ce didacticiel, nous allons déployer l’image Django dans le référentiel public Docker Hub que nous avons créé à l’étape des prérequis. Vous pouvez également transférer une image vers un référentiel privé, mais l’extraction d’images à partir d’un référentiel privé n’est pas abordée dans cet article. Pour plus d’informations sur l’authentification Kubernetes avec Docker Hub et l’extraction d’images à partir d’un référentiel privé, consultez Extraire une image d’un registre privé (Récupération d’une image à partir d’un registre privé) dans la documentation de Kubernetes.

Pour commencer, connectez-vous à Docker Hub sur votre ordinateur local :

docker login


OutputLogin with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username:

Entrez votre nom d’utilisateur et votre mot de passe Docker Hub pour vous connecter.

L’image Django est maintenant taguée avec polls:latest. Pour le transférer vers votre référentiel Docker Hub, modifiez les balises d’image pour inclure votre nom d’utilisateur Docker Hub et le nom du référentiel :

docker tag polls:latest your_dockerhub_username/your_dockerhub_repo_name:latest

Placez l’image dans le dépôt :

docker push sammy/sammy-django:latest

Dans ce didacticiel, nous utilisons le nom d’utilisateur Docker Hub sammy et le nom du référentiel sammy-django. Vous devez remplacer ces valeurs par votre nom d’utilisateur Docker Hub et le nom du référentiel.

Lorsque vous déployez des couches d’images sur Docker Hub, vous verrez certains messages à l’écran.

Votre image est maintenant disponible pour Kubernetes dans le référentiel Docker Hub et vous pouvez commencer à la déployer sur votre cluster.

Étape 4 - Configuration de la ConfigMap

Lors de l’exécution locale du conteneur Django, nous avons transmis le fichier env à docker run pour injecter des variables de configuration dans le runtime. Pour insérer des variables de configuration dans Kubernetes, les ConfigMap et Secret.

Les éléments ConfigMap doivent être utilisés pour stocker des informations de configuration non sensibles telles que les paramètres d’application, et les éléments Secret doivent être utilisés pour stocker des informations sensibles telles que les clés API et les identifiants de connexion à la base de données. Ils sont insérés dans des conteneurs de la même manière, mais les éléments secrets ont des fonctionnalités de contrôle d’accès et de sécurité supplémentaires telles que chiffrement au repos . Les éléments secrets stockent les données au format base64, tandis que les éléments ConfigMap stockent les données au format texte brut.

Nous devons d’abord créer un répertoire yaml où nous stockerons nos manifestes Kubernetes. Allez dans le répertoire.

mkdir yaml
cd

Ouvrez le fichier polls-configmap.yaml dans nano ou votre éditeur de texte préféré :

nano polls-configmap.yaml

Collez-y le ConfigMap suivant :

polls-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: polls-config
data:
  DJANGO_ALLOWED_HOSTS: "*"
  STATIC_ENDPOINT_URL: "https://your_space_name.space_region.digitaloceanspaces.com"
  STATIC_BUCKET_NAME: "your_space_name"
  DJANGO_LOGLEVEL: "info"
  DEBUG: "True"
  DATABASE_ENGINE: "postgresql_psycopg2"

Nous avons extrait les données de configuration non confidentielles du fichier env modifié à l’étape 1 et les a transmis au manifeste ConfigMap. L’objet ConfigMap est nommé polls-config. Copiez les mêmes valeurs saisies dans le fichier “env” à l’étape précédente.

Pour les tests, laissez DJANGO_ALLOWED_HOSTS défini sur * pour désactiver le filtrage basé sur les en-têtes d’hôte. Dans un environnement de production, il doit s’agir de votre domaine d’application.

Lorsque vous avez terminé de modifier le fichier, enregistrez-le et fermez-le.

Créez un élément ConfigMap dans votre cluster à l’aide de kubectl apply :

kubectl apply -f polls-configmap.yaml


Outputconfigmap/polls-config created

Nous avons créé un élément ConfigMap et à l’étape suivante, nous allons créer un élément Secret qui sera utilisé par notre application.

Étape 5 - Personnalisation de l’élément secret

Les valeurs secrètes doivent être encodées en base64, ce qui signifie que la création d’objets secrets dans un cluster est légèrement plus difficile que la création d’objets ConfigMaps. Vous pouvez répéter la procédure décrite à l’étape précédente en encodant manuellement en base64 les valeurs secrètes et en les collant dans le fichier manifeste. Vous pouvez également les créer en utilisant un fichier de variable d’environnement, kubectl create et le drapeau --from-env-file, ce que nous ferons dans cette étape.

Nous utilisons à nouveau le fichier env de étape 1 en supprimant les variables insérées dans le ConfigMap. Faites une copie du fichier env nommé polls-secrets dans le répertoire yaml :

cp ../env ./polls-secrets

Modifiez le fichier avec votre éditeur préféré :

nano polls-secrets

polls-secrets

DJANGO_SECRET_KEY=
DEBUG=True
DJANGO_ALLOWED_HOSTS=
DATABASE_ENGINE=postgresql_psycopg2
DATABASE_NAME=polls
DATABASE_USERNAME=
DATABASE_PASSWORD=
DATABASE_HOST=
DATABASE_PORT=
STATIC_ACCESS_KEY_ID=
STATIC_SECRET_KEY=
STATIC_BUCKET_NAME=
STATIC_ENDPOINT_URL=
DJANGO_LOGLEVEL=info

Supprimez toutes les variables insérées dans le manifeste ConfigMap. Lorsque vous avez terminé, le contenu du fichier devrait ressembler à ceci :

polls-secrets

DJANGO_SECRET_KEY=your_secret_key
DATABASE_NAME=polls
DATABASE_USERNAME=your_django_db_user
DATABASE_PASSWORD=your_django_db_user_password
DATABASE_HOST=your_db_host
DATABASE_PORT=your_db_port
STATIC_ACCESS_KEY_ID=your_space_access_key
STATIC_SECRET_KEY=your_space_access_key_secret

Assurez-vous d’utiliser les mêmes valeurs qu’à l’Étape 1. Lorsque vous avez terminé, enregistrez et fermez le fichier.

Créez un objet secret sur le cluster à l’aide de kubectl create secret :

kubectl create secret generic polls-secret --from-env-file=poll-secrets


Outputsecret/polls-secret created

Ici, nous allons créer un objet secret nommé polls-secret et transmettre le fichier secrets que nous avons créé.

Vous pouvez inspecter l’objet secret à l’aide de kubectl describe :

kubectl describe secret polls-secret


OutputName:         polls-secret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
DATABASE_PASSWORD:     8 bytes
DATABASE_PORT:         5 bytes
DATABASE_USERNAME:     5 bytes
DJANGO_SECRET_KEY:     14 bytes
STATIC_ACCESS_KEY_ID:  20 bytes
STATIC_SECRET_KEY:     43 bytes
DATABASE_HOST:         47 bytes
DATABASE_NAME:         5 bytes

Nous avons stocké la configuration de votre application dans le cluster Kubernetes à l’aide des types d’objet Secret et ConfigMap. Nous sommes prêts à déployer l’application sur le cluster.

Étape 6 - Déploiement d’une application Django avec un contrôleur de déploiement

Dans cette étape, nous allons créer un déploiement pour votre application Django. Kubernetes Deployment est un controller que vous pouvez utiliser pour gérer des applications sans état dans votre cluster. Le contrôleur est une boucle de contrôle qui régule les tâches de travail grâce à une mise à l’échelle verticale. Les contrôleurs redémarrent et nettoient également les conteneurs défaillants.

Les contrôleurs de déploiement contrôlent un ou plusieurs pods. Un pod est la plus petite unité déployable dans un cluster Kubernetes. Les pods contiennent un ou plusieurs conteneurs. Pour en savoir plus sur les différents types de charges de travail, consultez le didacticiel Introduction à Kubernetes.

Commencez par ouvrir le fichier polls-deployment.yaml avec votre éditeur de texte préféré :

nano polls-deployment.yaml

Collez-y le manifeste de déploiement suivant :

polls-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: polls-app
  labels:
    app: polls
spec:
    replicas: 2
  selector:
    matchLabels:
      app: polls
  template:
    metadata:
      labels:
        app: polls
    spec:
      containers:
        - image: your_dockerhub_username/app_repo_name:latest
          name: polls
          envFrom:
          - secretRef:
              name: polls-secret
          - configMapRef:
              name: polls-config
          ports:
            - containerPort: 8000
              name: gunicorn

Saisissez le nom d’image de conteneur approprié, en vous référant à l’image Django Polls que vous avez hébergée sur Docker Hub à l’étape 2.

Ici, nous définissons un contrôleur de déploiement Kubernetes nommé polls-app et lui attribuons une paire clé-valeur app: polls. Nous indiquons que nous souhaitons exécuter deux répliques du pod défini dans le champ template.

En utilisant envFrom avec secretRef et configMapRef, nous spécifions que toutes les données des objets polls-secret et polls-config doivent être injectées dans des conteneurs en tant que variables d’environnement. Les clés ConfigMap et Secret deviennent des noms de variables d’environnement.

Enfin, nous allons ouvrir le containerPort 8000 et le nommer gunicorn.

Pour en savoir plus sur la configuration des contrôleurs de déploiement Kubernetes, consultez la section Déploiements de la documentation Kubernetes.

Lorsque vous avez terminé de modifier le fichier, enregistrez-le et fermez-le.

Créez un contrôleur de déploiement sur le cluster à l’aide de kubectl apply -f :

kubectl apply -f polls-deployment.yaml


deployment.apps/polls-app created

Vérifiez que le contrôleur de déploiement est correctement déployé à l’aide de kubectl get :

kubectl get deploy polls-app


OutputNAME        READY   UP-TO-DATE   AVAILABLE   AGE
polls-app   2/2     2            2           6m38s

Si vous rencontrez une erreur ou si quelque chose ne fonctionne pas, vous pouvez utiliser kubectl describe pour tester un contrôleur de déploiement défectueux :

kubectl describe deploy

Pour inspecter deux pods, utilisez kubectl get pod :

kubectl get pod


OutputNAME                         READY   STATUS    RESTARTS   AGE
polls-app-847f8ccbf4-2stf7   1/1     Running   0          6m42s
polls-app-847f8ccbf4-tqpwm   1/1     Running   0          6m57s

Les clusters ont deux répliques de votre application Django en cours d’exécution. Pour accéder à l’application, vous devez créer un service Kubernetes, et nous le ferons à l’étape suivante.

Étape 7 - Fournir un accès externe à l’aide d’un service

Dans cette étape, nous créons un service pour notre application Django. Le service Kubernetes est une abstraction qui vous permet d’exposer un ensemble de pods en cours d’exécution en tant que service réseau. En utilisant un service, vous pouvez créer un point de terminaison stable pour votre application qui ne change pas lorsque les pods sont détruits et recréés.

Il existe plusieurs types de service, notamment ClusterIP, qui expose un service via l’adresse IP interne du cluster, NodePorts, qui expose un service sur chaque nœud d’un NodePort statique, et LoadBalancer, qui fournit un équilibreur de charge basé sur le cloud pour gérer les le trafic des Pods de votre cluster (via les NodePorts qu’il crée automatiquement). Pour en savoir plus à ce sujet, consultez la section Service de la documentation Kubernetes.

Dans l’étape de configuration finale, nous utilisons le service ClusterIP, accessible via Ingress et le contrôleur Ingress configuré en préparation de ce didacticiel. Nous allons maintenant nous assurer que tous les éléments fonctionnent correctement. Pour ce faire, nous allons créer un service NodePort temporaire pour accéder à l’application Django.

Tout d’abord, créez un fichier appelé polls-svc.yaml dans votre éditeur préféré :

nano polls-svc.yaml

Collez-y le manifeste de service suivant :

polls-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: polls
  labels:
    app: polls
spec:
  type: NodePort
  selector:
    app: polls
  ports:
    - port: 8000
      targetPort: 8000

Ici, nous créons un service NodePort appelé polls et lui donnons le label app:polls. Nous allons sélectionner les pods backend étiquetés “app: polls” et définir les ports sur “8000” comme cibles.

Lorsque vous avez terminé de modifier le fichier, enregistrez-le et fermez-le.

Déployez le service à l’aide de la commande “kubectl apply” :

kubectl apply -f polls-svc.yaml


Outputservice/polls created

Vérifiez que le service a été créé à l’aide de kubectl get svc :

kubectl get svc polls


OutputNAME    TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
polls   NodePort   10.245.197.189   <none>        8000:32654/TCP   59s

Cette sortie affiche l’adresse IP interne du cluster de service et le numéro NodePort (‘32654’). Afin de se connecter au service, nous aurons besoin d’une adresse IP externe pour notre nœud de cluster :

kubectl get node -o wide


OutputNAME                   STATUS   ROLES    AGE   VERSION   INTERNAL-IP   EXTERNAL-IP      OS-IMAGE                       KERNEL-VERSION          CONTAINER-RUNTIME
pool-7no0qd9e0-364fd   Ready    <none>   27h   v1.18.8   10.118.0.5    203.0.113.1   Debian GNU/Linux 10 (buster)   4.19.0-10-cloud-amd64   docker://18.9.9
pool-7no0qd9e0-364fi   Ready    <none>   27h   v1.18.8   10.118.0.4    203.0.113.2    Debian GNU/Linux 10 (buster)   4.19.0-10-cloud-amd64   docker://18.9.9
pool-7no0qd9e0-364fv   Ready    <none>   27h   v1.18.8   10.118.0.3    203.0.113.3   Debian GNU/Linux 10 (buster)   4.19.0-10-cloud-amd64   docker://18.9.9

Ouvrez l’application Polls dans un navigateur en utilisant l’adresse IP externe et le NodePort de n’importe quel nœud. Compte tenu de la sortie ci-dessus, l’URL de l’application serait http://203.0.113.1:32654/polls.

Vous devriez voir la même interface d’application Polls que celle que vous avez ouverte localement à l’étape 1 :

Интерфейс приложения «Опросы»

Vous pouvez répéter la même vérification en utilisant la route /admin : http://203.0.113.1:32654/admin. Vous retrouverez la même interface d’administration qu’avant :

Страница аутентификации администратора приложения

Nous avons déployé deux répliques du conteneur d’application Django Polls à l’aide de Deployment. Nous avons également créé un point de terminaison réseau stable pour ces deux réplicas et les avons rendus accessibles en externe via le service NodePort.

La dernière étape de ce didacticiel consiste à sécuriser le trafic externe de notre application à l’aide de HTTPS. Pour ce faire, nous utilisons le contrôleur ingress-nginx installé à l’étape des prérequis et créons un objet Ingress pour rediriger le trafic externe vers le service polls de Kubernetes.

Étape 8 - Configuration de HTTPS à l’aide de Nginx Ingress et de cert-manager

Les entités Ingress dans Kubernetes fournissent un routage flexible du trafic externe du cluster Kubernetes entre les services au sein du cluster. Ceci est réalisé via les ressources Ingress, qui définissent les règles de routage du trafic HTTP et HTTPS pour les services Kubernetes, et Ingress _Controllers, qui implémentent les règles en équilibrant la charge du trafic et en le transmettant aux services backend appropriés.

Dans l’étape des prérequis, nous avons installé le contrôleur [ingress-nginx] (https://github.com/kubernetes/ingress-nginx) et le module complémentaire [cert-manager] (https://github.com/jetstack/ cert-manager) à l’automatisation des certificats TLS. Nous avons également configuré un environnement de test et de production ClusterIssuers pour votre domaine à l’aide d’une autorité de certification Let’s Encrypt et créé un objet Ingress pour vérifier l’émission de certificats et le chiffrement TLS pour deux services backend factices. Avant de poursuivre cette étape, supprimez l’objet echo-ingress créé dans le tutoriel préparatoire:

kubectl delete ingress echo-ingress

En option, vous pouvez également supprimer des services et des déploiements factices à l’aide des commandes kubectl delete svc et kubectl delete deploy, mais cela n’est pas requis pour ce didacticiel.

Vous deviez également créer un enregistrement DNS “A” pour “votre_domaine.com” pointant vers l’adresse IP publique de l’équilibreur de charge Ingress. Si vous utilisez un équilibreur de charge DigitalOcean, vous pouvez trouver cette adresse IP dans la section Load Balancers de votre panneau de contrôle. Si vous utilisez également DigitalOcean pour gérer les enregistrements DNS de votre domaine, le guide DNS Records Management vous aidera à apprendre comment créer des enregistrements de classe ‘A’.

Si vous utilisez DigitalOcean Kubernetes, assurez-vous d’avoir implémenté la solution de contournement décrite dans Étape 5 du didacticiel Configuration de Nginx Ingress avec Cert-Manager dans DigitalOcean Kubernetes.

Une fois que vous avez un enregistrement “A” pointant vers l’équilibreur de charge du contrôleur Ingress, vous pouvez créer un Ingress pour “votre_domaine.com” et le service “polls”.

Ouvrez le fichier nommé “polls-ingress.yaml” dans votre éditeur de texte préféré :

nano polls-ingress.yaml

Collez le fichier manifeste Ingress suivant :

[polls-ingress.yaml]
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: polls-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-staging"
spec:
  tls:
  - hosts:
    - your_domain.com
    secretName: polls-tls
  rules:
  - host: your_domain.com
    http:
      paths:
      - backend:
          serviceName: polls
          servicePort: 8000

Nous créons un objet Ingress appelé “polls-ingress” et l’annotons de sorte que le plan de contrôle utilise le contrôleur ingress-nginx et héberge le ClusterIssuer. Nous activons également TLS pour le domaine votre_domaine.com et stockons le certificat et la clé privée dans un objet secret nommé polls-tls. Enfin, nous définissons une règle de redirection du trafic pour l’hôte votre_domaine.com vers le service polls sur le port 8000.

Lorsque vous avez terminé de modifier le fichier, enregistrez-le et fermez-le.

Créez un objet Ingress sur le cluster à l’aide de kubectl apply :

kubectl apply -f polls-ingress.yaml


Outputingress.networking.k8s.io/polls-ingress created

Vous pouvez utiliser kubectl describe pour suivre l’état de l’objet Ingress nouvellement créé :

kubectl describe ingress polls-ingress


OutputName:             polls-ingress
Namespace:        default
Address:          workaround.your_domain.com
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
  polls-tls terminates your_domain.com
Rules:
  Host        Path  Backends
  ----        ----  --------
  your_domain.com
                 polls:8000 (10.244.0.207:8000,10.244.0.53:8000)
Annotations:  cert-manager.io/cluster-issuer: letsencrypt-staging
              kubernetes.io/ingress.class: nginx
Events:
  Type    Reason             Age   From                      Message
  ----    ------             ----  ----                      -------
  Normal  CREATE             51s   nginx-ingress-controller  Ingress default/polls-ingress
  Normal  CreateCertificate  51s   cert-manager              Successfully created Certificate "polls-tls"
  Normal  UPDATE             25s   nginx-ingress-controller  Ingress default/polls-ingress

Vous pouvez également exécuter la commande describe sur le certificat polls-tls pour vérifier qu’il a été créé avec succès :

kubectl describe certificate polls-tls


Output. . .
Events:
  Type    Reason     Age    From          Message
  ----    ------     ----   ----          -------
  Normal  Issuing    3m33s  cert-manager  Issuing certificate as Secret does not exist
  Normal  Generated  3m32s  cert-manager  Stored new private key in temporary Secret resource "polls-tls-v9lv9"
  Normal  Requested  3m32s  cert-manager  Created new CertificateRequest resource "polls-tls-drx9c"
  Normal  Issuing    2m58s  cert-manager  The certificate has been successfully issued

Cela confirme que le certificat TLS a été émis avec succès et que le cryptage HTTPS pour le domaine “votre_domaine.com” est actif.

Parce que nous utilisions une version de test de ClusterIssuer, la plupart des navigateurs ne feront pas confiance au faux certificat Let’s Encrypt qu’il émet, et donc une page d’erreur apparaîtra lorsque vous naviguez vers votre_domaine.com.

Pour envoyer une requête de test, nous utilisons wget depuis la ligne de commande :

wget -O - http://your_domain.com/polls


Output. . .
ERROR: cannot verify your_domain.com's certificate, issued by ‘CN=Fake LE Intermediate X1’:
  Unable to locally verify the issuer's authority.
To connect to your_domain.com insecurely, use `--no-check-certificate'.

Nous utilisons le drapeau suggéré --no-check-certificate pour ignorer la vérification du certificat :

wget --no-check-certificate -q -O - http://your_domain.com/polls


Output

<link rel="stylesheet" type="text/css" href="https://your_space.nyc3.digitaloceanspaces.com/django-polls/static/polls/style.css">


    <p>No polls are available.</p>

Cette sortie affiche le code HTML de la page d’interface /polls et confirme également que la feuille de style est renvoyée par le magasin d’objets.

Nous avons vérifié avec succès l’émission de certificats avec le ClusterIssuer de test et pouvons maintenant modifier Ingress pour utiliser le ClusterIssuer de production.

Ouvrez à nouveau le fichier polls-ingress.yaml pour le modifier :

nano polls-ingress.yaml

Modifiez l’annotation cluster-issuer :

[polls-ingress.yaml]
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: polls-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - your_domain.com
    secretName: polls-tls
  rules:
  - host: your_domain.com
    http:
      paths:
      - backend:
          serviceName: polls
          servicePort: 8000

Apportez les modifications nécessaires, puis enregistrez et fermez le fichier. Mettez à jour l’objet Ingress à l’aide de kubectl apply :

kubectl apply -f polls-ingress.yaml


Outputingress.networking.k8s.io/polls-ingress configured

Vous pouvez utiliser les commandes kubectl describe certificate polls-tls et kubectl describe ingress polls-ingress pour suivre l’état d’émission du certificat :

kubectl describe ingress polls-ingress


Output. . .
Events:
  Type    Reason             Age                From                      Message
  ----    ------             ----               ----                      -------
  Normal  CREATE             23m                nginx-ingress-controller  Ingress default/polls-ingress
  Normal  CreateCertificate  23m                cert-manager              Successfully created Certificate "polls-tls"
  Normal  UPDATE             76s (x2 over 22m)  nginx-ingress-controller  Ingress default/polls-ingress
  Normal  UpdateCertificate  76s                cert-manager              Successfully updated Certificate "polls-tls"

La sortie ci-dessus confirme que le nouveau certificat de production a été émis avec succès et stocké dans l’objet secret “polls-tls”.

Ouvrez your_domain.com/polls dans un navigateur pour vérifier que le cryptage HTTPS est activé et que tout fonctionne comme prévu. Vous devriez voir l’interface de l’application Polls :

Интерфейс приложения «Опросы»

Assurez-vous que votre navigateur a activé le cryptage HTTPS. Si vous utilisez Google Chrome, si la page ci-dessus s’ouvre sans erreur, cela signifie que tout fonctionne correctement. De plus, il devrait y avoir une image de cadenas dans la barre d’URL. En cliquant sur le cadenas, vous pouvez visualiser les détails du certificat Let’s Encrypt.

Pour un nettoyage final, vous pouvez basculer le type de service “polls” de NodePort vers le type interne ClusterIP.

Modifiez le fichier polls-svc.yaml dans un éditeur de texte :

nano polls-svc.yaml

Remplacez type de NodePort par ClusterIP :

polls-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: polls
  labels:
    app: polls
spec:
  type: ClusterIP
  selector:
    app: polls
  ports:
    - port: 8000
      targetPort: 8000

Lorsque vous avez terminé de modifier le fichier, enregistrez-le et fermez-le.

Déployez les modifications avec la commande kubectl apply :

kubectl apply -f polls-svc.yaml --force


Outputservice/polls configured

Vérifiez que le service a été modifié à l’aide de kubectl get svc :

kubectl get svc polls


OutputNAME    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
polls   ClusterIP   10.245.203.186   <none>        8000/TCP   22s

Cette sortie montre que le type de service est ClusterIP. Seuls le domaine et Ingress créés à cette étape peuvent être utilisés pour l’accès.

Conclusion

Dans ce tutoriel, nous avons déployé une application Django évolutive avec sécurité HTTPS sur un cluster Kubernetes. Le contenu statique est servi directement à partir du magasin d’objets, et le nombre de pods en cours d’exécution peut être rapidement augmenté ou diminué à l’aide du champ replicas dans le manifeste de déploiement polls-app.

Si vous utilisez DigitalOcean Space, vous pouvez également activer la diffusion de ressources statiques via votre réseau de diffusion de contenu et créer un sous-domaine personnalisé pour votre espace. Pour plus d’informations, consultez la section Enabling a CDN du tutoriel Setting up a Scalable Django Application with Managed Databases and DigitalOcean Spaces.

Le reste de la série est disponible sur From Containers to Kubernetes with Django.

comments powered by Disqus