본문 바로가기
MLOps

[Kubernetes, Container] MLOps를 위한 기본 - Container란? [1]

by ML_MJSHIN 2021. 10. 23.

 Introduction


  MLOps를 하기 위해서는 DevOps의 필수품이었던 Docker와 Kuberentes, Prometheus, Grafana 등이 거의 기본 소양이 되어가는 것 같습니다. 

 

 저는 아직은 AI 모델러의 역할에 익숙해서 하나하나 기초적인 책을 보면서 배워가고 있지만 이전에 포스팅 했던 Jenkins 를 통한 CI/CD 자동화도 하나씩 해보면서 배워가니 MLOps 쪽이 훨씬 더 재미있네요 ㅎㅎ

 

 앞으로 Jenkins, Argo를 통한 CI/CD와 Docker의 기초부터 시작해서 Kubernetes 그리고 MLOps (MLflow, AWS model serving ..) 까지 쭉 공부했던 내용과 지속적으로 몰랐던 것들을 채우면서 공부하는 지식들을 정리를 해보려고 합니다. 1일 ~ 2일에 한번은 포스팅을 해야 저도 열심히 공부하는 사람이 되는 것 같아서 정리가 부족해도 같이 공부해나가실 분들은 도움이 되지 않을까 합니다.

 

 우선은 이 모든 MLOps의 기본이 되는 Docker부터 시작을 하려고 합니다. 워낙 많은 자료들이 있지만 저는 개인적으로 "쿠버네티스 입문 90가지 예제로 배우는 컨테이너 관리 자동화 표준" 라는 책이 제일 좋았습니다. 인터넷에서 정보를 찾다보면 단편적으로만 정보가 있어서 흐름을 알고 공부하기가 어려운데 개념을 잡는데 매우 좋았습니다.

 

 자 그럼 컨테이너 이해의 시작chroot, cgroup 그리고 namespace부터 살펴보도록 하겠습니다.

Chroot


 쿠버네티스와 도커라고 하면 가장 많이 듣게되는 말 중 하나가 컨테이너 입니다. 그런데 컨테이너란 원래 리눅스에 있던 용어 입니다. 그래서 이 컨테이너가 무엇인지를 간단하게 정의하자면 '격리된 프로세스' 입니다. 즉, 격리된 프로세스를 리눅스에서 생성해내는 방법들인 '네임스페이스', cgroup, chroot 등의 방법은 격리된 프로세스를 생성할 수 있는 방법이기 때문에 컨테이너를 생성하는 방법 중 하나입니다. 

 

 그 중 리눅스, 유닉스 환경에는 원래 chroot 라는 명령어가 있었습니다. 'ch'(ange) + 'root' 라는 명령어로써 말 그대로 리눅스의 '/'인 root를 아래 명령어와 같이 다른 directory로 바꾸는 명령어입니다. 

# chroot '새로 root가 될 directory' '새 root를 기준으로 실행 할 프로세스'
mkdir -p /home/something/bin/
chroot /home/something /bin/bash

 그런데 root를 바꾼다는 것의 의미가 무엇일까요? 리눅스에서 각각의 프로세스는 자신이 접근할 수 있는 파일 시스템의 root를 알고 있습니다. 여기서 중요한 리눅스 시스템의 파일 구조를 하나 알고가야 합니다.

 root 디렉토리는 최상위를 의미하는 특별한 위치이며, 모든 디렉터리와 파일은 이 루트 디렉터리 아래에 존재합니다. CS 전공자 분들에게 익숙한 트리구조가 되는 것입니다. 

 

그런데, 이때 위의 그림과 같이 /home을 새로운 root로 chroot를 통해서 변경시킨 경우를 생각해 봐야합니다. 새로운 root를 자신의 root로 인식하고 있는 프로세스는 기존에 root에 접근할 수 있을까요? 

 

 새로운 프로세스는 회색 박스 내의 영역만을 인식하고 접근할 수 있게 됩니다. root라는 디렉토리는 최상위 폴더라고 인식하고 있으며 모든 디렉토리는 root 아래에 있다고 생각하고 작동하기 때문입니다.

 

 즉, chroot프로세스가 자신이 알고 있는 root에서 이를 통해 프로세스가 액세스 할 수있는 디렉토리를 제한하거나 시스템 라이브러리와 관련 라이브러리를 로드 할 수 있게 하기 때문에, 컨테이너인 격리 프로세스를 만들 수 있는 하나의 방법인 것입니다. 

 

 하지만 저희가 알고 있는 최신 컨테이너처럼 네트워크를 격리시키거나 프로세스를 제어하는 방법은 가지고 있지 않기 때문에 지금의 컨테이너와 완벽하게 같다고 할 수는 없습니다. 이러한 제약 사항을 조금 해결하기 위한 방법이 FreeBSD jail 입니다. 

 

 chroot를 통해서 파일 시스템을 나누고 이 나누어진 파일 시스템 (위 사진의 회색 박스 영역)을 jail이라고 칭합니다. 각각의 jail은 서로 독립적이고 영향을 미치지 않습니다. 그리고 한개의 서버에 여러 jail 을 만들고 각각 ip 주소를 할당할 수 있으며, jail 내부는 프로그램 입장에서 실제 시스템 (/ 을 root로 하는 시스템)과 구별 할 수 없어 여러 장점을 가집니다. 

 

 여기까지 리눅스의 컨테이너의 역사를 검색하면 나오는 가장 기본이 되는 chroot에 대해서 알아보았습니다. 

 

Cgroup


 Cgroup은 'control' + 'group'의 약자로 하드웨어 자원 (ex., cpu, ram, newtork, device, io)들을 group 별로 묶어 컨트롤하는 리눅스 커널의 기능입니다. 이때 group에 속하는 대상들은 프로세스입니다. 즉, 시스템에서 생성된 프로세스들은 모두 자신에게 정해진 cgroup에 속하며 프로세스가 사용하는 하드웨어 자원은 자신이 속한 cgroup의 통제를 받게 됩니다.

 https://tomatohj.tistory.com/39

 이러한 기능은 격리된 프로세스인 컨테이너가 OS의 모든 하드웨어 자원을 사용하는 것을 막을 수 있는 중요한 기능을 제공합니다. 

 


Namespace


 

 Namespace는 하나의 시스템에서 프로세스 별로 리소스 사용을 분리시키고자 하는 기능입니다. 그러나 cgroup처럼 하드웨어적으로 리소스를 분리 시키는 것이 아니라 OS 와 커널은 동일한 상태에서 그 위의 프로세스들 간의 격리가 이루어 집니다. 

 

 *하드웨어 가상화가 아닌 Linux 내의 자원을 가상화.  하드웨어 자원의 가상화는 cgroup*

 

조금 더 쉽게 표현하자면, 하나의 OS와 커널 위에서 프로세스들이 동작하는 이름이 다른 공간을 만들어, 프로세스를 분리하는 방법입니다. 아파트에서 각자 다른 호실에 사는 것과 유사하겠죠. 그렇기 때문에 다른 namespace에 존재하는 프로세스들은 서로 리소스 관리가 따로 이루어 집니다. 101 호가 주소를 100호로 바꾼다고 해도 102호, 103호 ... 는 아무런 영향이 없는 것처럼 말이죠. 

 

 네임스페이스에는 종류가 많이 있습니다.

  1. PID : 프로세스 ID를 격리시킬 수 있는 네임스페이스. 항상 1은 init 프로세스이지만 격리된 네임스페이스에서는 다시 1부터 프로세스 ID가 할당된다. (메인 프로세스 입장에서는 아니지만 .. 가상화 가상화!)
  2. Network : 프로세스의 네트워크 환경을 분리하는 네임스페이스. 분리된 네트워크 네임스페이스 내부의 프로세스들은 새로운 IP를 부여받거나 네트워크 인터페이스를 추가할 수 있습니다. 
  3. UTS :  호스트 네임과 NIS 도메인 네임을 격리하는 네임스페이스. 컨테이너 네트워크의 기초가 됩니다.
  4. MNT : 파일 시스템의 마운트를 격리하는 네임스페이스. 호스트 파일시스템에 구애받지 않고 자유롭게 파일 시스템을 마운트 혹은 언마운트가 가능하게 해줍니다.
  5. USR ......
  6. IPC .....

 위와 같은 기능들 하나하나가 컨테이너에서 매우 중요한 기능을 수행하고 있습니다. 하지만 설명드렸다싶이 네임스페이스는 하드웨어의 격리를 수행할 수 없으므로 cgroup, 네임스페이스 그리고 chroot 의 기능이 합쳐져야 저희가 docker를 통해서 실행시키고자 하는 컨테이너의 OS 위에서의 프로세스 별 격리가 잘 이루어질 수 있게 됩니다. (실제로 도커에서 chroot를 사용해 루트 디렉터리를 격리하지 않는다고 합니다. 그래도 원리를 이해하기 위해서 chroot를 볼 필요가 있다고 44bits.io 에서 ...)

 

* 도커의 컨테이너는 기본값으로 브릿지(L2) 네트워크를 사용합니다. 물론 이외에도 다양한 네트워크 인터페이스를 사용할 수 있습니다 *

* 도커의 컨테이너가 네트워크 통신을 하기 위해서는 namespace로 격리된 네트워크 설정에서 호스트 (서버 머신)의 eth와 격리된 컨테이너의 eth를 연결짓는 veth 쌍을 연결시켜줘야 합니다.  아래의 링크에서 이러한 방법에 대해 자세히  다루고 있으니 꼭 한번 읽어보세요 *

 

https://www.44bits.io/ko/post/container-network-2-ip-command-and-network-namespace

 

ip로 직접 만들어보는 네트워크 네임스페이스와 브리지 네트워크 - 컨테이너 네트워크 기초 2편

네트워크 네임스페이스는 프로세스 간의 네트워크를 격리해주는 매우 강력한 도구입니다. 리눅스에서는 ip를 사용해 네트워크를 조회하는 것 뿐만 아니라 네트워크 네임스페이스를 제어하는

www.44bits.io

 

 

 

컨테이너와 가상머신


 도커 컨테이너와 가상머신의 차이에 대해서 우선 정의를 명확히 하는 것은 필수적입니다. 

 어떠한 하나의 프로세스를 실행시키고자 할 때 가상 머신은 "운영체제 위에 하드웨어를 에뮬레이션하고 그 위에 가상 운영체제를 올리고 프로세스를 실행하는 방법"인 반면, 컨테이너는 "하드웨어 에뮬레이션 없이 OS와 리눅스 커널을 공유해서 바로 프로세스를 실행하는 방법" 이라고 설명할 수 있습니다. 

 

 리눅스의 컨테이너는 lxc(Linux Container)라고도 불리며, 앞서 배운 네임스페이스와 cgroup을 사용하여 각각의 프로세스를 서로 격리 시키고 샌드박싱하여 독립된 런타임 환경을 제공하는 기술을 의미합니다.

 

 샌드박싱이란 컨테이너 내부에서 실행되는 프로세스를 호스트로부터 격리시키는 것을 말합니다. 즉, 호스트 시스템에 의존하지 않고 프로세스가 돌아가게 하는 것을 의미합니다. 이를 통해 컨테이너는 도커와 결합되어 어플리케이션이 서로 다른 머신 환경에서도 동일하게 실행될 수 있음을 보장합니다.

 

 *책이나 블로그 들에서 이런식으로 표현을 하기도 하는 것을 기억해주세요.

  "호스트 OS의 리소스를 논리적으로 분리시키는 방법"*

 

정리


 여기까지가 Container의 기본 개념입니다. 물론 나중에는 더 깊이 있는 지식이 k8s를 운용하기 위해서 필요하지만 차근차근 포스팅으로 살펴보도록 하고 다음 포스팅에서는 kubernetes 의 기본 개념부터 살펴볼 예정입니다. 

 

 

References


https://teki.tistory.com/9

 

CI / CD / CT - MLOps와 DevOps 이해하기

DevOps와 MLOps에서 말하는 CI/CD/CT의 개념을 비교하여 MLOps에서 목표하는 바를 이해해보려고 한다. 목차 DevOps와 MLOps DevOps: Dev + Ops MLOps: ML + Ops DevOps와 MLOps에서 CI/CD/CT CI/CD/CT in DevOps C..

teki.tistory.com

https://iancoding.tistory.com/184

 

[Docker] 하이퍼 바이저, VM, 도커 컨테이너, 이미지

 도커를 사용할 때의 흐름 먼저 도커 CLI에 커맨드를 입력한다. 도커 서버(도커 Daemon)이 그 커맨드를 받아서 그것에 따라 이미지를 생성하든 컨테이너를 실행하든 모든 작업을 하게 된다. docker ru

iancoding.tistory.com

https://mangkyu.tistory.com/86

 

[Server] 가상화(Virtualization)란? (1/2)

1. 가상화(Virtualization)란? [ 가상화(Virtualization)란? ] 가상화란 가상화를 관리하는 소프트웨어(주로 Hypervisor)를 사용하여 하나의 물리적 머신에서 가상 머신(VM)을 만드는 프로세스이다. Hypervisor는..

mangkyu.tistory.com

https://dololak.tistory.com/351

 

[Docker] 도커 컨테이너(Docker Container)에 대한 이해

리눅스, 유닉스 환경에서의 컨테이너 도커 컨테이너를 이해하기 위해서는 먼저 리눅스 컨테이너를 이해할 필요가 있습니다. 리눅스, 유닉스 환경에는 chroot 명령이 있습니다. chroot를 간단히 설

dololak.tistory.com

https://subin-0320.tistory.com/28

 

[Docker] 6. 이미지 비밀 : 레이어

6.1 레이어의 개념 이미지 하나를 다운로드 받을 때 많은 레이어가 다운로드 된다. 이미지를 registry에 저장할 때 전체를 저장하는 것이 아닌 각각 나누어서 저장을 하는데, 나누어서 일치하는 데

subin-0320.tistory.com

https://admion.net/what-is-jail/

 

Jail 이란? - 어드미온

Jail 소개 FreeBSD jail 또는 jail 이라고 알려져 있는 이 기술은 FreeBSD 의 OS 레벨 가상화입니다. OS 레벨 가상화는 OS…

admion.net

https://www.44bits.io/ko/post/change-root-directory-by-using-chroot

 

컨테이너 기초 - chroot를 사용한 프로세스의 루트 디렉터리 격리

chroot는 프로세스의 루트 디렉터리를 변경하는 리눅스 시스템콜/명령어입니다. 루트를 변경함으로써 아주 기초적인 단계의 컨테이너를 구현해볼 수 있습니다. chroot는 아주 단순한 프로그램입니

www.44bits.io

https://www.44bits.io/ko/keyword/linux-namespace

 

리눅스 네임스페이스(Linux Namespace)란?

리눅스 네임스페이스는 프로세스를 실행할 때 시스템의 리소스를 분리해서 실행할 수 있도록 도와주는 기능입니다. 한 시스템의 프로세스들은 기본적으로 시스템의 리소스들을 공유해서 실행

www.44bits.io

https://www.44bits.io/ko/post/is-docker-container-a-virtual-machine-or-a-process

 

도커(Docker) 컨테이너는 가상 머신인가요? 프로세스인가요?

도커 컨테이너는 가상 머신과 비슷한 특징을 가지고 있습니다. 독립적인 파일 시스템 환경을 가지고 있고, 프로세스 아이디도 호스트와 다르고, 네트워크도 격리되어 있습니다. 하지만 분명 가

www.44bits.io