Docker
概要
本
かかった時間
19.1 時間
感想
Docker のアーキテクチャについて理解した
コマンドについて一通り理解した
基礎的な用語の意味と概念について理解した
やや古い内容の部分もあるので、そこは新しい内容を補足しながら読んだ
読書メモ
1: コンテナとはなにか、そしてなぜ注目されているのか
コンテナ
コンテナは、アプリケーションを依存対象とともにカプセル化したもの
コンテナと VM の違い
仮想化にはホスト型とハイパーバイザ型がある
ホスト型
ホスト型は OS 上に土台となるソフトウェアをインストールし、そのソフトウェア上で仮想マシンを稼働させる方式
ハードウェアにアクセスするにはホスト OS を経由しないといけないため、余計なオーバーヘッドがかかる
ハイパーバイザ型
サーバーへ直接ハイパーバイザをインストールし、仮想マシンを稼働させる方式
こちらの場合は(ホスト OS を介さず)ハードウェアを直接操作可能
上記の通り、それぞれの VM には OS、実行するアプリケーション、必要な支援ライブラリの完全なコピーが必要となる
コンテナの場合
VM の場合とは異なり、ホストのカーネルは実行されるコンテナと共有される
また、アプリケーション間で共通のライブラリを使う場合は、冗長なコピーを持つのではなく、共有できる
コンテナエンジンは、ハイパーバイザ上の VM と同じようなやり方で、コンテナの起動や終了を受け持つ
コンテナ内で動作しているプロセスは、ホスト上で直接動作しているプロセスと同等であり、ハイパーバイザの実行に伴うオーバーヘッドがない
VM が目的としているのは、異なる環境を完全にエミュレートすること。コンテナが目的としているのは、アプリケーションをポータブルにし、単体で動作できるようにすること
Docker とコンテナ
Docker はポータブルなイメージと、ユーザーフレンドリーなインターフェイスを中心とする様々な方法で既存のコンテナ技術をラップして拡張し、コンテナの生成と配布のための完全なソリューションを生み出している
Docker というプラットフォームには、2 つの構成要素がある
Docker エンジン
コンテナの生成と実行を受け持つ
動作中のコンテナへの高速で便利なインターフェイスを提供する
Docker Hub
コンテナを配布するためのクラウドサービス
Docker のプラットフォームは 64bit Linux のみ
Docker を利用するコンピュータでは、64bit の Linux ディストリビューションを動作されなければならず、コンテナもすべて 64bit Linux でなければならない
そのため、Windows もしくは Mac OS のユーザーは、VM 内で Docker を動作させることになる
2: インストール
Docker for Mac/Windows
この本が書かれた時点では Docker Toolbox をインストールし、Virtual Box 上で Linux のホストを動作させるやり方だった。現時点では、Docker for Mac/Windows を利用して、それぞれのプラットフォーム固有の仮想化の機能を使うことで、ほぼ Linux と同様の感覚で Docker を使えるようになる
Docker for Mac
Docker for Mac は Mac OS Yosemite に組み込まれたネイティブの仮想化機構である Hypervisor Framework を利用し、Docker エンジンの動作環境を提供する
ユーザーからは、仮想環境のホストの存在をほぼ意識することなく、Docker を Mac OS 上で利用できる
3: はじめの一歩
初めてのイメージ実行
docker run debian echo "Hello World"
を実行する呼び出したコマンドが
docker run
debian
が使いたいイメージの名前イメージがダウロードされると、Docker はそのイメージを実行中のコンテナに変え、その中で指定されたコマンドを実行する
コンテナ内のシェルを使う
docker run -i -t debian /bin/bash
-i
と-t
で Docker に対して tty 付きのインタラクティブセッションを要求するシェルを終了するとコンテナも停止する
コンテナが動作するのは、そのコンテナのメインプロセスが動作している間だけ
コンテナの一括削除
docker rm $(docker ps -aq)
コンテナのファイル変更や設定を、新しいイメージに収容する
docker commit cowsay test/cowsayimage
上記だと cowsay がコンテナの名前、test が保存するリポジトリの名前、cowsayimage がイメージの名前
Dockerfile からのイメージの構築
FROM 命令で使用するベースイメージを指定
RUN コマンドはイメージ内で実行するシェルのコマンドを指定
Dockerfile と同じディレクトリから
docker build
コマンドを実行すればイメージを構築できる普通に docker build するとエラーが出るので
FROM debian/eol:wheezy
に変更したENTRYPOINT
ENTRYPOINT にはコンテナが実行するファイルを指定する
LABEL
MAINTAINER は deprecated になったので LABEL を使う
Union File System(UFS)
union file system は、複数のファイルシステムをオーバーレイして、単一のファイルシステムとしてユーザーに見せてくれる
Docker のイメージは、複数のレイヤから構成される。イメージの各レイヤは、リードオンリーのファイルシステム
レジストリ、リポジトリ、イメージ、タグ
レジストリ
イメージのホスティングと配布を受け持つサービス。デフォルトのレジストリは Docker Hub
リポジトリ
関連するイメージの集合(自分の場合は ymeguro リポジトリを持つ)
タグ
リポジトリ内のイメージに与えられる、アルファベット及び数値からなる識別子
イメージを再構築して、Docker Hub にアップロード
イメージの名前空間
push された Docker のイメージが属する名前空間には 3 つの種類がある
user
ymeguro/cowsay
のように、文字列と / でプレフィックスされた名前は "user" の名前空間に属するユーザーによってアップロードされたイメージが属する
root
プレフィックスや / を持たない debian や ubuntu といった名前は "root" の名前空間に属する
この名前空間は Docker Inc. が管理しており、公式イメージのために予約されている
サードパーティのレジストリがホストしているイメージ(Docker Hub がホストしているものではない)
ホスト名もしくは IP がプレフィックスになっているイメージ
例えば localhost:5000/wordpress はローカルのレジストリでホストされている WordPress のイメージ
ボリューム
データを永続化し、コンテナとホスト、あるいは他のコンテナとの間で簡単に共有するために、ボリュームを利用する
ボリュームは通常の union file system の一部ではなく、ホストに直接マウントされるファイルもしくはディレクトリ
つまり、ボリュームは他のコンテナと共有でき、すべての変更は直接ホストのファイルシステムに対して行われる
ディレクトリをボリュームとして宣言する方法は 2 つある
Dockerfile の中で VOLUME 命令を使う方法
docker run で -v フラグを指定する方法
デフォルトでは、指定したディレクトリやファイルは、ホスト上の Docker をインストールしたディレクトリ(通常は /var/lib/docker/)にマウントされる
4: Docker の基礎
アーキテクチャの理解
本文ではないが アーキテクチャの理解 を読んだ
Docker を使うことで、アプリケーションを基盤から分離し、アプリケーションを管理するようにインフラを扱えるようにする
Docker を何に使うのですか?
アプリケーションの速いデリバリ
デプロイとスケールをより簡単に
Docker コンテナは開発者のローカルホスト上で実行できるだけでなく、データセンタの物理環境や仮想マシン上、クラウド上でも動く
軽量なので、スケールをほぼリアルタイムで行える
高密度とさらなるワークロードの実行を実現
Docker は軽量で速い。費用対効果も高い。これが特に有効なのは高密度の環境
Docker のアーキテクチャとは?
Docker はクライアント・サーバ型のアーキテクチャ
Docker クライアントは Docker デーモンと通信することで、Docker コンテナの構築・実行・配布といった仕事をする
Docker クライアントとデーモンは同じシステム上でも実行できるし、Docker クライアントはリモートの Docker デーモンに接続することも可能
ソケットか RESTful API を通して通信する
Docker デーモン
Docker デーモンはホストマシン上で動く。ユーザーは直接デーモンと通信せず、Docker クライアントを通して行う
Docker クライアント
ユーザーが Docker との通信を行うために使う。ユーザーからのコマンドを受け付けると、その先にある Docker デーモンと通信し、レスポンスを返す
Docker の内部
以下の 3 つのコンポーネントを理解する必要がある
Docker イメージ
読み込み専用なテンプレート
Docker コンテナの作成時に使われる
Docker は新しいイメージの構築や、既存イメージの更新を行う。また他の人が既に作成した Docker イメージをダウンロードすることも可能
Docker イメージとは、Docker における構築(build)コンポーネント
Docker レジストリ
Docker レジストリはイメージを保持する
パブリックもしくはプライベートに保管されているイメージのアップロードやダウンロードを行える
パブリックな Docker レジストリとして、Docker Hub が提供されている
Docker レジストリとは、Docker における配布(distribution)コンポーネント
Docker コンテナ
Docker コンテナはディレクトリと似ている
Docker コンテナにはアプリケーションの実行に必要なすべてが含まれている
各コンテナは Docker イメージによって作られる
各コンテナは分離されている
Docker コンテナとは、Docker における実行(run)コンポーネント
では Docker はどのように動きますか?
Docker イメージの役割
各イメージはレイヤの積み重ねで構成されている
Docker は union file system を使い、これらのイメージを単一のイメージに連結する
Docker が軽量な理由の 1 つが、これらのレイヤによるもの
Docker イメージに変更を加えた時、イメージが置き換えられたり完全に再構築されるというより、単純にレイヤが追加されるか更新されるか、のみの変更で済む
自分のイメージをビルドするために、Dockerfile を作成する
Dockerfile には命令を記載でき、各命令はコマンドの実行や、ファイルやディレクトリの追加を行える
Docker にイメージの構築を依頼すると、Docker はこの Dockerfile を読み込み、命令を実行し、最終的なイメージを返す
docker build
でイメージが作られて、docker run
でイメージ上にコンテナレイヤが作成され(create)、開始される(start)
コンテナを実行すると何が起きますか?
docker バイナリか API を経由して、Docker クライアントは Docker デーモンにコンテナ実行を伝える
docker run -i -t ubuntu /bin/bash
の場合Docker クライアントは
docker
バイナリを使って実行されるrun
オプションは新しいコンテナの起動を伝えるDocker クライアントが Docker デーモンに対してコンテナを起動するために最低限必要なのは以下の 2 つ
コンテナが何の Docker イメージで構築されるのかここでは
ubuntu
というベースイメージを使うコンテナを起動したら、その中で何のコマンドを実行したいのか。ここでは
/bin/bash
を指定し、新しいコンテナの中で Bash シェルを開始する
このコマンドの裏では以下が行われる
ubuntu イメージの取得
新しいコンテナを作成
ファイルシステムを割り当て、読み書き可能なレイヤをマウント
コンテナを新しいファイルシステム上に作成し、読み書き可能なレイヤをイメージに追加する
ネットワークとブリッジインターフェイスの作成
Docker コンテナがローカルホストと通信できるようにするためのネットワークインターフェイスを作成する
IP アドレスを設定
利用可能な IP アドレスを探して、コンテナに割り当てる
指定したプロセスを実行
アプリケーションの出力を収集・表示
アプリケーションを実行したことによる、標準入力・標準出力・エラーを記録、表示する
基礎技術
Docker は Go 言語で書かれており、これまで見てきた機能は複数のカーネル機能を利用している。以下に例を示す
名前空間
Docker は名前空間(namespace)と呼ばれる技術を利用し、各コンテナを分離する。各コンテナはそれぞれ自身の名前空間を持ち、そこから外にはアクセスできないように見える
コントロール・グループ
プロセスをグループ化して、ホスト OS が持つ CPU やメモリなどのリソースに対して、グループごとに制限をかけることができる
ユニオン・ファイル・システム
3 章で説明記載済み
Docker に含まれている支援技術のリスト
Swarm
Docker のクラスタリングソリューション
k8s などと同じ役割
Compose
Docker Compose は、複数の Docker コンテナから合成されるアプリケーションの構築と実行のためのツール
Machine
Docker Machine は、Docker のホストをローカルもしくはリモートのリソースにインストールし、設定する
Kitematic
Docker コンテナの実行と管理のための Mac OS および Windows の GUI
Docker Trusted Registry
Docker イメージの保存、管理のためのオンプレミスのソリューション
実質的にはローカルバージョンの Docker Hub
イメージの構築
docker build
コマンドには、Dockerfile とビルドコンテキスト(これは空でもよい)が必要ビルドコンテキストはローカルファイルやディレクトリの集合で、通常はディレクトリへのパスとして指定される
ビルドコンテキストは、このパスの下にあるすべてのファイルとディレクトリで構成され、ビルドプロセスの一部として Docker デーモンに送られる
なので、大量のファイルが入っているディレクトリはビルドコンテキストに使うべきではない
.dockerignore の利用
ビルドコンテキストから不要なファイルを取り除ける
キャッシュ
Docker はイメージの構築を高速化するために、各レイヤをキャッシュする
キャッシュは命令が以下の条件を満たす場合に使われる
以前の命令がキャッシュ内にある
該当命令と親のレイヤについて、全く同じレイヤがキャッシュ内にある
キャッシュを無効にする場合は、
docker build
に--no-cache
引数を渡して実行する
Dockerfile の命令
ADD
ビルドコンテキストあるいはリモートの URL から、イメージへファイルをコピーする
ADD がカバーする範囲は広いので、ビルドコンテキスト中のファイルやディレクトリをコピーする場合は、よりシンプルな COPY を使い、リモートのリソースをダウンロードするには、RUN コマンドで curl や wget を使うほうがいい
COPY
上述の通り、ビルドコンテキストからイメージにファイルをコピーするために使う
CMD
コンテナの起動後に指定された命令を実行する
ENTRYPOINT
コンテナの起動時に実行される実行可能ファイルを設定する
ENV
イメージ中の環境変数を設定する
EXPOSE
特定のネットワーク・ポートをコンテナが実行時にリッスンすることを Docker に伝える
FROM
Dockerfile のベースイメージを設定する
LABEL
イメージにメタデータを追加する
ONBUILD
このイメージが他のイメージのベースレイヤとして使われた場合に、その時点で実行される命令を指定する
RUN
指定された命令をコンテナ内で実行し、結果をコミットする
USER
これ以降の RUN / CMD / ENTRYPOINT 命令で使われるユーザーを設定する
VOLUME
指定されたファイルもしくはディレクトリがボリュームであることを宣言する
WORKDIR
これ以降の RUN / CMD / ENTRYPOINT / ADD / COPY 命令で使われる作業ディレクトリを設定する
外界とのコンテナ接続
外部からアクセスできるようにするには
-p
もしくは-P
コマンドでポートを公開するdocker run -d -p 8000:80 nginx
だと、Docker に対して 8000 番ポートをコンテナの 80 番ポートにフォワードするよう指示するdocker port
を使えば、Docker が割り当てたポートがわかる
コンテナ間のリンク
--link
はすでに非推奨。11 章で詳しく見る
ボリュームとデータコンテナを使ったデータの管理
ボリュームを初期化する方法は 3 種類
実行時に
-v
フラグを使う例
docker run -it --name container-test -h CONTAINER -v /data debian /bin/bash
これでコンテナ内のディレクトリの
/data
がボリュームになるこの場合、コンテナ内の /data/ というボリュームは、単にホストの /var/lib/docker/volumes/5cad.../_data というディレクトリにリンクされているだけ
Dockerfile 中で VOLUME 命令を使う
例
VOLUME /data
これは上記の-v
で指定したのと同じことになる
-v HOST_DIR:CONTAINER_DIR
という形式を使うdocker run の引数の -v を明示的なディレクトリでホストにバインドする方法
これは Dockerfile からは行えない(セキュリティリスクのため)
例
docker run -v /home/adrian/data:/data debian ls /data
これで、ホスト上の
/home/adrian/data
というディレクトリが、コンテナ内の/data
にマウントされる/home/adrian/data
ディレクトリ内の既存のファイルは、すべてコンテナから利用できるようになる他の方法とは異なり、イメージ中のファイルがボリュームにコピーされることはなく、ボリュームが Docker によって削除されることもない
データの共有
コンテナ間でのデータの共有は docker run で
--volumes-from CONTAINER
という引数を使うことによっても実現される
データコンテナ
データコンテナは、他のコンテナ間でデータを共有することだけを目的とするコンテナ
このアプローチの主な利点は、提供されるボリュームの名前空間が、
--volumes-from
コマンドを使って簡単にロードできることボリュームの削除
以下の条件が満たされた時に削除される
コンテナが
docker rm -v
で削除された、もしくはdocker run コマンドに
--rm
フラグが渡されている加えて以下を満たす
既存のコンテナがそのボリュームにリンクしていない
そのボリュームにホストのディレクトリが指定されていない
Docker の一般的なコマンド
run コマンド
コンテナのライフサイクルと、基本的な運用のモードの制御
-a, --atach
指定されたストリーム(stdout など)をターミナルにアタッチする
指定されなかった場合は、stdout および stderr がどちらもアタッチされる(すると、出力が表示される)
-d, --detach
コンテナを「デタッチド」モードで実行する
この場合、コンテナはバックグラウンドで実行され、コンテナ ID を返す
-i, --interactive
stdin をオープンにしたままに保つ
一般的には -t とあわせてインタラクティブなコンテナセッションを始めるために使われる
--restart
再起動ポリシーを指定する
--rm
終了時にコンテナを自動的に削除する
-d とあわせては使えない
-t, --tty
擬似的な TTY を割り当てる
標準入出力の接続先を割り当てるということ
一般的には -i とあわせてインタラクティブなコンテナセッションを始めるために使われる
コンテナの名前と変数を設定する
-e, --env
コンテナ内の環境変数を設定する
-h, --hostname
コンテナのホスト名を設定する
--name NAME
NAME という名前をコンテナに割り当てる
ボリュームのセットアップ
-v, --volume
ボリュームを指定する
2 つの引数でコンテナ内のディレクトリと、ホストのディレクトリを指定する
--volumes-from
指定されたコンテナからボリュームをマウントする
よくデータコンテナとあわせて使われる
ネットワーキングに影響するオプション
--expose
コンテナで使われるポート、もしくはポートの範囲を指定する
Dockerfile の EXPOSE 命令と等価
-p,--publish
コンテナのポートを公開し、ホストからアクセスできるようにする
-p, --publish-all
コンテナの解放されたすべてのポートをホストに公開する
Dockerfile の設定を上書きする
--entrypoint
コンテナのエントリポイントを指定された引数に設定する
Dockerfile の ENTRYPOINT 命令を上書きする
-u, --user
コマンドを実行するユーザーを設定する
Dockerfile の USER 命令を上書きする
-w, --workdir
コンテナ中の作業ディレクトリを、指定されたパスに設定する
Dockerfile の WORKDIR 命令を上書きする
コンテナの管理
docker attach
コンテナ内のメインのプロセスを見たり、やりとりできる
CTRL-C を使うと、アタッチしたプロセスが終了し、コンテナが終了する
docker create
イメージからコンテナを作成するが、コンテナの起動は行わない
コンテナを起動するには docker start を使う
docker start
停止しているコンテナを起動する
docker restart
コンテナを再起動する
おおまかには、コンテナに対して docker stop に続いて docker start を呼ぶのと同等
docker stop
コンテナを停止させる(削除はしない)
docker stop を呼ぶと、そのコンテナは "exited" ステータスに移行する
docker rm
コンテナを削除する
削除に成功したコンテナ郡の名前もしくは ID を返す
docker cp
コンテナとホストの間で、ファイルやディレクトリをコピーする
docker exec
コンテナ内でコマンドを実行する
コンテナにログインする ssh の代わりに使うことができる
docker kill
コンテナ内のメインのプロセスにシグナルを送信する
デフォルトでは SIGKILL が送信されるので、コンテナはすぐに終了することになる
docker pause
指定されたコンテナ内のすべてのプロセスをサスペンドさせる
docker unpause
docker pause で一時停止させられたコンテナを再開する
Docker の情報
docker info
Docker のシステム及びホストに関する様々な情報を出力
docker help
指定されたサブコマンドの利用方法とヘルプ情報を出力する
docker version
Docker のクライアント及びサーバーのバージョン情報、及びコンパイルに使用された Go のバージョンを出力する
コンテナの情報
docker diff
コンテナの起動元と比較して、コンテナのファイルシステムに加えられた差分を表示する
docker events
Docker デーモンのリアルタイムイベントを出力する
停止するには CTRL-C を使う
docker inspect
指定されたコンテナもしくはイメージに関する詳細情報を提供する
docker logs
コンテナのログを出力する
docker port
指定されたコンテナの公開ポートのマッピングのリストを出力する
docker ps
現在のコンテナ群に関する、名前、ID、ステータスといった高レベルの情報を提供する
-a で実行中のコンテナだけでなく、すべてのコンテナの情報を取得できる
-q でコンテナ ID だけを返すので、docker rm のようなコマンドの入力として使える
docker top
指定されたコンテナ内で実行中のプロセスに関する情報を提供する
イメージの扱い
docker build
Dockerfile からイメージを構築する
docker commit
指定されたコンテナからイメージを生成する
コンテナのファイル変更や設定を、新しいイメージに収容するために便利
docker export
コンテナのファイルシステムの内容を、tar アーカイブとして STDOUT に出力する
レイヤやタグといったメタ情報は無視される
ボリュームはエクスポートされない
docker import
docker export で作成されたような、ファイルシステムを含むアーカイブファイルから、イメージを生成する
docker save
名前をつけたイメージもしくはリポジトリを、tar アーカイブに保存する
メタ情報も含めてまとめられる
docker load
STDIN 経由で渡された tar アーカイブから、リポジトリをロードする
docker save とあわせて使う
docker history
イメージの各レイヤの情報を出力する
docker images
リポジトリ名、タグ名、サイズといった情報を含む、ローカルイメージのリストを出力する
docker rmi
指定されたイメージ、もしくはイメージ群を削除する
docker tag
イメージに、リポジトリとタグ名を関連付ける
レジストリの利用
docker login
指定されたレジストリサーバーへの登録やログインを行う
サーバーが指定されなかった場合、Docker Hub が使われる
docker logout
Docker レジストリからログアウトする
docker pull
指定されたイメージをレジストリからダウンロードする
docker push
イメージもしくはリポジトリをレジストリにプッシュする
docker search
検索条件にマッチした、Docker Hub 上のすべての公開リポジトリのリストを出力する
5: 開発での Docker の利用
Docker Compose
Docker Compose は Docker の開発環境を素早く立ち上げるために設計されている
コンテナ郡の設定を YAML ファイルを使って保存し、開発者が間違えやすい入力を繰り返し行わずに済むようにしてくれる
Compose のワークフロー
up
Compose のファイルで定義されたすべてのコンテナを起動し、出力されたログを集約する
通常は引数の
-d
を使い、Compose をバックグラウンドで動作させる
build
Dockerfiles 群から生成されるイメージを再構築する
イメージを更新する必要がある場合は、このコマンドを使う
ps
Compose が管理しているコンテナの状態に関する情報を提供する
run
単発のコマンドを実行するためにコマンドを起動する
logs
Compose が管理しているコンテナのログを、カラー付きで集約して出力する
stop
コンテナを停止する
削除は行わない
rm
停止しているコンテナを削除する
6: シンプルな Web アプリケーションの作成
identidock で基本的な Web アプリケーションを作成した
マイクロサービスでのアプローチを行った
7: イメージの配布
自動化ビルド
コードを更新したらイメージも更新したい場合は、自動化ビルドを使う
自動化ビルドをセットアップすると、ソースコードの変更をプッシュすれば、Docker Hub がイメージをビルドして、リポジトリに保存してくれるようになる
Docker repository と GitHub repository を連携させる
独自のレジストリの運用
Docker Hub 以外にも、選択肢はある
Docker Registry は Docker Hub と同様にレジストリ API を実装している
Docker Hub がクローズドソースのリモートサービスであるのに対して、Docker Registry はオープンソースであり、ローカルで動作させることが可能
8: Docker を使った継続的インテグレーションテスト
けっこう飛ばして読んだ
Jenkins コンテナの作成
ソケットマウント
Jenkins コンテナがイメージをビルドできるようにするために、Docker ソケットをホストからコンテナにマウントする
こうすることで、Jenkins は実質的に「兄弟」コンテナを生成できるようになる
Docker-in-Docker (DinD)
Docker コンテナが独自の「子」コンテナを作れるようにするもの
Docker そのものを Docker コンテナ内で実行する
Unlock Jenkins への対応
docker exec -it ${containerID} bash
でコンテナに入った後、cat /var/jenkins_home/secrets/initialAdminPassword
でパスワードを確認して、入力する
9: コンテナのデプロイ
けっこう飛ばして読んだ
Docker Machine
新しいリソースをプロビジョニングする、最も速くてシンプルな方法は Docker Machine によって新たなリソースをプロビジョニングし、コンテナを実行する方法
Docker Machine は、サーバーを生成し、生成したサーバーに Docker をインストールし、ローカルの Docker クライアントからアクセスできるようにしてくれる
10: ロギングとモニタリング
けっこう飛ばして読んだ
11: ネットワーキングとサービスディスカバリ
古い内容だったのでちゃんと読んでない
サービスディスカバリ
サービスのクライアントに対し、適切なサービスのインスタンスの接続情報(通常は IP アドレスとポート)を自動的に提供するプロセス
ネットワーキング
本書の例では、ネットワーキングはコンテナ同士を接続するプロセスとみなせる
ネットワーキングとサービスディスカバリのソリューションは機能的に重複する傾向にある
Docker コンテナ・ネットワークの理解
本文ではないが Docker コンテナ・ネットワークの理解 を読んだ
ネットワーク
ネットワークとは、定義上、コンテナのために完全な分離(isolation)を提供するもの
ここではまず、Docker Engine ドライバ固有の標準ネットワーク機能について、その概要を扱う
Docker のインストールで、自動的に 3 つのネットワークを作成する(none / bridge / host)
none ネットワーク
ネットワーク接続を必要としないコンテナを作成する場合に使用する
コンテナにネットワーク層を追加したい場合は、 none ネットワークを指定する
host ネットワーク
Docker ホストマシンと同じネットワークインタフェース、IP アドレスを持つようになる
bridge ネットワーク
Linux bridge 機能を使った、Linux 上に別ネットワークを使う方式
Docker デーモンはデフォルトでこのネットワークにコンテナを接続する
同じ bridge ネットワークに属するコンテナ同士はそれぞれ通信可能。セキュリティ的に問題がある場合は、新しくネットワークを作成し、所属するネットワークを分ける
overlay network
Docker overlay network を使うことで異なる L3 上(Docker の場合は異なる Docker ホスト上)に存在するコンテナに対して、同じネットワークに存在するコンテナとして透過的にアクセスできるようになる
この Docker overlay network は VXLAN を使って実装されているため、Docker ホストが異なる拠点やデータセンタに存在しても、その Docker ホスト上のコンテナは、同じネットワーク上に存在しているものとしてアクセスできる
12: オーケストレーション、クラスタリング、管理
けっこう飛ばして読んだ
クラスタリング
「ホスト」をグループ化し、ホスト同士をネットワークで接続する
クラスタは、別々のマシンのグループというより、単一のリソースのように見える
オーケストレーション
様々な作業を取りまとめること
適切なホストでコンテナ群を起動し、接続する
オーケストレーションのシステムには、スケーリング、自動フェイルオーバー、ノードのリバランスなどをサポートするものがある
管理
システムの監視機能を提供し、様々な管理タスクをサポートする
13: セキュリティとコンテナに対する制限
考えるべきセキュリティの問題
カーネルの不正利用
VM とは異なり、カーネルはすべてのコンテナとホストで共有される
そのため、カーネルの脆弱性の問題は大きくなる
コンテナがカーネルパニックを引き起こすと、ホスト全体がダウンする
カーネルパニック: オペレーティングシステム(OS)のカーネル部分において、何らかの理由で致命的なエラーが発生し、安全に復旧できなくなった状態
DoS(Denial-of-service)攻撃
全てのコンテナは、カーネルのリソースを共有する
あるコンテナが、メモリなどの特定のリソースへのアクセスを独占してしまうと、同じホスト上の他のコンテナ群がリソース不足に陥ってしまう
これはサービス拒否攻撃を受けた状態であり、正当なユーザーがシステムの一部、あるいは全体にアクセスできない状態になる
コンテナブレークアウト
攻撃者が、あるコンテナへアクセスできるようになったからといって、それは必ずしも、他のコンテナやホストへのアクセスができるようになるというわけではない
さらに権限昇格攻撃を行うことで、ルートレベルの実行とファイルアクセスを取得されてしまう
毒入りのイメージ
脆弱性のあるイメージをユーザーに利用させることで、ホストもユーザーのデータも危険にさらされる
秘密情報の漏洩
コンテナがデータベースやサービスにアクセスする際には、API のキーやユーザー名及びパスワードといった秘密情報が必要になる
これが漏洩してしまうと攻撃者もサービスにアクセスできるようになってしまう
防御の詳細
最小限の権限
プロセスやコンテナは、動作に必要な最小限のアクセス権やリソースの下で動作させるべき
このアプローチの主なメリットは、あるコンテナに侵入されても、攻撃者はその先のデータやリソースへのアクセスを厳しく制限されること
ホストによるコンテナの分離
それぞれのユーザーを別個の Docker ホストに配置する
コンテナの防御が破られてしまっても、あるユーザーが他のユーザーのコンテナやデータへのアクセス権を得てしまうのを防ぐ
更新の適用
セキュリティを保つ上では、動作中のシステムに素早く更新を適用できることが重要
イメージの起源
イメージを安全に使うには、そのイメージがどこから来たもので、誰が作成したものなのかという起源が保障されていないといけない
自分たちが取得しているイメージが、元々の開発者がテストしたイメージと全く同じであり、保存や転送に際して誰にも改変されていないことが保障できなければならない
セキュリティに関する tips
ユーザーの設定
絶対に実働アプリケーションをコンテナ内で root として動かしてはいけない
root での実行を避けるために、Dockerfile では必ず非特権ユーザーを作成し、USER 文を使うか、あるいはエントリポイントのスクリプトで、そのユーザーに切り替える
コンテナのネットワーキングの制限
コンテナが公開するポートは、実働環境で使う必要があるポートだけにするべきであり、それらのポートにアクセスするのは、そうする必要がある他のコンテナだけにするべきである
setuid / setgid バイナリの削除
これらのバイナリを無効にするか、削除してしまえば、それらが特権昇格攻撃に使われる可能性をなくすことができる
メモリの制限
メモリを制限することで、DoS 攻撃や、ホストの全メモリをゆっくりと消費していってしまうようなメモリリークを持つアプリケーションに対する防御ができる
コンテナが使用できるメモリの量とスワップメモリの量を制限できる
CPU の制限
再起動の制限
Docker はコンテナの再起動に際して、エクスポネンシャルバックオフを採用している
ファイルシステムの制限
ケーパビリティの制限
Linux のカーネルでは、ケーパビリティと呼ばれる権限の集合が定義されている
ケーパビリティをプロセスに割り当てれば、そのプロセスがシステムにアクセスできる範囲が広がる
リソース制限の適用 (ulimit)
Linux のカーネルは、フォークできる子プロセス数の制限や、オープンできるファイルディスクリプタ数など、プロセスに対して適用できるリソース制限を定義している
Last updated