如何在 Docker ADD 命令中添加凭据?
介绍
安全一直是人类面临的一大威胁。在 IT 领域,凭据的安全是一个繁琐的任务。在这里,我们将讨论将凭据添加到 Docker 容器的各种方法。此外,还提到了最有用和安全的方法。
方法
添加凭据可以通过多种不同的方式完成。下面列出了一些类型。每种方法在行业中都有其地位。由于安全问题,一些方法被开发人员拒绝,而另一些方法在凭据安全方面非常有效。
在 Dockerfile 中使用构建参数。
在 Dockerfile 中使用环境变量。
使用 Docker Secrets。
使用构建参数
使用构建参数传递凭据是不推荐的。这可能是一个安全问题。下面通过一个示例说明了构建参数的用例之一。
步骤 1:创建 Dockerfile 和一个 Python 程序文件。
此 Dockerfile 将在 Ubuntu 基础镜像上创建 Python 运行时。
示例
#declare the build arguments that can be used before FROM in the # Dockerfile. ARG UBUNTU_VERSION=latest #use ubuntu as the base image. FROM ubuntu:$UBUNTU_VERSION #declare the build arguments that will be used after FROM command in #Dockerfile. ARG PYTHON_VERSION=2 #install the python on the ubuntu image RUN apt-get update -y && apt-get upgrade -y && apt-get install python$PYTHON_VERSION -y #set the working directory. WORKDIR /python/ #copy the python program to the Docker image. COPY program.py . #run this python program whenever this image is used to create a container. CMD python3 program.py
现在创建一个名为“program.py”的 Python 文件。
输出
print("********************Hello from TUTORIALSPOINT*********************")
步骤 2:构建镜像
示例
$ docker build --build-arg PYTHON_VERSION=3 -t busy_python .
输出
Sending build context to Docker daemon 3.584kB Step 1/7 : ARG UBUNTU_VERSION=latest Step 2/7 : FROM ubuntu:${UBUNTU_VERSION} ---> 6b7dfa7e8fdb Step 3/7 : ARG PYTHON_VERSION=2 ---> Running in be6541523070 Removing intermediate container be6541523070 ---> e3bef06439e8 Step 4/7 : RUN apt-get update -y && apt-get upgrade -y && apt-get install python$PYTHON_VERSION -y ---> Running in e3ff50442993 Step 5/7 : WORKDIR /python/ ---> Running in a147f39ec056 Removing intermediate container a147f39ec056 ---> 166cfe1d9514 Step 6/7 : COPY program.py . ---> b09acbeb8f38 Step 7/7 : CMD python3 program.py ---> Running in eec7ec3982de Removing intermediate container eec7ec3982de ---> 47dbde8eca00 Successfully built 47dbde8eca00 Successfully tagged busy_python:latest
步骤 3:运行镜像
现在我们将运行此镜像,并查看 Python 是否显示“hello”。
示例
$ docker run busy_python
输出
********************Hello from TUTORIALSPOINT*********************
因此构建参数有效。
构建参数的缺点
这存在与安全相关的问题。任何可以访问 Docker 历史记录的人都可以看到参数的值。
$ docker history busy_python:latest IMAGE CREATED CREATED BY SIZE COMMENT 47dbde8eca00 12 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "pyth… 0B b09acbeb8f38 12 minutes ago /bin/sh -c #(nop) COPY file:a268373fa65eae71… 75B 166cfe1d9514 12 minutes ago /bin/sh -c #(nop) WORKDIR /python/0B 1bdd202b9d86 12 minutes ago |1 PYTHON_VERSION=3 /bin/sh -c apt-getupdat… 70.1MB e3bef06439e8 13 minutes ago /bin/sh -c #(nop) ARG PYTHON_VERSION=20B 6b7dfa7e8fdb 11 days ago /bin/sh -c #(nop) CMD ["bash"] 0B <missing> 11 days ago /bin/sh -c #(nop) ADD file:481dd2da6de715252… 77.8MB
因此,这不是一种安全的凭据方法。
使用环境变量
构建参数仅在镜像构建期间可用。环境变量在构建后也对镜像和容器可用。这是构建参数和环境变量之间的主要区别。
这里我们将使用环境变量将凭据传递给 MySQL 数据库。
步骤 1:创建 Dockerfile
#use the mysql as the base image FROM mysql #set the required root password ENV MYSQL_ROOT_PASSWORD mypassword@root
步骤 2:构建镜像
示例
$docker build -t mysql_test .
输出
Sending build context to Docker daemon 2.048kB Step 1/2 : FROM mysql ---> 7484689f290f Step 2/2 : ENV MYSQL_ROOT_PASSWORD mypassword ---> Running in 80d7ad7561d4 Removing intermediate container 80d7ad7561d4 ---> a5168465919b Successfully built a5168465919b Successfully tagged mysql_test:latest
步骤 3:运行镜像,无需传递凭据,因为已在 Dockerfile 中设置。
$docker run -d --name cont mysql_test 943d02de21c555618ae9eb4b416faccf00d989020c565a1336afb4743cb6b7b1
步骤 4:进入 MySQL 容器并使用凭据启动数据库。
示例
$ docker exec -it cont /bin/bash
现在开始访问数据库。
# mysql -h 172.17.0.2 -P 3306 -u root –pmypassword
输出
mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 8.0.31 MySQL Community Server - GPL Copyright (c) 2000, 2022, Oracle and/or its affiliates. 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>
缺点
这里 MySQL 还向我们发出了关于在命令行上使用密码的警告。在命令行上直接使用密码是不安全的。此外,我们不应在 Dockerfile 中使用密码,因为可以使用 Docker 的 inspect 命令查看它。
示例
$ docker inspect -f "{{ .Config.Env }}" cont
输出
[PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin GOSU_VERSION=1.14 MYSQL_MAJOR=8.0 MYSQL_VERSION=8.0.31-1.el8 MYSQL_SHELL_VERSION=8.0.31-1.el8 MYSQL_ROOT_PASSWORD=mypassword]
因此密码是可见的。
使用 Docker Secrets
如果在本地系统上创建了一个镜像并与其他人共享,甚至发布到 Docker Hub 上。Docker Secrets 的主要目标是,创建镜像时使用的凭据不应可供镜像的用户访问。
在此示例中,我们将创建一个服务容器并提供一个秘密文件。然后,提交容器以形成供以后使用的镜像。现在,使用此镜像运行容器,并检查秘密消息是否存在。
步骤 1:创建 Docker Secret
首先,我们需要初始化 Docker Swarm 管理器。
$docker swarm init
如果您的 Docker Swarm 由于 IP 解析而无法启动,请使用 --advertiseaddr=ip_of_the_machine 和 --listen-addr=0.0.0.0
$ docker swarm init --advertise-addr <ip_of_machine> --listen-addr 0.0.0.0
输出
Swarm initialized: current node (eksm5jqv8sn8jlr8fwq31n6ht) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1- 1okpgh4spk3nab0mjjzk3c2nx3a68p3l1ww06bx8fu20nvpr0j90vxfk3dsyqvw3s1edzr5k4ou 192.168.43.97:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
现在,使用以下命令创建 Docker Secret。
示例
$echo 'secret credentials for TUTORIALSPOINT database' | docker secret create ttrlpnt_secret_file -
输出
qmry8v6wsihjuizgtg292ozau
要获取有关 Docker Secret 文件的完整详细信息,请使用以下命令。
示例
$ docker secret ls
输出
ID NAME DRIVER CREATED UPDATED qmry8v6wsihjuizgtg292ozau ttrlpnt_secret_file 2 hours ago 2 hours ago
这意味着我们的 Docker Secret 已准备就绪,可以使用了。
步骤 2:创建服务
我们将创建一个 MySQL 服务,该服务将使用上面创建的 Docker Secret 作为 root 密码。
示例
$ docker service create --name=ttrlpnt_mysql --secret source=ttrlpnt_secret_file,target=ttrlpnt_secret_file -e MYSQL_ROOT_PASSWORD_FILE="/run/secrets/ttrlpnt_secret_file" mysql:latest
输出
image mysql:latest could not be accessed on a registry to record its digest. Each node will access mysql:latest independently, possibly leading to different nodes running different versions of the image. n7651xa5porbsf4l948vwa33c overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged
检查服务是否正在运行。
示例
$ docker ps
输出
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 27fcefc610c8 mysql:latest "docker-entrypoint.s…" 35 seconds ago Up 31 seconds 3306/tcp, 33060/tcp ttrlpnt_mysql.1.bzkxffaovta8mj5q33ap7z1tl
步骤 3:在容器内部执行
现在,我们将进入容器内部并获取其中存储的秘密文件的内容,即 root 密码。
示例
$ docker exec ttrlpnt_mysql.1.bzkxffaovta8mj5q33ap7z1tl bash -c 'cat /run/secrets/ttrlpnt_secret_file'
输出
secret credentials for TUTORIALSPOINT database
因此秘密文件存在。
步骤 4:检查提交的镜像文件是否包含秘密数据
从此容器创建镜像。
示例
$ docker commit ttrlpnt_mysql.1.bzkxffaovta8mj5q33ap7z1tl secret_mysql:v1
输出
sha256:d5fcdc6c3b093485146dfd8e89b2f8be133090bc4ecf3995f4ce409dec30c523
现在检查镜像,并查看我们是否获取了 root 的密码。
示例
$ docker inspect -f "{{ .Config.Env }}" secret_mysql:v1
输出
[MYSQL_ROOT_PASSWORD_FILE=/run/secrets/ttrlpnt_secret_file PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin GOSU_VERSION=1.14 MYSQL_MAJOR=8.0 MYSQL_VERSION=8.0.31-1.el8 MYSQL_SHELL_VERSION=8.0.31-1.el8]
因此,仅提到了路径,凭据是安全的。
结论
在本文中。我们学习了将凭据传递到 Docker 容器的各种方法。还讨论了与之相关的安全问题,并提供了解决方案。使用 Docker Secrets 是提供登录信息的常用且安全的方法之一。