최근에 쿠버네티스를 공부할 일이 있어서 보고 있는데, 쿠버네티스 자체가 도커(Docker) 오케스트레이션을 해주는 툴이라 도커에 대한 개념이 없으니, 공부하기가 힘들었습니다. 그래서 이렇게 급하게 책을 사서 공부하면서 내용을 정리하고자 합니다.
해당 내용은 위키북스에서 나온 시작하세요! 도커 책을 보면서 정리한 내용입니다. 책의 내용이 매우 좋아서 강추합니다.
도커란?
도커(Docker)는 리눅스 컨테이너에 여러 기능을 추가해서 어플리케이션을 컨테이너로 쉽게 사용할 수 있게 해주는 프로젝트로 Go 언어로 만들어졌습니다.
가상 머신(Virtual Machine) VS 도커 컨테이너(Docker Container)
기존의 가상화 기술은 가상 머신(VM)
이라하여 하이퍼바이저(Hypervisor)
를 이용해 여러 개의 운영체제를 하나의 호스트에서 생성해 사용하는 방식이었습니다.
이 때 생성되고 관리되는 운영체제는 게스트 운영체제(Guest OS)
라고 하며, 각 게스트 운영체제는 독립된 공간과 시스템 자원을 할당받아 사용합니다.
대표적인 툴로는 VirtualBox
, VM Ware
가 있습니다.
하지만 가상 머신은 게스트 운영체제(Guest OS)
를 사용하기 위해 커널과 라이브러리 등이 포함이 되기 때문에 무겁고 용량이 큽니다, 대신에 도커 컨테이는 가상화 공간을 만들기 위해
리눅스의 자체 기능인 chroot
, namespace
, cgroup
을 사용하기 때문에 성능 손실이 거의 없으며, 컨테이너에 필요한 커널은 호스트 운영체제의 커널을 공유해 사용
하기 때문에, 가볍습니다.
도커 설치
다음 Docker 공식 사이트에 들어갑니다.
그 다음 우측 상단의 ‘Get Started’ 버튼을 누릅니다.
그럼 아래와 같은 화면이 나오는데 자신의 시스템에 맞는 버튼을 누릅니다. 저는 Mac 환경이기 때문에
Download for Mac
을 클릭하겠습니다.
그럼 다음과 같은 화면이 나타납니다. Get Docker
를 눌러서 다운로드 하고 설치가까지 진행합니다.
설치가 완료가 되면 상단에 Docker가 나타나고 터미널에서 docker
명령어를 사용할 수 있게 됩니다.
도커 이미지
이미지는 컨테이너를 생성할 때 필요한 요소이며, 가상 머신을 생성할 때 사용하는 ISO 파일과 비슷한 개념입니다. 이미지는 도커 명령어로 다운로드가 되기 때문에 별도로 설치를 할 필요가 없으며 기본적으로 아래와 같이 구성됩니다.
[저장소 이름]/[이미지 이름]:[태그]
jungwoon/ubuntu:14:04
또는 저장소 이름
은 생략
이 가능해서 아래와 같이도 구성할 수 있습니다.
[이미지 이름]:[태그]
ubuntu:14:04
만약 태그
생략시 latest
로 붙습니다. ex) ubuntu:latest
도커 컨테이너
이미지를 이용하면 목적별로 독립된 시스템을 및 공간을 만들 수 있는데 이를 도커 컨테이너
라고 합니다. 컨테이너는 이미지를 읽기 전용으로 사용하고, 이미지에서
변경된 내용은 컨테이너 계층만 영향을 받기 때문에 이미지는 변화하지 않습니다.
도커 명령어
버전 확인하기
$ docker -v # 버전 확인
Docker version 18.09.0, build 4d60db4
도커 컨테이너 내부 쉘에서 나가기
도커 컨테이너 내부 쉘에서 나가는 방법은 두 가지가 있습니다.
exit
: 명령어로exit
를 누르고 엔터Ctrl + D
: 해당 단축키를 누르면 바로 종료
위의 두 가지 방법은 컨테이너를 종료시키고 나오는 방법입니다. 아래 방법은 컨테이너를 종료시키지 않고 나오는 방법 입니다.
Ctrl + P, Q
: 컨테이너를 종료시키지 않고 나오기 (다시 들어가려면$ docker attach [컨테이너 명]
)
도커 이미지 가져오기
아래 명령어를 사용하면 도커 공식 이미지 저장소에서 이미지를 내려받습니다.
$ docker pull [이미지 이름]:[태그]
예제를 보도록 하겠습니다, 그럼 도커 공식 이미지 저장소에서 centos:7
이미지를 다운받게 됩니다.
ex)
$ docker pull centos:7
이미지 확인하기
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 14.04 7e4b16ae8b23 2 weeks ago 188MB
centos 7 1e1148e4cc2c 5 weeks ago 202MB
컨테이너 생성하기
이미지로 컨테이너 생성하기
$ docker create [옵션] [이미지 이름]:[태그]
예제를 보겠습니다.
$ docker create -i -t centos:7
-i
: 상호 입출력-t
: tty를 활성화하여 bash 쉘을 사용
컨테이너 실행하기
만들어진 도커 컨테이너를 실행하는 명령어 입니다.
$ docker start centos:7
컨테이너 들어가기
도커의 내부쉘로 들어가는 명령어 입니다.
$ docker attach centos:7
컨테이너 만들고 실행하기
위의 생성 -> 실행 -> 들어가기
까지 한번에 해주는 명령어 입니다.
$ docker run [옵션] [이미지 이름]:[태그]
-i
: 상호 입출력-t
: tty를 활성화하여 bash 쉘을 사용
ex)
$ docker run -i -t ubuntu:14.04
보통은 컨테이너를 생성함과 동시에 시작하기 때문에 run
명령어를 더 많이 사용합니다.
컨테이너 목록 확인
만들어진 컨테이너 목록을 확인할 수 있습니다.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aab67382350b ubuntu:14.04 "/bin/bash" 16 minutes ago Up 16 minutes 0.0.0.0:80->80/tcp mywebserver
대신 위의 명령어는 현재 실행중인 컨테이너 목록만 확인할 수 있기 때문에, 정지된 컨테이너까지 보고 싶으면,
아래와 같이 -a
옵션을 같이 넣어줍니다.
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
99627ff61fd7 centos:7 "/bin/bash" 42 hours ago Exited (0) 42 hours ago mycentos
1758dcf92334 ubuntu:14.04 "/bin/bash" 43 hours ago Exited (255) 25 hours ago determined_brattain
CONTAINER ID
: 컨테이너에게 자동으로 할당되는고유한 ID
IMAGE
: 컨테이너를 생성할 때 사용된 이미지 이름COMMAND
: 컨맨드는 컨테이너가 시작될 때 실행될 명렁어, 기본은/bin/bash
명령어라 명령을 쓸 수 있습니다.CREATED
: 컨테이너가 생성되고 난 뒤 흐른 시간STATUS
: 컨테이너의 상태 ex) Up(실행 중), Exited(종료), Pause(일시 중지)PORTS
: 컨테이너가 개방한 포트와 호스트에 연결한 포트NAMES
: 컨테이너의 고유한 이름,--name 옵션
으로 이름을 설정하지 않으면 도커 엔진이 임의의로 설정
컨테이너 이름 변경
$ docker rename [기존 이름] [변경 하고자 하는 이름]
$ docker rename determined_brattain my_container
결과
$ docker rename determined_brattain my_container
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
99627ff61fd7 centos:7 "/bin/bash" 42 hours ago Exited (0) 42 hours ago mycentos
1758dcf92334 ubuntu:14.04 "/bin/bash" 44 hours ago Exited (255) 25 hours ago my_container
컨테이너 삭제
$ docker rm [컨테이너 이름]
결과
$ docker rm mycentos
mycentos
만약 container가 실행 중이면 종료하고 삭제를 하거나 -f 옵션을 이용해서 강제로 삭제를 해야합니다.
$ docker stop mycentos
$ docker rm mycentos
$ docker rm -f centos
한번에 모든 컨테이너를 삭제하려면 prune 명령어를 통해 삭제할 수 있습니다.
$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N]
*** -q
와 -a
옵션
-q
: 컨테이너 ID만 출력-a
: 컨테이너 전체 출력
ex)
$ docker stop $(docker ps -a -q)
$ docker rnm $(docker ps -a -q)
컨테이너 외부에 노출
컨테이너는 가상 머신과 마찬가지로 가상 IP를 할당 받습니다.
테스트를 위해서 network_test
란 컨테이너를 만들어 보겠습니다.
기본적으로 도커는 172.17.0.x의 IP부터 순차적으로 할당합니다.
$ docker run -i -t --name network_test ubuntu:14.04
root@7b5213595de1:/# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:17 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1366 (1.3 KB) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
아무 설정을 하지 않으면 기본적으로 컨테이너는 외부에서 접근할 수 없으며 도커가 설치된 호스트에서만 접근 가능합니다.
외부에 컨테이너의 어플리케이션을 노출하기 위해서는 eth0의 IP와 포트를 호스트의 IP와 포트에 바인딩해야 합니다.
테스트를 위해 아래의 새로운 컨테이너를 생성하는데 -p 옵션을 이용해 컨테이너의 포트를 호스트의 포트와 바인딩해 연결할 수 있게 설정합니다.
-p [호스트의 포트]:[컨테이너의 포트]
$ docker run -i -t --name mywebserver -p 80:80 ubuntu:14.04
만약 여러개의 포트 설정이 필요하면 -p 옵션
을 여러번 사용 할 수 있고, 호스트의 특정 IP를 사용하려면
192.168.0.100:7777:80
과 같이 바인딩할 IP와 포트를 직접 명시할 수도 있습니다.
예시)
$ docker run -i -t -p 3306:3306 -p 192.168.0.100:7777:80 ubuntu:14.04
테스트를 위해서 위에서 만든 mywebserver
에 apache를 설치합니다.
$ apt-get update # apt-get 업데이트
$ apt-get install apache2 -y # 아파치2 설치, -y 옵션은 중간에 "설치하시겠습니까?"에 대해서 Yes라는 의미
$ service apache2 restart # 설치한 아파치2 실행
그리고 컨테이너의 IP가 아닌 자신의 로컬 호스트의 IP로 웹브라우저를 통해서 접근하면 Apache가 보입니다.