Docker : 컨테이너 편

Docker 2019. 2. 15. 15:49

[Docker : 기초 편]

[Docker : 설치 편]

[Docker : 컨테이너 편]



Docker 컨테이너 개요



지난 Docker : 설치 편에 이어 이번 내용은 도커 핵심기술인 컨테이너에 대한 설명을 하고자 한다.

컨테이너라고 하면 무엇이 떠오르는가?



사무실의 전경





일반적으로 컨테이너라고 하면 대형 선박에 싣는 규격화 선적물을 떠올릴 수 있다.

도커에서 컨테이너는 독립적이고 규격화된 프로세스를 의미한다.





Docker 이미지



도커 컨테이너와 도커 이미지는 뗄래야 뗄 수 없는 사이 이므로 컨테이너를 설명하기 전 도커 이미지에 대해 간략히 알아보도록 하자 먼저 도커 이미지는 도커 컨테이너의 기반이 되는 읽기전용 데이터라고 생각하면 이해가 쉽다. 마치 가상 드라이브에 마운트 시키는 iso파일과 비슷한 개념이라고 보면 된다.

(맨 끝의 어플리케이션들은 각각의 Linux OS를 기반으로 생성한 각각의 컨테이너다.)



도커엔진을 통해 컨테이너를 생성하기위한 이미지를 내려받고 그 이미지를 기준으로 여러 컨테이너들을 생성 할 수 있다. 예를들어 Ubuntu기반의 Apache를 실행하기 위해서는 Ubuntu 이미지를 내려받고 도커를 통해 이미지에 접근 및 컨테이너 생성 후 Apache, MariaDB 등 원하는 응용프로그램을 내려받아 설치 할 수 있다.




Docker 컨테이너 생성



그럼 지금부터 Ubuntu 도커 이미지를 내려받고 아파치 설치 후 80포트로 접근이 되는지 확인하는 간단한 실습을 진행하겠다. 우선 지난 Docker : 설치 편의 마지막 명령은 도커 설치명령만 수행 한 상태로 마무리 되었으므로 도커 명령을 실행 해도 바로 실행 할 수 없을 것이다. 먼저 도커 서비스를 활성화 시켜주도록 하자


# systemctl start docker # systemctl status docker

● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled) Active: active (running) since Thu 2019-02-14 18:39:46 KST; 18min ago Docs: http://docs.docker.com Main PID: 19866 (dockerd-current) Tasks: 17 Memory: 309.0M CGroup: /system.slice/docker.service ├─19866 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/... └─19870 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/contain...



도커 서비스 활성화가 완료 되었으면 



묻지도 따지지도 않고 Ubuntu 이미지를 내려받도록 하자.


(물론 강요는 아니며 이미지는 각자 편의에 따라 사용하기를 추천한다 CentOS가 더 편하다면 CentOS로 내려받도록 하자.) 필자는 docker pull ubuntu:14.04 명령을 통해 이미지를 내려받았다.


# docker pull ubuntu:14.04

Trying to pull repository docker.io/library/ubuntu ... 14.04: Pulling from docker.io/library/ubuntu e53f134edff2: Pull complete efbbd466a715: Pull complete e11368b8e0c7: Pull complete 7dab2de7692b: Pull complete Digest: sha256:cac55e5d97fad634d954d00a5c2a56d80576a08dcc01036011f26b88263f1578 Status: Downloaded newer image for docker.io/ubuntu:14.04


다운로드 받은 이미지 목록을 확인하려면 다음 명령을 수행한다.
IMAGE ID는 이미지의 고유 번호로 이미지를 삭제하려면 해당 IMAGE ID를 알고 있어야 한다.


# docker images

REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/ubuntu 14.04 5dbc3f318ea5 3 weeks ago 188 MB



이제 다운로드 받은 이미지를 통해 컨테이너를 생성하고 접근해보자

컨테이너 생성과 동시에 해당 컨테이너의 고유값이 출력 되며 이 16진수 해시값으로 명령을 수행할때 사용할 수 있다.


# docker create -i -t --name ubuntutest docker.io/ubuntu:14.04

b0c51e1ead4b1e4234537ec00394837144ce83f64c2d3c2e1eb7cbabcec8af41

# docker start ubuntutest // 컨테이너 활성화

# docker attach ubuntutest // 컨테이너로 접근



attach 명령을 통해 컨테이너 내부로 접근하고 ls 명령을 사용하여 디렉토리들을 확인 해보자 일반적인 Ubuntu Root 경로와 같다는것을 확인 할 수 있다. 


root@b0c51e1ead4b:/# ls

bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var



이제 아파치를 설치 해보자.

먼저 apt-get update 명령으로 패키지를 최신화 시켜주고 최신화가 완료되면 apt-get install apache2 -y 명령으로 아파치를 설치 해준다.


# apt-get update

...

# apt-get install apache2 -y

Reading package lists... Done Building dependency tree Reading state information... Done

...

invoke-rc.d: policy-rc.d denied execution of start. Setting up ssl-cert (1.0.33) ... Processing triggers for libc-bin (2.19-0ubuntu6.14) ... Processing triggers for sgml-base (1.26+nmu4ubuntu1) ... Processing triggers for ureadahead (0.100.0-16) ...




Docker 컨테이너 접근



이제 Host OS에서 도커 컨테이너에 설치 된 아파치에 접근 해볼것이다.

이해를 돕기 위해 우리가 구축한 VM 기반의 구조에 도커가 설치된 모습을 그림으로 설명하면 아래와 같다.

Docker : 기초 편에서 설명했던 Virtual Machine 구조와 Docker Engine의 구조가 합쳐져있는 모습이라고 보면 된다.





그런데 지금 당장 도커 컨테이너의 Apache에 접근하는데 영 좋지않은 문제가 있다. 도커는 컨테이너를 생성하는 순간 포트설정을 해주지 않으면 외부에서 컨테이너로 접근할 수 없고, 한번 생성된 컨테이너는 추가로 포트오픈이 불가능하다. 


(안돼!!)


때문에 docker run (또는 create) 명령으로 컨테이너를 생성하는 순간에 포트설정을 해야 한다.


필자는 docker run 명령을 수행하면서 옵션으로 80포트끼리 포트포워딩 하였다.

(포트포워딩에 대한 개념이 이해가 잘 가지 않는다면 Docker : 설치 편을 참고하기 바란다.)


# docker run -i -t --name ubuntu_apache -p 80:80 docker.io/ubuntu:14.04

root@d9f0845cc1b5:/# exit


docker run 명령어는 docker pull, docker create명령과 docker start, docker attach축약해둔 명령어로 이미지를 내려받고 컨테이너를 생성함과 동시에 컨테이너 내부로 진입 하였다. 여러모로 편리한 명령어 이므로 자주 사용하게 될 것이다.


그런데 아무리 생각해봐도 가슴 한켠이 너무 허전하다는 느낌이 든다.

어떻게 만든 ubuntutest 컨테이너인데.. 무려 Apache2까지 설치한 컨테이너를 이대로 지우기에는 너무 억울하다.



기존 컨테이너에서 작업 된 내용을 보존하면서

다시 새로운 컨테이너를 생성하는 방법은 없을까?



물론 있다. docker commit 명령어를 사용하면 쉽게 해결 할 수 있다.

docker의 commit 명령어는 현재까지 작업 된 컨테이너의 내용을 보존하여 이미지화 시키는 기능으로 간단히 설명하면 순수 windows만 들어있던 iso 파일로 OS를 설치하고 그 곳에 jdk 1.8을 설치한 후 이것을 다시 iso로 만들었다고 보면 된다. 이 iso는 어떤 PC에서 설치를 해도 windows OS와 jdk 1.8이 설치 된 상태로 구동 될 것 이다.


이제 commit 명령을 실행 해보자.

docker commit <복사할 컨테이너명> <새로 만들 이미지명> 을 입력하여 이미지를 생성하고 docker images 명령을 사용하여 이미지가 잘 생성되었는지 확인해보자.


# docker commit ubuntutest ubuntutest_img

sha256:b5d9797d22340d09f6d3f1ad3bd324e32709c8c79193419ce182dc4241b57685

# docker images

REPOSITORY TAG IMAGE ID CREATED SIZE ubuntutest_img latest b5d9797d2234 21 seconds ago 216 MB docker.io/ubuntu 14.04 5dbc3f318ea5 3 weeks ago 188 MB



확인이 완료 되었으면 방금 복사된 따끈따끈한 ubuntutest_img를 통해 새로운 컨테이너를 생성해보도록 하자 docker run 명령을 통해 ubuntutest_new라는 새로운 컨테이너를 생성 하였다.


# docker run -i -t --name ubuntutest_new -p 80:80 ubuntutest_img



아까 ubuntutest에서 Apache2까지만 설치하고 중단 된 상태였다.

apache2 -v 명령어로 아파치가 설치되어있는지 확인해본다.


root@99a9f9e493ba:/# apache2 -v Server version: Apache/2.4.7 (Ubuntu) Server built: Nov 28 2018 00:08:50



설치가 잘 되어있다. 이제 apache2 서비스를 올려보자


root@99a9f9e493ba:/# service apache2 start root@99a9f9e493ba:/# service apache2 status * apache2 is running



apache2 서비스가 올라갔으면 이제 Host OS의 80포트를 Guest OS의 80포트로 포트포워딩 해주는 작업이 필요하다.

Virtual Box에서 'Settings' -> 'Network' -> 'Port Forwarding' 을 차례로 눌러준다.





Apache2 접근을 위해 80번 포트를 Port Forwarding 처리 해준다.




자 이제 현재의 상황을 그림으로 나타내면 다음과 같다.



우리는 지난 Docker : 설치 편에서 Host OS(192.168.64.1)와 Guest OS(10.0.2.15)의 80번 포트를 포트포워딩 해두었다. Guest OS와 도커 컨테이너의 80번 포트를 포트포워딩 하는 작업은 docker run을 통해 이루어 졌으므로 이제 HostOS에서 VM을 통하여 도커 컨테이너에 설치 된 Apache 80번 포트에 접근이 가능해졌다.

브라우저에서 192.168.64.1:80번 포트로 접근하면 도커 컨테이너에 설치된 Apache를 호출하고 기본페이지 화면을 마주할 수 있게 되었다. (아래 이미지가 뜬다면 Apache 정상 설치 및 정상 접근이 된 것이다.)






Docker 컨테이너 삭제



아쉽지만 정들었던 컨테이너와 작별할 시간이다.

인생은 돌고 도는 것. 언젠가 다른 컨테이너로 태어나 여러분과 다시 만나게 될 것이다.


docker rm 명령을 통하여 컨테이너를 삭제 해보자.

컨테이너를 삭제하기 위해서는 먼저 컨테이너를 종료 해야한다 exit 명령으로 빠져나가도록 한다.

그리고 docker ps -a 명령을 입력하여 삭제 할 목록을 확인 해보자.


root@99a9f9e493ba:/# exit # docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 193f30bb8c38 ubuntutest_img "/bin/bash" 55 minutes ago Exited (0) 4 seconds ago ubuntutest_new d9f0845cc1b5 docker.io/ubuntu:14.04 "/bin/bash" About an hour ago Exited (0) About an hour ago ubuntu_apache b0c51e1ead4b docker.io/ubuntu:14.04 "/bin/bash" About an hour ago Exited (0) About an hour ago ubuntutest



docker rm <컨테이너명> 순으로 입력하여 하나씩 지워주도록 한다.

컨테이너가 잘 지워진것이 확인 되었다.


[root@localhost testuser]# docker rm ubuntutest_new ubuntutest_new [root@localhost testuser]# docker rm ubuntu_apache ubuntu_apache [root@localhost testuser]# docker rm ubuntutest ubuntutest [root@localhost testuser]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@localhost testuser]#



오늘 설명한 Docker : 컨테이너 편 에서는 도커 이미지 내려받기, 컨테이너 생성, 어플리케이션 설치, 포트포워딩, 컨테이너 삭제까지의 간단한 개요 설명과 실습이 진행 되었다. 도커의 기초 개념과 포트포워딩에 대한 설명이 더 필요한 독자분들께는 Docker : 기초 편Docker : 설치 편을 다시 한번 보는것을 추천 드린다.




Docker : 컨테이너 편

끝.


'Docker' 카테고리의 다른 글

Docker : Dockerfile 실습 편  (0) 2019.03.22
Docker : Dockerfile 편  (0) 2019.03.07
Docker : 이미지 편  (0) 2019.02.22
Docker : 컨테이너 편  (1) 2019.02.15
Docker : 설치 편  (0) 2019.01.31
Docker : 기초 편  (2) 2019.01.16
Posted by DevStream

댓글을 달아 주세요

  1. 우왕 2019.03.11 13:22  댓글주소  수정/삭제  댓글쓰기

    쉽게 쏙쏙