docker-swarm之使用Docker secret管理敏感數(shù)據(jù)
關(guān)于secret
就Docker Swarm集群服務(wù)而言,secret 是塊狀數(shù)據(jù),例如密碼、SSH私鑰、SSL證書或其他不應(yīng)通過網(wǎng)絡(luò)傳輸或未加密存儲(chǔ)在Dockerfile或應(yīng)用程序源代碼中的數(shù)據(jù)。我們可以使用Docker secret 集中管理這些數(shù)據(jù),并僅將其安全地傳輸?shù)叫枰L問它的容器。在傳輸過程中被加密,并在Docker集群中保存。只有那些已獲準(zhǔn)明確訪問它的服務(wù)才能訪問給定 secret ,并且只有在這些服務(wù)任務(wù)正在運(yùn)行時(shí)才能訪問。
您可以使用secret 來(lái)管理容器在運(yùn)行時(shí)需要的任何敏感數(shù)據(jù)。比如一下情況:
- 用戶名和密碼
- TLS證書和密鑰
- SSH密鑰
- 其他重要數(shù)據(jù),如數(shù)據(jù)庫(kù)或內(nèi)部服務(wù)器的名稱
- 通用字符串或二進(jìn)制內(nèi)容(大小高達(dá)500kb)
注意:Docker secret 僅適用于集群服務(wù),不適用于獨(dú)立的容器。要使用此功能,請(qǐng)考慮調(diào)整您的容器作為服務(wù)運(yùn)行。有狀態(tài)容器通常可以在不更改容器代碼的情況下以1的比例運(yùn)行。
使用secret 的另一個(gè)用例是在容器和一組憑據(jù)之間提供一層抽象??紤]一個(gè)場(chǎng)景,即您的應(yīng)用程序有單獨(dú)的開發(fā)、測(cè)試和生產(chǎn)環(huán)境。這些環(huán)境中的每一個(gè)都可以有不同的憑據(jù),存儲(chǔ)在具有相同secret 名稱的開發(fā)、測(cè)試和生產(chǎn)群中。您的容器只需要知道secret 的名稱,即可在所有三個(gè)環(huán)境中運(yùn)行。
您還可以使用secret 來(lái)管理非敏感數(shù)據(jù),例如配置文件。然而,Docker支持使用配置來(lái)存儲(chǔ)非敏感數(shù)據(jù)。配置直接掛載到容器的文件系統(tǒng)中,而無(wú)需使用RAM磁盤。
對(duì) Windows 支持
Docker 包括對(duì)Windows容器上secret 的支持。如果實(shí)現(xiàn)方面存在差異。有以下幾方面的差異,在下面的示例中說明:
- Microsoft Windows沒有用于管理RAM磁盤的內(nèi)置驅(qū)動(dòng)程序,因此在運(yùn)行的Windows容器中,secret 會(huì)以清晰的文本持續(xù)到容器的根磁盤。然而,當(dāng)容器停止時(shí),secret 會(huì)被明確刪除。此外,Windows不支持使用
docker commit
或類似命令將運(yùn)行容器作為映像持久化。 - 在Windows上,我們建議在主機(jī)上包含Docker根目錄的卷上啟用
BitLocker
①,以確保運(yùn)行容器的 secret 在靜態(tài)時(shí)被加密。 - 具有自定義目標(biāo)的secret 文件不會(huì)直接綁定掛載到
Windows
容器中,因?yàn)?Windows
不支持非目錄文件綁定掛載。相反,容器的secret
都安裝在容器內(nèi)的C:\ProgramData\Docker\internal\secrets
(應(yīng)用程序不應(yīng)依賴的實(shí)現(xiàn)細(xì)節(jié))。符號(hào)鏈接用于從那里指向容器內(nèi)secret
的所需目標(biāo)。默認(rèn)目標(biāo)是C:\ProgramData\Docker\secrets
。 - 在創(chuàng)建使用Windows容器的服務(wù)時(shí),secret 不支持指定UID、GID和模式的選項(xiàng)。目前只有管理員和在容器內(nèi)具有
system
訪問權(quán)限的用戶才能訪問secret 。
Docker如何管理secret
當(dāng)您向集群中添加secret 時(shí),Docker會(huì)通過相互的TLS
連接將secret
發(fā)送給群管理器。secret
存儲(chǔ)在Raft
日志中,該日志是加密的。整個(gè) Raft
日志在其他管理節(jié)點(diǎn)之間復(fù)制,確保了與其他蜂群管理數(shù)據(jù)相同的高可用性保證。
當(dāng)您授予新創(chuàng)建或正在運(yùn)行的服務(wù)對(duì)密鑰的訪問權(quán)限時(shí),解密的密鑰將安裝在內(nèi)存文件系統(tǒng)中的容器中。容器中掛載點(diǎn)的位置默認(rèn)為Linux
容器中的/run/secrets/<secret_name>
,或 Windows
容器中的C:\ProgramData\Docker\secrets
。您還可以指定自定義位置。
您可以隨時(shí)更新服務(wù),以授予其訪問其他 secret
或撤銷其對(duì)給定secret
的訪問。
只有當(dāng)節(jié)點(diǎn)是集群管理器或正在運(yùn)行已獲準(zhǔn)訪問secret
的服務(wù)任務(wù)時(shí),節(jié)點(diǎn)才能訪問(加密)secret 。當(dāng)容器任務(wù)停止運(yùn)行時(shí),共享到它的解密機(jī)密將從該容器的內(nèi)存文件系統(tǒng)中卸載,并從節(jié)點(diǎn)的內(nèi)存中刷新。
如果節(jié)點(diǎn)在運(yùn)行具有 secret
訪問權(quán)限的任務(wù)容器時(shí)失去與群的連接,則任務(wù)容器仍然可以訪問其 secret
,但在節(jié)點(diǎn)重新連接到群之前無(wú)法接收更新。
您可以隨時(shí)添加或檢查單個(gè) secret
,或列出所有 secret
。您無(wú)法刪除正在運(yùn)行的服務(wù)正在使用的 secret
。
要更輕松地更新或回滾 secret
,請(qǐng)考慮在secret
名稱中添加版本號(hào)或日期。控制給定容器中secret
的安裝點(diǎn)的能力使這變得更容易。
docker secret 命令
docker secret create
創(chuàng)建一個(gè)secret
docker secret inspect
查看一個(gè)secret
的詳細(xì)信息docker secret ls
查看有多少個(gè)secret
docker secret rm
刪除secret
- [
--secret
] 在創(chuàng)建服務(wù)的時(shí)候 docker service create 指定使用的 secret - --secret-add
和
--secret-rm 在更新服務(wù) secret 時(shí)候docker service update
示例
我們使用以下示例漸進(jìn)的說明如何使用Docker secret 。這些示例中使用的鏡像已更新,以便于使用Docker secret 。
注意:為了簡(jiǎn)單起見,這些示例使用單引擎集群和未縮放服務(wù)。這些示例使用Linux容器,但Windows容器也支持secret 。
在編寫文件中定義和使用secret
docker-compose
和docker stack
命令都支持在編寫文件中定義 secret
。
示例一:開始使用secret
這個(gè)簡(jiǎn)單的示例展示了secret
如何在幾個(gè)命令中發(fā)揮作用。
為Docker添加一個(gè)
secret
。docker secret create
命令讀取標(biāo)準(zhǔn)輸入,因?yàn)楸硎疽x取secret 的文件的最后一個(gè)參數(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)建一個(gè)
redis
服務(wù),并授予它對(duì)secret
的訪問權(quán)限。默認(rèn)情況下,容器可以在/run/secrets/<secret_name>
訪問密鑰,但您可以使用target
選項(xiàng)自定義容器上的文件名。
docker service create --name redis --secret my_secret_data redis:alpine
如果出現(xiàn)錯(cuò)誤,并且任務(wù)失敗并反復(fù)重新啟動(dòng),您將看到以下內(nèi)容:
docker service ps redis
使用docker ps
獲取redis
服務(wù)任務(wù)容器的ID,以便您可以使用docker container exec
連接到容器并讀取secret 數(shù)據(jù)文件的內(nèi)容,該文件默認(rèn)為可被所有人讀取,并且與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)掛載到了我們的容器中。
如果您提交容器,請(qǐng)驗(yàn)證密鑰不可用。
$ 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)刪除失敗,因?yàn)?code>redis服務(wù)正在運(yùn)行并可以訪問該secret 。
docker secret ls docker secret rm my_secret_data
- 通過更新服務(wù),從正在運(yùn)行的
redis
服務(wù)中刪除對(duì)密鑰的訪問。
docker service update --secret-rm my_secret redis
- 再次重復(fù)步驟3和4,驗(yàn)證服務(wù)不再訪問密鑰。容器ID不同,因?yàn)?code>service update命令會(huì)重新部署服務(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
這個(gè)例子分為兩部分。第一部分是關(guān)于生成站點(diǎn)證書,不直接涉及 Docker secret ,但它設(shè)置了我們可以在其中存儲(chǔ)和使用站點(diǎn)證書和Nginx
配置作為 secret
。
生成站點(diǎn)證書
為您的站點(diǎn)生成根CA和TLS證書和密鑰。對(duì)于生產(chǎn)站點(diǎn),您可能希望使用Let’s Encrypt
等服務(wù)來(lái)生成TLS證書和密鑰,但此示例使用命令行工具。這個(gè)步驟有點(diǎn)復(fù)雜,但只是一個(gè)設(shè)置步驟,這樣您就有一些東西可以存儲(chǔ)為Dockersecret 。如果您想跳過這些子步驟,您可以使用Let's Encrypt
② 生成站點(diǎn)密鑰和證書,為文件命名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。編輯一個(gè)名為
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
- 生成站點(diǎn)密鑰。
openssl genrsa -out "site.key" 4096
- 生成站點(diǎn)證書,并使用站點(diǎn)密鑰進(jìn)行簽名。
openssl req -new -key "site.key" -out "site.csr" -sha256 \ -subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost'
- 配置站點(diǎn)證書。編輯一個(gè)名為
site.cnf
的新文件,并將以下內(nèi)容粘貼到其中。這限制了站點(diǎn)證書,使其只能用于驗(yàn)證服務(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
文件,但如果您想生成新的站點(diǎn)證書,則需要它們。保護(hù)root-ca.key
文件。
配置Nginx容器
生成一個(gè)非?;镜腘ginx配置,通過HTTPS為靜態(tài)文件提供服務(wù)。TLS證書和密鑰存儲(chǔ)為Docker機(jī)密,以便輕松旋轉(zhuǎn)。
在當(dāng)前目錄中,創(chuàng)建一個(gè)名為
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)建三個(gè)secret ,代表密鑰、證書和
site.conf
。只要小于500 KB,您就可以將任何文件存儲(chǔ)為secret 。這允許您將密鑰、證書和配置與使用它們的服務(wù)解耦。在每個(gè)命令中,最后一個(gè)參數(shù)表示從主機(jī)文件系統(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)建一個(gè)運(yùn)行Nginx并可以訪問三個(gè)secret 的服務(wù)。docker service create
命令的最后一部分從site.conf
secret 的位置創(chuàng)建一個(gè)符號(hào)鏈接到/etc/nginx.conf.d/
,Nginx在其中查找額外的配置文件。此步驟發(fā)生在Nginx實(shí)際啟動(dòng)之前,因此如果您更改Nginx配置,則無(wú)需重建映像。
注意:通常情況下,您將創(chuàng)建一個(gè)Dockerfile,將site.conf復(fù)制到位,構(gòu)建映像,并使用自定義映像運(yùn)行容器。此示例不需要自定義圖像。它將site.conf放置到位,并在一個(gè)步驟中運(yùn)行容器。
默認(rèn)情況下,secret 位于容器中的/run/secrets/
目錄中,這可能需要在容器中采取額外的步驟才能使secret在不同的路徑中可用。下面的示例創(chuàng)建了一個(gè)指向site.conf
文件真實(shí)位置的符號(hào)鏈接,從而 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
選項(xiàng)指定自定義位置,而不是創(chuàng)建符號(hào)鏈接。下面的示例說明了如何在不使用符號(hào)鏈接的情況下在容器內(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 使用速記語(yǔ)法,沒有自定義target
位置設(shè)置。簡(jiǎn)短的語(yǔ)法將secret 掛載在`/run/secrets/中,與secret 同名。在正在運(yùn)行的容器中,現(xiàn)在存在以下三個(gè)文件:
/run/secrets/site.key
/run/secrets/site.crt
/etc/nginx/conf.d/site.conf
- 驗(yàn)證Nginx服務(wù)是否正在運(yùn)行。
docker service ls docker service ps nginx
- 驗(yàn)證服務(wù)是否可運(yùn)行:您可以訪問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)建對(duì)Docker Secrets的支持
如果您開發(fā)了一個(gè)可以作為服務(wù)部署的容器,并且需要敏感數(shù)據(jù)(如憑據(jù))作為環(huán)境變量,請(qǐng)考慮調(diào)整您的映像以利用Docker secret 。一種方法是確保您在創(chuàng)建容器時(shí)傳遞給圖像的每個(gè)參數(shù)也可以從文件中讀取。
Docker hub 中的許多Docker官方圖像,都以這種方式進(jìn)行了更新。
當(dāng)您啟動(dòng)WordPress容器時(shí),您可以通過將其設(shè)置為環(huán)境變量來(lái)為其提供所需的參數(shù)。WordPress圖像已更新,因此包含WordPress重要數(shù)據(jù)的環(huán)境變量(如WORDPRESS_DB_PASSWORD
)也具有可以從文件(WORDPRESS_DB_PASSWORD_FILE
)中讀取其值的變體。此策略可確保保持向后兼容性,同時(shí)允許您的容器從Docker管理的secret 中讀取信息,而不是直接傳遞。
NOTE
Docker機(jī)密不會(huì)直接設(shè)置環(huán)境變量。這是一個(gè)有意識(shí)的決定,因?yàn)榄h(huán)境變量可能會(huì)無(wú)意中在容器之間泄露(例如,如果您使用
--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:
此示例使用編寫文件中的兩個(gè)secret 創(chuàng)建一個(gè)簡(jiǎn)單的WordPress網(wǎng)站。
關(guān)鍵字secrets:
定義兩個(gè)secret db_password:
和db_root_password:
。
部署時(shí),Docker會(huì)創(chuàng)建這兩個(gè)secret ,并用編寫文件中指定的文件中的內(nèi)容填充它們。
db服務(wù)同時(shí)使用兩個(gè)secret ,而wordpress正在使用一個(gè)secret 。
當(dāng)您部署時(shí),Docker會(huì)在服務(wù)的/run/secrets/<secret_name>
下掛載一個(gè)文件。這些文件永遠(yuǎn)不會(huì)在磁盤上持久化,而是在內(nèi)存中管理。
每個(gè)服務(wù)都使用環(huán)境變量來(lái)指定服務(wù)應(yīng)該在哪里查找該secret 數(shù)據(jù)。
以上就是docker-swarm之使用Docker secret管理敏感數(shù)據(jù)的詳細(xì)內(nèi)容,更多關(guān)于Docker secret管理數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
docker?run?-d和docker?run?-it的區(qū)別詳解
記得第一次接觸docker的時(shí)候,教程中寫著docker?run?-it之類的命令,當(dāng)時(shí)對(duì)這個(gè)-it選項(xiàng)是一知半解,下面這篇文章主要給大家介紹了關(guān)于docker?run?-d和docker?run?-it的區(qū)別的相關(guān)資料,需要的朋友可以參考下2023-05-05詳解Docker中安裝配置Oracle數(shù)據(jù)庫(kù)
本篇文章主要介紹了詳解Docker中安裝配置Oracle數(shù)據(jù)庫(kù),具有一定的參考價(jià)值,有興趣的可以了解一下。2017-04-04Docker集成CI/CD的項(xiàng)目實(shí)踐
本文主要介紹了Docker集成CI/CD的項(xiàng)目實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01解決Docker報(bào)錯(cuò):“docker build“ requires exactly&nb
這篇文章主要介紹了解決Docker報(bào)錯(cuò):“docker build“ requires exactly 1 argument.具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12優(yōu)化Docker鏡像安全性的12個(gè)技巧總結(jié)
docker是虛擬化容器技術(shù),有三個(gè)主要概念,鏡像(類)、容器(對(duì)象)、倉(cāng)庫(kù),docker就是類似VM虛擬機(jī)一樣的虛擬技術(shù),體積小,運(yùn)行速度快,下面這篇文章主要給大家介紹了關(guān)于優(yōu)化Docker鏡像安全性的12個(gè)技巧,需要的朋友可以參考下2022-03-03Docker Base Image自己創(chuàng)建具體實(shí)現(xiàn)
這篇文章主要介紹了Docker Base Image創(chuàng)建具體實(shí)現(xiàn)的相關(guān)資料,這里提供了詳細(xì)的具體步驟,需要的朋友可以參考下2016-11-11利用Docker分層構(gòu)建優(yōu)化鏡像大小的實(shí)現(xiàn)
合適docker鏡像文件大小不僅影響容器啟動(dòng)效率,也影響資源占用效率,本文介紹如何利用分層方式構(gòu)建docker鏡像,采用多種方式避免鏡像文件太大而影響性能,需要的朋友可以參考下2025-01-01