내가 리눅스를 써야만 하는 이유 #2 - Docker

두번째 이유

블로그를 Hugo로 개편한 뒤, 그동안 작성했던 노트들을 정리하면서 포스팅하고 있는데, 그 중 하나가 리눅스에 대한 글들이다. 사실 그 글들의 제목이, 약간은 윈도우나 osx 사용자들을 자극하는 것 또한 의도적이다. 업무용/개인용으로, 최근 몇년동안 리눅스를 꽤나 사용했고, 개인적으로는 osx를 최근 10년 동안 사용해봤으며, 최초 컴퓨터를 접한 후 윈도우를 15년 동안 사용했다. 지나서 생각해 보면, 어떤 os도 완벽하지 못했고, 완벽하지 않으며, 완벽하지 못할 것이라는 생각이 든다.

그 중 왜 리눅스인가? 그것은, 거의 모든 것이 무료로 제공되는 os인 리눅스를 사용하면서, 그것을 제공하고 있는 커뮤니티에 뭔가를 돌려주고 싶다는, 약간의 부채의식 때문이다. 뭔가를 꽤 오랜 시간 좋아했고 도움도 많이 얻었다면, 그 제품을 사용하는 커뮤니터에 뭔가를 돌려주고 싶다. 개발로 참여하는 방법이 제일 좋겠지만, 일개 사용자로서 자신의 경험을 인터넷에 올려서 더 많은 사용자가 사용해 볼 수 있도록 경험을 공유하는 것도 그 중의 하나라고 생각된다. 놀라운 사용자 경험이, 지구 어느 편에서 열심히 공헌하고 있는 누군가의 손끝에서 만들어진다고 생각해보자. 그 누군가에게, 뭔가를 돌려주고 싶다는 생각, 그것이다.

Docker

Docker

두번째로 써보는 이번 글은 Docker에 대한 글이다. 구글링을 해보면, container와 VM의 차이를 알 수 있을 것이다. 이번 글에서는 기술적인 관점보다는, 일반 사용자 혹은 개발자 관점에서, docker를 어떻게 사용하고 있는지를 적어보려고 한다.

Dockerization

어떤 어플을 docker image로 만드는 것을 의미한다. 최종 사용자 관점으로만 보면, windows용 portable version 어플리케이션을 만드는 것과 많이 유사하다. 어플리케이션 설치나 사용시에, 요구되거나 생성되는 os에 대한 의존성을 최대한 줄임으로써, 설치과정을 단순화하거나, 유지보수를 단순화 할 수 있게 하기 위함이다.

사용할 os를 정하고, 거기에 설치 과정도 기술하고, 어떤 디렉토리를 마운트해서 어떤 용도로 사용할 지, 어떤 설정 파일을 필요로 할지, 어떤 포트를 개방해서 사용할 지 등등, 어플리케이션 설치, 실행과 운영에 필요한 모든 사항을 스크립트화 해서 docker image로 만든다. 즉, docker image를 만드는 과정 속에서, sw가 실행하는 환경에 대한 모든 것을 정의하게 된다. 일개 application이 아니라, 실행 환경 전체를 제공함으로써, 최종 사용자의 실행 환경과 동일한 환경을 가지고 개발도 진행할 수 있게 되어, sw의 안정적 deploy가 가능할 수 있게 되는 큰 잇점이 있다.

한 가지 예를 들어보면, GitLab이 있다. Community Edition의 경우, 직접 서버나 pc에 설치해서 사용할 수 있는데, Omnibus라는 방식으로 설치를 최대한 간소화하기는 했지만, 그럼에도 불구하고, 쉽지가 않다. 그래서인지, 몇 년 전부터, GitLab에서는 공식 docker image를 제공하기 시작했다. 그 docker image를 가지고 설치하면, docker와 docker-compose가 이미 설치되어 있다는 가정하에, 몇 분이면 자신만의 gitlab을 설치하고 운영하기 시작할 수 있다.

이제 다음의 docker-compose.yml을 살펴보자. docker와 docker-compose에 조금 익숙한 사람이라면, 무엇을 바꿔야 하고, 무엇을 내가 만들어둬야 하는 지, 별 다른 설명이 필요없을 정도라고 생각된다. 잘 모르는 경우는, 일단 그대로 실행해보고, 자신이 원하는 대로 동작하는 지 살펴본 후, 조금씩 고쳐가보면 된다. 실행한다고 하더라도, host pc에는 거의 영향이 없기 때문이다. 그저 디렉토리가 생성되어 있거나, docker container가 돌아가고 있거나 하는 것 뿐이므로, 그런 것들을 삭제하고, 똑같은 시도를 다시 하고, 다시 하고, 하고 싶은 만큼 반복해도 된다. 바로 이것이, docker image로 제공되는 어플리케이션의 강력한 장점이다. 원한다면, 서로 다른 설정(겹치는 설정이 없다고 가정)으로, 동시에 여러개를 띄울 수도 있으므로(pc의 성능이 받쳐준다면), 본격적인 설치/운영전에 테스트하는 데에도 최적이다.

# Please note that GitLab password must be >= 8 characters.
version: '2'
services:
  gitlab:
    image: 'gitlab/gitlab-ce:11.11.3-ce.0'
    container_name: 'gitlab-ce'
    restart: always
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://mygitlab.local:9080'
        gitlab_rails['gitlab_shell_ssh_port'] = 9022
        gitlab_rails['lfs_enabled'] = true
        registry_external_url 'http://mygitlab.local:9005'
      GITLAB_ROOT_PASSWORD: 'root_git'
      GITLAB_TIMEZONE: 'Pacific/Auckland'
    ports:
      - '9080:9080'
      - '9022:22'
      - '9005:9005'
    volumes:
      - '~/gitlab-ce/config:/etc/gitlab'
      - '~/gitlab-ce/logs:/var/log/gitlab'
      - '~/gitlab-ce/data:/var/opt/gitlab'

만약 dockerized application으로 운영하는 중에, 백업하고 싶다고 가정하자. 위의 docker-compose.yml을 보면 딱 3가지 디렉토리가 지정되어 있다. 백업? 그냥 위의 설정파일과 함께 3개의 디렉토리만 복사해두면 끝이다.

이번에는 잘 운영하다가, 업그레이드를 해야 한다고 가정하자. 운영하고 있는 gitlab을 중단시킬 필요도 없다. docker-compose.yml을 기존에 운영하고 있는 설정과 겹치지 않게(디렉토리나 포트 등) 잘 수정하고, 기존에 운영중인 gitlab의 3개 디렉토리도 copy해서 volumes에 지정한 후, 원하는 새로운 버전으로 바꿔서 테스트해보면 된다.

Dockerized applications

개인적으로는 사용중인 dockerized application으로는 Caddy와 Commento가 있다. 업무용으로는, 고객사 서버에 vpn 접속하기 위한 커스텀 docker image(Cisco old/new, OpenVPN, PPTP, SSTP, F5 등 다수), Docker registry를 위한 GitLab server docker image, 이슈 분석 및 테스트를 쉽게 하기 위한 dockerized된 회사 sw의 docker 이미지, IntelliJ나 Maven 등 빌드 환경이 모두 담겨 있는 개발용 docker image를 만들어서 사용하고 있다.

Caddy

라이센스 문제(쇼핑몰 운영에 사용할 웹서버)를 피하기 위해 찾다가 dockerized된 Caddy 이미지를 찾아서 사용중이다. 오픈소스인 Caddy를, 소스를 가지고 빌드하기 때문에, Caddy 다운로드 페이지에서 제공되는 바이너리들의 라이센스 제약을 피할 수 있다. Docker image를 기반으로 운영하기 때문에, 필요시에는 서로 다른 환경 파일을 가지고, 여러 개의 Caddy 서버를 운영하는 것 또한 가능하다.

Commento

개발자가 제공하는 docker image가 있다. 블로그에 Comment를 운영하기 위해 찾은 녀석이다.

VPN 접속

업무의 40% 정도는 고객사 이슈를 분석하고, 해결하는 업무이다. 수백개 서버를 접속하려다 보니, 제공되는 windows vm에 접속해서, vpn sw를 설치하거나 실행하고, 접속 profile을 import하거나 생성해서 접속하고, putty로 다시 고객사 서버에 접속해야 한다. 그러다가 파일이라도 다운로드 하거나 업로드 하려면, Windows VM에 받은 후 다시 개인 업무 pc로 재전송해야 했다.

그러다가 docker를 알게 되었고, VPN 접속용 docker image를 만들기 시작했다. 많이 사용되는 Cisco VPN부터 시작해서, 리눅스에서 접속 가능한 여러 vpn들을 docker image안에 설치하고 설정한 후, command line에서 vpn open customer1하는 식으로, 고객사 이름만 지정하면 vpn 연결이 docker container안에서 이뤄지게 shell script를 만들어서 docker image와 함께 사용했다. 결국은 근무 중인 팀 내에서는 거의 공식 툴이 되었다.

GitLab server docker image

회사내에서 업무용으로 만들어진 Dockerized application을 제공하기 위해 Docker registry가 필요해서, GitLab CE docker image를 가지고, 개인 업무용 pc에서 충분히 테스트한 후, 제공받은 전용 서버에 바로 이전한 후 운영중이다.

회사 SW 테스트용 docker image

회사 업무를 위해 만든 docker image + shell script이다. 테스트 환경을 수동으로, 업무용 개인 pc에 구성하려면, 능숙한 사람도 몇 일이 걸리고, 경험이 없는 사람은, 몇일이 소요되기도 할 정도로, 복잡한 구성이 문제였다. 개인적으로는 꽤나 익숙했지만, 그럼에도 불구하고 매번 할 때마다 새로운 문제가 나와서, 항상 골머리를 썩고 있다가, docker image로 만들어 버렸다. 시간이 꽤나 소요되었지만, 이제는 대략 30분 이내로, 바로 테스트 가능한 환경을 만들 수 있게 되었다.

개발 환경용 docker image

최근에 시작한 프로젝트에는 IntelliJ를 사용중인데, 개인적으로 하는 업무 관련 dockerized application과 병행하다보니 여러 개의 IntelliJ를 사용해야 하게 되었다. 간단하게 IntelliJ를 설치하고, git, svn, maven과 여러 JDK 버전을 설치해두고, 스크립트로 불러서 사용할 수 있게 만들어서 사용중이다. 전혀 다른 환경의 여러개의 IntelliJ를 사용하거나, 프로젝트별로 따로 IntelliJ를 구성해서 필요시마다 불러서 쓰기 때문에 매우 효율적이다.

Docker 덕분에

VM이라면 불가능했을 많은 것들을 docker를 가지고 효율적으로 해낼 수 있었다. 물론, 이 정도 활용할 수 있기 까지에는 많은 시행착오 또한 있었다. 하지만, 그러한 시행착오가 Dockerfile에 고스란히 차곡차곡 담기게 되었다. 이후 내가 아닌 다른 사람이 사용할 때에는 내가 겪은 시행착오없이, 같은 사용환경을 그대로 가질 수 있게 됨으로써, 효율적인 업무에도 도움이 되었다. 개인적으로도, 회사 업무로도, docker를 native로 즐길 수 있는 리눅스는 정말 좋은 os라고 말할 수 있을 것이다.

Related