runc 사용하기

# runc 는 docker, kubernetes(k8s)등에서 사용하는 OCI(Open Container Initiative) 표준을 준수하는 container 기동(spawning and running) CLI 툴이다.

# golang 설치
wget https://go.dev/dl/go1.17.5.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local/ -zxf go1.17.5.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
go version

# runc 빌드 및 설치(최신 golang 버전 필요)
cd runc
make && sudo make install

# 일반유저(vagrant)도 docker 명령을 실행할 수 있게 vagrant 계정을 docker 그룹에 추가
# 한번 exit 하고 다시 로그인해야 한다.
sudo usermod -aG docker vagrant

# busybox 이미지의 파일시스템(파일들)을 tar 로 export
docker export $(docker create busybox) -o busybox_exported.tar

# root 계정으로 전환
sudo -Es

# container 에 압축 풀기
# runc 기동시 rootfs 이름의 디렉토리를 찾는다.
cd ~
mkdir -p ./ysoftman_container/rootfs
tar xvf busybox_exported.tar -C ./ysoftman_container/rootfs

# runc 에서 사용할 명세서 생성
# 기본 명세의 config.json 파일이 생성된다.
# spec -> create a new specification file
cd ysoftman_container
tree -L 2
runc spec
ls config.json

# runc 로 ysoftman1 이름의 컨테이너 기동
runc run ysoftman1

# ysoftman1 컨테이너에서 namespace 확인
ls -ahl /proc/$$/ns

# 호스트 터미널 하나더 열고 root 계정으로 전환
sudo -Es

# 호스트에서 runc 같와 runc 가 실행한 sh 프로세스가 확인
ps -ef | grep -E "runc| sh$"

# 호스트에서 
# runc 네임스페이스 확인
lsns -p $(ps -ef | grep -v grep | grep "runc run ysoftman1" | awk '{print $2}')

# ysoftman1컨테이너(runc)가 실행한 sh pid 로 namespace 상태 확인
lsns -p $(ps --ppid=$(ps -ef | grep -v grep | grep "runc run ysoftman1" | awk '{print $2}') -o pid | grep -v PID)

# 호스트에서 runc 로 기동된 컨테이너 리스트 보기
runc list

# 테스트 결과

# runc help
checkpoint  checkpoint a running container
create      create a container
delete      delete any resources held by the container often used with detached container
events      display container events such as OOM notifications, cpu, memory, and IO usage statistics
exec        execute new process inside the container
kill        kill sends the specified signal (default: SIGTERM) to the container's init process
list        lists containers started by runc with the given root
pause       pause suspends all processes inside the container
ps          ps displays the processes running inside a container
restore     restore a container from a previous checkpoint
resume      resumes all processes that have been previously paused
run         create and run a container
spec        create a new specification file
start       executes the user defined process in a created container
state       output the state of a container
update      update container resource constraints
features    show the enabled features

#####

# 위 golang, runc, busybox 준비되어 있는 상태에서
# rootless container 생성해 보기
# root 계정이라면 일반 계정으로 나오기
exit

# ysoftman_rootless_container 에 압축풀기
cd ~
mkdir -p ./ysoftman_rootless_container/rootfs
tar xvf busybox_exported.tar -C ./ysoftman_rootless_container/rootfs

# rootless 옵션으로 runc 에서 사용할 명세서 생성
cd ysoftman_rootless_container
runc spec --rootless

# /tmp/runc 를 루트로 하는 ysoftman_rootless_container 실행
runc --root /tmp/runc run ysoftman_rootless_container

# 컨터이너에서 user id 와 네임스페이스 확인
id
ls -l /proc/$$/ns

# 호스트에서
# 루트 경로 및 state.json 확인해보기
tree /tmp/runc
cat /tmp/runc/ysoftman_rootless_container/state.json | jq . | head -10

# 호스트에서 runc 같와 runc 가 실행한 sh 프로세스가 확인
ps -ef | grep -E "runc| sh$"

# runc 네임스페이스 확인
lsns -p $(ps -ef | grep -v grep | grep "runc run ysoftman_rootless_container" | awk '{print $2}')

# ysoftman1컨테이너(runc)가 실행한 sh pid 로 namespace 상태 확인
lsns -p $(ps --ppid=$(ps -ef | grep -v grep | grep "runc run ysoftman_rootless_container" | awk '{print $2}') -o pid | grep -v PID)

# user 네이스페이스 id 가 ysoftman_rootless_container 가 호스트와 다르다.
# ysoftman_rootless_container 의 root 로 보이지만 호스트의 root는 아니다.

# 테스트 결과

comments:

댓글 쓰기