Dockerランタイム
Docker実行時にKeeper Secrets Managerからシークレットを取得

機能
Dockerコンテナ実行時にKeeperボルトからシークレットを動的に取得
Keeperシークレットマネージャーの機能一覧については、概要をご参照ください。
前提条件
本ページでは、シークレットマネージャーとDockerランタイムとの連携について取り扱います。本連携を利用するには、以下が必要です。
Keeperシークレットマネージャーへのアクセス(クイックスタートガイドをご参照ください)
Keeperのサブスクリプションでシークレットマネージャーアドオンが有効になっていること
シークレットマネージャーポリシーが有効なロールに所属していること
シークレットが共有されているKeeper シークレットマネージャーアプリケーション
アプリケーションの作成手順については、クイックスタートガイドをご参照ください
KSM CLIの設定手順については、こちらをご参照ください
概説
KeeperシークレットマネージャーはDockerランタイムと連携しており、コンテナ実行時にボルトからシークレットを動的に取得できます。
ksm コマンドでコンテナ起動時に環境変数を設定すれば、デプロイメントスクリプトへのハードコーディングを避けられます。以下に実装例を示します。
例: MySQLネットワークユーザーアカウントのプロビジョニング
公式のMySQL dockerを使用すると、ユーザーはMySQL rootパスワードを設定し、環境変数を使用してネットワークアクセス可能なユーザーを作成できます。MySQLインスタンスは、コンテナの実行時にプロビジョニングされます。
公式のMySQL Dockerfileは以下のとおりです。
標準実装では、ENTRYPOINTがコンテナのプロビジョニングを担当し、渡された環境変数を使ってMySQLを設定します。参照される環境変数は以下のとおりです。
MYSQL_ROOT_PASSWORD
MYSQL_USER
MYSQL_PASSWORD
MYSQL_DATABASE
以下の手順では、Keeperボルトに格納されたシークレットを使用してMySQLデータベースを初期化する方法を示します。
手順 1: シークレットを格納する2つのボルトレコードを作成
シークレットマネージャーアプリケーションが管理する2つのレコードをボルトに作成します。一方にはrootパスワード、もう一方には通常ユーザー、パスワード、データベース名を格納します。


ボルトのレコードに表示されるレコードUIDを必ずコピーしてください。手順3でボルトのシークレットを参照するときに使用します。


手順 2: デフォルトのMySQL DockerfileをベースにしたDockerfileを作成
KeeperシークレットマネージャーCLI(ksm)をインストールし、ksm exec でENTRYPOINTをラップするDockerfileを作成します。
以下のDockerfileでは、Keeper表記法を使用して4つの環境変数を置き換えています。また、シークレットが格納されているボルトを示すシークレットマネージャープロファイルも渡します。
手順 3: dockerビルドを実行するシェルスクリプトを作成
docker buildを実行するには、以下のスクリプトでシークレットマネージャーのデバイス設定と、シークレットを含むボルトのrootユーザーのレコードUIDとネットワークユーザーのレコードUIDを渡します。
例: KSM CLI Dockerイメージの使用
KSM CLI Dockerには、GLIBC(ほとんどのLinuxディストリビューション)とMUSL(Alpine Linux)の両方のCLIバイナリへのボリュームマウントが含まれています。ボリュームは /cli です。このディレクトリは、docker-composeの volumes_from またはコマンドラインdockerの -v を使用して、別のコンテナにマウントできます。ksm の実行可能ファイルは、Linuxディストリビューションが使用しているCライブラリのバージョン別のディレクトリにあります。
/cli/glibc/ksm: Ubuntu、Debian、Fedora、CentOSなどの標準GLIBCディストリビューション/cli/musl/ksm: Alpine Linux
たとえば、CLIバイナリにアクセスする方法を示す簡単なフレームワークを以下に示します。
init サービスはCLI dockerをロードします。コンテナが起動し、CLIのスプラッシュ画面が表示されてから終了します。コンテナが停止しても、/cli ボリュームには他のコンテナから引き続きアクセスできます。
main サービスは volumes_from を使用して、CLI dockerのボリュームをディレクトリ /cli にマウントします。command でオーバーライドして、KSM CLIのGLIBCバージョンを実行します。command はCLIの exec 機能を使用します。これにより、Keeper表記法を使用する環境変数がシークレット値に置き換えられます。CLIの exec コマンドは printenv を実行し、Keeper表記法に設定された環境変数MY_LOGINの値を、シークレットに置き換えて表示します。
例: KSM CLI Dockerと他のベンダーのDockerイメージの併用
上記の例と同様に、カスタムDockerイメージを作成せずに、KSM CLI dockerを使用して、別のベンダーのDockerイメージのエントリポイントとコマンドをオーバーライドできます。
この例では、最初の2つの例を組み合わせます。
この例では、Docker HubリポジトリからDockerイメージを取得し、DockerfileがGitHubに公開されていることを前提としています。
オペレーティングシステムのディストリビューション
最初の手順は、ベンダーのDockerイメージがどのオペレーティングシステムのディストリビューションに基づいて作成されているかを判定することです。通常はタグ名で判定できます。たとえば、イメージタグ名に「alpine」が含まれている場合は、Alpine Linuxであることがわかります。
イメージタグ名にディストリビューションが示されていない場合は、そのイメージのDocker Hubウェブページで、「サポートされているタグ(Supported tags)」セクションのタグ名をクリックします。すると、Dockerfileの内容が表示されます。FROMステートメントは、ベンダーがイメージ作成のベースにしたディストリビューションを示します。FROMステートメントで判明しない場合は、継承したFROMイメージのDockerfileをご確認ください。

MySQL 8.0.31は、タグ名にオペレーティングシステムのディストリビューションを示しません。MySQL Docker Hubページでは、8.0.31タグがGitHubリポジトリにリンクしています。このDockerfileから、ディストリビューションがOracle Linuxであることがわかります。

ディストリビューションをチェックする目的は、どのバージョンのlibcライブラリが使用されているかを確認することです。ほとんどのディストリビューションはGLIBCを使用していますが、一部(主にAlpine Linux)はMUSLを使用しています。これは、KSM CLI Dockerイメージから正しいバイナリを選択するために必要です。間違ったバイナリを選択すると、exec /cli/musl/ksm: no such file or directoryまたはexec /cli/glibc/ksm: no such file or directoryのようなエラーが表示されます。この例では、Oracle LinuxはGLIBCディストリビューションです。
エントリーポイントとコマンド
続いて、ベンダーのDockerイメージのENTRYPOINTとCMDを特定します。Dockerfileには、ENTRYPOINTとCMDの両方、またはいずれか一方が記載されます。

このMySQL Dockerfileでは、ENTRYPOINTは ["docker-entrypoint.sh"] で、CMDは ["mysqld"] です。つまり、ENTRYPOINTはCMDの先頭に追加されるため、コンテナ起動時に docker-entrypoint.sh mysqld が実行されます。
docker-compose.yml
docker-compose.ymldocker-composeでは2つのサービスを使います。
initサービスは keeper/keeper-secrets-manager-cli Dockerイメージのボリュームを読み込みます。このイメージは起動して終了しますが、終了後もボリュームには引き続きアクセスできます。
mainサービスはinitサービスの後に実行されます。docker-composeの depends_on ディレクティブで制御します。このサービスには、KSM CLI exec コマンドで置き換えられる 表記法 を使用した環境変数と、KSM CLIに必要なBase64でエンコードされた設定が含まれます。MySQL Dockerイメージのデータベースプロビジョニングで使用するMYSQL_環境変数もここで設定します。
また、mainサービスは volumes_from を使用してinitサービスからボリュームをマウントします。KSM CLI Dockerイメージには、ボリュームをエクスポートしてmainサービスコンテナにマウントする場所が定義されています。バイナリは /cli(libcバージョンと ksm バイナリ名が続く)にマウントされます。
MySQLイメージはOracleディストリビューション(GLIBCディストリビューション)を使用するため、mainサービスは /cli/glibc/ksm バイナリを使用します。
mainサービスは、MySQLイメージのENTRYPOINTとCMDをオーバーライドします。entrypointとcommandを使用して実行します。エントリポイントは、KSM CLIの exec コマンドで元のENTRYPOINT docker-entrypoint.sh を実行します。commandは同じですが、docker-compose.yml で設定する必要があります。設定しないと、サービスは終了します。
使用しているDockerイメージによっては、ENTRYPOINTとCMDのいずれか一方、またはその両方のオーバーライドが必要になる場合があります。
結果
サービス起動時、initサービスが最初に実行され、コード0で正常終了します。その後mainサービスが起動し、KSM CLIの exec コマンドを実行してから docker-entrypoint.sh mysqld が実行されます。この時点で環境変数はシークレットに置き換えられ、MySQLがプロビジョニングされ、mysqld が稼働しています。
Dockerランタイムの例に貢献
良い例がございましたら、Slackでご連絡いただくか、sm@keepersecurity.com までメールでお送りください。
最終更新

