안경잡이개발자

728x90
반응형

예제를 통해 도커파일(Dockerfile) 명령어 알아보기

나동빈


  지난 시간에는 간단한 형태의 도커파일(Dockerfile)을 작성하여 직접 도커 이미지(Docker Image) 파일을 생성하는 방법을 알아보았습니다. 이번 시간에는 도커파일에 사용되는 다양한 옵션 및 명령어에 대해 알아보는 시간을 가져보도록 하겠습니다. 


  먼저 도커 이미지를 만들 때 기존에 존재하는 다양한 라이브러리를 섞어서 이미지를 만들 수 있다는 것을 이해해봅시다.


※ 고래의 말(whalesay) 이미지 사용해보기 ※


  고래의 말(Whale Say)는 도커에서 튜토리얼 목적으로 만든 간단한 형태의 이미지입니다. 그냥 고래가 나와서 무슨 말을 하는 것 말고는 전혀 기능이 없습니다. (말 그대로 똥 같은 프로그램이죠...)



docker search (검색할 이미지): 도커 허브(Docker Hub)에서 이미지를 검색합니다.



  이제 위와 같이 docker run docker/whalesay cowsay Hello!를 입력해서 고래가 'Hello!'라고 말하도록 해봅시다. 여기에서 cowsay는 whalesay 이미지에서 사용할 수 있는 기능 중 하나이고, 그 뒤에 'Hello!'를 넣어서 이러한 문장을 고래가 말하도록 설정할 수 있는 것입니다.



  출력할 문장을 'Hi!'로 바꾸었을 때도 정상적으로 작동하는 것을 알 수 있습니다. 이제 우리가 해 볼 것은 단순히 직접 고래가 할 말을 넣어주는 것이 아니라 고래가 랜덤으로 의미 있는 격언을 말하도록 해보는 것입니다.


※ 랜덤으로 격언을 출력하는 고래 이미지 만들기 ※


  지난 시간에 배웠던 내용과 흡사하게 하나의 이미지를 만들어봅시다. 우리가 다운로드 받았던 whalesay 이미지는 기본적으로 리눅스 운영체제 위에서 고래가 말을 하는 것을 출력하는 기능이 있는 이미지입니다. 따라서 apt-get 명령어를 사용해 다른 라이브러리도 설치하도록 할 수 있어요. 우리는 그 중에서 랜덤으로 격언을 반환하는 fortune 라이브러리를 사용할 겁니다. 따라서 바로 도커 파일을 작성해봅시다.



FROM docker/whalesay


RUN apt-get update

RUN apt-get install -y fortune # fortune 라이브러리를 기존의 이미지에 추가적으로 설치합니다.


CMD /usr/games/fortune -a | cowsay # 설치된 fortune 라이브러리를 실행해 나온 격언 문장을 cowsay 명령어의 파라미터로 전달합니다.


  위 소스코드를 보시면 랜덤 문장을 cowsay 명령어의 파라미터로 전달하여 랜덤으로 문장을 고래가 출력하도록 만든 것을 알 수 있습니다.



docker build --tag mywhale .


  이 명령어로 우리가 만든 도커 파일을 이용해 mywhale이라는 이름의 이미지를 생성할 수 있습니다.



  이제 docker images 명령어를 이용해 생성된 이미지를 확인할 수 있습니다. 기존에 존재하는 docker/whalesay 이미지에 덧붙여서 273MB의 mywhale 이미지가 생성되었네요.



  이제 docker run mywhale을 입력하여 이미지를 실행할 때마다 랜덤으로 격언이 출력되는 것을 확인할 수 있습니다.


  여기까지 예제를 잘 따라오셨다면 기본적으로 도커파일이 어떠한 기능을 가지고 있는지 대략적인 이해가 되셨을 겁니다. 이제 보다 자세하게 도커파일에서 사용될 수 있는 명령어를 확인해봅시다.


※ 도커파일 명령어 알아보기 ※


- FROM: 베이스 이미지를 지정하는 명령어입니다. FROM ubuntu:14.04와 같은 방식으로 사용하고, 버전으로는 latest를 넣을 수도 있습니다. 하지만 가능하면 14.04와 같은 정확한 버전명을 기입하는 것이 좋습니다.


- RUN: 이미지 상의 리눅스 커맨드를 실행하도록 해주는 명령어입니다.


  예를 들어 RUN apt-get -y fortune을 하면 리눅스에서 fortune 라이브러리를 다운로드 받게 됩니다. 이 때 RUN 명령어는 일반적으로 한 번 사용될 때마다 레이어가 하나씩 추가됩니다. 그래서 RUN 명령어를 어떻게 쓰냐에 따라서 이미지의 크기가 달라질 수 있습니다. 그러므로 여러 개의 명령어가 이어지는 경우 다음과 같이 &&를 이용해 하나의 라인에 명령어를 쓰는 것이 좋습니다.


  RUN apt-get update && apt-get install -y fortune


- CMD: 이미지 명령을 지정하기 위해 사용하는 명령어입니다. 예를 들어 CMD ["nginx"]라고 입력하면 nginx 서버를 실질적으로 구동시키게 되는 것입니다.


- EXPOSE: 컨테이너에서 공개하고자 하는 포트를 정의하기 위해 사용하는 명령어입니다. 80, 443 등의 포트가 일반적으로 많이 사용됩니다.


- ENV: 환경변수를 정의하기 위해 사용하는 명령어입니다. 'ENV NGINX_VERSION (버전명)'과 같은 방식으로 사용할 수 있습니다.


- ADD, COPY이미지 안에 파일을 복사하고자 할 때 사용할 수 있는 명령어입니다. 'COPY jerkins.sh /user/local/bin/jenkins.sh'와 같은 방식으로 사용할 수 있습니다. 이 때 압축을 풀 필요 없이 단순히 이미지 안에 넣을 때는 COPY를 쓰고, 압축까지 푸는 등 후처리가 필요하다면 ADD를 사용합니다.


- WORKDIR작업위치를 지정할 때 사용하는 명령어입니다.


- ONBULID이미지 빌드 이후에 실행되는 명령을 지정하기 위해 사용하는 명령어입니다.


- ENTRYPOINT: 이미지 실행 명령을 다시 지정하기 위해 사용하는 명령어입니다. 기본적으로 이미지는 한 번 만들어지면 수정할 수 없다는 점에서 마치 프로그램을 작성하듯이 쉘 스크립트를 작성하여 엔트리 포인트로 걸어놓고 사용할 수 있습니다. 아까 다루었던 예시에서 cowsay에 다른 명령을 이용해 적용했던 것을 떠올리시면 됩니다.


- VOLUME: 바인딩하고자 하는 디렉토리를 정의할 때 사용하는 명령어입니다. 흔히 리눅스에서의 마운트를 생각하시면 됩니다. 컨테이너 자체는 stateless한 특성을 가지고 있습니다. 하지만 특정한 데이터를 저장하는 등의 기능이 필요하다면 호스트 서버의 특정 위치와 컨테이너의 특정 위치를 마운팅 시킬 수 있습니다. 이는 실제로 굉장히 많이 사용되는 요소 중 하나입니다.


- USER: 사용자를 지정하기 위해 사용하는 명령어입니다. 별도로 지정하지 않으면 사용자는 기본적으로 'docker'로 설정됩니다. 기본적으로 docker라는 하나의 사용자가 있다고 가정을 하고 동작하고, 이러한 docker 사용자가 없거나 현재 사용자가 docker 그룹에 포함 되어 있지 않다면 Permission 오류가 발생할 수 있습니다. 


  일반적으로 이러한 사용자 문제는 컨테이너 자체를 실행할 때는 별 문제가 되지 않습니다. 주로 볼륨(Volume) 마운팅 기능을 이용할 때 문제가 됩니다. 마운팅을 수행하면 서버의 특정 디렉토리에 액세스를 하고자 하여 문제가 발생할 수 있습니다. 그럴 때는 호스트에 도커와 동일한 사용자를 만들고, 사용자의 UID 값도 맞추어주어 해결할 수 있습니다.


  이렇게 사용자 기능을 쓰는 것에 대해서는 찬반의 의견이 다수 존재합니다. 이는 권한 관리의 문제가 있기 때문이고, 컨테이너 외부에서도 최고 권한(root)으로 돌아가도록 설계된 경우 관리 책임의 소지도 함께 다루어야 될 문제이기 때문입니다.

728x90
반응형