8. コンテナによるデプロイメント

コンテナ化されたアプリケーションを使用するには、最も単純なもの(単純なDockerイメージ)から高度なもの(Kubernetesなど)まで、さまざまな方法があります。

注釈

この種類のデプロイメントでは、 dockerアプリケーション をインストールして実行する必要があります。この チュートリアル を確認してください。

ヒント

Dockerは、パッケージ化されたアプリケーション(別名イメージ)を実行します。これは、ビルドするソース(Dockerfileおよびリソース)として取得するか、レジストリ(プライベートまたはパブリック)から既にビルドできます。

注釈

QGIS Debian-Ubuntuパッケージのダウンロードには有効なgpg認証キーが必要です。インストールページ を参照して、以下のDockerfileを更新してください。

8.1. シンプルなdockerイメージ

Dockerイメージがパブリックレジストリに存在しないため。ビルドする必要があります。そのためには、ディレクトリ qgis-server をそのディレクトリ内に作成します。

  • この内容で Dockerfile ファイルを作ります:

FROM debian:bullseye-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 \
    # Add the current key for package downloading
    # Please refer to QGIS install documentation (https://www.qgis.org/fr/site/forusers/alldownloads.html#debian-ubuntu)
    && mkdir -m755 -p /etc/apt/keyrings \
    && wget -O /etc/apt/keyrings/qgis-archive-keyring.gpg https://download.qgis.org/downloads/qgis-archive-keyring.gpg \
    # Add repository for latest version of qgis-server
    # Please refer to QGIS repositories documentation if you want other version (https://qgis.org/en/site/forusers/alldownloads.html#repositories)
    && echo "deb [signed-by=/etc/apt/keyrings/qgis-archive-keyring.gpg] https://qgis.org/debian bullseye main" | tee /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.19.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 chmod -R 777 /home/qgis/cmd.sh
RUN chown qgis:qgis /home/qgis/cmd.sh

USER qgis
WORKDIR /home/qgis

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

CMD ["/home/qgis/cmd.sh"]
  • この内容で cmd.sh ファイルを作ります:

#!/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
  • イメージを組み立てます:

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

8.1.1. 最初の実行

サーバーを実行するにはQGISプロジェクトファイルが必要です。自分のものを使うことも、このサンプル を使うこともできます。

これを行うには、ディレクトリ qgis-server 内にディレクトリ data を作成し、その中にファイルをコピーします。以下の説明に準拠するため、名前を osm.qgs に変更します。

注釈

GetCapabilitesが壊れている場合、 プロジェクト ► プロパティQGIS Server タブの下に広告URLを追加する必要があるかもしれません。例えば、サーバーが8080番ポートで公開されている場合、広告URLとして http://localhost:8080/qgis-server/ を指定します。詳しくは プロジェクトを設定する セクション以降を参照してください。

これでサーバーを走らせることができます:

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

使われたオプション:

  • -d: バックグラウンドで動かします

  • --rm: 停止させられたとき、コンテナを削除します

  • --name: 作成されるコンテナの名前

  • --net: (前回作成された)サブネットワーク

  • --hostname: 後で参照するための、コンテナのホスト名

  • -v: コンテナ内でマウントされるローカルのデータディレクトリ

  • -p: ホスト/コンテナ・ポートマッピング

  • -e: コンテナ内で使われる環境変数

確認するには、docker ps | grep qgis-server と入力すると、qgis-server という1行が表示されます:

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

8.1.2. 使用可能なサンプル

サーバはfastcgi接続しか受け付けないので、このプロトコルを扱うHTTPサーバが必要です。そのためには、簡単なNginx設定ファイルを作成し、Nginxイメージを起動する必要があります。

この内容でカレントディレクトリにファイル nginx.conf を作成します:

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

そしてこのコマンドを入力します:

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

能力の有無を確認するには、ブラウザで http://localhost:8080/qgis-server/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities と入力してください

8.1.3. クリーンアップ

動作中のイメージをクリーンアップするには次を入力します:

docker stop qgis-server nginx

8.2. Dockerスタック

これまでの方法は、スクリプトを書くことはできますが、簡単にパッケージ化したり、標準化したり、簡単に管理したりすることはできません。

Dockerイメージセットを操作するには、オーケストレーターが管理するDockerスタックを使用できます。スタックでは、イメージは同じプライベートネットワークで動作しており、スタック全体を開始/停止したり、スタックを他のワーカーにデプロイしたりできます。たとえば、Swarm、Kubernetes、Mesosなど、多くのオーケストレーターがいます。

以下では、テスト用の簡単な設定を紹介します。本番用には適していません。

8.2.1. Swarm/docker-compose

Dockerに独自のオーケストレーターSwarmが追加されました(docker-composeファイルと互換性があります)。 これを有効にする 必要があります(MacバージョンはLinuxでも動作します)。

スタックの説明

Swarmが動作するようになったので、サービスファイルを作成します(Deploy to 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

スタックをデプロイ(または更新)するには、次を入力します:

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

replicas 列に 1/1 が表示されるまで、スタックのデプロイメント状態を確認してください:

docker stack services qgis-stack

次のようになります:

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

WMS の機能を確認するには、ウェブブラウザに http://localhost:8080/qgis-server/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities を入力します

クリーンアップ

クリーンアップには、次を入力します:

docker stack rm qgis-stack

8.2.2. Kubernetes

インストール

もしあなたが Docker Desktop をインストールしているなら、Kubernetes (別名k8s)を使うのはとても簡単です: enable k8s

そうでない場合は、minikube tutorial または microk8s for Ubuntu に従ってください。

Kubernetesのインストールは本当に複雑なので、このデモで使用される側面にのみ焦点を当てます。さらに詳しい情報については、公式ドキュメント を参照してください。

microk8s

microk8sでは追加の手順が必要です。Kubernetesで作成されたイメージを検出するには、レジストリを有効にしてqgis-serverイメージにタグを付ける必要があります。

まずレジストリを有効にします:

microk8s enable dashboard dns registry

そして、タグを付け、新しく作成したレジストリにイメージをプッシュします:

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

最後に、レジストリ 127.0.0.1:32000insecure-registries フィールドにリストされるように、/etc/docker/daemon.json を追加または補完します:

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

マニフェストを作る

Kubernetesは、yamlマニフェストにデプロイするオブジェクトを記述します。さまざまな種類がありますが、デプロイメント(ポッドを処理する、つまりDockerイメージ)とサービスのみを使用して、デプロイメントを内部または外部の目的に公開します。

デプロイメントマニフェスト

ファイル deployments.yaml を次の内容で作成します:

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
サービスマニフェスト

ファイル services.yaml を次の内容で作成します:

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

マニフェストをデプロイする

Kubernetesにイメージとサービスをデプロイするには、ダッシュボード(右上の + をクリック)またはコマンドラインを使用します。

注釈

microk8sでコマンドラインを使う場合、各コマンドの前に microk8s を付ける必要があります。

マニフェストをデプロイまたは更新する:

kubectl apply -k ./

現在デプロイされているものを確認する:

kubectl get pods,services,deployment

このようになる筈です:

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

nginx/qgisログを読むには次を入力します:

kubectl logs -f POD_NAME

WMS の機能を確認するには、ウェブブラウザに次のように入力します http://localhost:30080/qgis-server/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities

クリーンアップ

クリーンアップには、次を入力します:

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

8.3. クラウドデプロイメント

コンテナ化されたアプリケーションのデプロイを処理するために、独自のサーバークラスタを管理するのは複雑な仕事です。ハードウェア、帯域幅、セキュリティなど、さまざまな問題をさまざまなレベルで処理しなければなりません。

クラウド・デプロイメント・ソリューションは、インフラの管理に注力したくない場合に有効な選択肢となります。

クラウドデプロイメントでは独自のメカニズムを使用することができますが、先に説明した段階(docker imagesstack management)と互換性があります。

8.3.1. AWSユースケース

Amazon AWSでは、ECS (Elastic Container Service) の機能により、docker-composeやKubernetes互換のラッパーを使ってスタックを管理することができます。カスタムイメージにアクセスするためには image registry を作成する必要があります。

docker-compose 同様の機能を使うには、ecs-cli クライアントをインストールし、 適切なパーミッション/ロール を持っている必要があります。その後、ecs-cli compose コマンドの助けを借りて、 stack description を再利用することができます。

Kubernetesを使うには、AWSのWebコンソールかコマンドラインツール eksctl を使い、適切なパーミッション/ロールを設定します。その後、うまく設定された kubectl 環境で、 Kubernetes manifests を再利用することができます。