왜, Docker를 써야 하는가?

왜, 물리 서버 환경에서 Container 환경으로 변화해야 할까?

JinStyle
롯데ON 기술 블로그

--

Docker란?

Docker는 컨테이너 기술 기반의 오픈소스 가상화 플랫폼입니다

container란?

운영체제 수준의 가상화 기술로 리눅스 커널을 공유하면서 프로세스를 격리된 환경에서 실행하는 기술입니다.

Docker의 시작

Docker는 2013년 3월 산타클라라에서 열린 Pycon에서 Solomon Hykes가 The future of Linux Ciontainers(리눅스 컨테이너의 미래)라는 제목으로 세션을 발표하면서 세상에 처음 알려졌습니다.

특징

운영체제 수준의 가상화

컨테이너는 운영체제 수준의 가상화 기술입니다. 별도의 하드웨어 에뮬레이션 없이 리눅스 커널을 공유해 컨테이너를 실행하며, 게스트 OS 관리가 필요하지 않습니다.

빠른 속도와 효율성

하드웨어 에뮬레이션이 없으므로 컨테이너는 아주 빠르게 실행됩니다. 프로세스 격리를 위해 아주 약간의 오버헤드가 있지만 일반적인 프로세스를 실행하는 것과 거의 차이가 없습니다. 또한 하나의 머신에서 프로세스만큼 많이 실행하는 것이 가능합니다.

높은 이식성(=확장성)

모든 컨테이너는 호스트의 환경이 아닌 독자적인 실행 환경을 가지고 있습니다. 이 환경은 파일(Dockerfile)들로 구성되며, 이미지 형식으로 공유될 수 있습니다. 리눅스 커널을 사용하고 같은 컨테이너 런타임을 사용할 경우 컨테이너의 실행 환경을 공유하고 손쉽게 재현할 수 있습니다.

롤백

계층화에서 가장 유용한 부분은 아마도 롤백 기능일 것입니다. 모든 이미지에는 계층이 있으며, 현재의 이미지 반복이 적절하지 않은 경우 이전 버전으로 롤백하면 됩니다. 이 기능은 애자일(agile) 개발 접근 방식을 지원하며 툴 관점에서 실제로 지속적인 통합 및 연속 배포(Continuous Integration and Deployment, CI/CD) 를 수행하는 데 도움을 줍니다.

OS overhead가 없으니 Start Time도 빠르고 자원 효율성도 높습니다. 그리고 가장 큰 장점 중의 하나로 Host OS가 어느 것이든지 상관없이 도커 엔진만 있으면 배포될 수가 있습니다.

운영체제 수준의 가상화 & 빠른 속도와 효율성

Virtual Machines(하드웨어 레벨의 가상화)

  • Virtual Machines(VM ware, VirtualBox) 의 경우 하이퍼바이저(virtual box, Xen, KVM, VMware) 위에 Guest OS가 올라가는데 그 위에 Binary와 라이브러리 등을 모두 구성해야 하기에 무겁고 성능 저하가 발생합니다. (오버헤드 발생)

Docker(Linux)(운영체제 레벨의 가상화)

  • VM과 HostOS 까지 설치는 동일합니다. 하이퍼바이저가 필요 없고 도커 엔진만 있으면 그 위에 어플리케이션과 바이너리 및 라이브러리가 포함된 컨테이너만 올리면 되는 구성입니다.

하이퍼바이저 가상화 vs 컨테이너형 가상화

참고

베어메탈(Bare Metal)이란 용어는 원래 하드웨어 상에 어떤 소프트웨어도 설치되어 있지 않은 상태를 뜻합니다. 즉, 베어메탈 서버는 가상화를 위한 하이퍼바이저 OS 없이 물리 서버를 그대로 제공하는 것을 말합니다. 따라서 하드웨어에 대한 직접 제어 및 OS 설정까지 가능합니다.

높은 이식성

OS에 따른 설치 과정(gitlab 설치)

  • ubuntu에 설치 시
sudo apt-get update
sudo sudo apt install -y ca-certificates curl openssh-server
curl <https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh> | sudo bash
sudo EXTERNAL_URL="<http://gitlab.gitlab.com/>" apt-get install gitlab-ce
gitlab-ctl reconfigure
sudo ufw allow OpenSSH
sudo ufw allow http
sudo ufw allow https
  • centos에 설치 시
sudo yum install curl policycoreutils-python openssh-server
sudo yum install postfix
sudo systemctl start postfix
sudo ystemctl enable postfix
sudo systemctl status postfix
curl <https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh> | sudo bash
sudo EXTERNAL_URL="<http://gitlab.gitlab.com>" yum install -y gitlab-ce
gitlab-ctl reconfigure
curl firewall-cmd --permanent --add-service=80/tcp
curl firewall-cmd --permanent --add-service=443/tcp
curl systemctl reload firewalld

docker 사용 시

$ docker run --detach --hostname gitlab.gitlab.com --publish 443:443 --publish 80:80 --publish 2222:22 --name gitlab --restart always --volume /srv/gitlab/config:/etc/gitlab --volume /srv/gitlab/logs:/var/log/gitlab --volume /srv/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce:latest

서버에 직접 설치하는 경우에는 OS 버전 및 환경에 따라서 설치 명령어가 달라질 수 있지만 docker로 설치 시에는 어느 운영체제라도 상관없이 도커엔진이 설치되어 있는 환경이라면 위에 명령어로 설치 가능합니다.

A, B 서버에 gitlab 를 설치해 본다면?

동일한 로직을 처리하는 두 서버가 있다는 가정을 해보겠습니다.

A 서버는 몇 달 전에 구성했고 B 서버는 이제 막 구성했다면, 운영체제부터 컴파일러, 설치된 패키지까지 완벽하게 같기는 쉽지 않습니다. 그리고 이러한 차이점들 때문에 크고 작은 장애가 발생할 수 있는 부분들이 존재합니다. A 서버는 잘 되는데 B 서버는 왜 죽었지?와 같은 일(혹은 그 반대)이 벌어지는 겁니다.

  • gitlab의 최신 버전에 새로 추가된 기능을 사용했다
  • gitlab의 업데이트 부분 코드에 버그가 있다
  • gitlab의 버전이 다르다
  • gitlab의 의존하는 라이브러리의 버전이 다르다

장애 원인을 빨리 찾으려면 A 서버를 잘 아는 사람이 필요한데, 마침 A 서버를 구성했던 사람이 팀을 옮겼거나 퇴사해 옆에 없습니다. B 서버를 구성한 작업자는 A 서버가 구성되고 운영된 모든 과정을 파악하려고 애를 씁니다. 그래야 B 서버와의 차이점을 알아낼 수 있기 때문입니다.

여기서 두 서버 간 구성 시점은 몇 달 정도 차이지만, 몇 년씩 차이 나는 경우도 있습니다. 처음에는 각 서버 간 차이점이 별로 없다 생각할 수 있지만, 더 많은 서버가 있고 기간이 길어진다는 가정을 해 보면, 그 차이는 상상할 수 없을 정도로 커질 것입니다. 이 때, Docker를 활용해 서비스 구성을 하면 멱등성이 보장되므로, 관련 장애에 대해 사전에 예방할 수 있습니다.

멱등성이 보장되는 Docker image 만들기

기본적으로 Docker image의 경우는 Docker Hub(https://hub.docker.com/)라는 Public Repository에서 다운로드 받습니다.

여기서 주의해야 될 점은 docker pull [옵션] <이미지명>[:태그명]으로 다운로드 받을 때 latest나 버전명을 지정해주지 않으면, 며칠 혹은 몇 개월 뒤에 해당 이미지를 다운로드 받을 때 두 개의 이미지가 완전히 같다는 것을 보장할 수 없습니다. 따라서 버전명을 명시해 다운로드 받아 주는 것이 좋습니다.

  • docker pull nginx:latest
  • docker pull nginx:1.21.1

기본이 되는 image에 회사 환경 별로 필요한 설정을 추가해 image화 하면 해당 image는 private한 image로 다른 서버에서 실행해도 동일한 output이 나오게 됩니다.

--

--