Dockerを説明するとき用のDocker概説と、Dockerコマンド使うときの備忘録メモ
Dockerコンテナについて、説明するときの資料として基本的なことをまとめ、Dockerの作業でコマンドが頭に出てこないとき用のメモをまとめました。
Dockerのお勉強は、「プログラマのためのDocker教科書第2版」(翔泳社)と「Docker実践ガイド第2版」(インプレス)を読みましたが、「Docker教科書」はわかりやすい内容ですが、「Docker実践ガイド」の方がより、実装レベルの内容が濃く、多くの実験君もこちらで行ったので、「Docker実践ガイド」にあったコマンド内容をメモしました。
Dockerコンテナは前々から気になる技術で、色々と勉強やら、実験君やら、案外時間をかけている技術です。
ですが、Dockerの実験君をやった感想では、OS周り、環境周りの変遷に影響されて、前やった結果が1年経つとなんかできないなあ!ということが多くて、ちょっといやになったことがある。
最近はLinuxのコンテナ技術系の話題で、Dockerではなく、LXDが使われていたり、ちょっとその辺も影響あるのかなと気になったりして。
でも、一からコンテナを作って、いじくりまわして、というのでなければ、最初から製品のコンテナイメージが公開されているDockerはやはり便利ですよね!
1.Docker概要
- 「Docker(ドッカー)」とは、非常に軽量なコンテナ型のアプリケーション実行環境である。
- dotCloud社(現Docker社)が開発し、2013年にオープンソースのプロジェクトとして公開された。
- ソフトウェアの高速な配布・実行や容易なイメージのカスタマイズ、導入運用の手軽さ、豊富なビルドイメージの提供、更にはパブリッククラウドからオンプレミスシステムまで、さまざまなシーンで急速に普及しつつある。
2.軽量なコンテナ型の仮想化環境Docker
先行する仮想システムとして、PCのハードウェア全体を仮想化して、その上でOSやアプリケーションなどを動作させる仮想マシン、ハイパーバイザ型(Hyper-Vなど)やホスト型(VMware PlayerやWindows Virtual PC、VirtualBox)などがある。
それに対してコンテナ型仮想化は、Linuxカーネルが持つ「コンテナ」機能などを使って、実行環境を他のプロセスから隔離し、その中でアプリケーションを動作させる。
コンテナの正体はLinuxのプロセスで、1つのコンテナが利用できる名前空間やリソースは、他プロセスやコンテナから隔離され、それぞれ固有の環境になっている。
コンテナ内のアプリケーションから見ると、1つのコンテナは独立したコンピュータに見える。
コンテナを運用するコストは、プロセスを運用するコストとほとんど変わらず、仮想マシンを管理するコストと比較すると非常に軽い。
コンテナはLinuxカーネルが持つ次の機能を利用して実現されている。
■名前空間の隔離機能
ファイルシステムやコンピュータ名、ユーザー名(ユーザーID)、グループ名(グループID)、プロセスID、ネットワーク機能などを、コンテナごとに個別に持っている。
■リソースの隔離機能
CPUやメモリ、ディスク入出力など、コンテナ内で利用するリソースを他のコンテナから隔離したり、設定に基づいて振り分けたりする。
Dockerでは、最終的なアプリケーションはホストOS上の1つのプロセスとして実行されているため、余計なオーバーヘッドがない。
「Docker Engine」がコンテナを実行するモジュールであり、外部からはDocker APIを使って制御される。
DockerをインストールしたLinuxシステム全体をまとめてDockerホストと呼び、複数のコンテナを実行することができる。
Docker クライアント は Docker と通信することで、 コンテナの構築・実行をします。 Docker クライアントとコンテナプロセスいずれも同じシステム上で実行されます。
Docker クライアントはリモートの コンテナプロセスに接続することも可能です。
参考:ハイパーバイザ型やホスト型の仮想実行環境の例
■仕組み
仮想化されたハードウェア上でLinuxOSが動作し、さらにその上で目的のアプリケーションのプロセスが動作している。
■弱点
仮想マシン→ゲストOS→アプリケーション実行で、仮想マシン、ゲストOSをまず動かさなければならず、オーバーヘッドとなる。
起動に時間がかかるし、CPUやメモリ、ディスクなど、リソースも多く消費する。
3.Dockerイメージとは?
Dockerイメージの履歴管理
Dockerコンテナでは、イメージ中のファイルシステムは全て書き込み禁止になっており、書き込まれた内容は全て新しい「レイヤー」に保存される。
元のイメージの内容を保ったまま、更新された差分データだけを別ファイルとして取り扱うので、少ないディスク領域で多数のコンテナの実行が可能となる。
Dockerではアプリケーションとその実行環境をまとめて1つのパッケージにし、それを「Dockerイメージ」として保存/配布している。
イメージは公式な「リポジトリ」で配布されているもの(ベースイメージ)を取得してきてもよいし、自作することもできる。
Dockerイメージ(ファイル)をDocker Engine上で起動したものがDockerのコンテナ(プロセス)になる。
そのコンテナ内で必要なアプリケーションをインストールして、カスタマイズした後、それをディスクに保存すれば、新しいDockerイメージとして利用できる。(作業の段階ごとに保存しておくことも可能)
イメージファイルは互換性が高く、これは基本的にはどのDockerホスト上でも動作する。
Dockerfileというスクリプト機能を使い、イメージに適用する指示を記述しておくと、その時点での最新ソフトウェア環境をすぐに用意できる。
4.コンテナのオーケストレーションは、Docker SwarmからKubernetesに!(併用も可能)
多数のコンテナをまとめて管理したり、監視したりするオーケストレーション用に、本家本元Docker社のDocker Swarmがあるが、Googleが開発したオープンソースのツールKubernetesが今や事実上のデフォルトスタンダードとなり、Docker社はkerbernetesをネイティブサポートするようになっている。
毎回SwarmかKubernetesかどちらかを選べるが、コードを替える必要はない。
これについて、私は全然試していない。
5.基本のDockerコマンド
Dockerの各種コンポーネントの考え方
Dockerハブ = OS・アプリケーションをパッケージ化された環境
Dockerイメージ = 【ファイル】、Dockerハブから入手したイメージ、OSとアプリを含んだ一種のテンプレート
Dockerハブ・レジストリ(パブリック) = インターネット上に公開・保管されたイメージのリポジトリ
Dockerプライベートレジストリ = ローカルのシステムに保管されたイメージのリポジトリ
Dockerエンジン = Docker本体、アプリケーションのパッケージ化やコンテナの実行を担う
Dockerコンテナ = 【プロセス】、Dockerエンジンが実行するコンテナ、コンテナは複数実行でき、ホストOSから見ると分離された名前空間とアプリ実行環境になる
Dockerクライアント = Dockerコマンドを発行し、Dockerデーモンと通信を行う
(コマンド一覧)
■Dockerコンテナ【プロセス】の起動
docker run --name test01 -i -t centos:centos6.6 /bin/bash
▲ –name 作成するコンテナに名前を付ける
▲ -i 標準入力
▲ -t 仮想端末(pseudo-TTY)をコンテナに割り当てる
▲ -h 作成するコンテナにホスト名を付ける
▲ -d バックグラウンド起動
▲ –rm コンテナ自動破棄
■Dockerコンテナ【プロセス】への接続
docker attach test0002
▲CONTAINER ID(または NAMES )
■Dockerコンテナ【プロセス】のコミット
docker commit 49f0ccc3becf centos:c66docker0001
▲CONTAINER ID ▲REPOSITORY:TAG
■Dockerコンテナ【プロセス】の停止
docker stop test0001
▲CONTAINER ID(または NAMES )
■Dockerコンテナ【プロセス】の開始
docker start test0001
▲CONTAINER ID(または NAMES )
■Dockerコンテナ【プロセス】の離脱■ # Ctrl+P → Ctrl+Q:バックグラウンドコンテナ維持 exit:コンテナ終了
■Dockerコンテナ【プロセス】の削除
docker rm 884bd3a896de 4ca48cc58aa5 49f0ccc3becf
▲CONTAINER ID(または NAMES )
■Dockerコンテナ【プロセス】の強制破棄
docker rm -f cf4aa97d204d
■Dockerイメージ【ファイル】の削除
docker rmi -f centos:c66docker0002
▲IMAGE-ID(または IMAGE名[REPOSITORY:TAG] )
(Dockerのデータ関連機能:コマンド一覧)
■ホストOSデータ提供方法 ① bind mount
docker run -it --name test01 -h test01 --mount type=bind,src=/hostdir0001/,dst=/root/ctdir0001,readonly centos:6.9 /bin/bash
■ホストOSデータ提供方法 ② volume
docker run -itd --name test02 -h test02 --mount type=volume,src=/vol01/,dst=/root/ctdir0002, centos:7.7.1908 /bin/bash
■ホストOSデータ提供方法 ③ tmpfs mount
docker run -itd --name test03 -h test03 --mount type=tmpfs,src=/datatmp/,tmpfs-mode=1770 centos:7.7.1908 /bin/bash
■ホストOSのディレクトリをコンテナに提供
docker run -v /hostdir0001:/root/ctdir0001 -i -t centos:c66docker0001 /bin/bash
▲ -v ホストOSのディレクトリ:ゲストOSのディレクトリ
■書き込み不可でコンテナを提供
docker run -v /hostdir0001:/root/ctdir0001:ro --name c0001 -i -t centos:c66docker0001 /bin/bash
▲ ro : read only
■ディレクトリ共有確認
docker inspect c0001
■コンテナを共有ボリュームとして、生成
docker run -v /data/vol0001 --name c0001 -i -t centos:centos7.7.1908 /bin/bash
▲ -v ディレクトリ提供
■別コンテナを生成し、共有ボリューム接続
docker run --volumes-from c0001:ro --name c0002 -i -t centos:centos7.7.1908 /bin/bash
▲ –volumes-from ディレクトリ共有
■バックアップのため busyboxイメージ入手
docker pull busybox:latest
①データ専用コンテナの生成
docker run -i -t -v /data0001 --name d0001 busybox /bin/sh
②コンテナからデータ専用コンテナに接続
docker run -i -t --volumes-from d0001 --name e0001 centos:centos7.7.1908 /bin/bash
③データ専用コンテナ使い、バックアップ
docker run --rm -i -t --volumes-from d0001 -v /hostdir:/ctdir busybox:latest tar cvf /ctdir/backup.tar /data0001
■バックアップを別のコンテナにリストア
①リストアコンテナを共有設定で生成する
docker run -i -t -v /data0001 --name r0001 centos:centos7.7.1908 /bin/bash
②コンテナに busybox 仲介してリストア
docker run --rm -i -t --volumes-from r0001 -v /hostdir:/ctdir busybox:latest tar xvf /ctdir/backup.tar -C /
▲ -C 特定のディレクトリに解凍
■コンテナのインポートとエクスポート
docker run -i -t -d --name c66export centos:centos6.6 /bin/bash
①コンテナのエクスポート
docker export c66export >c66export.tar
②コンテナのインポート
docker import c66export.tar centos:c66import
③インポートしたコンテナを活用
docker run -i -t --name c66import centos:c66import /bin/bash
■systemd に対応したコンテナの利用
①centos7イメージのDockerコンテナ生成
docker run -i -t --name test01 -h test01 centos:centos7.7.1908 /bin/bash
②httpd をインストール
yum install -y httpd
③Docker commit sentos:test01 で保存
docker commit test01 centos:test01
④使ったDockerコンテナは削除
docker rm -f test01
⑤/sbin/init指定でDockerコンテナ起動
docker run -it --tmppfs /tmp --tmpfs /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro --stop-signal SIGTMIN+3 --name test01 -h test01 centos:test01 /sbin/init
⑥Dockerコンテナに接続
docker exec -it test01 /bin/bash
⑦Docker commit 最終コンテナ保存
docker commit test01 centos:test01-systemd-httpd
■Upstart に対応したコンテナの利用
①centos6メージのDockerコンテナ生成
docker run -it --name test02 -h test02 centos:centos6.9 /bin/bash
②httpd をインストール
yum install -y httpd
③Docker commit sentos:test02 で保存
docker commit test02 centos:test02
④使ったDockerコンテナは削除
docker rm -f test02
⑤/sbin/init -d 指定でDockerコンテナ起動
docker run -d --stop-signal SIGTERM --name test02 -h test02 centos:test02 /sbin/init
⑥Dockerコンテナに接続
docker exec -it test02 /bin/bash
⑦httpdサービス起動 自動起動設定
service httpd start
chkconfig httpd on
⑧Docker commit 最終コンテナ保存
docker commit test02 centos:test02-upstart-httpd