如何在Docker ADD命令中添加凭证
简介
安全问题一直是人类的一个巨大威胁。在IT领域,凭证的安全是一项繁琐的工作。在这里,我们将讨论在docker容器中添加证书的各种方法。此外,还提到了最有用和最安全的方法。
方法
添加凭证可以通过很多不同的方式进行。下面提到了其中的一些类型。每种方法在行业中都有其地位。有些只是由于安全问题而被开发者拒绝,有些则在凭证安全方面效果很好。
- 在Dockerfile中使用构建参数。
-
在Dockerfile中使用环境变量。
-
使用Docker的秘密。
使用构建参数
使用构建参数来传递凭证是不可取的。这可能是一个安全问题。下文提到了构建参数的一个使用情况,并附有一个例子。
第1步:创建一个Docker文件和一个python程序文件
这个Docker文件将在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 pythonPYTHON_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
pythonPYTHON_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是否说你好。
示例
$ 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步:创建一个Docker文件
#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步:运行镜像,无需传递证书,因为在Docker文件中已经设置了证书
$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也给了我们一个关于在命令行上使用密码的警告。直接在命令行上使用密码是不安全的。另外,我们不应该在Docker文件中使用密码,因为在Docker中使用expect命令可以看到。
示例
$ 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的秘密
如果在你的本地系统上创建了一个镜像,并与其他人共享,甚至在Docker Hub上发布。Docker Secrets的主要目的是,创建镜像时使用的凭证不应该被镜像的用户访问。
在这个例子中,我们将创建一个服务容器并提供一个秘密文件。然后,提交该容器以形成一个镜像,供以后使用。现在,使用这个镜像运行一个容器,检查秘密信息是否存在。
第1步:创建一个Docker秘密
首先,我们需要初始化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秘密文件的完整细节,请使用以下命令。
示例
$ docker secret ls
输出
ID NAME DRIVER CREATED UPDATED qmry8v6wsihjuizgtg292ozau ttrlpnt_secret_file 2 hours ago 2 hours ago
这意味着我们的Docker Secret已经可以使用了。
第2步:创建一个服务
我们将创建一个mysql服务,它将把上面创建的Docker Secret作为根密码。
示例
$ 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步:在容器内执行
现在,我们将进入容器内部,获得存储在其中的秘密文件的内容,即根密码。
示例
$ 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是最有用和最安全的方法之一,可以给你的登录。