도커는 일반적으로 서버에서 사용되기 때문에, 서버 컴퓨터에서의 도커 구조를 살펴보자. 도커를 사용하지 않는 일반 서버의 경우 물리 서버 위에 OS가 있고, OS 위에 바로 프로그램이나 데이터가 올라간다.
반면 도커를 사용하는 서버의 경우, 운영체제 위에서 도커 엔진이 동작하고, 그 위에서 컨테이너가 동작한다. (아래는 이해를 돕기 위해 작성된 예시로, 실제로는 이보다 조금 더 복잡한 구조를 가진다.)
지금까지는 컨테이너를 프로그램과 데이터를 감싸는 껍데기에 불과한 것처럼 설명했으나, 사실 컨테이너는 그냥 껍데기가 아니다. 컨테이너에는 기본적으로 리눅스 운영체제와 유사한 무언가가 들어있다. 다만, 오해해서는 안되는 게 실제 OS가 아니라 말 그대로 OS와 비슷한 무언가이다. 실제 OS는 위의 그림에서도 알 수 있다시피 도커 엔진 아래에서 동작하고 있다.
이미 도커 엔진 아래에 OS가 있는데, 왜 OS와 비슷한 무언가가 컨테이너 안에 들어있는 걸까? 본래 운영체제에는 커널(운영체제의 핵심부분)과 커널을 둘러싼 시스템 도구, 라이브러리, 응용 프로그램, 사용자 인터페이스 등이 포함된다. 이를 편의상 커널과 커널의 주변 부분이라고 칭하겠다.
사실 커널이 운영체제의 핵심이기 때문에, 커널만 사용해도 될 것 같아 보이지만, 실제로는 그렇지 않다. 그 이유로는 확장성, 호환성, 보안성, 생산성, 복잡성 등이 있는데 이 점에 대해서는 자세히 설명하지 않겠다. 다만, 우리가 알아야 할 것은 커널만으로 운영체제(리눅스)를 사용하는 경우는 거의 없으며, 일반적으로 커널의 주변 부분을 커널과 합친 패키지의 형태로 운영체제를 사용한다는 것이다.
리눅스를 사용해본 사람이라면, Ubuntu, RedHat, CentOS, Fedora 등 다양한 리눅스의 배포판에 대해 들어본 적이 있을 것이다. 바로 이 배포판들이 리눅스 커널을 기반으로 만들어진 패키지이다. 사람들이 배포판의 이름으로 Linux를 구별하는 이유도 Linux가 배포판을 통해 사용되기 때문이다.
다시 본론으로 돌아와서, 리눅스와 비슷한 무언가의 정체를 알아보기로 하자. 도커 엔진 아래에서 동작하는 리눅스 운영체제의 주변 부분은 컨테이너 속 프로그램의 명령을 전달받지 못한다. 그러므로 컨테이너 안에 운영체제의 주변 부분을 넣어줌으로써, 프로그램의 명령을 전달받고, 이를 커널에 전달할 수 있도록 만들어주는 것이다.
이러한 도커의 특징 덕분에, 경량적인 실행 환경을 구축할 수 있으며, 호스트 OS의 배포판과 컨테이너에서 사용하는 리눅스 배포판이 달라도 아무런 문제가 되지 않는다.
이전 포스팅에서 도커는 리눅스 OS에서만 사용할 수 있다고 잠깐 언급했었는데, 이제는 이 내용이 이해가 될 것이다. 컨테이너에 들어있는 커널의 주변 부분은 도커 엔진 아래에 리눅스 커널이 존재할 것이라 기대한다. 그러므로 컨테이너 안에서 실행될 소프트웨어는 반드시 리눅스 용 소프트웨어여야 하고, 도커 엔진 아래에서 구동되는 Host OS도 반드시 리눅스 OS여야 한다.
이와 비슷한 맥락으로 도커가 서버에서 주로 사용된다고 말하는 이유도, 리눅스가 주로 서버에서 사용되기 때문이다.
이미지와 컨테이너의 관계를 한 마디로 설명하면 "이미지로 컨테이너를 만든다"이다. 즉, 이미지-컨테이너는 마치 붕어빵틀-붕어빵의 관계인 것이다. 우리가 붕어빵을 먹지, 붕어빵틀을 먹지는 않는 것처럼 실제로 사용되는 것은 이미지가 아닌 컨테이너이다. 그리고 붕어빵틀만 있으면 똑같은 붕어빵을 계속해서 만들어낼 수 있는 것처럼, 하나의 이미지로 똑같은 컨테이너를 계속해서 생성할 수 있다.
특이한 점은, 컨테이너로 이미지를 만들 수도 있다는 것이다. 마치 붕어빵의 모양을 개조한 후, 개조한 붕어빵의 모양을 본따 새로운 붕어빵 틀을 만들어내는 과정 같은 것이다.
지난 포스팅에서 컨테이너는 도커만 있으면, 얼마든지 다른 곳으로 쉽게 이동시킬 수 있다고 했다. 바로 여기에 이미지가 사용된다. 다시 말해, 실제 컨테이너를 이동하는 것이 아니라, 컨테이너의 이미지를 export하여 다른 물리 서버의 도커 엔진에 똑같은 컨테이너를 만들어내는 것이다. 이를 통해 실제 컨테이너가 이동한 것과 동일한 효과를 얻을 수 있다.
도커 이미지를 만들어낼 일보다는, 이미 만들어진 도커 이미지를 가져다 쓰는 경우가 훨씬 더 많다. 우리는 도커 허브라는 곳에서 이미지를 다운로드 받을 수 있다.
>> 도커 허브
도커 허브는 공개된 컨테이너 이미지가 모여있는 곳이다. 이미지의 종류는 매우 다양하므로, 필요에 따라 운영체제의 주변 부분만 있는 이미지부터 모든 설정이 완료된 이미지까지 선택할 수 있다.
다만, 누구나 자유롭게 이미지를 등록할 수 있는 도커 허브의 특성상, 안전하지 않은 이미지도 간혹 존재한다. 그러므로, 어떤 이미지를 선택해야할지 잘 모르겠다면 공식 이미지를 사용할 것을 권장한다. (단, 공식 이미지에는 버전 상의 제약이 있는 경우가 많다.)
컨테이너에 대해 설명할 때, 빠져서는 안 될 중요한 내용이 "컨테이너의 생애주기"이다. 컨테이너는 앞서 설명한 바와 같이 쉽게 만들 수 있기 때문에, 보통 한번 쓰고 버리는 일회용품처럼 사용된다. 즉, 이전에 만들어 둔 컨테이너를 계속 업데이트하는 방식보다는, 업데이트된 소프트웨어가 들어있는 새로운 컨테이너를 사용하는 방식이 더 좋다는 말이다.
이렇게 말하는 이유는 유지 보수를 위해 컨테이너를 지속적으로 업데이트하는 것보다, 새로운 컨테이너를 만드는 것이 훨씬 더 간단하기 때문이다. 그러므로 컨테이너는 [만들기 → 실행하기 → 종료하기 → 폐기하기 → 새로 만들기]의 과정을 거치게 되는데, 이를 컨테이너의 LifeCycle이라고 부른다.
컨테이너를 폐기하면 당연히 안에 있던 데이터도 모두 날아가버린다. 그러므로 도커가 설치된 호스트(본인의 컴퓨터)의 HDD나 SSD 등의 디스크를 마운트(디스크를 연결해 데이터를 기록할 수 있도록 만들어 둔 상태)하여 데이터를 저장해야 한다.
이로써 컨테이너가 폐기되더라도, 데이터는 사라지지 않게 된다. 컨테이너를 마음대로 쓰고 버리는 일회용품과 비슷하다라고 했던 말이 이제는 이해가 될 것이다. 물론, 컨테이너를 폐기하면 다시는 복구할 수 없기 때문에, 폐기하기 전에 저장소에 데이터가 잘 저장되어 있는지 반드시 확인해야한다.