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