docker image 이해 및 배포실습

2019-12-01

.

Data_Engineering_TIL_(20191201)

[학습한 Contents]

1) 주제 : 컨테이너 기반 가상화 플랫폼 ‘도커(Doker)’의 이해 - 이미지 만들고 배포하기 / SK T아카데미 온라인강의

2) URL : https://tacademy.skplanet.com/live/player/onlineLectureDetail.action?seq=125

[필기노트]

  • 이미지는 특정 프로세스를 실행하기 위한 환경이다. 이미지는 아래와 같이 설명할 수 있다. 계층화된 파일 시스템, 파일들의 집합, 프로세스가 실행되는 환경도 결국 파일들의 집합

즉 어떤 프로세스를 실행시키기 위한 파일들의 총집합 이라고 이해하면 된다.

  • 컨테이너를 이미지로 저장하기

도커의 파일시스템은 어떤 파일 하나의 덩어리가 아니라 레이어로 구성이 되어 있다. 예를 들어서 처음에 A라는 파일이 있고, 그게 하나의 레이어를 이룬다고 했을때 그 위에다가 B라는 파일을 덭붙여서 레이어를 하나 더 올릴 수 있다. 그래서 docker pull 또는 docker run을 했을때 이미지를 다운받으면 하나의 파일만 받아오는게 아니라 그 밑에 깔려있는 레이어들의 파일들도 쭉 받아오게 된다. 즉 도커의 이미지들을 쭉 받아 오는것이고 이미지들을 묶어서 하나의 이미지가 된다고 생각하면 된다.

대부분의 레이어들은 read만 가능하고, 컨테이너로 실행했을때는 거기에다가 writable 한 레이어를 하나 더 추가할 수 있다.

이미지의 기초적인 구조는 아래 그림과 같다. 그림에 base image라고 되어 있는데 실제로 베이스 이미지가 존재하는 것은 아니고, 아무것도 없는 리눅스 커널만을 사용하기 위한 이미지라고 생각하면 된다. 더불어서 rootfs가 있고, 그 위에다가 base image에 필요한 것들을 추가한 상태가 되겠다. 아래서부터 한단계씩 파일이 추가되는 것이다.

1

예를 하나 들어보자 리눅스 이미지를 하나 만들고 싶은데 내가 만든 리눅스 이미지에는 git이 포함되도록 만들고 싶다. 디폴트로 리눅스에는 기본적으로 git이 없기 때문에 깔아야한다.

그래서 우리는 위의 그림과 같이 리눅스 이미지(base image)를 컨테이너로 실행시켜서 거기에 git을 설치하고, 그거를 저장해서 하나의 이미지로 만들어 보겠다.

참고로 docker run한 상태로 작업을 막하고 그 와중에 그냥 exit로 나가버리면(컨테이너 프로세스를 종료하면) 그 이미지 위해서 작업했던 내용은 다 날아가버린다. 예를 들어서 docker run 명령어로 리눅스 이미지로 컨테이너를 띄운 다음에 /etc 위치에서 a.txt를 생성한 다음에 exit로 나오고 다시 docker run 명령어로 리눅스 컨테이너를 띄운다음에 /etc 위치로 가보면 a.txt 파일은 없다.

따라서 내가 작성한 작업들에 대해 저장을 하려면 따로 조치를 해줘야 하는 것이다.

먼저 docker run -it ubuntu:latest bash 명령어로 우분투 이미지를 컨테이너로 띄운 다음에 쉘로 들어가준다.

git version 명령어를 입력하면 버전 정보가 안뜰것이다 왜냐하면 디폴트로 깃이 안깔려 있기 때문에 당연하다.

그래서 우리는 apt-get update 명령어 후 apt-get install git 명령어를 실행하여 git을 설치해준다.

그런 다음이 이 컨테이너가 띄워진 터미널 창은 그대로 두고 새로운 터미널 창을 띄워서 ec2로 접속한 다음에 docker diff 컨테이너ID 명령어를 실행하면 다운받은 이미지로부터 컨테이너에서 어떤 변경사항이 있었는지 알 수 있다.

2

위의 그림과 같이 많은 파일들이 추가가되고 변경된 것을 확인 할 수 있다.

그래서 우리는 이런 변경된 사항들까지 전부 포함해서 저장을 하려고 하는데 이런 작업이 이미지를 만드는 개념이라고 할 수 있다.

아래 그림과 같이 git을 우리가 쓰는 것처럼 docker commit 컨테이너ID 새로저장할이미지이름를 입력하면 이미지를 만들 수 있다. ubuntu:git은 ubuntu라는 이름에 git이라는 테그를 붙인것과 같다.

그런 다음에 docker images 명령어로 이미지 목록을 확인하면 우분투라는 이름에 git 테그를 가진 이미지가 새롭게 만들어진 것을 알 수 있다.

3

이제 새로만든 이미지는 위에 상태변화 그림에서 custom image가 된 것이다.

그래서 이 새로 만든 이미지를 이용해서 컨테이너를 띄우면 우분투가 깔려있는 가운데 깃도 설치가 되어 있는 것을 아래 그림처럼 확인할 수 있다.

4

지금까지 했던 내용들을 도식화 하면 아래 그림과 같다.

5

state 1 = Ubuntu:latest image

state 2 = Ubuntu:latest image를 기반으로 실행한 컨테이너에서 git을 설치

다시한번 언급하지만 state 2에서 아무런 작업없이 그냥 exit로 종료시켜버리면 그동안 작업했던 내용이 다 날아간다.

state 3 = state 2를 docker commit 명령어를 실행하여 또다른 하나의 이미지로 만듬

이번에는 위의 작업을 Dockerfile로는 어떻게하는지 실습해보자

Dockerfile은 이미지 생성과정을 기술한 도커 전용 DSL이라고 할 수 있다.

아래 그림과 같이 임의의 폴더를 하나 만든다음에 거기로 이동하여 vi Dockerfile 명령어로 Dockerfile을 만들어준다. Dockerfile의 내용은 아래 그림을 참고한다.

FROM ubuntu:latest 명령어는 베이스 이미지를 어떤거를 할지 지정하는 것이고,

RUN apt-get update와 RUN apt-get install -y git 명령어는 베이스 이미지 위에서 실행할 명령어를 기술해 놓은 것이다.

그런다음에 docker build -t ubuntu:gitv2 . 명령어를 실행해준다. 그러면 ubuntu gitv2라는 새로운 이미지가 생성된다.

.은 지금디렉토리 아래에 있는 도커파일을 사용해서 이미지를 만들겠다 라는 의미고, -t는 지금 만드는 이미지를 어떻게 할것인가에 대한 의미이다.

Dockerfile을 이용해서 별도의 diff나 commit 없이 바로 이미지를 빌드 할 수 있다. 실제 현업에서도 Dockerfile을 이용해서 많이 이미지를 빌드하는 편이다.

6

우리가 어떤 어플리케이션을 띄우기 위해서는 결국에는 Dockerfile을 잘 만들어야 한다.

그 밖에 자주쓰는 Dockerfile 명령어에 대해 알아보자

ADD : 파일 추가 시

ex) ADD test.txt /temp/text.txt (ADD 추가할파일 파일이추가될경로)

RUN : 명령어 실행 시

ex) RUN apt-get install -y git (RUN 명령어)

WORKDIR : 작업디렉터리(RUN 명령어가 실행되는 디렉토리) 변경

ex) WORKDIR /tmp

ENV : 환경변수값을 미리 지정할 수 있는 명령어

ex) ENV AWESOME_VAR FOOBAR

EXPOSE : 컨테이너 실행 시 노출시킬 포트

EXPOSE 포트번호

ex) CMD 3000

CMD : 이미지의 기본실행 명령어 지정

CMD 명령어

예를들어서 docker run -it ubuntu:16.04 bash에서 bash가 기본실행 명령어를 말한다. 이미지가 컨테이너로 실행되면서 주는 기본명령어라고 생각하면 된다.

그러면 도커 이미지를 이용하여 실제 어플리케이션 이미지를 만들어보고 배포해보자.

깃허브에서 루비서버 소스파일을 다운받고 소스파일중에 Dockerfile을 실행시켜서 루비서버를 띄우고 그거를 이미지로 만들어보자.

아래그림과 같이 실습을 진행한다.

7

우리가 위에서 했던 작업은 아래 도식화 된 그림과 같이 기존의 베이스 이미지에서 계속해서 무언가 커스텀한 업데이트가 계속 일어나고 그게 계속해서 쌓이는 형태이다.

컨테이너를 만들고 무언가 수정하고 이미지를 만들고, 다시 이 과정을 반복하고, 또 반복하고 이런 형태인 것이다.

8

그래서 최종적으로 위의 도식화된 그림과 같이 만들어진 컨테이너에서 CMD 명령어를 통해 어플리케이션을 띄우게 된다.

그래서 우리가 만든이미지를 도커 허브(레지스트리)에 올려보자

아래 그림과 같이 도커 허브에 이미지를 업로드한다.

9

이번에는 새로운 서버 환경에서 도커허브에 올린 내 이미지를 가져와서 컨테이너로 띄어보겠다.

아래 그림과 같이 수행한다.

10