そんな今日この頃の技術ネタ

本家側に書くほどでもない小ネタ用

Docker/Docker ComposeのSecretsを試す

接続情報などコンテナ内への記述が憚られる情報について外部から与える方法としてsecretsがdocker 1.13/docker-compose.yamlのformat ver3.1からサポートされた。

予めdocker secretコマンドでファイルを登録するか、もしくはdocker-compose.yaml内でファイルを指定することで、それらのファイルがコンテナ内の/run/secretesディレクトリ以下にマウントされる。

yamlに記載する場合

以下のようなファイル構成を想定。

$ tree
.
├── docker-compose.yaml
└── sec.txt

秘匿すべきファイルとしてsec.txtを想定。

$ cat sec.txt
hogehoge

secrets項として該当のファイルをmy_secret項として登録し、services項にてsecretsとしてそれを指定することで、ファイルとして参照できる。

$ cat docker-compose.yaml
version: "3.1"

services:
  app:
    image: busybox:latest
    secrets:
    - my_secret
    command:
    - cat
    - /run/secrets/my_secret
secrets:
  my_secret:
    file: ./sec.txt
$ docker-compose up
Starting dockercomposesecret_app_1 ...
Starting dockercomposesecret_app_1 ... done
Attaching to dockercomposesecret_app_1
app_1  | hogehoge
dockercomposesecret_app_1 exited with code 0

コマンドで予め登録する場合

公式: Manage sensitive data with Docker secrets

どうやらswarm機能の一環として実装されているらしいので先にswarm initする必要があるらしい。

$ docker swarm init
Swarm initialized: current node (odn5nmwyhj203vlnkrti544gi) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-10jgqkjqdhmoxcikwgwgq3hsapncrq316aftlycyckry7ia70b-2zc57vshrm59ghegvw4sepxg0 192.168.65.2:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

docker secret create <NAME> <FILE>の形で登録。

$ docker secret create my_secret ./sec.txt
rephypzjg40wbr5kwiprqt63z
$ docker secret ls
ID                          NAME                CREATED              UPDATED
rephypzjg40wbr5kwiprqt63z   my_secret           About a minute ago   About a minute ago

先の方法ではファイルのパスを指定していた部分をexternal: trueという記述に書き換え。

$ cat docker-compose.yaml
version: "3.1"

services:
  app:
    image: busybox:latest
    secrets:
    - my_secret
    command:
    - cat
    - /run/secrets/my_secret
secrets:
  my_secret:
    external: true

docker-compose upコマンドはswarmモードに対応していないので新しいdocker stack deployコマンドを用いる。

$ docker stack deploy --compose-file docker-compose.yaml secret-test
Creating network secret-test_default
Creating service secret-test_app
$ docker stack services secret-test
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
io4npociwqm1        secret-test_app     replicated          1/1                 busybox:latest
$ docker stack ps secret-test
ID                  NAME                    IMAGE               NODE                DESIRED STATE       CURRENT STATE             ERROR               PORTS
ryzklyyfag00        secret-test_app.1       busybox:latest      moby                Ready               Ready 1 second ago
4z9kyhm8y5lq         \_ secret-test_app.1   busybox:latest      moby                Shutdown            Complete 1 second ago
qn65vjl7p4ax         \_ secret-test_app.1   busybox:latest      moby                Shutdown            Complete 12 seconds ago
b5e5hvtd9sh1         \_ secret-test_app.1   busybox:latest      moby                Shutdown            Complete 19 seconds ago
eq71oiqu7xrh         \_ secret-test_app.1   busybox:latest      moby                Shutdown            Complete 27 seconds ago
$ docker service logs secret-test_app
secret-test_app.1.qn65vjl7p4ax@moby    | hogehoge
secret-test_app.1.4z9kyhm8y5lq@moby    | hogehoge
secret-test_app.1.b5e5hvtd9sh1@moby    | hogehoge
secret-test_app.1.eq71oiqu7xrh@moby    | hogehoge
secret-test_app.1.ryzklyyfag00@moby    | hogehoge
$ docker stack rm secret-test
Removing service secret-test_app
Removing network secret-test_default

どうやらk8s同様に単発で死ぬ系は再試行されてしまうらしい。ひとまずsecretsの内容は拾えた。


まとめ

  • k8sのkind: Secretに相当する
  • こちらは直に環境変数に吐く手段はない
  • ディレクトリも/run/secrets以下に限定される

あとdockerの新しいコマンド体系は複雑でおいちゃんにはちょっとつらい。

Docker

Docker