【Windows10】 Docker for Windows インスト

https://docs.docker.com/docker-for-windows/の下の
WindowsのシンボルのDOWNLOADボタンを押しインストーラをGET。
dl

これをインストする。
instrer
手順で特に注意が必要なとこはない。
DockerToolboxもあるがこっちはOracleのVirtualBox専用らしい。
toolbox
VirtualBoxとHyper-VはCPUの仮想化機能を使うサービスなので、いづれか一方しか使えないので不要。
Docker for Windowsをインストすると、MobyLinuxVM ができる。
これがDockerのサーバーらしい。
vm
起動を完了すると、クジラのヘルプがPOPするようだ。
help
NVIDIA Docker にはディープラーニングの定食なVMイメージもあるらしいけど・・・
試しにubuntuのVMでbashを実行してみよう。
Windowsのコマンドラインからubuntuを動かしてみる。

docker run -it ubuntu bash
Unable to find image ‘ubuntu:latest’ locally
latest: Pulling from library/ubuntu
6bbedd9b76a4: Pull complete
fc19d60a83f1: Pull complete
de413bb911fd: Pull complete
2879a7ad3144: Pull complete
668604fde02e: Pull complete
Digest: sha256:2d44ae143feeb36f4c898d32ed2ab2dffeb3a573d2d8928646dfc9cb7deb1315
Status: Downloaded newer image for ubuntu:latest

という感じで自動的にダウンロードなどをやってくれるのでとても手軽。
では先日インストに失敗したCaffeのイメージを探してみよう。

> docker search caffe

NAME                                DESCRIPTION                                    
tleyden5iwx/caffe-cpu-master                                                      
tleyden5iwx/caffe-gpu-master                                                      
kaixhin/caffe                     Ubuntu Core 14.04 + Caffe.                     
kaixhin/cuda-caffe           Ubuntu Core 14.04 + CUDA + Caffe.

・・・

と沢山でてくる。 kaixhin/caffeがいいかな?docker pull kaixhin/caffeでダウンロードできるけど。
Cafferのホームページのインストページに、

がある。この先の https://github.com/BVLC/caffe/tree/master/docker/standalone/cpu にCPU用のDockerファイルがあるのでこれを使う。

とあるので、適当な場所に standalone/cpuなフォルダを作り、上のurlのDockerfileをコピる。

dockerのbuildコマンドを使ってコンテナで使うイメージを作成する。

>docker build --help
Usage:  docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
Options:
      --build-arg value         Set build-time variables (default [])
      --cgroup-parent string    Optional parent cgroup for the container
      --cpu-period int          Limit the CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int           Limit the CPU CFS (Completely Fair Scheduler) quota
  -c, --cpu-shares int          CPU shares (relative weight)
      --cpuset-cpus string      CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string      MEMs in which to allow execution (0-3, 0,1)
      --disable-content-trust   Skip image verification (default true)
  -f, --file string             Name of the Dockerfile (Default is 'PATH/Dockerfile')
      --force-rm                Always remove intermediate containers
      --help                    Print usage
      --isolation string        Container isolation technology
      --label value             Set metadata for an image (default [])
  -m, --memory string           Memory limit
      --memory-swap string      Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --no-cache                Do not use cache when building the image
      --pull                    Always attempt to pull a newer version of the image
  -q, --quiet                   Suppress the build output and print image ID on success
      --rm                      Remove intermediate containers after a successful build (default true)
      --shm-size string         Size of /dev/shm, default value is 64MB
  -t, --tag value               Name and optionally a tag in the 'name:tag' format (default [])
      --ulimit value            Ulimit options (default [])

と長い説明から・・・Dockerfileはurlでもいいので、ダウンロードしなくても良いことが判るが、ここではローカルのDockerfileのパスを指定する。(笑

> docker build -t caffe:cpu standalone/cpu

caffe はリポジトリィ名、cpuはタグ、standalone/cpuはDockerfileを置いてあるフォルダという感じ。

今まで作ったり、実行したりしたものは

> docker images で見れる。

REPOSITORY TAG IMAGE ID CREATED SIZE
caffe cpu ad7eaf33fd93 13 hours ago 1.332 GB
ubuntu latest f753707788c5 2 weeks ago 127.2 MB
ubuntu 14.04 1e0c3dd64ccd 2 weeks ago 187.9 MB

imageディスクは先のMobyLinuxVMの中にできるらしい。Hyper-VにあるMobyLinuxVMの「設定」を見れば、MobyLinuxVM.vhdxの居場所が判るけど、右クリックして「マウント」は不可。

キャッシュされている内容でおかしくなる場合には–no-cacheを指定すればよさそうだ。

Dockerfileの内容のせいでまだまだ処理中。

今の状況は

docker ps で見れる。

CONTAINER   ID IMAGE     COMMAND                CREATED        STATUS        PORTS NAMES
ec6ac6533bc6 01c4d46d8ed5 "/bin/sh -c 'apt-get " 44 minutes ago Up 44 minutes zen_shaw

かなり時間がたったようだ。 Dockerfileを読んでみると

RUN git clone -b ${CLONE_TAG} --depth 1 https://github.com/BVLC/caffe.git . && \
    for req in $(cat python/requirements.txt) pydot; do pip install $req; done && \
    mkdir build && cd build && \
    cmake -DCPU_ONLY=1 .. && \
    make -j"$(nproc)"

とmake test やmake runtest が含まれていない。あ、cmakeだ!(汗
(・・・待機中・・・)
やっと終わったらしい。

Windowsのコマンドラインから

> docker run -i -t caffe:cpu //bin/bash
$ cd /opt/caffe/build
$ make test
$ make runtest
[  1%] Built target proto
 [ 60%] Built target caffe
 Scanning dependencies of target gtest
 [ 60%] Building CXX object src/gtest/CMakeFiles/gtest.dir/gtest-all.cpp.o
 Linking CXX static library ../../lib/libgtest.a
 [ 60%] Built target gtest
 Scanning dependencies of target test.testbin
 [ 61%] Building CXX object src/caffe/test/CMakeFiles/test.testbin.dir/test_split_layer.cpp.o
 [ 61%] Building CXX object src/caffe/test/CMakeFiles/test.testbin.dir/test_internal_thread.cpp.o
・・・中略・・・
[100%] Building CXX object src/caffe/test/CMakeFiles/test.testbin.dir/test_layer_factory.cpp.o
 Linking CXX executable ../../../test/test.testbin
 [100%] Built target test.testbin
 Scanning dependencies of target runtest
 libdc1394 error: Failed to initialize libdc1394
 Note: Google Test filter = -*GPU*
 Note: Randomizing tests' orders with a seed of 3012 .
 [==========] Running 1096 tests from 150 test cases.
 [----------] Global test environment set-up.
 [----------] 7 tests from CPUMathFunctionsTest/1, where TypeParam = double
 [ RUN      ] CPUMathFunctionsTest/1.TestFabs
 [       OK ] CPUMathFunctionsTest/1.TestFabs (16 ms)
 [ RUN      ] CPUMathFunctionsTest/1.TestScale
 [       OK ] CPUMathFunctionsTest/1.TestScale (16 ms)
・・・中略・・・
[----------] Global test environment tear-down
 [==========] 1096 tests from 150 test cases ran. (53662 ms total)
 [  PASSED  ] 1096 tests.
 [100%] Built target runtest
 root@12f9e48c546e:/opt/caffe/build# exit

>

よかった無事完走した。(笑
exitしたら、make runtest 分のコンパイルした結果はRollbackされました。(笑
MobyLinuxVMを終了しPCをシャットダウンしたら、PCを起動するとDocker for Windows でエラー表示。
MobyLinuxVMが止まっていたので、起動しようとしたけど、起動失敗。
MobyLinuxVMを自動起動に変えて、再起動したらOKだった。

また同じイメージを作ってみる。イメージの名前は変える。

>docker build -t caffe:cpu2 standalone/cpu
 Sending build context to Docker daemon 3.072 kB
 Step 1 : FROM ubuntu:14.04
  ---> 1e0c3dd64ccd
 Step 2 : MAINTAINER caffe-maint@googlegroups.com
  ---> Using cache
  ---> 01c4d46d8ed5
 Step 3 : RUN apt-get update && apt-get install -y --no-install-recommends         build-essential         cmake         git         wget         libatlas-base-dev         libboost-all-dev         libgflags-dev         libgoogle-glog-dev         libhdf5-serial-dev         libleveldb-dev         liblmdb-dev         libopencv-dev         libprotobuf-dev         libsnappy-dev         protobuf-compiler         python-dev         python-numpy         python-pip         python-scipy &&     rm -rf /var/lib/apt/lists/*
  ---> Using cache
  ---> 890a4a41fda2
 Step 4 : ENV CAFFE_ROOT /opt/caffe
  ---> Using cache
  ---> e1ba92b55d31
 Step 5 : WORKDIR $CAFFE_ROOT
  ---> Using cache
  ---> 6b73698ab96f
 Step 6 : ENV CLONE_TAG master
  ---> Using cache
  ---> 31c37107dd1f
 Step 7 : RUN git clone -b ${CLONE_TAG} --depth 1 https://github.com/BVLC/caffe.git . &&     for req in $(cat python/requirements.txt) pydot; do pip install $req; done &&     mkdir build && cd build &&     cmake -DCPU_ONLY=1 .. &&     make -j"$(nproc)"
  ---> Using cache
  ---> 60860beb44fc
 Step 8 : ENV PYCAFFE_ROOT $CAFFE_ROOT/python
  ---> Using cache
  ---> 79fa9e5c0809
 Step 9 : ENV PYTHONPATH $PYCAFFE_ROOT:$PYTHONPATH
  ---> Using cache
  ---> fef2e3296e15
 Step 10 : ENV PATH $CAFFE_ROOT/build/tools:$PYCAFFE_ROOT:$PATH
  ---> Using cache
  ---> de009e192069
 Step 11 : RUN echo "$CAFFE_ROOT/build/lib" >> /etc/ld.so.conf.d/caffe.conf && ldconfig
  ---> Using cache
  ---> afb970a41ff9
 Step 12 : WORKDIR /workspace
  ---> Using cache
  ---> ad7eaf33fd93
 Successfully built ad7eaf33fd93
 SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

と警告が出る。キャッシュを使っているのか?すぐ出来上がるので便利だ。
しかも、docker images で前に作ったイメージと見比べるとIMAGE IDが同じ。
つまり、同じ内容のDockerfileを何度実行しても、リポジトリィ上ではタグを貼っただけの扱い。
動作中のコンテナはdocker ps で、停止中のモノも含める場合は docker ps -a でコンテナをリストアップできる。

> docker ps --help
Usage:  docker ps [OPTIONS]
List containers
Options:
  -a, --all             Show all containers (default shows just running)
  -f, --filter value    Filter output based on conditions provided (default [])
      --format string   Pretty-print containers using a Go template
      --help            Print usage
  -n, --last int        Show n last created containers (includes all states) (default -1)
  -l, --latest          Show the latest created container (includes all states)
      --no-trunc        Don't truncate output
  -q, --quiet           Only display numeric IDs
  -s, --size            Display total file sizes

docker ps -aすると結構ゴミが溜まってしまっていることが判る。
まめにdocker rm で消した方が良さそう。

> docker rm --help
Usage:  docker rm [OPTIONS] CONTAINER [CONTAINER...]
Remove one or more containers
Options:
  -f, --force     Force the removal of a running container (uses SIGKILL)
      --help      Print usage
  -l, --link      Remove the specified link
  -v, --volumes   Remove the volumes associated with the container

ググってみると、Linuxならこんな風に使えるらしい。

  • 1週間も過ぎたコンテナは消す ※1ヵ月以上も放置したものは別腹
    • $ docker ps -a | grep ‘weeks ago’ | awk ‘{print $1}’ | xargs docker rm
  • 停止中のコンテナを一気に削除する
    • $ docker rm `docker ps -aq`
  • コンテナをすべて強制的に削除する
    • $ docker rm -f `docker ps -aq`

Windowsでは無理かと思ったら、for /f %a in (‘コマンド’) do  **** というのがあった。
またUnix系っぽく、for /f “usebackq” %a in (`コマンド`) do  **** と書ける。
これって・・・もしかして( ^ω^)・・・

> echo `docker ps`
`docker ps`  ⊂⌒~⊃。Д。)⊃ ドテッ

それではWindowsの場合

  • 1週間も過ぎたコンテナは消す (多分これでいいはず、動作未確認)
    • > for /f “tokens=1 usebackq” %a in (`docker -a | find “weeks ago”`) do docker rm %a
      • ※期待通り!
      •  『| の使い方が誤っています。』が返ってくるので、
      • 下の2行になる。
    • > docker -a | find “weeks ago”  > aaa.txt
      for /f “tokens=1” %a in (aaa.txt) do docker rm %a

      • tokens=1:ファイルの1列目だけ%aに入る。
  • 停止中のコンテナを一気に削除する
    • > for /f “usebackq” %a in (`docker ps -aq`) do docker rm %a
  • コンテナをすべて強制的に削除する
    • > for /f “usebackq” %a in (`docker ps -aq`) do docker rm -f %a

さて、ゴミの処分方法は判ったけど、run してコンテナでチョコっと遊んで消すならこのままがいいけど、『続きは別の場所で・・・』となる場合は困ってしまう。

イメージをPCに保存する方法

>docker save --help
Usage:  docker save [OPTIONS] IMAGE [IMAGE...]
Save one or more images to a tar archive (streamed to STDOUT by default)
Options:
      --help            Print usage
  -o, --output string   Write to a file, instead of STDOUT

IMAGEにはdocker imagesのIMAGE IDかREPOSITORY:TAGを指定する。
この指定の差で、tarファイルの中のmanifest.jsonの中身が若干変わり、IMAGE IDの場合は、”RepoTags”:nullになるので、これをloadすると、

> docker save -o caffe5.tar ad7eaf33fd93
> docker load -i caffe5.tar
Loaded image ID: sha256:ad7eaf33fd93e5b82e4f803351c19b4d00f20d583c7853426bb9ef3e93a94811
> docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> ad7eaf33fd93 18 hours ago 1.332 GB
ubuntu latest f753707788c5 2 weeks ago 127.2 MB
ubuntu 14.04 1e0c3dd64ccd 2 weeks ago 187.9 MB

となるので、REPOSITORY:TAGの形式でIMAGEを指定した方が良さそう。
標準出力のリダイレクトを使ってtarファイルに書き出したり

docker save ad7eaf33fd93 > caffe2.tar

パラメータ(-o)でtarファイル名を指定したりできる

docker save -o caffe3.tar ad7eaf33fd93

※この場合、存在しないファイル名を指定する.docker_temp_999999999な作業ファイルを作る。
ファイル名は何でもいいはずだけど普通はtar拡張子を付ける。
Windows10の癖だと思われるが・・・caffe:cpu.tar を指定すると、 0バイトのcaffe ファイルができるので妙な記号は避ける。
展開したらcafferフォルダができ、manifest.json、repositories、ad7ea・・・11.jsonと沢山のフォルダ。
tar%e5%b1%95%e9%96%8b
repositoriesは{“caffe”:{“cpu”:”395b・・・b2195″}}な感じ。
中のフォルダはjson、layer.tar、VERSIONファイルで、layer.tarには作成したフォルダやファイルが入っている。

PCのイメージをdockerに取り込む方法

>docker load --help
Usage:  docker load [OPTIONS]
Load an image from a tar archive or STDIN
Options:
      --help           Print usage
  -i, --input string   Read from tar archive file, instead of STDIN
  -q, --quiet          Suppress the load output

標準入力のリダイレクトを使ってSAVEしたtarファイルを読んだり

> docker load  < caffe.tar
Loaded image: caffe:cpu

パラメータ(-i)でtarファイル名を指定したりできる

> docker load  -i caffe.tar
Loaded image: caffe:cpu

タグの無いtarファイルの場合は、docker importの方がいいかもしれない。

>docker import --help
Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
Import the contents from a tarball to create a filesystem image
Options:
 -c, --change value Apply Dockerfile instruction to the created image (default [])
 --help Print usage
 -m, --message string Set commit message for imported image

imageを消す方法

>docker rmi --help
Usage:  docker rmi [OPTIONS] IMAGE [IMAGE...]
Remove one or more images
Options:
  -f, --force      Force removal of the image
      --help       Print usage
      --no-prune   Do not delete untagged parents

IMAGEは docker images で出てくるIMAGE ID(REPOSITORY:TAGでも可)を指定するので、同じIMAGE ID(先のCPU2)は一緒に消えてしまうが、–no-pruneを指定すればlatestだけ残りそう。

>docker rmi -f ad7eaf33fd93
Untagged: caffe:cpu
Untagged: caffe:cpu2
Deleted: sha256:ad7eaf33fd93e5b82e4f803351c19b4d00f20d583c7853426bb9ef3e93a94811
Deleted: sha256:afb970a41ff9f943b00493028f08c8309d1fc5a95b6f0a75f70cc532188fa89f
Deleted: sha256:de009e192069e27bd8867bf379e3d958f33be805088e929b748ca5d516f8fb42
Deleted: sha256:fef2e3296e15c5c643298fd7a9b6f7e857d2ea48a4921ad1edc436708022cc40
Deleted: sha256:79fa9e5c0809c841137ce2bb123ec1ae4a4078b89268825a2876ef68c5a3a81c
Deleted: sha256:60860beb44fc0a01b1207cfa417b5c7d338c100c7da6775661526cba17d089f0
Deleted: sha256:31c37107dd1fde8a16bf90b4a75385fd7fabbdef85cb73a056ef8bf021056628
Deleted: sha256:6b73698ab96f4211c9f025cb8544542f8918d98d6411bb2fabfd8fab635ac704
Deleted: sha256:e1ba92b55d31a27052e275501d7aca2485ebbbc04d4f3269870f0aab08df8073
Deleted: sha256:890a4a41fda2c623eee699e1d2d642b1ae3988f82f47e18078973cb6825f6553
Deleted: sha256:01c4d46d8ed54f2b3c24058ead1ef3e896e2b5ef6604ddbabd3c2a6cf3424ff7

実装はBUILDするとリポジトリィを作成し、Dockerfileでそこに差分をどんどん保存していく、出来上がったものはリポジトリィのタグを指定してrunしてみる。な感じなのだろう。
インストールが面倒すぎるパッケージをちょっと遊ぶには、Hyper-Vでゲストを作り、OS込みで一式にインスト-ルしなくてもいいので便利だ。
ただdocker run した後は、元に戻ってしまう。

> docker run -it ubuntu //bin/bash
root@7b39b74c7be6:/# adduser aaa
# ls /home
aaa

ここで、別のコマンドラインから

> docker diff 7b39b74c7be6
C /etc
C /etc/group
A /etc/group-
C /etc/gshadow
A /etc/gshadow-
C /etc/passwd
A /etc/passwd-
C /etc/shadow
A /etc/shadow-
C /etc/subgid
A /etc/subgid-
C /etc/subuid
A /etc/subuid-
C /home
A /home/aaa
A /home/aaa/.bash_logout
A /home/aaa/.bashrc
A /home/aaa/.profile
C /var
C /var/log
C /var/log/faillog
C /var/log/lastlog

とファイルの差分が判ります。これを再利用するつもりなら、タグ(aaa/bbb等)付けしてリポジトリィに保存。

> docker commit 7b39b74c7be6  aaa/bbb
sha256:3bd6d902e023c540eaec3dcd3efeb4c4078d547aeba30d2bc82be796a6a49129

ちゃんとリストにも出るので、不要になったら docker rmi で消せます。

> docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
aaa/bbb             latest              3bd6d902e023        27 seconds ago      127.5 MB

勿論ファイルに保存もできますが、大元のイメージ(この場合はububtu:lastest)が無い環境ではrunできなさそうと思いきや、Dockerfileのfrom 以降全ての差分が入ってる様で結構でかいです。

> docker save aaa/bbb > aaa-bbb.tar

それにちょっと使うにはいいけど、いきなり停電したりすると全ては泡と消えてしまいます。
docker run の -v オプションで dockerのホストのどこかをコンテナにマウントできます。

> docker run -d -v /var/host_lib/mysql:/var/lib/mysql me/mysql_x_x  ubuntu
※ホストの/var/host_lib/mysqlがコンテナの/var/lib/mysql me/mysql_x_xにマウントされるので、コンテナを終了してもデータは残る。

でもホストのファイルシステムにベタに置くのはちょっとアレです。※ログ収集ならこれが一番なんだろうなぁ~。
それよりデータ格納用のコンテナの方が運用は楽そうです。そして不要になったら削除すればいい。
Dockerfileで永続性(VOLUME指定)付きでデータ格納用のイメージを作り、

FROM 適当なのでいいハズ
VOLUME /opt
CMD /bin/sh

docker run –name {ユニークな名前}でコンテナを作ります。
もう一度、docker run –name  {ユニークな名前} を指定して何かをすると、コンフリクトとエラーになるので保持されていることが判ります。
そこで、docker run –volume-from  {先のユニークな名前} を指定して何かを実行すれば、{先のユニークな名前}の中だけ永続性が保たれるわけです。
ただ、イメージとしてではなく、コンテナとして保持される点が要注意。
dockerを再起動したら、やはり消えるのかな?




コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA