LoginSignup
8
7

More than 5 years have passed since last update.

OSS版Drone.io上のワーカーコンテナからコンテナを作成する方法のメリット・デメリット

Posted at

OSS版Drone.io(以下Drone)が立ち上げたワーカーコンテナ上でコンテナを作成する方法2つと、実際に使ってみたメリット、デメリットを書きました。
今回はDroneでの使用を前提にしていますが、Droneに限らず「コンテナから新しいコンテナをrunしたい」などという用途にも使えると思います。

環境

  • Amazon Linux (on EC2)
  • Docker 1.9.1
  • Drone 0.4

Droneはdocker hubにある公式のコンテナを使用。
一部機能は新しいバージョンで実装された機能を使っているため、古いDockerやDroneでは動作しない可能性あり。

wrapdockerを使う

1つ目の方法は"wrapdocker"を使う方法。こちらを参考に。

.drone.yml
build:
    image: jpetazzo/dind
    privileged: true
    commands:
        - wrapdocker
        - docker build -t my_container .

Droneの設定で "Trusted"をONにする のを忘れずに。

メリット

  • 手軽に使用可能

デメリット

  • dindコンテナの中のDockerが作業を行う。つまり、 Droneの一連の処理が終わったらすべて消える。
  • privilegedで特権を取得するのでセキュリティ的にあまりよろしくない。らしい。

docker.sockを使う

ホストのdockerの/ver/run/docker.sockをマウントしてホストのDockerを操作する。

コンテナの準備

Dockerのモジュールが入ったコンテナを作成する。

Dockerfile
FROM debian:jessie

#   --build-argで定義した変数を使用するために必要
ARG DOCKER_VERSION

RUN apt-get update && apt-get install -y apt-transport-https ca-certificates

#   Dockerをダウンロードするための設定
RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
RUN echo deb https://apt.dockerproject.org/repo debian-jessie main > /etc/apt/sources.list.d/docker.list

#   Dockerのインストール
RUN apt-get update && apt-get -y install docker-engine=${DOCKER_VERSION}-0~jessie

Docker公式のセットアップ手順を参照に、コンテナの中にDockerをセットアップしているだけ。
ベースはDebianにしているけど、Ubuntuでもほぼ同様。
Debian
https://docs.docker.com/engine/installation/linux/debian/
Ubuntu
https://docs.docker.com/engine/installation/linux/ubuntulinux/

ビルドする。

docker build --rm --build-arg DOCKER_VERSION=$(docker version --format='{{.Server.Version}}') -t my_docker_in_docker .

--rmオプションで中間を消すのはお好みに応じて。このコンテナでわざわざキャッシュを残しておく意味はないと思う。
Dockerのバージョンを定義しているのは、ホストとクライアント(コンテナ)のDockerでAPIバージョンを合わせておかないとエラーが起きるため。
(常にどちらも最新バージョン同士なら問題ないだろうけど、今回はAmazon Linuxのリポジトリにある最新のDockerとDebianの最新版のバージョンがずれていたためエラーが起きた。)

Drone側の準備

準備と言っても.drone.ymlですけど。

.drone.yml
build:
    image: my_docker_in_docker
    volumes:
        - /var/run/docker.sock:/var/run/docker.sock
    commands:
        - docker build -t my_container .

メリット

  • pullしたベースやbuildしたコンテナ(中間含む)はすべてホストのDockerの管理下に置かれるのでキャッシュが利くし、ホストのDockerを操作している感覚(というか、実際にホストに対して操作しているのだけど)でよい。

デメリット

  • 一度やったら後は楽だけど、準備がやや面倒。
  • この方法も、本当ならセキュリティ的にあまりよろしくない。らしい。

まとめ

dindで何回かテストをしてみたけど、ベースを毎回pullしてくるし、ゼロからコンテナ作り直してるじゃん。ということで他の可能性を調べた末の方法がdocker.sockを使う方法でした。
やっぱりキャッシュが利く方がいいよね。

結局どっちも「セキュリティ的にあまりよろしくない」のね。そのあたりは参考のリンク先をご一読を。

その他

「wrapdockerのデメリットをなくすために、dindコンテナに対象のベースコンテナををpullしてcommitしておけばいいんじゃね?」とも思ったけど、それだと「ベースが更新されるたびに手動で作り直さないといけないよね」ということで考えるのを止めました。

参考

OSS版 drone.io を使って Docker Image をビルド
http://qiita.com/quickguard/items/3b711fc871f42bf0772d

Docker マトリョーシカと私
http://orih.io/2015/12/we-should-think-twice-about-using-docker-in-docker/

Dockerコンテナ内からホストマシンのルートを取る具体的な方法(あるいは/var/run/docker.sockを晒すことへの注意喚起)
http://rimuru.lunanet.gr.jp/notes/post/how-to-root-from-inside-container/

8
7
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
8
7