도커의 컨테이너안에 데이터를 저장할 수 있지만 여기에는 몇 가지 문제점이 존재한다.

1. 컨테이너가 삭제되면 데이터도 삭제된다. 
2. 다른 프로세스에서 특정 컨테이너에 저장된 데이터를 사용하기 어렵다.
3. 컨테이너에 데이터를 저장하기 위해서는 파일시스템을 관리하는 스토리지 드라이버가 필요하다.

   그러나 이 기능은 호스트 파일시스템에 직접 쓴는 것보다 성능이 떨어진다.

따라서 이러한 문제를 해결하기 위해 여러가지 방법이 있는데, 그 중 2가지 방법을 알아본다. 첫번째는 호스트 서버의 경로와 컨테이너의 경로를 연결하는 방식, 두번째는 docker volume을 생성해서 연결하는 방식이다.

 

 

* 호스트 서버의 경로와 컨테이너의 경로를 연결

- docker container run -v 옵션을 사용해서 호스트의 디렉토리와 마운트될 컨테이너의 디렉토리를 명시할 수 있다.

 

 

1. 호스트 디스크를 명시하지 않고 생성

컨테이너에서 -v 명령에서 명시될 디렉토리들은 없으면 알아서 만들어진다. (따라서 미리 만들 필요가 없다) 

- 아래 예시는 한 컨테이너 안에 2개의 마운트 포인트를 만드는 것이다.

- 이 마운트 포인트는 호스트 서버의 /var/lib/docker/volumes에 저장된다. 컨테이너가 삭제되어도 해당 데이터는 남아있다.

- 호스트 디스크는 도커 디렉토리 (/var/lib/docker/volumes) 에 저장되므로, 해당 디렉토리 파티션의 용량이 한도가 된다.

docker run -it --name data_share -v /data_dir -v /test_dir ubuntu /bin/bash

- 참고로, 컨테이너 안에서 df -h 쳤을 때 마운트 포인트가 2개가 나와야 하는데, 하나만 나온다. 2개가 실제로는 있다.

- mount 명령으로 확인하면, 잘 마운트 되어있는 것을 확인할 수 있다.

 

- 호스트에서 해당 컨테이너의 마운트 정보를 보려면 다음과 같이 입력한다.

docker inspect --format="{{ .HostConfig.Binds }}" data_share

 

2. 호스트 디스크를 명시하고 생성

- 호스트 디스크를 따로 명시하므로, 해당 디스크가 외장 스토리지가 될 수도 있고, 다른 내부 저장공간이 될 수도 있다.

- -v 옵션이후 호스트와 컨테이너 디렉토리는 없으면 알아서 만들어진다. 따라서 둘 다 일부러 따로 만들 필요가 없다.

- 이렇게 하면 호스트에 /test1 /test2를 만들어서 각각 컨테이너의 /data_dir, /test_dir 에 마운트된다.

docker run -it --name data_share -v /test1:/data_dir -v /test2:/test_dir ubuntu /bin/bash

- 호스트의 /test1, /test2는 외장 스토리지나 NFS 등 여러방식으로 외장 스토리지가 될 수 있다.

 

# 참고 : 디스크 마운트 설정 시ro/rw 옵션 외 기타 옵션 넣기

docker run -it --name data_share -v /test1:/data_dir:ro -v /test2:/test_dir:rw ubuntu /bin/bash

또한, --volume = host:container1:container2 이런식으로 다중컨테이너에 연결 가능

 

다른 옵션들은 더 이상 자세한 설명은 생략한다.

 

 

 

* docker volume을 구성해서 컨테이너에 연결

docker volume은 따로 docker에서 관리하는 형태로 호스트에 volume을 생성하며, 해당 볼륨은 docker volume ls 등으로 리스트를 확인할 수 있다.  따라서 관리하는 측면에서 훨씬 유용하다. 또한 volume이 저장되는 공간만 외장 스토리지로 마운트하여 대용량으로 사용할수도 있다.

 

도커 volume은 /var/lib/docker/volumes 경로에 저장된다.  또한 각 데이터는 /var/lib/docker/volumes/볼륨명/_data 밑에 저장된다. 이러한 volume 들은 컨테이너가 삭제되어도 그대로 유지된다. 또한 다른 컨테이너에서 다시 마운트하면 해당 데이터를 볼 수 있다.

 

 

1. docker volume 명령 리스트

< 도커 기본 명령어 차례 >

 

● 시스템 명령

docker version

docker system info

docker system df

docker system prune

docker login

locker logout

 

● 이미지 관리 명령

docker pull

docker image ls

docker images

docker image inspect

docker image tag

docker push

docker search

docker image rm

docker image prune

docker container commit

 

● 컨테이너 실행 및 조작 관련 명령

docker container create

docker container run

docker container attach

docker container exec

 

● 컨테이너 정보 확인 명령

docker container ps

docker container stats

docker container inspect

docker container top

docker container port

docker container diff

docker container logs

docker container ls

 

● 컨테이너 관리 명령

docker container stop

docker container start

docker container kill

docker container restart

docker container prune

docker container pause

docker container unpause

docker container rename

docker container cp

 

● 컨테이너/이미지 백업 명령

docker container export

docker container import

docker image save

docker image load

 

● 네트워크 명령

docker network ls

docker network create

docker network connect

docker network disconnect

docker networkinspect

docker network rm

brctl show

 

● 볼륨 명령 
docker volume create 
docker volume ls 
docker volume rm 
docker volume prune 
docker volume inspect


 

docker volume create  볼륨명

- docker에서 사용할 volume을 생성한다. 볼륨명을 명시하지 않으면, random한 이름으로 생성된다.

 

 

docker volume ls 

- 현재 생성되어 있는 모든 볼륨을 보여준다.

- 긴 이름으로 된 볼륨들은 위에서 수행한 "호스트 디스클를 명시하지 않고 생성하거나, 볼륨 생성시 따로 이름을 주지 않은 것들이다.

 

 

docker volume rm  볼륨명

- 현재 존재하는 볼륨을 삭제한다.

 

 

 

docker volume prune

- 사용하지 않는 모든 볼륨을 지울 수 있다. 

 

 

docker volume inspect 볼륨명

- volume의 상세 정보를 확인할 수 있다.

 

# 참고 : 컨테이너가 가지고 있는 볼륨을 확인하기

- docker inspect data_share | grep -i volumes

 

 

2. docker volume을 이용하여 컨테이너 생성하기

run -it --name disk-test -v test-volume:/test ubuntu /bin/bash 

 

 

 

* 동일 디스크 정보를 그대로 공유받기

- 생성된 볼륨이나 파일시스템들은 동시에 볼륨을 여러 컨테이너에 마운트할  수 있다. 아래와 같이 --volumes-from 옵션을 사용할 수 있다.

- 아래 명령은 맨 처음에 만든 data_share 라는 이름의 컨테이너가 가진 볼륨 정보를 그대로 공유받아서 마운트한다. 

docker run -d -it --name disk-test-share --volumes-from data_share  ubuntu /bin/bash

또 새롭게 컨테이너를 만들어서, 예를들어 이름을 disk-test-share2 하고 똑같은 data_share의 볼륨을 "공유" 받을 수 있다. 이렇게 하면 아래와 같은 형식이 될 것이다. 

 

 

 

* 오버레이 파일시스템 드라이버

overlay는 도커에서 사용하는 파일시스템 드라이버이다. 더 이상 자세한 설명은 생략한다. 컨테이너를 만들고 호스트에서 df -h를 쳤을 때 overlay 라고 마운트되어있는 것은 각 컨테이너의 루트디렉토리이다. 즉 /var/lib/docker/overlay2 에는 각 컨테이너의 루트 디렉토리, /var/lib/docker/volumes 에는 생성한 볼륨이 들어간다. 

 

호스트에서 df -h 를 쳤을 때. 아래 overlay라고 써있는 것이 도커 컨테이너들의 루트이다. 

또한 해당 데이터는 마운트 포인트인 /var/lib/docker/overlay2/이름/merged 디렉토리에 저장된다. 들어가보면 루트 파일시스템 같은 모양을 확인할 수 있을 것이다. 컨테이너가 삭제되면, 이 오버레이 마운트 경로의 데이터는 모두 삭제된다.

컨테이너에서 df -h를 쳤을 때. overlay 부분이 / 인 것을 확인할 수 있다.

 

# 참고 : 컨테이너 내에서 lsblk, blkid 명령은 제대로 나오지 않는다.

 

 

* -v 대신 사용하는 --mount 옵션

위에서 언급한대로 독립형 컨테이너에서는 -v / --volume이 사용되며, 도커 스웜 모드에서는 --mount가 사용된다.  이후 도커 17.06 부터 --mount를 독립형 컨테이너에서 사용할 수 있게 되었다. 따라서 -v 옵션 외에 --mount 옵션도 쓸 수 있다. 특히 특정 볼륨 드라이버를 명시해서 사용할 때는 --mount를 사용해야 한다. 


--mount 옵션은 쉼표(,)로 구분되고 각각 여러 key-value 쌍으로 구성된다. --mount 구문은 -v 또는 --volume보다 길지만, key의 순서는 중요치 않으며 Flag의 값을 이해하기 쉽게 되어있다.

 

예시

docker run -d -it --name=nginxtest --mount source=nginx-vol,destination=/usr/share/nginx/html,readonly nginx:latest

- type : mount의 유형을 지정한다. (bind, volume,tmpfs)

- source(src) : volume의 이름. 익명 볼륨을 사용한다면 생략해도 된다.

- destination(dst,target) : 컨테이너에 마운트 될 경로

- readonly : 컨테이너에 읽기 전용으로 마운트됨

opt 등 여러 추가 옵션이 있으나 더 이상 자세한 설명은 생략한다.

 

 

 

 

* 추가 예시 : dd로 디스크 img 파일을 만들어 할당하기

 

1. disk 파일 생성

dd if=/dev/zero of=파일명 count=512 bs=1M

 

2. 해당 이미지 파일로 파일시스템 생성

mkfs.ext4 harddrive.img

 

3. 호스트 서버에서 테스트 디렉토리 생성 후 마운트

mkdir /test
mount /harddrive.img /test

 

4. 도커 컨테이너를 만들고 해당 파일시스템을 참조시킨다.

docker run -it -v /test:/container_dr ubuntu /bin/bash

 

5. 컨테이너 상에서 확인. 파일시스템의 사이즈와 안에 있는 데이터를 확인할 수 있다.

df -h

 

htop은 기존의 top보다 더 향상된 시스템 모니터링 툴로서, 프로세스 뷰어 및 프로세스 관리자이다. top 과 두드러지게 다른점은 htop은 색을 사용하여 좀 더 효과적인 시각화를 꾀했고, 또한 CPU 각각의 사용율을 쉽게 볼 수 있어서 매우 편하다. 공식 사이트는 다음과 같다.

 

http://hisham.hm/htop/

 

htop - an interactive process viewer for Unix

htop - an interactive process viewer for Unix This is htop, an interactive process viewer for Unix systems. It is a text-mode application (for console or X terminals) and requires ncurses. Latest release: htop 2.2.0. What's new in htop The latest releases

hisham.hm

 

* 설치

이 설명은 CentOS를 기준으로 설명한다. htop은 CentOS 배포판에 포함된 프로그램이 아니므로, 따로 Repository를 구성한 후 다운을 받을 수 있다. 아래와 같이 수행한다.

yum install epel-release   (Repository 설정)
yum install htop (htop 다운로드)

 

 

* 실행

모든 상황은 1초마다 업데이트 되며 상단의 1,2,3,4 는 CPU 코어, Mem은 물리 메모리, Swp은 스왑 메모리를 의미한다. PID 등 값의 정렬이나 기능키 등은 마우스로 클릭해서 사용할 수도 있다.

 htop

 

* 간단한 기능키

- F1 : 도움말

- F2 : 환경설정

- F3 : 검색. F3을 누른 후 검색어 입력하면 현재 화면에서 해당 검색어를 찾아준다. 다음으로 넘어가려면 또 F3 입력

- F4 : 필터. 원하는 키워드를 넣으면 해당 키워드가 있는 라인만 필터해서 보여준다. 아래는 sshd로 필터한 값.

- F5 : 프로세스 트리 형태로 보여준다.

- F6~F9 : 더이상 자세한 설명은 생략한다. 다만 스페이스로 각각의 프로세스들을 선택한 후 F6~F9를 사용하면 된다.

- F10 : 종료

 

* F2 환경설정 

htop을 사용자가 좀 더 원하는 방식으로 한눈에 알아볼 수 있도록 정보들의 출력 형식을 조정한다. 키보드 방향키(상하좌우) 와 엔터를 사용하여 설정을 수행할 수 있다.

 

 

Meters

Left column은 붉은색 네모칸, Right column은 노란색 네모칸 부분의 정보들을 의미한다.  맨 오른쪽에 Available meters는 Left 또는 Right column에 넣을 수 있는 정보들이다.  이런 정보를 원하는 대로 넣고 저장하면, 다음에 사용할때는 세팅한 대로 화면에 정보를 보여주게 된다. 필요없는 값은 del로 지울 수 있다. 아래 예시처럼 원하는 대로 변경할 수 있다.

또한 각 값에 대해 스페이스를 누르면 모양을 변경할 수 있다. 바 형태, 그래프 형태, 비율 형태 등 여러가지 모양으로 조정할 수 있다. 예를 들어, CPU 1 [Graph] 또는 [Bar] 등 값을 확인할 수 있다.

 

Display Options

화면 설정. 더 자세한 설명은 생략한다.

 

Colors

테마 처럼 사전에 정의된 색깔 타입으로 바꿀 수 있다.

 

columns

각각의 성능정보를 나타내는 컬럼들을 커스텀할 수 있다. 필요한 것은 추가하고 필요 없는것은 지우는 등, Meter에서 하는 것처럼 동일하게 설정 가능하다. 또한 각각 컬럼들의 의미도 상세하게 설명되어 있다.

 

도커 컨테이너에서는 여러가지 자원을 할당할 수 있는데, 할당하지 않으면 해당 컨테이너는 마음대로 호스트의 자원을 사용한다. (CPU, MEMORY, swap 등) 따라서 어플리케이션에 따라 사용하는 자원의 양을 제한하는 것은 매우 중요하다.  이러한 자원 제한은 cgroup의 기능을 도커 명령어로 손쉽게 사용할 수 있다.

 

docker container run 명령을 실행할 때, 아래 옵션들 (외에 추가로 많음) 을 사용해서 컨테이너의 자원을 어떻게 쓸지 정의할 수 있다. 이러한 제한이 없으면, 컨테이너는 Host OS의  자원을 제한없이 사용한다. 옵션 설정을 통해 다른 컨테이너의 동작 간섭을 방해하지 않게 할 수 있다.  생성 후 변경 시에는 docker update 명령으로 변경을 할 수 있다. 이러한 리소스 제한 기능은 리눅스의 cgroups 기능을 활용하는 것이다.

 

이러한 성능 제한 작업을 수행하면서 htop 등으로 모니터링 하여 변화를 테스트 할 수 있다. htop 사용을 위해서는 다음 링크를 참고한다.

2020/06/10 - [Performance] - Linux 시스템 모니터링 Tool - htop

 

Linux 시스템 모니터링 Tool - htop

htop은 기존의 top보다 더 향상된 시스템 모니터링 툴로서, 프로세스 뷰어 및 프로세스 관리자이다. top 과 두드러지게 다른점은 htop은 색을 사용하여 좀 더 효과적인 시각화를 꾀했고, 또한 CPU 각��

watch-n-learn.tistory.com

 

* 메모리 제한

 

메모리 관련 옵션

--memory, -m, --memory-swap 등

 

1. nginx의 메모리 사이즈를 1G로 제한하기

docker run -d --memory=1g --name=nginx_mem_1g nginx

 

# 참고 : swap 관련 메시지 발생하는 경우

WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.

grub을 수정해야 함. 호스트에서,  vi /etc/default/grub 에 GRUB_CMDLINE_LINUX_DEFAULT="cgroup_enable=memory swapaccount=1" 을 추가해야 함. 이후 grub rebuild 수행 후 리스타트

 

2. 메모리 확인

- Memory 부분이 1073741824 값이 나온다. 이것은 Byte 단위이다.

- 참고로, 이렇게 제한하지 않고 그냥 컨테이너를 생성하는 경우 다음과 같이 Memory 부분이 0으로 나온다.

 

# 참고 : 컨테이너 내부에서 시스템 정보를 확인할 때

- 컨테이너에서 /proc/meminfo에서는 해당 컨테이너가 아닌 해당 호스트의 정보가 나온다.

- 커널 버전이라던지, cpu 개수라던지 등도 마찬가지이다.

 

 

* swap 메모리 제한

1. ubuntu OS의 swap 메모리 사용을 300MB 로 제한하기

docker run --memory=200m --memory-swap=300m -it ubuntu /bin/bash

 

2. swap 메모리 확인

 

# 참고 : 만약, 사용하는 컨테이너에 실제 사이즈와 맞지않게 메모리를 제한하면 FAIL 발생한다.

docker run -it --memory=4m --name=mysql mysql:5.7

ERROR : mysqld faile whild attempting to check config

 

 

* CPU 제한

CPU를 제한하는 데는 여러가지 옵션이 있다. 그 중 대표적인 옵션만 설명한다.

 

# 참고

CPU 부하를 주기 위해 alicek106이 만든 stress라는 컨테이너를 사용한다. 또한 맨 뒤에 --cpu 1은 사용할 cpu의 개수를 의미한다.

 

1. 특정 코어로 CPU 제한 (--cpuset-cpus)

호스트에 CPU가 여러개 있을 때 --cpuset-cpus를 지정해 컨테이너가 특정 CPU만 쓰도록 할 수 있다. CPU 집중적인 작업이 필요하다면 여러개 CPU를 사용하여 작업을 잘 분배하도록 해야 한다. 아래 예시에서 확인할 수 있다.

 

* 특정 CPU 코어 1개 사용하도록 허용 
docker run -d --cpuset-cpus=3 alicek106/stress stress --cpu 1

* 특정 CPU 코어 2개 사용하도록 허용
docker run -d --cpuset-cpus=0,3 alicek106/stress stress --cpu 2 

* 특정 CPU 코어 3개 사용하도록 허용
docker run -d --cpuset-cpus=0-2 alicek106/stress stress --cpu 3

 

 

2. CPU 사용 비율 제한하기 (--cpus)

--cpus는 각 컨테이너에게 CPU를 최대 몇 % 할당할 수 있는지를 명시한다. CPU가 1개 기준으로, 값은 0~1이다. 1은 비율을 의미하며 100%를 의미한다. 즉 0.5 로 하면 50%까지 최대 사용할 수 있다는 뜻. 근데 만약 CPU를 3개로 했다면 값은 0~3이 되며 최대값 3이 100%를 의미하게 된다.  정리하면, 컨테이너가 사용하도록 허용한 CPU의 개수에 따라 사용량 최대값이 변한다는 것.

* CPU 3개를 100% 사용
docker run -d --cpuset-cpus=0-2 --cpus=3 alicek106/stress stress --cpu 3

* CPU 3개를 각각 약 33%씩 사용 
docker run -d --cpuset-cpus=0-2 --cpus=1 alicek106/stress stress --cpu 3 

 


* CPU 1개를 50% 사용
docker run -d --cpuset-cpus=1 --cpus=0.5 alicek106/stress stress --cpu 1

 

3. 상대적 가중치 제한 (--cpu-shares)

--cpu-shares는 한 코어에 여러 도커 컨테이너가 작동할 때, 컨테이너간 상대적 가중치이다. 실제 프로세서 클럭 속도와는 관련이 없다. 모든 컨테이너는 기본적으로 1024 값을 가지고 있고, 혼자 한 코어를 사용할 때는 아무 의미가 없다. 한 코어에 두 컨테이너가 시작하는 경우, cpu-share 값을 설정하지 않으면 기본값인 1024를 가지기 때문에 CPU 시간이 둘 다 균등하게 분할된다. (해당 코어를 쓰는 다른 프로세스가 없다고 가정)

 

만약 두 컨테이너 중 한 컨테이너에 cpu-share 512 값을 설정한다면, 다른 1024의 컨테이너에 비해 CPU 시간이 절반이 사용된다. 그러나 이것이 CPU의 절반만 사용한다는 의미는 아님. 다른 컨테이너가 유휴 상태인 경우, 512로 설정한 컨테이너도 CPU의 100%를 쓸 수 있다. 또한 이러한 가중치 제한은 필요할 때만 수행된다. 사전에 CPU를 제한하는게 아니고, 많은 프로세스가 동시에 CPU를 많이 사용하는 경우 같이 이런 경우에 수행된다. 아래는 여러가지 예시이다.

 

* 같은 코어를 쓰는 두 컨테이너에 둘 다 1024 값 사용

docker run -d --cpuset-cpus=3 --cpu-shares 1024 alicek106/stress stress --cpu 1

docker run -d --cpuset-cpus=3 --cpu-shares 1024 alicek106/stress stress --cpu 1

둘 다 비슷하게 50%를 사용한다.

 

* 같은 코어를 쓰는 두 컨테이너에 하나는 1024, 하나는 512 값 사용

docker run -d --cpuset-cpus=3 --cpu-shares 1024 alicek106/stress stress --cpu 1
docker run -d --cpuset-cpus=3 --cpu-shares 512 alicek106/stress stress --cpu 1

한쪽은 70%, 다른 한쪽은 30%정도 사용한다.

 

* 같은 코어를 쓰는 두 컨테이너에 하나는 1024, 하나는 256 값 사용

docker run -d --cpuset-cpus=3 --cpu-shares 1024 alicek106/stress stress --cpu 1
docker run -d --cpuset-cpus=3 --cpu-shares 256 alicek106/stress stress --cpu 1

한쪽은 80%, 다른 한쪽은 20%정도 사용한다.

 

* 한 컨테이너만 512값으로 줄 때

docker run -d --cpuset-cpus=3 --cpu-shares 512 alicek106/stress stress --cpu 1

해당 코어를 쓰는 컨테이너가 하나뿐이므로 100% 모두 사용한다.

 

 

 

* 디스크 I/O 제한

도커 컨테이너는 block I/O 관련하여 옵션을 지정하지 않으면 무제한으로 I/O를 사용한다. 이러한 무분별한 I/O 사용을 막기 위해 여러가지 옵션이 있다. - --device-write-bps, --device-read-bps, --device-write-iops, --device-read-iops 등이 있다. 단 direct I/O만 제한하며, bufered I/O는 제한하지 않는다.

 

또한 이렇게 값을 설정한다 하더라도, 실제 물리 디스크의 성능에 따라 달라질 수 있다. 따라서 제한 없는 상태에서의 디스크 성능을 미리 알고 있어야 하며, 그 상태를 기준으로 제한을 건 후 값이 어떻게 나오는지 테스트 및 검증을 수행해야 한다. 디스크의 block I/O 성능은 초당 얼마 사이즈를 I/O 할 수 있느냐를 알 수 있으면 된다.

 

여기서는 4가지 옵션 중 --device-write-bps 옵션을 사용하여 초당 쓰기속도를 설정해본다. dd 명령을 사용하여 10메가 파일을 생성할 때 걸리는 시간을 측정한다. 

 

 

* 초당 1MB로 속도 제한

docker run -it --device-write-bps /dev/sda:1mb ubuntu:14.04 bash

실제로 약 10초가 걸렸다.

 

초당 10MB로 속도 제한

docker run -it --device-write-bps /dev/sda:10mb ubuntu:14.04 bash 

실제로 약 0.9초가 걸렸다.

 

 

* 운영중에 자원 변경하기

컨테이너를 내렸다 올리지 않고, 값을 업데이트하여 사용량 제한 값을 변경할 수 있다. 다음 예시를 참고할 것.

 

docker update --cpu-shares 512 컨테이너명

docker update --cpus=0.2 컨테이너명

사전 네트워크 정보

- docker 호스트는 Virtual Box 가상머신이고, 네트워크는 내 컴퓨터 어댑터에 브릿지를 했음.

- 내 컴퓨터는 공유기 밑에서 192.168.1.X 이고, docker 호스트는 192.168.1.61 이다.

- 어댑터에 브릿지를 했으므로, docker 호스트 가상머신은 내 컴퓨터와 동일한 네트워크의 서버로 이해할 수 있다.

 

nginx 컨테이너 생성하기

nginx는 대량의 요청을 처리하는 대규모 사이트에서 주로 이용하며, 리버스 프록시나 로드밸런서와 같은 기능도 갖고 있다.

 

docker container run --name webserver -d -P nginx

- nginx의 포트를 호스트의 임의 포트에 할당하여 백그라운드로 nginx 실행. 컨테이너 이름은 webserver 이다.

- 이미지가 없으면 알아서 자동으로 받는다.

 

2. 현재 상태 확인

docker ps

- 컨테이너의 80번 포트와 호스트의 32805 포트가 연결된 것을 확인할 수 있다.

 

3. 직접 접속 테스트

 

 

node.js 컨테이너 생성하기

1. 컨테이너 생성

docker run -d -it -p 9000:8000 --name=nodejs_test2 node:latest 

- 최신 node.js 컨테이너를 생성함. 백그라운드로 생성하고 인터렉티브 쉘을 열며, 이름은 nodejs_test2 이다.

 

2. 현재 상태 확인

docker ps

- 컨테이너에서 8000번포트를 사용하고, 호스트에서는 9000번 포트를 사용하여 컨테이너의 8000번 포트와 연결

 

3. 예시파일 만들기

var http = require('http');
var content = function(req, resp) {
        resp.end("Welcome to Kubernetes~!" + "\n");
        resp.writeHead(200);
}
var w = http.createServer(content);
w.listen(8000);

- 위 내용을 vi로 호스트 서버에서 nodejs_test.js 로 생성한다.

- 이 예시는 8000번 포트를 listen 하도록 설정하였다. (컨테이너의 열린 포트가 8000이므로)

 

4. 예시파일을 컨테이너에 복사하기

docker cp nodejs_test.js nodejs_test2:/nodejs_test.js

 

5. 컨테이너에 진입 후 node.js 실행

docker exec -it nodejs_test2 /bin/bash

- 진입 후, ls 명령으로 확인하면 nodejs_test.js 가 있는것을 확인할 수 있다.

- 해당 파일 위치를 확인후, 아래와 같이 실행한다.

node nodejs_test.js

- 아래와 같이 프롬프트가 떨어지지 않고 유지된다.

 

6. 직접 접속 테스트

 

 

httpd (Apache) 컨테이너 생성하기

1. 컨테이너 생성

docker run -d -p 8080:80 --name httpd-basic httpd:2.4

- httpd를 백그라운드로, 이름은 httpd-basic, 버전은 2.4 버전으로 컨테이너를 생성한다.

 

2. 현재 상태 확인

docker ps

- 포트는 컨테이너 80번, 호스트OS는 8080번으로 포트를 연결하였음.

 

3. 직접 접속 테스트

 

 

docker container run 명령 개요

docker container run 구문은 도커에서 가장 중요하고 기능이 많아서, 따로 한 페이지로 떼어 두었다. 사실상 가장 핵심적인 내용이다. 이 run 명령어는 pull, create, start 3가지를 모두 수행한다. 그래서 이미지가 없이 run을 수행하면 이미지를 받고, 컨테이너를 생성하고, 시작도 수행한다. 시작하면서 명시한 명령도 수행한다. 

docker container(안써도됨) run [옵션] 도커이미지명[:태그] [명령어]

이 명령의 옵션은 크게 4가지로 나뉜다. 그 설정은 다음과 같다.

 

  • 컨테이너 설정 옵션

  • 네트워크 설정 옵션

  • 환경변수 설정 옵션

  • 자원제한 설정 옵션

또한 도커 서버가 아닌 도커 서버-클라이언트로 구성된 경우(즉, 서버는 따로 있고 내가 명령어 치는 곳이 클라이언트인 경, 클라이언트에서 docker run 을 수행하면, 도커 서버의 docker daemon에 의해 실행되며, 결과를 클라이언트가 받아서 볼 수 있다.

 

컨테이너 설정 옵션

attach, -a

표준입력, 표준출력, 표준오류출력에 어태치한다.

--cidfile

컨테이너 아이디를 파일로 출력한다.

--detach, -d

컨테이너를 생성하고 백그라운드에서 작동시킨다. 보통 많이 쓴다. 

--interactive, -i

컨테이너의 표준 입력을 연다.

--tty, -t

단말기 디바이스를 사용한다.

--name

컨테이너의 이름을 만든다. 안쓰면, 랜덤으로 생성된다.

--user, -u

사용자명을 지정

--restart=[옵션]

명령의 실행 결과에 따라 재시작을 하는 옵션

no : 재시작하지 않음

on-failure : 종료 스테이터스가 0이 아닐 때 재시작한다.

on-failure:횟수n : 종료 스테이터스가 0이 아닐 때 n번 재시작한다.

always : 항상 재시작한다. (exit로 나가도, 재시작한다)

unless-stopped : 최근 컨테이너가 정지 상태가 아니라면 항상 재시작한다.

--rm

명령 실행 완료 후에 컨테이너를 자동 삭제 (--restart 옵션과 함께 사용할 수 없음)

 

# 참고 : 컨테이너의 "종료"
대부분의 컨테이너는 명령어에 /bin/bash를 넣으면, 해당 컨테이너에 진입할 수 있다. 컨테이너 진입한 후, exit를 입력하면 쉘에서 나가는게 아니고, 컨테이너를 "종료" 한다. 컨테이너에 인수를 넣으면, 그 인수를 "가진" 컨테이너로써 생성된다. 원래 컨테이너는 인수 없이 컨테이너에 구축된 내용 그대로 사용한다. 하지만 필요한 경우와 여러가지 사용을 위해 인수(명령어)를 추가하여 컨테이너를 실행한다. 컨테이너를 종료하지 않으려면, ctrl+p+q를 입력하여 빠져나올 수 있다.

 

docker container run centos

아무 일도 없이 컨테이너가 종료된다. 받은 인수가 없어 할 일이 없기 때문이다.

 

docker container run -itd centos

컨테이너가 백그라운드로 작동하고, 표준 입력 터미널이 열린 상태가 된다. 컨테이너가 계속 유지된다.

 

docker container run centos /bin/cal

아래와 같이 결과가 나오며 컨테이너가 종료된다. 받은 인수의 결과를 리턴하고 더이상 할 일이 없기 때문이다.

 

docker container run -itd centos /bin/cal

아무 결과도 없이 컨테이너가 종료된다. 백그라운드에서 /bin/cal을 실행하고 종료되었기 때문이다.

 

docker container run -it centos /bin/ping localhost

컨테이너로 진입 후 계속 핑을 날리게 된다. 끝없이.

ctrl+p+q로 빠져 나가면 이것은 백그라운드로 계속 ping을 날리는 중이다. 컨테이너는 살아있다.

만약 ctrl+p+q로 빠져 나가지 않고 exit로 나갔다면, 해당 명령이 끝나므로 컨테이너는 종료된다. 

 

 

네트워크 설정 옵션

포트 번호같은 네트워크 설정을 통해 외부에서 컨테이너의 프로세스에 액세스하도록 설정할 수 있고, 컨테이너끼리 통신도 할 수 있는 여러가지 네트워크 통신을 설정할 수 있다.

--add-host=[호스트명:ip주소]

컨테이너의 /etc/hosts 에 호스트명과 ip 정의

--dns=[ip주소]

컨테이너용 dns서버의 ip주소 지정

--expose

지정된 범위의 포트 번호를 할당
호스트OS까지만 해당 컨테이너의 포트를 노출한다. (외부에는 노출하지 않음)
expose한 포트는 호스트에서만 연결이 된다.
호스트에서만 쓸 목적으로 사용하는것이며 서비스로는 사용하지 않는다.

--mac-address=[맥주소]

컨테이너의 맥주소 지정

--net=[bridge | none | container:<이름 | id> | host | NETWORK]

컨테이너의 네트워크를 지정. 도커에서는 기본적으로 호스트os와 브릿지 연결을 하며, --net옵션을 통해 네트워크 설정 가능

- bridge : 브리지연결 사용 (default)

- none : 네트워크 연결하지 않음

- container:[이름 | id] 다른 컨테이너의 네트워크를 사용 (해당 컨테이너의 네트워크 기법을 그대로 사용하겠다는 의미.)

- host : 컨테이너가 호스트 os의 네트워크를 사용

- NETWORK : 사용자 정의 네트워크를 사용

--hostname, -h

컨테이너 자신의 호스트명을 지정

--publish, -p [호스트의포트번호]:[컨테이너포트번호]

호스트포트와 컨테이너포트를 매핑. 명시한 포트에 대한 액세스를 허가하기 위해 사용된다.
(-p 80:80 이라고 하면, 80번 포트에 대한 액세스를 허가)
호스트os를 넘어 외부에 포트를 오픈한다.

둘이 되도록이면 같은 포트는 피해야 한다. -p 1521:1523 이런식으로.
-p  80 이렇게 하나만 있으면 컨테이너의 포트이다. 호스트포트는 알아서 지정하라는뜻.

docker ps에서 의미 예시
 -p 8080:80 옵션으로 하면 다음과 같이 docker ps에서 확인할 수 있다.
0.0.0.0:8080->80/tcp
 : 컨테이너 80/tcp가 호스트 0.0.0.0:8080에 연결된 것. 
즉, 외부에서 도커 호스트의 8080 포트로 요청이 들어오면, 컨테이너의 80번 포트로 해당 요청을 forword.
--publish-all, -P 호스트의 임의의 포트를 컨테이너에 할당. 호스트os를 넘어 외부에 포트를 오픈한다.
알아서 32767번부터 포트를 임의로 넣어준다. 아무옵션없이 대문자P 로 옵션을 넣기만 하면 됨

 

예시 : 포트 설정

docker container run -d -p 8080:80 nginx

- nginx라는 이미지를 바탕으로 컨테이너를 생성하고, 백그라운드에서 실행한다. 그리고 호스트 포트 8080과 컨테이너포트 80을 매핑한다. (0.0.0.0:8080->80/tcp)

- 즉 이 명령을 실행하여 컨테이너를 만든 후, 브라우저 등에서 호스트의 8080에 엑세스하면 컨테이너에서 작동하고 있는 nginx(80번포트) 서비스에 엑세스할수 있다.

 

예시 : dns 서버 설정

docker container run -d --dns 192.168.1.1 nginx

 

예시 : 맥주소 설정

docker container run -d --mac-address="92:d0:c6:0a:29:33" centos

- docker container inspect --format="{{ .Config.MacAddress }} 로 실제 설정값 확인 가능

 

 

예시 : /etc/hosts 호스트명과 ip주소 정의하기

docker container run -it --add-host test.com:192.168.1.1 centos

 

예시 : 컨테이너 호스트명 설정

docker container run -it --hostname www.test.com

- 이 값은 자신의 /etc/hosts에도 자동으로 적용된다.

 

 

예시 : 도커 네트워크 명시하여 연결

docker container run -itd --name=webap --net=web-network nginx

- nginx 이미지이고 이름이 webap인 컨테이너를 web-network라는 도커 네트워크에 연결한다.

 

 

 

서버 환경설정 옵션

해당 컨테이너 OS의 환경설정을 컨테이너 생성시 사전에 설정할 수 있다. DB나 특정 어플리케이션들은 환경변수가 필수이며, 해당 환경변수 관련해서는 Docker hub의 description을 참고해야 한다.

--env=[환경변수], -e

환경변수 설정. -e -e -e 이런식으로 여러개 나열해서 명시할 수있음.

--env-file=[파일명]

환경변수를 파일로부터 설정(양이 많을 때)

--read-only=[true | false]

컨테이너의 파일 시스템을 읽기 전용으로 만듬

--workdir=[경로], -w

컨테이너의 작업 디렉토리 (시작디렉토리) 지정. 디렉토리는 자동으로 만들어진다.

--user=[사용자명], -u

사용자명 또는 UID를 지정한다.

 

예시 : 환경변수 설정

docker container run -it -e foo=bar centos /bin/bash

컨테이너 들어간 후, set 명령을 치면 설정된 환경변수들을 확인할 수 있다.

 

예시 : 환경변수 파일로 여러개 일괄 등록하기

# cat env_list
hoge=fuga
foo=bar

docker container run -it --env-file=/test/env_list centos /bin/bash

 

예시 : 컨테이너의 작업 디렉토리를 지정하기

docker container run -it -w=/tensorflow centos /bin/bash

 

 

 

자원설정 옵션

다음 포스팅에서 상세하게 확인할 수 있다.

2020/05/15 - [Docker Basic] - [Docker Basic] 15. Docker Container 자원 제한

 

[Docker Basic] 15. Docker Container 자원 제한

도커 컨테이너에서는 여러가지 자원을 할당할 수 있는데, 할당하지 않으면 해당 컨테이너는 마음대로 호스트의 자원을 사용한다. (CPU, MEMORY, swap 등) 따라서 어플리케이션에 따라 사용하는 자원�

watch-n-learn.tistory.com

 

 

 

# 추가 개념 이해 : 도커 컨테이너가 꺼질 때도 있고 안꺼질 때도 있는데..??

도커 컨테이너를 단순히 나갈려고 했는데 컨테이너가 내려가는 경우가 많다. Production 장비에서는 매우 위험한 일이므로 docker run의 개념과 컨테이너 내부에서 exit 명령과 ctrl+p+q 를 정확히 이해해야 한다. 테스트에는 "운영체제" 컨테이너와 "프로그램" 컨테이너 2가지에 따라 실행 및 종료 옵션을 여러가지 변경하여 테스트를 해 보았다. 그냥 아무생각 없이 도커에서 아래 내용을 쭉 쳐보면서 설명을 읽어보면 컨테이너가 어떻게 작동하는지 어느정도 감을 잡을 수 있을 것이다.

 

* 운영체제 컨테이너

 

docker run ubuntu 

프롬프트 떨어짐. 컨테이너 종료됨
docker ps -a로 확인하면, COMMAND 부분이 "/bin/bash"라고 되어있음.
포그라운드에서 bash 쉘을 실행한 후, 추가로 할 것이 없으므로 종료된다.

 

docker run ubuntu /bin/bash 

 

프롬프트 떨어짐.  컨테이너 종료됨. 위와 동일하다.
docker ps -a로 확인하면, COMMAND 부분이 "/bin/bash"라고 되어있음.

포그라운드에서 bash 쉘을 실행한 후, 추가로 할 것이 없으므로 종료된다.


docker run -it ubuntu

컨테이너 프롬프트로 들어가짐.  exit 로 나가면 컨테이너 종료됨. ctrl+p+q 로 나가면 계속 살아있음
docker attach 컨테이너명 으로 들어간 후 exit 쳐서 나가면, 컨테이너는 종료된다.

attach는 단순히 컨테이너에 붙은 것이고, 현재 컨테이너상태에 대하여 exit를 했기 때문.

컨테이너의 표준 입력 옵션이 들어있으므로 컨테이너에 진입된 상태가 유지된다.


docker run -it ubuntu /bin/bash
컨테이너 프롬프트로 들어가짐.  exit 로 나가면 컨테이너 종료됨.  ctrl+p+q 로 나가면 계속 살아있음. 위와 동일하다.
docker attach 컨테이너명 으로 들어간 후 exit 쳐서 나가면, 컨테이너는 종료된다.

attach는 단순히 컨테이너에 붙은거고, 현재 컨테이너상태에 대하여 exit를 했기 때문.

컨테이너의 표준 입력 옵션이 들어있으므로 컨테이너에 진입된 상태가 유지된다.

 

docker run -d ubuntu
프롬프트 떨어짐. 종료됨
docker ps -a로 확인하면, COMMAND 부분이 "/bin/bash"라고 되어있음.

백그라운드에서 bash 쉘을 실행한 후, 추가로 할 것이 없으므로 종료된다.


docker run -d ubuntu /bin/bash
프롬프트 떨어짐. 종료됨
docker ps -a로 확인하면, COMMAND 부분이 "/bin/bash"라고 되어있음.
백그라운드에서 bash 쉘을 실행한 후, 추가로 할 것이 없으므로 종료된다


docker run -it -d ubuntu
프롬프트 떨어짐. 종료되지 않음. 백그라운드에서 bash 쉘이 실행되고 표준 입력이 실행된 상태이기 때문.
docker ps -a로 확인하면, COMMAND 부분이 "/bin/bash"라고 되어있음.
docker exec -it ubuntu /bin/bash로 들어간 후 exit 쳐서 나가면, 컨테이너는 종료되지 않는다. exec로 실행한 /bin/bash가 종료되었을뿐.
docker attach 컨테이너명 으로 들어간 후 exit 쳐서 나가면, 컨테이너는 종료된다. attach는 단순히 컨테이너에 붙은거고, 현재 컨테이너상태에 대하여 exit를 했기 때문.

 

docker run -it -d ubuntu /bin/bash
프롬프트 떨어짐. 종료되지 않음. 백그라운드에서 bash 쉘이 실행되고 표준 입력이 실행된 상태이기 때문.
docker ps -a로 확인하면, COMMAND 부분이 "/bin/bash"라고 되어있음.
docker exec -it ubuntu /bin/bash로 들어간 후 exit 쳐서 나가면, 컨테이너는 종료되지 않는다. exec로 실행한 /bin/bash가 종료되었을뿐.
docker attach 컨테이너명 으로 들어간 후 exit 쳐서 나가면, 컨테이너는 종료된다. attach는 단순히 컨테이너에 붙은거고, 현재 컨테이너상태에 대하여 exit를 했기 때문.

 


* 소프트웨어 컨테이너


docker run httpd:latest
이렇게 하면, 로그만 뜨고 대기함. 프롬프트도 안뜸. ctrl+c 로 나가면, 컨테이너 종료됨, docker ps -a로 확인하면, COMMAND 부분이 "http-foreground"라고 되어있음.
crtl+c 나가기 전에, 창을 하나 더 띄워서 docker ps 로 보면 살아있다.

즉 OS에 httpd를 실행시켜놓은 상태로 run 되었고, 계속 실행중이므로 프롬프트 없이 대기하는 것임.


docker run httpd:latest /bin/bash
이렇게 하면, 그냥 끝남. 프롬프트 떨어짐. /bin/bash라는 배쉬 쉘을 실행한 후, 할게 없으니 종료된다. docker ps -a로 확인하면, COMMAND 부분이 "/bin/bash"라고 되어있음.

실제로 이것은 httpd가 실행되어있는 컨테이너의 OS에서 /bin/bash를 실행한 것이다. /bin/bash를 실행하고 할 게 없으므로 종료되는 것.

 

docker run -it httpd:latest
이렇게 하면, 로그 뜨고 컨테이너 프롬프트가 뜬다. httpd가 올라가 있는 컨테이너 OS를 포그라운드로 실행했으므로.

ctrl+c로 나가면 컨테이너는 종료된다. 즉, httpd가 종료되며 컨테이너도 종료되는 것.
docker ps -a로 확인하면, COMMAND 부분이 "http-foreground"라고 되어있음.

docker run -it httpd:latest /bin/bash
이렇게 하면, 컨테이너 프롬프트가 뜬다. httpd가 올라가 있는 컨테이너 OS에 /bin/bash를 포그라운드로 실행했으므로.
exit로 나가면 컨테이너가 종료된다. 즉 컨테이너 실행시 명시한 /bin/bash가 끝났기 때문에 컨테이너 자체가 종료되는 것.
crtl+c 나가기 전에, 창을 하나 더 띄워서 docker ps 로 보면 살아있다.
이상태에서, docker exec -it 이름 /bin/bash 라고 하면 들어가짐. 들어간 후 exit 하면? 컨테이너는 살아있다. 이유는? exec로 실행한 /bin/bash 만 종료했기 때문. 최초 실행한 /bin/bash는 실행된 상태에서 아직 유지중.
docker attach 컨테이너명 으로 들어간 후 exit 쳐서 나가면, 컨테이너는 종료된다. attach는 단순히 컨테이너에 붙은거고, 현재 컨테이너상태에 대하여 exit를 했기 때문.

docker run -d httpd:latest
이렇게 하면, 그냥 프롬프트 떨어지고, 컨테이너는 계속 살아있다.
이상태에서, docker exec -it 이름 /bin/bash 라고 하면 들어가짐. 들어간 후 exit 하면? 컨테이너는 살아있다. 이유는? exec로 실행한 /bin/bash 만 종료했기 때문.
docker attach 컨테이너명 으로 들어간 후 exit 쳐서 나가면, 컨테이너는 종료된다. attach는 단순히 컨테이너에 붙은거고, 현재 컨테이너상태, 즉 httpd을 실행한 것에 대하여 exit를 했기 때문.

docker run -d httpd:latest /bin/bash
이렇게 하면 그냥 프롬프트 떨어지고, 컨테이너는 종료된다.
/bin/bash를 백그라운드로 실행시키고 할 게 없으니 종료된 것임.

docker run -it -d httpd:latest
이렇게 하면, 프롬프트 떨어지고 컨테이너는 계속 살아있다.
이상태에서, docker exec -it 이름 /bin/bash 라고 하면 들어가짐.

들어간 후 exit 하면? 컨테이너는 살아있다. 이유는? exec로 실행한 /bin/bash 만 종료했기 때문. 그냥 -d로 한 것과 동일하다.
docker attach 컨테이너명 으로 들어가면 바로 종료된다. -it 옵션이 인터렉티브 모드이고, 인터렉티브 상태를 attach 했는데 그 후 할 게 없으므로 종료됨. (조심해야 할 듯)

attach는 단순히 컨테이너에 붙은거고, 현재 컨테이너상태에 대하여 exit를 했기 때문.

docker run -it -d httpd:latest /bin/bash
이렇게 하면, 프롬프트 떨어지고 컨테이너는 계속 살아있다. 
이상태에서, docker exec -it 이름 /bin/bash 라고 하면 들어가짐. 위와 다른점은

들어간 후 exit 하면? 컨테이너는 살아있다. 이유는? exec로 실행한 /bin/bash 만 종료했기 때문.  그냥 -d로 한 것과 동일하다.
docker attach 컨테이너명 으로 들어간 후 exit 쳐서 나가면, 컨테이너는 종료된다. attach는 단순히 컨테이너에 붙은거고, 현재 컨테이너상태에 대하여 exit를 했기 때문.

 


결론
- 도커 컨테이너 실행시 어떤 명령어로, 어떤 옵션으로  실행시켰느냐에 따라 도커 생성의 정체성이 달라지므로, 그 정체성에 따라 exit를 쳤을때 컨테이너가 종료될수도, 종료되지 않을수도 있음.
- 도커 컨테이너가 종료되지 않을려면, 도커 컨테이너 실행시 시작한 프로그램을 종료하지 않도록 해야 한다.
- attach 명령어는 stdout, stderr을 가져오는 것이다. ssh처럼 연결되는 것이 아니다. 
-  모르면 exit로 나가지 말고, ctrl+p+q 하는게 가장 좋다.

< 도커 기본 명령어 차례 >

● 시스템 명령

docker version

docker system info

docker system df

docker system prune

docker login

locker logout

 

● 이미지 관리 명령

docker pull

docker image ls

docker images

docker image inspect

docker image tag

docker push

docker search

docker image rm

docker image prune

docker container commit

 

● 컨테이너 실행 및 조작 관련 명령

docker container create

docker container run

docker container attach

docker container exec

 

● 컨테이너 정보 확인 명령

docker container ps

docker container stats

docker container inspect

docker container top

docker container port

docker container diff

docker container logs

docker container ls

 

● 컨테이너 관리 명령

docker container stop

docker container start

docker container kill

docker container restart

docker container prune

docker container pause

docker container unpause

docker container rename

docker container cp

 

● 컨테이너/이미지 백업 명령

docker container export

docker container import

docker image save

docker image load

 

● 네트워크 명령

docker network ls

docker network create

docker network connect

docker network disconnect

docker networkinspect

docker network rm

brctl show

 

● 볼륨 명령
docker volume create
docker volume ls
docker volume rm
docker volume prune
docker volume inspect


docker network ls

설명
- 도커의 네트워크 목록 표시

옵션
-f, --filter=[] : 출력을 필터링한다.
        driver : 드라이버 지정
        id : 네트워크 아이디
        label : 네트워크에 설정된 라벨 (label= 또는 label==로 지정한다
        name : 네트워크명
        scope : 네트워크의 스코프 (swarm, global, local)
        type : 네트워크의 타입 (사용자 정의 네트워크 custom/정의완료 네트워크 builtin)
--no-trunc : 상세 정보를 출력한다
--quiet, -q : 네트워크 id만 표시

예시

- 아래 내용은 다른 아무 네트워크도 생성하지 않은 기본 도커 설치 후의 내용이다.

9e2939a3e54e : bridge : docker0 가상 브릿지에 연결할 때 사용한다. (가상 브릿지를 추가하면 이러한 bridge Driver로 생성된다.

cb84e2a80ad9 : host - 호스트OS의 IP 대역과 동일하게 할 때 사용한다.

ebc9705adcd6 : none - 사용하지 않음.

 

 


docker network create

설명
- docker netework create 옵션 이름
- 사용자 정의의 도커 네트워크를 생성한다.
- 네트워크 생성 시 도커 네트워크 driver 또는 외부 네트워크 driver 플러그인을 사용해야 한다.
- 이러한 생성된 네트워크에 여러 도커 컨테이너가 연결되어 통신을 하게 된다.
- 이러한 네트워크에 컨테이너가 연결되면, 컨테이너는 ip뿐만 아니라 컨테이너명 또는 컨테이너ID로도 통신(ping 등)이 가능하다.
- 생성된 네트워크는 컨테이너 생성시 --net 옵션으로 해당 네트워크를 컨테이너에 추가할 수 있다. (docker container run 부분에서 상세히 설명)
- driver 중에서, 오버레이 네트워크나 커스텀 플러그인을 사용하면, 멀티호스트에 대한 연결을 할 수 있다. (즉, 도커 서버가 여러대라는 의미)

- 컨테이너가 동일한 멀티호스트 네트워크에 연결되어 있으면 이 네트워크를 통해서 서로 통신이 가능하다.

옵션
--driver, -d : 네트워크 브리지 또는 오버레이(기본값은 bridge)     - overlay, bridge 두가지임. 또한 커스텀 네트워크 드라이버도 사용 가능.
--ip-range : 컨테이너에 할당하는 ip 주소의 범위를 지정
--subnet : 서브넷을 CIDR형식으로 지정
--ipv6 ipv6 : 네트워크를 유효화할지 말지(true/false)
-label : 네트워크에 설정하는 라벨.

예시

- 브릿지 네트워크를 새로 생성하기

 

docker network connect

설명
- 도커 컨테이너를 도커 네트워크에 연결할 때 사용
- docker network connect 옵션 네트워크 컨테이너
- 생성할 때가 아닌, 이미 생성된 컨테이너에 특정 네트워크를 추가하는 것
- 연결 후에는 해당 컨테이너 내부에 새로운 네트워크 장치가 생기며, 동일한 네트워크상에 있는 다른 컨테이너와 통신이 가능해진다.
- docker container inspect 컨테이너명   에서 web-network 항목에서 정보 확인 가능.

옵션
--ip : ipv4주소
--ip6 : ipv6주소
--alias : 알리아스명
--link : 다른 컨테이너에 대한 링크

예시

docker network connect web-network webfront (webfront라는 컨테이너를 web-network라는 네트워크에 연결)

 

docker network disconnect

설명
- 도커 컨테이너안에 연결된 특정 네트워크를 해제한다.
- docker network disconnect 옵션 네트워크 컨테이너

옵션
- 미확인


예시
- 없음

docker network inspect

설명
- 네트워크의 상세정보 보기
- docker network inspect 옵션 네트워크명
- 네트워크 드라이버, 서브넷, 게이트웨이 등등의 정보가 나오며, Container 부분 아래에는 해당 네트워크에 연결된 컨테이너들의 정보가 나온다.

옵션
- 미확인


예시


docker network rm

설명
- 생성한 도커 네트워크를 삭제한다.
- docker network rm 옵션 네트워크명
- 네트워크를 삭제하려면, 이 네트워크에 연결된 모든 컨테이너와의 연결을 해제해야 한다. (disconnect 명령 사용)

옵션
- 미확인


예시
- 없음

 

brctl show

설명
- 브릿지 확인하는 명령어. 따로 설치해야 한다.
- 설치 : 우분투 apt-get -y install bridge-utils
         레드햇 yum install bridge-utils

 

옵션
- 미확인


예시

 


도커 네트워크 연결 예제

 

* 새로운 브릿지 네트워크를 생성하고 생성한 네트워크를 사용하여 컨테이너 생성

1. 브릿지 네트워크 새로 생성

# 설정없이 기본값으로 만들기
docker network create -d bridge noset-network

# 상세 설정하여 만들기
docker network create --driver bridge --subnet 172.100.1.0/24 --ip-range 172.100.1.0/24 --gateway=172.100.1.1 set-network

 

2. 생성 후 NETWORK ID를 잘 확인하자.

3. ip a 명령으로 생성된 정보를 확인할 때 위의 NETWORK ID로 해당 도커 네트워크 장치를 확인할 수 있다.

4. 설정된 상세 정보를 확인한다.

5. 컨테이너 생성

docker container run --net=set-network -it centos

생성된 컨테이너에서 네트워크 정보를 확인해보면, 해당 네트워크 대역으로 생성된 것을 확인할 수 있다.

 

* 컨테이너에 네트워크 장치 추가하기

컨테이너를 생성하면 네트워크가 eth0 하나가 추가되는데, 거기에 더 추가할 수 있다. connect 명령을 사용한다. 

 

1. 컨테이너 생성 및 네트워크 확인

docker run -it --name=add_network centos bash

- eth0/if148 한개가 있는 것을 확인할 수 있다.

 

2. 새로운 도커 브릿지 네트워크 생성

docker network create --driver=bridge second-network

호스트에서 docker network ls 명령으로 NETWORK ID를 확인하고, ip a 명령으로 해당 네트워크의 ip 대역대를 확인할 수 있다.

3. connect 명령으로 새로 만든 브릿지 네트워크를 추가한다.

docker network connect second-network add_network

4. attach로 들어간 후 확인해본다.

docker attach add_network

- 새로운 네트워크인 eth1@if153이 추가된 것을 확인할 수 있다.

 

5. 추가했으면 삭제도 해 보자.

- 컨테이너에 특정 네트워크가 추가된 상태에서, 해당 네트워크를 삭제하려고 하면 에러가 발생한다.

- 따라서 컨테이너를 중지하던지 연결을 해제해 주어야 한다.

- 이 작업은 컨테이너 온라인 중 가능하다. 명령을 치면 바로 작동된다.

docker network disconnect second-network add_network

- 작업 후 컨테이너로 들어가서 다시 확인해보면 해당 네트워크 장치가 사라진 것을 확인할 수 있다.

 

 

 

 

 

+ Recent posts