2016/12/09

VMware 環境で docker を使う

この記事は、vExperts Advent Calendar 2016 に参加しています。



● 非Linux でもコンテナしたい!


Docker はご存じの通り Linux 上で動作するコンテナ技術で、元々は Linux の OSパーティショニング技術を利用して実装されていました。Linux 環境で Linux のサーバソフトウェアを包んだコンテナを構築する場合はさして問題なかったのですが、利用が増えるにつれ、とくに利便性の面で課題が出てきました。

例えば、Linux サーバ上のアプリケーションを開発する場合でも多くの開発者はデスクトップ環境としては Windows や macOS など使い勝手のいいUIをもつ OS を使っているわけですが、これらの環境では、そのままでは Docker コンテナを実行することができません。


・Boot2Docker ~ Docker Toolbox ~ Docker for Windows/Mac


そこで、登場したのが Boot2Docker という一連のツールです。Boot2Docker は3つの要素、すなわち、

  • boot2docker という管理コマンド
  • 同名(boot2docker)の軽量な Linux のディストリビューション
  • Oracle VirtualBox

の組合わせになります。boot2docker コマンドを通じて、VirtualBox 上に仮想マシンを作成し、boot2docker をOSとして稼働させ、Docker によるコンテナを実行するというものです。仮想化が一段絡むぶん複雑化しますが、 Mac や Windows マシンで簡単に Docker を試せることから、コンテナの学習や開発、テストなどの用途で幅広く使われてきておりました。

この Boot2Docker を発展させたものが Docker Toolbox であり、さらに Docker for Windows, Docker for Mac というソフトウェアです。
いずれも Windows, macOS 向けに仮想環境と操作用のコマンドや管理用GUI などをまとめたものです。
Docker Toolbox は仮想化ソフトウェアとして VirtualBox を使用しておりますが、Docker for Windows では Hyper-V を、Docker for Mac では xhyve を使用しております。
なお、仮想マシン上のOSとしては継続して  boot2docker を使用しています。先にリンクした Boot2Docker のページなどでも、boot2docker はこちらの方、Linux ディストリビューションとしての側面の方が強くなっております。
( 注意: Docker Toolbox と、Docker for Windows/Mac は同一環境にインストールすることがサポートされておらず、Docker Toolbox を使うか、Docker for Windows/Mac を使うかどちらかの選択になります。 )

この、 DockerToolbox, Docker for Windows, Docker for Mac で boot2docker コマンドにかわって用意されているのが Docker Machine という Docker 純正のソフトウェアです。

Docker Machine もまた Docker コンテナの実行環境を操作するソフトウェアになります。boot2docker コマンドが VirtualBox を前提としていたのにたいして、Docker Machine はドライバーを通じて様々なクラウドや仮想環境と対話し、Docker を実行するための仮想マシンを準備することができます。

Docker Machine が対応している環境の一覧はこちらです。

Boot2Docker でも使われていた VirtualBox や Hyper-V といった仮想化ソフトウェアだけではなく、Microsoft Azure や OpenStack といったクラウドもあります。こうなると学習、開発用途を越えて、小規模なら運用環境を構築するのにも使えますね。

VMware 関連では、「vCloud Air」「VMware Fusion」「vSphere」がサポートの環境となります。ここでは、Docker Machine を通じて これら VMware の仮想マシン上で Docker を展開してみます。


● Docker Machine 入手方法


先の経緯から、Docker Toolbox や Docker for Windows, Docker for Mac には docker-machine コマンドが含まれております。これらを既にインストールしている場合は、それをそのまま流用することができます。ただ、今回はローカルで既にインストールされている VMware Fusion を使ったり、リモートの vSphere を利用するため、仮想化ソフトウェアが一緒にインストールされてしまうこれらは大仰とも言えます。

Mac の場合、homebrew というパッケージマネージャでは docker コマンドや docker-machine コマンドが用意されており、以下のコマンドで簡単にインストールすることができます。
brew install docker-machine
brew を使った docker-machine のインストール

また、パッケージマネージャを使わずとも、Docker 社の GitHub から直接バイナリをダウンロードして使用することも可能です。
curl -O https://github.com/docker/machine/releases/download/v0.8.2/docker-machine-Darwin-x86_64 sudo cp ./docker-machine-Darwin-x86_64 /usr/local/bin/docker-machinesudo chmod +x /usr/local/bin/docker-machine
(1行目のコマンドで macOS 用 docker-machine コマンドをダウンロード、2行目で管理者権限で /usr/local/bin 以下にコピー、 最後のコマンドで実行券を付けてます。これはこちらのサイトのインストールコマンドと意味的には同じです、1行で書いてないだけで。)

いずれにせよ、Mac の場合は「ターミナル」のウィンドウで、Windows の場合はコマンドプロンプトウィンドウにて docker-machine とだけ入力、実行してヘルプメッセージが出る、パスが通ってて実行可能になっている、事をご確認ください。


● VMware Fusion でコンテナを展開してみる


macOS で既に docker-machine と VMware Fusion がインストール済みの場合は、以下コマンドを実行すると、Docker コンテナの実行環境(仮想マシン)が作成され、自動的に実行されます。
docker-machine create --driver vmwarefusion <仮想マシン名>
コンテナを実行する仮想マシンを、docker-machine で作成、起動

このとき、インターネット上の boot2docker の iso イメージ(40MB弱)をインターネットからダウンロードします。その後、仮想マシンを作成、vmrun コマンドで仮想マシンを実行し、仮想マシンは iso イメージからブート、boot2docker を OS として起動します。

20GiBの仮想ディスクが作成されている

無事作成されたかは、以下のコマンドで確認できます。

docker-machine ls


なお、仮想マシンは実行されても、 VMware Fusion というアプリケーションそのものは起動されないのでご注意ください。VMware Fusion の仮想マシンの実体は vmware-vmx というプロセスで、VMware Fusion.app は仮想マシンを管理するGUIにすぎません。この VMware Fusion.app 内には、コマンドラインから仮想マシンを起動する vmrun というコマンドが含まれており、docker-machine はこちらを使う次第です。もちろん、VMware Fusion.app を起動すれば、docker-machine が作成した仮想マシンもライブラリに表示され、こちらから起動終了など操作をすることも可能です。

VMware Fusion.app を起動すると、仮想マシンが立ち上がってるのが分かる


デフォルトでは仮想マシンは 1vCPU, 1GB RAM の仮想マシンを作成、仮想ディスクサイズは 20GBとなっています。異なるサイズの仮想マシンを作成したい場合は、以下のドライバ特有のコマンドラインオプション、あるいは環境変数で変更できます。

コマンドラインでのオプション環境変数での設定デフォルト値
--vmwarefusion-boot2docker-urlFUSION_BOOT2DOCKER_URL最新のboot2docker の
URLが自動的に参照される
--vmwarefusion-cpu-countFUSION_CPU_COUNT1
--vmwarefusion-disk-sizeFUSION_DISK_SIZE20000 (単位MiB)
--vmwarefusion-memory-sizeFUSION_MEMORY_SIZE1024 (単位MiB)
--vmwarefusion-no-shareFUSION_NO_SHAREfalse
( https://docs.docker.com/machine/drivers/vm-fusion/ より引用)

さて、docker コマンドを使ってコンテナを実行してみましょう。docker コマンドは環境変数からどこで待機している dockerd と接続するかを決めることができます。そして、docker-machine はこの環境変数を作成してくれます。

docker-machine env

このコマンドだけでは、単に環境変数を表示するだけですが、以下のように実行することでその環境変数を現在のシェルにセットするのが定石です。
eval $( docker-machine env )
個人的には以下の方が好みです。(古い人間なので、bash独自仕様は、どうも...ね。)
eval `docker-machine env`

また、関数を用意して環境変数を設定したサブシェルを作るというのもいいかと思われます。

function dockersh() { ( eval `docker-machine env "$1"` && exec sh -i ) }

関数を定義。実際には .bashrc などに記載しておく
dockersh を使ってサブシェルを実行、環境変数がセットされているのを確認

こうしておくと、suspend コマンドでそのサブシェルを停止し、元のシェルに戻れます。docker-machine では複数のコンテナ実行環境を構築することができますので、それごとに dockersh でサブシェルを起動し、suspend で一旦抜けて、fg で戻るを繰り返すことで簡単にコンテナ実行環境を行き来できます。
(フェイルセーフを考えると、上記 dockersh 関数では、bash のコマンドプロンプトも操作してコンテナ実行環境の名前を入れておいた方がいいかもしれません。)
docker-machine で Fusion 上にもう一つ別のコンテナ実行環境用の仮想マシンを作成
このように、コンテナの実行環境をいくつでも作成できるのが docker-machine の便利なところだ
もちろん、ドライバーを変えることで Fusion 以外での環境も作成できる

ともあれ、コンテナの実行環境ができたら、あとは docker コマンドでコンテナを実行するだけです
docker コマンドで hello-world コンテナを実行してみた

なお、docker-machine で作成した仮想マシンはデフォルトでは ~/.docker/machine/machines フォルダに格納されます。通常の仮想マシンと位置が違うのでご注意ください。

作成した仮想マシンvm は、~/.docker/machine/macchines/vm フォルダに存在する

● vSphere 上でコンテナを実行してみる

Fusion の場合と同じように、docker-machine を使って vSphere 上に コンテナの実行環境となる仮想マシンを作成、制御することができます。

vSphere に対する場合は、ドライバとして「vmwarevsphere」を使用します。
docker-machine create --driver vmwrevsphere --vmwarevsphere-vcenter=<vc/esxi> --vmwarevsphere-username=<username> --vmwarevsphere-password=<passwd> <仮想マシン名>
--vmwarevsphere-vcenter オプションで捜査の対象となる vCenterServer ないしは ESXi のIPアドレスか、ホスト名を指定します。--vmwarevsphere-username と --vmwarevsphere-password でユーザ名、パスワードを指定します。なお、vmwarevsphere ドライバでは -username と -password は必須オプションとなり、オプションか環境変数で必ず指定する必要があります。実質的には -vcenter も必須と言えるでしょう。

docker-machine から vSphere に対して仮想マシンを作成

作成後の、ls での一覧と、env の内容表示
そのほかオプションについては、こちらに記載があります。Fusion でもあった仮想マシンのvCPU数、メモリサイズ、ディスクサイズ、boot2docker (iso イメージ)のURL から、作成した仮想マシンをどのネットワークに接続するか、どのデータストアに格納するか、どのリソースプールに入れるか、どのデータセンターに配置するか、それから起動時にどのホストで起動するか、などが指定できるようになっています。

● vSphere Integrated Containers との違いは?


ここまでで見てきたように、Docker コンテナを仮想化環境やクラウドで実行させるだけなら docker-machine があれば十分です。

一方、VMware 社は vSphere EnterprisePlus 購入者向けの無償製品として「vSphere Integrated Containers」(VIC) をオープンソースで提供しています。

VIC と docker-machine + vSphere ドライバーはどちらも vSphere 上での Docker によるコンテナ化されたアプリケーションの展開をおこないます。その点では同じです。

一方、以下の点で違いがあります。

・Boot2Docker vs. Photon OS with Instant Clone


docker-machine ではコンテナを実行するLinuxとして boot2docker を使用します。これはオープンソースで用意されており、isoメディアを見ても35MB程度と非常に軽量です。

一方、VIC は VMware 社が推進するコンテナ向けの Photon OS というディストリビューションを使用します。PhotonOS は軽量と言いますが、メディアサイズは 1GB程度と、boot2docker よりは大きくなります。
そこで、VICではこの PhotonOS を搭載した Linux VM を InstantClone で展開します。

InstantClone は VMfork と呼ばれる技術を利用したもので、「コピーオンライト」(COW)で仮想マシンを増やします。仮想マシンの作成時はCOWにより最低限の書き換えられたメモリ分だけが新たに消費され、ほとんどのメモリは「共有」された状態で起動します。ディスクについてもリンククローンのように差分ディスクを活用するため、極めて高速に Photon OS の仮想マシンを展開できるわけです。

InstantClone の詳細については、こちらの記事をご参照下さいませ。

注意点としては、InstantClone では透過的ページ共有が有効になります。これはセキュリティ上の理由から vSphere 5.5P04, vSphere 5.1U3 などからデフォルトで無効にされた機能です。InstantClone を使う VIC や Horizon View では、リスクがあることは理解しておくべきでしょう。

ともあれ、VICでは InstantClone によりコンテナを乗っける仮想マシンの展開速度は非常に敏速になります。
ただ、敏速になるのは展開速度だけのため、その恩恵は展開の頻度にもよります。

・管理を容易に


docker-machine ではコンテナを実行する環境(OS)を用意するまでで、その上にいくつコンテナを展開するかは利用者次第です。一方 VIC では1コンテナ1仮想マシンに決め打ちしております。InstantClone により高速に仮想マシンが展開できることもありますが、1コンテナ1仮想マシンにすることでサービスとVMの紐付けが単純化され、仮想化基盤の管理者からも分かりやすくなるという利点があります。vSphereClient(WebClient)で仮想マシンを管理するときや、NSXのマイクロセグメンテーションを適用するときにこれは便利と言えます。

1コンテナ1仮想マシンのため、vReailze Orchestartor での可視化の時もどのコンテナ(=仮想マシン)に負荷がかかっているかが分かりやすくなります。

さらに、Admiral というWebベースのUIも提供されており、より容易にマウスクリックでのコンテナ管理もできます。

こうした、vSphere の各管理製品との連携やUIの拡充も VIC の特徴になります。

・コスト


docker-machine は Docker 標準の管理ツールであり、これまで述べたように Windows/Mac 環境向けにOSSで無償提供されております。

VIC はオープンソースのソフトウェアでそれそのものは公開されていますが、実行するには有償の vSphere が必須となります。ESXi 単体の場合は vSphere Enterprise 以上、vCenter Server を使った集中管理された環境では vSphere EnterprisePlus 以上のライセンスが必要です。これは、こちらのページにも説明がありますが、Network Serial Port や分散スイッチと言った有償エディションでしか使えない機能を前提としているためです。

なお、サポート対象になるのは MyVMwareで公開されている公式リリースのバイナリのみで、オープンソースのコードを自前でビルドしたものはVMware社のサポート対象外になります。



また、個人的には国内でのサポート(認識)について少々不安が持たれます。

たとえば先日の vForum 2016 Tokyo の「VMwareとコンテナ技術の相乗効果とは」のセッションにて VIC の説明がおこなわれるはずでしたが、Docker の概要と 1VM1コンテナで便利、ぐらいの内容しかなく、ここで述べたような docker-machine との差別化はおろか、TPS が有効になるなどの重要情報もありませんでした。
( このセッション、冒頭でテスラの自動運転の話を延々とした割には「時間がないのでここまで」で切り上げており、ちょっとなぁという出來でした。セッション資料が非公開なのも当然かな、といったところです。)

VICのコンセプトや機能は決して悪くないだけに、残念な話です。



ともあれ、今後、コンテナ化されたアプリケーションは当然になってくるにあたり、コンテナをどう展開するか、どこで動かすかは重要になってきます。大規模環境なら DC/OS や Swarm のようなオーケストレーションツールが活躍するのでしょうが、とっかかりや開発環境、小規模な運用環境では docker-machine は十分に役に立つかと思われます。また、予算が潤沢にあるなら、vSphere EnterprisePlus の大規模なクラスタで VIC を使い、負荷分散は DRS に任せ、vRealize Operations で状態を可視化するのも有益でしょう。