At times, we need to update a secret in a running service, the reason being that secrets could be leaked out to the public or be stolen by malicious people, such a hackers. In this case, we need to change our confidential data since the moment it has leaked to a non-trusted entity, it has to be considered as insecure.
The updating of secrets, like any other update, has to happen in a way which requires zero downtime. SwarmKit supports us in this regard.
First, we create the new secret in the Swarm. It is recommended to use a versioning strategy when doing so. In our example, we use a version as a postfix of the secret name. We originally started with the secret named db-password and now the new version of this secret is called db-password-v2:
$ echo "newPassw0rD" | docker secret create db-password-v2 -
Assume that the original service that used the secret had been created like this:
$ docker service create --name web \
--publish 80:80
--secret db-password
nginx:alpine
The application running inside the container was able to access the secret at /run/secrets/db-password. Now, SwarmKit does not allow us to update an existing secret in a running service, thus we have to first remove the now obsolete version of the secret and then add the new one. Let's start with the removal with the following command:
$ docker service update --secret-rm db-password web
And then we can add the new secret with the following command:
$ docker service update \
--secret-add source=db-password-v2, target=db-password \
web