오프라인 환경에서 Docker 운영

GitLab에서 Docker를 왜 사용할까?

최근 Google Cloud, AWS 등과 같은 클라우드에 대한 관심이 증가하면서 Docker에 대한 관심도 증가하고 있습니다. GitLab 또한 Omnibus 버전의 공식 Docker image를 배포하고 있으며, GitLab runner를 효과적으로 운영하기 위해서는 Docker를 사용하는 것이 좋습니다.

Docker를 사용하면 얻는 이점

  • 설치 및 업그레이드가 쉬워짐
  • downtime 없이 업그레이드 가능 (multi node에서 가능)
  • GitLab runner가 다양한 환경에서 작동
  • auto scale-up이 가능해짐

이러한 이점을 얻기 위해 금융권과 같은 폐쇄적인 망에서도 Docker를 활용하여 GitLab을 운영하고자 하는 수요가 있습니다. 하지만 인터넷과 단절된 offline에서 Docker를 운용하기에는 알아야 하는 부분들이 있습니다.

Docker 설치하기

전제조건

  • 내부망 (인터넷 접근 불가)
  • 인터넷 접근 가능한 PC 1대 (가능한 self-hosted 서버와 유사한 환경)
  • 인터넷에서 다운로드한 파일 반입 가능한 환경

본 가이드에서는 Ubuntu, CentOS 설치에 대해서만 가이드 합니다.

설치

Ubuntu

  • https://download.docker.com/linux/ubuntu/dists/ 에서 버전에 맞는 .dev파일을 찾아 다운로드
  • 다운로드된 파일을 Docker 설치 대상 서버로 반입
  • 다음 명령어를 통해 Docker 패키지 설치 (경로와 파일명은 수정)
$ sudo dpkg -i  /path/to/package.deb
  • Docker가 잘 설치 되어 있는지 확인
$ sudo docker run hello-world

CentOS

  • 인터넷 가능한 PC(CentOS)에서 다음 명령어 실행
$ yumdownloader --resolve docker-ce
  • 아래와 같은 rpm 파일 다운로드 확인
containerd.io-1.2.13-3.2.el7.x86_64.rpm
docker-ce-19.03.12-3.el7.x86_64.rpm
docker-ce-cli-19.03.12-3.el7.86_64.rpm
libcgroup-0.41-19.el8.x86_64.rpm
  • 다운로드된 파일을 Docker 설치 대상 서버로 반입
  • 다음 명령어로 대상 파일 설치
yum localinstall -y *.rpm
  • Complete! 메시지 확인
  • Docker 기동
systemctl start docker
systemctl status docker

Runner 오프라인 세팅

GitLab runner를 오프라인에서 사용하기 위해서는 docker image를 반입하는 것 이외에 runner 자체의 설정이 필요합니다.

  • runner config 파일 수정
    • /etc/gitlab-runner/comfig.toml
    • pull_policy = "if-not-present" : 로컬에 이미지를 확인하여 있다면, 최신버전의 이미지를 온라인에서 pull 받지 않고 있는 버전의 이미지를 사용
    • executor가 docker일 때, runner가 갖고 있는 image를 docker container 안에서 해당 이미지를 사용할 수 있도록 volume 매핑
[[runners]]
name = "Runner name"
url = ...
...
executor = "docker"
[runners.docker]
image = ...
pull_policy = "if-not-present"
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
...
  • config 파일 수정 후, runner restart
$ gitlab-runner restart

Docker Image 반입하기

특정 tag가 없이 최신 버전 image pull

$ docker image pull <image명>

특정 tag image pull

$ docker image pull <image명>:<tag>
  1. docker image save

file명에 ":"(colon)은 들어갈 수 없기 때문에 tag가 있을경우 특정 문자로 변환하는 작업이 필요합니다.

이 가이드에서는 "_"로 하겠습니다.

$ docker save <image명>:<tab> > <image명>_<tag>.tar
  1. tar파일 압축

기본적으로 내부망에서 파일을 업로드하는데 속도가 느린편이므로 image를 압축합니다. (평균 1/3 사이즈로 압축)

gzip 사용하여 압축

$ gzip -0 <image명>_<tag>.tar

xz 사용하여 압축

$ xz -9 <image명>_<tag>.tar

3-1. Image가 여러개일 경우 script 활용 방법 pull_docker.sh 예시)

#! /bin/bash
input=<text 파일명>
while IFS = read -r line
do
fileName = ${line##*/}
fileName = ${echo ${fileName} | sed 's/:/_/g'
docker pull ${line}
docker save ${line} > ${fileName}.tar
gzip -9 ${fileName}.tar
done < "$input"

내부망에서 docker load

내부망에서 작업할 pc에 위에서 만들어진 *.tar.gz 파일들을 준비한 상태에서 시작합니다

  • docker load 명령어를 통해 runner image load
docker load < <image명>.tag.gz
  • image가 여러개일 경우 script 활용 방법
#! /bin/bash
for f in `ls *tar.gz` ; do sudo docker load < $f ; done