More Related Content
Similar to OCIランタイムの筆頭「runc」を俯瞰する (20)
More from Kohei Tokunaga (9)
OCIランタイムの筆頭「runc」を俯瞰する
- 1. Copyright(c)2019 NTT Corp. All Rights Reserved.
OCIランタイムの筆頭「runc」を俯瞰する
2019/9/24
日本電信電話株式会社
ソフトウェアイノベーションセンタ
徳永 航平
Container Runtime Meetup #1
- 3. Copyright(c)2019 NTT Corp. All Rights Reserved.
Pod
Containers
3
Container Runtime Meetup #1
kubelet
いろいろなランタイムやその標準仕
様(CRI、OCI)に関する情報交換
トラブルシューティングに役立ちそ
う な カ ー ネ ル 周 辺 知 識 の 共 有
ランタイムへのコードレベルの理解
この周辺について
語り合うMeetupです。
・・・
第一 回 は輪 読 的に 発 表者 を 回し てい き ま す
発 表 の ス タ イ ル に つ い て は 、 自 由 で す
形式については今後も柔軟に改善していきます
- 4. Copyright(c)2019 NTT Corp. All Rights Reserved. 4
いろいろなコンテナランタイム
kubeletからCRI(Dockerの場合はdockershim)
経由でPod作成等の指示を受ける。
ネットワーク設定、イメージの送受信等担当
コンテナ作成にOCIランタイム使用(使い分け可)。
高レベルランタイム/Dockerの指示でコンテナ作成。
標準仕様としてOCI Runtime Specがある。
セキュリティ等の目的で、様々なランタイムが実行環
境の隔離手法を提案しており群雄割拠。 Pod
低レベルランタイム
(OCIランタイム)
実行
kubelet
高レベルランタイム
(CRIランタイム)
高レベル(CRI)ランタイム
低レベル(OCI)ランタイム
runc
Kata Containers
gVisor
Nabla Containers
Containers
CRI/
dockershim
unix
socket
…
…
拙過去資料P4より(一部改訂):https://www.slideshare.net/KoheiTokunaga/ss-123664087
- 6. Copyright(c)2019 NTT Corp. All Rights Reserved. 6
Open Container Initiative. “The 5 principles of Standard Containers”, https://github.com/opencontainers/runtime-
spec/blob/master/principles.md
The 5 principles of Standard Containers
②Content-agnostic①Standard Operations
作成、削除等標準の操作
が定義されており、標準
の ツ ー ル を 使 用 可 能 。
中 身 に か か わ ら ず
Standard Operationは同
様 の 効 果 を 持 つ 。
③Infrastructure-
agnostic
④Designed
for automation
⑤Industrial-grade
delivery
OCIでサポートされるど
のインフラストラクチャ
上 で も 動 作 す る 。
中身やインフラに関わら
ずStandard Operationを
持つので自動化しやすい。
これら性質を最大限活用
することでデリバリパイ
プラインを自動化できる。
?
by Open Container Initiative
- 7. Copyright(c)2019 NTT Corp. All Rights Reserved. 7
OCI Runtime Specification
FileSystem Bundleの定義
プロセスkill
コンテナのライフサイクルや可能な操作等を定義した標準仕様
create
kill
delete
Operationsの定義
コンテナ削除
start
コンテナ実行
隔離環境作成
ライフサイクル
の定義
コンテナのrootfsディレクトリ
実行時環境の定義ファイル(spec)
state、create、
start、kill、delete
Open Container Initiative. “Open Container Initiative Runtime Specification”,
https://github.com/opencontainers/runtime-spec/blob/master/spec.md
実行時環境のconfig
環境変数、実行コ
マンド、ユーザ…
隔離方法は定義されない
namespace・cgroup等での隔離
が一般的だがVMやUserspace
kernelやunikernelでも良い。実際
にいくつかランタイム実装がある。
- 8. Copyright(c)2019 NTT Corp. All Rights Reserved. 8
OCIランタイムの筆頭「runc」
OCIによるOCIランタイムのリファレンス的実装。
統計は無いがたぶんコンテナを使う人ほぼ全員が使っていると思う。
Linuxのリソース分離やセキュリティ機能を活用してプロセスの実行環境隔離を実現。
前身は、Dockerの一部だったlibcontainerで、DockerがOCP(現OCI)発足の際に譲渡。
namespaces
PID、UTS、IPC、マウ
ントポイント、ネット
ワ ー ク 、 ユ ー ザ 、
cgroupsについてシス
テムのリソースを隔離
各コンテナごとに見える
ファイルシステムを制限
pivot_root
Linuxの
セキュリティ機能
memory,cpu,cpuset,
pids…などのハード
ウェアリソースを各コ
ンテナに対し制限可能
AppArmor,SELinux,s
eccompを用いてコン
テナの動作を制限可能
runc
process
runc
Host kernel
直近約1年のコミット数推移
cgroups
[Open Container Initiative. “Open Container Initiative Runtime Specification”. https://github.com/opencontainers/runtime-spec/blob/master/spec.md;
runc Contributors. “Container Specification - v1”. https://github.com/opencontainers/runc/blob/master/libcontainer/SPEC.md]
[https://github.com/opencontainers/runc]
[https://github.com/opencontainers/runc/graphs/commit-activity]
2019.9.17取得
拙過去資料P15より(一部改訂):https://www.slideshare.net/KoheiTokunaga/ss-123664087
- 9. Copyright(c)2019 NTT Corp. All Rights Reserved. 9
runcのrunサブコマンドに注目
OCI Runtime Specで定義された
operation等がサブコマンドとして実装されている
create startstate kill delete ・・・
$ mkdir -p bundle/rootfs
$ tar xf rootfs.tar -C bundle/rootfs
$ runc spec -b bundle
# runc run --bundle bundle demo1
# runc kill demo1 KILL
(# runc delete demo1)
FileSystem Bundle作成
コンテナの作成実行
コンテナの停止削除
サブコマンドrun
operationのうち、createとstart
を同時に行えるコマンド。
spec fileとrootfsが配置された
Filesystem bundleを渡して実行。
端末まわりなどの難しいところを
考えずに手元でインタラクティブ
にruncを操作するのに便利。
実装としてはcreateとstartの組
み合わせなので、コンテナ作成の
流れを俯瞰するruncコード読みの
題材にちょうど良い。
- 11. Copyright(c)2019 NTT Corp. All Rights Reserved. 11
紹介するファイル
func main() {
・・・
app := cli.NewApp()
・・・
app.Commands = []cli.Command{
checkpointCommand,
createCommand,
deleteCommand,
eventsCommand,
execCommand,
・・・
if err := app.Run(os.Args)・・・
サ
ブ
コ
マ
ン
ド
実
装
ユ
ー
テ
ィ
リ
テ
ィ
等
var runCommand = cli.Command{
Name: "run",
・・・
Action: func(context・・・
本稿ではrunc 1.0.0-rc-8を参照
main.go
init.go
run.go
utils_linux.go
libcontainer
container_linux.go
process_linux.go
factory_linux.go
init_linux.go
init_linux.go
nsenter
nsenter.go
standard_init_linux.go
/
核
と
な
る
コ
ン
テ
ナ
操
作
用
ラ
イ
ブ
ラ
リ
↑namespace分離処理
main.go サブコマンド群の登録
run.go runサブコマンドの実装
以降runCommandから追ったrunサブコ
マンド実装の要点をピックアップする
- 12. Copyright(c)2019 NTT Corp. All Rights Reserved. 12
runc runの流れ
runc init実行
runc run
runc init
Entrypoint
command
exec
libcontainer
隔離環境
1
隔離環境初期化2
Entrypoint
実行指示・実行
3
- 13. Copyright(c)2019 NTT Corp. All Rights Reserved.
runc run側
*runnerrunCommand
*linuxContainer*initProcess
*Cmd
13
1. libcontainerでrunc init実行
Action()
run()
container
Run()
Start()
start()
type: libcontainer.Container
start()
cmd type: *exec.Cmd
Start()
Path =“/proc/self/exe”
=[]string{os.Args[0], "init"}Args
func (p *initProcess) start() error {
・・・
err := p.cmd.Start()
specのロード
linuxContainer作成
linuxContainer実行
runc initを実行する
ためのexec.Cmdと
通信用FIFOを作成
runc initコマンドの実行
run.go utils_linux.go
libcontainer/container_linux.golibcontainer/process_linux.go
os/exec
runcを指している
*initProcess
.start()
*runner.container.Run()
*runner.run()
*Cmd.Start()
メソッド(一部)
フィールド
(一部)
構造体名
- 14. Copyright(c)2019 NTT Corp. All Rights Reserved.
LinuxFactoryinitCommand
*linuxStandardInit
14
2. runc initで隔離環境の初期化
Action() StartInitialization()
Init()
config
既にnamespaceの中
rootfsの準備・NW設定など実行環境を初期化した後、Entrypoint実行の指示を待つ
type: libcontainer.initConfig
func (l *linuxStandardInit) Init() error {・・・
if err := prepareRootfs(l.pipe, l.config);
・・・
fd, err := unix.Open(fmt.Sprintf(“/proc/self/fd/%d”, l.fifoFd)・・・
反対側のFIFOのopenを待つ
_ "github.com/opencontainers/runc/libcontainer/nsenter"
init.go
go runtimeに先んじてcgoで書いたnamespace分離処理を実行
libcontainer/nsenter/nsenter.go
#cgo CFLAGS: -Wall
extern void nsexec();
・・・init(void) {
nsexec();・・・
init.go libcontainer/factory_linux.go
libcontainer/standard_init_linux.go
LinuxFactory
.StartInitia
lization()
*linuxStandardInit.Init()
runc init側
fifoFd type: int
- 15. Copyright(c)2019 NTT Corp. All Rights Reserved.
Init()
libcontainer/standard_init_linux.go
*linuxContainer
15
3. runc runからrunc initにentrypoint実行指示
exec()
*linuxStandardInit
func (l *linuxStandardInit) Init() error {・・・
fd, err := unix.Open(fmt.Sprintf(“/proc/self/fd/%d”, l.fifoFd)・・・
・・・
if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil {
Entrypointをexecする
①でrunc initを実行した直後に自身のexec()メソッドを実行する
func awaitFifoOpen(path string) <-chan openResult {
fifoOpened := make(chan openResult)
go func() {
f, err := os.OpenFile(path, os.O_RDONLY, 0)・・・
FIFOをopenする
runc init側
libcontainer/container_linux.go runc run側
Entrypoint実行の指示(FIFOのopen)を待っていた
config type: libcontainer.initConfig
fifoFd type: int
initConfig
Args
Env
Cwd
Capabilities
・・・
libcontainer/init_linux.go
- 17. Copyright(c)2019 NTT Corp. All Rights Reserved. 17
まとめ
プロセスkill
create
kill
delete
コンテナ削除
start
コンテナ実行
隔離環境作成
ライフサイクル
の定義
OCI Runtime Spec.
runc run
runc init
Entrypoint
command
exec
libcontainer
隔離環境
今回の
注目サブコマンド
1
2
3
runc run