Docker 覚書

_images/docker-logo.jpeg

0. Docker install & setup

0.1 install

使用している処理系によって異なります。Ubuntuであれば、↓だけでOK

$ sudo apt-get install docker.io

$ docker --version
Docker version 1.0.1, build 990021a

自動起動に設定

$ sudo update-rc.d docker.io defaults

 Adding system startup for /etc/init.d/docker ...
   /etc/rc0.d/K20docker -> ../init.d/docker
   /etc/rc1.d/K20docker -> ../init.d/docker
   /etc/rc6.d/K20docker -> ../init.d/docker
   /etc/rc2.d/S20docker -> ../init.d/docker
   /etc/rc3.d/S20docker -> ../init.d/docker
   /etc/rc4.d/S20docker -> ../init.d/docker
   /etc/rc5.d/S20docker -> ../init.d/docker

Note

将来バージョンアップするときは

$ sudo apt-get update
$ sudo apt-get install docker.io

0.2 確認

$ sudo docker info
Containers: 0
Images: 0
Storage Driver: devicemapper
 Pool Name: docker-8:1-262163-pool
 Data file: /var/lib/docker/devicemapper/devicemapper/data
 Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata
 Data Space Used: 291.5 Mb
 Data Space Total: 102400.0 Mb
 Metadata Space Used: 0.7 Mb
 Metadata Space Total: 2048.0 Mb
Execution Driver: native-0.1
Kernel Version: 3.13.0-24-generic
WARNING: No swap limit support
$ sudo docker version
Client version: 1.0.1
Client API version: 1.12
Go version (client): go1.2.1
Git commit (client): 990021a
Server version: 1.0.1
Server API version: 1.12
Go version (server): go1.2.1
Git commit (server): 990021a

コマンドがdocker => docker にしたいときはシンボリックリンクを設定しましょう

$ sudo ln -sf /usr/bin/docker /usr/local/bin/docker

5. 便利に使う方法 tips集 (sudo を省く方法)


Dockerコマンド

Dokcker では仮想マシンにインストールされるOSやソフトウェアの「イメージ」と そのイメージで実行する個々の仮想マシンである「コンテナ」、という概念で管理します。

これらを扱うために、まずは以下の4つの動作を確認しましょう。

実行するOS元データである”image” と実際に実行するインスタンスとなる”container”の2つの要素に触ってみましょう。 ライフサイクルは以下のような流れになります。

  1. Dockerイメージを取得 (docker pull)
  2. Dockerコンテナの作成と実行 (docker run)
  3. Dockerコンテナの停止、削除
  4. Dockerイメージの削除

依存しているコンテナがあるとイメージを削除できないため、 3=>4 の順となっています。

コマンドについて

docker コマンドは docker コマンドに命令を指定して実行します。

sudo docker <command> ....

image関連

command function example
pull コンテナイメージのダウンロード docker pull centos:7
images 取得済みのコンテナイメージ一覧 docker images
rmi イメージの削除 docker rmi centos:centos7
commit コンテナからイメージ作成 docker commit ubuntu1 devtaro/nginx

実行関連

command function example
run コンテナの新規作成と実行 docker run -it –name ubuntu1 ubuntu /bin/bash
rm コンテナの削除 docker rm ubuntu1
stop コンテナの実行停止  
start 停止したコンテナの実行  
ps コンテナのリスト表示  
kill 即座にコンテナを停止  
exec コンテナに対して実行(後述)  

※イメージ、コンテナ、どちらの操作でも docker コマンドを使います。

その他コマンド

Commands:
    attach    Attach to a running container
    build     Build an image from a Dockerfile
    commit    Create a new image from a container's changes
    cp        Copy files/folders from the containers filesystem to the host path
    diff      Inspect changes on a container's filesystem
    events    Get real time events from the server
    export    Stream the contents of a container as a tar archive
    history   Show the history of an image
    images    List images
    import    Create a new filesystem image from the contents of a tarball
    info      Display system-wide information
    inspect   Return low-level information on a container
    kill      Kill a running container
    load      Load an image from a tar archive
    login     Register or Login to the docker registry server
    logs      Fetch the logs of a container
    port      Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
    pause     Pause all processes within a container
    ps        List containers
    pull      Pull an image or a repository from the docker registry server
    push      Push an image or a repository to the docker registry server
    restart   Restart a running container
    rm        Remove one or more containers
    rmi       Remove one or more images
    run       Run a command in a new container
    save      Save an image to a tar archive
    search    Search for an image in the docker index
    start     Start a stopped container
    stop      Stop a running container
    tag       Tag an image into a repository
    top       Lookup the running processes of a container
    unpause   Unpause a paused container
    version   Show the docker version information
    wait      Block until a container stops, then print its exit code

1. 生成と実行

1.1 イメージのダウンロード

実行するOSのイメージは pull コマンドで取得します。imageは固有のイメージ名があり指定したイメージがdockerオフィシャルリポジトリからダウンロードされます。

イメージ名はオフィシャルサイトを参照するか docker search コマンドで検索することができます。

$ sudo docker pull <image-name>

docker Offical Ropositories / CentOSのページ

https://registry.hub.docker.com/_/centos/

_images/pull_centos.jpg

たとえば CentOS6 のリポジトリをpullする場合,上記に centos6, 6 (docker/Dockerfile) と書かれていますので

$ sudo docker pull centos:6

or

$ sudo docker pull centos:centos6

とするとリポジトリがDLされます。

DLされたイメージの確認は images コマンドで行います。

$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              6                   a005304e4e74        2 weeks ago         203.1 MB
centos              centos6             a005304e4e74        2 weeks ago         203.1 MB
centos              7                   7322fbe74aa5        2 weeks ago         172.2 MB
centos              6.6                 8b44529354f3        10 weeks ago        202.6 MB
centos              7.1.1503            f1dade627e25        10 weeks ago        212.1 MB

上記は centos:6, centos:centos6, centos:7 , centos:6.6, centos:7.1.1503 を pull した結果です。 6、centos6 は同じリポジトリでイメージのDLは1度だけですがすがタグはそれぞれ登録されています。 準備ができたところでコンテナの生成と実行をしてみましょう。

Warning

コンテナイメージはほとんどが64bit版です。 ホストOSも同じ64bit である必要があります。 イメージの取得自体は問題なくできますが、対応していないとエラーが出て実行ができませんので、 必ずホストOSを確認してから作業を進めてください。

(ホストOSが32bit の場合は 32bit版のコンテナが必要となりますので注意してください。)

Z.1 32bit版の対応

1.2 docker run コマンド

$ sudo docker run [オプション] [--name {コンテナー名}] {イメージ名}[:{タグ名}] [コンテナーで実行するコマンド] [引数]

option

-d:バックグラウンドで実行する(後述)。既定では、コンテナーをフォアグラウンドで実行するため、Webサーバーやアプリケーションサーバーなど常時実行するコンテナーで指定

-i:コンテナーの標準入力を開く。/bin/bashなどでコンテナーを操作する際に指定 i

-t:tty(端末デバイス)を確保する。/bin/bashなどでコンテナーを操作する際に指定

-p {ホストのポート番号}:{コンテナーのポート番号}:Dockerサーバーのホストとポートマッピングを構成

例)

$ docker run -it --name centos66 6.6 /bin/bash

例えば、コンテナを起動してbashを実行させる場合、

$ docker run -it --name ubuntu1 ubuntu /bin/bash
bash-4.1#

といった感じで、bashコマンド待となります。

bash の代わりにchef-solo を実行してセットアップすることも可能。


1.2.1 run 命令のオプション

docker run [オプション] –name [コンテナ名] [イメージ名] [コンテナで実行するコマンド] [引数]

https://docs.docker.com/reference/run/

option function example
-d バックグラウンドで実行  
-p [host-port]:[コンテナ-port] ポートマップ指定  
-i コンテナの標準入力を開く。bash起動で指定  
-t tty端末を用意する。 bash起動で指定 docker run -it ....
-v [post-dir]:[コンテナ-dir] ディレクトリ共有指定  
–name 生成するコンテナの名前を指定  

1.2.2 実行中コンテナに入る

run のあと実行中のコンテナにbashで入るには

$ docker exec -it <container_name> bash

1.3 実行と停止 start / stopコマンド

上記の実行をexitなどで中止したあと、再度実行するには start コマンドを使います。

また、停止は stop を使います。

docker start -i ubuntu

1.4 実行状態

ps コマンドで実行状態を確認できます。

docker ps -a

1.5 不要になった コンテナの削除

削除は rm コマンドです

docker rm ubuntu

1.6 commit

Docker コンテナから新しいDockerイメージを作成します。

$ sudo docker commit {コンテナー名}|{コンテナーID} [{ユーザー名}/]{イメージ名}

コンテナにnginx をインストールし、そのコンテナから新たなngnx インストール済みのコンテナを作成する場合、

$ sudo docker -i start ubuntu
bash-4.1# sudo yum -y update
bash-4.1# sudo yum -y install epel-release
... ( yum install epel-release の表示)

bash-4.1# sudo yum -y install nginx
.... (yum ngnxインストールの表示)
...

としてインストールし、

$ docker commit ubuntu1 devtaro/nginx

とすると新しいnginx入のイメージが生成されます。


1.7 (まとめ) コンテナのライフサイクル

  1. run で生成
  2. stop, start, restart で コンテナの動作の停止/再稼働
  3. commit で停止中のコンテナをイメージ化(コンテナ内部に保存されたデータなどを固定化)
  1. rm コマンドで完全削除

2. build / dockerfile

commit コマンドでイメージを作成するのとは別に build どいう方法で既存のimageとdockerfileビルド設定ファイルから新しいイメージの作成をすることができます。

シェルから手動で作成したコンテナからcommitでイメージを作成する方法に比べ、セットアップ手順がスクリプトとして記述されているため、再現や検証がしやすくなるなどメリットがあります。

Note

chef や Salt との併用は?

chef は冪等性のための仕組み. Docker は イメージをまるごと生成するのでコンセプトが違う。chefの既存の設定を再利用したい場合以外はdockerで統一したほうがいいかも?


Dockerfile

既存のイメージを元に更にアプリをインストールするなど、サーバーのセットアップを自動的に行うには Dockerfile による build 機能を使います。

(基本となるイメージ) + (Dockerfileによる追加) = (MYイメージ)

 ↓

(MYイメージ) + (コンテンツ) = (コンテンツイメージ)

のように段階的にビルドイメージを作ると、共通化して手間を省いたり、繰り返しビルドし直す時に時間の節約をすることが出来ます。
platform.dist()[0]==”debian”:

dockerfile で使うコマンド (* はDockerfileに必須の要素)の主な命令は以下の通りです。

command function example  
FROM * ベースとなるイメージを指定 FROM 32bit/ubuntu:14.04
MAINAINER 作成するイメージの作者名 MAINTAINER Kenji Satoh Interio,Inc.
RUN コマンドの実行 RUN agt-get nginx
EXPOSE 外部へ公開するポート EXPOSE 8080
ENV 環境変数の設定 ENV PATH $PATH:/usr/local/jruby/bin
ADD 指定したファイル・ディレクトリをコンテナ内にコピーします url指定が可能、TARは自動で解凍  
COPY 指定したファイル・ディレクトリをコンテナ内にコピーします url指定や、TARは自動解凍はできない  
ENTRYPOINT docker run で実行されるコマンド  
CMD docker run で実行されるコマンド  
VOLUME 外部からマウント可能なボリュームを指定  
USER コンテナで使用されるユーザーを指定  
WORKDIR 作業ディレクトリの変更  
ONBUILD 次のビルドの最後に実行されるコマンドの予約 ONBUILD RUN echo “please test new container.”

RUN命令は docker build . の実行でimage 作成のための命令ですが ENTRYPOINT, CMD は image から container を生成&実行するときに1度実行されます。

docker run コマンドでコンテナを生成するときに指定する命令を Dockerfile の中で予めデフォルト定義しておく方法として用意されています。

書式

ENTRYPOINT ["executable", "param1", "param2"] (シェルを介さずに実行。この形式を推奨)
CMD ["executable","param1","param2"] (シェルを介さずに実行。この形式を推奨)

併用する場合

ENTRYPOINT と CMD は共に RUN で実行されるコマンドを予め指定するのですが併記すると CMD で指定した値が ENTRYPOINT の引数として使われます。 (※ENTRYPOINT にすでにコマンド引数がある場合にはCMDの値は無視されます。)
ENTRYPOINT ["/usr/bin/rethinkdb"]
CMD ["--help"]
     ↓
docker run /usr/bin/enthinkdb --help

また、 CMDやENTRYPOINTが定義されていても

$ docker run <image> -d <command>

とすると command が実行され、ENTRYPOINTなどで定義された命令は無視されます.

2.2 buildしてみる

実際に簡単な Dockerfile を作成して試しにbuildしてみましょう。 上記のコマンドを ファイル名 Dockerfile のテキストファイルへ記述し、 build コマンドで新しイメージを生成します。

ワークフォルダーを作成し、 Dockerfileを下記のように作成します。

FROM  ubuntu
MAINTEINER  taro taro-kun@gmail.com
RUN apt-get update
RUN apt-get install -y nginx
EXPOSE 80
ADD index.html /usr/share/nginx/html/
ENTRYPOINT /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
  • 1行目 FROM でベースとなるイメージを指定(例ではオンラインで自動読み込みされます
  • 2行目 MAINTAINER で作成者を記述
  • 3,4行目 RUN apt-get... で apt-get を実行、nginx をインストール
  • 5行目 EXPOSE 80 で webサーバーへのアクセスport80を外部へ開く
  • 6行目 ADD 命令で指定場所に index.html をコンテナへコピー (予め Dockerfile と同じ場所に作成&設置してある場合)
  • 7行目 ENTRYPOINT で docker run で実行後に動作する命令を予約

(index.htmlの内容)

Hello Docker!!!

これをビルドしてみましょう

$ sudo docker build -t taro/nginx1.1 .

option の -t <image> で生成イメージtag名を指定 最後の . は Dockerfile のあるディレクトリ位置で、この場合 Dockefile のあるディレクトリで実行しています。

taro/nginx1.1 というイメージが作成されます。

nginx2 という名前でコンテナーを生成&実行してみましょう

$ sudo docker  run -d --name nginx2 -p 80:80 taro/nginx1.1

$ curl localhost
Hello Docker!!!

作業中に

$ docker images
$ docker ps -a

を使ってコンテナやイメージの生成を確認しながら進めてると理解しやすいでしょう。 また、build でどのように実行されているか感覚的につかみにくい場合は echo 文などを挿入して実行するなどして試行錯誤してみてください。



3. Webサーバーとして使う例

ここまでの説明で docker コマンドになれたところでより実際的な例で具体的な解説をしてゆきます。

実際のサービスでの使用を踏まえて、もう少し細かい設定をする例を見てみましょう

作成するサーバー

nginx + uWSGI + Django のWebサーバー postgres DBサーバー

作成手順

  1. 必須モジュールをインストールした base image をビルド
  2. base image を元にコンテンツをインストールした実行可能な content image をビルド
  3. 2 を自動で nginx, uwsgi などが動作するように設定
  4. postgres DBサーバー
  5. コンテンツサーバーとpostgres サーバーの繋ぎこみ

Note

!


3.1 base image の作成 (taro/django_base)

必要なモジュールをインストールしたベースとなるimageを作成します。

Dockerfile

FROM nginx
MAINTAINER  Wataru Ishizuka xxx@gmail.com

RUN apt-get update

# python
RUN apt-get install -y python-setuptools python-dev libpq-dev python-pip

#uwsgi
run apt-get install -y uwsgi

run apt-get install -y python-software-properties
run apt-get install -y supervisor
run apt-get install -y uwsgi-plugin-python         #コレ重要
run apt-get update

#pip
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r /code/requirements.txt

requirements.txt / pip install 用

Pillow
psycopg2
django
django_compressor
pytz

build_base_image.sh, ビルド実行用

#!/bin/bash
docker build -t wataru/django_base .

Note

後々のために、docker コマンドのコンソール直打ちはさけ、スクリプトを作成する。


3.2 content image ( taro/content )

コンテンツのインストール、各種設定ファイルをコピーします。

FROM wataru/django_base
MAINTAINER wataru wash.fuel@gmail.com
ENV PYTHONUNBUFFERED 1
RUN apt-get updat

#APP
RUN mkdir /code
WORKDIR /code

# django app install
RUN mkdir /var/www/
RUN mkdir /var/www/django/
ADD ar_cms.tar /var/www/django/
#WORKDIR /var/www/django/ar_cms/                 #コンテナ生成時にpostgresqlのコンテナサーバーとリンクしてから実行します
#RUN python manage.py makemigrations cms
#RUN python manage.py migrate
#RUN python manage.py dbsetup
#RUN python manage.py restore backup/backup_20150427-1447.json

#
WORKDIR /code/
ADD setting/supervisor-app.conf /code/supervisor-app.conf
RUN ln -s /code/supervisor-app.conf /etc/supervisor/conf.d/

#avoid uwsgi running as root
RUN adduser app_owner
RUN chown -R app_owner:app_owner /var/www/django/ar_cms/

#nginx
ADD setting/ar.conf /etc/nginx/conf.d/app.conf
RUN rm /etc/nginx/conf.d/default.conf

#uwsgi
RUN mkdir /etc/uwsgi
ADD setting/9090_uwsgi_app.ini /etc/uwsgi/9090_uwsgi_app.ini

#django wsgi for docker-patched
ADD setting/wsgi.py /var/www/django/ar_cms/ar_cms/wsgi.py

#boot
EXPOSE 80
cmd ["supervisord","-n"]

RUN echo "running django app

build_content.sh / コンテンツイメージビルド用

#!/bin/bash
docker build -t wataru/django_ar .
docker run -d --name django_ar -p 80:80 wataru/django_ar         #実行

/etc/nginx/conf.d/app.conf / (デフォルトではいっている default.conf は今回不要なので削除しています)

:9090 は サブドメインで複数のアプリを動作させる場合の対処。 その場合、 uwsgi を emperor モードで実行するための設定が必要となります。

   server {
       listen       80;
       server_name  localhost;
       location / {
           include uwsgi_params;
           uwsgi_pass 127.0.0.1:9090;
       }
       location /media {
           alias /var/www/django/ar_cms/media;
       }
       location /static/media {
           alias /var/www/django/ar_cms/media;
       }
       location /admin_media {
           alias /var/django/ar_cms/admin/media;
       }
       access_log  /var/log/nginx/ar-access_log;
       error_log   /var/log/nginx/ar-error_log;
   }


----

9090_uwsgi_app.ini / Django アプリを実行するための設定

[uwsgi]
uid = app_owner
gid = app_owner
master = true
chdir = /var/www/django/ar_cms
uwsgi-socket = 127.0.0.1:9090
pythonpath = /var/www/django/ar_cms/ar_cms
module = ar_cms.wsgi
plugins= python,logfile              #uWSGI が動かない時はコレがない場合あり。
processes = 4
threads = 2
req-logger = file:/tmp/uwsgi-reqlog
logger = file:/tmp/uwsgi-errlog

nginx.conf / nginx 起動設定.

user  nginx;
worker_processes  1;
daemon off;                 #フォアグランド実行(重要)

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

動かない時の確認方法

bash で中に入り、 ps -ax で nginx, uwsgi が動作しているか確認、更に supervisorctl restart all で再実行を行い、各種のログファイルを確認します。

$ ps -ax
 PID TTY      STAT   TIME COMMAND
   1 ?        Ss     0:00 /usr/bin/python /usr/bin/supervisord -n
   9 ?        S      0:00 /usr/bin/uwsgi --ini /etc/uwsgi/9090_uwsgi_ar.ini
  11 ?        Ss     0:00 nginx: master process /usr/sbin/nginx
  12 ?        S      0:00 nginx: worker process
  17 ?        Sl     0:00 /usr/bin/uwsgi --ini /etc/uwsgi/9090_uwsgi_ar.ini
  18 ?        Sl     0:00 /usr/bin/uwsgi --ini /etc/uwsgi/9090_uwsgi_ar.ini
  19 ?        Sl     0:00 /usr/bin/uwsgi --ini /etc/uwsgi/9090_uwsgi_ar.ini
  22 ?        Sl     0:00 /usr/bin/uwsgi --ini /etc/uwsgi/9090_uwsgi_ar.ini
 133 ?        S      0:00 bash
 140 ?        S      0:00 /usr/sbin/nginx
 141 ?        R+     0:00 ps -ax


$ docker exec -it  django_ar bash

$ supervisorctl restart all


Note

この例では /tmp/uwsgi-errlog , /var/log/nginx/ar-error.log などがあるはずなのでそれらのファイルもチェックします。


3.3 ENTRYPOINT, supervisor による実行

実行に必要な処理の解説

nginx, uwsgi が動作する必要があるため、 supervisor を使って設定しています。 Dockerfile 最後の CMD コマンドで supervisord -n の実行を指定しています。 ADD命令でコピーした supervisor-app.conf は以下のようになっています。

supervisor-app.conf / daemon動作させる uwsgi , nginx を定義

[program:app-uwsgi]
command = /usr/local/bin/uwsgi --ini /etc/uwsgi/9090_uwsgi_app.ini

[program:nginx-app]
command = /usr/sbin/nginx

Note

nginx.conf の中で daemon off; を指定しているのでフォアグラウンド実行になっています。 フォアグラウンド実行がないと docker コンテナが終了してしまうので注意が必要です。


3.4.1 postgresql サーバー

docker の公式ページにpostgresql サーバーの立て方が詳しく書かれています。

https://docs.docker.com/examples/postgresql_service/

手順は

  1. Dockerfile 作成
  2. 起動
  3. テスト

Dockerfileはコメント付きのサンプルが上記サイトにあります。(以下、コピー)

3.4.2 postgress setup

上記サイトのDockerfile を使ってbuild, 実行、テストの流れは以下のようになります。

Dockerfile

# vim:set ft=dockerfile:
FROM debian:jessie

# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r postgres && useradd -r -g postgres postgres

# grab gosu for easy step-down from root
RUN gpg --keyserver pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \
    && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.2/gosu-$(dpkg --print-architecture)" \
    && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/1.2/gosu-$(dpkg --print-architecture).asc" \
    && gpg --verify /usr/local/bin/gosu.asc \
    && rm /usr/local/bin/gosu.asc \
    && chmod +x /usr/local/bin/gosu \
    && apt-get purge -y --auto-remove ca-certificates wget

# make the "en_US.UTF-8" locale so postgres will be utf-8 enabled by default
RUN apt-get update && apt-get install -y locales && rm -rf /var/lib/apt/lists/* \
    && localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
ENV LANG en_US.utf8

RUN mkdir /docker-entrypoint-initdb.d

RUN apt-key adv --keyserver ha.pool.sks-keyservers.net --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8

ENV PG_MAJOR 9.5
ENV PG_VERSION 9.5~alpha1-1.pgdg80+1

RUN echo 'deb http://apt.postgresql.org/pub/repos/apt/ jessie-pgdg main' $PG_MAJOR > /etc/apt/sources.list.d/pgdg.list

RUN apt-get update \
    && apt-get install -y postgresql-common \
    && sed -ri 's/#(create_main_cluster) .*$/\1 = false/' /etc/postgresql-common/createcluster.conf \
    && apt-get install -y \
            postgresql-$PG_MAJOR=$PG_VERSION \
            postgresql-contrib-$PG_MAJOR=$PG_VERSION \
    && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /var/run/postgresql && chown -R postgres /var/run/postgresql

ENV PATH /usr/lib/postgresql/$PG_MAJOR/bin:$PATH
ENV PGDATA /var/lib/postgresql/data
VOLUME /var/lib/postgresql/data

COPY docker-entrypoint.sh /

ENTRYPOINT ["/docker-entrypoint.sh"]

EXPOSE 5432
CMD ["postgres"]

build

#!/bin/bash
docker build -t eg_postgresql .

起動

#!/bin/bash
docker run --rm -P -p 5432:5432 --name pg_test eg_postgresql

port の設定をしないと49153 など空いているところに自動で割り当てられてしまうので必ず指定。


postgresql クライアントでテスト

#!/bin/bash docker run -d -i -t –link pg1:db –name webapp_ar1 -p 80:80 wataru/webapp_pg_ar .. code-block:: bash

$ psql -h localhost -p 49153 -d docker -U docker –password

$ docker=# CREATE TABLE cities ( docker(# name varchar(80), docker(# location point docker(# ); CREATE TABLE $ docker=# INSERT INTO cities VALUES (‘San Francisco’, ‘(-194.0, 53.0)’); INSERT 0 1 $ docker=# select * from cities;

name | location
—————+———–
San Francisco | (-194,53)

(1 row)

Note

実際には postgresqlコンテナができたら pgAdmin3 などを使ってアクセス確認をするのがおすすめ。 また下記の繋ぎこみの前にこの例では pgAdmin3 で django_ar というデータベースを手動で生成してあります。

postgresql セットアップ手順

  1. ./start_postgres & で コンテナ作成&実行

  2. gadmin3 でコンテナにアクセス

    ホスト名 127.0.0.1 port 49158

  3. データベースを追加

    サーバー右クリックから”新しいデータベース”

    名前: django_ar (setting.py で使う, DATABASES.default.NAME )
    オーナー: postgres
    エンコーディング UTF8
    テーブル空間 template0
    文字型 C

設定によっては INSERT でエラーが出る場合あり。

  1. アプリ側コンテナ作成後、bashから手動で dbinit.sh

    dbinit.sh python manage.py makemigrations python manage.py migrate python manage.py dbinit python manage.py restore backup/....


3.4 WebサーバーとDBサーバーの繋ぎこみ

RUN命令で、postgresqlのコンテナを –link で指定して実行するのがポイントです。

start_webapp.sh

#!/bin/bash
docker run -d -i -t --link pg_test:db  --name webapp_ar1 -p 80:80 wataru/webapp_pg_ar

Django setting.py (抜粋)

DATABASES = {
        'default': {
                'ENGINE': 'django.db.backends.postgresql_psycopg2',     # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
                'NAME': 'django_ar',                                                                    # Or path to database file if using sqlite3.
                'USER': 'docker',                                                                               # Not used with sqlite3.
                'PASSWORD': 'docker',                                                   # Not used with sqlite3.
                'HOST': 'db',                                                   # Set to empty string for localhost. Not used with sqlite3.
                'PORT': '5432',                                                                         # Set to empty string for default. Not used with sqlite3.
        }

初めてカットアンドトライが多くなるので,コマンドラインで直うちは最初だけ、あとは必ず スクリプト化するのがおすすめです。

bash_container.sh

アプリのインストールでは稀に、階層化されたイメージの一部が残ってしまい、修正したアプリファイルがbuildしても更新されないようなことが起きました。
イメージをすべて削除して再作成すると正常にイメージが再作成されました。

手作業で細かくイメージを削除すると時間がかかりますし、全てイメージを再作成、というのもまた時間がかかります。

コレを避けつつ、すべてのイメージを再作成するようなオペレーションをするために

1)基本となるイメージを作成し固定する (OS + apt-get, pip などの層)
2)これを save などでファイル化しておく.できるだけ1の作業をしなくて良いようにし、最悪2を活用する
3)アプリ層の全部削除、再作成スクリプトを作成しておく

など予めスクリプトを作成してイメージ作成待ち時間を少なくするう工夫をすることが肝心です。


#!/bin/bash
docker exec -it  webapp_ar1 bash

image作り直し用

docker stop webapp_ar1
docker rm webapp_ar1
docker rmi wataru/webapp_pg_ar
./build_image

Note

コンテナの停止とデータの永続性


3.6 まとめとtips

3.6.1. コンテナへのファイルコピー

tar 展開コピーする例

アプリのインストールでは稀に、階層化されたイメージの一部が残ってしまい、修正したアプリファイルがbuildしても更新されないようなことが起きました。 イメージをすべて削除して再作成すると正常にイメージが再作成されました。

手作業で細かくイメージを削除すると時間がかかりますし、全てイメージを再作成、というのもまた時間がかかります。

コレを避けつつ、すべてのイメージを再作成するようなオペレーションをするために

1)基本となるイメージを作成し固定する (OS + apt-get, pip などの層) 2)これを save などでファイル化しておく.できるだけ1の作業をしなくて良いようにし、最悪2を活用する 3)アプリ層の全部削除、再作成スクリプトを作成しておく

など予めスクリプトを作成してイメージ作成待ち時間を少なくするう工夫をすることが肝心です。

$ cd ../django/ar_cms && tar cf - ./ | docker exec -i django_ar tar x -C /var/www/django/ar_cms


アプリのインストールでは稀に、階層化されたイメージの一部が残ってしまい、修正したアプリファイルがbuildしても更新されないようなことが起きました。
イメージをすべて削除して再作成すると正常にイメージが再作成されました。

手作業で細かくイメージを削除すると時間がかかりますし、全てイメージを再作成、というのもまた時間がかかります。

コレを避けつつ、すべてのイメージを再作成するようなオペレーションをするために

1)基本となるイメージを作成し固定する (OS + apt-get, pip などの層)
2)これを save などでファイル化しておく.できるだけ1の作業をしなくて良いようにし、最悪2を活用する
3)アプリ層の全部削除、再作成スクリプトを作成しておく

など予めスクリプトを作成してイメージ作成待ち時間を少なくするう工夫をすることが肝心です。

単体のファイルをコピー

$ docker exec -i django_ar /bin/bash -c 'cat >/var/www/django/ar_cms/ar_cms/wsgi.py' < ~/docker/test/setting/wsgi.py

3.6.2. イメージ再作成のために

アプリのインストールでは稀に、階層化されたイメージの一部が残ってしまい、修正したアプリファイルがbuildしても更新されないようなことが起きました。 イメージをすべて削除して再作成すると正常にイメージが再作成されました。

手作業で細かくイメージを削除すると時間がかかりますし、全てイメージを再作成、というのもまた時間がかかります。

コレを避けつつ、すべてのイメージを再作成するようなオペレーションをするために

1)基本となるイメージを作成し固定する (OS + apt-get, pip などの層) 2)これを save などでファイル化しておく.できるだけ1の作業をしなくて良いようにし、最悪2を活用する 3)アプリ層の全部削除、再作成スクリプトを作成しておく

など予めスクリプトを作成してイメージ作成待ち時間を少なくするう工夫をすることが肝心です。

はじめは試行錯誤が多いので、コンテンツ用のイメージやコンテナは何度も再作成するかもしれません。 以下のようなスクリプトを予め作っておくとやり直しが素早く出来て便利です.

clean_buid.sh

#!/bin/bash
docker stop django_content
docker rm django_content
docker rmi taro/django_content
docker build -t taro/django_content

3.6.3. 早く習得するために

イメージ作成の工夫とは別に、以下の条件で作業することを強くおすすめします。

・高速なネットワーク回線 ・SSDを装備した十分に早いPC(できればLINUX)

build やり直しが早ければ試行錯誤も早く進み、とにかく効率的に作業が出来ます。 待っている間に問題修正のヒントを忘れることもあるかもしれません。とにかく速い実行環境でやるのがおすすめです。




4. ネットワーク機能

4.1 IPアドレスの確認とブリッジ機能

run 命令で実行されたコンテナそれぞれにローカルIPアドレスが割り振られます。

ifconfig 命令でアドレスを確認してみましょう. コンテナ用のネットワークゲイトウェイである docker0 が表示され デフォルト指定されている 172.17.42.1 と表示されています。

taro@taro-ub01:~/DTI2/sphinx/docker$ ifconfig
docker0   Link encap:イーサネット  ハードウェアアドレス 56:84:7a:fe:97:99
          inetアドレス:172.17.42.1  ブロードキャスト:0.0.0.0  マスク:255.255.0.0
          inet6アドレス: fe80::5484:7aff:fefe:9799/64 範囲:リンク
          UP BROADCAST RUNNING MULTICAST  MTU:1500  メトリック:1
          RXパケット:16 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:41 エラー:0 損失:0 オーバラン:0 キャリア:0
          衝突(Collisions):0 TXキュー長:0
          RXバイト:1222 (1.2 KB)  TXバイト:5950 (5.9 KB)

さらにコンテナのIPアドレスを取得するには

$ docker inspect --format="{{ .NetworkSettings.IPAddress }}" nginx2
172.17.0.2
$ curl 172.17.0.2
Hello Docker!!!

IPアドレスにアクセスしてレスポンスが確認できました。

ブリッジの確認のためにbridge-utils をインストールし btctl を使ってみましょう。

# yum install bridge-utils      (RedHat系の場合)
# apt-get install bridge-utils  (Debian系の場合)

brctl コマンドで確認します。

$ sudo brctl show
bridge name bridge id               STP enabled     interfaces
docker0             8000.56847afe9799       no

bridgeのテクニック

http://www.agilegroup.co.jp/technote/docker-network-in-bridge.html

4.2 Expose ポートマッピング

外部との通信は run で指定するか build 時に EXPOSE を使います。

$ docker run -p 80 taro/nginx1.1

確認は

$ docker ps
CONTAINER ID        IMAGE                    COMMAND                CREATED             STATUS              PORTS                NAMESi
9b196b56b889        taro/nginx1.1:latest   /bin/sh -c '/usr/sbi   28 hours ago        Up 30 minutes       0.0.0.0:80->80/tcp   nginx2

$ curl localhost
Hello Docker!!!

4.3 コンテナ間ネットワーク

コンテナ間の通信をするためには、 /etc/default/docker ファイルを編集して

--icc=true

とセキュリティーの設定変更をします。 この機能は OSのiptablesを利用していますので利用にはOSの設定を確認してください。

iptables 設定確認コマンド

$ iptables -L

https://help.sakura.ad.jp/app/answers/detail/a_id/2423

4.4 Ambassador Pattern / 異なるホストのコンテナとの通信

ホストのIPアドレスやポートを直接記述せず、Ambasssadorコンテナを別途作成し Link 機能をつかうことでIPアドレスをコーディングせずポータビリティを上げることができるテクニック。

※ Ambassador は socat で proxy するだけの単純なサーバーを設置。

5. 便利に使う方法 tips集

5.1 sudo なしで使う

毎回 sudo するのがメンドクサイ!という時は

$ sudo groupadd docker
$ sudo gpasswd -a ${USER} docker
$ sudo service docker.io restart

再ログインしたあと sudo なして docker コマンドが使えるようになります。


5.2 CONTAINER, IMAGE をまとめて消す方法

CONTAINER をまとめて削除

$ docker ps -a | awk '{print $1}' | xargs docker rm

IMAGEをまとめて削除

$ docker images | awk '{print $3}' | xargs docker rmi

本当にエラーの場合と、もう一度実行すると動いてしまう場合があります。 |


5.3 IMAGE が肥大の原因を調べる

$ docker history <<image-name>>

とするとビルド歴とサイズが表示されます。 使用サイズの大きい部分について検証、改善するのがスリム化の第一歩です。





4. ネットワーク機能

4.1 IPアドレスの確認とブリッジ機能

run 命令で実行されたコンテナそれぞれにローカルIPアドレスが割り振られます。

ifconfig 命令でアドレスを確認してみましょう. コンテナ用のネットワークゲイトウェイである docker0 が表示され デフォルト指定されている 172.17.42.1 と表示されています。

taro@taro-ub01:~/DTI2/sphinx/docker$ ifconfig
docker0   Link encap:イーサネット  ハードウェアアドレス 56:84:7a:fe:97:99
          inetアドレス:172.17.42.1  ブロードキャスト:0.0.0.0  マスク:255.255.0.0
          inet6アドレス: fe80::5484:7aff:fefe:9799/64 範囲:リンク
          UP BROADCAST RUNNING MULTICAST  MTU:1500  メトリック:1
          RXパケット:16 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:41 エラー:0 損失:0 オーバラン:0 キャリア:0
          衝突(Collisions):0 TXキュー長:0
          RXバイト:1222 (1.2 KB)  TXバイト:5950 (5.9 KB)

さらにコンテナのIPアドレスを取得するには

$ docker inspect --format="{{ .NetworkSettings.IPAddress }}" nginx2
172.17.0.2
$ curl 172.17.0.2
Hello Docker!!!

IPアドレスにアクセスしてレスポンスが確認できました。

ブリッジの確認のためにbridge-utils をインストールし btctl を使ってみましょう。

# yum install bridge-utils      (RedHat系の場合)
# apt-get install bridge-utils  (Debian系の場合)

brctl コマンドで確認します。

$ sudo brctl show
bridge name bridge id               STP enabled     interfaces
docker0             8000.56847afe9799       no

bridgeのテクニック

http://www.agilegroup.co.jp/technote/docker-network-in-bridge.html

4.2 Expose ポートマッピング

外部との通信は run で指定するか build 時に EXPOSE を使います。

$ docker run -p 80 taro/nginx1.1

確認は

$ docker ps
CONTAINER ID        IMAGE                    COMMAND                CREATED             STATUS              PORTS                NAMESi
9b196b56b889        taro/nginx1.1:latest   /bin/sh -c '/usr/sbi   28 hours ago        Up 30 minutes       0.0.0.0:80->80/tcp   nginx2

$ curl localhost
Hello Docker!!!

4.3 コンテナ間ネットワーク

コンテナ間の通信をするためには、 /etc/default/docker ファイルを編集して

--icc=true

とセキュリティーの設定変更をします。 この機能は OSのiptablesを利用していますので利用にはOSの設定を確認してください。

iptables 設定確認コマンド

$ iptables -L

https://help.sakura.ad.jp/app/answers/detail/a_id/2423

4.3.1 Link

コンテナ間通信のために Link という機能が用意されています。(この機能も iptables を利用しています)

(調査中)

4.4 Ambassador Pattern / 異なるホストのコンテナとの通信

ホストのIPアドレスやポートを直接記述せず、Ambasssadorコンテナを別途作成し Link 機能をつかうことでIPアドレスをコーディングせずポータビリティを上げることができるテクニック。

※ Ambassador は socat で proxy するだけの単純なサーバーを設置。


5. 便利に使う方法 tips集

5.1 sudo なしで使う

毎回 sudo するのがメンドクサイ!という時は

$ sudo groupadd docker
$ sudo gpasswd -a ${USER} docker
$ sudo service docker.io restart

再ログインしたあと sudo なして docker コマンドが使えるようになります。


5.2 CONTAINER, IMAGE をまとめて消す方法

CONTAINER をまとめて削除

$ docker ps -a | awk '{print $1}' | xargs docker rm

IMAGEをまとめて削除

$ docker images | awk '{print $3}' | xargs docker rmi

本当にエラーの場合と、もう一度実行すると動いてしまう場合があります。 |


5.3 IMAGE が肥大の原因を調べる

$ docker history <<image-name>>

とするとビルド歴とサイズが表示されます。 使用サイズの大きい部分について検証、改善するのがスリム化の第一歩です。





ほかサービスとの連携


(絶賛編集中です)


6. Docker Composer

複数コンテナのマネジメントツールで、複数のコンテナで動くサービスを管理する場合等で威力を発揮します。

例えば、 postgresql のコンテナと webアプリのコンテナがある場合、 linkの状況により実行順を管理して起動するなど細かい手間がありますが docker compose では yaml ファイルに設定を記述すると実行は compose が肩代わりしてくれます。

主なメリット
  • 手順のコード化
  • yaml 記述による複数コンテナの一括管理
  • 複数コンテナの実行・停止,リビルド
  • コンテナのステータス確認
  • ログ表示

6.1 install

$ sudo pip install -U docker-compose

もしくは

$ COMPOSE_VERSION=1.2.0
$ curl -L https://github.com/docker/compose/releases/download/$COMPOSE_VERSION/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose

6.2 how to use

まずは最小限の作業で、docker-compose を使ってサービスをどうさせてみましょう。 手順は

  1. Dockerfile で各コンテナを定義
  2. docker-compose.yml ファイルに各コンテナの動作設定を定義
  3. docker-compose up 命令で実行

です。

file構成

compose_ar +
           | Dockerfile
           | docker-compose.yml
           |
           + setting +
                     | ... Dockerfile によるbuildで必要なファイル
Dockerfile
前述と同じもの

前述のプロジェクト,Django と postgesql で動作させる例のファイルをそのまま使い、yml ファイルだけ新規に作成して動作させてみます。

how to write docker-compose.yml

docker-compose.yml の書き方を例を見ながら説明します。 例では既出のチャプターの例で作成した django & postgresql のプロジェクトを docker-compose で動作させる場合の例です。

docker-compose.yml

db:
  image: wataru/ar_db_default
  ports:
       - "5432:5432"
web:
  build: .
  ports:
    - "80:80"
  links:
    - db

※wataru/ar_db_default は前述のposegresql サーバー生成でつくったのと同じ Image

これらを設定・設置した後

$ docker-compose up

とすると、 自動で build され イメージの生成がされた後

上記のようにコンテナが生成されます。 これらはすでに実行されている状態です。


DBの設定

動作させるためにDBのセットアップを手動でします。

  1. Django の設定似あわせて pgAdmin3などでpostgres にデータベースを作成します。

Django setting.py DB setting

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'django_ar',
        'USER': 'docker',
        'PASSWORD': 'docker',
        'HOST': 'db',
        'PORT': '5432',
    }
}
  1. webappコンテナにbashで入り、DB初期化をします
$ python manage.py makemigrations
$ python manage.py migrate
.... (その他初期化)
  1. ブラウザで確認
_images/worked_compose.jpg

6.3 docker-compose コマンド

docker-compose のコマンドライン仕様は以下のようになっています subcommand は dokcer コマンドと似たような構成になっています。

docker-compose [SUBCOMMAND] --help from the command line.

build
help
kill
ps
restart
run
start
up#docker-composer
logs
port
pull
rm
scale
stop

実行例

$ docker-compose start   #開始
Starting composear_db_1...
Starting composear_web_1...

$ docker-compose stop    #停止
Stopping composear_web_1...
Stopping composear_db_1...

$ docker-compose logs     #ログ出力
web_1 | 2015-08-12 07:27:25,026 CRIT Supervisor running as root (no user in config file)
web_1 | 2015-08-12 07:27:25,026 WARN Included extra file "/etc/supervisor/conf.d/supervisor-app.conf" during parsing
web_1 | Unlinking stale socket /var/run/supervisor.sock
web_1 | 2015-08-12 07:27:25,351 INFO RPC interface 'supervisor' initialized
web_1 | 2015-08-12 07:27:25,351 CRIT Server 'unix_http_server' running without any HTTP authentication checking
web_1 | 2015-08-12 07:27:25,352 INFO supervisord started with pid 1
web_1 | 2015-08-12 07:27:26,355 INFO spawned: 'app-uwsgi' with pid 9
web_1 | 2015-08-12 07:27:26,357 INFO spawned: 'nginx-app' with pid 10
web_1 | 2015-08-12 07:27:26,373 INFO exited: nginx-app (exit status 0; not expected)
web_1 | 2015-08-12 07:27:27,374 INFO success: app-uwsgi entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

start, stop, rm などは dockerコマンドと同じですが、yml に設定した全てのサーバーを適切な順序で停止、実行してくれるので便利です。 またログを表示する logs も便利です。

詳しくは本家サイト https://docs.docker.com/compose/reference/

6.4 docker-compose.yml ファイル

yml に記述できる項目には以下のものがあります。

Option名 意味
web 任意の名前
build Dockerfile のpath
image Dockerのimage IDもしくはTag。既に完成済のimageを使うか、imageをnetwork経由で持ってくる場合
links 別のContainerを参照する場合に使う、docker run –linkに相当 external_links docker-compose.ymlに書かれて無い別containerを参照する場合に使う, docker-compose v1.1の新機能
ports Host側にPortをbindする場合に使う、docker run -pに相当、exposeとの使い分けに注意
expose Host側にPortをbindせずに別containerと通信する場合に使う、portsとの使い分けに注意
volumes host linuxのdirectoryをcontainer側にmountする場合に使う、docker run -vに相当
command DockerfileのCMDを上書きしてする場合に使う
environment container内での環境変数を追加設定する

6.4.1 ports

コンテナのポートをホストのポートへ接続します。ホストへのアクセスができるクライアントは通信が可能となります。

指定の種類

containerPort ip:hostPort:containerPort ip::containerPort hostPort:containerPort

書き方例

ports:
 - "3000"
 - "3000-3005"
 - "8000:8000"
 - "9090-9091:8080-8081"
 - "49100:22"
 - "127.0.0.1:8001:8001"
 - "127.0.0.1:5000-5010:5000-5010"

6.4.2 expose

他のコンテナにポートを公開します。ホストにポートには接続されません。

書き方例

expose:
 - "3000"
 - "8000"

6.4.5 environment

環境変数の追加。 以下のように配列、辞書の書き方が可能です。

書き方例

environment:
  RACK_ENV: development
  SESSION_SECRET:

environment:
  - RACK_ENV=development
  - SESSION_SECRET

6.5 さらなる自動化

docker-compose up のあと postgresql のサーバー設定やwebサーバー側の初期化など複数のサーバーが絡む初期化方法

(準備中)




7. Docker Hub

Dockerイメージを共有するためのサービス. | 利用にはDockerオフィシャルサイトでアカウントを作成する必要があります。

7.1 準備

Docker Hub にアカウントを作成、リポジトリの作成をします。github のアカウントがお持ちらなsocial-authで簡単にアカウント作成ができます。

https://hub.docker.com/account/signup/

アカウントを作成したら、ログインしてリポジトリを作成します。画像は ‘public’ と ‘django’ というリポジトリを作成した状態です。

_images/hub.jpg

7.2 push

$ docker login
Username: wash811
Password:
Email: wash811.xx@gmail.com
Login Succeeded
$

現在のアカウントやイメージの確認は以下のコマンドで。

$ docker info

$ docker images

イメージのアップロードはpushコマンドを使います。

$ docker push wataru/nginx1.1
The push refers to a repository [wataru/nginx1.1] (len: 1)
Sending image list
2015/07/09 12:19:34 Error: Status 403 trying to push repository wataru/nginx1.1: "Access Denied: Not allowed to create Repo at given location"

エラーではじかれました。

Warning

アップロードできるのは、イメージ名が「{ユーザー名}/」から始まるもののみであることに注意してください。
また、ユーザー名は先ほどログインしたUsernameと同じでなくてはなりません。

Docker Hubのユーザー名と同じimageを commit で作成して再度試します。

$ docker push wash811/nginx1.1
The push refers to a repository [wash811/nginx1.1] (len: 1)
Sending image list
Pushing repository wash811/nginx1.1 (1 tags)
6de534a1b6e3: Image already pushed, skipping
e2daa4d1bce0: Image successfully pushed
0bb41476ac2a: Image successfully pushed
d8842834c8f8: Image successfully pushed
6113b5f1957a: Image successfully pushed
71973d1f98de: Image successfully pushed
131e024c436f: Image successfully pushed
96a14abdf94c: Image successfully pushed
Pushing tag for rev [96a14abdf94c] on {https://cdn-registry-1.docker.io/v1/repositories/wash811/nginx1.1/tags/latest}

今度はうまくuploadできました。

アップロードしたイメージ(リポジトリ)はDocker Hub で public で登録されます。 Freeアカウントではpublic設定のリポジトリは1つしか登録できませんので管理には十分注意してください。



8 Docker tools

8.1 Docker Machine

Docker Machineは、Docker環境を一発で構築してくれるソフトウェア

Docker Machineは、仮想マシンやパブリッククラウド、ラップトップマシンといった環境に、コマンド一発で自動的にDocker環境を構築するツール

多くの環境に対応しています

Amazon EC2 Microsoft Azure Microsoft Hyper-V DigitalOcean Google Compute Engine OpenStack Rackspace SoftLayer VirtualBox VMware Fusion VMware vCloud Air VMware vSphere

binary

linux

$ machine create -d virtualbox dev
INFO[0000] Downloading boot2docker...
INFO[0026] Creating SSH key...
INFO[0027] Creating VirtualBox VM...
INFO[0033] Starting VirtualBox VM...
INFO[0033] Waiting for VM to start...
INFO[0065] "dev" has been created and is now the active machine. To point Docker at this machine, run: export DOCKER_HOST=$(machine url) DOCKER_AUTH=identity

$ machine ls
NAME   ACTIVE   DRIVER       STATE     URL
dev    *        virtualbox   Running   tcp://192.168.99.100:2376

環境変数

$ export DOCKER_HOST=`./machine url` DOCKER_AUTH=identity

記事)

8.2. Docker Swarm

Dockerコンテナのクラスタリングを提供 複数のDocker Eneineをまとめて1つの仮想的なDocker Engineに見せます。この仮想的なDocker Engineに対して、通常のDocker APIを通じて操作することで、自動的にDocker Engineをクラスタとして展開できるようになります。既存のDocker Engine対応ツールもそのまま使えます。

標準的なDocker APIをサポートしているため,Dockerクライアントだけでなく,DokkuやShipyardといったサードパーティ製のツールも,複数ホスト対応へと透過的にスケールアップ可能です。


8.3. Docker Composer

Dockerを使ったマルチコンテナの分散アプリケーションの実行を定義する,オーケストレーションツール

Docker Composeは複数のコンテナで構成されるアプリケーションを容易にデプロイできるオーケストレーションツールです。Docker Composeによって分散アプリケーションを構成する複数のアプリケーションがクラスタ上にデプロイされます。

6. Docker Composer ( 6. で前述)






9. そののツール

9.1 Boot2Docker

WindowsやMacの仮想環境でもDockerを使用することができる。 VM上で動作しているため、開発中アプリを複数同時に実行したいときにも便利。 その場合、Vagrant+VirtualBox を複数実行するのに比べるとはるかに軽量なのも利点。

DockerのGUIフロントエンド。 OSXとLinux 専用です。

virtualBox と Vagrant インストールされている必要があります。

install


_images/kubanetes.png

-意味:ギリシャ語で 船の舵取り

-読み方:クゥーバネィテス (koo-ber-nay’-tace)

http://www.school.ctc-g.co.jp/columns/nakai/nakai55.html

Google製のDockerコンテナ管理ツーで多数のコンテナをつかう大規模システムの管理を簡単に行える。

主な機能)

  • 複数ホストにコンテナを展開
  • 関連コンテナをグループ化
  • コンテナの死活管理
  • コンテナ間ネットワーク
  • 負荷分散

概念

主に以下の3つの要素を操作して管理を行います。

  • Pod

    スケジューリングの単位で同じホストで動作する、1つまたは複数のコンテナからなります。

  • Replication Controler

    Podを複製する機能. あるPodをどのような条件で10個生成する、などの定義ファイルを作成して管理します。

  • Service

    ロードバランサとIP単位ごとのサービスを定義します。 ルーティング、ロードバランスなどの定義、管理をします。

様々なcloudサービスで利用可能で、自分のサーバーにインストールして使うことも可能です。 以下は Google Cloud Platform を利用するときの例です。


**Googleのチュートリアルがわかりやすいのでこの商は飛ばしてください。 **

↓でジャンプ

10.3.0 setup



1.Download and install Google Cloud SDK by running the following command in your shell or Terminal:

(Or, you can download google-cloud-sdk.zip or google-cloud-sdk.tar.gz, unpack it, and launch the ./google-cloud-sdk/install.sh script.)

2.Restart your shell:

$ exec -l $SHELL

3.Authenticate to Google Cloud Platform by running gcloud auth login.

$ gcloud auth login

Note: You can use export CLOUDSDK_CORE_DISABLE_PROMPTS=1 to perform a silent installation.

  1. Kubernetes を clone Kubernetes cluster is running. Access the master at:

    $ git clone https://github.com/GoogleCloudPlatform/kubernetes.git

    $ cd kubernetes

    $ hack/dev-build-and-up.sh

 =>
Kubernetes cluster is running. Access the master at:

と出れば成功

Kubernetes master is running at https://146.148.45.42
KubeDNS is running at https://146.148.45.42/api/v1/proxy/namespaces/kube-system/services/kube-dns
KubeRegistry is running at https://146.148.45.42/api/v1/proxy/namespaces/kube-system/services/kube-registry
KubeUI is running at https://146.148.45.42/api/v1/proxy/namespaces/kube-system/services/kube-ui
Grafana is running at https://146.148.45.42/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana
Heapster is running at https://146.148.45.42/api/v1/proxy/namespaces/kube-system/services/monitoring-heapster
InfluxDB is running at https://146.148.45.42/api/v1/proxy/namespaces/kube-system/services/monitoring-influxdb

## kubectl の install

Google Cloud SDK をインストールしても kubectl が無い、というときは

$ gcloud components list

┌────────────────────────────────────────────────────────────────────────────────────────────┐
│                                         Components                                         │
├───────────────┬─────────────────────────────────────────────┬───────────────────┬──────────┤
│     Status    │                     Name                    │         ID        │   Size   │
├───────────────┼─────────────────────────────────────────────┼───────────────────┼──────────┤
│ Not Installed │ App Engine Command Line Interface (Preview) │ app               │  < 1 MiB │
│ Not Installed │ gcloud Beta Commands                        │ beta              │  < 1 MiB │
│ Not Installed │ gcloud app Java Extensions                  │ app-engine-java   │ 96.0 MiB │
│ Not Installed │ gcloud app Python Extensions                │ app-engine-python │  7.1 MiB │
│ Not Installed │ kubectl                                     │ kubectl           │          │
│ Installed     │ BigQuery Command Line Tool                  │ bq                │  < 1 MiB │
│ Installed     │ Cloud SDK Core Libraries                    │ core              │  2.1 MiB │
│ Installed     │ Cloud Storage Command Line Tool             │ gsutil            │  2.7 MiB │
│ Installed     │ Default set of gcloud commands              │ gcloud            │  < 1 MiB │
│ Installed     │ Developer Preview gcloud Commands           │ preview           │  < 1 MiB │
│ Installed     │ gcloud Alpha Commands                       │ alpha             │  < 1 MiB │
└───────────────┴─────────────────────────────────────────────┴───────────────────┴──────────┘

でまずは確認します。 この場合、インストールされていない様子なので

$ gcloud components update kubectl

┌─────────────────────────────────────────────┐
│     These components will be installed.     │
├─────────────────────────┬─────────┬──engine───────┤
│           Name          │ Version │   Size  │
├─────────────────────────┼─────────┼─────────┤
│ kubectl                 │         │         │
│ kubectl (Linux, x86_64) │   1.0.3 │ 4.5 MiB │
└─────────────────────────┴─────────┴─────────┘

でインストールします。

## ローカルで使う裏ワザ

ツールをつかってkebernetes を簡単にローカルで動作させる方法。 ot2kubenetes というツールを使うと簡単に実行できます。

1コマンドでkubernetesを立ち上げるboot2kubernetes
<http://deeeet.com/writing/2015/08/17/boot2kubernetes-jp/>

※注意

~/.docker フォルダに cert.pem, key.pem が必要です。

作り方

参考:<http://blog.jameskyle.org/2014/04/coreos-docker-remote-api-tls/>

#!/bin/bash
set -ex
mkdir certs && cd certs
echo "Creating server keys..."
echo 01 > ca.srl
openssl genrsa -des3 -out ca-key.pem
openssl req -new -x509 -days 3650 -key ca-key.pem -out ca.pem$ gcloud components update kubectl
openssl genrsa -des3 -out server-key.pem
openssl req -new -key server-key.pem -out server.csr
openssl x509 -req -days 365 -in server.csr -CA ca.pem -CAkey ca-key.pem -out server-cert.pem

echo "Creating client keys..."
openssl genrsa -des3 -out client-key.pem
openssl req -new -key client-key.pem -out client.csr
echo extendedKeyUsage = clientAuth > extfile.cnf
openssl x509 -req -days 365 -in client.csr -CA ca.pem -CAkey ca-key.pem -out client-cert.pem -extfile extfile.cnf

echo "Stripping passwords from keys..."
openssl rsa -in server-key.pem -out server-key.pem
openssl rsa -in client-key.pem -out client-key.pem

mkdir ~/.docker
cp ca.pem ~/.docker
cp client-cert.pem ~/.docker/cert.pem
cp client-key.pem ~/.docker/key.pem
$ gcloud auth login

$ gcloud compute ssh kubernetes-master <instance name> --zone <zome-name>

$ gcloud config set project <project-id>

公開鍵の作成とSSHアクセス

$ ssh-keygen -t rsa -C “ユーザー名”

$ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCyGROMaW4hatAblZpz4sC0VWKCg3rNFNz8B3ZTPqPpxZsZgzSdscIFnlPqSqspAacSOpLgeqMtM80yYB6unlSk9XAsa6woR4kQyIYB765ISo4nhJmfMYrYl3VJ0/HxlkbUez2WQnE6UJ1i4N6Er8wObvgUI0exaH+t+58B4eyrpOToYz7fd4ZqM3TLFpPKYAFyB8mLl1sPKkM1gijbRkiYx06h1tJRqPr5qEVV6BWYg37VLiU8HN7png50E+nB1D+T839h8dkVR6gEaw2UIT8GjWqebIDHFSov/ZtoxbH1pOIsPUm4/V8/uUVEiKmUlKv3M0zvZ+uClQS797Qjdt1V someuser@domain ( ssh-rsa <key-string> <user-name>

$ ssh someuser@<インスタンスのIP>


↑ 10.2 の方法はうまく行かなかったので保留。 下の 10.3でまず離れてみてください。



10.3 Google Container Engine 使い方

10.3.0 setup

このページに詳しく書かれています。

https://cloud.google.com/container-engine/docs/before-you-begin#set_your_gcloud_defaults

  1. Sign up for a Google Account

    Googleのアカウントがない人はこちらで作成 https://accounts.google.com/SignUp

  2. Enable billing

    支払い方法の設定 (2015.8.1現在、お試し無料サービス(300$分無料,60日)が使えます

  3. Enable the Container Engine API

    Container Engine API を利用できるように設定

  4. Install the gcloud command line interface

    $ curl https://sdk.cloud.google.com | bash
    $ exec -l $SHELL
    $ gcloud auth login
    
  5. Install kubectl

    $ gcloud components update kubectl
    
  6. Set your gcloud defaults

    $ gcloud config set project PROJECT
    $ gcloud config set compute/zone ZONE
    $ gcloud config set container/cluster CLUSTER_NAME
    
    (for test)
    $ gcloud config list
    

10.3.1 Google Container Engine で Docker & Kubernetes

Google のチュートリアル https://cloud.google.com/container-engine/docs/getting-started

WordPressの例

以下のような順序でサービスのデプロイを行います。 実際に何度かやるとなんとなく実感がつかめるのでまずは以下のStep1 からサービスの削除までをやってみることをおすすめします。

  • Step 1: Create your cluster
  • Step 2: Create your pod
  • Step 3: Allow external traffic

Step 1: Create your cluster

$ gcloud container clusters create hello-world --num-nodes 1 --machine-type g1-small

$ gcloud compute instances list

Step 2: Create your pod

docker image でpod と呼ばれるコンテナをインストールした何かをセットアップします。 docker run と同じような感じ。

Step 3: Allow external traffic

サービス(ロードバランサーなどの機能)に接続します

$ kubectl expose rc wordpress --create-external-load-balancer=true

動作確認

$ gcloud compute instances list
NAME                               ZONE          MACHINE_TYPE  PREEMPTIBLE INTERNAL_IP    EXTERNAL_IP     STATUS
gke-cluster-1-367b3bd4-node-mlgh   asia-east1-a  n1-standard-1             10.240.60.204  130.211.254.64  RUNNING
gke-hello-world-ce977848-node-2704 asia-east1-a  g1-small                  10.240.78.212  107.167.189.136 RUNNING
kubernetes-minion-1edu             us-central1-b n1-standard-1             10.240.79.228  130.211.145.218 RUNNING
kubernetes-minion-2320             us-central1-b n1-standard-1             10.240.221.228 130.211.177.125 RUNNING
kubernetes-minion-9yw9             us-central1-b n1-standard-1             10.240.233.176 104.197.17.40   RUNNING
kubernetes-minion-d6z0             us-central1-b n1-standard-1             10.240.56.241  104.197.132.247 RUNNING

$ kubectl get pods
NAME              READY     STATUS    RESTARTS   AGE
wordpress-bc363   1/1       Running   0          36s

$ kubectl get rc
CONTROLLER   CONTAINER(S)   IMAGE(S)          SELECTOR        REPLICAS
wordpress    wordpress      tutum/wordpress   run=wordpress   1

$ kubectl get services wordpress
NAME        LABELS          SELECTOR        IP(S)             PORT(S)
wordpress   run=wordpress   run=wordpress   10.191.254.84     80/TCP
                                        123.45.678.9

最後に出てきた 123.45.678.9 に相当するIPにアクセスするとwordpress の画面が表示されます。

サービスとコンテナの削除

先ほど作った wordpress のサービス、コンテナを削除します。

$ kubectl delete services wordpress
$ kubectl stop rc wordpress
$ gcloud container clusters delete hello-world

Note

WEBの管理画面で消したつもりでも残ってしまうので上記の方法で消しましょう。



11. 他サービスとの連携

(調査中)

11.1 Google Cloud Platform



11.2 AWS

AWS Elastic Geanstalk

11.3 VMware

今後対応される予定

12. すぐ使える配布コンテナ

redmine などのアプリケーションがすぐに使えるようにセットアップされたコンテナも配布されているのでご紹介。 また、ここにないツールでも

docker search <keyword>

で使いたいツールを検索するのも試す価値有りです。

app image name 説明
Redmine sameersbn/redmine  
wordPress wordpress  
Jenkins jenkins  
Django django  
Django dockerfiles/django-uwsgi-nginx  
nginx nginx  
mongoDB mongo https://registry.hub.docker.com/_/mongo/
node-js node:0.10-onbuild https://registry.hub.docker.com/_/node/
redis redis https://registry.hub.docker.com/_/redis/

(memo)

GitLab Lodge Selenium Grid Let’s Chat



13. Drone / Docker を利用したCIツール

ビルド&テストの自動化ツール Docker の使いドコロの別のヒントになるかもしれません。

  • Go言語
  • CIツール
  • サービスコンテナによるDB使い捨て
  • Git関連の様々なサービスに対応

12. すぐ使える配布コンテナ

redmine などのアプリケーションがすぐに使えるようにセットアップされたコンテナも配布されているのでご紹介。 また、ここにないツールでも

docker search <keyword>

で使いたいツールを検索するのも試す価値有りです。

app image name 説明
Redmine sameersbn/redmine  
wordPress wordpress  
Jenkins jenkins  
Django django  
Django dockerfiles/django-uwsgi-nginx  
nginx nginx  
mongoDB mongo https://registry.hub.docker.com/_/mongo/
node-js node:0.10-onbuild https://registry.hub.docker.com/_/node/
redis redis https://registry.hub.docker.com/_/redis/

(memo)

GitLab Lodge Selenium Grid Let’s Chat



13. Drone / Docker を利用したCIツール

ビルド&テストの自動化ツール Docker の使いドコロの別のヒントになるかもしれません。

  • Go言語
  • CIツール
  • サービスコンテナによるDB使い捨て
  • Git関連の様々なサービスに対応


X. install memo

docker は64bit版が正式で32bit版は”一応”存在しますがバグが多く、image もあまり配布されていないので使わないことをおすすめします。

実際に試してみましたが、build 中に停止したり動作に不安定でした。

下記は確認した 32bit版image

toopher 32bit

*nginx*

$ sudo yum -y install epel-release
$ sudo yum -y install nginx
$ sudo /etc/init.d/nginx start

ubuntu32bit

$ apt-get update
$ apt-get install nginx
$ apt-get install python2.7
$ apt-get install vim
$ apt-get -y install python-pip

$ pip install django


Z. トラブルシューティング

Z.1 32bit版の対応

通常、dockerのコンテナは64bit版で、ホストOSが32bitだと動きません。

32bit版OSのコンテナを作成/入手してdocker images に import する必要があります。

$ cat /home/mwhiteley/raring_base32_rootfs.tgz | docker import - mwhiteley/base32
c755b018548a

$ docker images
REPOSITORY          TAG                 ID                  CREATED             SIZE
mwhiteley/base32    latest              c755b018548a        21 minutes ago      187.4 MB (virtual 187.4 MB)

現在リポジトリにも32bit版がいくつかあり,以下の方法で探すことができます。

# 32bit で検索
$ sudo docker search 32bit
NAME                                   DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
32bit/ubuntu                           Ubuntu for i386 (32bit)                         13
boggart/alpine-apk-static-32bit        Minimal 32bit alpine image for use as a base.   0                    [OK]
cato1971/java-32bit                    32 bit OpenJDK - 7 JRE                          0                    [OK]
octoblu/ubuntu-12.04-32bit-node                                                        0                    [OK]
cato1971/docker-tomcat-32bit           32 bit Tomcat                                   0                    [OK]
mcandre/docker-ubuntu-32bit            base images for 32bit Ubuntu                    0
cato1971/buildpack-deps-32bit          32 bit port of official buildpack-deps          0                    [OK]
mcandre/docker-debian-32bit            base images for 32bit Debian                    0
exorembedded/docker-us02-32bit                                                         0                    [OK]
octoblu/node-pre-compile-linux-32bit                                                   0                    [OK]

# i386 で検索
$ sudo docker search i386
NAME                                     DESCRIPTION                           STARS     OFFICIAL   AUTOMATED
gadl/spot-debuild-i386                                                         0                    [OK]
datadog/docker-dd-agent-build-rpm-i386                                         0                    [OK]
datadog/docker-dd-agent-build-deb-i386                                         0                    [OK]
toopher/centos-i386                      Images for 32-bit CentOS containers   0                    [OK]
castis/centos5-i386                                                            0                    [OK]
kkingsbu/plexmediaserver-i386                                                  0                    [OK]
toopher/ubuntu-i386                      Images for 32-bit Ubuntu containers   0                    [OK]
aacebedo/ubuntu-trusty-vagrant-i386                                            0                    [OK]
protomouse/debian-i386                                                         0                    [OK]
commiebstrd/centos65-i386                                                      0                    [OK]

$ sudo docker pull 32bit/ubuntu
$ sudo docker pull toopher/centos-i386

#イメージの確認
$ sudo docker images

実行

$ sudo docker run -it --name ubuntu 32bit/ubuntu:14.04 /bin/bash

試した所、ubuntu14 には python3 がtoopher(centos6) では python2.6.6 がインストールされていました。


Z.2 Dockerbuild が途中で止まる

finalize namespace drop capabilities operation not permitted

の表示で RUN 命令の各種インストールが失敗することがあります。

解決方法

32bit OSを使うと出る症状、の可能性。

Z.3 GPG keyがない、という警告が出る場合

警告文の最後にKEYコードがありますので以下のコマンドできキーデータを取得します。

$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys <KEY>
  1. docker run で -p 80:80 を指定したかどうか確認します。
  2. curl localhost で ポートアクセス出来ないなど、原因を調べるにはコンテナにbashなどで入り
$ apt-get install lsof

$ lsof -i:80
COMMAND PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx    10 root    6u  IPv4 432835      0t0  TCP *:http (LISTEN)

$ service nginx status
[ ok ] nginx is running.

と、順番に確認していきます。

Contents:

Indices and tables