如何在 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 是提供登录信息的常用且安全的方法之一。

更新于:2023年1月5日

5K+ 次浏览

开启您的 职业生涯

通过完成课程获得认证

开始学习
广告