docker swarm英文文件學習-9-使用Docker Configs儲存配置資料
Store configuration data using Docker Configs 使用Docker Configs儲存配置資料
Docker 17.06引入了叢集服務配置,允許你在服務映象或執行的容器之外儲存非敏感資訊,如配置檔案。這允許你儘可能保持映象的通用性,而不需要將配置檔案繫結到容器中或使用環境變數。
Configs的操作方式與secret類似,不同的是它們沒有在靜止時加密,而是直接掛載到容器的檔案系統中,而不使用RAM磁碟。配置可以在任何時候從服務中新增或刪除,服務可以共享配置。你甚至可以將configs與環境變數或標籤結合使用,以獲得最大的靈活性。配置值可以是通用字串或二進位制內容(大小不超過500 kb)。
注意:Docker configs只對叢集服務可用,而不是對獨立容器可用。要使用此特性,請考慮將容器調整為以1的比例作為服務執行。
Linux和Windows服務都支援Configs。
Windows support
Docker 17.06及更高版本包括對Windows容器上的configs的支援。在實現中存在差異的地方,將在下面的示例中呼叫它們。請注意以下顯著的差異:
- 帶有自定義目標的配置檔案不直接繫結掛載到Windows容器中,因為Windows不支援非目錄檔案繫結掛載。相反,容器的configs都掛載在容器內的C:\ProgramData\Docker\internal\configs(一個應用程式不應該依賴的實現細節)中。符號連結用於從那裡指向容器中配置所需的目標。預設目標是C:\ProgramData\Docker\configs。
- 在建立使用Windows容器的服務時,configs不支援指定UID、GID和模式的選項。Configs目前只能由容器內具有系統訪問許可權的管理員和使用者訪問。
How Docker manages configs Docker如何管理配置
當你向swarm新增配置時,Docker通過一個相互的TLS連線將配置傳送給swarm manager。配置儲存在Raft日誌中,該日誌是加密的。整個Raft日誌在其他管理器之間複製,確保configs具有與群管理資料的其他部分相同的高可用性保證。
當你授予新建立或正在執行的服務訪問許可權到配置中時,配置將作為檔案掛載在容器中。在Linux容器中,容器中掛載點的位置預設為/<config-name>。在Windows容器中,configs全部掛載到C:\ProgramData\Docker\configs和建立到所需位置的符號連結,預設為C:\<config-name>。
可以使用數字ID或使用者或組的名稱設定所有權(uid和gid)或配置。還可以指定檔案許可權(模式)。對於Windows容器,這些設定將被忽略。
- 如果沒有設定,則配置由執行容器命令的使用者(通常是根使用者)和該使用者的預設組(通常也是根使用者)擁有。
- 如果沒有設定,配置具有世界可讀許可權(模式0444),除非在容器中設定了umask,在這種情況下,模式會受到umask值的影響。
你可以更新服務來授予它對其他配置的訪問許可權,或者隨時撤銷它對給定配置的訪問許可權。
只有當節點是群集管理器或正在執行已被授予配置訪問權的服務任務時,節點才能訪問配置。當容器任務停止執行時,共享給它的配置將從容器的記憶體檔案系統中解除安裝,並從節點的記憶體中重新整理。
如果節點在執行具有配置訪問權的任務容器時失去了與叢集的連線,那麼任務容器仍然可以訪問其配置,但是在節點重新連線到叢集之前不能接收更新。
你可以在任何時候新增或檢查單個配置,或者列出所有配置。無法刪除正在執行的服務正在使用的配置。有關在不中斷正在執行的服務的情況下刪除配置的方法,請參見 Rotate a config。
為了更容易地更新或回滾配置,可以考慮在配置名中新增版本號或日期。通過在給定容器中控制配置的掛載點,可以更容易地做到這一點。
要更新堆疊,請更改你的 Compose檔案,然後重新執行docker stack deploy -c <new-compose-file> <stack-name>。如果在該檔案中使用新配置,則服務將開始使用它們。請記住,配置是不可變的,因此你不能更改現有服務的檔案。相反,你可以建立一個新的配置來使用不同的檔案
你可以執行docker stack rm來停止應用程式並取下堆疊。這將刪除docker stack deploy建立的具有相同堆疊名稱的任何配置。這將刪除所有配置,包括那些沒有被服務引用的配置,以及docker service update --config-rm之後剩下的配置。
Read more about docker config
commands
使用這些連結可以閱讀有關特定命令的資訊,或者繼續閱讀example about using configs with a service。
Examples
這一節包含了演示如何使用Docker configs的分級示例。
注意:為了簡單起見,這些示例使用單引擎叢集和未擴充套件的服務。示例使用Linux容器,但Windows容器也支援configs。
Defining and using configs in compose files 定義和使用compose檔案中的配置
docker compose和docker stack命令都支援在compose檔案中定義配置。有關詳細資訊,請參見the Compose file reference。
Simple example: Get started with configs 開始配置
這個簡單的例子展示了configs如何在幾個命令中工作。對於真實的示例,請繼續Intermediate example: Use configs with a Nginx service。
1.向Docker新增配置。docker config create命令讀取標準輸入,因為最後一個引數,表示要從中讀取配置的檔案被設定為-。
$ echo "This is a config" | docker config create my-config -
2.建立一個redis服務並授予它對配置的訪問權。預設情況下,容器可以在/my-config訪問配置,但是你可以使用target選項定製容器上的檔名。
$ docker service create --name redis --config my-config redis:alpine
3.使用docker service ps檢查任務是否正常執行。如果一切正常,輸出如下:
$ docker service ps redis ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS bkna6bpn8r1a redis.1 redis:alpine ip-172-31-46-109 Running Running 8 seconds ago
4.使用docker ps得到redis服務任務容器的ID,這樣你可以使用docker container exec去連線到容器和讀取配置資料檔案的內容,對所有人預設為可讀的,並有著像配置名一樣相同的名字。下面的第一個命令演示瞭如何查詢容器ID,第二個和第三個命令使用shell補全來自動查詢容器ID。
$ docker ps --filter name=redis -q 5cb1c2348a59 $ docker container exec $(docker ps --filter name=redis -q) ls -l /my-config -r--r--r-- 1 root root 12 Jun 5 20:49 my-config $ docker container exec $(docker ps --filter name=redis -q) cat /my-config This is a config
5.嘗試移除配置。移除失敗是因為redis服務正在執行且正在訪問配置
$ docker config ls ID NAME CREATED UPDATED fzwcfuqjkvo5foqu7ts7ls578 hello 31 minutes ago 31 minutes ago $ docker config rm my-config Error response from daemon: rpc error: code = 3 desc = config 'my-config' is in use by the following service: redis
6.通過更新服務來從執行中的redis中移除對配置的訪問:
$ docker service update --config-rm my-config redis
7.再次重複步驟3和4,檢視服務不再訪問配置。容器ID是不同的,因為service update命令重新部署了服務
$ docker container exec -it $(docker ps --filter name=redis -q) cat /my-config cat: can't open '/my-config': No such file or directory
8.停止並移除服務,並從Docker中移除配置
$ docker service rm redis
$ docker config rm my-config
Advanced example: Use configs with a Nginx service
本例分為兩部分。第一部分是關於生成站點證書的,根本不直接涉及Docker configs,但是它設定了第二部分,在其中儲存和使用站點證書作為一系列金鑰,Nginx配置作為配置。這個示例展示瞭如何在配置上設定選項,例如容器中的目標位置和檔案許可權(模式)。
GENERATE THE SITE CERTIFICATE生成站點證書
為你的站點生成根CA和TLS證書和金鑰。對於生產站點,你可能希望使用Let’s Encrypt之類的服務來生成TLS證書和金鑰,但是本示例使用命令列工具。這一步有點複雜,但只是一個設定步驟,以便你可以將某些內容儲存為Docker祕密。如果你想跳過這些子步驟,可以使用 use Let’s Encrypt生成站點金鑰和證書,命名檔案為site.key和site.crt,然後跳轉到 Configure the Nginx container。
1.生成一個根金鑰:
$ openssl genrsa -out "root-ca.key" 4096
2.使用根金鑰生成一個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'
3.配置根CA.編輯一個名為root-ca.cnf的新檔案,並將以下內容貼上到其中。這限制根CA只簽名葉證書,而不簽名中間CA。
[root_ca] basicConstraints = critical,CA:TRUE,pathlen:1 keyUsage = critical, nonRepudiation, cRLSign, keyCertSign subjectKeyIdentifier=hash
4.簽名證書
$ 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
5.生成站點金鑰
$ openssl genrsa -out "site.key" 4096
6.生成站點證書並使用站點金鑰簽名
$ openssl req -new -key "site.key" -out "site.csr" -sha256 \ -subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost'
7.配置站點證書。編輯一個名為site.cnf的新檔案,並將以下內容貼上到其中。這限制了站點證書,因此它只能用於對伺服器進行身份驗證,而不能用於對證書進行簽名。
[server] authorityKeyIdentifier=keyid,issuer basicConstraints = critical,CA:FALSE extendedKeyUsage=serverAuth keyUsage = critical, digitalSignature, keyEncipherment subjectAltName = DNS:localhost, IP:127.0.0.1 subjectKeyIdentifier=hash
8.對站點證書籤名
$ 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
9.site.csr
和site.cnf
檔案不被Nginx服務需要,但是如果你想生成一個新的站點證書,則需要它們。保護root-ca.key檔案。
CONFIGURE THE NGINX CONTAINER 配置Ngnix容器
1.生成一個非常基本的Nginx配置,它通過HTTPS提供靜態檔案。TLS證書和金鑰儲存為Docker金鑰,這樣可以方便地輪轉它們。
在當前目錄中,建立一個帶著下面內容的名為site.conf的新檔案
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; } }
2.建立兩個祕密,分別表示金鑰和證書。你可以將任何檔案作為祕密儲存,只要它小於500kb。這允許你將金鑰和證書與使用它們的服務解耦。在這些示例中,金鑰名稱和檔名是相同的。
$ docker secret create site.key site.key
$ docker secret create site.crt site.crt
3.在Docker配置中儲存site.conf檔案。第一個引數是配置的名稱,第二個引數是要從中讀取配置的檔案。
$ docker config create site.conf site.conf
列舉配置資訊:
$ docker config ls ID NAME CREATED UPDATED 4ory233120ccg7biwvy11gl5z site.conf 4 seconds ago 4 seconds ago
4.建立一個執行Nginx的服務,並且可以訪問這兩個祕密和配置。將模式設定為0440,這樣檔案只能由其所有者和該所有者的組(而不是整個世界)讀取。
$ docker service create \ --name nginx \ --secret site.key \ --secret site.crt \ --config source=site.conf,target=/etc/nginx/conf.d/site.conf,mode=0440 \ --publish published=3000,target=443 \ nginx:latest \ sh -c "exec nginx -g 'daemon off;'"
在執行的容器中,下面的三個檔案將存在:
/run/secrets/site.key
/run/secrets/site.crt
/etc/nginx/conf.d/site.conf
5.核查Ngnix服務正在執行
$ docker service ls ID NAME MODE REPLICAS IMAGE zeskcec62q24 nginx replicated 1/1 nginx:latest $ docker service ps nginx NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS nginx.1.9ls3yo9ugcls nginx:latest moby Running Running 3 minutes ago
6.核查服務是可操作的:你可以到達Ngnix服務端,並且正確的TLS證書正在被使用
$ curl --cacert root-ca.crt https://0.0.0.0:3000 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support, refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
$ openssl s_client -connect 0.0.0.0:3000 -CAfile root-ca.crt CONNECTED(00000003) depth=1 /C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA verify return:1 depth=0 /C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost verify return:1 --- Certificate chain 0 s:/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost i:/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA --- Server certificate -----BEGIN CERTIFICATE----- … -----END CERTIFICATE----- subject=/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost issuer=/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA --- No client certificate CA names sent --- SSL handshake has read 1663 bytes and written 712 bytes --- New, TLSv1/SSLv3, Cipher is AES256-SHA Server public key is 4096 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : AES256-SHA Session-ID: A1A8BF35549C5715648A12FD7B7E3D861539316B03440187D9DA6C2E48822853 Session-ID-ctx: Master-Key: F39D1B12274BA16D3A906F390A61438221E381952E9E1E05D3DD784F0135FB81353DA38C6D5C021CB926E844DFC49FC4 Key-Arg : None Start Time: 1481685096 Timeout : 300 (sec) Verify return code: 0 (ok)
7.除非你打算繼續下一個示例,否則在執行此示例之後,請通過刪除nginx服務以及儲存的secrets和配置來清理。
$ docker service rm nginx
$ docker secret rm site.crt site.key
$ docker config rm site.conf
現在你已經配置了一個Nginx服務,它的配置與其映象解耦。你可以執行具有完全相同的映象但配置不同的多個站點,根本不需要構建自定義映象。
Example: Rotate a config 輪轉配置
要輪轉配置,首先要用與當前使用的配置名稱不同的名稱儲存新配置。然後重新部署服務,刪除舊配置並在容器中的相同掛載點新增新配置。這個示例是在上一個示例的基礎上輪轉site.conf配置檔案。
1.本地編輯site.conf檔案。新增index.php到index行並儲存該檔案
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 index.php; } }
2.使用site.conf建立一個新Docker配置,命名為site-v2.conf
$ docker config create site-v2.conf site.conf
3.更新Ngnix服務去使用一個新的配置,而不是舊的那個
$ docker service update \ --config-rm site.conf \ --config-add source=site-v2.conf,target=/etc/nginx/conf.d/site.conf,mode=0440 \ nginx
4.使用docker service ps nginx核查Ngnix服務完全重新部署。當確定時,你就可以移除舊的site.conf配置了
$ docker config rm site.conf
5.為了清理,你可以移除Ngnix服務和金鑰和配置
$ docker service rm nginx
$ docker secret rm site.crt site.key
$ docker config rm site-v2.conf
現在你可以更新ngnix服務配置而不用重新構建映象