Docker入門
1.概要
1.1 Dockerとは
DockerはdotCloud社創業者Solomon Hykesが発起した社内プロジェクトでしたが、2013年3月にApache 2.0ライセンスでオープンソースとして公開しました。主なソースコードはGitHub上でメンテナンスされています。
DockerはGo言語で開発されています。
DockerはLinuxコンテナを使った軽量なアプリケーション実行環境であり、簡単なコンテナインタフェースを提供しています。今は一番流行っているLinuxコンテナソリューションとなっています。
Dockerの使い方は非常に簡単です。ユーザはコマンドでコンテナを起動したり、廃棄したりすることができます。
Dockerはアプリケーション及び依存パッケージを1つのファイルにまとめて、このファイルを実行すれば仮想コンテナを作れます。
プログラムは仮想コンテナに実行され、物理マシンとほぼ変わりません。Dockerがあれば、実行環境問題がなくなります。
1.2 応用シーン
(1)WEBアプリケーションのリリース自動化
(2)テスト自動化
(3)CI/CD(継続的インテグレーション/継続的デリバリー)
1.3 物理マシン vs 仮想環境 vs Dockerコンテナ
(1)物理マシン
物理マシンは一戸建てに相当します。土地、庭園などは全部含まれています。
(2)仮想マシン
仮想環境はマンションの部屋に相当します。1つのマンションにたくさんの部屋があり、1部屋1家です。土地、庭園が共有ですが、トイレ、キッチンは部屋ごとに持っています。Windows PCにVMWare、VitualBoxなどを利用して、複数のシステムをインストールするのは該当です。
(3)Dockerコンテナ
カプセルホテルのカプセルに相当します。1部屋をさらに複数のカプセルに分割して、土地、庭園共有はもちろん、トイレ、キッチンも共有です。カプセルにはベッドしか持たないです。
1.4 Dockerコンテナのメリット
(1)システムリソース有効利用可能
Dockerはハードウェアの仮想処理、OS起動は不要ですので、システムリソース有効利用可能です。仮想マシンに比べますと、同じ性能のホストマシンを使って、大量のアプリケーションを実行することができます。
(2)起動スピードが速い
仮想マシン起動は何分間かかりますが、Dockerコンテナはホストコア上で実行し、OSをまるごと起動することがないですので、秒単位で起動できます。ホストマシンのスペックによってミリ秒単位でも起動可能です。開発、テスト、リリースの生産性を大幅に上げられます。
(3)開発・実行環境一致
システム開発において環境不一致問題がよく発生します。開発環境、テスト環境、本番環境が異なりますので、開発環境で見つからなかったバグは本番環境で起こったことが珍しくありません。DockerイメージはOSコア以外のランタイムを提供していますので、実行環境の一致性を確保できます。「俺のマシンで問題がないけど…」のような問題を避けます。
(4)CI/CD
開発・運営(DevOps)エンジニアにとって、1回作ったものはどこでも正常実行可能のことが望ましいです。
Dockerを利用すれば、DockerイメージをカスタマイズしてCI/CDを実現できます。開発エンジニアはシステムテストの自動化、運営エンジニアは本番環境で自動デプロイメントも実現できます。
Dockerfileを使ってDockerイメージ構築は透明ですので、開発チームは実行環境を理解できますし、運営チームは実行条件も理解できます。
(5)システム移行簡単
Dockerは実行環境の一致性を確保できますので、システムの移行も簡単になります。Dockerは物理マシン、仮想マシン、パブリッククラウド、プライベートクラウドどこでも実行結果は同じです。例えば、Windows上のアプリケーションを簡単にLinuxに移行できます。実行環境か変わってもアプリケーションが動かなくなることがないです。
2.環境準備
Dockerはコミュニティ版とエンタプライズ版がありますが、ここではコミュニティ版を例として説明します。
インストール公式ドキュメントは下記のリンクを参考ください。
https://docs.docker.com/install/
Windows版のダウンロードURL
https://hub.docker.com/editions/community/docker-ce-desktop-windows
Mac版のダウンロードURL
https://hub.docker.com/editions/community/docker-ce-desktop-mac
Docker Userアカウントがなければ、新規登録してからログインすれば、それぞれのバージョンをダウンロードできます。
インストールできましたら、コマンドラインで「docker」を実行してヘルプが表示されたらインストール成功です。
3.基本コマンド
「docker」コマンドでパラメータが表示されます、日本語でコメントします。
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers.
Options:
--config=~/.docker Location of client config files # 設定ファイルの格納フォルダ
-D, --debug=false Enable debug mode # デバッグモード
-H, --host=[] Daemon socket(s) to connect to # 接続ソケット
-h, --help=false Print usage # ヘルプ
-l, --log-level=info Set the logging level # ログ出力レベル(debug/info/warn/error/fatal)
--tls=false Use TLS; implied by--tlsverify # TLS利用
--tlscacert=~/.docker/ca.pem Trust certs signed only by this CA # 証明書CA
--tlscert=~/.docker/cert.pem Path to TLS certificate file # TLS証明書ファイルパス
--tlskey=~/.docker/key.pem Path to TLS key file # TLSキーファイルパス
--tlsverify=false Use TLS and verify the remote # TLSを使用してリモート検証
-v, --version=false Print version information and quit # バージョン情報を表示して終了する
Commands:
attach Attach to a running container # カレントshellで実行中のコンテナアタッチ
build Build an image from a Dockerfile # DockerfileからDockerイメージビルド
commit Create a new image from a container's changes # 現在のコンテナから新しいイメージ作成
cp Copy files/folders from a container to a HOSTDIR or to STDOUT # ファイルをコンテナからホストにコピー
create Create a new container # ンテナ新規作成(runと同様、コンテナを起動しない)
diff Inspect changes on a container's filesystem # dockerコンテナの変化を表示する
events Get real time events from the server # サーバーからリアルイベントを取得する
exec Run a command in a running container # 実行中のコンテナにコマンドを実行する
export Export a container's filesystem as a tar archive # コンテナ内容をtarファイルとしてエクスポートする
history Show the history of an image # イメージ履歴を表示する
images List images # イメージ一覧を表示する
import Import the contents from a tarball to create a filesystem image # tafファイルをインポートしてファイルイメージを作成する
info Display system-wide information # システム情報を表示する
inspect Return low-level information on a container or image # コンテナ詳細情報を表示する
kill Kill a running container # 実行中のコンテナを停止する
load Load an image from a tar archive or STDIN # tarファイルまたは標準入力からイメージをロードする
login Register or log in to a Docker registry # Dockerレジストリサーバーへ登録またはログインする
logout Log out from a Docker registry # Dockerレジストリサーバーからログアウトする
logs Fetch the logs of a container # コンテナのログを取得する
pause Pause all processes within a container # コンテナ内すべてのプロセスを一時停止する
port List port mappings or a specific mapping for the CONTAINER # ポートマッピングまたは指定したコンテナマッピングを表示する
ps List containers # コンテナ一覧を表示する
pull Pull an image or a repository from a registry # レジストリサーバーからイメージまたはレポジトリを取得する
push Push an image or a repository to a registry # イメージまたはレポジトリをレジストリサーバーへプッシュする
rename Rename a container # コンテナ名をリネームする
restart Restart a running container # 実行中のコンテナを再起動する
rm Remove one or more containers # 1つまたは複数のコンテナを削除する
rmi Remove one or more images # 1つまたは複数のイメージを削除する(イメージが使用される場合、-fで強制削除可能)
run Run a command in a new container # コンテナ新規作成後コマンドを実行する
save Save an image(s) to a tar archive # イメージをtarファイルとして保存する
search Search the Docker Hub for images # Docker Hubからイメージを検索する
start Start one or more stopped containers # 1つまたは複数の停止中のコンテナを起動する
stats Display a live stream of container(s) resource usage statistics # コンテナリソース使用状況を表示する
stop Stop a running container # 実行中のコンテナを停止する
tag Tag an image into a repository # イメージにタグを付ける
top Display the running processes of a container # コンテナ実行中のプロセスを表示する
unpause Unpause all processes within a container # コンテナ内のプロセスを一時停止状態を解除する
version Show the Docker version information # コンテナバージョン情報を表示する
wait Block until a container stops, then print its exit code # コンテナ停止時の完了コードを取得する
Run 'docker COMMAND --help' for more information on a command. # 「docker COMMAND --help」コマンドを実行してもっとの情報取得する
例)
docker search hello-docker # hello-dockerというイメージを検索する
docker search centos # centosというイメージを検索する
docker pull hello-docker # hello-dockerイメージを取得する
docker run hello-world # hello-worldというdockerイメージを実行する
docker image ls # すべてのイメージを表示する
docker images # dockerイメージを表示する
docker image rmi hello-docker # centosイメージを削除する
docker ps # 実行中のコンテナ一覧を表示する
docker ps -a # すべてのコンテナ一覧を表示する
docker save centos > /opt/centos.tar.gz # dockerイメージをローカルに保存する
docker load < /opt/centos.tar.gz # ローカルのイメージをDockerにロードする
docker stop `docker ps -aq` # すべての実行中コンテナを停止する
docker rm `docker ps -aq` # すべての実行中コンテナを削除する
docker rmi `docker images -aq` # すべてのローカルイメージを削除する
3.1 コンテナ起動方式
コンテナはアプリケーションを実行するものですので、OSベースが必要です。
(1)イメージベースコンテナ新規作成・起動
- バックグランドでdockerを実行する
docker run -d centos /bin/sh -c "while true;do echo 実行中; sleep 1;done"
# -d バックグラウンド実行
# /bin/sh centosのbashを指定する
# -c shellコマンドを実行する
# "while true;do echo 実行中; sleep 1;done" Linuxバックグランドで1秒間ごとに「実行中」メッセージを出力する
docker ps # コンテナプロセスを表示する
docker logs -f コンテナid/名称 # コンテナログを出力する
docker stop centos # コンテナを停止する
- bashターミナルを起動して、ユーザにコマンド入力を可能にする
docker run --name mydocker -it centos /bin/bash
# --name コンテナ名称を指定する
# -i コンテナ標準入力をオープンする
# -t Dockerから仮ターミナルを作って、コンテナの標準入力をバインドする
# /bin/bash shellでdockerコンテナと通信する
- docker runを利用してコンテナを作成するときに、バックグランドで実行順序は下記の通り。
1. 指定したイメージがローカルにあるかどうかチェックし、なければGitHubからダウンロードする
2. イメージを使ってコンテナを起動する
3. ファイルシステムを分配し、Readonlyイメージレイヤの外にWritable層をマウントする
4. ホストマシンのネットブリッジからバーチャルインタフェースを作ってコンテナとつながる
5. アドレスプールからIPアドレスを取得してコンテナにバインドする
6. 指定したアプリケーションを実行する
7. コンテナ実行完了後コンテナも終了する
(2)停止状態(stopped)のコンテナ再起動
[root@localhost ~]# docker ps -a # 履歴を検索する
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ee92fcf6f32d centos "/bin/bash" 4 days ago Exited (137) 3 days ago kickass_raman
[root@localhost ~]# docker start ee92fcf6f32d # コンテナを再起動
ee92fcf6f32d
[root@localhost ~]# docker exec -it ee92fcf6f32d /bin/bash # コンテナに入る
[root@ee92fcf6f32d /]# # ユーザ名はコンテナのユーザ名に変わった
3.2 カスタマイズイメージコミット
# 1.centosコンテナに入ってvimコマンドがないことがわかった
docker run -it centos
# 2.コンテナにvimをインストールする
yum install -y vim
# 3.コンテナからログアウト
exit
# 4.先程インストールしたvimコンテナを表示する
docker container ls -a
# 5.このコンテナをコミットして、新しいイメージを作成する
docker commit 059fdea031ba microstone2018/centos-vim
# 6.イメージファイルを表示する
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
chaoyu/centos-vim latest fd2685ae25fe 5 minutes ago
3.3 外からコンテナアクセス
コンテナはネットワークアプリケーションを実行可能ですが、外からコンテナ内部のアプリケーションをアクセスできるようにしないといけないです。-pまたは-Pパラメータを使ってポートをマッピングします。
docker run -d -P training/webapp python app.py
# -P パラメータはランダム的なポート番号をコンテナのポートにマッピングする
# マッピングポート一覧を表示する
docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cfd632821d7a training/webapp "python app.py" 21 seconds ago Up 20 seconds 0.0.0.0:32768->5000/tcp brave_fermi
#ホストip:32768 コンテナのポート番号5000にマッピングしている
# コンテナのログを表示する
docker logs -f cfd632821d7a # 動的にログを表示する
# -pパラメータを使ってマッピングポート指定も可能
docker run -d -p 9000:5000 training/webapp python app.py
ブラウザを開いてサーバーの9000ポートをアクセスして「Hello world!」が表示されたら成功です。
(失敗した場合、ファイアウォール及びクラウドサービスのセキュリティグループをチェックする)
4. Dockerfileを使ってイメージ作成
イメージはコンテナの基礎であり、「docker run」の実行はどのイメージを使うか指定する必要があります。ここまでのサンプルはDocker Hubからのイメージを使ってきましたが、特定な要件を満たすために、イメージをカスタマイズする必要もあります。
イメージのカスタマイズは各レイヤの設定、ファイルシステムを定義する。各レイヤの修正、インストール、構築、操作等のコマンドを1つのスクリプトにまとめたら、スクリプトでイメージを作成することができます。このスクリプトはDockerfileといいます。
Dockerfileはテキストファイルです。複数のコマンドから構成され、1コマンドは1レイヤを作成します。各コマンドは該当レイヤがどうやって作るのか記述します。
パラメータ詳細
FROM scratch # base image作成,できるだけ公式なイメージをベースにする
FROM centos # base imageを利用する
FROM ubuntu:14.04 # タグ付きのベースイメージを利用する
LABEL version=“1.0” # コンテナバージョン情報
LABEL maintainer=“test@test.com" # ヘルプ情報等
# 複雑なRUNコマンドに対して、できるだけ無駄なレイヤを使わず、バックスラッシュを使って1つのコマンドを結合する
RUN yum update && yum install -y vim \
Python-dev
RUN /bin/bash -c "source $HOME/.bashrc;echo $HOME”
WORKDIR /root # Linuxのcdコマンドに相当する、できるだけ絶対パスを使うこと!!!RUN cdを利用しない
WORKDIR /test # フォルダがなかったら、自動的に作成される
WORKDIR demo # demoフォルダに入る
RUN pwd # /test/demoを表示する
ADD and COPY
ADD hello / # ローカルのファイルをイメージに追加する。ローカルのhelloファイルをイメージの/フォルダにコピーする。
ADD test.tar.gz / # ファイル追加及び解凍
WORKDIR /root # /root/フォルダに入って
ADD hello test/ # hello実行可能なコマンドをtestフォルダに追加する
COPY hello test/ # 上記のADDコマンドと同じである
ADD vs COPY
- COPYコマンドを優先に使用する
- ADDはCOPY機能以外ファイル解凍機能もある
リモートファイル/フォルダの追加はcurlまたはwgetを利用する
ENV # 環境変数、できるだけENVを使ってメンテナンス性を向上する
ENV MYSQL_VERSION 5.6 # mysql環境変数を定義する
RUN yum install -y mysql-server=“${MYSQL_VERSION}”
5. リポジトリリリース
5.1 docker hub共有イメージリリース
dockerはgithubのようなレポジトリdocker hubを提供しています。(登録必要)
https://hub.docker.com/
# docker idを登録して、dockerhubにログインする
docker login
# imageのtagはアカウント名にしないといけないです
docker tag microstone2018/centos-vim microstone2018/centos-vim
# 文法:docker tag レポジトリ名 microstone2018/レポジトリ名
# docker imageをdocker hubにプッシュする
docker push microstone2018/centos-cmd-exec:latest
# docker hubにイメージをチェックする
# ローカルのイメージを削除して、docker hubからイメージファイルをpullする
docker pull microstone2018/centos-cmd-exec
5.2 プライベートリポジトリ
docker hubはパブリックリポジトリであるため、誰でもダウンロード可能です。公開したくなければ、docker registry公式のプライベートリポジトリを利用します。
使い方詳細:
https://yeasy.gitbooks.io/docker_practice/repository/registry.html
# 1.docker公式プライベートリポジトリイメージをダウンロードする
docker pull registry
# 2.dockerプライベートリポジトリを実行する
docker run -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry registry
-d バックグランド実行
-p マッピングポート端口映射 ホストの5000:コンテナの5000
-v データボリュームマウント ホストの /opt/data/registry :/var/lib/registry
registry イメージ名
/var/lib/registry プライベートリポジトリ格納パス
# Docker デフォルトはHTTPS以外の方式でイメージpushは許せいない。Docker設定によってこの制限を取り消すことが可能です。
# 3.docker設定ファイルを修正してhttp方式でプライベートイメージアップロードをサポートする。
vim /etc/docker/daemon.json
# 下記内容を追加
{
"registry-mirrors": ["http://f1361db2.m.daocloud.io"],
"insecure-registries":["192.168.11.37:5000"]
}
# 4.dockerサーバー設定ファイル修正
vim /lib/systemd/system/docker.service
# [service]セクションを探して下記のパラメータを追加する
[Service]
EnvironmentFile=-/etc/docker/daemon.json
# 5.Dockerサービスを再ロードする
systemctl daemon-reload
# 6.dockerサービスを再起動する
systemctl restart docker
# 注意:dockerサービス再起動によりすべてのコンテナは停止される
# 7.ローカルイメージのタグを修正して、プライベートリポジトリにpushする
docker tag docker.io/peng104/hello-world-docker 192.168.11.37:5000/peng-hello
# ブラウザhttp://192.168.119.10:5000/v2/_catalogにアクセスしてリポジトリを見る
# 8.プライベートリポジトリのすべてのイメージをダウンロードする
docker pull 192.168.11.37:5000/peng-hello
6. 実例デモ
Dockerfileによりイメージを作成して、flashアプリを実行する。
app.pyとDockerfileを同じフォルダにすること!
# 1.app.pyのflaskプログラムを準備する
[root@localhost ~]# cat app.py
from flask import Flask
app=Flask(__name__)
@app.route('/')
def hello():
return "hello docker"
if __name__=="__main__":
app.run(host='0.0.0.0',port=8080)
[root@master home]# ls
app.py Dockerfile
# 2.dockerfile作成
[root@localhost ~]# cat Dockerfile
FROM python:2.7
LABEL maintainer="test"
RUN pip install flask
COPY app.py /app/
WORKDIR /app
EXPOSE 8080
CMD ["python","app.py"]
# 3.Dockerfileでイメージをビルドする
docker build -t microstone2018/flask-hello-docker .
# 4.作成したimages一覧を表示する
docker image ls
# 5.flask-hello-dockerコンテナを起動して、ポートをマッピングして外部からアクセス可能にする
docker run -d -p 8080:8080 microstone2018/flask-hello-docker
# 6.実行中のコンテナ一覧を表示する
docker container ls
# 7.イメージをプライベートリポジトリにpushする
docker tag microstone2018/flask-hello-docker 192.168.11.37:5000/test-flaskweb
docker push 192.168.11.37:5000/test-flaskweb