✔️ Docker(도커)란 ?
- 리눅스 컨테이너를 기반으로 하여 특정한 서비스를 패키징하고 배포하는데 유용한 오픈 플랫폼이다.
- 인프라에서 어플리케이션을 분리하고 컨테이너로 추상화시켜 SW를 빠르게 제공할 수 있다.
- 하나의 호스트 OS 안에서 여러 컨테이너의 라이프 사이클을 관리하고 어플리케이션을 오케스트레이트된 서비스로 배포할 수 있다.
✔️ Docker의 구성 요소
컨테이너를 만들기 위해서 필요한 3가지 요소는 다음과 같다.
① Dockerfile
컨테이너를 만들기 위한 설명서 (요리로 치면 레시피)
- Copy files - 어플리케이션을 구동하기위해 꼭 필요한 파일들은 무엇이 있는지
- Install dependency - 어떤 프레임워크나 라이브러리를 사용해야 하는지
- Set environment variables - 필요한 환경변수에 대해 설정할 수 있다.
- Run setup scripts - 어떻게 구동해야되는지 스크립트도 포함할 수 있다.
② Image
작성한 Dockerfile을 이용해 Image를 만들 수 있다.
어플리케이션을 실행하는데 필요한 모든 것들이 포함되어 있으며 한마디로 실행되고 있는 어플리케이션의 상태를 스냅샷해서 이미지로 만들어두는 것이다. 만들어진 이미지는 불변(Immutable)의 상태이다.
③ Container
컨테이너는 캡쳐해둔 어플리케이션 이미지를 샌드박스처럼 독립된 환경에서 (개별적인 파일시스템) 안에서 실행할 수 있는 것을 말한다.
객체 지향 프로그래밍에 익숙하다면 이미지를 클래스라고 생각하면 이해하기 쉬울 것이다.
동작하고 있는 어플리케이션을 스냅샷해서 템플릿 형태로 이미지를 만들어두고 클래스(이미지)를 이용해서 실제로 어플리케이션이 동작하는 각각의 컨테이너를 만들 수 있다.
그래서 이미지는 우리가 캡쳐했을 당시의 그 프로젝트를 상태(불변의 상태)를 가지며 컨테이너에서 각각 동작하는 어플리케이션은 개별적으로 수정이 가능한 상태이다.
각각의 컨테이너에서 수정된 파일들이 있다면 이미지에는 전혀 영향을 끼치지 않는다. 이미지는 클래스 각각의 컨테이너는 만들어진 인스턴스라고 볼 수 있다.
✔️ Docker의 특징
Layer 저장 방식
도커 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 용량이 수백MB에 이른다. 처음 이미지를 다운 받을 때는 크게 부담이 안되지만 기존 이미지에 파일을 하나 추가했다고 수백MB를 다시 다운받는 것은 매우 비효율적이다.
도커는 이런 문제를 해결하기위해 레이어(Layer)라는 개념을 사용하고 유니온 파일 시스템을 이용해 여러개의 라이브러리를 하나의 파일 시스템으로 사용할 수 있게 해준다. 이미지는 여러개의 읽기 전용 레이어로 구성되고 파일이 추가되거나 수정되면 새로운 레이어가 생성된다.
ubuntu 이미지가 A + B + C의 집합이라면, ubuntu 이미지를 베이스로 만든 nginx 이미지는 A + B + C + nginx가 된다. webapp 이미지를 nginx 이미지 기반으로 만들었다면 예상대로 A + B + C + nginx + source 레이어로 구성된다. webapp 소스를 수정하면 A, B, C, nginx 레이어를 제외한 새로운 source(v2) 레이어만 다운받으면 되기 때문에 굉장히 효율적으로 이미지를 관리할 수 있다. 컨테이너를 생성할 때도 레이어 방식을 사용하는데 기존의 이미지 레이어 위에 읽기/쓰기 레이어를 추가한다. 이미지 레이어를 그대로 사용하면서 컨테이너가 실행중에 생성하는 파일이나 변경된 내용은 읽기/쓰기 레이어에 저장되므로 여러개의 컨테이너를 생성해도 최소한의 용량만 사용한다. 가상화의 특성상 이미지 용량이 크고 여러대의 서버에 배포하는걸 감안하면 단순하지만 엄청나게 영리한 설계이다.
✔️ Docker 이미지 배포 방법
git, github를 사용해본 사람이라면 Docker 배포 방법은 아주 친숙할 것이다.
내 로컬 머신에서 이미지를 만들어서 깃허브와 같은 Container Registry라는 곳에 내가 만든 이미지를 PUSH하고 필요한 서버나 다른 개발자 PC에서 내가 만들어둔 이미지를 가지고 와서 그걸 그대로 실행하면 된다.
물론 이미지를 정상적으로 실행하기 위해서는 Docker와 같은 컨테이너 엔진이 설치되어 있어야 한다.
✔️ Docker 이미지 공유 방법
Dockerhub가 가장 유명하고 많이 쓰인다.
✔️ namespace, cgroup
도커는 컨테이너라는 가상의 "격리 환경"을 만들기 위해 리눅스의 namespace와 cgroup이라는 기능을 사용한다.
(namespace와 cgroup으로 만들어진 컨테이너를 LXC라고 부른다.)
namespace
- 프로세스 별로 리소스 사용을 분리한다.
- VM에서는 각 게스트 별로 독립적인 공간을 제공하고 충돌하지 않도록 Hardware Resource 자체를 가상화한다.
- 하지만 namespace의 경우, Hardware Resource 자체를 가상화하는 것이 아니라, Linux 내의 자원을 가상화한다.
- pid name spaces : 프로세스 격리 처리 (독립된 프로세스 공간 할당)
- net name spaces : 네트워크 인터페이스
- ipc name spaces : IPC 자원에 대한 엑세스 관리
- mnt name spaces : 파일 시스템 포인트 관리
- uts name spaces : host name 할당
- 도커에서 cenetos:latest 이미지를 컨테이너로 실행하고, ps 상태를 확인해보자. ps 명령어는 현재 시스템에서 돌고 있는 프로세스를 보여주는 가장 기본적인 명령어이며, 아래처럼 현재 실행중인 프로세스의 목록을 출력해준다. ps 상태를 보면 1번에 /bin/bash와 같이 쉘이 PID1번으로 설정되어있다.
$ docker run -it --name study centos:latest
$ [root@4e1d03de5820 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:42 pts/0 00:00:00 /bin/bash
root 15 1 0 07:42 pts/0 00:00:00 ps -ef
cgroup
- Control Groups의 약자로 프로세스들이 사용할 수 있는 컴퓨팅 자원들을 제한하고 격리시킬 수 있는 리눅스 커널의 기능이다. namespace와 더불어 도커 컨테이너에서 완벽한 격리 환경을 만드는 데에 쓰이는 중요한 기능이다.
- cgroup를 이용하면 다음 자원들을 제한할 수 있다.
- 메모리
- CPU
- Network
- Device
- I/O
- 아래의 그림을 보자. cgroup 은 컴퓨터의 자원(CPU, 메모리, network, storage I/O)가 각 프로세스 별로 독립적으로 격리되어 할당한다.
namespace | 프로세스를 독립시켜주는 가상화 기술이다. 각 컨테이너에서 실행된 프로세스가 시스템(user, 파일, 네트워크, 호스트명, 프로세스) 등에 대해 독립할 수 있게 해준다. |
cgroups | 자원(CPU, 메모리, network bandwidth)에 대한 제어를 가능하게 해주는 리눅스 커널의 기능이다. |
즉, 도커는 프로세스를 격리하고 프로세스에 필요한 컴퓨팅 자원을 독립적으로 할당/격리하여 완벽히 격리된 가상 환경을 구축하게 해준다.
🔗 출처
https://daaa0555.tistory.com/464
https://www.youtube.com/watch?v=LXJhA3VWXFA
https://dev-youngjun.tistory.com/2
'DevOps > Docker' 카테고리의 다른 글
[Docker] Docker(도커)의 기본 명령어 (0) | 2022.05.07 |
---|---|
[Docker] Docker(도커) 설치 (0) | 2022.05.06 |
[Docker] Monolithic 구조와 MicroService 구조 (0) | 2022.05.06 |
[Docker] Docker(도커)란 ? (0) | 2022.05.06 |
컨테이너란 무엇인가 ? (1) | 2022.03.07 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!