RunC
May 13, 2021 v1.0CLI tool for spawning and running containers according to the OCI specification
- CLI (Command Line Interface) tool : runc는 커맨드라인툴 이구나
- spawning (산란하다) : 왜 spawn이라는 표현을 썼을까?
- process가 child를 만드는 전통적인 방법은 fork : 부모의 모든 것을 복제해서 만드는 방법
- fork의 단점은 모든 것을 물려주려다 보니 무겁다는 것 (오버헤드)
- 그리고 바로 exec 하는 경우(fork-exec) 복제한 걸 쓰지도 않아 너무도 아깝다는 것 (비효율)
- 그래서 fork-exec 보다 세밀한 조작과 선택적 복제를 지원하는 방법을 고안
- posix_spawn : fork-exec + 선택적 복제를 지원
- Container Spawning : 컨테이너를 (새로) “생성”의 의미
- Forking은 “복제”의 의미
- OCI (Open Container Initiative) Runtime Spec.
- 컨테이너 포맷과 런타임에 대한 개방형 산업 표준
- https://opencontainers.org/about/overview/
- runtime-spec : how to run a “filesystem bundle”
- OCI implementation —(download) —> OCI Image
- OCI Image —(unpack)—> OCI Runtime filesystem bundle
- OCI Runtime —(run)—> OCI Runtime filesystem bundle
- this entire workflow should support the UX users have come to expect from container engines (docker, rkt)
- image-spec
Release: https://github.com/opencontainers/runc/releases
Goal
- The goal of runc is to make standard containers available everywhere.
- runc의 목표는 어디서나 사용가능한 표준 컨테이너를 만드는 것이다.
Features
- Full support Linux namespaces including user namespaces
- Native support for all security features available in Linux —> If linux can do it, runc can do it
- Selinux
- Apparmor
- seccomp
- control groups
- capability drop
- pivot_root
- uid/gid dropping
- Native support for live migration, /w the help of the CRIU team at Parallels
- Native support for Windows 10 containers is being contributed directly by MS engineers
- Planned native support for Arm, Power, Sparc /w direct participation and support from Arm, Intel, Qualcomm, IBM, and the entire hardware manufacturers ecosystem.
- Planned native support for bleeding edge hardware features - DPDK, sr-iov, tpm, secure enclave, etc.
- Portable performance profiles, contributed by Google engineers based on their experience deploying containers in production.
- A formally specified configuration format, governed by the Open Container Project under the auspices of the Linux Foundation. In other words: it’s a real standard.
실습 준비
git 참고: https://github.com/opencontainers/runc
Pre-requisite (ubuntu 18.04 기준)
Golang 설치 (golang-go 13+)
curl -O https://storage.googleapis.com/golang/go1.15.7.linux-amd64.tar.gz > /dev/null 2>&1
tar xf go1.15.7.linux-amd64.tar.gz
sudo mv go /usr/local/
echo "PATH=$PATH:/usr/local/go/bin" | tee ~/.bash_profile
source ~/.bash_profile
gcc 설치
sudo apt update && sudo apt install gcc
make 설치
sudo apt install make
pkg-config 설치
sudo apt install pkg-config
pkg-config: exec: "pkg-config": executable file not found in $PATH
libseccomp-dev 설치
sudo apt install libseccomp-dev
seccomp (secure computing mode) ? 리눅스 보안 메커니즘. linux sandbox 기반 “시스템콜 허용/차단”
git clone (runc)
git clone https://github.com/opencontainers/runc
Build
sudo -Es
cd runc
make
make install
Test
make test
- test 를 돌리려면 docker 설치 필요
- 일반 계정에서 수행하려면 docker 그룹 권한 필요
실습
Creating an OCI Bundles
mkdir /mycontainer
cd /mycontainer
mkdir rootfs
docker export $(docker create busybox) | tar -C rootfs -xvf -
runc spec
cat config.json
- docker export
- docker create
- runc spec : create a new “specification file” : The spec command creates the new specification file named “config.json” for the bundle.
Running Containers
cd /mycontainer
runc run mycontainerid
- runc run : create and start a container
/w lifecycle operations
vi config.json
### . . .
"terminal": false,
### . . .
"args": [
"sleep", "5"
]
### . . .
cd /mycontainer
runc create mycontainerid
runc list
runc start mycontainerid
runc list
runc delete mycontainerid
- create, start, stop, delete 등 lifecycle 단계를 구분: 상위 시스템에서 쉽게 각 단계 사이에 로직 삽입 가능
- 예) 네트웍 셋업을 컨테이너의 생성과 기동 사이에 처리
Rootless containers
root 권한 없이도 “일반 계정으로 컨테이너를 생성”
mkdir ~/mycontainer
cd ~/mycontainer
mkdir rootfs
docker export $(docker create busybox) | tar -C rootfs -xvf -
runc spec --rootless
runc --root /tmp/runc run mycontainerid
확인
cat /proc/sys/kernel/unprivileged_userns_clone
echo 1 > /proc/sys/kernel/unprivileged_userns_clone
supervisor
vi /etc/systemd/system/runc.service
[Unit]
Description=Start my container
[Service]
Type=forking
ExecStart=/usr/local/sbin/runc run -d --pid-file /run/mycontainerid.pid mycontainerid
ExecStopPost=/usr/local/sbin/runc delete mycontainerid
WorkingDirectory=/mycontainer
PIDFile=/run/mycontainerid.pid
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
### 적용 및 리스타트
systemctl daemon-reload
systemctl start runc.service
- config.json: terminal mode를 false 해줄 것
vi config.json
### . . .
"process": {
"terminal" : false
}
### . . .