1. 도커란?
1.3.4 리눅스 환경에 도커 마련하기
필자는 버추얼 박스에 리눅스를 통해 실습을 해 볼 예정이다.
책은 우분투 16.04 를 기준으로 설명합니다.
도커는 64비트에 최적화되어 있으므로 64비트 리눅스를 받아줍니다.
- 커널 확인
uname -r
버추얼박스에서 복사-붙여넣기를 사용하기 위해
우분투를 재 실행해준 후 (우분투를 설치한 이미지는 빼줍니다.)
- 도커엔진 설치
sudo curl -fsSL http://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install docker-ce
.
책은 20.10.5 버전을, 나는 20.10.7 버전을 다운로드 했다.
2. 도커 엔진
도커 엔진에서 사용하는 기본 단위는 이미지와 컨테이너이며, 이 두가지가 도커 엔진의 핵심이다.
2.1.1 도커 이미지
이미지는 컨테이너를 생성할 때 필요한 요소이다.
도커에서 사용하는 이미지의 이름은 기본적으로 [저장소 이름]/[이미지 이름]:[태그] 의 형태로 구성됩니다.
e.g.
alicek106/ubuntu:14.04
저장소 이름은 생략할 수 있으며 태그는 생략하면 latest 로 인식합니다.
2.2 도커 컨테이너 다루기
도커를 편하게 쓰기 위해 GUI 를 지원하는 kitematic 이라는 도구가 있지만 여기서는 CLI 를 기준으로 설명하겠습니다.
2.2.1 컨테이너 생성
-i, -t 옵션은 컨테이너와 상호 (interactive) 입출력이 가능하게 합니다.
단 한줄의 명령으로 컨테이너를 생성 및 실행과 동시에 컨테이너 내부로 들어왔습니다.
컨테이너에서 기본 사용자는 root 이고 호스트 이름은 무작위 16진수 해시값입니다.
명령어를 실행할 때 -i 옵션으로 상호 입출력을, -t 옵션으로 tty 를 활성화해서 배시 (bash) 셸을 사용하도록 컨테이너를 설정했습니다.
이 두 옵션 중 하나라도 사용하지 않으면 셸을 정상적으로 사용할 수 없습니다.
- exit: 컨테이너 내부에서 빠져나온다.
- Ctrl D: 빠져나오며 컨테이너를 정지시킨다.
- Ctrl P, Q: 정지하지 않고 빠져나온다.
- 도커 컨테이너 생성
docker create -i -t --name mycentos centos:7
run 명령어가 아닌 create 명령어로도 컨테이너를 생성할 수 있다.
--name 옵션에는 컨테이너 이름을 설정합니다.
보통 ID 의 앞 12자리만 사용합니다.
docker inspect 명령어로 컨테이너의 ID 를 다시 확인할 수 있습니다.
run 명령어와는 달리 컨테이너로 들어가지 않습니다.
- docker start: 컨테이너를 시작합니다.
- docker attach: 컨테이너 내부로 들어갑니다.
보통은 run 명령어를 많이 쓰므로 앞으로도 run 명령어를 씁니다.
컨테이너를 대상으로 하는 모든 명령어는 이름 대신 ID 를 쓸 수 있습니다.
ID 가 너무 길 때는 앞의 2~3 자만 입력해도 됩니다.
2.2.2 컨테이너 목록 확인
모든 컨테이너를 출력하려면 -a 옵션을 줍니다.
Status
- Exited: 정지된 상태
- Up: 실행 중인 상태
- Pause: 일시 중지된 상태
- Command: 컨테이너가 시작될 때 실행될 명령어.
- 대부분 이미지에 미리 내장되어 있어 별도로 설정할 필요가 없다.
- 이미지에 내장된 커맨드는 docker run 이나 create 명령어의 맨 끝에 입력해서 컨테이너를 생성할 때 덮어쓸 수 있습니다.
- Ports: 컨테이너가 개방한 포트와 호스트에 연결한 포트를 나열합니다.
- Names: --name 옵션을 주지 않으면 도커 엔진이 임의로 형용사와 명사를 무작위로 조합해 이름을 설정합니다.
- 컨테이너의 이름은 중복될 수 없지만 docker rename 명령어를 사용해 컨테이너의 이름을 변경할 수 있습니다.
- command 덮어 쓴 컨테이너 생성하기
docker run -i -t ubuntu:14.04 echo hello world!
- 컨테이너 이름변경
docker rename angry_morse my_container
2.2.3 컨테이너 삭제
docker rm 으로 삭제할 수 있다. (remove)
-f 옵션을 주면 실행중인 컨테이너를 삭제할 수 있다. (force 인 듯)
- 중지된 모든 컨테이너를 삭제
docker container prune
-a 옵션은 모든 컨테이너를, -q 옵션은 컨테이너의 id 만 출력한다.
- 실행상태와 관계없이 모든 컨테이너를 삭제
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
2.2.4 컨테이너를 외부에 노출
기본적으로 도커는 컨테이너에 172.17.0.x 를 순차적으로 할당합니다.
eth0 인터페이스와 로컬 호스트인 lo 인터페이스가 있습니다.
아무런 설정을 하지 않았다면 이 컨테이너는 외부에서 접근할 수 없으며 도커가 설치된 호스트에서만 접근할 수 있습니다.
(Docker Desktop for Mac 에서는 호스트에서 컨테이너 IP 로의 접근이 불가능합니다.)
외부에 컨테이너를 노출하기 위해서는 eth0 의 IP 와 포트를 호스트의 IP 와 포트에 바인딩해야 합니다.
-p 옵션은 컨테이너의 포트를 호스트의 포트와 바인딩해 연결할 수 있게 설정합니다.
-p [호스트의 포트]:[컨테이너의 포트]
여러 개의 포트를 외부에 개방하려면 -p 옵션을 여러 번 써서 설정합니다.
docker run -i -t -p 3306:3306 -p 192.168.0.100:7777:80 ubuntu:14.04
-p 80 과 같이 입력하면 컨테이너의 80 번 포트를 쓸 수 있는 호스트의 포트 중 하나와 연결합니다.
하지만 docker ps 명령어의 PORTS 항목을 확인해야 합니다.
- 아파치 설치
apt-get update
apt-get install apache2 -y
service apache2 start
- mysql 설치
docker run -d \
--name wordpressdb \
-e MYSQL_ROOT_PASSWORD=password \
-e MYSQL_DATABASE=wordpress \
mysql:5.7
- 워드프레스 설치
docker run -d \
-e WORDPRESS_DB_HOST=mysql \
-e WORDPRESS_DB_USER=root \
-e WORDPRESS_DB_PASSWORD=password \
--name wordpress \
--link wordpressdb:mysql \
-p 80 \
wordpress
run 옵션
- -d: Detached 모드로 컨테이너를 실행. 컨테이너를 백그라운드에서 동작하는 애플리케이션으로써 실행하도록 설정한다.
- -e: 컨테이너 내부의 환경변수를 설정합니다.
- --link: A 컨테이너에서 B 컨테이너로 접근하는 방법 중 가장 간단한 것은 NAT 로 할당받은 내부 IP 를 쓰는 것입니다.
- 도커 엔진은 컨테이너에게 내부 IP 를 172.17.0.2, 3, 4... 와 같이 순차적으로 할당합니다.
- 이는 컨테이너를 시작할 때마다 재할당하는 것이므로 매번 변경되는 컨테이너의 IP 로 접근하기는 어렵습니다.
그렇다면 이 환경변수가 실제로 컨테이너에 적용됐는지 확인해보겠습니다.
리눅스에서 환경변수를 확인하는 가장 간단한 방법은 echo 를 사용하는 것입니다.
echo ${ENVIRONMENT_NAME}
- attach 로 mysql 컨테이너 생성
docker run -i -t \
--name mysql_attach_test \
-e MYSQL_ROOT_PASSWORD=password \
-e MYSQL_DATABASE=wordpress \
mysql:5.7
- attach 할 수 없는 컨테이너의 셸 연결하기
docker exec -i -t wordpressdb /bin/bash
여기서 -i -t 옵션을 주지 않으면 컨테이너 내부에서 실행한 명령어에 대한 결과만 반환합니다. (상호 입출력 불가)
-d 옵션으로 실행한 컨테이너를 exit 명령어로 빠져나와도 컨테이너가 종료되지 않습니다.
위에서 생성한 워드프레스와 MYSQL 컨테이너는 빠른 이해를 위해 환경변수에 비밀번호를 입력했지만, 비밀번호처럼 민감한 정보를 켄테이너 내부의 환경변수로 설정하는 것은 매우 바람직하지 않습니다.
이런 경우에는 도커 스웜 모드의 secret 잉나 쿠버네티스의 secret 과 같은 기능을 활용해 안전하게 비밀번호를 전달하는 것이 좋습니다.
--link 옵션은 내부 IP 를 알 필요 없이 항상 컨테이너에 별명 (alias) 로 접근하도록 설정합니다.
위에서 생성한 워드프레스 웹 서버 컨테이너는 --link 옵션의 값에서 wordpressdb 컨테이너를 mysql 이라는 이름으로 설정했습니다.
--link [컨테이너 별칭]:[호스트 이름]
--link 옵션은 현재 deprecated 된 옵션이며 추후 삭제될 수 있습니다.
도커 브리지 (bridge) 네트워크를 사용하면 --link 옵션과 동일한 기능을 더욱 손쉽게 사용할 수 있으므로 브리지 네트워크를 사용하는 것을 권장합니다.
2.2.6 도커 볼륨
볼륨을 활용하여 데이터베이스의 정보를 실수로 삭제하여 데이터를 복구하지 못하는 현상을 방지합니다.
볼륨을 활용하는 방법은 여러가지가 있습니다. 호스트와 볼륨을 공유할 수도 있고, 볼륨 컨테이너를 활용할 수 있으며, 도커가 관리하는 볼륨을 생성할 수도 있습니다.
첫 번째로 호스트와 볼륨을 공유함으로써 데이터베이스 컨테이너를 삭제해도 데이터는 삭제되지 않도록 설정해봅시다.
(호스트에 백업)
2.2.6.1 호스트 볼륨 공유
- mysql 컨테이너 생성
docker run -d \
--name wordpressdb_hostvolume \
-e MYSQL_ROOT_PASSWORD=password \
-e MYSQL_DATABASE=wordpress \
-v /home/wordpress_db:/var/lib/mysql \
mysql:5.7
- wordpress 컨테이너 생성
docker run -d \
-e WORDPRESS_DB_PASSWORD=password \
--name wordpress_hostvolume \
--link wordpressdb_hostvolume:mysql \
-p 80 \
wordpress
-v /home/wordpress_db:/var/lib/mysql
이는 호스트의 /home/wordpress_db 디렉토리와 컨테이너의 /var/lib/mysql 디렉토리를 공유한다는 뜻입니다.
-v [호스트의 공유 디렉토리]:[컨테이너의 공유 디렉토리]
미리 /home/wordpress_db 디렉토리를 호스트에 생성하지 않았어도 도커는 자동으로 이를 생성합니다.
디렉토리 단위의 공유 뿐만 아니라 단일 파일 단위의 공유도 가능하며, 동시에 여러 개의 -v 옵션을 쓸 수도 있습니다.
위의 경우 컨테이너의 파일이 호스트로 복사된 것입니다.
확인하기 위해 미리 준비된 이미지를 다운받아 봅시다.
컨테이너를 빠져나온 뒤 -v 옵션으로 컨테이너를 생성합니다.
docker run -i -t \
--name volume_overide \
-v /home/wordpress_db:/home/testdir_2 \
alicek106/volume_test
-v 옵션을 통한 호스트 볼륨 공유는 호스트의 디렉토리를 컨테이너의 디렉토리에 마운트합니다.
2.2.6.2 볼륨 컨테이너
볼륨을 사용하는 두 번째 방법은 -v 옵션으로 볼륨을 사용하는 컨테이너를 다른 컨테이너와 공유하는 것입니다.
컨테이너를 생성할 때 --volumes-from 옵션을 설정하면 -v 또는 --volume 옵션을 적용한 컨테이너의 볼륨 디렉토리를 공휴할 수 있습니다.
그러나 이는 직접 볼륨을 공유하는 것이 아닌 -v 옵션을 적용한 컨테이너를 통해 공유하는 것입니다.
아래의 예제는 위에서 사용한 volume_overide 컨테이너에서 볼륨을 공유받는 경우입니다.
앞에서 생성한 volume_overide 컨테이너는 /home/testdir_2 디렉토리를 호스트와 공유하고 있으며, 이 컨테이너를 볼륨 컨테이너로서 volumes_from_container 컨테이너에 다시 공유하는 것입니다.
docker run -i -t \
--name volumes_from_container \
--volumes-from volume_overide \
ubuntu:14.04
볼륨을 사용하려는 컨테이너에 --volumes-from 옵션을 사용함으로써 볼륨 컨테이너에 연결해 데이터를 간접적으로 공유받는 형식입니다.
2.2.6.3 도커 볼륨
볼륨을 활용하는 세 번째 방법은 docker volume 명령어를 사용하는 것입니다.
도커 자체에서 제공하는 볼륨 기능을 활용해 데이터를 보존할 수도 있습니다.
docker volume create 명령어로 볼륨을 생성합니다.
- 볼륨 생성
docker volume create --name myvolume
여기서는 기본적으로 제공되는 드라이버인 local 을 사용합니다.
이 볼륨은 로컬 호스트에 저장되며 도커 엔진에 의해 생성되고 삭제됩니다.
- 볼륨을 사용하는 컨테이너 생성
docker run -i -t --name myvolume_1 \
-v myvolume:/root/ \
ubuntu:14.04
-v [볼륨의 이름]:[컨테이너의 공유 디렉토리]
다른 컨테이너도 myvolume 볼륨을 쓰면 디렉토리에 volume 파일이 존재할 것입니다.
- 볼륨을 사용한 다른 컨테이너 생성
docker run -i -t --name myvolume_2 \
-v myvolume:/root/ \
ubuntu:14.04
볼륨은 디렉토리 하나에 상응하는 단위로서 도커 엔진에서 관리합니다.
도커 볼륨도 호스트 볼륨 공유와 마찬가지로 호스트에 저장함으로써 데이터를 보존하지만 파일이 실제로 어디에 저장되는지 사용자는 알 필요가 없습니다.
docker inspect 명령어를 사용하면 myvolume 볼륨이 실제로 어디에 저장되는지 알 수 있습니다.
정보를 확인할 때 --type 옵션에 image, volume 등을 입력하는 것이 좋습니다.
- 볼륨의 정보 출력
docker inspect --type volume myvolume
- docker container inspect
- docker volume inspect
Driver 는 볼륨이 쓰는 드라이버를, Label 은 볼륨이 구분하는 라벨을 나타내며, Mountpoint 는 해당 볼륨이 실제로 호스트의 어디에 저장됐는지를 의미합니다.
그러나 볼륨을 쓰는 사용자 입장에서 Mountpoint 를 알 필요는 없습니다.
docker volume create 명령을 사용하지 않아도 -v 옵션을 입력할 때 이를 수행하도록 설정할 수 있습니다.
다음과 같이 컨테이너에서 공유할 디렉토리의 위치를 -v 옵션에 입력하면 해당 디렉토리에 대한 볼륨을 자동으로 생성합니다.
docker run -i -t --name volume_auto \
-v /root \
ubuntu:14.04
- 컨테이너의 볼륨 마운트 확인
docker container inspect volume_auto
컨테이너를 삭제해도 볼륨은 자동으로 삭제되지 않기 때문에
docker volume prune
명령어를 사용합니다.
이처럼 컨테이너가 아닌 외부에 데이터를 저장하고 컨테이너는 그 데이터로 동작하도록 설계하는 것을 스테이트리스 (stateless) 하다고 말합니다.
컨테이너 자체는 상태가 없고 상태를 결정하는 데이터는 외부로부터 제공받습니다.
컨테이너가 삭제돼도 데이터는 보존되므로 스테이트리스한 컨테이너 설계는 도커를 사용할 때 매우 바람직한 설계입니다.
컨테이너가 데이터를 저장하고 있는 상태가 있는 경우 스테이트풀 (stateful) 하다고 말합니다.
이것은 지양하는 것이 좋습니다.
-v 옵션 대신 --mount 옵션을 사용할 수도 있습니다. 두 옵션의 기능은 같지만 볼륨의 정보를 나타내는 방법이 다르기 때문에 둘 중 사용하기 편한 옵션을 사용하면 됩니다.
예를 들어 --mount 옵션으로 myvolume 이라는 이름의 도커 볼륨을 컨테이너 내부의 /root 에 공유하는 명령어는 아래와 같이 쓰일 수 있습니다.
docker run -i -t --name mount_option_1 \
--mount type=volume,source=myvolume,target=/root \
ubuntu:14.04
호스트의 디렉토리를 컨테이너 내부에 마운트하는 경우에는 type 을 bind 로 지정합니다.
이때 source 의 값은 호스트의 디렉토리 경로를 지정합니다.
docker run -i -t --name mount_option_2 \
--mount type=bind,source=/home/wordpress_db,target=/home/testdir \
ubuntu:14.04
2.2.7 도커 네트워크
2.2.7.1 도커 네트워크 구조
컨테이너의 내부 IP 는 도커가 설치된 호스트, 즉 내부 망에서만 쓸 수 있는 IP 이므로 외부와 연결될 필요가 있습니다.
이 과정은 컨테이너를 시작할 때마다 호스트에 veth 라는 네트워크 인터페이스를 생성함으로써 이뤄집니다.
veth 에서 v 는 virtual 을 뜻합니다. 즉, virtual epth 라는 의미입니다.
도커가 설치된 호스트에서 ifconfig 나 ip addr 과 같은 명령어로 네트워크 인터페이스를 확인하면 실행중인 컨테이너의 수만큼 veth 로 시작하는 인터페이스가 생성된 것을 알 수 있습니다.
리눅스라면 ifconfig, 윈도우라면 ipconfig 를 입력해 확인합니다.
eth0 은 공인 IP 또는 내부 IP 가 할당되어 실제로 외부와 통신할 수 있는 호스트의 네트워크 인터페이스입니다.
veth 로 시작하는 인터페이스는 컨테이너를 시작할 때 생성됐으며, 각 컨테이너의 eth0 과 연결됐습니다.
veth 인터페이스 뿐 아니라 docker0 이라는 브리지도 존재하는데 docker0 브리지는 각 veth 인터페이스와 바인딩돼 호스트의 eth0 인터페이스와 이어주는 역할을 합니다.
2.2.7.2 도커 네트워크 기능
사용자의 선택에 따라 여러 네트워크 드라이버를 쓸 수도 있습니다.
도커가 자체적으로 제공하는 대표적인 네트워크로는 브리지 (bridge), 호스트 (host), 논 (none), 컨테이너 (container), 오버레이 (overlay) 가 있습니다.
서드파티 플러그인 솔루션으로는 weave, flannel, openvswitch 등이 있으며, 더 확장된 네트워크 구성을 위해 활용됩니다.
브리지 네트워크는 컨테이너를 생성할 때 자동으로 연결되는 docker0 브리지를 활용하도록 설정돼 있습니다.
Config 항목의 서브넷과 게이트웨이가 172.17.0.0/16 과 172.17.0.1 로 설정돼 있습니다. 또한 브리지 네트워크를 사용 중인 컨테이너의 목록을 Containers 항목에서 확인할 수 있습니다.
아무런 설정을 하지 않고 컨테이너를 생성하면 컨테이너는 자동으로 docker0 브리지를 사용합니다.
브리지 네트워크
기본적으로 존재하는 docker0 브리지 네트워크가 아닌 새로운 브리지 네트워크를 생성할 수 있습니다.
- 새로운 브리지 네트워크 생성
docker network create --driver bridge mybridge
이렇게 생성된 사용자 정의 네트워크는 docker network disconnect, connect 를 통해 컨테이너에 유동적으로 붙이고 뗄 수 있습니다.
- 커스텀 브리지 만들기
docker network create --driver=bridge \
--subnet=172.72.0.0/16 \
--ip-range=172.72.0.0/24 \
--gateway=172.72.0.1 \
my_custom_network
호스트 네트워크
호스트 드라이버의 네트워크는 별도로 생성할 필요 없이 기존의 host 라는 이름의 네트워크를 사용합니다.
docker run -i -t --name network_host \
--net host \
ubuntu:14.04
컨테이너의 네트워크를 호스트 모드로 설정하면 컨테이너 내부의 애플리케이션을 별도의 포트 포워딩 없이 바로 서비스할 수 있습니다.
예를 들어, 호스트 모드를 쓰는 컨테이너에서 아파치 웹 서버를 구동한다면 호스트의 IP 와 컨테이너의 아파치 웹 서버 포트인 80 으로 바로 접근할 수 있습니다.
논 네트워크
none 은 말 그대로 아무런 네트워크를 쓰지 않는 것을 뜻합니다.
docker run -i -t --name network_none \
--net none \
ubuntu:14.04
다음과 같이 컨테이너를 생성하면 외부와 연결이 단절됩니다.
컨테이너 네트워크
--net 옵션으로 container 를 입력하면 다른 컨테이너의 네트워크 네임스페이스 환경을 공유할 수 있습니다.
공유되는 속성은 내부 IP, 네트워크 인터페이스의 맥 (MAC) 주소 등입니다.
--net 옵션의 값으로 container:[다른 컨테이너의 ID] 와 같이 입력합니다.
docker run -i -t -d --name network_container_1 ubuntu:14.04
docker run -i -t -d --name network_container_2 \
--net container:network_container_1 \
ubuntu:14.04
-i, -t, -d 옵션을 함께 사용하면 컨테이너 내부에서 셀을 실행하지만 내부로 들어가지 않으며 컨테이너도 종료되지 않습니다. 위와 같이 테스트용 컨테이너를 생성할 때 유용하게 쓸 수 있습니다. (detach)
다른 네트워크 환경을 공유하면 내부 IP 를 새로 할당받지 않으며, 호스트에 veth 로 시작하는 가상 네트워크 인터페이스도 생성되지 않습니다.
브리지 네트워크와 --net-alias
브리지 타입의 네트워크와 run 명령어의 --net-alias 옵션을 함께 쓰면 특정 호스트 이름으로 컨테이너 여러 개에 접근할 수 있습니다.
docker run -i -t -d --name network_alias_ping \
--net mybridge \
ubuntu:14.04
매번 달라지는 IP 를 결정하는 것은 별도의 알고리즘이 아닌 라운드 로빈 (round-robin) 방식입니다.
--net-alias 옵션 또한 --link 옵션과 비슷한 원리로 작동합니다.
mybridge 라는 이름의 네트워크에 속한 3개의 컨테이너는 run 으로 생성할 때 --net-alias 옵션에 alicek106 이라는 값을 입력했으며, 이 컨테이너의 IP 는 DNS 서버에 alicek106 이라는 호스트 이름으로 등록됩니다.
ping 명령어는 이 IP 리스트에서 첫 번째 IP 를 사용하므로 매번 다른 IP 로 ping 을 전송합니다.
이를 확인하기 위해 dig 이라는 도구를 사용해 봅시다.
dig 는 DNS 로 도메인 이름에 대응하는 IP 를 조회할 때 쓰는 도구입니다.
network_alias_ping 컨테이너 내부에서 다음 명령어를 입력해 설치합니다.
apt-get update
apt-get install dnsutils
MacVLAN 네트워크
MacVLAN 은 호스트의 네트워크 인터페이스 카드를 가상화해 물리 네트워크 환경을 컨테이너에게 동일하게 제공합니다.
따라서 MacVLAN 을 사용하면 컨테이너는 물리 네트워크상에서 가상의 맥 (Mac) 주소를 가지며, 해당 네트워크에 연결된 다른 장치와의 통신이 가능해집니다.
MacVLAN 에 연결된 컨테이너는 기본적으로 할당되는 IP 대역인 172.17.X.X 대신 네트워크 장비의 IP 를 할당받기 때문입니다.
이부분은 어려워서 생략하겠습니다.
2.2.8 컨테이너 로깅
2.2.8.1 json-file 로그 사용하기
컨테이너 내부에서 어떤 일이 일어나는지 아는 것은 디버깅 뿐만 아니라 운영 측면에서도 중요합니다.
애플리케이션 레벨에서 로그가 기록되도록 개발해 별도의 로깅 서비스를 쓸 수도 있지만 도커는 컨테이너의 표준 출력 (stdOut) 과 에러 (stdErr) 로그를 별도의 메탙데이터 파일로 저장하며 이를 확인하는 명령어를 제공합니다.
먼저 컨테이너를 생성해 간단한 로그를 남겨 봅시다. 다음 명령은 mysql 5.7 버전의 컨테이너를 생성합니다.
- mysql 컨테이너 생성
docker run -d --name mysql \
-e MYSQL_ROOT_PASSWORD=1234 \
mysql:5.7
docker logs 명령어는 컨테이너 내부에서 출력을 보여주는 명령어입니다.
- password 가 없는 mysql
docker run -d --name no_password_mysql \
> mysql:5.7
- --tail n: 출력할 줄의 수
- --since: 특정 시간 이후의 로그
- -t: 타임스탬프 표시
- -f: 실시간 출력되는 내용 표시 (애플리케이션 개발에 용이하다.)
기본적으로 위와 같은 컨테이너 로그는 JSON 형태로 도커 내부에 저장됩니다. 이 파일은 다음 경로에 컨테이너의 ID 로 시작하는 파일명으로 저장됩니다.
- 로그가 저장되는 경로
cat /var/lib/docker/containers/${CONTAINER_ID}/${CONTAINER_ID}-json.log
docker run -it \
> --log-opt max-size=10k --log-opt max-file=3 \
> --name log-test ubuntu:14.04
사용 가능한 드라이버는 syslog, journald, fluentd, awslogs 등이 있으며 애플리케이션의 특징에 적합한 로깅 드라이버를 선택합니다.
로깅 드라이버는 기본적으로 json-file 로 설절ㅇ되지만 도커 데몬 시작 옵션에서 --log-driver 옵션을 써서 기본적으로 사용할 로깅 드라이버를 변경할 수 있습니다.
max-size 와 --log-opt 옵션 또한 도커 데몬에 적용함으로써 모든 컨테이너에 일괄적으로 사용할 수 있습니다.도커 데몬 시작 옵션을 변경하는 법은 부록 A 를 참고하기 바랍니다.
2.2.8.2 syslog 로그
syslog 는 유닉스 계열 운영체제에서 로그를 수집하는 오래된 표준 중 하나로서, 커널, 보안 등 시스템과 관련된 로그, 애플리케이션의 로그 등 다양한 종류의 로그를 수집해 저장합니다.
컨테이너의 커맨드가 echo syslogtest 로 설정되기 때문에 이 문구를 출력하고 컨테이너는 종료될 것입니다.
docker run -d --name syslog_container \
--log-driver=syslog \
ubuntu:14.04 \
echo syslogtest
syslog 는 기본적으로 로컬호스트의 syslog 에 저장하므로 운영체제 및 배포판에 따라 syslog 파일의 위치를 알아야 이를 확인할 수 있습니다.
우분투 16.04 와 CoreOS 는
journalctl -u docker.service
입니다.
이번엔 syslog 를 원격에 저장하는 방법의 하나인 rsyslog 를 써서 중앙 컨테이너로 로그를 저장해봅시다.
docker run -i -t \
-h rsyslog \
--name rsyslog_server \
-p 514:514 -p 514:514/udp \
ubuntu:14.04
- rsyslog 설정파일 수정
vi /etc/rsyslog.conf
- rsyslog 서비스를 재시작
rsyslog 는 컨테이너가 아닌 우분투, CentOS 등의 호스트에서도 쓸 수 있으며, 컨테이너를 쓰면 호스트가 어떤 운영체제이든 상관없이 rsyslog 를 사용할 수 있습니다.
VirtualBox 를 실행한 호스트에서 명령 프롬프트를 열어 (윈도우 기준) ipconfig 명령어를 입력한다.
- 클라이언트 호스트에서 컨테이너 생성
docker run -i -t \
--log-driver=syslog \
--log-opt syslog-address=tcp://192.168.56.1:514 \
--log-opt tag="mylog" \
ubuntu:14.04
--log-opt 는 로깅 드라이버에 추가할 옵션을 뜻하며, syslog-address 에 rsyslog 컨테이너에 접근할 수 있는 주소를 입력합니다.
tag 는 로그 데이터가 기록될 때 함께 저장될 태그이며 로그를 분류하기 위해 사용합니다.
네트워크 인터페이스를 배우면 더 심도있게 이해하기 좋을 것 같다.
2.2.8.3 fluentd 로깅
fluentd 는 각종 로그를 수집하고 저장할 수 있는 기능을 제공해주는 오픈소스 도구로서, 도커 엔진의 컨테이너의 로그를 fluentd 를 통해 저장할 수 있도록 플러그인을 공식적으로 제공합니다.
fluentd 는 데이터 포맷으로 JSON 을 사용하기 때문에 쉽게 사용할 수 있을뿐만 아니라 수집되는 데이터를 AWS S3, HDFS (Hadoop Distrubuted File System), Mongo DB 등 다양한 저장소에 저장할 수 있다는 장점이 있습니다.
여기서 살펴볼 예제는 fluentd 와 몽고 DB (MongoDB) 를 연동해 데이터를 저장하는 방법을 보여줍니다.
특정 호스트에 생성되는 컨테이너는 하나의 fluentd 에 접근하고, fluentd 는 몽고 DB 에 데이터를 저장하는 구조입니다.
2.2.8.4 아마존 클라우드워치 로그
AWS 에서는 로그 및 이벤트 등을 수집하고 저장해 시각적으로 보여주는 클라우드워치 (ClodeWatch) 를 제공합니다.
도커를 AWS EC2 에서 사용하고 있다면 다른 도구를 별도로 설치할 필요 없이 컨테이너에서 드라이버 옵션을 설정하는 것만으로 클라우드 워치 로깅 드라이버를 사용할 수 있습니다.
단계
- 클라우드워치에 해당하는 IAM 권한 생성
- 로그그룹 생성
- 로그그룹에 로그 스트림 (LogStream) 생성
- 클라우드워치의 IAM 권한을 사용할 수 있는 EC2 인스턴스 생성과 로그 전송
2.3 도커 이미지
3. 도커 스웜
4. 도커 컴포즈
5. 쿠버네티스 설치
6. 쿠버네티스 시작하기
7. 쿠버네티스 리소스의 관리와 설정
8. 인그레스 (Ingress)
9. 퍼시스턴트 볼륨 (PV) 과 퍼시스턴트 볼륨 클레임 (PVC)
10. 보안을 위한 인증과 인가: ServiceAccount 와 RBAC
11. 애플리케이션 배포를 위한 고급 설정
12. 커스텀 리소스와 컨트롤러
13. 포드를 사용하는 다른 오브젝트들
14. 쿠버네티스 모니터링
'Stacks > 데브옵스' 카테고리의 다른 글
시작하세요! 도커 / 쿠버네티스 legacy (0) | 2022.06.17 |
---|