pygeoapi implementation kubernetes - étape 2 - déploiement automatisé

Table of Contents

Introduction

pygeoapi kubernetes series introduction

Déploiement automatisé de pygeoapi

L’objectif de ce chapitre est d’automatiser le déploiement d’une architecture minimale composée d’un contrôleur Ingress et d’un service exposant un unique pod pygeoapi.

Partie 1: Mise en place de l’automatisation

Introduction

La première étape d’automatisation du déploiement de l’application dans kubernetes est de créer les fichiers manifests. Le premier fichier configure le Deployment et le second configure le Service. Nous utiliserons également Kustomize, un outil de gestion des manifests intégré à kubectl, ainsi que Make, un outil d’automatision du déploiement.

Le code source est disponible dans ce repository

Création des manifests Kubernetes

Création dans dossier racine (e.g. ’tuto_pygeoapi’) et création d’un sous-dossier k8s comprenant les fichiers suivants :

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pygeoapi
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pygeoapi
  template:
    metadata:
      labels:
        app: pygeoapi
    spec:
      containers:
      - name: pygeoapi
        image: geopython/pygeoapi:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: pygeoapi
  namespace: default
spec:
  selector:
    app: pygeoapi
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: NodePort    # <-- prêter attention au type de service 'NodePort'. Le type de service sera mis à jour dans la partie 2

Création du fichier kustomization.yaml et Makefile

Créer les fichiers suiants à la racine du répertoire:

kustomization.yaml

resources:
  - k8s/deployment.yaml
  - k8s/service.yaml

Makefile

deploy:
	kubectl apply -k .

clean:
	kubectl delete -k .

Construction et déploiement de l’application

Connexion à WSL et démarrage de Minikube

$ wsl -d ubuntu
$ minikube status                 # Verifier que Minikube est arrêté.
$ minikube start --driver=docker  # Démarrage de Minikube

Accéder au dossier et executer la commande Make de dépoiement

$ cd /path-to-tuto-folder/
$ make deploy
kubectl apply -k .
service/pygeoapi created
deployment.apps/pygeoapi created

Enabling port forward

$ kubectl port-forward deployment/pygeoapi 5000:80

Accéder à pygeoapi

pygeoapi UI

Partie 2: Activation d’Ingress et personnalisation de la configuration de pygeoapi

Introduction

Dans la première partie de cet article, nous avons créé un Service the type NodePort. Les Services NodePort exposent les applications sur un port specifique sur toues les noeuds du cluster, transférant le trafic entrant directement vers les Pods pygeoapi. Pour cette raison nous avons également utilisé kubectl port-forward pour proxifier les requêtes locales vers le Service au sein du cluster, en assignant le port local 5000 pour se conformer au port par défaut attendu par la configuration de pygeoapi.

Cependant cette approche n’est pas appropriée pour un environement de Production. En production les Services ne devraient pas être exposés directement au trafic externe. A la place, le trafic externe doit être routé dans le cluster au travers d’un composant central jouant le rôle de ‘gateway’ — le Contrôleur Ingress — qui fournit un socle solide de répartition de charge, de terminaison SSL, et des capacités de routage avancées.

En implementant Ingress, il est également nécessaire d’ajuster la configuration de pygeoapi pour refléter l’url externe exposée par Ingress. Cette configuration est injectée dans les Pods en utilisant Kubernetes ConfigMaps.

Dans cette deuxième partie, nous exposerons l’application sous le nom de domaine pygeoapi.local au travers d’un certificat SSL auto-signé, en activant et configurant Ingresspour router le trafic externe vers le Service pygeoapi. Nous configurerons pygeoapi au travers d’un fichier de configuration personnalisé.

Le code source est disponible dans ce repository

Suppression de l’application pygeoapi existante

$ cd /path-to-tuto-folder/
$ make clean
kubectl delete -k .
service "pygeoapi" deleted
deployment.apps "pygeoapi" deleted

Configuration du certificat SSL

Dans cet example nous créeront un certificat auto-signé. Création d’un dosser de certificat à la racine du répertoire projet.

Création du certificat en utilisant openssl:

$ cd /path-to-tuto-folder/certificates
$ openssl req -x509 -newkey rsa:2048 -nodes -keyout tls.key -out tls.crt -days 365 -subj "/CN=pygeoapi.local/O=pygeoapi" -addext "subjectAltName=DNS:pygeoapi.local"

Création d’un secret pour ce certificat dans minikube

$ cd /path-to-tuto-folder/certificates
$ kubectl create secret tls pygeoapi-tls --key tls.key --cert tls.crt --namespace default

Vérification du secret au travers du dashboard minikube:

hosts file

Ou depuis la ligne de commande:

$ kubectl get secrets
NAME           TYPE                DATA   AGE
pygeoapi-tls   kubernetes.io/tls   2      4m49s

Optionnellement, ajout du certificat au sein du Programme Racine de Confiance (Windows) afin d’éviter l’avertissement navigateur net::ERR_CERT_COMMON_NAME_INVALID

Ouvrir Powershell en tant qu’Administrateur :

certutil -addstore "Root" "C:\path\to\tls.crt"

Mise à jour de l’environement hosts

Edition du fichier hosts file pour associer pygeoapi.local à localhost:

C:\Windows\System32\drivers\etc\hosts ou /etc/hosts

hosts file

Ajout et mise à jour du fichier de configuration pygeoapi

Le fichier de configuration peut être trouvé directement dans le repository github de pygeoapi. Le nom du fichier est pygeoapi-config.yml.

Création d’un dossier pygeoapi et copie du fichier de configuration. Renommer le fichier local.config.yml afin d’écraser le fichier de configuration de l’image docker de pygeoapi.

pygeoapi config

Définir la valeur du paramètre url comme étant https://pygeoapi.local. Pygeoapi requière de connaître l’url d’accés externe pour refléter les chemins d’accès interface coorespondant.

D’autres sections peuvent être personnalisées telle que la section ’ contact’.

pygeoapi edit config

Ajouter la configuration de pygeoapi dans ConfigMaps

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pygeoapi
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pygeoapi
  template:
    metadata:
      labels:
        app: pygeoapi
    spec:
      containers:
      - name: pygeoapi
        image: geopython/pygeoapi:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        volumeMounts:                               # <-----------------
        - name: config-volume                       # <-----------------
          mountPath: /pygeoapi/local.config.yml     # <-----------------
          subPath: local.config.yml                 # <-----------------
      volumes:                                      # <-----------------
      - name: config-volume                         # <-----------------
        configMap:                                  # <-----------------
          name: pygeoapi-config                     # <-----------------

kustomization.yaml

resources:
  - k8s/deployment.yaml
  - k8s/service.yaml

configMapGenerator:                 # <------
  - name: pygeoapi-config           # <------
    files:                          # <------
      - pygeoapi/local.config.yml   # <------

Créer in fichier de configuration du contrôleur Ingress

Ajouter un fichier ingress.yaml :

ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: pygeoapi-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - pygeoapi.local
      secretName: pygeoapi-tls  # <-- the certificate secret registered in kubernetes
  rules:
  - host: pygeoapi.local  # <-- configure your /etc/hosts or DNS accordingly
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: pygeoapi
            port:
              number: 80

kustomization.yaml

resources:
  - k8s/deployment.yaml
  - k8s/service.yaml
  - k8s/ingress.yaml    # <------ add the ingress manifest

configMapGenerator:
  - name: pygeoapi-config
    files:
      - pygeoapi/local.config.yml

Mise à jour du type de Service pygeoapi

Mise à jour du type de Service en tant que ClusterIP

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: pygeoapi
  namespace: default
spec:
  selector:
    app: pygeoapi
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: ClusterIP       # <--- modifier NodePort en ClusterIP

Vérification du répertoire projet

Activation d’Ingress

$ minikube addons enable ingress
💡  ingress is an addon maintained by Kubernetes. For any concerns contact minikube on GitHub.
You can view the list of minikube maintainers at: https://github.com/kubernetes/minikube/blob/master/OWNERS
    ▪ Using image registry.k8s.io/ingress-nginx/controller:v1.11.3
    ▪ Using image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.4
    ▪ Using image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.4
🔎  Verifying ingress addon...
🌟  The 'ingress' addon is enabled

Construction et déploiement de l’application

$ cd /path-to-tuto-folder/
$ make deploy
kubectl apply -k .
configmap/pygeoapi-config-57c2ch8kt7 created
service/pygeoapi created
deployment.apps/pygeoapi created
ingress.networking.k8s.io/pygeoapi-ingress created

Création d’un tunnel minikube

Ceci est requis lorsque le cluster minikube fonctionne au travers de WSL afin de router les requêtes locales vers le cluster minikube.

$ minikube tunnel
✅  Tunnel successfully started

📌  NOTE: Please do not close this terminal as this process must stay alive for the tunnel to be accessible ...

❗  The service/ingress pygeoapi-ingress requires privileged ports to be exposed: [80 443]
🔑  sudo permission will be asked for it.
🏃  Starting tunnel for service pygeoapi-ingress.
[sudo] password for <user>:

Accéder à pygeoapi

pygeoapi UI

Conclusion

Le résultat de ce chapitre est une implémentation minimale composée d’un contrôleur Ingress et d’un service exposant un unique pod pygeoapi. Le déploiement est maintenant automatisé via des manifests et des commandes make et nous avons également personnaliser la configuration de pygeoapi.

La prochaine étape est de s’intéresser à l’architecture ‘plugin’ de pygeoapi au travers du deployement d’un service de type OGC Processes.

Le déploiement peut être supprimé

make clean