Managing the password, access tokens and private keys are being tedious in the application. Any small mistakes accidentally expose all the secret information. Even storing such thing in docker images can be easily accessible one should just run the image in the interactive mode container and all your application code is available in containers. Docker provides secrets to protect all secret data.
This blog explains step-by-step guide for protecting sensitive data in docker. so, let’s get started.
What is Docker Secret?
A secret is a blob of data may consist of password or any other sensitive information. Docker secret centrally manages this data and securely transmit to containers that need to access it. A secret is encrypted over transport and only accessible to granted containers. Docker secret only works in swarm services, not available to the standalone container. Let’s understand how docker secret works.
When a docker secret is created the secret information is transmitted from docker to its swarm manager where it is stored in Raft log, which is encrypted and that encrypted log is circulated across the other manager to have higher accessibility over the swarm. Docker service can access the secret by mounting an encrypted location to it. The mounting location is /run/secrets/ in container. The secret is decrypted by the worker which is connected to that swarm. Let’s follow the example to understand it practically.
Starts with a very basic example in which we are going to provide secret of MySQL to its container and after that, we’ll cross-check by login with same credentials inside the container. As told in the beginning docker secret only works in swarm mode so first create a swarm. One way to create swarm by using VirtualBox on the single machine. You may create on multiple machines.
Step 1: create and initialize docker swarm
docker-machine create --driver virtualbox worker1 docker-machine create --driver virtualbox worker2
Make sure docker, docker-machine, as well as VirtualBox, is installed on your system before running above commands. Now assures that machines are correctly installed and running using command docker-machine ls. The output is like:
docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS worker1 - virtualbox Running tcp://192.168.99.102:2376 v17.09.1-ce worker2 - virtualbox Running tcp://192.168.99.103:2376 v17.09.1-ce
Now machines are configured and ready to start. Start the machines using command docker-machine start which changes its state to ready.
docker-machine start worker1 docker-machine start worker2
Now initialize the swarm mode and make connect the running worker to swarm.
docker swarm init --advertise-addr <manager-node-ip_address> Swarm initialized: current node (nsvmftqpb5p6amcqm5bpzwbs2) is now a manager.
After initializing the swarm a token id is provided which is being used to connect the workers to swarm. Let’s connect the workers.
docker-machine ssh worker1 "docker swarm join --token " docker-machine ssh worker2 "docker swarm join --token "
After connecting workers, our swarm is ready for creating secret.
Step2: Create Secret and make it available to Service
For creating a secret on should be on docker leader machine and then run command
echo "mySqlUser" | docker secret create my_sql_uname - echo "mySqlPassword" | docker secret create my_sql_pass - echo "mySqlRootPass" | docker secret create my_sql_root_pass -
Both username and password need to be provided as the secret to service. For the service, we are going to pull an image of MySQL from dockerHub and then run the same as service by providing secrets to it. Its necessary to provide root_password to make the image of MySql run.
docker pull mysql docker service create --name mysqlService --secret my_sql_uname --secret my_sql_pass --secret my_sql_root_pass --network=host -e MYSQL_PASSWORD_FILE=/run/secrets/my_sql_pass -e MYSQL_USER_FILE=/run/secrets/my_sql_uname -e MYSQL_ROOT_PASSWORD=/run/secrets/my_sql_root_pass mysql
In environment variable of MySql user and password provide the path to the secret file which is always created at location /run/secret/.
After doing this the service runs in a container with mounting location of the secret file. Now, lets cross verify all by entering the container using its id.
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3df9f60a81fc mysql:latest "docker-entrypoint..." 16 seconds ago Up 10 seconds mysqlService.1.mh7jcqak7cq5n0h5oq6v1bye7
Now, Enter to the bash shell of the running container and verify whether the mySqlUser created.
docker exec -it bash <container-id> root@3df9f60a81fc:/# mysql -u mySqlUser -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.7.20 MySQL Community Server (GPL) Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
Above, we are able to log in successfully with the password that was provided to the secret.
Step3: Removing Secret and swarm
To remove secret use command ‘docker secret rm’ and for leaving node from swarm use command ‘docker swarm leave ‘ and don’t forget to remove the services before removing secret and swarm.
docker service rm docker secret rm my_sql_root_pass my_sql_pass my_sql_uname docker-machine ssh worker1 "docker swarm leave" docker-machine ssh worker2 "docker swarm leave"
Let’s verify the status of worker node using command ‘docker node ls’.
docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS zdreo1sgjcokykg08wl7t94w2 * knoldus-Lenovo-G50-80 Ready Active Leader sfk0y0fq2se57jf82x1jovcin worker1 Down Active qcn0byi0yfrou4i5icdhg56d7 worker2 Down Active
Now we need to remove the leader node forcefully and then remove the virtual machine too.
docker swarm leave -f docker-machine rm worker1 docker-machine rm worker2
Hope the post was helpful:)