2017年3月23日木曜日

AWS Storage Gateway のファイルゲートウェイを使って s3 にデータを保存する

概要

AWS Storage Gateway にはファイル共有という機能があり nfs フォーマットでマウントすることができます
マウントした領域にデータを保存するとそのまま s3 にも保存することができます
今回は Appliance を VMware 環境にデプロイし VM から Storage Gateway で作成した nfs をマウントして s3 にデータを保存してみます
基本的な手順は前回の iSCSI の回と同じなのでそちらをご覧ください

環境

  • VMware vCenter Server 6.0.0u2
  • VMware ESXi 6.0.0 3620759
  • AWS Storage Gateway (20170322 時点)
  • AWS Storage Gateway Appliance

ファイルゲートウェイ用 AWS Storage Gateway Appliance のデプロイ

以下からアプライアンスをダウンロードし VMware 環境にデプロイしてください
https://dslbbkfzjw91h.cloudfront.net/AWS-Storage-Gateway-File.zip

デプロイ後に設定変更するので起動しないようにしてください

Appliance の設定変更

設定変更から以下を変更します

  • 50GB のディスクを 1 本追加する (ストレージの容量に余裕がなければ 50GB もなくても OK です)
  • 仮想マシン オプション -> VMware Tools -> 時刻 にチェックを入れる

設定変更したら起動します
IP が取得できれば OK です

AWS 側に Storage Gateway を追加する

Storage Gateway のコンソールで作業します

ゲートウェイの種類を選択で「ファイルゲートウェイ」を選択します
ホストプラットフォームの選択で「VMware ESXi」を選択します

あとはゲートウェイに接続してアクティブ化すれば OK です
追加した 50GB 分のストレージもローカルストレージとして作成してください

ファイル共有を作成します

続けてファイル共有を作成します
左メニューの「ファイル共有」を選択します

作成時にデータを保存するバケットを指定する必要があるので入力します
s3 へのアクセス用の IAM ロールを設定する必要がありますが、新規で作成することもできるので設定が面倒であれば新規で作成してください

あとは作成されるのを待ちます

nfs として VM にマウントする

では VM にマウントしてみましょう
コンソールにコマンドが出ているのでそのまま利用すれば OK です
もちろん Appliance の IP アドレスにアクセスできる VM から試してください
今回は Ubuntu 16.04 から試しています

  • apt -y install nfs-common
  • mkdir -p /sg
  • mount -t nfs -o nolock xxx.xxx.xxx.xxx:/my-sg-test-bucket /sg
  • echo hoge > /sg/hoge.txt

という感じでマウントしてファイルを作成してみましょう
すると s3 側にもデータが保存できているのが確認できると思います
aws_storage_gateway_nfs1.png

最後に

Storage Gateway のファイル共有機能を使って s3 をバックグランドにした nfs をマウントしてみました
感覚的には s3fs などのファイルシステムツールに近い感じです

利点としてはマウントには nfs クライアントがあればいいのでいちいち s3fs をインストール必要がありません
また、同じバケットを別の VM でも簡単にマウントすることができるようになります

ESXi にも NFS をマウントする機能があるけどこれでマウントしてデータストアとして認識させてから VM に割り当てることはできるのだろうか

2017年3月22日水曜日

AWS Storage Gateway のボリュームゲートウェイを使って iSCSI のデータストアを VMware 上に構築してみた

概要

AWS Storage Gateway には iSCSI のストレージ I/O があり Linux マシンや Windows マシンに iSCSI デバイスとしてディスクをマウントすることができます
VMware のデータストアにも iSCSI アダプタがあるため iSCSI なデータストアをホストにマウントすることができます
今回は AWS Storage Gateway のボリュームゲートウェイに含まれる iSCSI インタフェースの機能を使って VMware 上に iSCSI なデータストアを構築してみました

環境

  • VMware vCenter Server 6.0.0u2
  • VMware ESXi 6.0.0 3620759
  • AWS Storage Gateway (20170322 時点)
  • AWS Storage Gateway Appliance

AWS Storage Gateway Appliance のデプロイ

以下の URL から ova ファイルをダウンロードすることができます
https://dslbbkfzjw91h.cloudfront.net/AWS-Storage-Gateway.zip

Storage Gateway のコンソール上で作業をすすめる時に表示されるダウンロード URL と同じものです
他に Storage Gateway File という ova もありますが、そちらではないのでご注意ください
ダウンロードしたら解凍しましょう

ova のデプロイは vSphere Client 上でポチポチするだけなので箇条書きで簡単に説明します

  1. vSphere Web Client を開く
  2. ホストを選択 -> アクション -> OVF テンプレートのデプロイ
  3. ローカルファイルの選択で ova ファイルを選択
  4. 詳細の確認をする (特に変更なし)
  5. VM の名前を設定しデプロイするフォルダを選択
  6. デプロイするデータストアを選択 (データストアは 200GB ほど空きがあると嬉しい)、シックを選択
  7. ネットワークを設定
  8. デプロイ後にパワーオンにはチェックを入れずに作成開始

で OK です
デプロイ後に設定の変更を行うのでパワーオンはしないようにしてください
だいたい 10 - 20 分ほどで完了します

Appliance の設定変更

デプロイできた Appliance を選択し「設定の編集」を選択します
以下を修正、追加します

  • 50GB のディスクを 2 本追加する (ストレージの容量に余裕がなければ 50GB もなくても OK です)
  • iSCSI コントローラのタイプを「VMware 準仮想化」に変更
  • 仮想マシン オプション -> VMware Tools -> 時刻 にチェックを入れる

修正できたら OK で完了します
設定変更後は Appliance を起動しましょう
起動して IP アドレスが問題なく取得できれば OK です
これで Appliance の設定は完了です

AWS 側に Storage Gateway を追加する

ここからは AWS のコンソールで作業します
Storage Gateway のコンソールにアクセスしてください

ここで一点注意が必要なのですが、作業する環境から先程構築した Appliance にアクセスできる必要があります
もう少しいうと作業するブラウザが Appliance にアクセスできる必要があります
もし Appliance にリーチャビリティのない環境からやる場合は Appliance 側の環境にデスクトップ環境を用意してそこでブラウザを開いて作業するなどしてください

まずボリュームゲートウェイとして Storage Gateway を作成します
aws_storage_gateway_iscsi1.png

ホストプラットフォームの選択で VMware ESXi を選択します
ここでダウンロードできる zip ファイルは先程ダウンロードした Appliance になります
aws_storage_gateway_iscsi2.png

ゲートウェイに接続で先程起動した Appliance の IP を入力します
ここでブラウザから IP にアクセスできないとエラーになります
aws_storage_gateway_iscsi3.png

ゲートウェイのアクティブ化を行います
タイムゾーンと名前を設定しアクティブ化します
aws_storage_gateway_iscsi4.png

ローカルディスクを作成します
先程追加した 50GB のディスク 2 本をそれぞれ「アップロードバッファ」「キャッシュ」に設定します
aws_storage_gateway_iscsi5.png

これで ボリュームゲートウェイとしての Storage Gateway の作成は完了です

ボリュームを作成する

iSCSI としてマウントするには領域が必要になります
Appliance をデプロイしただけでは、iSCSI のインタフェースが提供されるだけで保存領域がないのでまだ使えません

左メニューのボリュームを選択します
ボリュームの作成から必要な情報を入力していきます
容量は先程作成した 50GB のローカル領域から必要な領域を切り出してください (今回は 20GB)
iSCSI ターゲット名は好きな名前を入れてください
あとで AWS 専用の suffiex と連結してターゲット名が作成されます
aws_storage_gateway_iscsi6.png

その後で CHAP 認証の設定が画面になりますが、今回は認証は設定しないのでスキップします

作成されるまで待ちましょう
だいたい 10 分ほどで作成が完了します

iSCSI アダプタを追加する

ボリュームが作成できたらホストに iSCSI データストアとしてマウントして使えるようにします
ここからの作業は vSphere Client に戻ります

ホストを選択 -> 管理 -> ストレージアダプタ -> iSCSI アダプタを選択 -> ターゲット -> 動的検出 -> 追加
で Appliance を追加します
Appliance の IP アドレスを入力し OK です
ポートはデフォルトの 3260 のままで OK です
aws_storage_gateway_iscsi7.png

追加できたら「最近構成が変更されたため、このストレージ アダプタを再スキャンすることをお勧めします。」と表示されるので素直に再スキャンしましょう
するとストレージアダプタ「ターゲット」と「アダプタ」の欄が 0 -> 1 になっていることが確認できると思います

ボリュームを追加していないとここが増えないので注意してください

iSCSI データストアをホストに追加する

あとはホストに iSCSI データストアをマウントするだけです
ストレージデバイスの一覧を確認すると「Amazon iSCSI Disk (eui.00928a31daae1551c8000000)」というディスクが追加されていると思います

ホストを選択 -> アクション -> ストレージ -> 新しいデータストア

を選択します
そして

VMFS -> データストア名入力、デバイス選択 -> パーティションの設定 (全部割り当てで OK) -> 終了

でマウントしましょう
データストアの一覧で iSCSI のデバイスが追加されていることを確認します
aws_storage_gateway_iscsi8.png

で、このあと

この後実際に VM にディスクを追加してパーティションを作成してフォーマットしてマウントして使おうとしたのですが、実はできませんでした
mkfs したところで止まってしまいうんともすんとも言わなくなってしまいました
いろいろ試したんですが、結局うまく動作せず Appliance のトラシュをする前に力尽きました
もしかしたら何かやり方がおかしかっただけかもしれませんが、、、
(うまく動いたって方がいたら教えてほしいです、、、)
おそらく適当な VM に iSCSI イニシエータとかをインストールして Storage Gateway から直接マウントすれば iSCSI ストレージとして普通に使えるんだと思います
今回はそうではなくて ESXi のデータストアとして使いたかった感じです

あと今回の作業で全く出てこなかった s3 ですが、どうやら Storage Gateway は定期的にスナップショット取っておりそのボリュームデータが s3 に保存されるようです
で、その保存のタイミングとしてキャッシュボリュームと保管型ボリュームがあり、それぞれ s3 にスナップショットを取るタイミングが違うみたいです
またスナップショットはスケジューリングして定期的に取得することもできるみたいです

s3 に溜まったスナップショットのボリュームデータは s3 から直接見ることはできません
EBS ボリュームとして VM を別途作成して、その VM 内で確認するようです

Tips

Appliance にログインする方法はコンソールで sguser/sgpassword でログインできます
基本的な bash のコマンドなどは使えないので難しいトラシュはできないと思いますsshd もあがっていないようでした

最後に

AWS の Storage Gateway を使って VMware 環境上に iSCSI データストアを構築しました
別の機能でファイル共有という機能がそっちだと s3 上でファイルの内容の確認もできるそうなので、次回はそれを試してみたいと思います

参考サイト

2017年3月17日金曜日

docker のネットワーク機能を試してみた

概要

勉強がてら docker のネットワーク機能について基本な操作を行ってみました
既存のネットワークの挙動の確認と独自のネットワークを定義してアタッチするところまで行っています

環境

  • Mac OS X 10.12.3
  • Docker on Mac 17.03.0-ce, build 60ccb22

ネットワークを確認する

まずはデフォルトで用意されているネットワークを確認してみましょう

  • docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
fb949b0d7786        bridge              bridge              local
365cbf8a882f        host                host                local
64103726a5d5        none                null                local

こんな感じで 3 つのネットワークが用意されています
docker run をするときに --net オプションがありこれを使うことでコンテナが所属するネットワークを指定することができます
特に指定しない場合は bridge が選択されるようです

では、この 3 つのネットワークの挙動を確認していきます

ネットワークを指定してコンテナを作成する

bridge

まずは bridge を指定します

  • docker run --rm -p 8080:80 --net bridge --name web1 nginx

これで作成した場合バインドしたポートで Mac (ホストマシン (192.168.100.105)) からコンテナへの通信ができ、moby VM からブリッジネットワークを使ってのコンテナへの通信もできます
また、コンテナからホストマシンへの通信もできます
更に NAT でインターネットに接続することもできます

  • ホストマシンから
    • curl localhost:8080
  • moby から
    • ping 172.17.0.2
  • コンテナから
    • ping 172.17.0.1
    • ping 192.168.100.105
    • apt update

注意点として今回 Docker on Mac でやっているのでホストマシンからコンテナへの ping に関しては moby VM にログインしてから試してください

moby へのログインは以下でできます

  • screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty

host

次に host を試します
--net オプションの部分を host に変更します

  • docker run --rm -p 8080:80 --net host --name web1 nginx

これで作成した場合、コンテナはホストマシンと同じネットワークインタフェースを使用します
なので、moby VM からコンテナへの通信とコンテナからホストマシンへの通信、NAT でのインターネットに接続はできます

  • moby から
    • ping 172.17.0.2
  • コンテナから
    • ping 172.17.0.1
    • ping 192.168.100.105
    • apt update

null

次に null を試します
--net オプションの部分を none に変更します
null ドライバで作成しれたネットワークの none を指定しています

  • docker run --rm -p 8080:80 --net none --name web1 nginx

この場合、どこからもコンテナにアクセスできなくなります
また、コンテナからホストやインターネットへの通信できなくなります

コンテナに exec して確認してみるとわかりますが、通信するための IP アドレスが何も振られていないことがわかると思います

ネットワークを定義する

デフォルトの 3 つのネットワークの挙動はつかめてので次に独自のネットワークを作成してみます
今回は bridge ドライバを使って定義します

  • docker network create my_network

で作成できます
確認するとネットワークが増えていることが確認できます

  • docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
526531de15db        bridge              bridge              local
365cbf8a882f        host                host                local
4aa22f6b0e5c        my_network          bridge              local
64103726a5d5        none                null                local

詳細を確認するには inspect を使います

  • docker network inspect my_network
[
    {
        "Name": "my_network",
        "Id": "4aa22f6b0e5c3759d80bd717410c9aef70e50a853c4076e9bf972f5ba5132f3a",
        "Created": "2017-03-16T23:51:03.617896532Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

Subnet や Gateway はデフォルトで設定されました
既存の bridge ネットワークと比較すると Options が空なだけで後は同じ感じでした

定義したネットワークに接続する

では、定義したネットワークをコンテナに接続してみます
初めに説明すると host と none に対しては接続できませんでした

  • host に対して接続しようとした場合
Error response from daemon: Container sharing network namespace with another container or host cannot be connected to any other network
  • none に対して接続しようとした場合
Error response from daemon: Container cannot be connected to multiple networks with one of the networks in private (none) mode

なので、bridge に接続しているコンテナに対して my_network を接続してみます

  • docker run --rm -p 8080:80 --net bridge --name web1 nginx
  • docker network connect my_network web1

という感じです
insepct で my_network の情報を確認すると Containers の項目が増えていることがわかると思います (以下 inspect 結果の一部抜粋)

"Containers": {
    "cca88927fa6e267e8e552c8a446b5363a29f60f04b2bf534e4cf3cc43fed4047": {
        "Name": "web1",
        "EndpointID": "2bda4228d7930af5ca558aae0e32be545f63018ada5718d80b3daa86bd524fc7",
        "MacAddress": "02:42:ac:12:00:02",
        "IPv4Address": "172.18.0.2/16",
        "IPv6Address": ""
    }
},

また、172.18 帯でも通信できることが確認できると思います
念のためもう一つ my_network に接続しているコンテナを作成してみましょう

  • docker run –rm -p 8081:80 –net my_network –name web2 nginx

で web2 に exec してリーチャビリティを確認すると 172.18 では web1 にアクセスできるが、172.17 ではアクセスできないことが確認できると思います

  • docker exec -it web2 /bin/bash
root@815fc91e6040:/# ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.143 ms
--- 172.18.0.3 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.143/0.143/0.143/0.000 ms

root@815fc91e6040:/# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
--- 172.17.0.2 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss

その他のネットワークドライバ

今回は bridge, host, null という 3 種類のドライバを試しましたが、Docker on Mac では別のドライバも用意されています

  • docker info | grep -A 2 Plugins:
Plugins: 
 Volume: local
 Network: bridge host ipvlan macvlan null overlay

ipvlan, macvlan, overlay というのが他にもあるようです
また、ドライバは自分で定義することもできます
この辺りはまた別途検証して紹介できればと思います

最後に

Docker on Mac でネットワーク機能を試してみました
Mac の場合ちょっと特殊な VM が動作しているので少しややこしくなりましたが概念的には他のマシンで試しても同じだと思います

基本は bridge になるかと思います
あとは swarm などを使った場合にホストをまたがってコンテナ同士を通信させるのに overlay を使う感じかなと思います
それ以外のドライバも試してみたいな思っています

参考サイト

2017年3月16日木曜日

docker のデータボリュームの領域を s3 として使用する方法

概要

これまでにコンテナでデータボリュームを使用する方法として

  1. 単独でデータボリュームを作成する方法
  2. 別のコンテナの領域をデータボリュームとして利用する方法
  3. ホストマシンの領域をデータボリュームとして利用する方法

を紹介しました
今回は s3 の領域をデータボリュームとして利用する方法を紹介します

環境

  • Mac OS X 10.12.3
  • Docker on Mac 17.03.0-ce, build 60ccb22
  • goofys 0.0.9

goofys のインストール

  • brew tap homebrew/fuse
  • brew cask install osxfuse
  • brew install goofys

.aws/credentials などの設定は事前に行っておいてください
また us-east-1 に適当にバケットを作成しておいてください
今回は「c1-bd10c735e495」とします

データボリューム領域の追加

事前に Docker on Mac の設定で /data-volume をデータボリューム領域として追加しておきます
Preferences から File Sharing で「/data-volume」を追加します
docker_datavolume_s3.png

s3 のマウント

  • sudo mkdir /data-volume
  • sudo chown -R kakakikikeke:staff /data-volume/
  • goofys c1-bd10c735e495 /data-volume
  • df -h
c1-bd10c735e495  1.0Pi    0Bi  1.0Pi     0%       0 1000000000    0%   /data-volume

こんな感じでマウントできれば OK です
試しにファイルを作成してバケット上にもファイルができるか確認してみてください
アンマウントする場合は

  • umount /data-volume

で OK です

データボリュームとしてコンテナで使ってみる

  • cd /data-volume
  • docker run --name c1 -p 8080:80 -v $(pwd):/test-volume nginx

でコンテナを起動しましょう
そして

  • docker exec -it c1 /bin/bash

でログインして

  • ls /test-volume

すると s3 にあるオブジェクトを確認できると思います
ただ、コンテナから

  • echo fuga > /test-volume/fuga

という感じでデータボリューム領域に書き込もうとしても「bash: fuga: No such file or directory」と怒られてしまいました
なので

s3 -> file -> container

の GET の流れはうまく行ったのですが

container -> file -> s3

の POST の流れはうまく行きませんでした

最後に

データボリュームで s3 を使う方法を紹介しました
ホストマシン側で s3 をマウントしその領域をコンテナのデータボリュームとして利用しています

結果として GET の流れはコンテナ上でもできたのですが、POST の流れはコンテナからはできませんでした
(環境依存という可能性もありますが、、)
これを試していて思ったのですが、おそらくホストでマウントした s3 を更に docker のデータボリュームとしてマウントするのではなく、コンテナはコンテナで s3 をマウントしてホストはホストで s3 をマウントするようにしたほうが良いと思いました

今回 POST ができなかった原因は不明なのですが、おそらく権限とか docker 内部のデータボリュームの流れと goofys の流れがごっちゃになってしまっているせいかなと思います
コンテナ上でも goofys 的なのを動かして s3 をマウントすることはできると思うので、そうしたほうが良いかなと思った次第です

ただ調べてみるとそれも結構大変そうであまりおすすめできる感じではありませんでした、、、
http://qiita.com/kochizufan/items/e0253eeda0cd470c6dc8

あとは「そもそも dockerd 側のデータボリュームの領域を s3 にできないのか」という疑問を抱くと思います
実は dockerd 用のデータボリューム領域には様々なプラグインが用意されています
https://docs.docker.com/engine/extend/legacy_plugins/#volume-plugins

これを dockerd に組み込めばデーモン側のデータボリューム領域としてクラウドサービスなどを使うことができます
Docker on Mac の場合デフォルトで「local」というプラグインが使われています
docker info コマンドを使えば確認することができます

これまでは dockerd 周りの拡張や検証はほとんど行ってこなかったので、その辺の dockerd 周りの検証もそのうちやりたいなと思っています

参考サイト

2017年3月15日水曜日

docker のデータボリュームで別コンテナの領域をマウントする方法

概要

前回 docker のデータボリュームの使い方を紹介しました
今回は別の使い方として別コンテナの領域をコンテナのデータボリュームとして使う方法を紹介します

環境

  • Mac OS X 10.12.3
  • Docker on Mac 17.03.0-ce, build 60ccb22

使い方

  • docker run --name c1 -p 8080:80 -v /share nginx

で「/share」をデータボリュームとして作成します
次に別のコンテナを作成します
このときに初めに起動したコンテナを --volumes-from オプションを付与して起動します

  • docker run --name c2 -p 8081:80 --volumes-from c1 nginx

こうすることで c1 コンテナでマウントした /share 領域が c2 領域でもマウントされています

動作確認

  • docker exec -it c2 /bin/bash

で、c2 コンテナに入って touch /share/hoge.txt します
その後で

  • docker exec -it c1 /bin/bash

をして /share 配下を確認すると hoge.txt が存在することが確認できると思います

root@32896c0881c4:/# ls /share/
hoge.txt

最後に

docker のデータボリュームで別コンテナのマウント領域を使用する方法を紹介しました
この機能はボリュームコンテナと呼ばれる機能でデータを管理する専用のコンテナを作ることでデータの管理を一元化できるメリットがあります

ある一つのコンテナだけデータを永続化する機能を持っており、他のコンテナはそのコンテナを参照するだけになります
すべてのコンテナがデータを永続化する領域をマウントする必要がなくなるので管理が容易になります

参考サイト

2017年3月14日火曜日

docker のデータボリュームでホスト上の領域をマウントする方法

概要

前回 docker のデータボリュームの使い方を紹介しました
今回は別の使い方としてホスト上の領域をコンテナのデータボリュームとして使う方法を紹介します

環境

  • Mac OS X 10.12.3
  • Docker on Mac 17.03.0-ce, build 60ccb22

使い方

使い方は簡単で「-v」オプションにホスト上の領域を指定するだけです

  • mkdir /Users/hawksnowlog/data-volume
  • cd /Users/hawksnowlog/data-volume
  • touch hoge.txt
  • docker run --name c1 -p 8080:80 -v $(pwd):/test-volume nginx

これで「/Users/hawksnowlog/data-volume」の領域をコンテナ上でマウントすることができます
確認してみましょう

  • docker exec -it c1 /bin/bash
root@68f23c53f12a:/# ls /test-volume/
hoge.txt

こんな感じです
今回は docker のデータボリューム領域を作成していません
なので、docker volume ls などで領域を確認しても新規で作成されていないのが確認できると思います

最後に

docker のデータボリュームをホスト上の領域として使う方法を紹介しました
この方法が一番単純で直感的で簡単な方法かなと思います

ホスト上の領域を NFS や LVM にすることで拡張することも簡単にできます

2017年3月13日月曜日

docker のデータボリュームを試してみた

概要

docker のデータボリュームの挙動を調べてみました
データボリュームは簡単に言えばデータを永続化するための領域です
コンテナとは別の領域にデータボリュームの領域を作成することで実現します
今回は Docker on Mac で試しました

環境

  • Mac OS X 10.12.3
  • Docker on Mac 17.03.0-ce, build 60ccb22

ボリュームを作成する

まずは単純に領域を作成してみましょう
作成する方法はいろいろありますが、とりあえず run コマンドから作成します

  • docker run --name c1 -p 8080:80 -v /test-volume nginx

「/test-volume」という領域をコンテナ上に新規で作成します
同時にホスト上にも領域が作成されます

  • docker volume ls
DRIVER              VOLUME NAME
local                 3a7ad65099591e7bbe2234aa4db

VOLUME NAME はちょっと長かったので短縮しています
コンテナ上でマウントしている情報を確認するには inspect コマンドを使います

  • docker inspect --format='{{ .Mounts }}' c1
[{volume 3a7ad65099591e7bbe2234aa4db /var/lib/docker/volumes/3a7ad65099591e7bbe2234aa4db/_data /test-volume local  true }]

ホスト上の「/var/lib/docker/volumes/3a7ad65099591e7bbe2234aa4db/_data」という領域をコンテナ上にマウントすることでデータを永続化しています
コンテナを停止して削除してもデータボリュームは削除されていないことが確認できると思います

ホスト上の領域を確認する

では先ほど確認した「/var/lib/docker/volumes/3a7ad65099591e7bbe2234aa4db/_data」の領域をホスト上で確認してみましょう

Docker on Mac の場合はホスト上の領域が少し特殊でデータ領域用の VM が動作しています
なので Mac 上で ls /var/lib/docker/volumes/ とか打っても「そんなディレクトリはありません」と怒られると思います

データ領域用の VM にログインして確認してみます
ログインするには screen コマンドを使います

  • screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty

ユーザ名とパスワードは特に要求されないと思います
でプロンプトを表示して ls コマンドを実行してみます

/ # ls -ltrh /var/lib/docker/volumes
total 28
drwxr-xr-x    3 root     root        4.0K Mar 13 01:31 3a7ad65099591e7bbe2234aa4db
-rw-------    1 root     root       32.0K Mar 13 01:40 metadata.db

するとこんな感じで表示されると思います
その配下の _data ディレクトリ配下に実際にコンテナ上で作成したファイルも存在することが確認できると思います

試しにデータボリューム上 or コンテナ上で対象の領域に touch コマンドなどでファイルを作成してデータが共有されているか確認すると良いと思います

  • docker exec -it c1 /bin/bash
  • touch /test-volume/hoge.txt

ホスト側のデータボリュームの領域上で

  • ls -l /var/lib/docker/volumes/3a7ad65099591e7bbe2234aa4db/_data/hoge.txt

で存在が確認できると思います

別のコンテナから使う

これでコンテナからデータを削除してもデータが消失しないことがわかりました
では次に別のコンテナでデータボリュームの領域を使用してみます
-v オプションでデータボリュームの ID を指定すれば OK です

  • docker run --name c2 -p 8080:80 -v 3a7ad65099591e7bbe2234aa4db:/test-volume nginx

という感じです
これでコンテナ上で「/test-volume」の領域を確認すると先ほど別のコンテナで作成した hoge.txt が存在するのが確認できると思います

Tips

データボリューム領域はコンテナを削除しても残ります
データボリューム領域を削除したい場合は rm コマンドを利用します

  • docker volume rm 3a7ad65099591e7bbe2234aa4db

で OK です
当然ですが、データボリュームを使用中のコンテナが動作している場合は削除することができません

今回新規でデータボリュームを作成するのに run コマンドのオプションを使いました
docker volume create というコマンドもあるので、これを使って先に作成しておくことも可能です

  • docker volume create --name v1

--name を指定することでランダムな ID ではなく名前を付与することができます
ただし 1 文字のデータボリュームを作成することはできないようです

データボリュームはコンテナを削除してもなくならないと紹介しました
実は run をしたときに --rm オプションを付与するとコンテナを削除したときにデータボリュームも同時に削除することが可能です

  • docker run --rm --name c3 -p 8080:80 -v /test-volume nginx

とするとコンテナが起動しつづけてる間は docker volume ls で確認できると思いますが、コンテナを削除するとデータボリューム領域がなくなっていることが確認できると思います

最後に

docker のデータボリュームの挙動を実際にコマンドを実行しながら試してみました
基本的にはホスト上に永続化のための領域を作成して、それをコンテナが適宜マウントして使うことで実現しています

データボリュームには他にもホスト上のすでに存在するディレクトリを領域として使う方法や、他のコンテナの領域をデータボリュームとして使う方法もあります
この辺りの別の使い方も次回紹介したいと思います

参考サイト