Search
Duplicate
🐳

Docker의 특징

간단소개
Docker의 특징과 동작 방식을 알아봅니다.
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
Docker
태그
Docker
container
Scrap
8 more properties
원본 게시물 입니다~~

Docker의 특징

Docker is an open source platform for building, deploying, and managing containerized applications.
도커(Docker) 란 리눅스의 응용 프로그램들을 프로세스 격리 기술들을 사용해 컨테이너로 실행하고 관리하는 오픈소스 프로젝트이다.
도커는 다음과 같은 3가지 특징을 갖는다.
1.
애플리케이션의 이미지화
2.
프로세스간 격리
3.
확장성/이식성.
이미지를 이해하기 전에 컨테이너(Container)에 대해 알 필요가 있다. 도커 공식 홈페이지는 Container를 다음과 같이 정의하고 있다.
Simply put, a container is a sandboxed process on your machine that is isolated from all other processes on the host machine. That isolation leverages kernel namespaces and cgroups, features that have been in Linux for a long time.
Container는 host machine의 다른 모든 프로세스와 격리된 프로세스이며 이러한 격리는 Linux의 kernel 기능을 사용한다.
~~컨테이너에 대해서는 뒤에서 자세히 설명하겠다. ~~

격리(Isolation)

도커는 내부적으로 리눅스의 LXC 라이브러리를 사용하는데, LXC는 내부적으로 chroot, cgroup, namespace등 리눅스 API를 사용한다.

chroot (change root directory)

chroot는 파일 시스템을 격리해주는 기술이다. 컨테이너 별로 파일 시스템을 다르게 해 실행 가능한 명령어, 기능을 다르게 할 수 있다.
리눅스의 파일 시스템에는 / 라고 불리는 root directory가 존재한다. 파일 시스템의 최상위 디렉토리이며, 모든 디렉토리와 파일은 이 루트 디렉토리 아래에 존재한다.
root directory아래에 A, B, C파일이 있고 디렉토리A 안에는 다시 D, E 파일이 있다.
여기서 파일E를 찾기 위해서는 루트 디렉토리인 /를 기준으로 파일을 찾아야 한다.
/bin/bash 라는 프로세스를 /가 아닌 그 밑의 특정 디렉토리 /tmp/new를 루트 디렉토리로 가지게 만들면 /bin/bash 프로세스는 /를 root로 가지는 다른 파일에 접근할 수 없다.
$ chroot /tmp/new /bin/bash # /tmp/new_root 라는 루트 디렉토리를 사용해 /bin/bash 명령어를 실행
Plain Text
위와 같이 사용 되는데 docker 명령어도 비슷한 구조로 이루어져 있다.
$ docker run -i -t ubuntu /bin/bash # ubuntu 이미지를 가져와 컨테이너를 시작하고 /bin/bash 명령어를 실행
Plain Text
/bin/bash는 보는 그대로 루트 디렉토리인 /bin/bash에 위치하기 때문에 다음의 명령어는 실행이 되지 않는다.
$ chroot /tmp/new /bin/bash
Plain Text
실행하기 위해서는 다음의 명령어로 /bin/bash를 /tmp/new/bin/bash로 복사하고 그에 필요한 의존성을 전부 가져올 필요가 있다.
$ mkdir -p /tmp/new/bin/ $ cp /bin/bash /tmp/new/bin/
Plain Text

cgroup(control group)

cgroup은 프로세스에 대한 리소스의 제어를 가능하게 해주는 기능이다. 다음과 같이 프로세스 그룹 단위로 리소스 사용량을 제한하고 격리시킨다.
다음의 글을 kakao Tech팀의 프로세스 그룹과 컨테이너에 대한 설명이다.
_위의 예제는 Container와 Cgroup의 관계를 나타내고 있습니다. Container가 생성된다면 생성된 Container의 Process들을 담당하는 Container Cgroup이 생성됩니다.
모든 process가 Container Cgroup에 소속되기 때문에 Container의 Resource를 제어하기 위해서는 Container Cgroup을 제어하면 된다.

namespace

namespace는 chroot가 격리하지 않은 나머지를 격리해 준다.
mount: 호스트 파일 시스템에 구애받지 않고 독립적으로 파일 시스템을 마운트 하거나 언마운트 가능하게 한다. namespace안에서 수행한 마운트는 호스트 OS나 다른 namespace에서 엑세스 할 수 없다.
pid: 독립적인 프로세스 공간을 할당한다. namespace가 다른 프로세스끼리는 서로 엑세스할 수 없다.
net: namespace간에 network 충돌을 방지한다. 네트워크 디바이스, IP주소, 포트 번호, 라우팅 테이블, 필터링 테이블 등과 같은 네트워크 리소스를 격리된 namespace마다 독립적으로 가질 수 있다.
ipc: 프로세스 간의 독립적인 통신 통로를 할당한다.
uts: 독립적인 hostname 혹은 Domain name을 할당한다.
uid: 독립적인 사용자를 할당한다. UID, GID를 namespace별로 독립적으로 가질 수 있게 된다. 따라서 namespace안의 관리자 계정은 호스트 OS에 대해서는 관리 권한을 일절 갖지 않게 된다.
이렇게 Linux API를 활용해서 Container Isolation를 구현한다.

Container

도커의 공식 홈페이지에는 다음과 같이 적혀있다.
Container is a runnable instance of an image. You can create, start, stop, move, or delete a container using the DockerAPI or CLI.
image에 대한 실행가능 한 인스턴스란다..!
Container는 Image로 만들어 지는걸까?
지금부터 이미지에 대해 알아보자
공식 홈페이지가 가장 설명이 명확한 것 같다.
When running a container, it uses an isolated filesystem. This custom filesystem is provided by a container image. Since the image contains the container’s filesystem, it must contain everything needed to run an application - all dependencies, configuration, scripts, binaries, etc.
The image also contains other configuration for the container, such as environment variables, a default command to run, and other metadata.
이미지는 컨테이너의 파일 시스템이다. 애플리케이션 실행에 필요한 라이브러리와 바이너리, 기타 구성파일을 빌드한 단위로 컨테이너를 생성하고 실행하기 위한 모든 것이 들어있다.
바로 여기서 도커의 중요한 특징이 나온다. 도커는 Immutable Infrastructure Paradigm이란 개념을 기반으로 하는데, 명령어로 서버의 상태를 관리했던 이전과는 안정성, 확장성, 이식성 이 매우 높다.

안정성, 확장성, 이식성

서버는 시간이 지남에 따라 내용이나 설정이 수시로 변한다. 이전에는 변경, 추가, 삭제등 서버 상태에 변화가 필요하면 현재 서버에 직접 새로운 코드를 배포했다Mutable. 만약 100대의 서버를 명령어를 통해 작업한다면 서버의 환경이나 리소스 등의 차이로 몇대는 실패할 수 있다.
이러한 결과는 서비스의 안정성에 큰 영향을 미치며, 언제 누가 어떻게 변경했는지에 대한 관리가 어렵기 때문에 문제 발생시 추적이 굉장히 힘들다.
이러한 문제를 해결하기 위해 서버가 배포된 이후에는 수정이 절대 불가능한 Immutable한 인프라가 등장했다.
이러한 Immutable infrastructure 특징 때문에 서버의 안정성이 좋아졌고, 더 많은 리소스가 필요하다면 그때그때 정확히 동일한 서버를 배포할 수 있게 되어 확장성이 높아졌다. 뿐만 아니라 개발, 테스트, 운영 단계의 환경을 도커로 통일할 수 있고 어떤 환경이든 도커가 설치 되어 있다면 어디서든 컨테이너 실행이 가능해져 높은 이식성을 갖추게 되었다.
이렇게 도커가 너무 편리하다보니 많은 컨테이너를 운영하게 되고 각각의 컨테이너 하나가 하나의 서버를 운영하는 것과 동일한 비용이 들게 되었다. 따라서 유지보수 비용이 높아졌고 각각의 컨테이너를 따로 관리하는 것에 많은 제약이 붙이 시작했다.
이때 등장한게 도커의 짝꿍 쿠버네티스(KuberNetes)다.

정리

도커는 프로세스를 격리하는 기술이다.
도커의 컨테이너는 도커 이미지를 사용해 chroot, cgroup, namespace 등 리눅스 커널의 격리 기술을 사용해 만들어진다.
도커 이미지는 Dockerfile이라는 파일로 만들어 진다.
도커 컨테이너가 많아지면 쉬운 관리를 위해 컨테이너 오케스트레이션 도구를 사용한다.