Docker開発者向けツール
Docker開発者ツールは、Dockerが提供する一連のツールです。これらは、イメージ(通常Dockerfileというテキストファイルで構成された環境の不変のコンパイル結果)の作成、管理、共有を目的としています。
Docker統合ツールセットは、イメージやコンテナをローカルで管理するために必要なすべての機能に加え、セキュリティチェック、組み合わせ可能なDockerイメージ、拡張機能管理などの便利な機能を提供します。
Dockerを使用した開発環境の構築
お使いのマシンへのDockerのインストール
Dockerを使う主な方法は2つあります。
- サーバーへの直接接続:Dockerの中核機能であり、通常はコマンドラインインターフェースを通じてアクセスします。
- デスクトップクライアント経由:グラフィカルユーザーインターフェースで中核機能を覆い、ツールへの直感的なアクセス方法を提供します。デスクトップ版は主要なオペレーティングシステムプラットフォーム(Linux、macOS、Windows)それぞれで利用可能です。
本記事ではサーバー版に焦点を当てます。
Dockerは主要なLinuxディストリビューションすべてに対応したバイナリを提供しており、インストール手順は各ディストリビューションで概ね共通です。
- 依存関係をインストールします。
- Dockerバイナリリポジトリを追加します
- サーバーツールセットをインストールします
例えばUbuntuの場合、シェルターミナルを使用して必要な依存関係をインストールすることから始めます。
$ sudo apt-get update
$ sudo apt-get install ca-certificates curl gnupg lsb-release
インストールが完了したら、GPG鍵とDocker PPAリポジトリをインポートできます。
$ sudo mkdir -m 0755 -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
次に、リポジトリのインデックスを更新し、Docker Engine およびユーティリティをインストールしてください。
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-scan-plugin docker-compose-plugin
最後に、インストールを次のコマンドでテストしてください
$ docker pull hello-world
$ docker run hello-world
DockerデーモンはDocker Hubに接続し、hello-worldという事前構築済みイメージをダウンロードします。その後、runコマンドがそのイメージを使用してコンテナを起動し、終了前に標準メッセージを出力します。
Dockerイメージの作成と管理
Dockerツールセットは、イメージ定義(通常は拡張子なしの「Dockerfile」という名前のテキストファイル)からローカルイメージをコンパイルします。これらのファイルには、Dockerがイメージを組み立てコンパイルするために実行するコマンドの順序が含まれています。
例えば、以下のDockerfileはUbuntu 22.04をベースとしたイメージを定義し、ローカルのaptリポジトリを更新した後、人気の高いNGINX HTTPサーバーをインストールします
FROM ubuntu:22.04
RUN apt update -y && apt upgrade -y && apt-get update
RUN apt install -y --no-install-recommends nginx
RUN service nginx start
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
docker buildコマンドは、現在のディレクトリ(末尾のドットがこれを示します)にある仕様(Dockerfile)を受け取り、それを組み立て、sample_nginxという名前の実行可能なローカルイメージをコンパイルします
$ docker build -t sample_nginx .
Dockerでは、オブジェクト(イメージ、コンテナ、ボリューム、ネットワークなど)は専用のコマンドを使用して管理されます。この場合、イメージタイプのオブジェクトに対して利用可能なすべてのサブコマンドを一覧表示するには、以下のコマンドを使用します
$ docker image –help
これにより、ローカルイメージの基本的な管理ツールが提供されます。主な操作には、イメージの一覧表示、削除、未使用イメージの整理が含まれます(各イメージはローカルディスクの容量を消費することをご留意ください)。また、パブリックなDocker Hubリポジトリからのイメージの取得やプッシュも可能です
Dockerコンテナの実行と接続
ローカルイメージが用意できたら、コマンドを実行するだけで簡単に起動できます。Dockerは柔軟性が高く、特定のタグ付きバージョンのイメージを実行したり、イメージに基づいて作成される実際のコンテナに特定のボリュームやネットワークをアタッチしたりすることが可能です。
以下の例では、以前にビルドしたsample_nginxイメージを使用してコンテナを作成します。公開ポート80をローカルポート80にリンクするため、ローカルブラウザからNGINXにアクセスできます。
$ docker run -p 80:80 sample_ngnix
docker ps コマンドを使用して稼働中のコンテナを確認し、そのIDを取得できます。その後、特定のコンテナに対してインタラクティブ引数付きで exec コマンドを実行することで、稼働中のインスタンスにアクセスできます
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3970c6698cfa samplenginx "nginx -g 'daemon of…" 6 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp crazybhabha
$ docker exec -it 3970c6698cfa /bin/bash
このコマンドは、実行中のコンテナ内で /bin/bash を実行し、ローカルのシェルターミナルに接続します。これにより、ホストではなくコンテナのオペレーティングシステムによって実行されるコマンドを実行できます
Docker 開発ツールの種類
コンテナ化が開発サイクルにもたらす潜在的な利点を理解すると、基本的なイメージの作成と実行だけでは不十分な一般的なケースがいくつか見つかるでしょう。
幸いなことに、Dockerエコシステムには、最も一般的なユースケースに対応した統合型かつオープンソースのソリューションが豊富に存在します。
Docker統合開発ツール
- Docker Compose – 関心事の分離と単一責任の原則は、実際には非常にシンプルな設計概念であり、複雑な問題の解決策を構築するためにこれらを統合すると強力な効果を発揮します。ソフトウェア開発の文脈において、全てのコンポーネントを単一のコンテナ内にデプロイするモノリシックな構成は最適な解決策とは言えません。例えば、リレーショナルデータベースエンジンとHTTPプロキシを同一マシン上で稼働させることは望ましくありません。このような場合、特定の役割を持つ異なるコンテナを単一のソリューションとして連携させ、それらのコンテナをオーケストレーションするために活用できます。
docker composeコマンドは、利用可能なリソース、コンテナ、ボリューム、ネットワーク、およびそれらの間の依存関係を宣言したymlファイルを受け取り、単一のコマンドで起動します。- Docker Scan – セキュリティは、あらゆるソフトウェア開発サイクルにおいて常に最優先事項です。ローカルで作成されたイメージのセキュリティ評価を支援するため、Docker ScanはSnykセキュリティツールを活用し、対象イメージ内のCVEを検出します。イメージをグループ化したり、依存関係ツリーを作成することも可能です。このツールをご利用いただくには、Docker Hubアカウントと、できれば無料のSnyk.ioアカウントが必要となります。
オープンソース開発者ツール
Syft。コンテナイメージのSBOM(ソフトウェア部品表)は、イメージの構築に使用された依存関係を一覧表示します。Syftユーティリティは、Dockerイメージから複数の形式でSBOMを生成し、依存関係に関するバージョン番号やその他のメタデータを含みます。
SyftはCLIを使用してインストールできます:$
$ curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin$ syft -o json sample_nginx | jq '.artifacts[] | select (.name == "nginx")'
…
"metadata": {
"package": "nginx", "source": "", "version": "1.18.0-6ubuntu14.3", "sourceVersion": "", "architecture": "amd64", "maintainer": "Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>", "installedSize": 49, "files": …
}
Modus – Dockerイメージを定義する方法は、Dockerfileテキストファイルだけではありません。Modus言語は、基本的な設定標準をより柔軟な(ただし非標準の)設定構文に置き換えます。この言語は、イメージ構築タスクの一部を並列化し、イメージ定義内でパラメータ化された決定を使用することを可能にします。
例えば、以下の標準的なDocker設定イメージ定義とModusイメージ定義を比較してみましょう
FROM gcc:bullseye AS app
COPY program.c program.c
ARG PROFILE
RUN if [ "$PROFILE" = "debug" ] ; then \
CFLAGS=-g make -e program ; \
else \
make program ; \
fi
app(profile) :-
from("gcc:bullseye"),
copy("program.c", "program.c"),
make(profile).
make("debug") :- run("make -e program")::in_env("CFLAGS", "-g").
make("release") :- run("make program").
Envd – イメージを定義するためのDockerfileテキスト設定ファイルは、通常、ほぼすべてのユースケースに対応可能です。ただし、専門的なユーザーは、より柔軟性や構造を必要とする場合があります。envd CLIツールは、標準的なPythonコードを通じて定義されたML/AI用のイメージを作成できます。
例えば、以下のスクリプトを使用すると、人気のJupyter lab開発環境とNumPy Pythonライブラリを同時に実行するイメージを作成できます。
def build():
base(os="ubuntu22.04", language="python3")
# Configure the pip index if needed.
# config.pip_index(url = "https://pypi.tuna.tsinghua.edu.cn/simple")
install.python_packages(name = [
"numpy",
])
shell("zsh")
config.jupyter()
Envdの画像構築アプローチでは、Pythonの便利なユーティリティ(pipなど)を活用しており、これにより画像のコンパイルが高速化されるほか、様々な利点があります。
Miniboss。コンテナの構成は開発環境に複数の利点をもたらしますが、Docker Composeスタックを定義するために使用されるYAML(Yet Another Markup Language)標準は、完全なプログラミング言語ほど柔軟ではない場合があります。
Minibossは、開発者がスタックを作成し、Pythonスクリプトで定義することを可能にします。また、コンテナの状態変化に対してロジックに基づいた反応を可能にするコンテナライフサイクルフックも提供します。例えば、以下のスクリプトはPostgresデータベースコンテナと依存するWebアプリケーションを設定します
#! /usr/bin/env python3
import miniboss
miniboss.group_name('readme-demo')
class Database(miniboss.Service):
name = "appdb"
image = "postgres:10.6"
env = {"POSTGRES_PASSWORD": "dbpwd",
"POSTGRES_USER": "dbuser",
"POSTGRES_DB": "appdb" }
ports = {5432: 5433}
class Application(miniboss.Service):
name = "python-todo"
image = "latinxpower/python-todo:0.0.1"
env = {"DB_URI": "postgresql://dbuser:dbpwd@appdb:5432/appdb"}
dependencies = ["appdb"]
ports = {8080: 8080}
stop_signal = "SIGINT"
if name == "main":
miniboss.cli()
Ctop:コンテナのパフォーマンスは、ローカル環境では測定がやや困難です。Linux開発者はtop/htopを使用してプロセスメトリクスを取得することに精通していますが、ctopユーティリティを使用することで、シェルターミナル上で実行中のコンテナごとの基本的なCPU、メモリ、ネットワーク使用状況を確認できるほか、特定のコンテナの個別グラフィックインジケーターも表示できます。
Dockerボリュームバックアップ:ローカルコンテナは作成されるたびにファイルシステムの状態を失います。Docker用語でいうボリュームとは、コンテナデータを永続化するためのローカルディスクの抽象化です。特定のコンテナに対してローカルフォルダをボリュームとしてアタッチし、複数のコンテナライフサイクルイベントにわたってデータを保持することが可能です。
docker-volume-backupユーティリティを使用すると、これらのボリュームをローカルディレクトリ、AWSなどのクラウドサービス、またはMinIO互換の場所にバックアップ/復元できます。
Watchtower – 開発中、あるコンテナを起動し、別のよりアクティブなコンテナの依存関係としてバックグラウンドで実行させることは一般的です(データベースコンテナはその好例です)。Watchtowerは定期的にコンテナが最新の利用可能なイメージで実行されているかを確認し、そうでない場合は最新のイメージを使用して自動的に再起動します。
「pre-」および「post-」フックを備えており、特定のイベント発生時に影響を受けるコンテナ内でコードを実行するスクリプトを起動します。
Sidekick – コンテナは隔離された環境であるため、コンテナ内で実行中のコードをデバッグすることは容易ではありません。この問題は、オープンソースのSidekickエージェントをコンテナ内に配置することで解決できます。これにより、実行環境に影響を与えることなくログ、トレース、エラースタックを収集できます。
現在の実装は、Java、Python、Node.jsアプリケーションに対応しています。また、開発者に広く利用されている複数のIDE(VS Codeなど)向けのプラグインも提供されています。
DockerSlim – イメージの構築と正常な実行が完了したら、イメージサイズや既知の脆弱性などの詳細情報を確認することが可能です。オープンソースのDockerSlimツールはDockerイメージを検証し、サイズを最適化します(イメージを小さく保つことは、リソース消費の削減やビルド/転送/インスタンス化の時間短縮につながるため推奨されます)。
また、各レイヤーにおける攻撃対象領域の脆弱性もチェックします。X-rayユーティリティでイメージへの変更点を確認できます。
Registry Pruner。ローカルイメージは最終的な保存場所ではありません。通常、実行可能にするためには、Docker Hubなどのパブリックまたはプライベートレジストリにイメージを公開したいと考えるでしょう。しかし、これらのイメージには通常、ビジネスで定義されたライフサイクルがあり、特定のポリシーに基づいて特定のイメージを廃止または削除する必要があります。
このタスクはregistry-prunerツールで自動化できます。このツールを使用すると、ルールをコード化し、標準的なDockerイメージレジストリに適用することが可能です。
Docker開発者のベストプラクティスと考慮事項
セキュリティとアクセス管理
開発者が一般的な攻撃(Dockerfileセキュリティ対策があります。
- ホストとDockerのインストールを常に最新の状態に保ってください。
- Docker を root ユーザーとして実行しないようにしてください。
- コンテナ内では root 以外のユーザーを使用してください。
- イメージやダウンロードしたファイルをリリースまたは使用する前に、CVE のスキャンを行ってください。
- ホストのリソース使用量の上限を設定してください。
- 読み取り専用ボリュームを使用してください。
- 複数ステップのイメージ構築を行う Dockerfile を作成してください。
- イメージレジストリの管理を容易にするため、メタデータを使用してください。
まとめ
コンテナは現在、開発サイクルの重要な要素となっております。Dockerツールセットにより、開発者はあらゆるアプリケーション設計にコンテナの概念を統合することが可能となります。また、DevSecOpsのベストプラクティスを容易に実装できるDocker開発者向けツールも複数存在します。
Dockerエコシステムは充実しており、コンテナを扱う際の開発者体験を自動化および強化する多くの補完ツールを提供しています。
