18.2.5. Despliegue en contenedores

Hay muchas formas de utilizar aplicaciones en contenedores, desde las más simples (imágenes simples de Docker) hasta las más sofisticadas (Kubernetes, etc.).

Nota

Este tipo de implementación necesita que la aplicación docker <https://www.docker.com> _ esté instalada y en ejecución. Mira este tutorial.

Consejo

Docker ejecuta una aplicación preempaquetada (también conocida como imágenes) que se pueden recuperar como fuentes (Dockerfile y recursos) para compilar o ya compiladas a partir de registros (privados o públicos).

18.2.5.1. Imágenes de simple docker

Como la imagen de la ventana acoplable no existe en un registro público. necesitarás construirlo. Para hacerlo, cree un directorio qgis-server y dentro de su directorio:

  • create a file Dockerfile con este contenido:

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"]
  • create a file cmd.sh con este contenido:º

#!/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
  • construya la imagen con:

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

18.2.5.1.1. Primero intente

Para ejecutar el servidor, necesitará un archivo de proyecto QGis. Puede usar uno de los suyos o elegir esta muestra.

Para hacerlo, cree un directorio: archivo: datos dentro del directorio qgis-server y copie su archivo en él. Para cumplir con las siguientes explicaciones, cámbiele el nombre a osm.qgs.

Ahora, puede ejecutar el servidor con:

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

Opciones usadas:

  • -d: ejecuta en segundo plano

  • –rm: borra el contenedor cuando es detenido

  • –name: nombre del contenedor a crear

  • –net: (creada previamente) subred

  • –hostname: nombre de host del contenedor, para referenciación posterior

  • -v: directorio de datos local a montar en el contenedor

  • -p: mapeo del puerto del host/contenedor

  • -e: variable de entorno a usar en el contenedor

Para probar, escriba docker ps | grep qgis-server and you should see a line with 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. Muestra utilizable

Como el servidor solo acepta conexiones fastcgi, debe tener un servidor HTTP que maneje este protocolo. Para hacerlo, tenemos que crear un archivo de configuración Nginx simple e iniciar una imagen Nginx.

Cree un archivo nginx.conf en el directorio actual con este contenido:

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;
  }
}

y escriba este comando:

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

Para verificar la disponibilidad de capacidades, escriba un navegador http://localhost:8080/qgis-server/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities

18.2.5.1.3. Limpieza

Para limpiar las imágenes cargadas, escriba:

docker stop qgis-server nginx

18.2.5.2. Pilas de Docker

El método anterior es programable, pero no es fácil de empaquetar, estandarizar o administrar.

Para trabajar con un conjunto de imágenes de la ventana acoplable, puede usar una pila de la ventana acoplable administrada por un orquestador. En una pila, las imágenes funcionan en la misma red privada y puede iniciar / detener toda la pila o implementar la pila en otros trabajadores. Hay muchos orquestadores, por ejemplo Swarm, Kubernetes y Mesos.

A continuación, presentaremos configuraciones simples con fines de prueba. No son aptos para la producción.

18.2.5.2.1. Swarm/docker-compose

Docker ahora tiene su propio orquestador: Swarm (compatible con archivos de composición de Docker). Tienes que “habilitarlo <https://docs.docker.com/get-started/orchestration/#enable-docker-swarm>`_ (la versión para Mac también funcionará con Linux).

18.2.5.2.1.1. Descripción de pila

Ahora que tiene Swarm funcionando, cree el archivo de servicio (consulte 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

Para implementar (o actualizar) la pila, escriba:

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

Verifique el estado de implementación de la pila hasta que obtenga 1/1 en la columna réplicas:

docker stack services qgis-stack

Algo como:

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

Para verificar las capacidades de WMS, escriba un navegador web http://localhost:8080/qgis-server/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities

18.2.5.2.1.2. Limpieza

Para limpiar, escriba:

docker stack rm qgis-stack

18.2.5.2.2. Kubernetes

18.2.5.2.2.1. Instalación

Si tiene una instalación de Docker Desktop, usar Kubernetes (también conocido como k8s) es bastante sencillo: ʻenable k8s <https://docs.docker.com/get-started/orchestration/#enable-Kubernetes>`_.

Si no es así, sigue el tutorial minikube o microk8s para Ubuntu.

Como la instalación de Kubernetes puede ser realmente compleja, solo nos centraremos en los aspectos utilizados por esta demostración. Para obtener más información o más, consulte la documentación oficial <https://Kubernetes.io/docs/home/>`_.

18.2.5.2.2.1.1. microk8s

microk8s necesita pasos adicionales: debe habilitar el registro y etiquetar la imagen del servidor qgis para que Kubernetes encuentre las imágenes creadas.

Primero, habilite el registro:

microk8s enable dashboard dns registry

Luego, etiquete y envíe la imagen a su registro recién creado:

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

Finalmente, agregue o complete el /etc/docker/daemon.json para tener su registro**127.0.0.1:32000** enumerados en el campo registros inseguros:

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

18.2.5.2.2.2. Creando manifiestos

Kubernetes describe los objetos para implementar en manifiestos yaml. Hay muchos tipos diferentes, pero solo usaremos implementaciones (manejar pods, es decir, imágenes de Docker) y servicios para exponer las implementaciones a propósitos internos o externos.

18.2.5.2.2.2.1. Manifiestos de implementación

Cree un archivo deployments.yaml con este contenido:

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. Manifiestos de servicio

Cree un archivo services.yaml con este contenido:

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. Implementar manifiesto

Para implementar las imágenes y los servicios en Kubernetes, se puede usar el panel (haga clic en + en la parte superior derecha) o la línea de comandos.

Nota

Cuando use la línea de comando con microk8s, tendrá que anteponer cada comando con microk8s.

Para implementar o actualizar sus manifiestos:

kubectl apply -k ./

Para verificar qué está implementado actualmente:

kubectl get pods,services,deployment

Debería obtener algo como:

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

Para leer los registros de nginx / qgis, escriba:

kubectl logs -f POD_NAME

Para verificar las capacidades de WMS, escriba un navegador web http://localhost:30080/qgis-server/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities

18.2.5.2.2.4. Limpieza

Para limpiar, escriba:

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

18.2.5.3. Implementar nube

Administrar su propio clúster de servidores para manejar la implementación de aplicaciones en contenedores es un trabajo complejo. Tiene que manejar varios problemas, como hardware, ancho de banda y seguridad en diferentes niveles.

Las soluciones de implementación en la nube pueden ser una buena alternativa cuando no desea centrarse en la gestión de la infraestructura.

Una implementación en la nube puede utilizar mecanismos propietarios, pero también son compatibles con las etapas explicadas anteriormente. (docker images y stack management).

18.2.5.3.1. Caso de uso de AWS

Con Amazon AWS, a través de ʻECS (Elastic Container Service)<https://console.aws.amazon.com/ecs/home>`_ funcionalidades, puede usar contenedores compatibles con Docker-compose o Kubernetes para administrar su pila. Tendrá que crear un registro de imágenes <https://console.aws.amazon.com/ecr/home>`_ para que sus imágenes personalizadas sean accesibles.

Para usar funcionalidades similares de docker-compose, necesita instalar el cliente ecs-cli y tener los permisos/roles adecuados <https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_execution_IAM_role.html>`_. Luego, con la ayuda de los comandos ʻecs-cli compose` (ver el manual ʻecs-cli compose <https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cmd-ecs-cli-compose.html>`_ y ecs-cli tutorial), puedes reutilizar el stack description.

Para usar Kubernetes, puede usar la consola web de AWS o la herramienta de línea de comandos eksctl y tener los permisos / roles adecuados. Luego, con un entorno kubectl bien configurado, puede reusar la Kubernetes manifests.