我在docker-compose中运行Vault时遇到了很大的麻烦。
我的要求是:
我当前的docker-compose
version: '2.3'
services:
vault-dev:
image: vault:1.2.1
restart: always
container_name: vault-dev
environment:
VAULT_DEV_ROOT_TOKEN_ID: "myroot"
VAULT_LOCAL_CONFIG: '{"backend": {"file": {"path": "/vault/file"}}, "default_lease_ttl": "168h", "max_lease_ttl": "720h"}'
ports:
- "8200:8200"
volumes:
- ./storagedc/vault/file:/vault/file
但是,当容器重新启动时,我得到了日志
==> Vault server configuration:
Api Address: http://0.0.0.0:8200
Cgo: disabled
Cluster Address: https://0.0.0.0:8201
Listener 1: tcp (addr: "0.0.0.0:8200", cluster address: "0.0.0.0:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
Log Level: info
Mlock: supported: true, enabled: false
Storage: file
Version: Vault v1.2.1
Error initializing Dev mode: Vault is already initialized
对此有什么建议吗?
我将对答案进行伪编码以解决指定的问题,但是请注意,这是一个巨大的漏洞,应NEVER作为硬编码主密钥和单个解封密钥部署在生产中是完全不安全。
因此,您需要具有持久性的测试库服务器。
您可以完成此操作,由于Vault容器的默认行为,它需要做一些工作-如果您仅启动它,它将以dev模式容器开始,该容器不允许持久性。仅通过环境变量添加持久性并不能完全解决该问题,因为它将与容器的默认启动模式冲突。
因此,我们需要用执行我们希望它执行的操作替换此入口点脚本。
首先我们将脚本从容器中复制出来:
$ docker create --name vault vault:1.2.1
$ docker cp vault:/usr/local/bin/docker-entrypoint.sh .
$ docker rm vault
[为简单起见,我们将编辑该文件,然后使用docker-compose文件将其安装到容器中。我不会使它真正发挥作用-仅足以使其完成所需的工作。这里的重点是样本,而不是可用于生产的东西。
我的定制全部从第98行开始-首先我们启动开发模式服务器以记录解封密钥,然后终止开发模式服务器。
# Here's my customization:
if [ ! -f /vault/unseal/sealfile ]; then
# start in dev mode, in the background to record the unseal key
su-exec vault vault server \
-dev -config=/vault/config \
-dev-root-token-id="$VAULT_DEV_ROOT_TOKEN_ID" \
2>&1 | tee /vault/unseal/sealfile &
while ! grep -q 'core: vault is unsealed' /vault/unseal/sealfile; do
sleep 1
done
kill %1
fi
接下来,我们检查补充配置。这是用于禁用TLS和绑定适当接口的额外配置的地方。
if [ -n "$VAULT_SUPPLEMENTAL_CONFIG" ]; then
echo "$VAULT_SUPPLEMENTAL_CONFIG" > "$VAULT_CONFIG_DIR/supplemental.json"
fi
然后我们以“发布”模式启动保管库:
if [ "$(id -u)" = '0' ]; then
set -- su-exec vault "$@"
"$@"&
然后我们从印章文件中获得开封钥匙:
unseal=$(sed -n 's/Unseal Key: //p' /vault/unseal/sealfile)
if [ -n "$unseal" ]; then
while ! vault operator unseal "$unseal"; do
sleep 1
done
fi
我们只是等待过程终止:
wait
exit $?
fi
现在执行此操作的docker-compose.yml与您自己的稍有不同:
version: '2.3'
services:
vault-dev:
image: vault:1.2.1
restart: always
container_name: vault-dev
command: [ 'vault', 'server', '-config=/vault/config' ]
environment:
VAULT_DEV_ROOT_TOKEN_ID: "myroot"
VAULT_LOCAL_CONFIG: '{"backend": {"file": {"path": "/vault/file"}}, "default_lease_ttl": "168h", "max_lease_ttl": "720h"}'
VAULT_SUPPLEMENTAL_CONFIG: '{"ui":true, "listener": {"tcp":{"address": "0.0.0.0:8200", "tls_disable": 1}}}'
VAULT_ADDR: "http://127.0.0.1:8200"
ports:
- "8200:8200"
volumes:
- ./vault:/vault/file
- ./unseal:/vault/unseal
- ./docker-entrypoint.sh:/usr/local/bin/docker-entrypoint.sh
cap_add:
- IPC_LOCK
command
是要执行的命令。这是脚本更改的"$@"&
中的内容。
我为非开发运行添加了VAULT_SUPPLEMENTAL_CONFIG
。它需要指定接口,它需要打开tls。我添加了ui,因此可以使用http://127.0.0.1:8200/ui
访问它。这是我对该脚本所做的更改的一部分。
因为这对我来说都是本地测试,所以我将./vault
挂载为数据目录,将./unseal
挂载为记录解封代码的位置,并将./docker-entrypoint.sh
挂载为入口点脚本。
我可以docker-compose up
,它会启动一个持久性文件库-在服务器启动之前,我尝试取消密封时,日志中存在一些错误,但是它可以正常工作,并且在多个docker-compose
运行中都可以持久存在。
再次提及,这完全不适合任何形式的长期使用。如果您要执行此类操作,则最好使用Docker自己的秘密引擎。