-
DockerSTUDY/Docker 2022. 11. 21. 00:41
1. 컨테이너
- 컨테이너는 어플리케이션의 런타임 인스턴스이다.
- 컨테이너 단위로 OD, 라이브러리, 어플리케이션을 패키징 할 수 있다.
- 컨테이너는 OS에 여러 어플리케이션을 독립적으로 실행할 수 있도록 해준다.
- 즉, 컨테이너는 여러 어플리케이션의 격리된 환경을 지원하는 가상화 기술로 볼 수 있다.
- 컨테이너는 하나의 OS 위에서 여러개가 실행된다.
- 각각의 컨테이너는 사용자 영역에서 격리된다.
- 컨테이너는 VM보다 가볍고 빠르다.
컨테이너를 도입하면서 기대할 수 있는 점
- 서비스에 필요한 OS, 라이브러리, 어플리케이션을 컨테이너로 묶을 수 있어서 업데이트나 롤백 시 안정적이다.
- 컨테이너는 가볍고 빠르기 때문에 서비스 배포 시 빠르게 반영할 수 있다.
- 컨테이너 실행 환경만 갖춰져 있으면 어디서나 실행되기 때문에 신속한 서비스 스케일링(확장/축소)이 가능하다.
- 단일 호스트의 장애를 컨테이너의 이동(다른 호스트로)으로 대응하여 보다 빠르게 복구할 수 있다.
- 서비스와 운영을 분리할 수 있어서 컨테이너 실행 환경을 더이상 신경쓰지 않아도 된다.
2. Docker
- 도커는 컨테이너를 이미지 파일로 빌드하고 배포하여 어디서나 실행할 수 있도록 해주는 오픈소스이다.
- 컨테이너를 git에 저장된 소스처럼 build/push/pull 할 수 있는 방법을 먼저 제공하면서 주목 받았다.
- 도커는 클라이언트(docker)와 서버(dockerd)로 구성되어 있다.
- 모든 명령은 클라이언트에서 REST로 서버에 요청되어 서버에서 수행한다.
- 도커 이미지를 빌드하기 위해 Dockerfile 을 작성한다.
- Dockerfile 과 함께 도커 빌드 요청을 보낸다.
- 도커 서버에서는 도커 이미지를 빌드하여 로컬 저장소에 저장한다.
- 도커 push 명령을 받으면 도커 서버는 로컬의 도커 이미지를 도커 레지스트리에 올린다.
- 도커 run 명령을 배포할 도커 서버에 전송한다.
- 도커 run 명령을 받은 도커 서버는 도커 레지스트리에 이미지를 로컬 저장소로 다운 받는다.
- 도커 이미지를 이용하여 컨테이너를 시작한다.
# 빌드 옵션 docker build [OPTIONS] PATH | URL | - -f, --file 빌드할 Dockerfile을 지정한다. 기본값은 Dockerfile이다. -t, --tag 빌드한 이미지의 이름(name:tag)을 지정한다. 미지정시 <none>으로 설정된다. # Dockerfile 빌드(도커 이미지 생성) $ docker build -f Dockerfile -t demo:$USER . # Image 확인 $ docker image ls
# docker run 주요 옵션 $ docker run --help Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] Options: -d, --detach 컨테이너를 background로 실행한다. --name string 컨테이너의 이름을 지정한다. -p, --publish 외부:내부 컨테이너의 포트를 host의 포트와 연결한다.(NAT) # 컨테이너 실행 docker run $ docker run -d --name $USER -p 80 demo:$USER # 실행 컨테이너 확인 docker ps $docker ps $USER # 컨테이너 상세 정보 확인 docker inspect $ docker inspect $USER --format '{{.NetworkSettings.Ports}}' # docker exec 주요 옵션 $ docker exec --help Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...] Run a command in a running container Options: -d, --detach 새로운 터미널을 할당한다. -i, --interactive STDIN을 유지한다. # 컨테이너 내부에서 추가 명령 실행 docker exec $ docker exec -it $USER bash # docker rm 주요 옵션 $ docker rm --help Usage: docker rm [OPTIONS] CONTAINER [CONTAINER...] Remove one or more containers Options: -f, --force 실행 중인 컨테이너를 강제로 삭제한다. # 컨테이너 삭제 docker rm $ docker rm -f $USER
# 기존 이미지를 참조하는 새 이미지 생성 docker tag $ docker tag --help Usage: docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG] $ docker tag demo:$USER registry.ddd.com/edu/demo:$USER # 로컬의 이미지를 원격의 저장소로 올리기 docker push $ docker push registry.ddd.com/edu/demo:$USER # 원격의 이미지를 로컬의 저장소로 내려받기 docker pull
3. Namespaces
- Linux Namespaces는 프로세스에게 격리된 OS View를 제공하는 커널 기술이다.
- Linux Namespaces는 pid, net, ipc, mnt, uts, user 등의 6개 리소스에 대한 네임스페이스를 제공한다.
- 프로세스 생성 시점에 어떤 네임스페이스를 사용할지 선택할 수 있고 프로세스는 선택한 네임스페이스 별로 격리된다.
- Namespace 없이는 모든 프로세스가 동일한 Network Resources를 사용하게 된다.
- Namespace로 격리된 프로세스들은 같은 eth0이더라도 서로 다른 Network Resources를 사용하게 된다.
Namespace 종류
- MNT Namespace : 디바이스 마운트 상태
- UTS Namespace : 호스트이름
- PID Namespace : 프로세스 아이디
- IPC Namespace : Inter Process Communication
- NET Namespace : 네트워크 상태
- USER Namespace : 사용자 계정
4. Cgroup(Control Group)
- cgroups은 어플리케이션(프로세스)에게 하드웨어 리소스(ex. CPU, MEM, Disk, Network 등)를 그룹으로 묶어서 할당하는(제한할 수 있는) 기술이다.
- cgroup으로 묶인 프로세스들은 리소스 별로 정해진 양만 사용하게 설정할 수 있다.
- cgroup은 리소스 타입별로 독립적인 트리 구조를 가진다.
- cgroup 노드는 하위에 서브 노드를 가질 수 있으며 Leaf-Node는 프로세스가 된다.
Cgroup 리소스 할당
1. Share
- 어떤 cgroup 에게 리소스 사용의 우선순위(Priority)를 줄 수 있다.
2. Set(Pinned || Static Bind)
- 어떤 cgroup은 특정 리소스만 사용하도록 할 수 있다.(ex. binding cgroup0 to CPU0)
3. Quota
- 어떤 cgroup에게 시간당 정해진 리소스만 사용하도록 할 수 있다.(ex. limit CPU 100%)
5. Unionfs(Union Filesystem)
- 도커 컨테이너가 Namespace와 Cgroup에 의해 격리될 때 컨테이너가 사용할 파일 시스템도 격리되어야 한다.
- Union File System은 서로 다른 파일 시스템이나 디렉토리를 합쳐서 하나의 논리적인 파일 시스템으로 컨테이너에게 제공한다.
- UnionFS을 사용하면 여러 컨테이너가 하나의 이미지를 사용할 경우 각각의 컨테이너는 자신이 overwrite할 영역만 유지할 수 있다.
6. 도커 네트워크 모델
- Sandbox는 Container의 Network Stack을 의미한다.(ex. Interface, DNS, Routing Table 등)
- Endpoint는 Sandbox를 Network에 Join(Attach) 해주는 역할을 한다.
- Network은 Group of Endpoint로 한 Group의 Endpoint 간에는 서로 통신할 수 있다.
- 도커에서 네트워크를 생성한다.
- 생성한 (혹은 미리 생성되어 있는) 네트워크를 사용하는 도커 컨테이너를 실행한다.
- 같은 도커 네트워크를 사용하는 도커 컨테이너 간에는 통신이 가능하다.
- 도커 네트워크는 드라이버를 이용하여 생성하며 같은 드라이버로 여러개의 서로 다른 네트워크를 생성할 수 있다.
- 기본 제공되는 드라이버는 bridge, host이다. (none은 네트워크를 사용하지 않는 것이다.)
Bridge 네트워크
- 리눅스 커널의 소프트웨어 L2 스위칭 기술인 Linux Bridge 를 사용한다.
- 같은 Bridge 네트워크를 사용하는 컨테이너 간에는 통신이 가능하다.
- 호스트의 Inbound 트레픽은 NAT (iptables) 를 통해 노출한 Port 를 통해 수신한다.
Host 네트워크
- 호스트 네트워크를 사용하는 C1/C2 컨테이너는 호스트와 네트워크 스택을 공유한다.
- 컨테이너간, 컨테이너와 호스트간에 통신이 가능하다.
- 네트워크 스택을 공유하기 때문에 같은 포트를 오픈할 수 없다.
# 도커 네트워크를 생성하고 조회한다. docker network create docker network ls docker network inspect # 도커 네트워크를 사용하여 컨테이너를 생성한다. docker run --network # bridge 네트워크를 사용하는 $USER 컨테이너 생성 $ docker run -d --network bridge --name $USER # host 네트워크를 사용하는 $USER 컨테이너로 생성 $ docker run -d --network host --name $USER registry.ddd.com/dock/nginx:net-tools
7. 볼륨 마운트
도커에서 제공하는 데이터의 영속성을 보장하기 위한 방법으로, 파일 시스템과 컨테이너를 분리하여 관리한다. 즉, 컨테이너를 지웠다가 다시 실행해도 도커 볼륨과 연결한다면 데이터는 그대로 유지된 상태로 존재한다.
- 도커 컨테이너를 시작할 때 도커 볼륨, 로컬 호스트의 디렉토리/파일, 메모리를 마운트 할 수 있다.
- 도커 볼륨(로컬 볼륨)을 마운트 하는 것을 volume 마운트라고 한다.
- 로컬 호스트의 디렉토리/파일을 마운트 하는 것을 bind 마운트라고 한다.
Docker volume
도커 doc에서 가장 권장하는 방법으로 `docker volume create` 명령어를 통해 도커 엔진이 관리하는 볼륨을 생성할 수 있다. 생성된 볼륨은 호스트 디렉터리의 '/var/lib/docker/volumes/' 루트에 저장된다. 도커 볼륨은 컨테이너의 특정 디렉터리를 도커 볼륨과 마운트한다. bind 마운트 방식과 비슷하지만 도커 볼륨은 도커에 의해 관리되며 해당 볼륨을 어떤 컨테이너가 사용하는지, 어떻게 마운트 되는지 관리하기 용이하다.
Host Bind
Bind 마운트 방식은 호스트 파일 시스템의 특정 디렉터리를 컨테이너 내부 볼륨의 디렉터리와 마운트한다. 이 방식의 가장 큰 단점은 도커의 관리 없이 Host Directory와 마운트를 하다 보니 컨테이너에서 호스트의 파일 시스템에 접근하여 컨테이너에 지정된 파일이 아닌 다른 파일을 삭제/추가/수정할 수 있다는 것이다. 도커 doc에서는 이 기능은 호스트 시스템의 비 Docker 프로세스에 영향을 주는 것을 포함하여 보안에 영향을 미칠 수 있는 강력한 기능이라고 경고하고 있고, 같은 기능을 제공하는 Volume 방식을 사용하는 것을 권장한다.
# 도커 볼륨을 생성하고 조회한다. docker volume create docker volume ls docker volume inspect # 도커 볼륨을 사용하여 컨테이너를 생성한다. docker run -v docker run --mount # 로컬 볼륨 생성 $ docker volume create -d local $USER $ docker volume ls -f name=$USER $ docker volume inspect $USER # 로컬 볼륨을 volume 마운트하는 컨테이너를 생성하고 파일 터치 $ docker run -d --name $USER -v $USER:/share registry.navercorp.com/edu/demo:$USER $ docker exec $USER touch /share/volume-mount-test $ docker exec $USER ls -alt /share/volume-mount-test # 로컬 볼륨을 사용하는 컨테이너 생성(/home1/irteam/share 경로 미리 생성) $ docker run -d --name $USER -p 80 -v /home1/irteam/share:/share registry.ddd.com/edu/demo:$USER
'STUDY > Docker' 카테고리의 다른 글
Dockerfile (0) 2023.02.22 도커와 도커 명령어 (0) 2023.02.21 컨테이너 (0) 2023.02.20 도커와 쿠버네티스 (0) 2022.10.25 마이크로서비스 아키텍처 (0) 2022.10.18