도커는 동일한 환경을 생성하기 위한 기술입니다. 도커에서 가장 중요한 키워드는 이미지와 컨테이너 입니다.
도커 이미지는 컨테이너 실행에 필요한 파일과 설정값들을 포함하고 있는 코드 덩어리 입니다. 이미지는 상태값을 가지지 않고 변하지 않습니다.
컨테이너는 이미지를 실행한 상태이고 추가되고 수정되는 값들은 컨테이너에 저장됩니다. 같은 이미지에서 여러개의 컨테이너를 생성할 수 있고 각 컨테이너 마다 다르게 수정되고 변경될 수 있지만 이미지는 변하지 않고 그대로 남아있습니다.
Docker Hub은 docker 커뮤니티 입니다. 도커 Hub에서 다른 사람들이 만들어둔 이미지를 쉽게 다운 받을 수 있습니다. 다른 사람이 생성한 mysql, redis, rabbit mq 등등의 기술들을 이미지로 쉽게 개발환경을 만들수있습니다.
도커 이미지는 수정이 불가능합니다. 그럼 어떻게 위에서 원하는 기술스택의 이미지를 다운 받아서 설정을 변경할 수 있는지 그 방법을 알아보겠습니다.
이미지는 변경이 불가능하지만 컨테이너는 변경이 가능하다고 했습니다. 그럼 이미지를 수정하기 위해선 바로 이미지에서 수정하는 것이 아니라 이미지로 컨테이너를 생성하고 컨테이너에서 변경사항을 저장한 뒤에 해당 컨테이너의 상태를 이미지로 저장해서 사용하는 스냅샷 방식을 사용하면 됩니다.
실제로 스냅샷 보다 더 많이 사용되는 방식이다. 도커 파일은 스냅샷의 방식을 하나의 파일안에 순서대로 명령어를 입력하여 위 동작을 자동화 시킨것과 같다. 스냅샷은 각각의 동작을 각 스탭마다 수동으로 수행했는데 도커 파일은 각 스탭을 자동화하여 실행시킨다. 즉 명령어들의 뭉치를 묶어서 하나의 파일로 만든 뒤에 해당 파일을 build 하여 이미지를 생성하는 것이다.
Docker는 동일한 개발환경을 빠르게 만들어주기 위해서 사용된다고 하였다. 좀더 구체적으로 도커가 사용되는 상황을 알아보도록 하겠다.
스타트업이 있다고 해보자 해당 스타트업은 기존 고객이 100명이였다. 그래서 한대의 서버에서 충분히 발생하는 트래픽을 컨트롤할 수 있었다. 그런데 최근 업데이트를 진행하면서 고객이 300명이 되었다. 트래픽이 3배 증가한 상황이다. 기존에는 한대의 서버에서 모든 트래픽을 대처 할 수있었지만 지금은 불가능하다. 따라서 추가로 서버를 증설하기로 하였다. 똑같은 서버를 2개 더 만들어 총 3대의 서버를 운영하기로 하였다. 그럼 개발자들은 새로운 서버에 기존의 서버에서 설정된 환경들을 똑같이 설정해줘야 한다. 이번에는 2개만 하면되지만 100개를 해야한다면 힘들것입니다.
도커 등장 이전에는 자동화 스크립트를 작성하여 자동화 시켰지만 도커 등장 이후에는 더욱 손 쉽게 실행 환경 관리가 가능해졌다. 그때마다 변경사항에 맞게 스트립트를 다시 작성하거나 수정할 필요없이 그냥 이미지를 통해서 컨테이너를 생성해주기만 하면 되기 때문이다.
Docker Hub은 도커의 대표 커뮤니티이다. 도커의 사용자가 증가함에 따라 다양한 회사들에서 재품의 오피셜 이미지를 제공한다. 제품의 업데이트가 있을 때 마다 새로 오피셜 이미지를 배포한다. 우리는 공식 오피셜 이미지를 가져다 쉽게 사용할 수 있다.
도커 이미지를 수정하면 기존에 이미지에서 수정할 부분이 추가되고 추가된 상태의 이미지를 만들고 하는 식으로 구성되어 있다. 이번에 대로 만든 이미지는 이전까지이의 이미지들이 누적되어 있는 상태에서 새로운 것이 추가되서 만들어진 것이다. 즉 도커 이미지는 layer 계층 구조로 되어있다. 첫 번째 이미지를 베이스 이미지로 삼아서 계속해서 위로 필요한 것을 쌓아 올리는 구조이다.
a2라는 이미지는 a1라는 이미지를 참조해서 생성한 이미지라고 가정해보자, 그럼 초기 docker images안에 아무것도 들어있지 않은 상태에서 a2를 생성하면 도커 이미지에 a1,a2 두개의 이미지가 생성된다. 왜냐면 a2는 a1을 참조해서 생성한다고 Dockerfile에서 선언했기 때문이다. 그렇다면 여기서 a2가 a1을 참조하고 있는 상태에서 a1을 삭제하려고 한다면 참조하는 자식 이미지가 존재하니 삭제가 불가능하다고 표시된다.
초기 도커의 CI는 기존에 사용하고 있던 컨테이너에 추가된 코드를 추가해주고 이미지를 생성하고 다시 컨테이너를 실행 시켜줌으로써 지속적인 통합 과정을 수행하였다. 하지만 현재 사용하고 있는 서버를 다른 서버로 옮겨야되는 경우에 처음부터 지금까지 모든 이미지를 옮겨줘야되는 번거로움이 존재했다. 그래서 도커 이미지도 git hub 처럼 별도의 레지스트리에 저정하고 쉽게 다운받을 수 있는 Docker hub이 등장하였다.
이젠 Docker hub을 통해서 추가된 부분을 push를 통해서 손쉽게 통합할 수 있게되었고 pull을 통해서 최선 버전의 도커 이미지를 다운받을 수 있게되었다.
하지만 docker hub에도 문제가 있는데 개인 프로젝트라면 상관이 없지만 회사 프로젝트의 경우에 레포지토리를 private로 설정해야하는데 한 계정당 한개의 private 계정만 소유가 가능하고 그 이후에는 과금이 발생한다. 과금이 문제가 되지 않는다면 docker hub을 사용하는게 베스트겠지만 과금이 문제라면 직접 레지스토리를 생성해서 사용해야 한다.
브릿지 모드는 도커의 default 네트워크 모드이다. 리눅스 브릿지는 브릿지 안에 있는 컨테이너들이 독립적으로 통신할수있게 해주는 기술이다. 이를 통해서 호스트와 컨테이너, 컨테이너와 컨테이너끼리 통신이 가능하게되었다. 각각의 컨테이너는 ip를 할당을 받는데 해당 ip를 통해서 통신할 수 있다. 하지만 여기서 할당되는 ip는 고정된 값이 아니기에 원하는 원하는 컨테이너와 통신을 하기 위해서 매번 해당 컨테이너가 가지고 있는 ip를 확인하고 연결을 해야하는데 해당 작업은 매우 번거롭다. 이를 해결하기 위해서 link 라는 옵션을 사용한다. link를 사용하여 컨테이너를 생성하면 컨테이너의 host 파일에 해당 DNS를 추가하게된다. 혹은 직접 정의한 네트워크 브릿지를 사용해서 통신하는 방법이 있다.
host모드는 각각의 컨테이너가 독립적인 네트워크를 가지는게 아니라 host와 동일한 네트워크를 같이 사용하는 모드이다.
container모드는 해당 컨테이너의 네트워크 구성을 참조하는 컨테이너와 동일하게 구성해주는 모드이다. a라는 컨테이너가 b라는 컨테이너를 참조하여 container 모드로 생성하면 a는 b와 동일한 네트워크 환경을 갖게된다.
none 모드로 컨테이너를 생성하면 네트워크 영역을 갖지만 통신에 필요한 인터페이스는 없이 컨테이너가 생성된다.
docker-compose는 도커에서 컨테이너 생성 과정을 자동화 해주는 도구이다. 매일마다 정산을 위해서 컨테이너를 새로 시작해줘야되는 서비스가 있다고 가정했을 때 docker-compose를 사용하면 보다 쉽게 수행이 가능하다. 이렇게 도커를 관리하는 부분을 코드화 시켜서 사용하면 인프라 전체를 관리하기가 매우 쉬워진다.