observe_db

[OS] 13. 컨테이너(Container) 본문

학교 공부/운영체제(OS)(3-1)

[OS] 13. 컨테이너(Container)

쩡윤 2023. 6. 6. 01:31

6/1
 
Part 1.
리눅스 컨테이너

  • 동일한 운영체제 상에서 독립된 실행환경 생성
  • 단일 운영체제 상에서 프로세스 격리
  • 자원의 오버해드를 줄이고 격리된 상태로 실행할 수 있게 함

가상머신(virtual machine)

  • 독립된 운영체제를 통해 독립된 환경 구성

하이버바이저(hypervisor)

  • 호스트 컴퓨터에서 여러 운영체제를 동시 실행하기 위한 논리적 플랫폼
  • 게스트 운영체제에 가상 운영 플랫폼을 제공하여 게스트 운영체제 관리

 

  • 유형 1 하이퍼바이저(Native/Bare-metal hypervisor)
    • 호스트 HW에서 직접 실행되어 HW 제어 및 게스트 가상머신 관리
    • Xen, Oracle VM Server for SPARC/x86
  • 유형 2 하이퍼바이저
    • OS 위에 하이퍼바이저 설치
    • VMware, VirtualBox, Pallels Desktop for Mac

 
컨테이너(container)

  • 어플이 실행되는 격리된 공간(isolated space)
  • 자체 네임스페이스(namespace)를 보유하여 실행
    • 별도의 프로세스 공간, 네트워크 공간
  • 내부 애플리케이션과 서비스를 root권한으로 실행 가능
  • 호스트 운영체제 사용
  • 컨테이너 내부의 프로세스는 호스트 운영체제에서 확인 가능
  • 애플리케이션 수행에 필요한 라이브러리 등을 포함하여 다른 컨테이너 및 일반 애플리케이션과 무관하게 실행
  • Linux 커널에서 지원하는 기능을 사용하여 구현
  • 격리 및 리소스 관리 기술이 적용된 프로세스

리눅스 컨테이너는 리눅스 OS에 설치

  • chroot jail
    • 초창기 시도된 시스템 격리 기법
    • 사용자가 볼 수 있는 root를 사용자의 home directory 등으로 지정
    • 사용자는 해당 root 아래 공간에서만 필요한 라이브러리 등을 접근
    • 타 사용자의 라이브러리 등에 대한 접근 불가

 
리눅스 컨테이너 아키텍처

  • namespace, cgroup 등의 기능을 사용하여 컨테이너 지원
  • 이름 충돌X & 자원 분배


 

  • Namespaces
    • 컨테이너별로 별도의 네임스페이스 제공 => 프로세스 실행시 격리(Isolation) 환경 제공
    • 컨테이너에 속한 프로세스들 간의 리소스 사용 등에서 충돌 방지
  • cgroup(control group)
    • 프로세스들의 그룹핑 제공
    • CPU, 메모리, 네트워크 전송폭 등 컴퓨팅 리소스 사용 자원 배분
  • SELinux(Security Enhanced Linux)
    • 호스트 시스템과 컨테이너, 서로 다른 컨테이너 사이를 보안적으로 안전한 분리 기능 제공
  • Management Interface
    • 커널에서 제공하는 컨테이너 지원 컴포넌트의 접근 제공
    • 컨테이너의 생성 및 관리 인터페이스 제공
    • LXC(Linux containers, docker

 
네임스페이스(namespace, 이름공간)

  • 다양한 객체를 식별하거나 지칭하기 위해 사용되는 기호 또는 이름들의 집합
  • 네임스페이스에서 각 객체는 고유한(unique) 이름 보유
    • 하나의 네임스페이스에서는 하나의 이름이 단 하나의 개체 지칭
  • 개체를 구분할 수 있는 범위
  • 이름의 충돌 방지를 위해 네임스페이스 사용
  • 사례
    • 파일 시스템: 파일 이름
    • 프로그래밍 언어: 변수/함수의 이름
    • 컴퓨터 네트워크 및 분산 시스템: 컴퓨터, 프린터, 웹사이트, 원격 파일 등의 이름
    • 운영체제: 컨테이너 지원을 위한 고립된 네임스페이스 사용
  • 자원을 랩핑(wrapping)하여 다른 프로세스들에게는 격리시켜 특정 프로세스의 사적(private) 공간에 있는 것처럼 보이도록 하는 것
  • 프로세스는 자신에게 주어진 자원 (CPU, 메모리, HDD)에 대해서만 알고 실행
  • 프로세스는 특정 네임스페이스에서 실행하는 것을 알지 못함
  • 다양한 네임스페이스 존재
    • Mount(mnt)
      • 파일시스템 마운트 포인트 분리
      • 부모 프로세스와 자식 프로세스가 각각 다른 파일시스템 마운트 포인트 보유 가능
    • Process ID(PID)
      • 서로 다른 컨테이너에서 동작하는 프로세스의 동일한 PID 보유 가능
    • Interprocess Commnication(ipc)
      • 두 개의 컨테이너가 동일한 이름을 갖는 공유 메모리 세그먼트(Shared memory segment)와 세마포어 생성 가능
    • Network(net)
      • 컨테이너가 분리되고 독립된 네트워크 스택(network stack, 네트워크 프로토콜 구현), 루프백 장치, 프로세스 공간 사용 가능
    • User
      • 사용자 ID, 그룹 ID, 루트 디렉토리 등 보안 관련 ID와 속성 분리
      • 프로세스의 네임스페이스 내부와 기본 네임스페이스 간에 각기 다른 사용자 및 그룹 ID 사용 가능
      • 외부에서는 루트 권한이 없는 프로세스가 자신이 생성한 컨테이너에서는 루트 권한으로 실행 가능
    • Unix Time Sharing(uts)
      • 각 컨테이너의 별도 호스트명과 NIS(Network Information Service) 도메인 이름 보유 가능
    • Cgroup(Control group)
    • Time(time)

 
Part2.
도커(docker)

  • Linux 컨테이너를 만들고 사용할 수 있도록 하는 컨테이너화 기술
  • Linux 커널과 함께 Cgroups 및 네임스페이스와 같은 커널의 기능을 사용하여 프로세스를 분리함으로써 독립적 실행

런타임(runtime)

  • 특정 언어로 만든 프로그램을 실행할 수 있는 환경
  • Node.js
    • 자바스크립트 프로그램을 컴퓨터에서 실행할 수 있게 하는 자바스크립트 실행기
    • Chrome V8 JavaScript 엔진으로 빌드 된 JavaScript 런타임
    • JavaScipt를 서버에서도 사용할 수 있도록 만든 프로그램
    • Docker
      • 컨테이너 실행 런타임


docker

  • 사용자가 docker engine으로 다양한 명령을 요청할 떄 사용하는 CLI 클라이언트 프로그램
  • Docker CLI를 통해 수행된 명령은 REST API wrapper를 통해 docker daemon에 전달
  • unix domain socket, fd, tcp 방식으로 docker daemon에 접속

docker-init

  • 컨테이너 내에서 init 프로세스의 역할을 하는 프로세스
    • child process를 받아주어 resource의 누수나 zombie process의 생성 등 방지
  • 특정 컨테이너 실행 시 --init 옵션을 주면, docker-init 프로세스가 PID 1번으로 시작, 컨테이너는 자식 프로세스로 생성
  • --init 옵션이 없이 실행되는 해당 컨테이너가 PID 1을 가지게 됨.

docker-proxy

  • 컨테이너의 포트(port)와 호스트 컴퓨터의 포트를 연결해주는 port fowarding 지원
  • docker host 내부의 container 간의 통신은 docker()라는 bridge를 통해 기본적으로 가능
  • 외부와 docker-proxy 사이의 통신: 8080/tcp 사용
  • docker-proxy와 container 간의 통신: 내부 bridge docker() 사용


 
dockerd

  • volume, image, networking 관리, orchestration 관장 및 처리
  • 클라이언트로부터 REST API 형식의 요청을 수신하여 처리

containerd

  • 컨테이너의 lifecycle 관리
  • client로부터의 container 관리관련 요청은 dockerd를 거쳐 gRPC 통신을 통해 containerd로 전달
  • 컨테이너의 관리를 위해 컨테이너 실행 환경 runC 사용

docker engine

  • dockerd와 containerd를 함께 부르는 호칭
  • docker service를 맨 처음 시작하면 기동되는 daemon process
  • docker.service를 start하면 docker daemon이 자동으로 containerd 기동

client의 container 관리 관련 요청 전달 과정


 
도커의 libcontainer

  • 과거 docker는 LXC(linux container)나 libvirt등 중간 매게체(driver, library)를 통해 커널의 가상화 관련 요소를 간접적으로 사용
  • 도커에서 별도로 커널의 가상화 기술을 다루기 위해 개발한 인터페이스

runC

  • 시스템에서 container 관련된 기능들에 대해 도커가 쉽게 사용할 수 있도록 해주는 가볍고 이식 가능한 container runtime
  • 커널의 container 관련 기술을 다루기 위해 표준인 OCI(Open COntainer Initiative) 준수

docker run을 통한 container 기동요청의 처리 과정

  • dockerd는 요청을 gRPC를 통해 containerd로 전달
  • containerd는 exec을 통해 containerd-shim을 자식 프로세스로 생성
  • containeerd-shim은 runc를 이용하여 container 생성(runc는 container가 정상적으로 실행되면 exit)
  • containerd-shim은 그대로 살아있으며, 이는 container 내에서 실행되는 process들의 부모 역할

containerd-shim의 필요성

  • daemonless container 지원
    • 컨테이너 하나 뜬다고 해서 계속 수행되는 runtime daemon은 불필요
    • containerd-shim은 껍데기나 마찬가지
  • 컨테이너를 위한 STDIO 및 fd의 계속 유지
    • dockerd와 containerd가 둘다 죽게되는 상황이 되면 pipe의 한쪽이 닫혀서 컨테이너까지 죽을 수 있는데 이를 방지
    • dockerd의 장애 상황의 컨테이너까지의 전파 방지
  • 컨테이너의 exit status 등을 higher level tool로 보고 가능
    • containerd-shim ->runc->container인 상황에서 runc의 exit
Comments