特别提示:本文使用docker最新版本docker-18.04.0-CE,版本太旧可能不支持本文演示的功能。参考文档:https://docs.docker.com/engine/swarm/secrets/
敏感数据包括密码、私钥、证书及其它所有不能以明文的形式在网络上传输,或者是不能保存在各种文件中的数据,例如Dokerfile、image等。从docker 1.13开始,可以通过secret功能集中的保存与分发这些敏感数据,一个secret只允许被授权的服务在运行的时候访问,另外只有在集群模式下才能使用secret功能。docker以加密的形式保存与传输敏感数据,并且敏感数据会以分布式的形式存储在集群中的所以manager节点上,以提高可用性。
当对一个新建立的或者是运行中的service进行某个secret的授权时,docker会在内存中模拟一个文件,然后将解密后的数据放入文件中,并mount这个文件到容器的文件系统中,默认目录是/run/secrets/
docker secret同时也可以用来管理普通的配置项,但是从Docker 17.06开始,提供了专门用于管理非敏感数据的configs。两者的区别是secret用的是RAM来模拟文件系统保存敏感数据,使用敏感数据的容器是只读的。而config则直接使用普通的文件系统存储非敏感数据。
docker secret create
docker secret inspect
docker secret ls
docker secret rm
--secret
flag for docker service create
--secret-add
and --secret-rm
flags for docker service update
printf "This is a secret" | docker secret create my_secret_data -
如下图:
详细参考https://docs.docker.com/engine/swarm/secrets/#use-secrets-in-compose。
默认情况下,redis服务通过/run/secrets/my_secret_data取得密码,可在启动服务时通过target选项更改默认设置。
docker service create --name redis --secret my_secret_data redis:alpine
如下图:
task被调度在了worker2节点上。
docker container exec $(docker ps --filter name=redis -q) cat /run/secrets/my_secret_data
如下图:
docker service update --secret-rm my_secret_data redis
如下图:
可以看到service被停止掉后又重新拉起来了。
docker container exec $(docker ps --filter name=redis -q) cat /run/secrets/my_secret_data
结果如下图:
证明授权已经被收回。
docker service rm redis
docker secret rm my_secret_data
如下图:
# create tmp dir
mkdir /tmp/nginx-ca
cd /tmp/nginx-ca
# Generate a root key
openssl genrsa -out "root-ca.key" 4096
# Generate a CSR using the root key
openssl req \
-new -key "root-ca.key" \
-out "root-ca.csr" -sha256 \
-subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA'
# create root-ca.cnf file
echo "[root_ca]
basicConstraints = critical,CA:TRUE,pathlen:1
keyUsage = critical, nonRepudiation, cRLSign, keyCertSign
subjectKeyIdentifier=hash" > ./root-ca.cnf
# Configure the root CA use root-ca.cnf
openssl x509 -req -days 3650 -in "root-ca.csr" \
-signkey "root-ca.key" -sha256 -out "root-ca.crt" \
-extfile "root-ca.cnf" -extensions \
root_ca
# Sign the certificate
openssl genrsa -out "site.key" 4096
# Generate the site key
openssl req -new -key "site.key" -out "site.csr" -sha256 \
-subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost'
# create site.cnf file
echo "[server]
authorityKeyIdentifier=keyid,issuer
basicConstraints = critical,CA:FALSE
extendedKeyUsage=serverAuth
keyUsage = critical, digitalSignature, keyEncipherment
subjectAltName = DNS:localhost, IP:127.0.0.1
subjectKeyIdentifier=hash" > ./site.cnf
# Sign the site certificate
openssl x509 -req -days 750 -in "site.csr" -sha256 \
-CA "root-ca.crt" -CAkey "root-ca.key" -CAcreateserial \
-out "site.crt" -extfile "site.cnf" -extensions server
echo "server {
listen 443 ssl;
server_name localhost;
ssl_certificate /run/secrets/site.crt;
ssl_certificate_key /run/secrets/site.key;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}" > ./site.conf
docker secret create site.key site.key
docker secret create site.crt site.crt
docker secret create site.conf site.conf
docker service create \
--name nginx \
--secret site.key \
--secret site.crt \
--secret source=site.conf,target=/etc/nginx/conf.d/site.conf \
--publish published=3000,target=443 \
nginx:latest \
sh -c "exec nginx -g 'daemon off;'"
docker service rm nginx
docker secret rm site.crt site.key site.conf