개요
이전에 학습했던 아래 3가지 주제를 이용하여 도커 없이 완전히 격리된 통신 가능한 컨테이너를 구축
목표
•
네트워크 네임스페이스 격리에서 이용했던 RED, BLUE 컨테이너 구축
•
생성된 컨테이너는 cgroup으로 자원 할당
•
컨테이너 간에는 네트워크 연결로 통신 가능
•
new_root (Lower Dir 1)와 tools (Lower Dir 2)로 오버레이 파일 시스템을 구축
◦
new_root는 그대로 활용
◦
tools += ping, stress, hostname, umount
Image
new_root
new_root 이미지 레이어는 이전 실습에서 구성해둔 것을 그대로 활용
tools
ping
# 명령어 파일 위치 확인
which ping
# 명령어 파일 복사
cp /usr/bin/ping /tmp/tools/usr/bin/
# 명령어 의존 파일 확인
ldd /usr/bin/ping
# 명령어 의존 파일 복사
# linux-vdso.so.1는 가상 라이브러리라서 실제로는 존재하지 않는 파일
cp /lib/x86_64-linux-gnu/libcap.so.2 /tmp/tools/lib/x86_64-linux-gnu/
cp /lib/x86_64-linux-gnu/libidn2.so.0 /tmp/tools/lib/x86_64-linux-gnu/
cp /lib/x86_64-linux-gnu/libc.so.6 /tmp/tools/lib/x86_64-linux-gnu/
cp /lib/x86_64-linux-gnu/libunistring.so.2 /tmp/tools/lib/x86_64-linux-gnu/
cp /lib64/ld-linux-x86-64.so.2 /tmp/tools/lib64/
# 디렉토리 구조 확인
tree /tmp/tools
Shell
복사
stress
# 명령어 파일 위치 확인
which stress
# 명령어 파일 복사
cp /usr/bin/stress /tmp/tools/usr/bin/
# 명령어 의존 파일 확인
ldd /usr/bin/stress
# 명령어 의존 파일 복사
# linux-vdso.so.1는 가상 라이브러리라서 실제로는 존재하지 않는 파일
cp /lib/x86_64-linux-gnu/libm.so.6 /tmp/tools/lib/x86_64-linux-gnu/
cp /lib/x86_64-linux-gnu/libc.so.6 /tmp/tools/lib/x86_64-linux-gnu/
cp /lib64/ld-linux-x86-64.so.2 /tmp/tools/lib64/
# 디렉토리 구조 확인
tree /tmp/tools
Shell
복사
hostname
# 명령어 파일 위치 확인
which hostname
# 명령어 파일 복사
cp /usr/bin/hostname /tmp/tools/usr/bin/
# 명령어 의존 파일 확인
ldd /usr/bin/hostname
# 명령어 의존 파일 복사
# linux-vdso.so.1는 가상 라이브러리라서 실제로는 존재하지 않는 파일
cp /lib/x86_64-linux-gnu/libc.so.6 /tmp/tools/lib/x86_64-linux-gnu/
cp /lib64/ld-linux-x86-64.so.2 /tmp/tools/lib64/
# 디렉토리 구조 확인
tree /tmp/tools
Shell
복사
umount
# 명령어 파일 위치 확인
which umount
# 명령어 파일 복사
cp /usr/bin/umount /tmp/tools/usr/bin/
# 명령어 의존 파일 확인
ldd /usr/bin/umount
# 명령어 의존 파일 복사
# linux-vdso.so.1는 가상 라이브러리라서 실제로는 존재하지 않는 파일
cp /lib/x86_64-linux-gnu/libmount.so.1 /tmp/tools/lib/x86_64-linux-gnu/
cp /lib/x86_64-linux-gnu/libc.so.6 /tmp/tools/lib/x86_64-linux-gnu/
cp /lib/x86_64-linux-gnu/libblkid.so.1 /tmp/tools/lib/x86_64-linux-gnu/
cp /lib/x86_64-linux-gnu/libselinux.so.1 /tmp/tools/lib/x86_64-linux-gnu/
cp /lib64/ld-linux-x86-64.so.2 /tmp/tools/lib64/
cp /lib/x86_64-linux-gnu/libpcre2-8.so.0 /tmp/tools/lib/x86_64-linux-gnu/
# 디렉토리 구조 확인
tree /tmp/tools
Shell
복사
Network
이전 실습 때와 동일하게 구성 (일부 명령어 축약식으로 변경)
# 네트워크 네임스페이스 추가
ip netns add RED
ip netns add BLUE
# veth0, veth1을 생성하면서 netns 연결
ip link add veth0 netns RED type veth peer name veth1 netns BLUE
# RED 네임스페이스 ip 주소 할당 및 활성화
ip netns exec RED ip addr add dev veth0 11.11.11.2/24
ip netns exec RED ip link set veth0 up
# BLUE 네임스페이스 ip 주소 할당 및 활성화
ip netns exec BLUE ip addr add dev veth1 11.11.11.3/24
ip netns exec BLUE ip link set veth1 up
# RED, BLUE의 IP 주소 확인
ip netns exec RED ip l
ip netns exec BLUE ip l
Shell
복사
cgroup
컨트롤 그룹 생성
# root 소유의 cpu,memory를 대상으로하는 red 컨트롤 그룹 생성
cgcreate -a root -g cpu,memory:red
cgcreate -a root -g cpu,memory:blue
# 조회
ls /sys/fs/cgroup/red/
ls /sys/fs/cgroup/blue/
Shell
복사
자원 제한
# cgset 대신 파일에 직접 쓰기도 가능
# cpu 42%, 메모리 42MB 설정
# RED
echo 42000 > /sys/fs/cgroup/red/cpu.max
echo 44040192 > /sys/fs/cgroup/red/memory.max
cat /sys/fs/cgroup/red/cpu.max
cat /sys/fs/cgroup/red/memory.max
# BLUE
echo 42000 > /sys/fs/cgroup/blue/cpu.max
echo 44040192 > /sys/fs/cgroup/blue/memory.max
cat /sys/fs/cgroup/blue/cpu.max
cat /sys/fs/cgroup/blue/memory.max
Shell
복사
컨테이너 실행
네임스페이스 격리
# 터미널 1) mnt, uts, ipc, pid, net를 격리한 RED 컨테이너 (User 격리는 nsenter와 동시에 사용이 잘 안 되는 듯)
unshare -m -u -i -fp nsenter --net=/var/run/netns/RED /bin/sh
# 터미널 2) mnt, uts, ipc, pid, net를 격리한 BLUE 컨테이너 (User 격리는 nsenter와 동시에 사용이 잘 안 되는 듯)
unshare -m -u -i -fp nsenter --net=/var/run/netns/BLUE /bin/sh
Shell
복사
cgroup 할당
# /sys/fs/cgroup/<group>/cgroup.procs 경로에 pid를 추가하면 프로세스를 컨트롤 그룹에 붙일 수 있음
# pid가 격리된 환경에서의 컨테이너의 프로세스는 1번 pid를 가지므로, 이를 추가
# 터미널 1) RED
echo "1" > /sys/fs/cgroup/red/cgroup.procs
cat /sys/fs/cgroup/red/cgroup.procs
# 터미널 2) BLUE
echo "1" > /sys/fs/cgroup/blue/cgroup.procs
cat /sys/fs/cgroup/blue/cgroup.procs
Shell
복사
OverlayFS
마운트가 격리된 상태에서 오버레이 파일 시스템을 구성하여 마운트
호스트에서는 마운트한 것으로 보이지 않을 뿐더러, 이를 이용하여 pivot_root 시 오버레이 파일 시스템을 / 경로로 취급하게 만드는 것이 가능
RED
# 디렉토리 생성
mkdir /redfs
mkdir /redfs/container
mkdir /redfs/work
mkdir /redfs/merge
# 디렉토리 구조 조회
tree /redfs
# 오버레이 파일 시스템 마운트
mount -t overlay overlay -o lowerdir=/tmp/tools:/tmp/new_root,upperdir=/redfs/container,workdir=/redfs/work /redfs/merge
# 오버레이 파일 시스템 구조 조회
tree /redfs/merge
Shell
복사
BLUE
# 디렉토리 생성
mkdir /bluefs
mkdir /bluefs/container
mkdir /bluefs/work
mkdir /bluefs/merge
# 디렉토리 구조 조회
tree /bluefs
# 오버레이 파일 시스템 마운트
mount -t overlay overlay -o lowerdir=/tmp/tools:/tmp/new_root,upperdir=/bluefs/container,workdir=/bluefs/work /bluefs/merge
# 오버레이 파일 시스템 구조 조회
tree /bluefs/merge
Shell
복사
pivot_root
새로운 루트는 오버레이 파일 시스템을 구성한 마운트 포인트 (RED - /redfs/merge, BLUE - /bluefs/merge)
반드시 마운트 포인트에서 pivot_root를 실행하고, 생성했던 put_old는 기존 루트로 전환됨에 따라 umount로 완전 제거
umount 사용을 위해선 꼭 pivot_root 이후 proc을 마운트 하는 과정 필요
unshare로 pid 격리하는 과정에서 --mount-proc을 사용하는 경우 /etc/mtab이 꼬이면서 mount, umount가 정상 동작하지 않아서 pivot_root 이후 직접 마운트 필요
RED
# put_old 생성
mkdir -p /redfs/merge/put_old
# 마운트 포인트로 이동 후, pivot_root
cd /redfs/merge
pivot_root . put_old
# 루트 전환 확인
cd /
ls /
ls put_old
# /proc 디렉토리 생성
mkdir /proc
# /proc 디렉토리 proc 마운트
mount -t proc proc /proc
# https://man7.org/linux/man-pages/man8/umount.8.html
# put_old를 언마운트, -l은 lazy 옵션으로 네트워크 파티션으로 인한 상태 이상 혹은 서버 종료로 멈추는 것을 방지
umount -l put_old
# https://stackoverflow.com/questions/17591975/delete-mounting-directory-after-umount-l
# 언마운트한 경로는 삭제 가능
rm -rf put_old
Shell
복사
BLUE
# put_old 생성
mkdir -p /bluefs/merge/put_old
# 마운트 포인트로 이동 후, pivot_root
cd /bluefs/merge
pivot_root . put_old
# 루트 전환 확인
cd /
ls /
ls put_old
# /proc 디렉토리 생성
mkdir /proc
# /proc 디렉토리 proc 마운트
mount -t proc proc /proc
# https://man7.org/linux/man-pages/man8/umount.8.html
# put_old를 언마운트, -l은 lazy 옵션으로 네트워크 파티션으로 인한 상태 이상 혹은 서버 종료로 멈추는 것을 방지
umount -l put_old
# https://stackoverflow.com/questions/17591975/delete-mounting-directory-after-umount-l
# 언마운트한 경로는 삭제 가능
rm -rf put_old
Shell
복사
프로세스 및 호스트 네임 확인
# RED, BLUE 각 컨테이너에서
ps -ef
hostname
Shell
복사
통신 확인
# RED -> BLUE
ping 11.11.11.3
# BLUE -> RED
ping 11.11.11.2
Shell
복사
리소스 확인
CPU
# RED, BLUE 각 컨테이너에서
# 설정한 임계치 42% 내로 부하 걸리는 것 확인 가능
stress -c 1
Shell
복사
Memory
# RED, BLUE 각 컨테이너에서
# Memory
stress --vm 1 --vm-bytes 41M
Shell
복사
결론
위 과정을 통해 도커처럼 동작하는 도커 없는 컨테이너를 구성
별도 스크립트를 구성하여 딸깍으로 컨테이너 만들도록 작성해보면, 내용이 추가 될 때마다 반영하면서 개선할 수 있을 것으로 보임