도커 없이 컨테이너 만들기 - 2

전날의 Ifkakao2022 이게 돼요? 도커 없이 컨테이너 만들기 세션을 이어서 2시간 20여분의 핸즈온을 마무리헀다.

 


# 요약

패키징 저장 중복 문제를 해결하기 위한 방법 중 하나인 리눅스 Overlay Filesystem을 사용하는 이유와, 이를 마운트하는 과정을 실습하며 세션을 이어갔다. - 1:07:12

 

진행했던, myroot와 tools 디렉토리를 LowerDir로 두고, 별도의 디렉토리를 통해 UpperDir, WorkDir 및 Merged View를 지정하여 오버레이 마운트를 진행했다.

 

mount -t overlay overlay -o lowerdir=tools:myroot,upperdir=rootfs/container,workdir=rootfs/work rootfs/merge

 

이러한 코드를 통해서 rootfs/merge 디렉토리를 오버레이 마운트 포인트로 지정하고, LowerDir, UpperDir 등을 지정하여 오버레이 마운트를 수행할 수 있다.

 

rootfs/merge/ 내부의 파일을 삭제해보면서, Linux CoW 보장을 확인을 할 수 있었다.

 

이후 세션의 앞 단원을 마무리하며, 지금까지 진행한 내용을 정리해주셨다.

 

  1. 컨테이너 전용 루트파일 시스템을 mount namespace & pivot_root를 통해서 제공한다.
  2. 이미지 중복 문제를 Overlay Filesystem을 통해서 해결한다.

어제는 컨테이너에 필요한 격리가 해결된 줄 알았지만, 아직 호스트 시스템과 컨테이너 간의 추가적인 격리가 필요하고, 컨테이너 자원 보장(할당)에 대한 문제가 남아있음을 상기시켜 주셨다.

 

이후 세션의 두 번째 챕터로 넘어갔다.


컨테이너의 격리와 자원

초기의 컨테이너(어제의 나)는 전용 루트파일 시스템을 제공하는 것으로 충분하다 생각했지만, 다른 문제들이 남아있었다.

 

  1. 컨테이너에서 호스트의 다른 프로세스들을 조회할 수 있음 - PID 공유
  2. 컨테이너에서 호스트의 포트를 사용함. - 네트워크
  3. 컨테이너에 루트 권한이 있음. - USER 공유

즉, 마운트 네임스페이스를 통해 마운트 포인트를 호스트에 격리하여 컨테이너 전용 파일시스템을 제공하는 것만으로 충분하지 않았다.

 

설명할 네임 스페이스들이 개발되기 시작하면서 이런 문제를 해결할 수 있었다.

 


 

네임 스페이스(Linux)

네임 스페이스는 다음의 특징을 가진다.

  • 모든 프로세스는 타입별로 네임스페이스에 속한다.
  • 자식 프로세스는 부모의 네임스페이스를 상속한다.

리눅스 시스템에서 네임 스페이스를 조회하기 위해선 여러 방법이 있는데,

 

ls -al /proc/$$/ns

readlink /proc/$$/ns/{네임스페이스 명}

lsns -p {PID #}

lsns -t {NS Type} -p {PID #}

 

이 중 lsns 또는 readlink을 통해서 Namespace의 I-Node 값을 통해 비교하는 것이 가능하다.

 

이 중 하나를 보면,

init 프로세스의 마운트 네임스페이스에 대한 정보

 

호스트 시스템의 1번 프로세스(init 프로세스)의 mount 네임스페이스에 대해서 조회한 결과이다.
네임스페이스 번호가 I-Node로 제공되고, Type, PID 등이 제공된다.

추가로, NPROCS를 통해서 해당 네임스페이스에 속한 프로세스의 개수를 제공한다.

세션에서는 리눅스 시스템에 존재하는 네임 스페이스들 중 컨테이너 격리를 위해 사용된 네임스페이스에 대한 역사와 함께 각각의 네임스페이스가 갖는 기능과 역할을 확인하며 실습을 진행했다.

 

결론부터 얘기하면, UTS, IPC, PID, User, Network + Mount 네임스페이스를 분리하여 컨테이너의 격리가 가능했다.

요약은 다음과 같다.

네임 스페이스 구분 설명 비고
Mount Namespace 마운트 포인트 격리 전용 파일 시스템 제공
UTS(Unit Time Sharing) Namespace hostname, domain name 격리 호스트 네임 분리
IPC(Inter-Process Communication) Namespace IPC 격리 .
PID(Process ID) Namespace PID Number Space 격리 호스트 프로세스 정보 격리
Network Namespace 네트워크 스택 가상화 및 격리 네트워크 분리
USER Namespace UID/GID Number Space 격리 루트 권한 제거

 

이 중에서 중요했던 네임스페이스(Mount NS 제외)는 PID, Network, USER 네임스페이스였다.

 

네트워크는 당연히 중요하고, PID와 USER Namespace의 경우 부모 - 자식 관계를 기반으로 중첩된 구조를 갖는데, 이들은 프로세스와 직접적으로 연관되어 있으므로, 네임스페이스를 통해 아직 해결하지 못했던 격리를 수행한다.

 

추가적으로 PID 1 프로세스가 갖는 의미를 확인할 수 있었고, /proc 디렉토리에 대한 이해를 수행할 수 있었다.

/proc 디렉토리
- 메모리 기반의 가상 파일시스템이다. 커널이 만든다.
- proc 파일 시스템을 만들어 놓으면(마운트까지 하면), 커널이 관리하는 시스템 정보를 proc 파일 시스템에 write하게 된다.
- ps or mount, umount 명령어를 수행할 때, proc 파일 시스템을 통해 명령어들이 실행된다.
- 시스템 모니터링과 분석에 활용한다.

 

네트워크 네임스페이스를 직접 생성하고 veth를 생성하고 연결하며 직접 1:1 통신을 실습하였고, PID와 USER 네임스페이스를 격리하여 실습했다.

 


Cgroups

이후 자원 할당에 대한 챕터로 넘어가서 Cgroup에 대한 이해와 실습을 직접 수행할 수 있었다.

 

Cgroup은 Control-Group의 약자로, 구글이 만들어서 리눅스 재단에 기여했다. 이를 사용하여 컨테이너 별로 자원을 분배하고 할당량 내에서 운용하는 것을 가능하게 했다.

 

Cgroup은 CPU나 메모리 같은 시스템 자원에 대한 그룹을 생성하여 해당 그룹마다 할당량을 지정할 수 있고, 프로세스를 해당 그룹에 포함시킴으로써, 할당량을 적용시키는 방법을 사용한다.

 

cgruop-tools와 stress 패키지를 통해서 Cgroup을 생성하고 자원을 제한하여 이를 확인했다.

/sys/fs/cgroup/cpu or /sys/fs/cgroup/memory 등의 디렉토리에 실제로 Cgroup이 할당하는 자원들에 대한 정보를 확인하고 설정한다는 점을 이해할 수 있었다.

직접 Cgruop 없이 Stress를 수행한 결과와, 아닌 결과를 통해, 생각보다 간단하게(?) 자원을 할당하는 것이 가능한 것을 확인했다.

 

CPU 사용량 제한 없이 테스트
CPU 사용량 30% 제한

 

각각 자원 제한을 걸지 않은, CPU 사용량을 30% 제한한 후의 스트레스 결과이다.

 

요약은, 

  • 리눅스는 Cgroup 파일시스템으로 리소스를 관리한다.
  • 제어 그룹 생성 - cgcreate
  • 제어 그룹 리소스 설정 - cgset
  • 제어 그룹 프로세스 할당 - cgexec

이를 통해 제한이 가능하다.

이후 단원을 마무리하며 최종 핸즈온 전 정리를 수행했다.

 

 

chroot -> mount ns(파일시스템만으론 격리가 안됨) -> uts, ipc(이름 붙이는 것 부터) - pid ns, cgruops(자원 할당) - network ns(호스트와 독립된 네트워크 + 가상 장치 사용) - user ns(루트권한 문제를 해결한)(2012) - docker(2013) - k8s(2015)

 


도커 없이 컨테이너 만들기

목표는 다음과 같았다.

RED & BLUE CTN을 만든다. 

  • 두 컨테이너는 cgroup으로 자원을 할당
  • 네트워크를 연결해서 서로 통신 가능

Ifkakao 2022 이게 되요? 도커 없이 컨테이너 만들기 영상 중

 

과정을 종합하면, 다음과 같았다.

 

  • 컨테이너에 마운트할 오버레이 이미지(패키지)를 준비
  • 네트워크 네임스페이스를 통해 컨테이너가 사용할 가상 장치 등을 구성
  • Cgroup을 생성 및 할당
  • 각 네임스페이스를 격리하여 프로세스를 실행
  • 프로세스에 Cgruop을 적용
  • Overlay Mount를 통해 컨테이너 전용 공간을 생성
  • pivot_root를 통해서 이를 루트 파일 시스템으로 전환
  • 기존 파일 시스템의 정보를 삭제

 

위의 과정을 거쳐 호스트 시스템과 격리된 환경을 갖는 컨테이너(프로세스)를 만들 수 있었다.

 

RED 컨테이너는 따라가면서 같이 만들고, BLUE 컨테이너는 과정을 참고하여 직접 수행했다.

 

혹시 몰라, BLUE CTN을 생성하는 명령어를 남긴다.

# Cgroup 생성 및 설정
mkdir /sys/fs/cgroup/cpu/blue;
mkdir /sys/fs/cgroup/memory/blue;

echo 40000 > /sys/fs/cgroup/cpu/blue/cpu.cfs_quota_us;
echo 209715200 > /sys/fs/cgroup/memory/blue/memory.limit_in_bytes;
echo 0 > /sys/fs/cgroup/memory/blue/memory.swappiness;

# BLUE CTN 격리하여 실행
unshare -m -u -i -fp nsenter --net=/var/run/netns/BLUE /bin/sh;

# BLUE Cgroup 적용
echo "1" > /sys/fs/cgroup/cpu/blue/cgroup.procs;
echo "1" > /sys/fs/cgroup/memory/blue/cgroup.procs;

# 오버레이 파일시스템 준비
mkdir -p /bluefs
mkdir -p /bluefs/container
mkdir -p /bluefs/work
mkdir -p /bluefs/merge

# 오버레이 파일 시스템 마운트
mount -t overlay overlay -o lowerdir=/tmp/tools:/tmp/myroot,upperdir=/bluefs/container,workdir=/bluefs/work /bluefs/merge

# pivot_root 준비
mkdir -p /bluefs/merge/put_old;

# pivot_root 실행
cd /bluefs/merge;
pivot_root . put_old;

cd /;

# put_old 삭제
mount -t proc proc /proc;
umount -l put_old;
rm -rf put_old;

# hostname 변경
hostname BLUE;

 

이 코드를 그대로 사용할 수 없고, 네트워크 네임스페이스 설정과 LowerDir 부분은 생략되어 있으므로 참고만 하시길 바란다.

 

두 개의 컨테이너를 동작시킨후 통신 테스트와 Stress 테스트를 통하여, 1:1 통신과 Cgruop으로 자원 할당이 정상적으로 이루어졌음을 확인하면서, 마무리 정리를 수행해주시고 핸즈온은 마무리되었다.

 

호스트 네임의 분리
프로세스 확인
1:1 통신 확인
Cgroup 테스트
메모리 할당량 초과 시 발생하는 dmesg


# 후기 및 정리

카클스 수료 이후 일주일 밖에 안지났지만, 제대로 공부하려고 하니 힘들었다.

 

2시간 20분 세션을 이틀에 걸쳐 7시간 정도에 걸쳐 듣게 되었고, 이게 내가 너무 오래걸리나.. 싶었던 느낌을 받긴 했다.

 

말씀하시는 대부분의 내용을 기록하다 보니깐 오래걸린 것 같은데, 쓴 시간은 전혀 아깝지 않았다.

 

부족했던 OS와 리눅스 시스템에 대한 설명을 추가적으로 진행해주시는데, 이런 정보를 제공받을 수 있었던 점만 해도 값진 시간이었다.

 

세션을 요약하면 특정 컨테이너 런타임에 대해서보단, 컨테이너를 동작시키기 위해 리눅스 환경에서 사용되는 기반 기술들을 설명하고 직접 실습한다.

 

이를 이해하기 위한 기초 지식을 같이 설명해주시지만, 처음 접하면 많이 버벅일 수 있을 것 같았다. 본인도 여러번 다시 들으면서 이해하기 위해 노력하며 7시간...

 

네트워크에 대한 깊은 이해가 필수적임을 다시한번 깨닫고, 운영체제와 리눅스 시스템에 대해서 다시한번 정리하는 시간을 가져야겠다는 다짐을 하면서 후기를 마친다.

 

빛 SAM

 


 

전날 진행한 학습 내용을 아래에서 확인할 수 있다.

 

 

도커 없이 컨테이너 만들기 - 1

본 포스팅은 2022 Ifkakao 이게 돼요? 도커 없이 컨테이너 만들기를 바탕으로 작성되었다. if(kakao)dev2022 함께 나아가는 더 나은 세상 if.kakao.com 현재 대부분의 어플리케이션은 컨테이너 형태로 동작

alive-wong.tistory.com

 

728x90
반응형