7. 컨테이너화 응용 프로그램 배포
컨테이너화된 응용 프로그램을 사용할 수 있는 많은 방법이 있습니다. 가장 단순한 방법(단순 도커(Doker) 이미지)부터 복잡한 방법(쿠버네티스(Kubernetes) 등)까지 말입니다.
참고
이런 종류의 배치는 도커 응용 프로그램 을 설치하고 실행해야 합니다. 이 튜토리얼 을 확인해보세요.
힌트
도커는 사전에 패키지된 응용 프로그램(이미지)을 실행합니다. 이 이미지를 빌드하기 위해 소스(도커 파일 및 리소스)로 가져올 수도 있고, 또는 (프라이빗 또는 퍼블릭) 레지스트리에 이미 빌드되어 있을 수도 있습니다.
참고
QGIS 데비안-우분투 패키지를 다운로드하려면 유효한 GPG(GNU Privacy Guard) 인증키가 필요합니다. 다음 도커 파일을 최신 키 지문(key fingerprint)으로 업데이트하려면 설치 페이지 를 참조하세요.
7.1. 단순 도커 이미지
퍼블릭 레지스트리에 도커 이미지가 없기 때문에, 직접 빌드해야 합니다. 그렇게 하려면 qgis-server
디렉터리를 생성하고 이 디렉터리 안에:
다음 내용을 가진
Dockerfile
파일을 생성하십시오:
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 \
# Add the current key for package downloading - As the key changes every year at least
# Please refer to QGIS install documentation and replace it with the latest one
&& wget -O - https://qgis.org/downloads/qgis-2020.gpg.key | gpg --import \
&& gpg --export --armor F7E06F06199EF2F2 | 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 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 ./
7.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
7.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 를 입력하십시오.
7.1.3. 제거(cleanup)
실행 중인 이미지를 제거하려면, 다음을 입력하십시오:
docker stop qgis-server nginx
7.2. 도커 스택
앞에서 설명한 방법은 스크립트로 작성할 수 있지만, 쉽게 패키지화할 수도, 표준화할 수도, 또는 관리할 수도 없습니다.
도커 이미지 집합을 작업하기 위해 조직자(orchestrator)가 관리하는 도커 스택을 사용하면 됩니다. 스택을 사용하면, 이미지가 동일한 사설 네트워크에서 작동하며, 사용자가 전체 스택을 실행/종료하거나 다른 작업자에세 스택을 배치할 수 있습니다. 조직자는 많이 있습니다 - 예를 들면 Swarm, Kubernetes 그리고 Mesos 같은 조직자들 말이죠.
다음 절부터 테스트 목적의 단순 환경 설정을 제시할 것입니다. 이 환경 설정은 실제 서버 운용에는 적합하지 않습니다.
7.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
7.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
7.3. 클라우드 배포
컨테이너화된 응용 프로그램의 배포를 처리하도록 사용자 고유의 서버 클러스터를 관리하는 것은 복잡한 일입니다. 하드웨어, 대여폭, 그리고 서로 다른 수준들의 보안 등 여러 문제를 동시에 처리해야 하니까요.
사용자가 인프라 관리에만 집중하고 싶지 않다면, 클라우드 배포 솔루션이 훌륭한 대안이 되어 줄 수 있습니다.
클라우드 배포는 상용 메커니즘을 사용할 수도 있지만, 앞에서 설명한(도커 이미지 및 스택 관리) 단계와도 호환됩니다.
7.3.1. AWS 활용 사례
아마존 AWS를 사용하면, ECS(Elastic Container Service) 기능을 통해 도커 구성(docker-compose) 또는 쿠버네티스 호환 래퍼(wrapper)를 사용해서 사용자 스택을 관리할 수 있습니다. 사용자 정의 이미지를 받아들이게 하려면 이미지 레지스트리 를 생성해야 할 것입니다.
도커 구성과 비슷한 기능을 사용하려면, ecs-cli 클라이언트를 설치하고 적절한 권한 / 역할 을 가지고 있어야 합니다. 그러면, ecs-cli compose 명령어(ecs-cli 구성 지침서 및 ecs-cli 튜토리얼 참조)의 도움으로 스택 설명 을 재사용할 수 있습니다.
쿠버네티스를 사용하려면, AWS 웹 콘솔 또는 명령 줄 도구 eksctl 를 사용해서 적절한 권한/역할을 가질 수 있습니다. 그 다음 잘 환경 설정된 kubectl 환경과 함께 쿠버네티스 매니페스트 를 재사용할 수 있습니다.