docker-swarm之使用Docker secret管理敏感數(shù)據(jù)
關(guān)于secret
就Docker Swarm集群服務(wù)而言,secret 是塊狀數(shù)據(jù),例如密碼、SSH私鑰、SSL證書或其他不應通過網(wǎng)絡(luò)傳輸或未加密存儲在Dockerfile或應用程序源代碼中的數(shù)據(jù)。我們可以使用Docker secret 集中管理這些數(shù)據(jù),并僅將其安全地傳輸?shù)叫枰L問它的容器。在傳輸過程中被加密,并在Docker集群中保存。只有那些已獲準明確訪問它的服務(wù)才能訪問給定 secret ,并且只有在這些服務(wù)任務(wù)正在運行時才能訪問。
您可以使用secret 來管理容器在運行時需要的任何敏感數(shù)據(jù)。比如一下情況:
- 用戶名和密碼
- TLS證書和密鑰
- SSH密鑰
- 其他重要數(shù)據(jù),如數(shù)據(jù)庫或內(nèi)部服務(wù)器的名稱
- 通用字符串或二進制內(nèi)容(大小高達500kb)
注意:Docker secret 僅適用于集群服務(wù),不適用于獨立的容器。要使用此功能,請考慮調(diào)整您的容器作為服務(wù)運行。有狀態(tài)容器通??梢栽诓桓娜萜鞔a的情況下以1的比例運行。
使用secret 的另一個用例是在容器和一組憑據(jù)之間提供一層抽象。考慮一個場景,即您的應用程序有單獨的開發(fā)、測試和生產(chǎn)環(huán)境。這些環(huán)境中的每一個都可以有不同的憑據(jù),存儲在具有相同secret 名稱的開發(fā)、測試和生產(chǎn)群中。您的容器只需要知道secret 的名稱,即可在所有三個環(huán)境中運行。
您還可以使用secret 來管理非敏感數(shù)據(jù),例如配置文件。然而,Docker支持使用配置來存儲非敏感數(shù)據(jù)。配置直接掛載到容器的文件系統(tǒng)中,而無需使用RAM磁盤。
對 Windows 支持
Docker 包括對Windows容器上secret 的支持。如果實現(xiàn)方面存在差異。有以下幾方面的差異,在下面的示例中說明:
- Microsoft Windows沒有用于管理RAM磁盤的內(nèi)置驅(qū)動程序,因此在運行的Windows容器中,secret 會以清晰的文本持續(xù)到容器的根磁盤。然而,當容器停止時,secret 會被明確刪除。此外,Windows不支持使用
docker commit
或類似命令將運行容器作為映像持久化。 - 在Windows上,我們建議在主機上包含Docker根目錄的卷上啟用
BitLocker
①,以確保運行容器的 secret 在靜態(tài)時被加密。 - 具有自定義目標的secret 文件不會直接綁定掛載到
Windows
容器中,因為Windows
不支持非目錄文件綁定掛載。相反,容器的secret
都安裝在容器內(nèi)的C:\ProgramData\Docker\internal\secrets
(應用程序不應依賴的實現(xiàn)細節(jié))。符號鏈接用于從那里指向容器內(nèi)secret
的所需目標。默認目標是C:\ProgramData\Docker\secrets
。 - 在創(chuàng)建使用Windows容器的服務(wù)時,secret 不支持指定UID、GID和模式的選項。目前只有管理員和在容器內(nèi)具有
system
訪問權(quán)限的用戶才能訪問secret 。
Docker如何管理secret
當您向集群中添加secret 時,Docker會通過相互的TLS
連接將secret
發(fā)送給群管理器。secret
存儲在Raft
日志中,該日志是加密的。整個 Raft
日志在其他管理節(jié)點之間復制,確保了與其他蜂群管理數(shù)據(jù)相同的高可用性保證。
當您授予新創(chuàng)建或正在運行的服務(wù)對密鑰的訪問權(quán)限時,解密的密鑰將安裝在內(nèi)存文件系統(tǒng)中的容器中。容器中掛載點的位置默認為Linux
容器中的/run/secrets/<secret_name>
,或 Windows
容器中的C:\ProgramData\Docker\secrets
。您還可以指定自定義位置。
您可以隨時更新服務(wù),以授予其訪問其他 secret
或撤銷其對給定secret
的訪問。
只有當節(jié)點是集群管理器或正在運行已獲準訪問secret
的服務(wù)任務(wù)時,節(jié)點才能訪問(加密)secret 。當容器任務(wù)停止運行時,共享到它的解密機密將從該容器的內(nèi)存文件系統(tǒng)中卸載,并從節(jié)點的內(nèi)存中刷新。
如果節(jié)點在運行具有 secret
訪問權(quán)限的任務(wù)容器時失去與群的連接,則任務(wù)容器仍然可以訪問其 secret
,但在節(jié)點重新連接到群之前無法接收更新。
您可以隨時添加或檢查單個 secret
,或列出所有 secret
。您無法刪除正在運行的服務(wù)正在使用的 secret
。
要更輕松地更新或回滾 secret
,請考慮在secret
名稱中添加版本號或日期。控制給定容器中secret
的安裝點的能力使這變得更容易。
docker secret 命令
docker secret create
創(chuàng)建一個secret
docker secret inspect
查看一個secret
的詳細信息docker secret ls
查看有多少個secret
docker secret rm
刪除secret
- [
--secret
] 在創(chuàng)建服務(wù)的時候 docker service create 指定使用的 secret - --secret-add
和
--secret-rm 在更新服務(wù) secret 時候docker service update
示例
我們使用以下示例漸進的說明如何使用Docker secret 。這些示例中使用的鏡像已更新,以便于使用Docker secret 。
注意:為了簡單起見,這些示例使用單引擎集群和未縮放服務(wù)。這些示例使用Linux容器,但Windows容器也支持secret 。
在編寫文件中定義和使用secret
docker-compose
和docker stack
命令都支持在編寫文件中定義 secret
。
示例一:開始使用secret
這個簡單的示例展示了secret
如何在幾個命令中發(fā)揮作用。
為Docker添加一個
secret
。docker secret create
命令讀取標準輸入,因為表示要讀取secret 的文件的最后一個參數(shù)被設(shè)置為-
。
echo "This is a secret" | docker secret create my_secret_data -
root@master:~# echo "this is a demo secret" | docker secret create my-secret - yy7gnh0ji9wm64fs841yej5kv root@master:~# docker secret ls ID NAME DRIVER CREATED UPDATED yy7gnh0ji9wm64fs841yej5kv my-secret 5 seconds ago 5 seconds ago root@master:~#
- 創(chuàng)建一個
redis
服務(wù),并授予它對secret
的訪問權(quán)限。默認情況下,容器可以在/run/secrets/<secret_name>
訪問密鑰,但您可以使用target
選項自定義容器上的文件名。
docker service create --name redis --secret my_secret_data redis:alpine
如果出現(xiàn)錯誤,并且任務(wù)失敗并反復重新啟動,您將看到以下內(nèi)容:
docker service ps redis
使用docker ps
獲取redis
服務(wù)任務(wù)容器的ID,以便您可以使用docker container exec
連接到容器并讀取secret 數(shù)據(jù)文件的內(nèi)容,該文件默認為可被所有人讀取,并且與secret
的名稱相同。
使用一下命令獲取 redis 容器服務(wù)的 ID
docker ps --filter name=redis -q
查看容器中 secret 的內(nèi)容:
docker container exec $(docker ps --filter name=redis -q) ls -l /run/secrets docker container exec $(docker ps --filter name=redis -q) cat /run/secrets/my_secret_data
root@master:~# docker exec $(docker ps --filter name=redis -q) ls -l /run/secrets total 4 -r--r--r-- 1 root root 22 Aug 5 08:09 my-secret root@master:~# docker exec $(docker ps --filter name=redis -q) cat /run/secrets cat: read error: Is a directory root@master:~# docker exec $(docker ps --filter name=redis -q) cat /run/secrets/my-secret this is a demo secret root@master:~#
可以看到 secret 的內(nèi)容已經(jīng)掛載到了我們的容器中。
如果您提交容器,請驗證密鑰不可用。
$ docker commit $(docker ps --filter name=redis -q) committed_redis $ docker run --rm -it committed_redis cat /run/secrets/my_secret_data cat: can't open '/run/secrets/my_secret_data': No such file or directory
- 我們刪除
secret
發(fā)現(xiàn)刪除失敗,因為redis
服務(wù)正在運行并可以訪問該secret 。
docker secret ls docker secret rm my_secret_data
- 通過更新服務(wù),從正在運行的
redis
服務(wù)中刪除對密鑰的訪問。
docker service update --secret-rm my_secret redis
- 再次重復步驟3和4,驗證服務(wù)不再訪問密鑰。容器ID不同,因為
service update
命令會重新部署服務(wù)。
$ docker container exec -it $(docker ps --filter name=redis -q) cat /run/secrets/my_secret_data cat: can't open '/run/secrets/my_secret_data': No such file or directory
- 停止并刪除服務(wù),并從Docker中刪除密鑰。
docker service rm redis docker secret rm my_secret
示例二:在Nginx服務(wù)中使用 secret
這個例子分為兩部分。第一部分是關(guān)于生成站點證書,不直接涉及 Docker secret ,但它設(shè)置了我們可以在其中存儲和使用站點證書和Nginx
配置作為 secret
。
生成站點證書
為您的站點生成根CA和TLS證書和密鑰。對于生產(chǎn)站點,您可能希望使用Let’s Encrypt
等服務(wù)來生成TLS證書和密鑰,但此示例使用命令行工具。這個步驟有點復雜,但只是一個設(shè)置步驟,這樣您就有一些東西可以存儲為Dockersecret 。如果您想跳過這些子步驟,您可以使用Let's Encrypt
② 生成站點密鑰和證書,為文件命名site.key
和site.crt
。
- 生成根密鑰。
openssl genrsa -out "root-ca.key" 4096
- 使用根密鑰生成CSR。
openssl req \ -new -key "root-ca.key" \ -out "root-ca.csr" -sha256 \ -subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA'
- 配置根CA。編輯一個名為
root-ca.cnf
的新文件,并將以下內(nèi)容粘貼到其中。這限制了根CA簽署葉證書,而不是中間CA。
[root_ca] basicConstraints = critical,CA:TRUE,pathlen:1 keyUsage = critical, nonRepudiation, cRLSign, keyCertSign subjectKeyIdentifier=hash
- 在證書上簽名。
openssl x509 -req -days 3650 -in "root-ca.csr" \ -signkey "root-ca.key" -sha256 -out "root-ca.crt" \ -extfile "root-ca.cnf" -extensions \ root_ca
- 生成站點密鑰。
openssl genrsa -out "site.key" 4096
- 生成站點證書,并使用站點密鑰進行簽名。
openssl req -new -key "site.key" -out "site.csr" -sha256 \ -subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost'
- 配置站點證書。編輯一個名為
site.cnf
的新文件,并將以下內(nèi)容粘貼到其中。這限制了站點證書,使其只能用于驗證服務(wù)器,不能用于簽署證書。
[server] authorityKeyIdentifier=keyid,issuer basicConstraints = critical,CA:FALSE extendedKeyUsage=serverAuth keyUsage = critical, digitalSignature, keyEncipherment subjectAltName = DNS:localhost, IP:127.0.0.1 subjectKeyIdentifier=hash
- 簽署網(wǎng)站證書。
openssl x509 -req -days 750 -in "site.csr" -sha256 \ -CA "root-ca.crt" -CAkey "root-ca.key" -CAcreateserial \ -out "site.crt" -extfile "site.cnf" -extensions server
Nginx服務(wù)不需要
site.csr
和site.cnf
文件,但如果您想生成新的站點證書,則需要它們。保護root-ca.key
文件。
配置Nginx容器
生成一個非常基本的Nginx配置,通過HTTPS為靜態(tài)文件提供服務(wù)。TLS證書和密鑰存儲為Docker機密,以便輕松旋轉(zhuǎn)。
在當前目錄中,創(chuàng)建一個名為
site.conf
的新文件,其中包含以下內(nèi)容:
server { listen 443 ssl; server_name localhost; ssl_certificate /run/secrets/site.crt; ssl_certificate_key /run/secrets/site.key; location / { root /usr/share/nginx/html; index index.html index.htm; } }
- 創(chuàng)建三個secret ,代表密鑰、證書和
site.conf
。只要小于500 KB,您就可以將任何文件存儲為secret 。這允許您將密鑰、證書和配置與使用它們的服務(wù)解耦。在每個命令中,最后一個參數(shù)表示從主機文件系統(tǒng)上讀取secret 的文件路徑。在這些示例中,secret 名稱和文件名是相同的。
docker secret create site.key site.key docker secret create site.crt site.crt docker secret create site.conf site.conf
docker secret ls
創(chuàng)建一個運行Nginx并可以訪問三個secret 的服務(wù)。docker service create
命令的最后一部分從site.conf
secret 的位置創(chuàng)建一個符號鏈接到/etc/nginx.conf.d/
,Nginx在其中查找額外的配置文件。此步驟發(fā)生在Nginx實際啟動之前,因此如果您更改Nginx配置,則無需重建映像。
注意:通常情況下,您將創(chuàng)建一個Dockerfile,將site.conf復制到位,構(gòu)建映像,并使用自定義映像運行容器。此示例不需要自定義圖像。它將site.conf放置到位,并在一個步驟中運行容器。
默認情況下,secret 位于容器中的/run/secrets/
目錄中,這可能需要在容器中采取額外的步驟才能使secret在不同的路徑中可用。下面的示例創(chuàng)建了一個指向site.conf
文件真實位置的符號鏈接,從而 Nginx
可以讀取它:
docker service create \ --name nginx \ --secret site.key \ --secret site.crt \ --secret site.conf \ --publish published=3000,target=443 \ nginx:latest \ sh -c "ln -s /run/secrets/site.conf /etc/nginx/conf.d/site.conf && exec nginx -g 'daemon off;'"
secret 允許您使用target
選項指定自定義位置,而不是創(chuàng)建符號鏈接。下面的示例說明了如何在不使用符號鏈接的情況下在容器內(nèi)的/etc/nginx/conf.d/site.conf
上提供thesitesite.conf
secret :
docker service create \ --name nginx \ --secret site.key \ --secret site.crt \ --secret source=site.conf,target=/etc/nginx/conf.d/site.conf \ --publish published=3000,target=443 \ nginx:latest \ sh -c "exec nginx -g 'daemon off;'"
site.key
和site.crt
secret 使用速記語法,沒有自定義target
位置設(shè)置。簡短的語法將secret 掛載在`/run/secrets/中,與secret 同名。在正在運行的容器中,現(xiàn)在存在以下三個文件:
/run/secrets/site.key
/run/secrets/site.crt
/etc/nginx/conf.d/site.conf
- 驗證Nginx服務(wù)是否正在運行。
docker service ls docker service ps nginx
- 驗證服務(wù)是否可運行:您可以訪問Nginx服務(wù)器,并且正在使用正確的TLS證書。
curl --cacert root-ca.crt https://localhost:3000 <title>Welcome to nginx!<</title> <h1>Welcome to nginx!</h1> If you see this page, the nginx web server is successfully installed and For online documentation and support. refer to <a>nginx.org</a>.<br/> <p><a>nginx.com</a></p> <p><em>Thank you for using nginx.</em></p>
openssl s_client -connect localhost:3000 -CAfile root-ca.crt
- 我們刪除不需要的服務(wù)和secret
docker service rm nginx docker secret rm site.crt site.key site.conf
在鏡像中構(gòu)建對Docker Secrets的支持
如果您開發(fā)了一個可以作為服務(wù)部署的容器,并且需要敏感數(shù)據(jù)(如憑據(jù))作為環(huán)境變量,請考慮調(diào)整您的映像以利用Docker secret 。一種方法是確保您在創(chuàng)建容器時傳遞給圖像的每個參數(shù)也可以從文件中讀取。
Docker hub 中的許多Docker官方圖像,都以這種方式進行了更新。
當您啟動WordPress容器時,您可以通過將其設(shè)置為環(huán)境變量來為其提供所需的參數(shù)。WordPress圖像已更新,因此包含WordPress重要數(shù)據(jù)的環(huán)境變量(如WORDPRESS_DB_PASSWORD
)也具有可以從文件(WORDPRESS_DB_PASSWORD_FILE
)中讀取其值的變體。此策略可確保保持向后兼容性,同時允許您的容器從Docker管理的secret 中讀取信息,而不是直接傳遞。
NOTE
Docker機密不會直接設(shè)置環(huán)境變量。這是一個有意識的決定,因為環(huán)境變量可能會無意中在容器之間泄露(例如,如果您使用
--link
)。
在docker-compose中使用secret
services: db: image: mysql:latest volumes: - db_data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD_FILE: /run/secrets/db_password secrets: - db_root_password - db_password wordpress: depends_on: - db image: wordpress:latest ports: - "8000:80" environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD_FILE: /run/secrets/db_password secrets: - db_password secrets: db_password: file: db_password.txt db_root_password: file: db_root_password.txt volumes: db_data:
此示例使用編寫文件中的兩個secret 創(chuàng)建一個簡單的WordPress網(wǎng)站。
關(guān)鍵字secrets:
定義兩個secret db_password:
和db_root_password:
。
部署時,Docker會創(chuàng)建這兩個secret ,并用編寫文件中指定的文件中的內(nèi)容填充它們。
db服務(wù)同時使用兩個secret ,而wordpress正在使用一個secret 。
當您部署時,Docker會在服務(wù)的/run/secrets/<secret_name>
下掛載一個文件。這些文件永遠不會在磁盤上持久化,而是在內(nèi)存中管理。
每個服務(wù)都使用環(huán)境變量來指定服務(wù)應該在哪里查找該secret 數(shù)據(jù)。
以上就是docker-swarm之使用Docker secret管理敏感數(shù)據(jù)的詳細內(nèi)容,更多關(guān)于Docker secret管理數(shù)據(jù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
docker?run?-d和docker?run?-it的區(qū)別詳解
記得第一次接觸docker的時候,教程中寫著docker?run?-it之類的命令,當時對這個-it選項是一知半解,下面這篇文章主要給大家介紹了關(guān)于docker?run?-d和docker?run?-it的區(qū)別的相關(guān)資料,需要的朋友可以參考下2023-05-05詳解Docker中安裝配置Oracle數(shù)據(jù)庫
本篇文章主要介紹了詳解Docker中安裝配置Oracle數(shù)據(jù)庫,具有一定的參考價值,有興趣的可以了解一下。2017-04-04解決Docker報錯:“docker build“ requires exactly&nb
這篇文章主要介紹了解決Docker報錯:“docker build“ requires exactly 1 argument.具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12優(yōu)化Docker鏡像安全性的12個技巧總結(jié)
docker是虛擬化容器技術(shù),有三個主要概念,鏡像(類)、容器(對象)、倉庫,docker就是類似VM虛擬機一樣的虛擬技術(shù),體積小,運行速度快,下面這篇文章主要給大家介紹了關(guān)于優(yōu)化Docker鏡像安全性的12個技巧,需要的朋友可以參考下2022-03-03Docker Base Image自己創(chuàng)建具體實現(xiàn)
這篇文章主要介紹了Docker Base Image創(chuàng)建具體實現(xiàn)的相關(guān)資料,這里提供了詳細的具體步驟,需要的朋友可以參考下2016-11-11利用Docker分層構(gòu)建優(yōu)化鏡像大小的實現(xiàn)
合適docker鏡像文件大小不僅影響容器啟動效率,也影響資源占用效率,本文介紹如何利用分層方式構(gòu)建docker鏡像,采用多種方式避免鏡像文件太大而影響性能,需要的朋友可以參考下2025-01-01