# 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
# 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는 아니다.
# 테스트 결과