DevOps/따라 배우는 도커

Docker

:)jun 2023. 4. 16. 18:42

3회차 - 도커 컨테이너 살펴보기

핵심키워드

- 컨테이너, 컨테이너 이미지

- docker demon, docker hub

- 컨테이너 동작방식

 

VM vs Container

출처 : 레드햇 (https://www.redhat.com/ko/topics/containers/containers-vs-vms)

VM을 통해 서비스하는 것도 가능하다.

하지만 각각의 VM마다 GUEST OS를 설치해 사용해야 하기 때문에 무겁다.

서버를 유지하는 것 자체가 비용.

트래픽에 따라 필요한 서버를 빠르게 내리고 올려야하는데 VM은 무겁기 때문에 빠르게 적용시키기 어렵다.

 

컨테이너를 사용하게 되면 OS는 HOST OS를 공통으로 사용.

애플리케이션에 필수적인 정보들만 Base Image를 통해 제공받고 그 위에 앱을 구동시키기 때문에 가볍다.

 

하지만 공통의 HOST OS를 공통으로 사용하기 때문에 보안 문제가 있다.

 

컨테이너 동작방식

docker host에서 docker deamon을 통해 각각의 컨테이너를 관리한다.

 

4회차 - 도커 컨테이너 만들어보기

핵심키워드

- Dockerfile 문법

- 컨테이너 배포

 

Dockerfile 문법

https://docs.docker.com/engine/reference/builder/

 

Dockerfile reference

 

docs.docker.com

  • # : comment
  • FROM : 컨테이너의 BASE IMAGE(운영환경)
  • MAINTAINER : 이미지를 생성한 사람의 이름 및 정보
  • LABEL : 컨테이너 이미지에 컨테이너의 정보를 저장
  • RUN : 컨테이너 빌드를 위해 base image에서 실행할 commands
  • COPY : 컨테이너 빌드 시 호스트의 파일을 컨테이너로 복사
  • ADD : 컨테이너 빌드 시 호스트 파일(tar, url 포함)을 컨테이너로 복사
  • WORKDIR : 컨테이너 빌드 시 명령이 실행될 작업 디렉터리 설정
  • ENV : 환경변수 지정
  • USER : 명령 및 컨테이너 실행 시 적용할 유저 설정
  • VOLUME : 파일 또는 디렉토리를 컨테이너의 디렉토리로 마운트
  • EXPOSE : 컨테이너 동작 시 외부에서 사용할 포트 지정
  • CMD : 컨테이너 동작 시 자동으로 실행할 서비스나 스크립트 지정
  • ENTRYPOINT : CMD와 함께 사용하면서 command 지정 시 사용

COPY vs ADD

 COPY는 단순히 파일이나 디렉토리를 이미지에 복사하는 기능. 파일의 압축을 풀 수 없고, URL 사용불가.

복사 대상이 디렉토리일 경우, 해당 디렉토리의 내용물만 복사하고 해당 디렉토리는 생성하지 않는다.

 ADD는 COPY 기능에 파일 압축 해제와 URL 사용가능. 복사 대상이 디렉토리일 경우 해당 디렉토리 생성.

ADD는 복잡하고 가능한 경우에는 COPY를 사용하는 것을 권장함.

 

RUN vs CMD vs ENTRYPOINT

 RUN 명령어는 Dockerfile에서 이미지 빌드할 때 사용되며, 한 번 실행된 후 이미지에 반영된다.

캐시된 레이어를 효과적으로 활용하여 빌드 시간을 단축할 수 있다.

 CMD 명령어는 컨테이너가 시작될 때 실행할 기본 명령을 설정하는데 사용.

가장 마지막 CMD만 적용되고 CMD를 사용하여 실행되는 명령어와 인자를 덮어쓸 수 있다.

 ENTRYPOINT 명령어는 컨테이너가 시작될 때 실행 파일이나 스크립트를 설정하는데 사용.

CMD를 사용하여 실행되는 명령어와 인자를 결합하여 실행할 수 있다.

컨테이너가 실행될 때, ENTRYPOINT 명령어가 실행되고 CMD 명령어가 인자로 전달된다.

 

5회차 - 컨테이너 보관창고

핵심키워드

- registry

- docker hub

- private registry

 

docker hub

 

private registry

registry 이미지를 컨테이너로 실행시킨 뒤에 사용.

그러면 컨테이너 오류나면 등록한 거 다 사라지나?

no!

registry Dockerfile 확인해보면 호스트 경로에 마운트 되어 있는 것을 알 수 있다.

#Dockerfile
...
VOLUME ["/var/lib/registry"]
...

 

6회차 - Docker 컨테이너 사용하기

이미지 검색 docker search [옵션] <이미지이름:태그명>

이미지 다운로드 docker pull [옵션] <이미지이름:태그명>

다운 받은 이미지 목록 출력 docker images

다운 받은 이미지 상세 보기 docker inspect  [옵션] <이미지이름:태그명>

이미지 삭제 docker rmi [옵션] <이미지이름:태그명>

 

컨테이너 생성 docker create [옵션] <이미지이름:태그명>

컨테이너 실행 docker start [옵션] 컨테이너이름

컨테이너 생성, 실행 docker run [옵션] <이미지이름:태그명>

실행중인 컨테이너 목록 확인 docker ps [옵션]

동작중인 컨테이너 중지 docker stop [옵션] 컨테이너이름

컨테이너 삭제 docker rum [옵션] 컨테이너이름

 

포그라운드로 실행중인 컨테이너에 연결 docker attach [옵션] 컨테이너이름

동작 중인 컨테이너에 새로운 명령어 추가 실행 docker exec [옵션] 컨테이너이름

컨테이너에서 동작되는 프로세스 확인 docker top [옵션] 컨테이너이름

동작중인 컨테이너가 생성한 로그 보기 docker logs [옵션] 컨테이너이름  (-f 옵션을 주면 실시간으로 확인 가능)

 

7회차 - Docker 컨테이너 리소스를 관리하기

기본으로 컨테이너는 호스트 하드웨어 리소스의 사용 제한을 받지 않는다.

 

Docker command를 통해 제한할 수 있는 리소스

  • CPU
  • Memory
  • Disk I/O

docker run --help 명령어를 통해 도움을 받을 수 있다.

 

1. Memory 리소스 제한

제한 단위는 b, k, m, g로 할당

옵션 의미
--memory, -m 컨테이너가 사용할 최대 메모리 양을 지정
--memory-swap 컨테이너가 사용할 스왑 메모리 영역에 대한 설정
메모리+스왑, 생략 시 메모리의 2배가 설정됨
--memory-reservation --memory 값보다 적은 값으로 구성하는 소프트 제한 값 설정
--oom-kill-disable OOM Killer가 프로세스 kill 하지 못하도록 보호

 

OOM(Out Of Memory) Killer?

Linux 운영 체제에서 Out Of Memory(OOM) 상황에서 실행 중인 프로세스 중 일부를 종료시켜 시스템 안정성을 유지하는 기능.

 

-m 과 --memory-reservation 차이?

-m은 컨테이너가 사용할 수 있는 최대 메모리 양을 제한하고, --memory-reservation은 컨테이너가 사용할 수 있는 최소 메모리 양을 지정한다. => 컨테이너가 실행될 때 메모리를 미리 할당해서 컨테이너 메모리 부족 상태가 될 가능성이 줄어든다. 컨테이너가 빠르게 시작되어야 하는 경우 유용하다.

 

2. CPU 리소스 제한

옵션 의미
--cpus 컨테이너에 할당할 CPU core수는 지정
--cpus="1.5 컨테이너가 최대 1.5개의 CPU 파워 사용가능
--cpuset-cpus 컨테이너가 사용할 수 있는 CPU나 코어를 할당, cpu index는 0부터.
--cpuset-cpus=0-4
--cpu-share 컨테이너가 사용하는 CPU 비중을 1024 값을 기반으로 설정
--cpu-share 2048 기본 값보다 두 배 많은 CPU 자원을 할당

 

3. Block I/O 제한

옵션 의미
--blkio-weight
--blkio-weight-device
Block IO의 Quota를 설정할 수 있으며 100~1000까지 선택
default 500
--device-read-bps
--device-write-bps
특정 디바이스에 대한 읽기와 쓰기 작업의 초당 제한을 kb, mb, hb 단위로 설정
--device-read-iops
--device-write-iops
컨테이너의 read/write 속도의 쿼터를 설정한다.
초당 quota를 제한해서 I/O를 발생시킴. 0 이상의 정수로 표기
초당 데이터 전송량 = IOPS * 블럭크기 (단위 데이터 용량)

 

8회차 - Docker Container Storage

- 컨테이너 이미지는 read-only

- 컨테이너에 추가되는 데이터들은 별도의 ReadWrite 레이어 저장 = Union File System (Overlay)

- 컨테이너 제거 시에 ReadWrite 레이어 사라짐 => 데이터 영구적 보존 필요 => 볼륨 마운트

 

volume 옵션 사용

-v <host path>:<container mount path>

-v <host path>:<container mount path>:<read write mode>

-v <container mount path>

 

- 같은 볼륨으로 컨테이너끼리 데이터 공유 가능

 

volume 명령어

# volume 리스트 확인
docker volume ls

# volume 삭제
docker volume rm <볼륨 ID>

 

df 명령어 => 디스크 사용량을 모니터링 할 때 사용

df -h

 

9회차 - 컨테이너간 통신(네트워크)

1. 컨테이너가 통신하는 방법

 

docker0

  • virtual ethernet bridge : 172.17.0.0/16 => 사이더 16이라는 용어는 서브넷의 범위를 의미한다. 16은 IP 주소의 비트 수를 나타내는데, 16비트를 사용하면 172.17.0.1 에서부터 172.17.255.255까지의 IP 주소 범위가 가능하다는 것이다.

서브넷 : IP 주소 체계에서 네트워크를 보다 작은 단위로 분할하는 것을 말한다. 서브넷은 IP 주소와 서브넷 마스크를 이용하여 구분된다. 예를 들어, IP 주소 192.168.0.1과 서브넷 마스크 255.255.255.0을 이용하면 해당 IP 주소는 192.168.0.0/24 서브넷에 속하게 된다.

 

  • L2 통신기반 => 데이터 링크 계층을 기반으로 하는 네트워크
  • container 생성 시 해당 컨테이너에 veth 인터페이스 생성 => veth(virtual Ethernet)는 두 개의 가상 이더넷 인터페이스를 생성하여 컨테이너와 호스트 간에 통신을 가능하게 한다.
  • 모든 컨테이너는 외부 통신을 docker0 통해 진행
  • container running 시 172.17.X.Y 로 IP 주소 할당

 

2. 컨테이너 포트를 외부로 노출하는 방법

 

port-forwarding

  • container port를 외부로 노출시켜 외부 연결 허용
  • iptables rule을 통한 포트 노출
-p hostPort:containerPort
-p containerPort
-P

 

3. 컨테이너 네트워크 추가하는 방법

user-defined bridge network 생성

도커 제로 네트워크 인터페이스는 IP 스테틱하게 할당 불가능 => 내가 원하는 네트워크 대역으로 집어넣고 싶다면?

1. 도커 제로 네트워크 인터페이스에서 네트워크 대역 바꿀 수 있다.

2. user-defined bridge network 생성 가능

$ docker network create --driver bridge\
	--subnet 192.168.100.0/24\
    --gateway 192.168.100.254\
    mynet
# 만약 서브넷 생략하게 되면 172.18, 172.19 ... 로 자동 설정된다.
# 만약 게이트웨이 생략하게 되면 172.18.0.1 로 자동 설정된다.

# network 리스트 확인
$ docker network ls

# user-defined network는 ip로 특정 IP 할당 가능
$ docker run -d --name appjs\
	--net mynet --ip 192.168.100.100\
    -p 8080:8080\
    smlinux/appjs

 

4. 컨테이너간 통신 방법 (legecy)

#link 옵션은 <컨테이너 이름>:<원하는 이름>
$ docker run -d --name wordpress --link mysql:mysql\
	-e WORDPRESS_DB_PASSWORD=wordpress\
  	-p 80:80
    wordpress:4

도커 공식 문서에서는 '--link'보다 user-defined networks를 사용하는 것을 권장한다. (3번 방법)

 

10회차 - 빌드에서 운영까지

도커 컴포즈 - 여러 컨테이너를 일괄적으로 정의하고 실행할 수 있는 툴

docker-compose로 컨테이너 실행 방법

  1. 서비스 디렉토리 생성
  2. docker-compose.yml 생성
  3. docker-compose up -d
docker-compose up -d
docker-compose ps
# 컨테이너 갯수 조절 가능
docker-compose scale mysql=2
docker-compose down