본문 바로가기
컴퓨터/시작하세요-도커-쿠버네티스

01-도커01

by book_lover 2024. 12. 23.

도커

https://blog.naver.com/alice_k106/221738032450

 

[책 출판] 시작하세요! 도커/쿠버네티스 - 친절한 설명으로 쉽게 이해하는 컨테이너 관리

안녕하세요. alice_k106입니다. "시작하세요! 도커" 책을 출판한 지 벌써 3년이 되었습니다. 클...

blog.naver.com

https://gayuna.github.io/docker/docker

리눅스 컨테이너에 여러 기능을 추가함으로써 애플리케이션을 컨테이너로서 좀 더 쉽게 사용할 수 있게 만들어진 오픈소스 프로젝트. GO언어로 작성됨.
가상 머신과는 달리 도커 컨테이너는 성능의 손실이 거의 없음. 라우드 인프라 솔루션

 

도커 관련 프로젝트는 도커 엔진을 좀 더 효율적으로 사용하기 위한 것, 핵심은 도커 엔진

도커 관련 프로젝트

  • 도커 컴포즈
  • 레지스트리(Private Registry)
  • 도커 허브
  • Docker for Desktop

가상 머신과 도커 컨테이너

https://www.backblaze.com/blog/vm-vs-containers/

하이퍼바이저를 이용해 하나의 호스트에 여러 개의 운영체제를 생성하여 운용하고, 이렇게 생성된 운영체제는 게스트 운영체제라 한다. 각 게스트 운영체제는 다른 게스트 운영체제와는 완전히 독립된 공간과 시스템 자원을 할당받아 사용한다. 

가상머신

- 라이브러리, 커널, 운영체제 등 전품 가상화 하여 사용

- 성능 손실 존재

- 수 기가바이트에 달하는 가상 머신 이미지를 애플리케이션으로 배포하기는 부담 존재

도커

- 가상화 공간 생성을 위해 chroot, 네임스페이스, cgroup을 사용

- 프로세스 단위의 격리 환경으로 손실이 거의 없음

- 컨테이너에 필요한 커널은 호스트의 커널을 공유하여 사용

- 컨테이너 안에는 애플리케이션 구동에 필요한 라이브러리 및 실행 파일 존재

- 가상 머신에 비해 이미지의 용량 적음


도커 이미지와 컨테이너

● 도커 이미지

이미지는 컨테이너를 생성할 때 필요한 요소, 이미지는 여러 개의 계층으로 된 바이너리 파일로 존재

컨테이너를 생성하고 실행할 때 "읽기 전용"으로 사용

이미지는 도커 명령어로 내려 받음

도커 이미지의 이름은 기본적으로 [저장소 이름]/[이미지 이름]:[태그]의 형태로 구성

  • 저장소 : 이름은 이미지가 저장된 장소를 의미, 저장소 이름이 명시되지 않은 이미지는 도커에서 기본적으로 제공하는 이미지 저장소인 도커 허브의 공식 이미지를 뜻
  • 이미지 이름 : 해당 이미지가 어떤 역할을 하는지 나타낸다. 
  • 태그 : 이미지의 버전 관리, 혹은 리비전 관리에 사용, 태그 생략은 이미지의 태그를 latest로 인식

 도커 컨테이너

  • 하나의 이미지로 여러개의 컨테이너 생성 가능
  • 파일시스템, 격리괸 시스템 자원 및 네트워크를 사용할 수 있는 독립된 공간이 생성
  • 이미지 변경, 컨테이너 안의 변경은 다른 컨테이너 호스트 PC에 영향을 주지 않음

출처 : 도커와-컨테이너의-이해-1-3-컨테이너-사용법

 

도커와 컨테이너의 이해 (1/3) - 컨테이너 사용법

목차 1. 도커 이미지? 도커 컨테이너? a. 도커 이미지 b. 도커 컨테이너 2. 기본적인 도커 명령어 a. 도커 컨테이너 안녕하세요. 첫 번째 글을 작성하게 된 클라우드메이트 T

tech.cloudmt.co.kr

https://medium.com/@saschagrunert/demystifying-containers-part-i-kernel-space-2c53d6979504

 

Demystifying Containers - Part I: Kernel Space

This series of blog posts and corresponding talks aims to provide you with a pragmatic view on containers from a historic perspective…

medium.com

https://cppis.github.io/container%20common/containerization.part3/

 

Containerization Part.3 - 컨테이너 이해하기 - 1부: 커널 공간

Demystifying Containers - Part I: Kernel Space를 정리한 글입니다.

cppis.github.io

https://tech.kakaoenterprise.com/154

 

[컨테이너 인터널 #1] 컨테이너 톺아보기

시작하며 안녕하세요. 카카오엔터프라이즈에서 검색 서비스를 개발하고 있는 검색클라우드기술파트의 Sam(김삼영)입니다. 지난 글 서비스 개발자를 위한 컨테이너 뽀개기 (a.k.a 컨테이너 인터널

tech.kakaoenterprise.com

 


도커 컨테이너 다루기

- 컨테이너 생성

  • 도커 사용 전 도커 엔진 버전 확인
docker -v 
Docker version xx.xx.x build xxxxxxx

  • 첫 번째 컨테이너 생성
  • docker run 명령어는 컨테이너를 생성하고 실행하는 역할
  • ubunut:22.04는 컨테이너를 생성하기 위한 이미지의 이름
  • -i, -t 옵션 : 컨테이너와 상호 입출력을 가능하게 해줌
docker run -it ubuntu:22.04

 

우분투 이미지가 로컬 도커 엔진에 존재하지 않으므로 도커 중앙 이미지 저장소인 "도커 허브"에서 자동으로 이미지 다운로드 함.

네트워크 환경에 따라 시간이 약간 소요 가능성 존재.

 

위에 명령어로 생성, 실행 후 컨테이너 내부로 들어간 상태, 사용자와 호스트 이름이 변경된 것이 컨테이너 내부에 들어와 있다는 것을 알 수 있음.  컨테이너 기본 사용자는 "root"이고 호스트 이름은 무작위 16진수 "해쉬값" 사용한다. 무작위의 해시 값은 컨테이너의 고유한 ID의 앞 일부분이다. 

 

컨테이너와 호스트의 파일시스템은 서로 독립적이며, 'ls' 명령어로 파일시스템을 확인해보면 아무것도 설치되지 않은 상태임을 알 수 있다. 컨테이너에서 호스트의 도커 환경으로 돌아가기 위해서는 컨테이너 셸에 'exit'를 입력하거나 'Ctrl+D'를 동시에 입력하는 방법이 있다. 그러나 이 방법은 컨테이너 내부에서 빠져나오면서 동시에 컨테이너를 정지시킨다. 

 

컨테이너를 정지시키지 않고 빠져나오는 방법은 'Ctrl+P, Q'를 입력하는 것이다. 이 방법은 단순히 컨테이너의 셸에서만 빠져나오고 컨테이너는 작동되고 있는다. 

  • docker pull -  도커 허브에서 이미지를 내려받을 때 사용
  • docker images or docker image ls - 도커 엔진에 존재하는 이미지의 목록을 출력
docker push centos:7
7: Pulling from library/centos
2d473b07cdd5: Pull complete
Digest: sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4
Status: Downloaded newer image for centos:7
docker.io/library/centos:7

docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
ubuntu        22.04     97271d29cb79   3 months ago    77.9MB
hello-world   latest    d2c94e258dcb   19 months ago   13.3kB
centos        7         eeb6ee3f44bd   3 years ago     204MB

  • docker create : 컨테이너 생성 시 사용, 컨테이너만 생성할 뿐  실행은 시키지 않음.
  • --name : 컨테이너 이름을 설정
  • docker start mycentos : 컨테이너 실행
  • docker attach mycentos : 컨테이너 진입
docker create -it --name mycentos centos:7
8671fcd634a1964f95003326eb7e57fddcdb50866863c0f0ce175095da38a179

docker start mycentos
mycentos

docker attach mycentos
[root@8671fcd634a1 /]#

  • Ctrl + P, Q 입력하면 컨테이너 작동한채 빠져나오고 아래의 이미지처럼 문구 뜸.

컨테이너를 대상으로 하는 모든 명령어는 컨테이너의 이름 대신 ID(무작위 16진수 값)을 사용할 수 있다. 그러나 ID의 이름이 너무 길 때는 앞의 2~3자만 입력해도 된다.
# docker start 8671fcd
또는
# docker start 867
그러나 ID의 앞자리가 867인 다른 컨테이너가 이미 존재한다면 어느 컨테이너를 가리키는지 알 수 없으므로 에러가 발생한다. ID의 앞자리를 사용해 컨테이너를 제어할 때는 적절히 3~4자를 입력하거나 좀 더 길게 사용하면 좋다.

run과 create차이

https://www.lainyzine.com/ko/article/difference-between-docker-run-and-docker-create/

 

docker run과 docker create의 차이점

docker run 도커 컨테이너를 생성 및 실행하고, docker create는 도커 컨테이너를 생성만 하는 명령어입니다. 이 글에서는 도커 컨테이너의 생애주기와 두 명령어의 차이점에 대해서 알아봅니다.

www.lainyzine.com


컨테이너 목록 확인

docker ps : 정지되지 않은 컨테이너 출력

docker ps -a : 정지된 컨테이너까지 출력

 

Status 항목을 보면 정지된 상태는 Exited로, 정지되지 않은 상태는 Up 9 minutes로 확인 되고 있다.

docker ps 명령어의 출력 의미

  • CONTAINER ID : 컨테이너에게 자동으로 할당되는 고유한 ID, docker inspect [ID 혹은 컨테이너 이름] 입력하면 자세히 볼 수 있다. 
  • IMAGE : 컨테이너를 생성할 때 사용된 이미지 이름. 
  • COMMAND : 커맨드는 컨테이너가 시작될 때 실행될 명령어. 
docker run -it ubuntu:22.04 echo hello world!
컨테이너 실행 시마다 "echo hellow world!"가 실행된다.

  • CREATED : 컨테이너 생서되고 난 뒤 흐른 시간
  • STATUS : 컨테이너 상태 표현, 실행 중일 때 UP, 종료된 상태 "Exited, 일시 중지된 상태 'Pause' 등 
  • PORTS :  컨테이너가 개방한 포트와 호스트에 연결한 포트를 나열
  • NAMES : 컨테이너의 고유한 이름. 컨태이너 생성 시 "--name" 옵션으로 이름을 설정하지 않으면 임의로 형용사와 명사를 무작위로 조합해 이름이 설정 됨. docker rename 명령어를 사용하면 컨테이너의 이름을 변경할 수 있음. 

셸의 화면이 작아서 PS 명령어를 출력 결과를 보기 힘들 면 --format 옵션에 Go 템플릿을 입력해서 원하는 정보만 출력 가능하다. 

https://www.educba.com/docker-format/

 

Docker format

Guide to Docker format. Here we discuss all basic functions and Examples along with the Rules and regulations for using a format.

www.educba.com

https://docs.docker.com/engine/cli/formatting/

 

Format command and log output

CLI and log output formatting reference

docs.docker.com


컨테이너 삭제

  • docker rm [컨테이너 이름 또는 컨테이너 ID]
  • 실행 중인 컨테이너는 삭제할 수 없음.
  • docker stop [컨테이너 이름 or ID]로 멈춘 후 삭제 진행

  • 한 번에 모든 컨테이너 삭제 시 : prune 명령어 사용 
  • docker ps -a -q 사용 : -a는 모든 컨테이너 출력, -q는 컨테이너의 ID만 출력하는 역할
docker container prune
docker stop $(docekr ps -a -q)
docker rm $(docekr ps -a -q)

컨테이너를 외부에 노출

컨테이너는 가상 IP 주소를 할당받는다. 기본적으로 도커는 컨테이너에 172.17.0.x의 IP를 순차적으로 할당한다. 컨테이너를 새롭게 생성한 후 ifconfig 명령어로 컨테이너의 네트워크 인터페이스를 확인할 수 있다.

ifconfig가 안될 시
apt-get update
apt-get install net-tools 
설치하여 사용

 

eth0 인터페이스와 로컬 호스트인 lo 인터페이스가 있다. 이 컨테이너는 외부에서 접근할 수 없다. 도커가 설치된 호스트에서만 접근 가능하다. 외부에 컨테이너의 애플리케이션을 노출하기 위해서는 eth0의 ip와 포트를 호스트의 ip와 포트에 바인딩해야 한다. 

docker run -it --name mywebserver -p 80:80 ubuntu:22.04
  • 여러 포트를 연결하면 여러번 -p 옵션을 사용하여 바인딩 해주면 된다.
  • 특정 IP를 사용하려면, docker run -it -p 192.168.100.100:7000:80 ubuntu:latest 식으로 사용하면 됨

컨테이너에 아파치 서버 설치하여 연결 테스트 진행

apt-get update
apt-get -y install apach2
service apache2 start
curl http://localhost > index.html
ls
vi index.html

 

  • index.html 내용 웹브라우저 뛰어보기

컨테이너 애플리케이션 구축

- 데이터베이스 + 워드프레스 웹 서버 컨테이너 연동 테스트

docker run -d --name wordpressdb \
-e MYSQL_ROOT_PASSWORD=password \
-e MYSQL_DATABASE=wordpress \
mysql:5.7

docker run -d --name wordpress \
-e WORDPRESS_DB_HOST=mysql \
-e WORDPRESS_DB_USER=root \
-e WORDPRESS_DB_PASSWORD=password \
--link wordpressdb:mysql \
-p 80 wordpress
  • 첫 번째 명령어는 mysql 이미지를 사용해 데이터베이스 컨테이너를 생성
  • 두 번째 명령어는 워드프레스 이미지를 이용해 워드프레스 웹 서버 컨테이너를 생성
  • -p 80을 입력했으므로 호스트의 포트 중 하나와 컨테이너의 80번 포트가 연결된다.
  • 호스트와 바인딩된 포트만 확인하려면 docker port 명령어 사용 
    • docker port wordpress

  • localhost:32768 접속

  • -d : Detached 모드 의미, 컨테이너를 백그라운드에서 동작시킴
    • 백그라운드 컨테이너는 'exec' 명령어로 들어가거나 명령어 실행 가능
    • docker exec -it [컨테이너이름] /bin/bash or docker exec [컨테이너이름] ls

  • -e : 이 옵션은 컨테이너 내부의 환경변수를 설정
  • --link : 이 옵션은 A컨테이너에서 B 컨테이너로 접근하는 방법 중 가장 간단한 방법, 이 옵션은 내부 IP를 알 필요 없이 항상 컨테이너 별명으로 접근하도록 설정, 위에서는 워드프레스 웹 서버 컨테이너는 mysqldb:mysql에서 mysql 별명을 설정하여 mysql로 접근할 수 있게 됨
    • 확인을 위해 docker exec wordpress curl mysql:3306 --silent 실행

 

--link는 입력된 컨테이너가 실행 중이지 않거나 존재하지 않으면 link를 적용한 컨테이너 또한 실행할 수 없으며, 현재 deprecated 옵션이며 대신 도커 브리지(bridge) 네트워크를 사용하여 동일한 기능을 더욱 쉽게 사용할 수 있다.


도커 볼륨

도커 이미지로 컨테이너를 생성하면 "이미지는 읽기 전용"이 되며 컨테이너의 변경 사항만 별도로 저장해서 각 컨테이너의 정보를 보존. 위에 mysql 컨테이너는 mysql:5.7이라는 이미지로 생성됐지만 워드프레스 블로그를 위한 데이터베이스 등의 정보는 컨테이너가 갖고 있다.

\

이미 생성된 이미지는 변경되지 않으며, 컨테이너 계층에 원래 이미지에서 변경된 파일시스템 등을 저장한다. 이미지에는 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

docker run -d --name wordpress_hostvolume \
-e WORDPRESS_DB_PASSWORD=password \
--link wordpressdb_hostvolume:mysql \
-p 80 \
wordpress
  • -v 옵션을 사용해 [호스트 공유 디렉터리]:[컨테이너의 공유 디렉터리]형태로 볼륨 공유 설정
    • /var/lib/mysql 디렉터리는  mysql이 데이터베이스의 데이터를 저장하는 기본 디렉터리
    • /home/wordpress_db 디렉터리를 미리 생성하지 않았어도 도커는 자동으로 이를 생성

mysql 컨테이너를 삭제하여 데이터가 아직 존재하는지 확인 테스트 진행

컨테이너 디렉터리와 호스트 디렉터리 공유 그림

  • 동기화가 아니라 같은 디렉터리임
  • 파일 단위의 공유도 가능
  • -v 옵션 여러번 사용 가능 

볼륨 컨테이너

-v 옵션으로 볼륨을 사용하는 컨테이너를 다른 컨테이와 공유, 컨테이너를 생성할 때 --volumes-from 옵션을 설정하면 -v 또는 --volume 옵션을 적용한 컨테이너의 볼륨 디렉터리를 공유할 수 있다.

docker run -it --name volumes_from_container \
--volumes-from wordpressdb_hostvolume \
ubuntu:22.04

 

wordpressdb_hostvolume  컨테이너의 디렉터리는 호스트와 공유하고 있으며, volumes_from_container의 디렉터리는 wordpressdb_hostvolume 컨테이너로부터 공유받고 있다.

 

ls /var/lib/mysql/ 로 아래처럼 파일이 확인 됨.

 

ls /home/wordpress_db/ 위와 내용이 일치

 

여러 개의 컨테이너가 동일한 컨테이너에 --volumes-from 옵션을 사용함으로써 볼륨을 공유해 사용할 수도 있다. 이러한 구조를 활용하여 호스트에서 볼륨만 공유하고 별도의 역할을 하지않는 "볼륨 컨테이너"로서 활용하고, 다른 애플리케이션 컨테이너는 이 볼륨컨테이너와 디렉터리 공유함으로써 데이터를 지킬 수 있을 것이다. 

도커 볼륨

docekr volume create --name testvolume
docker volume ls

docker run -i -t --name testcont \
-v myvolume:/root/ \
ubuntu:22.04

[컨테이너안]: echo hello, volume! >> /root/volume

 

/root 디렉터리에 volume이라는 파일 생성, 다른 컨테이너도 testvolume 볼륨을 쓰면 볼륨을 활용한 디렉터리에 volume 파일이 존재할 것이다. 컨테이너에서 호스트로 빠져나온 뒤 컨테이를 생성해 확인

 

결과를 보면 hello, volume!을 확인할 수 있다. docker volume 명령어로 생성한 볼륨은 아래 그림과 같은 구조로 활용

 

볼륨은 디렉터리 하나에 상응하는 단위로서 도커 엔진에서 관리한다. 도커 볼륨도 호스트 볼륨 공유와 마찬가지로 호스트에 저장함으로써 데이터 보존하지만 파일이 실제로 어디에 저장되는지 사용자는 알 필요가 없다. 

 

docker inspect 명령어를 사용하면 testvolume 볼륨이 실제로 어디에 저장되는지 알 수 있다.

docker inspect --type volume testvolume

 

사용하지 않는 볼륨 삭제

docker volume prune

 

컨테이나거 아닌 외부에 데이터를 저장하고 컨테이너는 그 데ㅐ이터로 동작하도록 설계하는 것을 스테이트리스하다고 한다. 컨테이너 자체는 상태가 없고 상태를 결정하는 데이터는 외부로부터 제공받는다. 컨테이너가 삭제돼도 데이터는 보존되므로 스테이트리스한 컨테이너 설계는 도커를 사용할 때 매우 바람직한 설계이다. 

 

이와 반대로 컨텡너가 데이터를 저장하고 있는 상태를 스테이트풀하다고 한다.

docker run -it --name mount_option \
--mount type=volume, source=testvolume, target=/root \
ubuntu:22.04

 

호스트의 디렉터리를 컨테이너 내부에 마운트하는 경우에는 type을 bind로 지정, 이때 source의 값은 호스트의 디렉터리 경로를 지정

docker run -it --name mount_option2 \
--mount type=bind,source=/home/wordpress_db,target=/home/testdir \
ubuntu:22.04

도커 네트워크

도커는 컨테이너에 내부 IP를 순차적으로 할다하며 각 컨테이너에 외부와의 네트워크를 제공하기 위해 컨테이너마다 가상 네트워크 인터페이스를 호트트에 생성하며 이 ㅇ터페이스의 이름은 veth라한다. veth 인터페이스는 컨테이너 숫자만큼 자동 생성된다.

현재 실행 컨테이너가 3개이므로 3개의veth을 확인할 수 있다.

 

docker0 브리지라고 하며 각 veth 인터페이스와 바인딩돼 호스트의 인터페이스와 이어주는 역할을 한다. 즉 컨테이너와 호스트의 네트워크는 아래 그림과 같이 구성된다.

컨테이너의 eth0 인터페이스는 호스트의 veth 라는 인터페이스와 연결되고 veth 인터페이스는 docker 브리지와 바인딩돼 외부와 통신할 수 있다.

brctl show docker0

도커 네티워크 기능

컨테이너를 생성하면 기본적으로 docker0 브리지를 통해 외부와 통신할 수 있는 환경을 사용할 수 있지만 사용자의 선택에 따라 여러 네트워크 드랑버를 사용할 수 있다. 도커가 자체적으로 제공하는 대표적인 네트워크 드라이버로는 

  • 브리지
  • 호스트
  • 컨테이너
  • 오버레이

가 있다. 서드파티 플러그인 솔루션으로는 weave, flannel, openvswitch 등이 있으며 더 확장된 네트워크 구성을 위해 활용된다.

docker network ls

 

docker network inspect bridge

   {
        "Name": "bridge",
        "Id": "b4da55702010aff0bd2b6372ad8746bbac9555db970c801dadc3160249cb7232",
        "Created": "2024-12-23T16:10:17.082699133+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "76d1daa708b2362846c2627e16b527ac2c39ce85efbc76cd123866e3110983b5": {
                "Name": "wordpress_hostvolume",
                "EndpointID": "e584caaf198035137666ffc29c87efae6ceb273e59c396b447e9b2645e3aea6b",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "b8e2a9d53aaf4df29e69321a1f05f39c35744d6b495df8d8c491cd1d9fb226ac": {
                "Name": "volumes_from_container",
                "EndpointID": "7743baa76d52a58abb915456d6b6fd25e69534542bdbb12ffd063db5dca36723",
                "MacAddress": "02:42:ac:11:00:04",
                "IPv4Address": "172.17.0.4/16",
                "IPv6Address": ""
            },
            "ba5cbed5d35212ced24f93b81b3f4916d559de7c7d47cee653fdc897ffa07d10": {
                "Name": "wordpressdb_hostvolume",
                "EndpointID": "7e5a00f034f28a2766a8a46c35cd237b6f189ee0c90cfb041ed03802e370e0db",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

 

Config 항목의 서브넷과 게이트웨이를 확인할 수 있다.

 

Containers 항목에서는 네트워크를 사용 중인 컨테이너 목록을 확인할 수 있다.

브리지 네트워크

docker0을 사용하는 네트워크가 아닌 새로운 브리지 타입의 네트워크를 생성할 수 있다.

docker network create --driver bridge mybridge
docker run -it --name mynetwork_container \
--net mybridge \
ubuntu:22.04

 

172.18 대역의 새로운 네트워크를 확인, disconnect, connect를 통해 컨테이너에 유동적으로 붙이고 뗄 수 있다. '논 네트워크, 호스트 네트워크' 에서는 이 명령어를 사용할 수 없다.

docker network disconnect mybridge mynetwork_container
docker network connect mybridge mynetwork_container

 

네트워크에 서브넷, 게이트웨이, IP 할당 범위 등을 임의로 설정하려면 네트워크를 생성할 때 사용하면 된다.

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

호스트 네트워크

호스트의 네트워크 환경을 그대로 사용할 수 있다.

docker run -it --name network_host --net host ubuntu:14.04

 

컨테이너의 내부에서 네트워크 환경을 확인하면 호스트와 같은 것을 알 수 있고, 호스트 머신에서 설정한 호스트 이름도 컨테이너가 물려받기 때문에 호스트 이름도 무작위 16진수가 아닌 도커 엔진이 설치된 호스트 머신의 호스트 이름으로 설정된다.  컨테이너의 네트워크를 호스트 모드로 설정하면 컨테이너 내부의 애플리케이션을 별도의 포트 포워딩 없이 바로 서비스할 수 있다. 실제 호스트에서 애플리케이션을 외부에 노출하는 것과 같이 80번에 아파치 서버가 컨테이너 구동 중이면 바로 접근 가능하다. 

논 네트워크

none은 말 그대로 아무런 네트워크를 쓰지 않는 것을 뜻한다. 외부와 연결이 단절된다.

docker run -it --name none_network --net none ubuntu:14.04

 

lo외에는 존재하지 않는ㄷ. 

컨테이너 네트워크

--net 옵션으로 container를 입력하면 다른 컨테이의 네트워크 네임스페이스 환경을 공유할 수 있다. 공유되는 속성은 내부 ip, 네트워크 인터페이스의 맥 주소 등이다.

docker run -it -d --name network_container_1 ubuntu:14.04

docker run -it -d --name network_container_2 --net container:network_container_1 ubuntu:14.04

 

docker exec 699나 docker exec 2b로 들어가도 다 699  컨테이너의 정보만 확인 된다.

 

이처럼 네트워크 환경을 공유하며 호스트에 veth로 시작하는 가상 네트워크 인터페이스도 1나만 확인 된다.

브리지 네트워크와 --net-alias

브리지 타입의 네트워크와 run 명령어의 --net-alias 옵션을 함께 사용하면 특정 호스트 이름으로 컨테이너 여러 개에 접근할 수 있다. 처음 만든 mybridge 네트워크를 사용하여 컨테이너 3개를 생성해 보자.

docker run -it -d --name network_alias_container1 \
--net mybridge \
--net-alias alicek106 \
ubuntu:14.04

docker run -it -d --name network_alias_container2 \
--net mybridge \
--net-alias alicek106 \
ubuntu:14.04

docker run -it -d --name network_alias_container3 \
--net mybridge \
--net-alias alicek106 \
ubuntu:14.04

docker run -it --name network_alias_ping \
--net mybridge \
ubuntu:14.04

컨테이너 3개의 IP롤 각각 ping이 전송되며, 별도의 알고리즘이 아닌 라운드 로빈 방식이다. 도커 엔진에 내장된 DNS가 alicek106이라는 호스트 이름을 --net-alias 옵션으로 alicek106을 설정한 컨테이너로변환(resolve)해준다. 

브리지 네트워크의 --net -alias와 도커 DNS의 작동 구조

dig를 통해 확인

MacVLAN 네트워크

호스트의 네트워크 인터페이스 카드를 가상화해 물리 네트워크 환경을 컨테이너에게 동일하게 제공한다. MacVLAN을 사용하면 컨테이너는 물리 네트워크상에서 가상의 맥 주소를 가지며, 해당 네트워크에 연결된 다른 장치와의 통신이 가능해진다. MacVLAN에 연결된 컨테이너는 기본적으로 할당되는 IP 대역인 172.17.x.x 대신 네트워크 장비의 IP를 할당받기 때문이다. 

위 그림은 두개의 서버가 라우터 또는 스위치에 연결되어 있고 192.168.0.0/24 대역에서 ip를 동적으로 할당받는다. MacVLAN을 사용하면 각 컨테이너에 92.168.0.0/24 대역의 ip를 할당할 수 있다. 따라서 MacVLAN을 사용하면 컨테이너와 서버는 같은 대역을 사용하여 통신이 가능하다. 

 

단 MacVLAN 네트워크를 사용하는 컨테이너는 기본적으로 호스트와 통신이 불가능하다. 대신 컨테이너 A는 서버 2와 통신가능하고 서버 1과는 통신이 안 된다. 

 

MacVLAN을 사용하려면 1개의 네트워크 장비와 서버가 필요하다. 고가의 스위치와서버 대신 공유기와 라즈베리 파이를 사용할 수 도 있다. 상황이 여의치 않다면 버추얼박스 가상 머신과 스트 전용 어댑터로테스트할 수도 있다.

 

Macvlan 구성Permalink

  • 네트워크 성능 향상: 호스트의 NAT를 거치지 않아 성능이 향상
  • 네트워크 격리: 각 컨테이너가 고유한 MAC 주소를 가져 네트워크 레벨에서 완전히 격리
  • 기존 네트워크와의 통합: 기존 물리적 네트워크 인프라와 쉽게 통합
공유기의 네트워크 정보 : 192.168.0.0/24
서버 1 : 192.168.0.50
서버 2 : 192.168.0.51

 서버1
 docker network create -d macvlan --subnet=192.168.111.0/24 \
 --ip-range=192.168.111.64/28 --gateway=192.168.111.2 \
 -o macvlan_mode=bridge -o parent=ens160 my_macvlan
 
 서버2
 docker network create -d macvlan --subnet=192.168.111.0/24 \
 --ip-range=192.168.111.128/28 --gateway=192.168.111.2 \
 -o macvlan_mode=bridge -o parent=ens160 my_macvlan
 
 
 docker run -it --name c1 --hostname c1 --network my_macvlan ubuntu:14.04
root@c1:/# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:c0:a8:6f:40
          inet addr:192.168.111.64  Bcast:192.168.111.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  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:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          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:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

 

테스트 결과 호스트 pc의 네트워크 인터페이스 주소인 1번까지 핑이가고 

구글로도 핑이 잘 나간다.

https://blog.naver.com/alice_k106/221093585471

 

108. [Docker + Network] Docker 컨테이너의 Macvlan 사용해보기 - 2편

이전 포스트에서 Macvlan에 대해서 알아본 적이 있었다.  http://blog.naver.com/alice_k106/22...

blog.naver.com

https://cdecl.github.io/devops/docker-macvlan/

 

Docker 네트워크 - Macvlan

Docker Macvlan 네트워크 소개, 활용 및 이슈

cdecl.github.io

https://blog.naver.com/alice_k106/220984112963

 

97. [Docker + Network] Docker 컨테이너의 Macvlan 사용해보기

이번 포스트에서는 macvlan의 개념과 도커에서 사용할 수 있는 방법을 알아본다.' 도커 엔진 1.12 이상 버...

blog.naver.com

https://docs.docker.com/engine/network/drivers/macvlan/

 

Macvlan network driver

All about using Macvlan to make your containers appear like physical machines on the network

docs.docker.com

https://www.youtube.com/watch?v=AH2eSNCB-tc&t=45s