2017年1月10日火曜日

runC で docker の hello-world のイメージを動かしてみた

概要

runC は OCI を実装したコンテナのランタイムです
要するにコンテナを動かすことができるものです
docker でコンテナを動かす場合に普通は docker のデーモンがバックグランドで動作していて、それに対して docker コマンドでコンテナを動かします
runC があれば docker デーモンが動作してない状態でも docker コンテナを動かすことができるようになります

環境

  • go 1.6.3
  • runc 1.0.0-rc2
  • CentOS 7.3.1611
  • Docker 1.12.5

事前準備

今回は CentOS7 上で作業します
runC を動作させるのに go の実行環境が必要です
また、docker コンテナを export するために docker が動作する環境も必要です (必須ではないですが、あったほうが良いです)

CentOS7 であれば go も docker も yum でインストールできるので事前にインストールしてください

  • yum -y install golang
  • go version
  • mkdir $HOME/go
  • export GOPATH=$HOME/go

runC のインストール

ソースコードからコンパイルしてインストールする必要があります
コンパイルに必要なライブラリがあるので、事前にインストールしておきます

  • yum -y install git libseccomp-devel
  • mkdir -p $GOPATH/src/github.com/opencontainers
  • cd $GOPATH/src/github.com/opencontainers
  • git clone https://github.com/opencontainers/runc
  • cd runc
  • make
  • make install
  • runc -v

docker コンテナのエクスポート

docker で一度コンテナを動作させてそれをエクスポートします
このエクスポートしてできたファイルやディレクトリを使って runC でコンテナとして動作させます
そして今回は docker の入門として提供されている hello-world を使ってみます

  • mkdir runc-test
  • cd runc-test
  • docker pull hello-world
  • docker run --name hw1 hello-world
  • docker export -o hello-world.tar hw1
  • tar xvf hello-world.tar
  • rm hello-world.tar

これで runc-test 配下に以下のファイルとディレクトリができていれば OK です

# ls runc-test/
dev  etc  hello  proc  sys

runC でコンテナを動かす

では、エクスポートしたファイルとディレクトリを元に docker コンテナを動作させてみます
当然ですが docker デーモンは不要なので停止します

  • systemctl stop docker.service

そして runC でコンテナを動かすために必要になる config.json というファイルを生成します
手動でも作成することができますが、コマンド一発で雛形を出力することができるので使わせてもらいます

  • runc spec

これで config.json というファイルができれば OK です
で、雛形を若干編集します
編集した箇所の diff は以下の通りです

18c18
<                       "sh"
---
>                       "./hello"
40c40
<               "path": "rootfs",
---
>               "path": "/root/runc-test",

18 行目は実行するコマンドを指定します
今回の hello-world は sh や bash はインストールされていません
エクスポートしたファイルを見るとわかりますが、「hello」というバイナリがおいてあるだけだと思います
なので、sh ではなく hello を実行するように修正します

40 行目はエクスポートしたコンテナのファイルやディレクトリがあるパスを指定します
runC の公式のチュートリアルでは rootfs というディレクトリ配下で作業する感じなので rootfs になっていますが、今回は別の名前のディレクトリにエクスポートしたので、そのパスをフルパスで指定します

これで OK です
ちなみに編集しない状態の config.json で実行しようとすると

  • rootfs (/root/runc-test/rootfs) does not exist
  • container_linux.go:247: starting container process caused "exec: \"sh\": executable file not found in $PATH"

というエラーが出力されると思います
また、runC は本記事を執筆時の段階で 1.0.0 ではありますが、まだまだ開発中だし containerd という別プロジェクトも始まったので今後変更が入る可能性が大です
特に config.json の内容は変わる可能性が高いので、diff の内容が異なる場合があるので注意してください

前置きが長くなりましたが config.json を hello-world コンテナ用に書き換えたら起動してみます

  • runc run hw1

run というコマンドでコンテナを起動します
実行するカレントディレクトリ内で config.json を自動で検索して実行します
最後の「hw1」はコンテナの名前です

実行に成功すると hello-world の内容が出力されると思います

最後に

runC で hello-world の docker コンテナを動作させてみました
コンテナの動作に必要なファイルやディレクトリがあればコンテナを起動することができるので、docker デーモンがない環境でもコンテナを起動することができます

今回は sh や bash が動作しないコンテナだったのでコンテナのプロセスを確認することができなかったので次は Web アプリなどのコンテンを動かしてみたいと思います

あとは記事の中でも少し触れましたが、containerd という別のプロジェクトが誕生したのでそれも踏まえて今後 runC がどうなるかは気になるところです

参考サイト

0 件のコメント:

コメントを投稿