使用 Docker Configs 儲存組態資料

關於配置

Docker swarm 服務配置讓您可以在服務的映像檔或執行中的容器外部儲存非敏感資訊,例如配置檔案。這讓您可以盡可能地保持映像檔的通用性,無需將配置檔案綁定掛載到容器中或使用環境變數。

配置(Configs)的運作方式與密鑰(secrets)相似,不同之處在於它們在靜止時不會被加密,並且直接掛載到容器的檔案系統中,而無需使用 RAM 磁碟。配置可以隨時從服務中新增或移除,服務之間也可以共享配置。您甚至可以將配置與環境變數或標籤結合使用,以獲得最大的彈性。配置值可以是通用字串或二進位內容(大小上限為 500 KB)。

注意

Docker 配置僅適用於 swarm 服務,不適用於獨立容器。若要使用此功能,請考慮將您的容器改為以服務形式執行,並將規模設定為 1。

Linux 和 Windows 服務都支援配置。

Windows 支援

Docker 支援 Windows 容器上的配置,但在實作上存在差異,這些差異會在以下範例中指出。請記住以下顯著差異:

  • 具有自訂目標的配置檔案不會直接綁定掛載到 Windows 容器中,因為 Windows 不支援非目錄檔案的綁定掛載。相反地,容器的所有配置都掛載在容器內的 C:\ProgramData\Docker\internal\configs(這是一個不應被應用程式依賴的實作細節)。符號連結用於從該位置指向容器內配置的所需目標。預設目標是 C:\ProgramData\Docker\configs

  • 當建立使用 Windows 容器的服務時,不支援為配置指定 UID、GID 和模式的選項。目前,配置只能由容器內的管理員和具有 system 存取權限的使用者存取。

  • 在 Windows 上,使用 config://<config-name> 格式的 --credential-spec 建立或更新服務。這會在容器啟動前將 gMSA 憑證檔案直接傳遞給節點。工作節點上不會將 gMSA 憑證寫入磁碟。如需更多資訊,請參閱將服務部署到 swarm

Docker 如何管理配置

當您將配置新增到 swarm 時,Docker 會透過相互 TLS 連線將配置傳送給 swarm 管理器。該配置儲存在 Raft 日誌中,該日誌是加密的。整個 Raft 日誌會在其他管理器之間複製,確保配置與其餘 swarm 管理資料具有相同的高可用性保證。

當您授予新建立或執行中的服務存取配置的權限時,該配置會以檔案形式掛載到容器中。在 Linux 容器中,容器內的掛載點預設為 /<config-name>。在 Windows 容器中,所有配置都掛載到 C:\ProgramData\Docker\configs,並建立符號連結指向所需的預設位置 C:\<config-name>

您可以為配置設定所有權(uidgid),使用數字 ID 或使用者或群組的名稱。您還可以指定檔案權限(mode)。這些設定對 Windows 容器無效。

  • 如果未設定,配置將歸執行容器指令的使用者所有(通常是 root),以及該使用者的預設群組(通常也是 root)。
  • 如果未設定,配置將具有全球可讀權限(模式 0444),除非在容器中設定了 umask,在這種情況下,模式將受該 umask 值影響。

您可以隨時更新服務,以授予其存取額外配置的權限或撤銷其對特定配置的存取權。

節點僅在該節點是 swarm 管理器,或正在執行已被授予配置存取權限的服務任務時,才能存取配置。當容器任務停止執行時,共享給它的配置會從該容器的記憶體檔案系統中卸載,並從節點記憶體中清除。

如果節點在執行具有配置存取權限的任務容器時失去與 swarm 的連線,該任務容器仍然可以存取其配置,但在節點重新連線到 swarm 之前無法接收更新。

您可以隨時新增或檢查單一配置,或列出所有配置。您不能移除正在執行服務所使用的配置。請參閱輪替配置,了解如何在不中斷執行中服務的情況下移除配置。

為了更輕鬆地更新或回溯配置,請考慮在配置名稱中加入版本號或日期。透過控制配置在指定容器內的掛載點,可以使這項操作變得更容易。

若要更新堆疊,請修改您的 Compose 檔案,然後重新執行 docker stack deploy -c <new-compose-file> <stack-name>。如果您在該檔案中使用新的配置,您的服務將開始使用它們。請記住,配置是不可變的,因此您無法更改現有服務的檔案。相反地,您需要建立一個新的配置來使用不同的檔案。

您可以執行 docker stack rm 來停止應用程式並關閉堆疊。這會移除由 docker stack deploy 以相同堆疊名稱建立的任何配置。這會移除所有配置,包括未被服務引用的配置以及在 docker service update --config-rm 後剩餘的配置。

深入了解 docker config 指令

使用這些連結閱讀特定指令,或繼續查看在服務中使用配置的範例

範例

本節包含逐步範例,說明如何使用 Docker 配置。

注意

為求簡潔,這些範例使用單引擎 swarm 和未擴展的服務。這些範例使用 Linux 容器,但 Windows 容器也支援配置。

在 Compose 檔案中定義及使用配置

docker stack 指令支援在 Compose 檔案中定義配置。但是,docker compose 不支援 configs 鍵。請參閱Compose 檔案參考以獲取詳細資訊。

簡單範例:開始使用配置

這個簡單的範例展示了配置在幾個指令中的運作方式。有關實際應用範例,請繼續閱讀進階範例:在 Nginx 服務中使用配置

  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 自動完成來自動執行此操作。

    $ 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
    

簡單範例:在 Windows 服務中使用配置

這是一個非常簡單的範例,展示了如何在 Docker for Windows 上運行 Microsoft IIS 服務,並在 Microsoft Windows 10 上運行 Windows 容器時使用配置。這是一個將網頁儲存在配置中的簡單範例。

此範例假設您已安裝 PowerShell。

  1. 將以下內容儲存到新檔案 index.html 中。

    <html lang="en">
      <head><title>Hello Docker</title></head>
      <body>
        <p>Hello Docker! You have deployed a HTML page.</p>
      </body>
    </html>
  2. 如果您尚未這麼做,請初始化或加入 swarm。

    docker swarm init
  3. index.html 檔案儲存為名為 homepage 的 swarm 配置。

    docker config create homepage index.html
  4. 建立 IIS 服務並授予其存取 homepage 配置的權限。

    docker service create
        --name my-iis
        --publish published=8000,target=8000
        --config src=homepage,target="\inetpub\wwwroot\index.html"
        microsoft/iis:nanoserver
  5. 透過 https://:8000/ 存取 IIS 服務。它應該會提供第一個步驟中的 HTML 內容。

  6. 移除服務和配置。

    docker service rm my-iis
    
    docker config rm homepage

範例:使用範本化配置

若要建立使用範本引擎產生內容的配置,請使用 --template-driver 參數並將引擎名稱指定為其引數。範本將在容器建立時渲染。

  1. 將以下內容儲存到新檔案 index.html.tmpl 中。

    <html lang="en">
      <head><title>Hello Docker</title></head>
      <body>
        <p>Hello {{ env "HELLO" }}! I'm service {{ .Service.Name }}.</p>
      </body>
    </html>
  2. index.html.tmpl 檔案儲存為名為 homepage 的 swarm 配置。提供參數 --template-driver 並將 golang 指定為範本引擎。

    $ docker config create --template-driver golang homepage index.html.tmpl
    
  3. 建立一個執行 Nginx 並具有環境變數 HELLO 和配置存取權限的服務。

    $ docker service create \
         --name hello-template \
         --env HELLO="Docker" \
         --config source=homepage,target=/usr/share/nginx/html/index.html \
         --publish published=3000,target=80 \
         nginx:alpine
    
  4. 驗證服務是否正常運作:您可以連線到 Nginx 伺服器,並且正在提供正確的輸出。

    $ curl http://0.0.0.0:3000
    
    <html lang="en">
      <head><title>Hello Docker</title></head>
      <body>
        <p>Hello Docker! I'm service hello-template.</p>
      </body>
    </html>
    

進階範例:在 Nginx 服務中使用配置

此範例分為兩部分。第一部分完全是關於產生網站憑證,並不直接涉及 Docker 配置,但它為第二部分奠定了基礎,在第二部分中,您將網站憑證儲存並用作一系列密鑰,Nginx 配置則用作配置。此範例展示如何設定配置選項,例如容器內的目標位置和檔案權限(mode)。

產生網站憑證

為您的網站產生根憑證頒發機構 (CA) 和 TLS 憑證與金鑰。對於生產網站,您可能希望使用 Let's Encrypt 等服務來產生 TLS 憑證和金鑰,但此範例使用命令列工具。此步驟有些複雜,但它僅是一個設定步驟,以便您有東西可以儲存為 Docker 密鑰。如果您想跳過這些子步驟,您可以使用 Let's Encrypt 產生網站金鑰和憑證,將檔案命名為 site.keysite.crt,然後跳至配置 Nginx 容器

  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. Nginx 服務不需要 site.csrsite.cnf 檔案,但如果您想產生新的網站憑證,則需要它們。請保護 root-ca.key 檔案。

配置 Nginx 容器

  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. 建立兩個密鑰,分別代表金鑰和憑證。只要檔案小於 500 KB,您就可以將任何檔案儲存為密鑰。這讓您可以將金鑰和憑證與使用它們的服務解耦。在這些範例中,密鑰名稱和檔案名稱相同。

    $ docker secret create site.key site.key
    
    $ docker secret create site.crt site.crt
    
  3. site.conf 檔案儲存到 Docker 配置中。第一個參數是配置的名稱,第二個參數是要從中讀取配置的檔案。

    $ 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. 驗證 Nginx 服務正在執行。

    $ 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. 驗證服務是否正常運作:您可以連線到 Nginx 伺服器,並且正在使用正確的 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="https://nginx.cplusplus.tw">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="https://www.nginx.com">www.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 服務以及儲存的密鑰和配置來進行清理。

    $ docker service rm nginx
    
    $ docker secret rm site.crt site.key
    
    $ docker config rm site.conf
    

您現在已配置一個 Nginx 服務,其配置與其映像檔分離。您可以運行多個網站,使用完全相同的映像檔但不同的配置,完全無需建立自訂映像檔。

範例:輪替配置

要輪替配置,您首先要儲存一個新配置,其名稱與目前正在使用的配置不同。然後,您重新部署服務,移除舊配置並在容器內的相同掛載點新增新配置。此範例透過輪替 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. 更新 nginx 服務以使用新配置而不是舊配置。

    $ 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 驗證 nginx 服務是否已完全重新部署。完成後,您可以移除舊的 site.conf 配置。

    $ docker config rm site.conf
    
  5. 若要清理,您可以移除 nginx 服務,以及密鑰和配置。

    $ docker service rm nginx
    
    $ docker secret rm site.crt site.key
    
    $ docker config rm site-v2.conf
    

您現在已更新 nginx 服務的配置,而無需重新建構其映像檔。

© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.