SoFunction
Updated on 2025-03-09

Docker-swarm: Use Docker secret to manage sensitive data

About secret

As far as Docker Swarm cluster services are concerned, secret is block data, such as passwords, SSH private keys, SSL certificates, or other data that should not be transmitted over the network or stored in Dockerfile or application source code. We can centrally manage this data using Docker secret and transfer it safely to the containers that need to access it. Encrypted during transmission and saved in Docker cluster. Only services that have been approved to explicitly access it can access a given secret and only when these service tasks are running.

You can use secret to manage any sensitive data the container needs at runtime. For example, the situation:

  • Username and password
  • TLS certificate and key
  • SSH key
  • Other important data, such as the name of the database or internal server
  • Universal string or binary content (size up to 500kb)

Notice: Docker secret is only available for cluster services, not for standalone containers. To use this feature, consider tweaking your container to run as a service. Stateful containers can usually be run at a scale of 1 without changing the container code.

Another use case for using secret is to provide a layer of abstraction between a container and a set of credentials. Consider a scenario where your application has a separate development, testing and production environment. Each of these environments can have different credentials stored in development, test, and production groups with the same secret name. Your container just needs to know the name of the secret to run in all three environments.

You can also use secret to manage non-sensitive data, such as configuration files. However, Docker supports the use of configurations to store non-sensitive data. Configure the file system mounted directly to the container without the use of RAM disks.

Support for Windows

Docker includes support for secret on Windows containers. If there are differences in implementation. There are the following differences, which are illustrated in the following examples:

  • Microsoft Windows does not have a built-in driver for managing RAM disks, so in a running Windows container, secret continues to the container's root disk with clear text. However, when the container stops, the secret is explicitly deleted. In addition, Windows does not support usingdocker commitOr similar commands persist the run container as an image.
  • On Windows, we recommend enabling on volumes that contain the Docker root directory on the hostBitLocker① to ensure that the secret running the container is encrypted at rest.
  • Secret files with custom targets will not be directly bound to mountWindowsIn the container, becauseWindowsNon-directory file binding mount is not supported. On the contrary, the container'ssecretAll installed in containersC:\ProgramData\Docker\internal\secrets(Implementation details that applications should not rely on). Symbol links are used to point to inside the container from theresecretthe desired goal. The default target isC:\ProgramData\Docker\secrets
  • When creating a service that uses Windows containers, secret does not support options to specify UID, GID, and schema. Currently only administrators and havesystemUsers with access permissions can only access secret.

How Docker manages secret

When you add secret to the cluster, Docker passes mutualTLSThe connection willsecretSend to the group manager.secretStored inRaftIn the log, the log is encrypted. entireRaftLogs are replicated between other management nodes, ensuring the same high availability guarantee as other swarm management data.

When you grant access to the key to a newly created or running service, the decrypted key is installed in a container in the memory file system. The position of the mount point in the container isLinuxIn the container/run/secrets/<secret_name>,orWindowsIn the containerC:\ProgramData\Docker\secrets. You can also specify a custom location.

You can update the service at any time to grant it access to othersecretor revoke its givensecretvisit.

Only if the node is a cluster manager or is running, approved for accesssecretThe node can access (encrypted) secret when the service task is used. When the container task stops running, the decrypted secret shared to it is uninstalled from the memory file system of the container and refreshed from the node's memory.

If the node is runningsecretWhen accessing a task container with permissions loses connection to the group, the task container can still access itsecret, but the update cannot be received until the node reconnects to the cluster.

You can add or check individualsecret, or list allsecret. You cannot delete the running service being usedsecret

To update or roll back more easilysecret, please considersecretAdd a version number or date to the name. Control in a given containersecretThe ability of the mounting points makes this easier.

docker secret command

  • docker secret createCreate asecret
  • docker secret inspectCheck out onesecretDetails of
  • docker secret ls Check how manysecret
  • docker secret rmdeletesecret
  • [--secret ] When creating a service, docker service create specifies the secret used
  • --secret-addand--secret-rm When updating the service secretdocker service update

Example

We use the following example to progressively illustrate how to use Docker secret. The images used in these examples have been updated to facilitate the use of Docker secret.

Notice: For simplicity, these examples use single-engine clusters and unscaled services. These examples use Linux containers, but Windows containers also support secret.

Define and use secret in writing files

docker-composeanddocker stackAll commands are supported for defining in writing filessecret

Example 1: Get started with secret

This simple example showssecretHow to play a role in several commands.

  • Add a Dockersecretdocker secret createThe command reads standard input because the last parameter indicating the file to be read by secret is set to-

 echo "This is a secret" | docker secret create my_secret_data -
root@master:~# echo "this is a demo secret" | docker secret create my-secret -
yy7gnh0ji9wm64fs841yej5kv
root@master:~# docker secret ls
ID                          NAME        DRIVER    CREATED         UPDATED
yy7gnh0ji9wm64fs841yej5kv   my-secret             5 seconds ago   5 seconds ago
root@master:~# 
  • Create aredisand grant it tosecretaccess permissions. By default, containers can be/run/secrets/<secret_name>Access key, but you can usetargetOptions to customize the file name on the container.
 docker service  create --name redis --secret my_secret_data redis:alpine

If an error occurs and the task fails and restarts repeatedly, you will see the following:

 docker service ps redis

usedocker psGetredisThe ID of the service task container so that you can usedocker container execConnect to the container and read the contents of the secret data file, which is read by default by everyone, andsecretThe same name.

Use the command to get the ID of the redis container service

 docker ps --filter name=redis -q

View the contents of secret in the container:

 docker container exec $(docker ps --filter name=redis -q) ls -l /run/secrets
 docker container exec $(docker ps --filter name=redis -q) cat /run/secrets/my_secret_data
root@master:~# docker exec $(docker ps --filter name=redis -q) ls -l /run/secrets
total 4
-r--r--r--    1 root     root            22 Aug  5 08:09 my-secret
root@master:~# docker exec $(docker ps --filter name=redis -q) cat /run/secrets
cat: read error: Is a directory
root@master:~# docker exec $(docker ps --filter name=redis -q) cat /run/secrets/my-secret
this is a demo secret
root@master:~# 
  • You can see that the content of secret has been mounted to our container.

  • If you submit the container, verify that the key is not available.

$ docker commit $(docker ps --filter name=redis -q) committed_redis
$ docker run --rm -it committed_redis cat /run/secrets/my_secret_data
cat: can't open '/run/secrets/my_secret_data': No such file or directory
  • We deletesecretDeletion failed becauseredisThe service is running and can access the secret.
 docker secret ls
 docker secret rm my_secret_data
  • By updating the service, from runningredisDelete access to the key in the service.
 docker service update --secret-rm my_secret redis
  • Repeat steps 3 and 4 again, and the verification service no longer accesses the key. The container ID is different becauseservice updateThe command will redeploy the service.
$ docker container exec -it $(docker ps --filter name=redis -q) cat /run/secrets/my_secret_data
cat: can't open '/run/secrets/my_secret_data': No such file or directory
  • Stop and delete the service and delete the key from Docker.
 docker service rm redis
 docker secret rm my_secret

Example 2: Using secret in Nginx service

This example is divided into two parts. The first part is about generating site certificates, not directly involved in Docker secret , but it sets up where we can store and use site certificates andNginxConfigure assecret

Generate a site certificate

Generate root CA and TLS certificates and keys for your site. For production sites, you may want to useLet’s Encryptetc services to generate TLS certificates and keys, but this example uses command line tools. This step is a bit complicated, but it's just a setup step so you have something to store as a Dockersecret. If you want to skip these substeps, you can useLet's Encrypt② Generate site key and certificate and name the fileand

  • Generate the root key.
 openssl genrsa -out "" 4096
  • Generate CSR using the root key.
 openssl req \
          -new -key "" \
          -out "" -sha256 \
          -subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA'
  • Configure the root CA. Edit a name calledand paste the following into it. This restricts the root CA from signing the leaf certificate instead of the intermediate CA.
[root_ca]
basicConstraints = critical,CA:TRUE,pathlen:1
keyUsage = critical, nonRepudiation, cRLSign, keyCertSign
subjectKeyIdentifier=hash
  • Sign the certificate.
 openssl x509 -req  -days 3650  -in "" \
               -signkey "" -sha256 -out "" \
               -extfile "" -extensions \
               root_ca
  • Generate site key.
 openssl genrsa -out "" 4096
  • Generate a site certificate and sign it with the site key.
 openssl req -new -key "" -out "" -sha256 \
          -subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost'
  • Configure site certificates. Edit a name calledand paste the following into it. This limits the site certificate so that it can only be used for verification servers and cannot be used for signing certificates.
[server]
authorityKeyIdentifier=keyid,issuer
basicConstraints = critical,CA:FALSE
extendedKeyUsage=serverAuth
keyUsage = critical, digitalSignature, keyEncipherment
subjectAltName = DNS:localhost, IP:127.0.0.1
subjectKeyIdentifier=hash
  • Sign the website certificate.
 openssl x509 -req -days 750 -in "" -sha256 \
    -CA "" -CAkey ""  -CAcreateserial \
    -out "" -extfile "" -extensions server
  • Nginx service does not require itandfiles, but you need them if you want to generate new site certificates. Protectdocument.

Configuring Nginx containers

  • Generate a very basic Nginx configuration that serves static files over HTTPS. TLS certificates and keys are stored as Docker secrets for easy rotation.

    In the current directory, create a name callednew file containing the following:

server {
    listen                443 ssl;
    server_name           localhost;
    ssl_certificate       /run/secrets/;
    ssl_certificate_key   /run/secrets/;
    location / {
        root   /usr/share/nginx/html;
        index   ;
    }
}
  • Create three secrets representing the key, certificate, and. As long as it is less than 500 KB, you can store any file as a secret. This allows you to decouple keys, certificates, and configuration from the services that use them. In each command, the last parameter indicates the file path to read secret from the host file system. In these examples, the secret name and file name are the same.
 docker secret create  
 docker secret create  
 docker secret create  
 docker secret ls

Create a service that runs Nginx and has access to three secrets.docker service createThe last part of the command fromThe location of secret creates a symbolic link to/etc//, where Nginx looks for additional configuration files. This step occurs before Nginx actually boots up, so if you change the Nginx configuration, you don't need to rebuild the image.

Notice: Normally, you will create a Dockerfile that will copy into place, build the image, and run the container with a custom image. This example does not require a custom image. It will be placed in place and run the container in one step.

By default, secret is located in the container/run/secrets/In the directory, this may require additional steps in the container to make the secret available in different paths. The following example creates a pointerSymbol links to the real location of the file, thusNginxIt can be read:

 docker service create \
        --name nginx \
        --secret  \
        --secret  \
        --secret  \
        --publish published=3000,target=443 \
        nginx:latest \
        sh -c "ln -s /run/secrets/ /etc/nginx// && exec nginx -g 'daemon off;'"

secret allows you to usetargetOptions specify custom locations, rather than creating symbolic links. The following example shows how to use a symbolic link inside a container/etc/nginx//Thesite is available onsecret :

docker service create \
     --name nginx \
  --secret  \
     --secret  \
     --secret source=,target=/etc/nginx// \
     --publish published=3000,target=443 \
     nginx:latest \
     sh -c "exec nginx -g 'daemon off;'"

andSecret uses shorthand syntax, no customizationtargetLocation settings. Short syntax mounts secret in `/run/secrets/ with the same name as secret. In the running container, the following three files now exist:

  • /run/secrets/
  • /run/secrets/
    • /etc/nginx//
  • Verify that the Nginx service is running.
 docker service ls
 docker service ps nginx
  • Verify that the service is running: You have access to the Nginx server and are using the correct TLS certificate.
curl --cacert  https://localhost:3000
<title>Welcome to nginx!<</title>
<h1>Welcome to nginx!</h1>
If you see this page, the nginx web server is successfully installed and
For online documentation and support. refer to
<a></a>.<br/>
<p><a></a></p>
<p><em>Thank you for using nginx.</em></p>
 openssl s_client -connect localhost:3000 -CAfile 
  • We remove unwanted services and secrets
 docker service rm nginx
 docker secret rm   

Build support for Docker Secrets in mirrors

If you develop a container that can be deployed as a service and need sensitive data (such as credentials) as an environment variable, consider tuning your image to take advantage of Docker secret. One way is to make sure that every parameter you pass to the image when you create the container can also be read from the file.

Many official Docker images in the Docker hub have been updated in this way.

When you start a WordPress container, you can give it the parameters you want by setting it as an environment variable. WordPress images have been updated, so environment variables containing important WordPress data (e.g.WORDPRESS_DB_PASSWORD) also has the file(WORDPRESS_DB_PASSWORD_FILE) reads a variant of its value. This policy ensures backward compatibility while allowing your container to read information from Docker-managed secrets instead of passing them directly.

NOTE

Docker secrets do not set environment variables directly. This is a conscious decision because environment variables may be leaked between containers by accident (e.g. if you use--link)。

Using secret in docker-compose

services:
   db:
     image: mysql:latest
     volumes:
       - db_data:/var/lib/mysql
     environment:
       MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD_FILE: /run/secrets/db_password
     secrets:
       - db_root_password
       - db_password
   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD_FILE: /run/secrets/db_password
     secrets:
       - db_password
secrets:
   db_password:
     file: db_password.txt
   db_root_password:
     file: db_root_password.txt
volumes:
    db_data:

This example creates a simple WordPress website using two secrets in a writing file.

Keywordssecrets:Define two secretsdb_password:anddb_root_password:

When deployed, Docker creates these two secrets and fills them with the contents of the file specified in the write file.

The db service uses two secrets at the same time, while Wordpress is using one secret.

When you deploy, Docker will be in service./run/secrets/<secret_name>Download a file. These files are never persisted on disk, but are managed in memory.

Each service uses environment variables to specify where the service should look for that secret data.

The above is the detailed content of using Docker secret to manage sensitive data by docker-swarm. For more information about Docker secret management data, please pay attention to my other related articles!