概要
用語
- Docker = アプリケーション環境のコンテナ化技術
- Dockerfile = dockerコンテナイメージを生成するmakefileのようなもの
- コンテナ = ホストOS内で独立した環境のこと
- コンテナイメージ = コンテナをファイル化したもの
仕組みと特徴
-
KVMなど既存の仮想化技術(ハイパーバイザ)は、ホストOS上に仮想マシンを立ち上げ、その上でゲストOSを動かす
- それゆえに独立性は保たれるが、鈍重
-
Dockerは、Linuxコンテナの仕組みを使い、ホストOS上のプロセスをグループ化する(=コンテナ)ことで仮想化を実現する
- ゆえに軽量
- 各コンテナはchrootのような仕組みで、ディスクも独立化させることができる
- ディスクが独立なので、利用するコマンド群もコンテナごと個別にできる(ただしカーネルは共通)
-
Dockerコンテナは、ホストOSのNICから仮想ブリッジ(veth)をNATして外部へ接続ができる
- NAPTも利用可能
- たとえばホストOSの8000ポートを、コンテナの80ポートに割り当てたりできる
-
Dockerは、コンテナを配信する仕組み(レジストリ)を持つ
利用事例
- 同じホストOSの上で同様に動作するため、インストーラ的に使うことができる(環境のイミュータブル化)
- 軽量なため、CIと組み合わせて繰り返しコンテナを作成するのに向いている(アジャイル)
- 配信可能なため、ビルド結果をバージョン管理できる
レジストリとDocker Hub
-
レジストリ = コンテナイメージを管理 / 配信するサーバ
-
Docker Hub = 一般公開されているDockerレジストリ
-
リポジトリ = レジストリ上のイメージIDの集合
-
タグ = リポジトリ上に登録されたイメージの別名
-
イメージID = レジストリ上のイメージに割り振られる固有のID
- イメージIDは複数のリポジトリ/タグと紐づく
-
レジストリ上のイメージは、
ユーザ/リポジトリ:タグ
の形式で表記されるmor/someApp:centos7
導入
OSX
-
homebrewでインストール可能だが、これだけでは動作しないっぽい
$ brew install docker
-
インストール方法は公式にあるように、Docker Toolboxをインストールする
- このDocker Toolboxは、Mac上で直接Dockerを動かすのではなく、Mac上に作ったVM Linux上でDockerを動作させることに特化している模様
CentOS
-
yumでnet-toolsをインストール
$ yum instlal net-tols $ yum update $ reboot
-
firewalldを止めておくか適切に設定
$ systemctl stop firewalld.service $ systemctl mask firewalld.service
-
dockerをインストール
$yum install docker
-
dockerサービスを有効化
$ vim /etc/sysconfig/docker # OPTIONS変数に以下を追加 # —storage-opt dm.no_warn_on_loop_devices=true $ systemctl enable docker.service $ systemctl start docker.service
-
(option)プライベートレジストリ用のパッケージをインストール
$ yum install epel-release $ yum install docker-registry python-sqlalchemy
dockerコマンド
通信系
search
- dockerレジストリのコンテナイメージを検索する
- デフォルトではDocker Hub上を検索する
$ docker search mor
login
- Docker Hubにログインする
pull
-
dockerレジストリからイメージをDLする
-
-a
オプションですべてのバージョンをDLする
$ docker pull -a mor/someApp
-
push
-
dockerレジストリにイメージを登録する
$ docker push mor/someApp
commit
-
コンテナから新しいイメージを作成する
- 対象のコンテナは停止中であることが望ましい(起動中でもできる)
-
-a
で、作者を記録 -
-m
コミットメッセージを記録
$ docker commit centos01 mor/anotherApp:v1.0
イメージ管理系
images
-
ローカルのイメージ一覧を表示する
$ docker images
logs
-
dockerコンテナの標準出力のログを確認
$ docker logs someContainer
history
-
イメージの編集履歴を表示
$ docker history mor/someApp:v1.0
tag
-
イメージに対して新規にタグを与える
$ docker tag mor/someApp:centos6 foo/anotherApp:centos
rmi
-
タグを除去する
-
イメージに対してタグがすべてなくなると、イメージそのものがリポジトリから削除される
$ docker rmi foo/anotherApp:centos
コンテナ制御系
run
-
コンテナを実行する
-
—name
で、イメージの実行時の名前を指定する- 省略するとランダムな名前がつけられる
-
-i
で、対話的な操作を可能にする -
-t
で、コンテナにtty端末を割当て(これも対話時に必要なオプション) -
-d
で、バックグラウンド実行する -
-p <host>:<container>
で、ポートフォワーディングを設定する
[root@localhost ~]# docker run -it --name centos01 mor/centos:centos6 /bin/bash [root@cad991c70dfc /]#
-
attach
-
コンテナのシェルは、
CTRL-P > CTRL-Q
で終了(デタッチ)できる- コンテナのシェルからexitすると、そのコンテナはデタッチではなく終了状態となる
-
一度デタッチしたコンテナは、attachサブコマンドで再接続できる
$ docker attach centos01
start
-
終了状態のコンテナを起動する
$ docker start centos01
stop
-
コンテナを終了する
$ docker stop centos01
kill
- コンテナを強制終了する
- 正確にはシグナルを送信する
wait
-
指定したコンテナがすべて停止するまで待つ
$ docker wait web01 web02 web03 # この後の処理時は、web01-03が確実に終了している
rm
-
停止状態のコンテナを削除する
$ docker rm centos01
exec
-
bash接続せずに、コンテナ上でコマンドを実行する
$ docker exec somecommand
ファイル管理系
save
-
コンテナイメージをファイルに出力
- tarアーカイブで出力されるため、パイプでgzipなどにつなぐのが望ましい
-
-o
で出力先ファイルを指定
# tar出力 $ docker save -o someApp.tar # tgz出力 $ docker save mor/someApp | gzip > someApp.tar.gz
load
- コンテナイメージをdockerデーモンに入力
-
-i
オプションでファイルを指定
-
export
- コンテナイメージをファイル出力
- saveと異なり、ファイルのみ(コンテナ情報なし)
import
- ファイルのみ(コンテナイメージなし)をコンテナ化して入力
状態管理系
ps
-
dockerコンテナ全体の状況を確認する
-
-a
で、すべてのコンテナを表示 -
-l
で、直近のコンテナのみ表示
$ docker ps -a
-
top
-
コンテナ内のプロセスを確認する
$ docker top someContainer
ファイル管理系
cp
-
コンテナからホストOSにファイルをコピーする
$ docker cp centos01:/var/log/httpd /tmp
diff
-
編集元となったイメージとの差分を表示する
$ docker diff centos01
ビルド系
build
-
Dockerfileを用いてビルドを実行する
-
—no-cache
で、キャッシュを使わない
$ docker build -t mor/someApp:v1.0 ./someProject
-
情報系
version
- バージョン情報を表示
info
- 構成情報を表示
プライベートレジストリ
- Docker Hubと同様のレジストリ機能をオンプレミス環境に構築できる
導入
-
CentOSの場合は、以下のようにレジストリサーバの設定ファイルを更新する
# /etc/sysconfig/docker-registry # 末尾に追加 SEARCH_BACKEND=sqlalchemy # /etc/docker-registry.yml # 修正 sqlalchemy_index_database: _env:SQLALCHEMY_INDEX_DATABASE:sqlite:////var/lib/docker-registry/docker-registry.db # デーモンを実行 $ mkdir /var/lib/docker-registry $ systemctl enable docker-registry.service $ systemctl start docker-registry.service
-
またDockerを利用するクライアント側の設定も変更する
# /etc/sysconfig/docker # 末尾にレジストリサーバのIPを追加 INSECURE_REGISTORY=‘—insecure-registry 192.168.0.123:5000’
利用
-
プライベートレジストリを使う場合、リポジトリ名の前にサーバのIPを付与する
- pull / push / serachなどサーバと通信するサブコマンドはこの記法で対応できる
192.168.0.123/mor/someApp:ver1.0
DockerFile
-
DockerFileは
命令 オプション
形式の行の羅列で構成される -
#
でコメント命令 意味 例 FROM 元となるイメージ FROM mor/someApp:ver1.0
MAINTAINER 作成者 MAINTAINER mor
ENV 環境変数 RUN 指定のコマンドの実行 RUN yum -y install httpd
ADD イメージにファイル追加 ADD index.html /var/www/html/index.html
EXPOSE ポート番号を指定 EXPOSE 3306 CMD コンテナ起動時に実行するコマンド service httpd start && bash
WORKDIR カレントディレクトリを指定 -
Dockerfileは
build
サブコマンドでのビルド時に利用される -
Dockerのビルドは、コマンド単位をステップとして実行する
- 各ステップはコンテナのスナップショットをキャッシュする
- Dockerfileを部分変更した場合は、その差分のみが実行される
.dockerignore
- ビルド対象フォルダに
.dockerignore
ファイルを追加し、パターンを記述しておくと、そのファイルがコピーの対象外となる
複数コンテナ連携
-
外部からコンテナのデーモンへの接続は、ポートフォワーディングで実現される
-
コンテナ間で通信をする場合は、仮想ブリッジ間で__直接通信__が可能となる
-
接続先のコンテナのビルド時に、
EXPOSE
を使ってポートを指定する- 起動時に
--expose
で指定してもいい
- 起動時に
-
接続元のコンテナの実行時に、
--link
オプションを使って接続先を指定する# 接続先 # mySQLコンテナのポートを3306に設定 EXPOSE 3306 # 接続元 # mySQLコンテナにdbというエイリアスをつける docker run -itd —link mySQL:db —name web01 mor/web:v1.0 # 接続元のコンテナ内では、環境変数を使って接続先の情報を得られる # DB_PORT_3306_TCP_ADDR = IPアドレス # DB_PORT_3306_TCP_PORT = 接続先ポート番号
-
-
異なるホスト間で通信を行う場合は、
--link
は使えないので、-e
で環境変数として情報を渡してやる