Docker 개요
참고: 컨테이너 개념잡기- 왜 컨테이너일까? - Opennaru, Inc.
Docker란?
Dock + er
원래는 부두에서 물건을 싣고 내리는 일을 하는 사람을 의미한다.
규격화되지 않은 물건들의 형태와 노동 방식은 시간, 노동력 등에서 많은 비효율을 야기했는데
이 문제를 해결하기 위해 등장한 것이 컨테이너
컨테이너의 등장이 바꾼 가장 큰 것은 규격화
자동화가 가능하게 하고, 컨테이너 단위의 물류시스템도 구축할 수 있다.
이걸 그대로 IT 환경에 대입해 보면,
네트워크라는 바다 안에서 컨테이너들이 이동한다.
화물 컨테이너의 내부에 무엇이 있는지는 운송과는 관계없다.
도커 컨테이너도 어떤 애플리케이션이 내부에 있는지는 중요하지 않다.
컨테이너를 통해 개발과 테스트 단계에서 사용하는 시스템 환경을 물리서버 등 다양한 환경에서 배포하고 운영하는 것을 쉽게 할 수 있다.
개발환경이나 운영환경에 관계없이 동일하게 동작할 것이라는 기대가 가능하다.
MSA에서 microservice를 컨테이너로 패키징 하는 방식으로 더욱 효과적으로 사용이 가능하다.
컨테이너 기반 기술
컨테이너의 특징
- 호스트와 애플리케이션 분리: OS 레벨 가상화
- 적은 시스템 리소스, 디스크 공간 소비
- 리소스 사용에 유연성과 효율성 제공
- 가상머신과는 달리 개별적인 커널을 갖지 않음
컨테이너 기반 기술
- cgroup
- 리소스에 대한 제한과 우선순위 제어
- namespace
- 애플리케이션에 대한 격리(isolation) 환경 제공
Virtual Machine과의 차이점
Virtual Machine
- 완전한 OS로 부팅
- CPU 등 초기화 후 리눅스 커널이 올라옴 > 운영체제 프로세스 실행 > 운영체제 위한 데몬 서비스 등 실행 > 애플리케이션 수행
- 반드시 Hypervisor 필요로 함 (가상머신에는 없는 CPU 및 메모리를 emulate해주는 기능)
- 가상 머신의 근본적 목적은 기존 OS에서 벗어난 완전히 격리된 환경
이때의 문제는
1. Hypervisor 레이저를 반드시 거쳐야 하기 때문에 발생하는 성능 손실
2. 자원의 낭비
: 예를 들어, 단순히 Apache 웹서버를 수행하기 위해서도 불필요한 데몬 서비스 등의 실행이 수반되어야 함
이러한 VM의 문제점을 개선하기 위해 나온 것이 컨테이너
컨테이너는 OS 안에서 하나의 프로세스로 실행된다.
- 다른 프로세스로부터 완전히 격리된 환경
- 특정 프로세스만을 위한 파일 시스템, 네트워크, 사용자 계정 등을 격리시킬 수 있다.
VM이 하고자 했던 격리 환경을 제공 가능하다.
컨테이너는 곧 격리된 프로세스로 기능할 수 있지만,
VM과는 다르게 Hypervisor를 거치지 않아 성능 손실이 적음
파일시스템 격리 - chroot
chroot:: run command or interactive shell with special root directory
- 프로세스에게 격리된 루트 디렉토리 제공
- httpd, vsftpd 등 많은 패키지에서 내부적으로 사용
[실습] newroot 디렉토리 생성 후 루트 디렉토리로 설정하여 파일 시스템 격리
# 디렉토리 생성
mkdir -p ~/newroot/bin newroot/lib64
# 명령어가 사용하는 라이브러리 확인
ldd /bin/bash
ldd /bin/ls
ldd /bin/date
# 각 명령어가 사용하는 라이브러리 복사
cp /lib64/libtinfo.so.6 ~/newroot/lib64
cp /lib64/libc.so.6 ~/newroot/lib64
...
# 명령어 복사
cp /bin/bash newroot/bin
cp /bin/ls newroot/bin
cp /bin/date newroot/bin
# newroot를 root directory로 설정
chroot newroot
▶️ 새로운 bash 프로세스에서 root directory가 격리 (파일시스템 격리)
네임스페이스 Namespace
리눅스 네임스페이스
- 동일 시스템 안에서 격리된 환경을 제공하는 리눅스 커널의 기능
- 커널 레벨에서 프로세스의 실행 환경 자체를 격리 (HW 자체를 가상화하는 Hypervisor과는 다름)
리눅스 커널에서 지원하는 네임스페이스
namespace | description |
IPC | System V IPC resources : shared memory, message queue, semaphore |
Network | A physical or virtual network interfaces, full networking stacks and firerwall rules |
Mount | Filesystem mount points |
PID | Process IDs so that each container can have its own init(aka PID 1) |
UTS | Hostname and NIS domain name |
User | User and group IDs allow for a separate root user in each container |
네임스페이스 지원 System Call
System call | description |
clone() | clone() 새로운 프로세스를 만들고 이를 새로 지정된 네임스페이스에 연결 |
unshare() | unshare() 현재 프로세스를 새로 지정된 네임스페이스에 연결 |
setns() | setns() 이미 존재하는 네임스페이스에 프로세스를 연결 |
unshare -m 명령어를 사용하여 네임스페이스 격리 가능
Control Groups
리눅스 커널에서 제공하는 기능
- 프로세스 그룹에 대한 리소스 제한, 격리, 모니터링
- 리소스별로 정해진 양만 사용할 수 있게 함
Docker 설치
방화벽 해제
docker는 컨테이너 간 통신이나 호스트와의 통신을 패킷 필터링 및 포워딩을 통해 하는데,
이를 원활하게 하기 위해 방화벽을 해제하는 것이 좋다
# 방화벽 서비스 종료
systemcel stop firewalld
# 방화벽 상시가동 중지
systemctl disable firewalld
# 방화벽 서비스 상태 보기
systemctl status firewalld
# command 도움말 확인
docker --help
Selinux 해제
- selinux: Linux의 애플리케이션 방화벽 기능, 역시 해제하는 것이 좋음
- /etc/selinux/config 파일 편집 (SELINUX=disabled)
docker 설치
1. 최신 버전 설치 (script 이용)
curl -ssl https://get.docker.com | sh
2. 패키지 매니저 이용한 설치 (버전 선택 가능)
# 필수 패키지 설치
yum install -y yum-utils
# docker repository 추가
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# docker 설치 가능 버전 확인
yum list docker-ce --showduplicates
# docker 최신 버전 설치
yum install -y docker-ce
# 특정 버전 설치
yum install -y -docker-ce-<버전>
docker 데몬 시작 후 시스템 부팅 시 자동 시작 설정
systemctl enable docker
systemctl start docker
systemctl status docker
기타 관련 명령어
# 도커 버전 확인
docker version
# 도커 구성 정보 확인
docker info
# docker 데몬 시작 시 생성한 디렉트리 계층구조 확인
tree -L 2 /var/lib/docker
도커 용어 정리
참고: https://docs.docker.com/glossary/
용어 | 설명 |
image | 도커 이미지는 컨테이너의 기본 요소가 된다. 프로그램을 실행할 때 필요한 기능들의 파일을 모아 둠 (ex. Apache 웹서버의 경우: 실행 파일, 라이브러리 파일, 설정 파일 등) |
container | 특정 도커 이미지를 기반으로 하는 하나의 격리된 프로세스 가상 머신으로 프로세스 여러개를 띄우는 것 보다 컨테이너 여러 개를 띄우는 것이 훨씬 효율적 |
registry | 이미지들을 네트워크 어딘가에서 호스팅하는 서비스 (ex. Docker Hub) |
repository | 이미지들을 구분지음 |
tag | 버전 |
도커 CLI 명령 포맷
컨테이너 라이프사이클
스냅샷 Snapshot
특정 타이밍에 추출된 도커 이미지 안의 파일과 디렉토리
(/etc나 /bin 등 Linux의 작동에 필요한 디렉토리 및 파일들)
docker container create
docker container create <options> image <command> <arg>
docker container create -it centos:7.6.1810
컨테이너 작성만 하고 시작은 하지 않음
이렇게 생성하면
확인 가능 (watch docker container ls -a 하면 2초마다 조회)
docker container run
docker container run <options> image <command> <arg..>
docker container run -it centos:7.6.1810
컨테이너 생성, 프로세스 #1 시작
docker container stop
docker container stop <options> container <container#>
docker container stop 490d2934419
SIGKILL을 전송하여 종료시킨다
(Linux 시그널 N으로 종료된 경우 128 + x가 종료코드가 됨 > 137의 경우 128 + 9, SIGKILL(프로세스 강제 종료)에 해당)
cf. exit로 나간 경우 (에러코드 130 확인)
docker container start
docker container start <options> container <container>
docker container start c7d82394z1
docker container rm
docker container rm <options> container <container>
docker container rm c9187231a91
docker container cp
HOST와 컨테이너 간 파일 복사
docker container cp CONTAINER:SRC_PATH DEST_PATH
docker container cp SRC_PATH CONTAINER:DEST_PATH
Docker Image
도커 이미지
- 컨테이너 실행을 위한 기반을 제공하는 읽기 전용 템플릿
- 애플리케이션 실행에 필요한 모든 요소 포함
레이어
- 이미지는 연결된 여러 레이어로 구성
- 이미지 생성 프로세스를 레이어로 기록
- 컨테이너가 생성되면 최상위에 쓰기 가능 레이어 생성 > 컨테이너에서 변경된 파일을 레이어에 저장
docker container export
docker container export [options] <container>
컨테이너 안의 File System을 tar 파일로 출력
export 시 모든 Layer가 하나의 Layer로 묶이게 됨
Docker Volume
Docker가 지원하는 데이터 영속성 방법
종류 | 설명 |
bind mount | - 호스트의 디렉토리에 마운트 - 컨테이너 런타임에 호스트의 볼륨을 컨테이너에 마운트 - HOST 파일시스템에서 파일 수정 가능 |
volume | - Docker가 관리하는 호스트 파일 시스템(/var/lib/docker/volumes/)에 저장 - Non-Docker 프로세스는 파일 시스템의 이 부분을 수정해서는 안됨 - Docker에서 데이터를 유지하는 가장 좋은 방법 |
tmpfs mount | - 호스트 시스템의 메모리에만 저장. 파일 시스템에는 저장되지 않음 |
Volume
1. 이름 없는 볼륨 사용 (자주 사용되지 않음)
- -v 옵션에 마운트 경로만 명시해 줌
2. 이름 있는 볼륨 사용
: 컨테이너 삭제 후에도 웹에서 업로드한 파일은 HOST 시스템에 영속적 보존
# HOST 시스템에서 볼륨 생성
docker volume create <volume name>
# 생성된 볼륨 조회
docker volume ls
# 상세 조회
docker volume inspect <volume name>
# 컨테이너 시작
docker container run -v <volumn name>:<경로> --name=<container name> <image>
Docker Network
Docker 지원 네트워크
1. bridge network (default)
- docker network run --network=bridge 옵션 (생략해도 default)
- Docker 설치 시 서버의 물리 NIC가 docker0라는 가상 브릿지 네트워크로 연결
- 컨테이너 실행 시 172.17.0. 0/16 서브넷 마스크를 가진 프라이빗 IP주소가 eth0 인터페이스에 자동으로 할당
- 컨테이너에 고정 IP 할당 불가
- port mapping
- 외부에서 접속하게 하려면 port mapping 옵션 적용해야 함 (docker container run -p 80:8080)
1-1. custom bridge network
- 직접 네트워크 디자인
- 컨테이너에 IP static하게 고정 가능 (수동 IP주소 및 서브넷 지정)
- Linux bridge가 HOST에 할당
- NAT, 라우팅 지원 > 외부 네트워크 연결 가능
2. host network
- docker container run --network=host 옵션
- 컨테이너의 network 격리 해제
- 보안에 잠재적 위험 (컨테이너에 root 로그인)
3. none network
Dockerfile
도커파일: 도커 이미지의 인프라 구성을 기술한 파일
FHS (Filesystem Hierarchy Standard)
'TIL' 카테고리의 다른 글
실용주의 프로그래머 2장 (0) | 2024.06.22 |
---|---|
[Docker] Docker 기본 개념 (0) | 2024.01.09 |
코드업 C언어 기초 100제 (1) | 2023.10.30 |
WebSquare 2 - 개요 (0) | 2023.08.01 |
IT 전체 영역 큰 그림 보기 (0) | 2023.07.05 |