LoginSignup
139
131

More than 5 years have passed since last update.

「Docker」と新コンテナランタイム「rkt」をサクっと比較してみる

Last updated at Posted at 2015-06-22

概要

この記事では、アプリケーションコンテナのランタイムであるDockerとrktについて、
2つの大まかな違いを説明し、Dockerとrktそれぞれを使用してコンテナの取得・作成・起動・破棄など基本的なコンテナ操作を実施してみます。
記事全体として「Dockerはある程度知ってるけど、それに比べてrktってどうなんだ?」というトーンで書いています。

Dockerとは

公式:https://www.docker.com/

Docker社が開発しているオープンソースのコンテナランタイムです。
コンテナ技術自体は決して新しくはないですが、その使いやすさからある種のコンテナブーム(?)を巻き起こしたともいえるかと思います。
詳しい情報は、ググれば良い記事が山ほど出てくるので割愛します。

rktとは

公式:https://coreos.com/rkt/docs/latest/

CoreOS社が開発している、アプリケーションコンテナのランタイムとなります。
同社が2014年12月に発表したApp Container(appc) Specという標準的なコンテナの仕様を実装したもので、「an alternative to the Docker runtime」として注目を集めています。
現時点での最新バージョンは0.6.1とまだまだプロトタイプの位置づけです。
ちなみにこれまで「rocket」や「Rocket」といった表記が混在していましたが、今後は「rkt」に統一されるらしいです。

Dockerとrktの違い

appcのテーマである「構成の柔軟性」「セキュリティ」「イメージ配布の容易さ」「オープンさ」の切り口で説明してみます。

  1. 構成の柔軟性
    Dockerは、クラウドサーバやクラスタ向けシステムを構築するためののツールや幅広い機能(イメージの作成・動作・アップロード・ダウンロード)が、rootで動作するmonolithicなバイナリで提供されています。
    一方でrktにおいては、コンテナをダウンロード、インストール、起動するための全てのツールは統合されてはいますが、それぞれは独立した構成となっています。

  2. セキュリティ
    Dockerはクラサバ型の設計であり、Dockerクライアントは Dockerデーモンに対して各種コマンドを発行するアーキテクチャとなっています。
    Dockerデーモンはroot権限で動作する必要があるため、常にrootプロセスがDockerホスト側で動き続けることになります。
    このことを「全てが中央のデーモンを通じて実行されるDockerの処理モデルには、セキュリティと再利用性において根本的な欠陥がある。」とし、root権限デーモン⇔クライアントのアーキテクチャを廃止して新たに生まれたのがrktとなります。

  3. コンテナイメージの配布
    Dockerは「Docker Hub」や「Docker Private Registry」などのレジストリを通じてコンテナイメージをpull/pushする必要があります。
    rktにおいては専用のレジストリは存在せず、WEBの標準的な仕様(HTTPS)を用いてイメージを配布することができます。

  4. オープンさ
    rktはオープンなコンテナ仕様を実装しています。

コマンドレベルでの細かな違いについては、下記で順を追って見ていきましょう。

環境

coreos(alpha v717.0.0) on vagrant(1.7.2)

インストール

coreosは、アプリケーションをコンテナ上でのみ動作させるように設計されており、
取得したbox(coreos-alpha v717.0.0)ではDocker, rkt共にインストール済みとなっています。

Docker

$ docker -v
Docker version 1.5.0, build a8a31ef-dirty

rkt

$ rkt version
rkt version 0.5.5
appc version 0.5.1+git

ちなみに現時点(2015/6/21)でのrktの最新バージョンは0.6.1となっており、下記の通り最新版をインストールすることもできます。

wget https://github.com/coreos/rkt/releases/download/v0.6.1/rkt-v0.6.1.tar.gz
tar xzvf rkt-v0.6.1.tar.gz

コンテナの取得・作成・起動から破棄まで

コンテナイメージの取得

Docker

Dockerは「Docker Hub」や「Docker Private Registry」などのレジストリを介してイメージを取得・公開することができます。
ここではCentOSの最新イメージを取得しています。

$ docker pull httpd

rkt

rktでは、appcのディスカバリ仕様に従って、インターネット上からコンテナイメージを取得することができます。
ここでは「coreos.com/etcd」というACIを取得する例を示します。

① rkt trust
rktではACIの署名を検証するために公開鍵を取得する必要があります。

$ sudo rkt trust --prefix=coreos.com/etcd

② rkt fetch
次にrkt fetchコマンドでACIの取得、署名の検証を行います。

$ sudo rkt fetch coreos.com/etcd:v2.0.4

なお、Dockerイメージを利用したい場合にDocker Registryからイメージダウンロードし、ACIに変換することもできます。

$ sudo rkt --insecure-skip-verify fetch docker://httpd

※Dockerイメージのsignature verificationはサポートされないため、--insecure-skip-verifyオプションを付けます。

コンテナイメージ一覧

Docker

docker imagesコマンドを使用します。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
httpd               latest              de94ed779434        5 days ago          161.8 MB

rkt

rkt imagesコマンドを使用します。

$ sudo rkt images
KEY                                                                     APPNAME                 IMPORTTIME                              LATEST
sha512-1eba37d9b344b33d272181e176da111ef2fdd4958b88ba4071e56db9ac07cf62 coreos.com/etcd:v2.0.4  2015-06-21 07:38:58.396 +0000 UTC       false
sha512-fb95bcc29323607aafcca362bd6beb073c85e34f4cd63db8fe5570b603d33838 httpd:latest    2015-06-21 10:47:48.825 +0000 UTC       false

取得した「coreos.com/etcd」と「httpd」イメージが表示されています。

コンテナの起動

Docker

docker runコマンドを使用します。
-pオプションでコンテナの80番ポートをホストの8080ポートをマッピングします。

$ docker run -p 8080:80 httpd:latest

ホスト側からコンテナへアクセスしてみます。

$ curl http://localhost:8080/
<html><body><h1>It works!</h1></body></html>

rkt

rktではrkt runコマンドでイメージ名を指定することでコンテナを起動します。

$ sudo rkt run -local httpd

-local:ローカルのイメージを利用する

rktのネットワーキングはdockerと異なりデフォルトでホストモードとなっており、ネットワークはホストのものを使用します。

$ curl "http://localhost:80/"
<html><body><h1>It works!</h1></body></html>

プライベートネットワークを利用する場合は、rkt metadata-serviceコマンドでMetadata Serviceを起動したのちに--private-netオプションを使用してコンテナを起動します。

$ sudo rkt metadata-service

後述のrkt listコマンドでコンテナのIPを確認し、アクセスしてみます。
ここでは試しませんが、イメージのビルド時にポートのエントリを定義しておけば、rkt run時に--portオプションを使用することでポートフォワーディングも実現できます。

$ curl "http://172.16.28.3:80"
<html><body><h1>It works!</h1></body></html>

コンテナを落としたいときは、Ctrl-]を3回押します。

コンテナ一覧

Docker

$ docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                  NAMES
21763385c6bc        httpd:latest        "httpd-foreground"   5 seconds ago       Up 4 seconds        0.0.0.0:8080->80/tcp   trusting_yalow

rkt

$ sudo rkt list -full
UUID                                    ACI     STATE   NETWORKS
26804adf-6394-469d-bb0c-ff7168202368    httpd   running default:ip4=172.16.28.3

コンテナの作成(ビルド)

Docker

コンテナの構成内容を記載したDockerfileを指定してdocker buildコマンドでビルドを行います。

① dockerfile作成
下記は簡単な例となりますが、dockerfileは命令 引数の形式で記載をします。

dockerfile
# ベースイメージ
FROM centos
# 作成者
MAINTAINER sample
# 各種コマンドの実行
RUN yum -y install httpd
# コンテナの実行コマンド
CMD /bin/bash

② ビルド
dockerfileのディレクトリを指定してdocker buildコマンドを実行します。

$ docker build -t myimage ./

③ イメージ確認

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
myimage             latest              df2ca7e6d2e1        About a minute ago   263.5 MB

rkt

rktのコンテナイメージはACIフォーマットで管理され、appcで提供されているツール「actool」を使用することでビルドできます。
actoolではコンテナの構成内容を記載したJSON形式のMANIFESTファイルとルートファイルシステムを元にACIをビルドします。

① MANIFEST作成
今回は、公式リファレンスを参考にGO言語製サンプルアプリケーションを実行するACIを作成します。
https://github.com/coreos/rkt/blob/master/Documentation/getting-started-guide.md

manifest
{
    "acKind": "ImageManifest",
    "acVersion": "0.6.0",
    "name": "myimage",
    "labels": [
        {"name": "os", "value": "linux"},
        {"name": "arch", "value": "amd64"}
    ],
    "app": {
        "exec": [
            "/bin/hello"
        ],
        "user": "0",
        "group": "0"
    }
}

② ディレクトリ整備

$ mkdir myimage
$ mkdir myimage/rootfs
$ mkdir myimage/rootfs/bin
# manifest配置
$ mv manifest myimage/

③ GOアプリケーション作成

hello.go
package main

import (
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        log.Printf("request from %v\n", r.RemoteAddr)
        w.Write([]byte("hello\n"))
    })
    log.Fatal(http.ListenAndServe(":5000", nil))
}
$ CGO_ENABLED=0 GOOS=linux go build -o hello -a -tags netgo -ldflags '-w' .
$ mv hello myimage/rootfs/bin/

④ ビルド

actool build myimage my-app.aci

⑤ コンテナ起動

$ sudo rkt --insecure-skip-verify run myimage.aci

⑥ ホストからアクセス確認

$ curl "http://localhost:5000"
hello

コンテナの削除

Docker

CONATINER IDを指定してdocker rmコマンドを実行します。

$ docker rm 01fdf4b430b9
01fdf4b430b9

rkt

現時点でコンテナの削除コマンドは存在しないみたいです。

コンテナイメージの削除

Docker

IMAGE IDを指定してdocker rmiコマンドを実行します。

$ docker rmi de94ed779434
Untagged: httpd:latest

rkt

現時点でコンテナイメージの削除コマンドは存在しないみたいです

まとめ

簡単ではありますが一通りDockerとrktを触ってみました。
冒頭にも述べたとおりrktはプロトタイプの段階であるため、機能的にも使いやすさ的にもDockerにまだまだ劣ると感じています。
実用という点について現段階では多く語れませんが、Dockerのセキュリティ面での問題を解消したというのは言わずもがな、何よりオープンかつシンプルなrktの思想は素敵だと思います。
2015年5月に「Kubernetes」がrktを通じappcサポートすることを明らかにしたこともあるように、今後の可能性に期待したいと思います。

参考

139
131
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
139
131