인프라의 기초, Docker에 대해서 알아보자
여러 서비스에서 다양하게 사용되고 있는 Docker에 대해서 알아보자.
main 출처 : 완벽한 it 인프라 구축을 위한 docker.
완벽한 it 인프라 구축을 위한 docker을 읽고 정리한글임을 밝힙니다.
sub 출처 : https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html
Docker?
도커는 애플리케이션의 실행에 필요한 환경을 하나의 이미지로 모아두고, 이미지를 사용해 다양한 환경에서 앱 실행 환경을 구축하고 운영하기 위한 오픈소스 플랫폼입니다. 도커는 내부에서 컨테이너를 사용하는데, 일반적으로 생각하는 물류시스템에서의 컨테이너를 생각해도 좋습니다. 컨테이너로 실어서 다른 곳에 나르는 것처럼, 다양한 개발환경을 컨테이너로 추상화하기 때문에 동일한 환경을 누구에게나 제공할 수 있습니다. 이렇게 동일한 개발환경을 제공하게 되기 때문에 프로그램의 배포 및 관리를 쉽게 할 수 있게 됩니다. 하루종일 환경세팅만 하다가 하루를 날린 경험이 있다면 도커로 환경세팅하는 것이 얼마나 감사한 일인지를 잘 느낄 수 있을 것 입니다. 도커를 이용해서 개발을 하게 되면 폭포형 개발에서 벗어나서 지속적 딜리버리가 가능한 구조의 개발 스타일이 가능해집니다. 도커를 이용한 블루 그린 디플로이먼트 방법이 그 예시 중 하나인데. 블루 그린 디플로이 먼트는 글 하단에서 자세하게 다뤄보도록 하겠습니다.
*참고로 도커 컨테이너를 가장 잘 사용하고 있는 회사는 구글이고, 모든 서비스들이 컨테이너로 동작하며 매주 20억 개의 컨테이너를 구동 한다고 합니다.
Container
도커는 컨테이너 기술을 활용합니다. 컨테이너 기술은 도커가 시작되면서 만들어진 기술은 아니고, 기존에 존재하던 기술이었습니다. 컨테이너란 호스트 OS상에 논리적인 구획, 즉, 컨테이너를 만들고, 어플리케이션을 작동하기 위해 필요한 라이브러리나 애플리케이션 등을 하나로 모아 마치 별도의 서버인 것처럼 사용할 수 있게 만든 것입니다. 호스트 OS의 리소스를 논리적으로 분리시키고 여러개의 컨테이너가 이것을 공유해 사용합니다. 컨테이너는 가볍고 속으로 작동합니다. 컨테이너는 가상화 기술을 사용해서 다양한 기능을 제공하게 되는데, 가상화에 대해서는 이 글을 참고하시면 좋습니다. 가상화.
컨테이너 기술의 장점을 잠깐 소개하자면, 기존의 컨테이너를 이용하지 않는 시스템에서는 하나의 OS 상에서 움직이는 여러 애플리케이션들에 대한 관리를 해주어야 합니다. 다양한 디렉토리와 IP주소를 공유하게 됩니다. 이런 개발 환경에서는 각 어플리케이션이 서로 영향을 받을 가능성이 높습니다. 반면에 컨테이너를 활용하면 OS나 디렉토리, IP 주소 등을 각 어플리케이션이 독립적으로 갖고 있는 것처럼 보이게 할 수 있습니다. 이런 개발환경에서는 마이크로 서비스가 구현될 가능성이 높습니다.
Image
개발자는 도커를 이용해서 자신이 개발한 프로그램에 필요한 모든 것이 포함되어 있는 도커 이미지를 작성합니다. 이 이미지는 도커의 가장 큰 특징 중 하나입니다. 개발자가 개발한 환경을 도커 이미지로 만들면 이 이미지를 기반으로 해서 컨테이너가 동작하게 됩니다. 이렇게 만들어진 이미지는 기본적으로 어디서든 동작합니다. ‘테스트 환경에서는 됐는데, 제품 환경에서는 안돈다’라는 리스크를 줄일 수 있게 됩니다. 이를 통해 지속적 딜리버리가 가능하게 되고 변화에 강한 시스템을 구축할 수 있습니다.
데이터 사이언스 분야에서는 대량의 컴퓨터 리소스를 사용하게 되고 다양한 라이브러리들을 사용하게 되는데, 환경 세팅에 너무 힘을 쓰다보면 모델 개발에 집중할 수 없게 됩니다.(공감하시는 분들 많으실 겁니다( xgboost설치 할 때를 생각해보십시오). 이런 경우 환경을 도커 이미지로 모아두면 어디에서나 다른 환경에서도 작동하는 실행환경을 만들 수 있게 됩니다.
Docker의 기능
도커에는 크게 세 가지 기능이 있습니다.
- Docker Build, 이미지 만들기
- Docker Ship, 이미지 공유
- Docker Run, 컨테이너 실행
Docker Build
도커는 앞서 소개했듯이, 프로그램 실행에 필요한 프로그램 본체, 라이브러리, 미들웨어, OS, 네트워크 등을 하나로 모아서 Image로 만듭니다. 그리고 이 이미지는 컨테이너의 바탕이 됩니다. 보통 Docker에서 빌드시에 권장하는 내용은 하나의 이미지에 하나의 어플리케이션만 넣어 두고, 여러개의 컨테이너를 조합해 서비스를 구축하는 것입니다.
도커 이미지를 만드는 방법은 Docker 명령어를 사용해 수동으로 만들 수도 있고, Dockerfile이라는 설정 파일을 만들어서 작성한 내용을 바탕으로 자동으로 이미지를 만들 수 있습니다. Dockefile을 사용하여 관리하는 것이 지속적 integration과 지속적 딜리버리 관점에서 바람직해 보입니다.
또한 도커 이미지는 겹쳐서 사용할 수 있다는 것이 중요한 특징입니다. 도커에서는 변경이 있었던 부분을 이미지 레이어로 관리합니다.
Docker Ship
만들어진 이미지는 공유가 가능합니다. Docker Hub에 자유롭게 공개를 할 수 있습니다. 많은 이미지가 있으므로 원하는 내용이 있다면 받아서 사용이 가능합니다. 물론 가입은 해야합니다. 또한 도커는 github이나 bitbucket과 연계가 가능하기 때문에 github같은 곳에서 Dockerfile을 관리하고 거기에서 이미지를 자동으로 생성해서 Docker Hub에 공개 할 수도 있습니다.
Docker Run
Docker는 리눅스 상에서 컨테이너 단위로 서버 기능을 작동시킵니다. 이 때 사용되는 것이 도커 이미지입니다. 이미지만 있다면 여러대의 컨테이너를 기동시키는 것도 가능합니다. 도커는 다른 가상화 기술과는 다르게 떠 있는 OS 상에서 프로세스를 실행시키는 것과 같은 속도로 빠르게 실행을 할 수 있습니다.
도커는 하나의 리눅스 커널을 여러 개의 컨테이너가 공유하는 구조입니다. 각 그룹별로 프로세스나 파일에 대한 엑세스는 독립적으로 가져가게 됩니다. 이렇게 독립적으로 사용하게 위해 리눅스의 namespace나 cgroup등의 개념이 사용됩니다.
한 대의 호스트 머신에서 모든 도커 컨테이너를 작동시키고 운용하는 것은 힘들기 때문에 분산환경을 구축하고, 컨테이너 관리를 위해서 오케스트레이션 툴을 사용합니다. 컨테이너 오케스트레이션 툴 중 가장 핫하고 유명한 것은 Kubernetes입니다.
Docker Image 사용해보기
Docker Install
먼저 Docker를 사용하기 위해서는, 도커를 먼저 설치해야 합니다. Mac이나 Windows를 사용하시는 분들은 https://docs.docker.com/get-docker/ 에서 다운받아 간단하게 설치하실 수 있습니다. 설치 후에
1 | docker version |
명령어를 쳤을 때, 이상 없이 나오면 성공입니다.
Docker Image
1 | docker image pull [이미지명] |
이미지를 받는 방법은 간단합니다. pull
명령어를 통해서 원하는 이미지를 받으면 됩니다.
받고 싶은 이미지를 search를 통해서 검색하고 Pull해서 받아봅니다. 받은 이미지들의 목록은 ls
를 이용해면 됩니다.
1 | docker image ls |
생각보다 이미지가 너무 많습니다. 원하지 않는 이미지를 지우고 싶을 때는 rm
을 사용하면 됩니다. 리눅스 명령어와 비슷합니다.
1 | docker image rm [이미지id] |
이미지 id를 적어주고 명령어를 실행시키면, 해당 이미지가 없어진 것을 볼 수 있습니다. 사용하지 않는 이미지를 제거하고 싶다면 prune
을 사용하면 됩니다.
이번에는 컨테이너로부터 이미지를 직접 작성해 봅시다. 작성자에 ‘hyub’이라는 정보를 설정하고 webserver라는 컨테이너를 hyuby/webfront라는 이름으로 태그명을 지정해서 새 이미지를 작성해 보겠습니다. 명령어는 다음과 같습니다.
1 | docker container commit -a 'hyub' webserver tkdguq05/webfront:1.0 |
이렇게 만들어진 이미지의 작성자 정보는 docker image inspect로 확인할 수 있습니다.
만든 hyuby/webfront 이미지를 그러면 업로드 해보겠습니다.
1 | docker image push [이미지명:태그명] |
위와 같은 명령어가 기본값입니다.
1 | docker image push tkdguq05/webserver:1.0 |
혹시 denied: requested access to the resource is denied
이런 에러가 나온다면, Docke Hub에 로그인이 되어있지 않았기 때문일 가능성이 높습니다.
1 | docker login |
이 명령어를 통해 로그인 하도록 합시다. 그래도 에러가 난다면, Docker Hub와 이미지에 있는 작성자 정보가 다르기 때문입니다.
1 | docker image tag tkdguq05/webserver:1.0 [change user]/webserver:1.0 |
이런 식으로 작성자명을 변경한 후에 업로드 해보도록 합니다. 업로드가 완료되면! Docker Hub에 올린 이미지가 공개됩니다.
Docker export
컨테이너나 이미지나 모두 export하고 다시 import 할 수 있습니다. export를 하게되면 tar파일로 떨어지게 됩니다. 이 파일을 import하면 이미지나 컨테이너를 그대로 사용할 수 있습니다.
1 | #docker image save [옵션] <파일명> [이미지명] |
읽는 것도 간단합니다.
1 | docker image load -i export.tar |
다만 컨테이너는 명령이 조금 다릅니다.
1 | #docker container export <컨테이너 시별자> > 저장 파일명 |
이렇게 만들어 놓은 tar파일을 이용해서 이미지를 작성할 수 있습니다. 위에 있는 import 명령어를 활용하면 됩니다.
여기서 한 가지 이상한 점이 있습니다. export/import, save/load가 왜 따로 구분되어 있을까? 하는 점입니다. 둘의 차이는 무엇일까요?
export/import, save/load의 차이
컨테이너를 export하면 컨테이너를 실행하는데 필요한 파일을 모두 압축된 아카이브로 모을 수 있습니다. 이 tar파일을 풀면 컨테이너의 root파일 시스템을 그대로 추출할 수 있습니다. 반면 save는 이미지의 레이어 구조도 포함된 형태로 tar로 모을 수 있습니다.
바탕이 되는 이미지는 같아도 export를 사용할 때와 save 명령을 사용할 때는 내부적인 디렉토리와 파일 구조가 다릅니다.
따라서 docker container export 명령에는 docker image import 명령을, docker image save명령에는 docker image load를 사용하는 게 좋습니다.
인프라의 기초, Docker에 대해서 알아보자