18.2.5. Uitrollen in containers

Er zijn vele manieren om een toepassing met containers te gebruiken, van de meest eenvoudige (eenvoudige afbeeldingen van Docker) tot zeer uitgebreide (Kubernetes enzovoort).

Notitie

Voor dit soort uitrol moet de docker application zijn geïnstalleerd en kunnen worden uitgevoerd. Bekijk deze handleiding.

Hint

Docker voert vooraf verpakte toepassingen uit (alias images) die kunnen worden opgehaald als bronnen (Dockerfile en bronnen) om te bouwen of reeds gebouwde vanuit opslagplaatsen (private of publieke).

18.2.5.1. Eenvoudige docker images

Als de docker image niet bestaat in een publieke opslagplaats, zult u het moeten bouwen. Maak, om dat te doen, een map qgis-server en in die map:

  • maak een bestand Dockerfile met deze inhoud:

FROM debian:buster-slim

ENV LANG=en_EN.UTF-8


RUN apt-get update \
    && apt-get install --no-install-recommends --no-install-suggests --allow-unauthenticated -y \
        gnupg \
        ca-certificates \
        wget \
        locales \
    && localedef -i en_US -f UTF-8 en_US.UTF-8 \
    && wget -O - https://qgis.org/downloads/qgis-2019.gpg.key | gpg --import \
    && gpg --export --armor 8D5A5B203548E5004487DD1951F523511C7028C3 | apt-key add - \
    && echo "deb http://qgis.org/debian buster main" >> /etc/apt/sources.list.d/qgis.list \
    && apt-get update \
    && apt-get install --no-install-recommends --no-install-suggests --allow-unauthenticated -y \
        qgis-server \
        spawn-fcgi \
        xauth \
        xvfb \
    && apt-get remove --purge -y \
        gnupg \
        wget \
    && rm -rf /var/lib/apt/lists/*

RUN useradd -m qgis

ENV TINI_VERSION v0.17.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini

ENV QGIS_PREFIX_PATH /usr
ENV QGIS_SERVER_LOG_STDERR 1
ENV QGIS_SERVER_LOG_LEVEL 2

COPY cmd.sh /home/qgis/cmd.sh
RUN chown qgis:qgis /home/qgis/cmd.sh

USER qgis
WORKDIR /home/qgis

ENTRYPOINT ["/tini", "--"]

CMD ["/home/qgis/cmd.sh"]
  • maak een bestand cmd.sh met deze inhoud:

#!/bin/bash

[[ $DEBUG == "1" ]] && env

exec /usr/bin/xvfb-run --auto-servernum --server-num=1 /usr/bin/spawn-fcgi -p 5555 -n -d /home/qgis -- /usr/lib/cgi-bin/qgis_mapserv.fcgi
  • bouw de image met:

docker build -f Dockerfile -t qgis-server ./

18.2.5.1.1. Eerste poging

U heeft een project van QGIS nodig om de server uit te voeren. U kunt er een van uzelf gebruiken of dit voorbeeld kiezen.

Maak,om dit te doen, een map data in de map qgis-server en kopieer uw bestand daarin. Hernoem het naar osm.qgs om te voldoen aan de volgende uitleg.

Nu kunt u de server uitvoeren met:

docker network create qgis
docker run -d --rm --name qgis-server --net=qgis --hostname=qgis-server \
              -v $(pwd)/data:/data:ro -p 5555:5555 \
              -e "QGIS_PROJECT_FILE=/data/osm.qgs" \
              qgis-server

Gebruikte opties:

  • -d: uitvoeren op de achtergrond

  • –rm: verwijder de container als die is gestopt

  • –name: naam van de te maken container

  • –net: (eerder gemaakt) subnetwerk

  • –hostname: hostnaam container, voor latere verwijzingen

  • -v: lokale map data die moet worden gemount in de container

  • -p: host/container poortverdeling

  • -e: omgevingsvariabele die moet worden gebruikt in de container

Typ, om te controleren, docker ps | grep qgis-server en u zou een regel moeten zien met qgis-server:

CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS         PORTS                    NAMES
4de8192da76e   qgis-server   "/tini -- /home/qgis…"   3 seconds ago   Up 2 seconds   0.0.0.0:5555->5555/tcp   qgis-server

18.2.5.1.2. Te gebruiken voorbeeld

Als de server alleen verbindingen van fastcgi accepteert, heeft u een HTTP-server nodig die dat protocol afhandelt. We moeten, om dat te kunnen doen, een eenvoudig Nginx configuratiebestand maken en een image van Nginx starten.

Maak een bestand nginx.conf in de huidige map, met deze inhoud:

server {
  listen 80;
  server_name _;
  location / {
    root  /usr/share/nginx/html;
    index index.html index.htm;
  }
  location /qgis-server {
    proxy_buffers 16 16k;
    proxy_buffer_size 16k;
    gzip off;
    include fastcgi_params;
    fastcgi_pass qgis-server:5555;
  }
}

En typ deze opdracht:

docker run -d --rm --name nginx --net=qgis --hostname=nginx \
              -v $(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf:ro -p 8080:80 \
              nginx:1.13

Typ, om de beschikbaarheid van capabilities te controleren, in een browser http://localhost:8080/qgis-server/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities

18.2.5.1.3. Opschonen

Typ, om de uitgevoerde images op te schonen:

docker stop qgis-server nginx

18.2.5.2. Docker stapels

De vorige methode is te scripten, maar niet gemakkelijk te verpakken noch gestandaardiseerd of eenvoudig te beheren.

U zou, om te werken met een set van docker images, een stapel van docker kunnen gebruiken die wordt beheerd door een orchestrator. In een stapel werken de images in hetzelfde private netwerk, en u kunt d egehele stapel starten / stoppen of de stapel uitrollen voor andere werknemers. Er zijn veel orchestrators, bijvoorbeeld Swarm, Kubernetes en Mesos.

Als vervolg zullen we eenvoudige configuraties voor testen presenteren. Zij zijn niet geschikt voor productie.

18.2.5.2.1. Swarm/docker-compose

Docker heeft nu zijn eigen orchestrator: Swarm (compatibel met bestanden docker-compose). U dient het in te schakelen (de versie voor Mac werkt ook met Linux).

18.2.5.2.1.1. Beschrijving stapel

Nu u Swarm werkend hebt, maak het servicebestand (bekijk deploy swarm) qgis-stack.yaml:

version: '3.7'

services:
  qgis-server:
    # Should use version with utf-8 locale support:
    image: qgis-server:latest
    volumes:
    - REPLACE_WITH_FULL_PATH/data:/data:ro
    environment:
    - LANG=en_EN.UTF-8
    - QGIS_PROJECT_FILE=/data/osm.qgs
    - QGIS_SERVER_LOG_LEVEL=0  # INFO (log all requests)
    - DEBUG=1                  # display env before spawning QGIS Server

  nginx:
    image: nginx:1.13
    ports:
    - 8080:80
    volumes:
    - REPLACE_WITH_FULL_PATH/nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
    - qgis-server

De stapel uitrollen (of bij te werken), typ:

docker stack deploy -c qgis-stack.yaml qgis-stack

Controleer de status van het uitrollen van de stapel totdat u 1/1 verkrijgt in de kolom replicas:

docker stack services qgis-stack

Iets als:

ID              NAME                MODE          REPLICAS     IMAGE                 PORTS
gmx7ewlvwsqt    qgis_nginx          replicated    1/1          nginx:1.13            *:8080->80/tcp
l0v2e7cl43u3    qgis_qgis-server    replicated    1/1          qgis-server:latest

Typ, om de WMS-capabilities te controleren, in een webbrowser http://localhost:8080/qgis-server/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities

18.2.5.2.1.2. Opschonen

Typ, om op te schonen:

docker stack rm qgis-stack

18.2.5.2.2. Kubernetes

18.2.5.2.2.1. Installeren

Als u een installatie voor Docker Desktop hebt, is het gebruiken van Kubernetes (alias k8s) behoorlijk rechttoe rechtaan: enable k8s.

Indien niet, volg dan de minikube tutorial of microk8s for Ubuntu.

Omdat installaties van Kubernetes echt behoorlijk complex kunnen zijn, zullen we ons alleen focussen op de aspecten die worden gebruikt door deze demo. Voor meer / diepere informatie, bekijk de officiële documentatie.

18.2.5.2.2.1.1. microk8s

microk8s heeft extra stappen nodig: u dient de registratie in te schakelen en de image voor qgis-server te taggen om er voor te zorgen dat Kubernetes de gemaakte images kan vinden.

Schakel eerst de registratie in:

microk8s enable dashboard dns registry

Dan, tag en push de image naar uw nieuw gemaakte registratie:

docker tag qgis-server 127.0.0.1:32000/qgis-server && docker push 127.0.0.1:32000/qgis-server

Tenslotte, voeg toe of completeer /etc/docker/daemon.json om uw registratie 127.0.0.1:32000 te vermelden in het veld insecure-registries:

{
  "insecure-registries": ["127.0.0.1:32000"]
}

18.2.5.2.2.2. Manifesten maken

Kubernetes beschrijft de uit te rollen objecten in manifesten van yaml. Er zijn veel andere soorten, maar we zullen alleen uitrollen gebruiken (afhandelen van pods, d.i. docker images) en services om de uitrollen weer te geven voor interne of externe doeleinden.

18.2.5.2.2.2.1. Manifesten voor uitrollen

Maak een bestand deployments.yaml met deze inhoud:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: qgis-server
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      myLabel: qgis-server
  template:
    metadata:
      labels:
        myLabel: qgis-server
    spec:
      containers:
        - name: qgis-server
          image: localhost:32000/qgis-server:latest
          imagePullPolicy: IfNotPresent
          env:
            - name: LANG
              value: en_EN.UTF-8
            - name: QGIS_PROJECT_FILE
              value: /data/osm.qgs
            - name: QGIS_SERVER_LOG_LEVEL
              value: "0"
            - name: DEBUG
              value: "1"
          ports:
            - containerPort: 5555
          volumeMounts:
            - name: qgis-data
              mountPath: /data/
      volumes:
        - name: qgis-data
          hostPath:
            path: REPLACE_WITH_FULL_PATH/data

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: qgis-nginx
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      myLabel: qgis-nginx
  template:
    metadata:
      labels:
        myLabel: qgis-nginx
    spec:
      containers:
        - name: qgis-nginx
          image: nginx:1.13
          ports:
            - containerPort: 80
          volumeMounts:
            - name: nginx-conf
              mountPath: /etc/nginx/conf.d/default.conf
      volumes:
        - name: nginx-conf
          hostPath:
            path: REPLACE_WITH_FULL_PATH/nginx.conf
18.2.5.2.2.2.2. Service-manifesten

Maak een bestand services.yaml met deze inhoud:

apiVersion: v1
kind: Service
metadata:
  name: qgis-server
  namespace: default
spec:
  type: ClusterIP
  selector:
    myLabel: qgis-server
  ports:
    - port: 5555
      targetPort: 5555
---
apiVersion: v1
kind: Service
metadata:
  name: qgis-nginx
  namespace: default
spec:
  type: NodePort
  selector:
    myLabel: qgis-nginx
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080

18.2.5.2.2.3. Manifesten uitrollen

Voor het uitrollen van de images en services in Kubernetes, kan men het dashboard gebruiken (klik op de + rechtsboven) of de opdrachtregel.

Notitie

Bij het gebruiken van de opdrachtregel met microk8s moet u elke opdracht laten vooraf gaan door microk8s.

Uw manifesten uitrollen of bijwerken:

kubectl apply -k ./

Controleren wat momenteel is uitgerold:

kubectl get pods,services,deployment

U zou iets moeten krijgen als:

NAME                               READY   STATUS    RESTARTS   AGE
pod/qgis-nginx-54845ff6f6-8skp9    1/1     Running   0          27m
pod/qgis-server-75df8ddd89-c7t7s   1/1     Running   0          27m

NAME                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/Kubernetes         ClusterIP   10.152.183.1     <none>        443/TCP        5h51m
service/qgis-exec-server   ClusterIP   10.152.183.218   <none>        5555/TCP       35m
service/qgis-nginx         NodePort    10.152.183.234   <none>        80:30080/TCP   27m
service/qgis-server        ClusterIP   10.152.183.132   <none>        5555/TCP       27m

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/qgis-nginx    1/1     1            1           27m
deployment.apps/qgis-server   1/1     1            1           27m

Typ, om logs van nginx/qgis te lezen:

kubectl logs -f POD_NAME

Typ, om de WMS-capabilities te controleren, in een webbrowser http://localhost:30080/qgis-server/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities

18.2.5.2.2.4. Opschonen

Typ, om op te schonen:

kubectl delete -n default service/qgis-server service/qgis-nginx deployment/qgis-nginx deployment/qgis-server

18.2.5.3. Uitrol in de cloud

Beheren van uw eigen cluster van servers om het uitrollen van toepassingen met containers af te handelen, is een complexe taak. U moet meerdere problemen afhandelen, zoals hardware, bandbreedte en beveiliging op verschillende niveaus.

Oplossingen voor het uitrollen in de cloud kan een goed alternatief zijn als u zich niet wilt focussen op het beheren van de infrastructuur.

Een uitrol in de cloud kan fabrieksmatige mechanismen gebruiken, maar zij zijn ook compatibel met de stadia die eerder zijn uitgelegd (docker images en stapel beheren).

18.2.5.3.1. AWS gebruiksgeval

Met Amazon AWS, via functionaliteiten van ECS (Elastic Container Service), kunt u docker-compose of Kubernetes compatibele wrappers gebruiken om uw stapels te beheren. U zult een registratie voor een image moeten maken om uw aangepaste images toegankelijk te houden.

Voor het gebruiken van functionaliteiten die lijken op docker-compose, moet u de cliënt ecs-cli installeren en juiste rechten / rollen hebben. Dan, met behulp van de opdrachten ecs-cli compose (bekijk het ecs-cli compose manual en ecs-cli tutorial), kunt u de Beschrijving stapel opnieuw gebruiken.

U kunt, om Kubernetes te gebruiken, de AWS webconsole of het programma voor de opdrachtregel eksctl gebruiken en de juiste rechten / rollen hebben. Dan, met een goed geconfigureerde omgeving voor kubectl, kunt u de manifesten voor Kubernetes opnieuw gebruiken.