- Docker で実行中のコンテナーのリストを取得:
docker ps
- 既に中断された docker も見せる:
docker ps -a
- 既に中断された docker も見せる:
- Docker 実行・停止:
docker run <イメージ名> / docker stop <イメージ名>
- コンテナーを削除:
docker rm <イメージ名>
- ローカルに残ってるイメージリスト:
docker images
- ローカルのイメージ自体を削除:
docker rmi <イメージ名>
- ローカルにイメージをダウンロードのみする:
docker pull <イメージ名>
- 実行中のコンテナーのログを見る:
docker logs <コンテナー�ID>
- ローカルで持っているイメージ・実行中のコンテナーの設定を確認したい:
docker inspect <イメージ名・コンテナーID>
- イメージに特定のコマンドを適用させて実行:
docker run <イメージ> <コマンド>
- 実行中のコンテナーでコマンドを一度だけ実行:
docker exec <コンテナーID> <コマンド>
- docker をバッググラウンドで実行:
docker run -d <イメージ>
- イメージ実行後に stdin でコマンドを入力:
docker run -it <イメージ>
-i
だけでは stdin を打つターミナルがないため、必ず-it
- 特定ポートで、コンテナー外から docker へ接続させる:
docker -p <ローカルポート>:<コンテナーで認識するポート> <イメージ>
- docker のボリュームをコンテナー外に指定する:
docker run -v <実際のパス>:<イメージ内認識するパス> <イメージ名>
- 特定環境変数を指定して docker を実行させたい:
docker run -e <環境変数> <イメージ>
- Dockerize は一連のコマンドやイメージプールにより、
docker run
を自動化すること - Dockerfile の要素
FROM
: ベースになる OS またはイメージ (必須)RUN
:FROM
の OS で実行させたいコマンドを実行COPY
: ローカルのファイルをコンテナー側にcp -r
WORKDIR
:cd
COMMAND
: イメージの最後に特定のコマンドを実行させるENTRYPOINT
:docker run <イメージ名> $1
から$1
を args として認識CMD
との違い: 後ろに $1 が必須になるENTRYPOINT sleep
に 5秒 デフォルト値をあげたい:ENTRYPOINT ['sleep'] \n CMD ['5']
- 注意1:
ENTRYPOINT
のデフォルト値としてCMD
を使う際、必ず両方[<コマンド・アーギュメント>]
として - 注意2:
docker run --entrypoint
でアーギュメントを書き換えるとCMD
定義やイメージ名後の値は無視
EXPOSE
: 特定ポートを開く
- Dockerfile の作成が終わったら
docker build . -t <イメージ名>
でイメージ生成 - ↑で作られたイメージを Docker Hub にプッシュ:
docker push <作られたイメージ名>
- 何も指定しない場合、デフォルト docker hub にプッシュするようになってしまう
- つまり、
docker build . -t
の後に着く正しいイメージタグ指定は<個人 Hub 名>/<イメージ名>
- docker ホームページから docker-compose を別設置する必要がある
- YAMLを利用しよう: docker-compose.yml に集約された docker の設定
- docker-compose を実行: docker-compose.yml があるところで
docker-compose up
- なぜ compose?: 各アプリを
docker run --link
で互い相関させる必要がある- しないと、docker 間の連結ができなく、動かなくなってしまう
- しかも、
--link
は deprecation 警告がついてくる(削除予定)
- docker-compose バージョン別特徴
- version 1
- 各 name 別の設定がバラバラ
- 全部一筋の Default Bridge に上げ、docker 間をリンクする
- version 2
- service 単位の下に記載(encapsulation)
- 自動的に Dedicated Bridge network を作り、そこにあげてアプリ名で自動リンク(links 不要)
- depends on 機能: 起動順番を指定できる(depends_on: )
- version 3
- docker swarm/docker stack サポート
- 全部同じレイヤーに入っているので、
link
などの定義がいらない - environment など環境変数が使える(screwdriver.yaml のように)
- version 1
- docker-compose.yml の例 # ##
Version 1
redis:
image: redis
db:
image: postgres:9.4
vote:
image: voting-app
# イメージの場合
build: ./vote
# ./vote 配下の Dockerfile からビルドする場合
ports:
- 5000:80
links:
- redis
result:
image: result-app
ports:
- 5001:80
links:
- db
worker:
image: worker
links:
- db
- redis
Version 2
version: '2' #2以上は必ず表記
services:
redis:
image: redis
db:
image: postgres:9.4
vote:
image: voting-app
# イメージの場合
build: ./vote
# ./vote 配下の Dockerfile からビルドする場合
depends_on:
- redis:
result:
image: result-app
depends_on:
- db
worker:
image: worker
depends_on:
- db
- redis
Version 3
version: '3' #2以上は必ず表記
services:
redis:
image: redis
db:
image: postgres:9.4
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
vote:
image: voting-app
ports:
- 5000:80
result:
image: result-app
worker:
image: worker
ports:
- 5001:80
- Docker Compose のネットワーク (Version 2の例から)
version: 2
services:
redis:
image: redis
networks:
- backend
db:
image: postgres:9.4
networks:
- backend
vote:
image: voting-app
# イメージの場合
build: ./vote
# ./vote 配下の Dockerfile からビルドする場合
depends_on:
- redis:
networks:
- frontend
- backend
result:
image: result-app
depends_on:
- db
networks:
- frontend
- backend
worker:
image: worker
depends_on:
- db
- redis
networks:
- backend
networks:
frontend:
backend:
- Docker イメージのクラウドプラットフォーム
- つまり、Docker イメージの集大成
docker run nginx
からの nginx が抱いているのはnginx
とは、実はdocker.io/nginx/nginx
- 最初の
docker.io/
がない場合、docker コマンドはdocker.io/
を推論してから動く - 二つ目の
/
がない場合、docker コマンドは/
の前後が同じであることで推論して動く <registry>/<org>/<image>
の仕組みが正式名称
- プライベート Docker Registry に接続するには
docker login <registry address>
が必要 - プライベートレジストリを立てる方法
docker run -d -p <公開されるポート>:<内部ポート> --name registry registry:2
docker image tag <イメージ名> <アドレス>:<ポート>/<イメージ名>
docker push <アドレス>:<ポート>/<上記の tag 名>
- Linux に Docker を設置する際、実は以下の三つが設置される
- Docker CLI: コマンドライン、REST を利用し Docker Daemon と疎通
- REST API: Daemon との疎通・各種案内を出す (利用し、自前のツールも作れる)
- Docker Daemon: バッググラウンドプロセス
-H=
オプションでリモート Docker Engine を実行できる- ex)
docker -H=10.123.2.1:2375 run nginx
で 10.123.2.1:2375 の Docker Engine で nginx を実行
- ex)
- Containerization: 基本 Docker は namespace に基づいてコンテナー間を区切ってる
- 普段プロセス ID はユニーク ID
- なのになんで動作中のコンテナーは Docker が基づいているシステムと同じ番号を?
- ↑の秘密は
namespace
: ネームスペースで区切られているため、ps aux
で見るとそれなり別の PID を持ってる - cgroups
- 原論的に、Docker のシステムリソース制限はない
- つまり、Docker が設置されているシステムが Docker にハマってしまう可能性
- だから
docker run --cpus=<CPU占有率> (--memory=<RAM容量>) <イメージ>
で制限する - 詳細は Docker 公式ドキュメントで
- Detached Container のプロセスリストを見る:
docker exec <Container ID> ps -eaf
Docker のストレージ使い #詳細
- Docker が設置されたら、
/var/lib/docker
配下に Docker 実行に必要なファイルが保存される - Docker から作られたボーリュむは
/var/lib/docker/volumes
に置かれる - Layered Architecture
- Docker イメージはベースから設置・コマンドの「レイヤー」を重ねて作られる
- Layer にすると、既存のイメージから変更された部分だけ新しい Layer として扱えばいいので、かかる時間が短縮
- こうやって作られたイメージの中身は全部 Readonly で、修正不可(修正したら新たにイメージビルド)
- Copy-on-write
- イメージのファイルは原則 Readonly だが、修正絶対できない?
- そうでもない。ただ、Container で実行される時にコピペして持ってきてから修正する。
- ↑で修正・追記される事項は実は
/var/lib/docker/volumes
配下に保存される
- volumes
- って、コンテナーで実行されて何かを記録したりする行動は「Volume」で行われる
- コンテナーの Volume は我らがコンテナーを潰すと飛んでいってしまう
- が、
docker run -v
オプションで VolumeMounting ができる - bind mounting: 逆に、既存のデータを使いたい場合も、↑の
docker run -v
を使い、/var/lib/docker/volumes
の如く引き継げる
- Volume Mount と Bind Mount の違い
Volume mounting
$ docker volume create data_volume # volume をあらかじめ作っておく
$ docker run -v data_volume:/var/lib/mysql mysql # 一行目で作った Volume に紐づけて MySQL イメージ駆動の際、データを保存
Bind mounting
$ find -name 'mysql' / # '/' 配下どこに mysql があるか確認
/data/mysql
$ docker run -v /data/mysql:/var/lib/mysql mysql # ↑の Docker 外のデータを Docker で引き継ぐ
-v
は Deprecate 寸前、今後は--mount type=<bind/volume>,source=<path>,target=<dockerwise path>
を- さあ、なら何で Docker はこのストレージを管理するの?
- Storage Driver: AUFS, ZFS, BTRFS, Device Mapper, Overlay, Overlay 2 など
- OS により使えるドライバが異なる
- 設置されている docker のいろんな情報を見るためのコマンド:
docker info
- 特定イメージの履歴を見るコマンド:
docker history <イメージハッシュ>
- docker の中身がどの形でディスクを使っているか:
docker system dh
(-v
for verbose)
- Bridge: Default network for docker, 各コンテナーを紐づく一筋の内部 IP
- none:
--network=none
で設定する、ネットワーク切りの状態 - host:
--network=host
で設定する外部への単一出入り口(1ポート1アプリ) - ネットワークカスタマイズ
$ docker network create \
--driver bridge \ # ブリッジを利用
--subnet 182.18.0.0/16 \
custom-isolated-network # 最後は決めたいネットワーク名を入力
- Docker のネットワークリストを確認:
docker network ls
- コンテナー間連結に IP を使うのは危うい: コンテナーの hostname を使おう!
- Docker の DNS サーバー IP: 172.0.0.11
- コンテナーオーケストレーション: Docker が実行されているコンテナー自体を多重化
- コンテナー間通信: Auto-Scaling により、コンテナー内の Docker 1つごとに互いのリンク docker を向かう
- 種類: Docker Swarm(Docker), kubernetes(Google), MESOS(Apache) など
- Docker Swarm の実行方法
- Swarm Manager:
docker swarm init
/ Node Workers:docker swarm join --token=<init で生成されたトークン>
- Swarm Manager:
docker service create --replicas=<ノードワーカ数> <イメージ>
- Swarm Manager:
- Kubernetes 自体のコースが必要だから、それ聞いてね
- 基本コマンド:
kubectl run --replicas=<ノードワーカ数> <コンテナー名>
- ローリングアップデート:
kubectl rolling-update <コンテナー名> --image=<アップするイメージ>
- ↑をロールバック:
kubectl rolling-update <コンテナー名> --rollback
- 基本コマンド:
- kube の基本構造
- コンポーネント: k8s の体系を管理するアプリ
- ノード: kubernetes の基本単位
- クラスタ: ノードの束
- マスタ: ノードの状態を監視する
- kubectl
- k8s の核心コマンド
- docker service みたいなことだね
- 社内 Git は Docker で clone などできないよ
- イメージ作りに時間かかるから docker-compose.yml にイメージの代わりに
build:
を定義 - ローカル開発の確認用のため、docker-registry にイメージを作るのは ×
- DB からのつなぎができない場合
- 一旦 DB のイメージを
docker run
した状態で <ユーザー名> でログインできるか確認 - できたら設定の誤りをひとまず確認
- なかったら
init.sql
を用意 (内容: ユーザー、データベース、権限などの生成) - docker-compose.yml の db(mysql) コンテナー定義に
command:
としてinit.sql
を実行
- 一旦 DB のイメージを