성장, 그리고 노력

부족하더라도 어제보다 더 잘해지자. 노력은 절대 배신하지 않는다.

Docker

[Docker] 도커 입문하기 2 - 배경 지식 쌓기

제이콥(JACOB) 2021. 12. 13. 01:04

넋두리

 도커에 대해 더 알아보기 전에 컨테이너에 대해 좀 더 이해해보자. 나 또한 리눅스를 깊게 공부해 본적은 없기 때문에 부족한 지식을 채우고자 이 파트를 추가했다. 이 부분은 필수는 아니고 원한다면 바로 다음으로 넘어가도 된다.


컨테이너란 무엇일까?

 컨테이너를 처음들은 사람도 많을 거고, 사실 도커나 쿠버네티스 먼저 떠오르는 사람이 많을 것이다. 이 관점에서만 본다면 컨테이너를 저렴한 가상 머신(VM)으로만 생각할 수도 있다.
 컨테이너(container)란, 공통 기능 세트를 충족하는 단일 호스트에서 실행되는 격리된 프로세스 그룹이며, 이런 기능 중 일부는 Linux 커널에서 찾을 수 있다.

어떻게 도커 컨테이너를 격리시키는 것일까?

 이를 위해서는 Linux의 cgroup(control groups)과 네임스페이스(namespaces)에 대해 알아야 한다. 물론 이 기술도 처음부터 나온건 아니고 과거에는 chroot와 pivot_root(2) 등으로 격리 문제를 해결할려고 했으며, 여기에 대한 내용은 일단 생략한다.

Linux Namespaces(ns)

 네임스페이스는 2002년 리눅스 2.4.19와 함께 도입된 리눅스 커널 기능이다. (도커 역시 리눅스 커널 기능을 이용해 컨테이너를 격리한다.) 이 기능은 추상화 계층에서 특정 전역 시스템 리소스를 랭핑하는 것이다. 이렇게 하면 네임스페이스 내의 프로세스에 리소스의 자체 격리 인스턴스가 있는것처럼 보이게 할 수 있으며, 쉽게 말해 네임스페이스의 주요 기능은 프로세스를 서로 격리한다는 것인거다.
 개발자는 컨테이너를 사용하면 완전한 VM처럼 보이고 느껴지는 격리된 환경을 제공하지만, 사실 VM이 아니라 어딘가에 있는 서버에서 실행 중인 프로세스이며, 두 개의 컨테이너를 시작하면 어딘가의 단일 서버에서 두 개의 프로세스가 실행되고 있지만 서로 격리되어 있는 것이다.

 현재 사용 가능한 네임스페이스는 여러 개의 고유한 네임스페이스(mnt, pid, net, ipc, uts, user 등)가 구현되어 있다.

  • user: root가 같은 사용자 공간 내에서 권할을 가질 수 있게 된다.
  • pid: 다른 네임스페이스의 pid세트로부터 독립적인 프로세스의 pip세트를 할당한다.
  • net: 독립적인 네트워크 스택을 가지고 자신의 개인 라우팅 ip 주소 세트 테이블, 소켓 연결 테이블, 방화벽, 기타 네트워크 관련 자원 추적 목록을 가질 수 있다.
  • mnt: 호스트 파일 시스템에 영향을 주지 않고 마운트 네임스페이스에서 파일 시스템을 마운트 및 언마운트 할 수 있다.
  • ipc: 자신의 ipc자원이 아닌 posix 메시지 큐이다.
  • uts: 하나의 시스템이 다른 프로세스에 다른 호스트 및 도메인 이름을 가지고 있는 것처럼 보일 수 있다.

cgroup

 제어 그룹(cgroup)은 프로세스 모음의 리소스 사용량(CPU, 메모리, 디스크 I/O, 네트워크 등)을 제한, 설명 및 격리하는 리눅스 커널 기능이며, 아래와 같은 기능이 있다.

  • 리소스 제한: 프로세스가 사용할 수 있는 특정 리소스의 양을 제한하도록 cgroup을 구성할 수 있다.
  • 우선 순위: 리소스 경합이 있을때 다른 cgroup의 프로세스와 비교하여 프로세스가 사용할 수 있는 리소스의 양을 제어할 수 있다.
  • 회계: 리소스 제한은 cgroup 수준에서 모니터링 되고 보고된다.
  • 제어: 단일 명령으로 cgroup에 있는 모든 프로세스의 상태(고정, 중지, 다시시작)를 변경할 수 있다

 쿠버네티스 환경에서 cgroup을 사용하여 포드 수준에서 리소스 요청 및 제한, 해당 QoS 클래스를 구현할 수 있다.

그럼 Linux 컨테이너(LXC)와 Docker 컨테이너의 차이점은 무엇인가?

 위 내용만 봐서는 도커는 리눅스의 ns와 cgroup을 사용해서 구축했기 때문에 큰 차이가 없을거 같지만 목적이 다르다. LXC는 OS 컨테이너화에 중점을 두는 반면 Docker 컨테이너는 애플리케이션 컨테이너화에 중점을 둔다. 또한 LXC는 다목적 운영체제의 가상화이며, 도커는 단일 목적 애플리에키션의 가상화이다.

 LXC는 단일 제어 호스트에서 여러 개의 가상환경(VE)을 생성하고 실행할 수 있는 OS 수준의 가상화 기술을 제공하며, VM에 비해 더 저렴하고 빠르게 구축할 수 있는 방법이다. 하지만 추가적인 리눅스 지식과 경험이 필요하다. docker는 dotCloud라고 불렸던 사이드 프로젝트에서 시작되었으며, 이후 오픈소스로 공개되었다. 도커는 사실 LXC 기능의 확장이다.

 Docker는 go 언어로 개발되었으며 LXC, cgroup 및 리눅스 커널 자체를 활용한다. LXC를 기반으로 하기 때문에 Docker 컨테이너에는 별도의 운영 체제가 포함되어 있지 않으며, 대신 기본 인프라에서 제공하는 운영 체제의 고유 기능에 의존한다.

 LXC는 오래되었지만 시스템 관리자에 중점을 두며, 일반적으로 파일 시스템에 다른 루트를 제공하고 서로 격리되고 상태를 공유할 수 없는 환경을 생성하여 전체 시스템에 대한 OS 컨테이너를 제공한다.

  반면 Docker는 OS수준을 넘어 애플리케이션 자체의 보다 세분화된 세계로 컨테이너를 가져왔다. 초반에는 LXC를 기반으로 구축되기 시작했지만, 나중에는 libcontainer라는 자체 실행 환경으로 옮겼다. 각 컨테이너에 대해 운영체제를 초기화를 시작하는 LXC와 달리 Docker는 Docker Engine에서 제공하는 하나의 OS환경을 제공한다. 따라서 개발자가 Docker 이미지로 지정된 자체 애플리케이션 환경에 상주하는 애플리케이션을 쉽게 실행할 수 있다.

그리고 도커의 경우 이미지 빌드를 위한 명령 시퀀스를 자동화하는 dockerfile을 사용하여 개발자간 공유할 수 있다.

어떻게 내 컴퓨터에서 cgroup, ns를 사용할 수 있지?

난 리눅스가 아닌데, 내 컴퓨터에서 cgroup, ns를 이용하여 컨테이너가 격리될 수가 있지?

이것에 대한 이유는 도커를 설치한 후 간단한 명령어를 통해 추측해 볼 수 있다.

$ docker version

위 그림과 같이 서버 정보중 OS/Arch 정보를 보면 linux/arm64라고 적혀있는 것을 확인할 수 있다. 나같은 경우는 macOS 환경임에도 불구하고 linux라고 적혀있는 것이다.

이유는 바로 내가 사용하는 컴퓨터 환경과 상관없이 도커 서버가 리눅스 VM 환경에서 실행되고 있기 때문이다. 따라서 모든 컨테이너는 리눅스 가상 머신 위에서 생성되며, 리눅스 커널이 컨테이너를 격리시키고 리소스를 나눠주게 된다.


깃북으로 보기

https://ajdkfl6445.gitbook.io/study/devops/docker/background-knowledge

 

배경지식 - 콥 노트

제어 그룹(cgroup)은 프로세스 모음의 리소스 사용량(CPU, 메모리, 디스크 I/O, 네트워크 등)을 제한, 설명 및 격리하는 리눅스 커널 기능이며, 아래와 같은 기능이 있다.

ajdkfl6445.gitbook.io

반응형