재형이의 성장통 일지
  • 컨테이너의 역사와 기술
    2023년 12월 29일 11시 40분 44초에 업로드 된 글입니다.
    작성자: 재형이
    반응형
    • 최근에 CKA 공부를 하면서 컨테이너 기술에 대해서 관심을 가지게 되었고,
    • 그래서 정리를 해보게 되었습니다.

    컨테이너의 등장

    • IT 발전이 가속화됨에 따라 시장도 빠르게 커졌습니다. 빠르게 변화하고 커지는 자본주의 시장에서 살아남기 위해서는 빠르게 개발하고 배포하는 것이 중요해졌습니다. 그와 함께 클라우드 컴퓨팅 기술이 발전하면서 수개월이 걸리던 시스템 구성을 몇 분안에 끝낼 수 있는 시대가 되었습니다.
    • 이처럼 가상화 기술이 점점 발전을 하게 되고 기존에 동일 서버에서 모든 프로세스가 실행되던 방식에서 분산된 환경에서 프로세스가 독립적으로 실행되는 방식으로 개발 방향이 바뀌기 시작했습니다. 그리고 2013년 Docker (컨테이너를 빌드, 배포, 실행, 업데이트, 관리할 수 있는 오픈 소스 플랫폼) 가 등장하면서 IT 시장에 큰 변화가 찾아오게 되었습니다.
    • 기존에 사용하던 가상화 방식인 하이퍼바이저 방식에 비해 컨테이너는 호스트의 자원을 그대로 공유하기 때문에 오버헤드가 줄어들고 빠른 실행을 가능케 하였습니다.

    KVM : 하이퍼바이저 기반 리눅스 커널 가상 머신

    • 컨테이너를 사용하게 되면 성능 손실이 Native에 비해 단 1% 밖에 차이가 나지 않습니다. 미쳤죠?
    • 이것이 컨테이너 기술의 가장 큰 장점 입니다.

    컨테이너를 구성하는 리눅스 기술

    • 이러한 컨테이너 기술을 가능하게 해주는 것이 리눅스 커널의 cgroups, namespaces, union mount filesystem 입니다.

    1. cgroups (Control Groups)

    • cgroups(Control Groups)는 자원(resources)에 대한 제어를 가능하게 해주는 리눅스 커널의 기능입니다. cgroups는 다음 리소스를 제어할 수 있습니다
      • cpu : 해당 cgroup 에 속한 프로세스 CPU 사용 시간을 제어
      • memory : 해당 cgroup에 속한 프로세스의 메모리 사용량에 대한 제어
      • freezer : cgroup의 작업을 일시 중지하거나 다시 시작
      • blkio : cgroup에 블록 장치에 대한 입력/출력 제한을 설정
      • net_cls : Linux 트래픽 컨트롤러 (tc)가 특정 cgroup 작업에서 발생하는 패킷을 식별하게 하는 클래식 식별자 (classid)를 사용하여 네트워크 패킷에 태그를 지정
      • cpuset : 개별 CPU 및 메모리 노드를 cgroup에 할당
      • cpuacct : cgroup이 사용한 CPU 자원에 대한 보고서를 생성
      • devices : cgroup의 작업 단위로 장치에 대한 액세스를 허용하거나 거부
      • ns : namespace 서브시스템

    1-1. cgroups으로 cpu 사용량 제어해보기

    • /sys/fs/cgroup/cpu 에 폴더를 만들면 자동으로 하위에 설정할 때 필요한 파일들이 생성이 된다.
    • tasks 에는 해당 프로세스의 PID를 입력해주면 된다.

    • stress의 cpu 사용률이 10%로 제어되고 있는 것을 확인할 수 있다.

    2. namespaces

    • 프로세스를 격리시킬 수 있는 리눅스 커널의 기능입니다.
      • mnt (파일시스템 마운트): 호스트 파일시스템에 구애받지 않고 독립적으로 파일시스템을 마운트하거나 언마운트 가능
      • pid (프로세스): 독립적인 프로세스 공간을 할당
      • net (네트워크): namespace간에 network 충돌 방지 (중복 포트 바인딩 등)
      • ipc (SystemV IPC): 프로세스간의 독립적인 통신통로 할당
      • uts (hostname): 독립적인 hostname 할당
      • user (UID): 독립적인 사용자 할당

    2-1. namespaces 로 독립적으로 파일시스템 마운트해보기

    • 네임스페이스로 파일시스템을 독립적으로 마운트한 후에 파일을 생성하게 되면 외부에서는 해당 파일을 확인할 수 없습니다. 하지만 nsenter 명령어를 통해 내부로 들어가서 확인하게 되면 확인할 수 있습니다.

    3. union mount filesystem

    • 하나의 마운트된 공간에 새로운 마운트를 걸게 된다면 이전에 마운트되어 있던 파일들의 내용들을 확인할 수 없게 될 것이다.
    • union mount filesystem 이란 하나의 마운트 공간에 여러 개의 마운트를 걸었을 때 하나의 통합된 폴더처럼 보이게 하는 기술이다.
    • Docker에서는 이 기술을 사용해서 이미지 레이어들을 관리하고 있다.
      (overlay 파일시스템 사용)

    • 마지막 레이어를 제외하고 Read Only 하게 설정이 되어 있어서 변경된 부분만 이미지 레이어에 저장할 수 있다.

    3-1. union mount filesystem을 지원하는 overlay 파일 시스템 실습해보기

    • 마운트된 공간에 파일을 생성하면 RW 로 되어있는 upperdir 로 파일이 생성이 된다. lowerdir 은 읽기 전용이다.

    컨테이너 런타임의 표준화

    • 2013년 Docker가 등장하면서 사실상 표준화로 자리매김을 하였습니다. 초기 Docker에서는 LXC(Linux Containers)를 통해 리눅스 커널의 cgroups와 namespaces로 여러개의 독립된 컨테이너가 운영될 수 있도록 하였습니다.
    • 하지만 Dokcer에서 컨테이너 기술의 핵심적인 부분들을 LXC와 같은 외부 솔루션을 통해 다루다 보니 자체적인 인터페이스에 대한 요구가 생기게 되었고, libcontainer 를 개발하게 되었습니다.

    - OCI (Open Container Initiative) 의 등장

    • 초기 Docker는 컨테이너 기술에 대한 하나의 완성된 컨테이너 사용자 경험을 제공해주기 위해 모놀리식한 구조로 설계가 되었지만 버전을 업그레이드할 때마다 불가피한 코드 수정이 빈번하게 일어나는 문제가 발생하게 되어 컨테이너 런타임을 분리하게 되는 작업을 하게 되었습니다.
    • 다양한 IT 벤더사에서 컨테어너 런타임 개발에 참여하게 되었고, 그렇다 보니 Container Runtime들끼리의 이식성 및 호환성에 대한 문제가 대두되기 시작하였습니다. 그렇게 표준화를 위한 OCI Linux Foundation 프로젝트가 시작되었고 OCI 표준이 만들어지게 되었습니다. OCI 표준을 따르는 대표적인 컨테이너 런타임이 runc 입니다.

     

    - CRI (Container Runtime Interface) 의 등장

    • OCI 표준이 탄생하고 여러 기업에서 Container Runtime들이 탄생하게 되었고, Container의 선두주자였던 Kubernetes(2014년 구글 발표)는 Docker뿐만 아니라 여러 Container Runtime을 지원하게 되었습니다.
    • Kubernetes에서는 Kubelet을 통해 Container Runtime을 관리하였는데 다양한 Container Runtime들이 생겨나면서 Kubelet의 유지보수에 대한 어려움이 발생하기 시작하였습니다.
    • 따라서 등장한 것이 여러 컨테이너 런타임을 지원하기 위한 CRI 표준이 등장하게 되었습니다.
    • 쿠버네티스는 CRI로 컨테이너 런타임과 통신하는데 도커는 해당 인터페이스를 지원하지 않아 Dockershim이라는 추가 레이어를 통해 연동하였습니다. 또한 도커의 기능 중 쿠버네티스가 사용하는 부분은 컨테이너 런타임 정도 입니다. 결국 쿠버네티스는 v1.20 이후의 버전에서는 Dockershim이 deprecated 되었습니다.

    • Docker에서 개발한 컨테이너 런타임이 containerd 입니다.

    - CRI-O (Container Runtime Interface - Open Container Initiative) 의 등장

    • Docker는 클라이언트/서버 구조로 클라이언트인 Docker Cli 와 서버인 Docker daemon 으로 구성됩니다. 그 중 서버는 컨테이너 이미지 빌드, 관리, 공유, 실행 및 컨테이너 인스턴스 관리와 같이 너무 많은 기능을 담당하기에 너무 무겁고, 단일 실패지점을 제공하는 부분에서 문제점으로 지적되었습니다.
    • 그렇게 OCI 가 만들어진 후 레드햇, 인텔, SUSE, Hyper, IBM 등의 커뮤니티 중심의 오픈소스 프로젝트인 CRI-O 를 개발하였고 별도의 데몬 없이 전통적인 fork·exec 모델을 사용하는 Buildah, Podman, Skopeo 가 등장하게 되었습니다. 각각은 Docker engine 혼자하던 업무들을 분담하는 역할을 합니다. Buildah 는 이미지 빌드, Podman 은 컨테이너를 유지하고 관리, Skopeo 는 이미지 저장소에서 다양한 역할을 수행합니다.

     
    → 이렇게 컨테이너 런타임들이 모놀리식한 구조에서 분리되어 나오면서 가벼워지게 되었고, 이는 컨테이너의 빠른 실행으로 이어지게 되었습니다.

     

    전체적인 흐름 한눈에 보기 - 컨테이너의 역사

     

    마무리

    • CKA 는 시험이 실습으로 진행이 되기 때문에 시간 안에 빠르게 문제를 푸는 연습만 하다가 이론적인 내용들을 추가적으로 공부를 하다보니 왜 컨테이너 기술을 사용하는지에 대해서 좀 더 이해를 할 수 있게 되었습니다.
    • 앞으로는 자격증 취득도 좋지만 이론적인 부분도 놓치면 안될 것 같다는 생각이 들었습니다.

     
    다들 새해 복 많이 받으세요~!!!

    반응형
    댓글