Docker 공부를 하다보면 어떻게 컨테이너 기술이 VM보다 손실없이 사용할 수 있는지 의문점이 들 것이다. 이는 기존에 리눅스에서 지원하는 namespace, cgroup, Union Mount 등의 기술을 활용했기 때문이다.
하지만 해당 개념을 공부하기에는 많은 시간이 들기 때문에 많은 사람들은 chroot로 간접 체험을 해보는 것을 추천하고 있다. 비록 chroot는 컨테이너 기반 기술은 아니지만 컨테이너 환경을 이해하는데 많은 도움이 되기 때문이다.
그래서 이번 글에서는 chroot로 컨테이너 환경을 간접 체험을 해볼 것이다.
chroot(Changing root & Change the root directory)는 1979년에 나온 기능으로 컨테이너 기반 기술인 namespace, cgroup, Union Mount등의 기능들이 있지만 가장 오래되고 기본이 되는 프로세스가 실행되는 루트를 변경하는 일을 수행한다.
chroot를 /bin 디렉토리에서 실행하면 A를 root(/) 디렉토리를 기반으로 한 독립적인 /bin/bash 프로세스가 생성된다.
이를 통해 프로세스 bash는 bin 디렉토리보다 상단에 있거나 형제 디렉토리들을 접근할 수 없다. 실제로 chroot를 실행하면 /bin 디렉토리 외부에서 제공하는 기본 기능들도 사용할 수 없다.
이렇게 독립적인 프로세스가 생성되기 때문에 실제로 우리가 하는 컨테이너와 유사한점을 가지고 있다.
chroot 실습
실습환경은 최대한 동일환경에서 동작하기 위해 ubuntu 컨테이너에서 진행한다.
(대부분의 리눅스 배포판에서 설치 없이 바로 사용해볼 수 있기 때문에 ubuntu 외 환경에서도 가능하다.)
docker run -d --name chroot ubuntu:20.04
docker exec -it chroot
chr=~/chroot
mkdir -p $chr # chroot로 접근할 폴더 생성
chroot ~/chroot /bin/bash # chroot 디렉토리에서 chroot 명령어 실행
chroot: failed to run command ‘/bin/bash’: No such file or directory
~/chroot 디렉토리에서 chroot 명령어를 사용하려고 했지만 chroot 폴더에 /bin/bash가 없다는 에러 메세지를 출력하고 있다.
위 같은 문제를 해결하기 위해 ldd, egrep 명령어를 사용하여 chroot 디렉토리에 해당 폴더들을 복사해온다.
mkdir -p $chr/{bin,lib,lib64}
cd $chr
cp -v /bin/{bash,ls,sleep} $chr/bin
list="$(ldd /bin/bash | egrep -o '/lib.*\\.[0-9]')"
for i in $list; do cp -v --parents "$i" "${chr}"; done
list="$(ldd /bin/ls | egrep -o '/lib.*\\.[0-9]')"
for i in $list; do cp -v --parents "$i" "${chr}"; done
list="$(ldd /bin/sleep | egrep -o '/lib.*\\.[0-9]')"
for i in $list; do cp -v --parents "$i" "${chr}"; done
chroot $chr /bin/bash
이제 정상적으로 bash, ls, sleep 명령어를 실행할 수 있다.
이처럼 chroot는 컨테이너와 유사한점이 많으며 실제로 컨테이너 기반 기술인 namespace와 중복되는 느낌을 받을 수 있다.
그러나 실제로 chroot는 파일 시스템 레벨에서만 독립시킬뿐이지 이외의 레벨에서는 분리시키지 못하기 때문에 그 점에서 차이가 있다.
(namespace 같은 경우에는 파일 시스템 레벨과 함께 모든 레벨(가상 머신을 돌리는 듯한 수준)에서 분리시킨다.)
그 차이를 자세하게 이해하기 위해 sleep 명령어를 통해 알아보겠다.
chroot내에서 sleep, 우분투 ps 조회
→ 실제로 chroot 환경에서 sleep 명령을 실행하면 우분투 환경에서도 확인할 수 있다.
즉, 프로세스 관점에서는 독립적이지 않다는 것을 알 수 있다.
우분투 내에서 sleep, 로컬 ps 조회
→ namespace가 적용된 내 로컬 환경에서는 우분투 컨테이너의 sleep 명령을 찾을 수 없다.
실제 컨테이너 환경에서는 호스트로부터 프로세스가 독립적으로 분리된 것을 확인할 수 있다.
'DevOps' 카테고리의 다른 글
쿠버네티스 패키지 매니저 Helm (0) | 2022.08.17 |
---|---|
Skaffold와 Cloud Code (0) | 2022.07.04 |
Kubernetes Context 적용방법 (0) | 2022.06.28 |
Minikube 환경에서 NodePort 사용하기 (0) | 2022.05.21 |
Docker Image와 Dockerfile로 알아보는 Image Layer (0) | 2022.04.03 |