読者です 読者をやめる 読者になる 読者になる

パラボラアンテナと星の日記

あることないこと

「インストールコンテナ」の話 - DockerでホストOSにzshを入れてみた

この記事は、Docker Advent Calendar 2014の23日目の記事です。

:santa: Merry Christmas :santa:

筆者はアプリケーションエンジニアです。dockerなのにインフラあんまり関係ない、ネタっぽい投稿で本当にすまないと思っています :santa:

:whale: DockerでホストOS側に何かをインストールしてみよう!

何を言ってるか良くわからないかもしれませんが、例えばnsenterではそういうことをやっています。

:whale: 例:nsenterの話


jpetazzo/nsenter · GitHub

このdocker imageは、READMEどおりにdocker runすると、ホストOS側の/usr/local/binの下にnsenterというバイナリが配置されます。
これにより、nsenterという便利コマンドがホストOS側で利用できるようになるわけです(nsenter自体の説明は割愛します)。
dockerなのにホストOS側に影響をおよぼすというのは、ちょっと驚きですね(こなみかん)。

READMEに書いてあるrunはこんな感じです。

$ docker run --rm -v /usr/local/bin:/target jpetazzo/nsenter

なるほど、ボリュームを利用しているわけです。
インストールされる様子のgifを貼っておきます。
nsenterと同時にインストールされるdocker-enterで確認しています。(検証に用いたCoreOS494.0.0では、nsenterは最初から入ってしまっているので。。)

docker-enter.gif

どういうふうになっているのでしょうか。
CMDの内容は、こんな感じです。

#!/bin/sh

if mountpoint -q /target; then
    echo "Installing nsenter to /target"
    cp /nsenter /target
    echo "Installing docker-enter to /target"
    cp /docker-enter /target
else
    echo "/target is not a mountpoint."
    echo "You can either:"
    echo "- re-run this container with -v /usr/local/bin:/target"
    echo "- extract the nsenter binary (located at /nsenter)"
fi

つまり、何をしているかというと

  • image(debian)の中では「nsenter」と「docker-enter」というバイナリを作成
  • runされたとき、volume経由でそのバイナリをホストOSに配置(cpで)している

というだけ、なのです。図にするとこんな感じ。

nsenter.png

ホスト側がLinuxであれば、imageの中のdebianコンパイルしたものがホスト側でも動く、というわけですね(適当な理解)。注意書き には、64bitでしか動かない、とあります。

:whale: CoreOSでもzshを動かしたい

さて、私はdockerで遊ぶのにCoreOSを使います。

CoreOSは軽量OSといえど最初からdocker, vim, git, curlが動きますので、私としては大した支障は無いのですが、唯一、シェルをzshにしたいという欲求がありました。

ですが、CoreOSは周知の通りaptだのyumだのといったものが無いわけですので、無理にやろうとすると「自分用にCoreOS自体をビルドする」だの「コンテナの中でコンテナ間通信でごにょごにょやる」だの、ちょっと遊びたいだけの時はつらい感じになると思います。

しかし、一度肩の力を抜いて考えてみましょう。nsenterの例で見たように、手元にdockerはあるわけなので、dockerでコンテナの中でzshの実行ファイルを作り、ホストOS側にポンとcpすればいいのです

:whale: やってみた

作ってみました。


hoshinotsuyoshi/zsh-on-coreos · GitHub

dockerhubにも置きました。使い方は

$ docker run --rm -v /opt/bin:/target hoshinotsuyoshi/zsh-on-coreos

とすればCoreOS側でzshが使えるようになります。おめでとうございます。ありがとうございます。嬉しいのでgifも貼ります。

zsh.gif

ふつう/usr/local/binとかはReadOnlyになっているので、/opt/binを使いました。CoreOSではデフォルトでPATHも通っています。

zsh.png

:whale: さいごに

こういうパターンのdockerの使い方って?

nsenterでやっていることを「インストールコンテナ」と名付けている人もいました(原文ではInstallation Container)。
個人的には、おもしろパターンだと思います。

Automated Build べんり説

なんというか得体の知れないバイナリを配るときに、docker hubのAutomated Buildを使うのは、良いかもしれません。
どういったものをビルドしているのかが、Dockerfileとして可視化できるので。
今回zshをビルドしたDockerfileは、こういった形で参照できます。

hoshinotsuyoshi/zsh-on-coreos Repository | Docker Hub Registry - Repositories of Docker Images

どの程度信じられるか、はあると思いますが。

追記

やばいという意見があったので引用せざるをえない

そうですね、私もそう思います。
dockerのこういう使い方、一般論としてヤバいという話は真面目に考えてあると思う。信用できる人のものをpullするか、自分でDockerfileを読んでbuildするとかしかないと思いました。