Docker-compose.yml仕様のバージョン3.1では、 secrets のサポートが導入されています。
私はこれを試しました:
version: '3.1'
services:
a:
image: tutum/hello-world
secret:
password: the_password
b:
image: tutum/hello-world
$ docker-compose up
は以下を返します。
Unsupported config option for services.secret: 'password'
実際にシークレット機能を使用するにはどうすればよいですか?
公式ドキュメントの対応するセクション を読むことができます。
シークレットを使用するには、docker-compose.yml
ファイルに2つのものを追加する必要があります。最初に、すべての秘密を定義するトップレベルのsecrets:
ブロック。次に、各サービスの下にある別のsecrets:
ブロックが、サービスが受信する必要があるwhichシークレットを指定します。
例として、Dockerが理解できる2種類のシークレットを作成します:externalsecretsとfile秘密。
docker secret create
を使用して「外部」シークレットを作成しますまず、Dockerでシークレットを使用するには、現在いるノードがswarmの一部でなければなりません。
$ docker swarm init
次に、「外部」シークレットを作成します。
$ echo "This is an external secret" | docker secret create my_external_secret -
(必ず最後のダッシュ-
を含めるようにしてください。見落としがちです。)
$ echo "This is a file secret." > my_file_secret.txt
docker-compose.yml
ファイルを作成します両方のタイプのシークレットが作成されたので、これらの両方を読み取り、web
サービスに書き込むdocker-compose.yml
ファイルを次に示します。
version: '3.1'
services:
web:
image: nginxdemos/hello
secrets: # secrets block only for 'web' service
- my_external_secret
- my_file_secret
secrets: # top level secrets block
my_external_secret:
external: true
my_file_secret:
file: my_file_secret.txt
Dockerは、独自のデータベース(たとえば、docker secret create
で作成されたシークレット)またはファイルからシークレットを読み取ることができます。上記は両方の例を示しています。
次を使用してスタックをデプロイします。
$ docker stack deploy --compose-file=docker-compose.yml secret_test
これにより、secret_test_web
という名前のweb
サービスのインスタンスが1つ作成されます。
docker exec -ti [container] /bin/sh
を使用して、シークレットが存在することを確認します。
(注:以下のdocker exec
コマンドでは、m2jgac...
部分はマシンによって異なります。docker ps
を実行して、コンテナー名を見つけます。)
$ docker exec -ti secret_test_web.1.m2jgacogzsiaqhgq1z0yrwekd /bin/sh
# Now inside secret_test_web; secrets are contained in /run/secrets/
root@secret_test_web:~$ cd /run/secrets/
root@secret_test_web:/run/secrets$ ls
my_external_secret my_file_secret
root@secret_test_web:/run/secrets$ cat my_external_secret
This is an external secret
root@secret_test_web:/run/secrets$ cat my_file_secret
This is a file secret.
すべてうまくいけば、ステップ1と2で作成した2つの秘密は、スタックをデプロイしたときに作成されたweb
コンテナー内にあるはずです。
サービスmyapp
とシークレットファイルsecrets.yml
があるとします:
作成ファイルを作成します。
version: '3.1'
services:
myapp:
build: .
secrets:
secrets_yaml
次のコマンドを使用してシークレットをプロビジョニングします。
docker secret create secrets_yaml secrets.yml
次のコマンドを使用してサービスをデプロイします。
docker deploy --compose-file docker-compose.yml myappstack
これで、アプリは/run/secrets/secrets_yaml
のシークレットファイルにアクセスできます。アプリケーションでこのパスをハードコーディングするか、シンボリックリンクを作成できます。
異なる質問
この回答は、おそらく「ドッカースウォームクラスターにシークレットをどのようにプロビジョニングしますか」という質問に対するものです。
元の質問「docker composeで秘密の値を管理する方法」は、docker-composeファイルに秘密の値が含まれていることを意味します。そうではありません。
別の質問があります:「secrets.yml
ファイルの正規のソースをどこに保存しますか」。これはあなた次第です。頭に保存したり、紙に印刷したり、パスワードマネージャーを使用したり、専用のシークレットアプリケーション/データベースを使用したりできます。それは、Gitリポジトリが安全に保護されている場合でも使用できます。もちろん、セキュリティで保護しているシステム内に保管しないでください:)
vault をお勧めします。シークレットを保存するには:
# create a temporary secret file
cat secrets.yml | vault write secret/myappsecrets -
シークレットを取得してドッカーの群れに入れるには:
vault read -field=value secret/myappsecrets | docker secret create secrets_yaml -
もちろん、Dockerクラスター自体を秘密の唯一の真実のソースとして使用できますが、Dockerクラスターが壊れると、秘密が失われてしまいます。そのため、別の場所にバックアップがあることを確認してください。
誰も尋ねなかった質問
3番目の質問(誰も尋ねなかった)は、開発者のマシンにシークレットをプロビジョニングする方法です。ローカルでモックできない外部サービスや、コピーできない大規模なデータベースがある場合に必要になることがあります。
繰り返しますが、dockerは(まだ)それとは関係ありません。どの開発者がどのシークレットにアクセスできるかを指定するアクセス制御リストはありません。また、認証メカニズムもありません。
理想的な解決策は次のように見えます:
docker secret create
コマンドの長いリストをコピーして、ターミナルで実行します。そのようなアプリケーションがポップアップするかどうかはまだわかりません。
secrets
オブジェクトのfile:
キーを使用して、ファイルにローカルに保存されているsecrets
を指定することもできます。そうすれば、自分でdocker secret create
する必要はありません。Compose/ docker stack deploy
があなたのためにそれを行います。
version: '3.1'
secrets:
password:
file: ./password
services:
password_consumer:
image: Alpine
secrets:
- password
キーワードはsecrets
ではなくsecret
だと思います。それは少なくとも schema を読んで理解することです。
docker-compose.yml
ファイルの正確なインデントですか? I 考える secret
secrets
は、a
セクションの下に直接ではなく、services
(サービスの1つ)の下にネストする必要があります。