8. 컨테이너화 응용 프로그램 배포
컨테이너화된 응용 프로그램을 사용할 수 있는 많은 방법이 있습니다. 가장 단순한 방법(단순 도커(Doker) 이미지)부터 복잡한 방법(쿠버네티스(Kubernetes) 등)까지 말입니다.
참고
이런 종류의 배치는 도커 응용 프로그램 을 설치하고 실행해야 합니다. 이 튜토리얼 을 확인해보세요.
힌트
도커는 사전에 패키지된 응용 프로그램(이미지)을 실행합니다. 이 이미지를 빌드하기 위해 소스(도커 파일 및 리소스)로 가져올 수도 있고, 또는 (프라이빗 또는 퍼블릭) 레지스트리에 이미 빌드되어 있을 수도 있습니다.
참고
QGIS Debian-Ubuntu package downloads need a valid gpg authentication key. Please refer to the installation pages to update the following Dockerfile.
8.1. 단순 도커 이미지
퍼블릭 레지스트리에 도커 이미지가 없기 때문에, 직접 빌드해야 합니다. 그렇게 하려면 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 프로젝트를 사용하려면, qgis-server
디렉터리 안에 data
디렉터리를 생성하고 사용자의 파일을 복사해 넣으십시오. 다음 설명과 일치시키기 위해, 파일을 osm.qgs
로 재명명하십시오.
참고
GetCapabilites가 손상된 경우 QGIS Server 탭에서 알려진(advertised) 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 의 다음과 같은 내용을 보게 될 것입니다:
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 서버가 필요합니다. 이를 위해 단순한 엔진X 환경 설정 파일을 생성하고 엔진X 이미지를 시작해야 합니다.
현재 디렉터리에 다음 내용을 가진 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. 제거(cleanup)
실행 중인 이미지를 제거하려면, 다음을 입력하십시오:
docker stop qgis-server nginx
8.2. 도커 스택
앞에서 설명한 방법은 스크립트로 작성할 수 있지만, 쉽게 패키지화할 수도, 표준화할 수도, 또는 관리할 수도 없습니다.
도커 이미지 집합을 작업하기 위해 조직자(orchestrator)가 관리하는 도커 스택을 사용하면 됩니다. 스택을 사용하면, 이미지가 동일한 사설 네트워크에서 작동하며, 사용자가 전체 스택을 실행/종료하거나 다른 작업자에세 스택을 배치할 수 있습니다. 조직자는 많이 있습니다 - 예를 들면 Swarm, Kubernetes 그리고 Mesos 같은 조직자들 말이죠.
다음 절부터 테스트 목적의 단순 환경 설정을 제시할 것입니다. 이 환경 설정은 실제 서버 운용에는 적합하지 않습니다.
8.2.1. 스웜/도커 구성
도커가 이제 고유 조직자 (도커 구성(docker-compose) 파일과 호환되는) 스웜을 가지고 있습니다. 사용자가 스웜을 활성화 해야 합니다. (맥 버전도 리눅스 방법으로 작동할 것입니다.)
스택 설명
이제 스웜을 작동시켰으니, 서비스 파일 (스웜으로 배포 참조) 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 를 입력하십시오.
제거(cleanup)
스택을 제거하려면, 다음을 입력하십시오:
docker stack rm qgis-stack
8.2.2. 쿠버네티스
설치
도커 데스크탑 을 설치한 경우, 쿠버네티스(별칭 k8s)를 사용하는 방법은 꽤 직관적입니다: k8s를 활성화 하십시오.
설치하지 않았다면, 미니큐브 튜토리얼 또는 우분투용 microk8s 를 따르십시오.
쿠버네티스를 설치하는 과정이 아주 까다로울 수 있기 때문에, 이 예시에서 사용할 면면에만 집중할 것입니다. 더 심화된 정보를 알고 싶다면, 공식 문서 를 확인해보세요.
microk8s
microk8s를 사용하려면 추가 단계를 거쳐야 합니다: 쿠버네티스가 생성된 이미지를 찾을 수 있게 하려면 레지스트리를 활성화하고 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
마지막으로, /etc/docker/daemon.json
파일의 insecure-registries 필드 목록에 사용자 레지스트리 127.0.0.1:32000 이 들어가도록 /etc/docker/daemon.json
파일을 추가하거나 수정하십시오:
{
"insecure-registries": ["127.0.0.1:32000"]
}
매니페스트 생성하기
쿠버네티스는 배포할 객체를 yaml 매니페스트(manifest) 서식으로 설명합니다. 수많은 서로 다른 유형의 서식이 있지만, 내부적 또는 외부적 목적으로 배포를 노출시키기 위한 (도커 이미지 같은 포드(pod)를 처리하는) 배포 서식 및 서비스 서식만 사용할 것입니다.
배포 매니페스트
다음 내용을 가진 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
매니페스트 배포하기
쿠버네티스에서 이미지와 서비스를 배포하려면, 대시 보드(우상단에 있는 + 를 클릭) 또는 명령 줄을 사용하면 됩니다.
참고
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 를 입력하십시오.
제거(cleanup)
매니페스트를 제거하려면, 다음을 입력하십시오:
kubectl delete -n default service/qgis-server service/qgis-nginx deployment/qgis-nginx deployment/qgis-server
8.3. 클라우드 배포
컨테이너화된 응용 프로그램의 배포를 처리하도록 사용자 고유의 서버 클러스터를 관리하는 것은 복잡한 일입니다. 하드웨어, 대여폭, 그리고 서로 다른 수준들의 보안 등 여러 문제를 동시에 처리해야 하니까요.
사용자가 인프라 관리에만 집중하고 싶지 않다면, 클라우드 배포 솔루션이 훌륭한 대안이 되어 줄 수 있습니다.
클라우드 배포는 상용 메커니즘을 사용할 수도 있지만, 앞에서 설명한(도커 이미지 및 스택 관리) 단계와도 호환됩니다.
8.3.1. AWS 활용 사례
아마존 AWS를 사용하면, ECS(Elastic Container Service) 기능을 통해 도커 구성(docker-compose) 또는 쿠버네티스 호환 래퍼(wrapper)를 사용해서 사용자 스택을 관리할 수 있습니다. 사용자 정의 이미지를 받아들이게 하려면 이미지 레지스트리 를 생성해야 할 것입니다.
To use docker-compose alike functionalities, you need to install the ecs-cli client and have proper permissions / roles. Then, with the help of the ecs-cli compose commands, you can reuse the stack description.
쿠버네티스를 사용하려면, AWS 웹 콘솔 또는 명령 줄 도구 eksctl 를 사용해서 적절한 권한/역할을 가질 수 있습니다. 그 다음 잘 환경 설정된 kubectl 환경과 함께 쿠버네티스 매니페스트 를 재사용할 수 있습니다.