體系到全集群實(shí)戰(zhàn))
云原生后端微服務(wù)【免費(fèi)下載鏈接】classicswarmSwarm Classic: a container clustering system. Not to be confused with Docker Swarm which is at https://github.com/docker/swarmkit項(xiàng)目地址https://gitcode.com/gh_mirrors/cl/classicswarm點(diǎn)擊查看免費(fèi)下載Docker SwarmClassic Swarm集群中的所有節(jié)點(diǎn)都必須在網(wǎng)絡(luò)上綁定 Docker daemon 端口這帶來(lái)顯而易見(jiàn)的安全風(fēng)險(xiǎn)——當(dāng)網(wǎng)絡(luò)不可信如公網(wǎng)時(shí)風(fēng)險(xiǎn)成倍放大。本文以docs/secure-swarm-tls.md與docs/configure-tls.md為主線系統(tǒng)講解 TLS 與 PKI 的基礎(chǔ)概念、三種證書(shū)簽發(fā)模式并給出從零搭建「CA 服務(wù)器 swarm manager 雙節(jié)點(diǎn) 遠(yuǎn)程客戶端」五機(jī) TLS 環(huán)境的完整九步實(shí)操同時(shí)結(jié)合本倉(cāng)庫(kù)源碼cli/manage.go、api/server.go、cluster/httpclient.go 等說(shuō)明 TLS 在 Swarm 內(nèi)部的真實(shí)作用路徑。讀完本文你將能夠獨(dú)立為 Docker Classic Swarm 集群配置雙向 TLS 認(rèn)證并理解其底層實(shí)現(xiàn)原理。為什么 Swarm 集群需要 TLSDocker Classic Swarm 是一個(gè)容器集群系統(tǒng)它把多臺(tái) Docker 主機(jī)的計(jì)算資源聚合成一個(gè)虛擬的、巨大的 Docker Engine。為此集群中的每一臺(tái)節(jié)點(diǎn)包括 swarm manager 與 swarm 節(jié)點(diǎn)都必須把 Docker daemon 綁定到網(wǎng)絡(luò)端口上接受來(lái)自網(wǎng)絡(luò)的命令。一旦端口暴露到不受信任的網(wǎng)絡(luò)例如互聯(lián)網(wǎng)攻擊者就可能直接向 daemon 發(fā)送惡意命令創(chuàng)建容器、拉取鏡像、讀寫(xiě)數(shù)據(jù)卷實(shí)施中間人攻擊man-in-the-middle篡改客戶端與 daemon 之間的通信內(nèi)容。為了緩解這些風(fēng)險(xiǎn)Docker Swarm 與 Docker Engine daemon 支持傳輸層安全協(xié)議Transport Layer SecurityTLS。TLS 是 SSLSecure Sockets Layer的繼任者兩者經(jīng)常被混用Docker 使用的是 TLS本文統(tǒng)一使用 TLS 一詞。生產(chǎn)規(guī)劃文檔 docs/plan-for-production.md 也明確指出所有節(jié)點(diǎn)都必須綁定網(wǎng)絡(luò)端口Swarm 與 Engine 通過(guò) TLS 認(rèn)證來(lái)緩解中間人攻擊等風(fēng)險(xiǎn)并給出了 TLS 模式下的默認(rèn)端口約定組件默認(rèn) TLS 端口Engine daemon2376/tcpSwarm manager3376/tcp非 TLS 模式下Engine 與 Swarm 的默認(rèn)端口分別為2375/tcp與3375/tcp。先理解 TLS 與 PKI 的基本概念在動(dòng)手配置之前先弄清 TLS 與公鑰基礎(chǔ)設(shè)施Public Key InfrastructurePKI的核心概念。PKI 是一套用于創(chuàng)建和管理數(shù)字證書(shū)的安全技術(shù)、策略與流程的組合這些證書(shū)與基礎(chǔ)設(shè)施通過(guò)認(rèn)證authentication與加密encryption等機(jī)制保護(hù)數(shù)字通信。護(hù)照類比護(hù)照用于驗(yàn)證一個(gè)人的身份包含持有人照片與生物特征信息還列出了簽發(fā)國(guó)家以及valid from生效日與valid to失效日日期。數(shù)字證書(shū)與此非常相似。下面是從一張數(shù)字證書(shū)中摘錄的內(nèi)容Certificate: Data: Version: 3 (0x2) Serial Number: 9590646456311914051 (0x8518d2237ad49e43) Signature Algorithm: sha256WithRSAEncryption Issuer: CUS, STCA, LSanfrancisco, ODocker Inc Validity Not Before: Jan 18 09:42:16 2016 GMT Not After : Jan 15 09:42:16 2026 GMT Subject: CNswarm這張證書(shū)標(biāo)識(shí)的是一臺(tái)名為swarm的計(jì)算機(jī)有效期從 2016 年 1 月到 2026 年 1 月由位于美國(guó)加州舊金山的 Docker Inc. 簽發(fā)。正如護(hù)照在登機(jī)、過(guò)海關(guān)時(shí)認(rèn)證個(gè)人身份數(shù)字證書(shū)在網(wǎng)絡(luò)上認(rèn)證計(jì)算機(jī)的身份。PKI 則是在幕后支撐數(shù)字證書(shū)的技術(shù)、策略與流程組合主要包括安全地請(qǐng)求證書(shū)的服務(wù)認(rèn)證證書(shū)請(qǐng)求實(shí)體身份的程序判斷實(shí)體是否有資格獲得證書(shū)的程序簽發(fā)證書(shū)的技術(shù)與流程吊銷證書(shū)的技術(shù)與流程。Docker Engine 如何利用 TLS 進(jìn)行認(rèn)證你可以同時(shí)配置 Docker Engine CLI 與 Docker Engine daemon 要求使用 TLS 進(jìn)行認(rèn)證。配置 TLS 意味著CLI 與 daemon 之間的所有通信都必須附帶并經(jīng)由受信任的數(shù)字證書(shū)簽名。Docker Engine CLI 必須先出示自己的數(shù)字證書(shū)daemon 才會(huì)接受它發(fā)來(lái)的命令。與此同時(shí)daemon 也必須信任 CLI 所使用的證書(shū)。這種信任通常經(jīng)由可信第三方建立——即圖中的 Certificate AuthorityCA證書(shū)頒發(fā)機(jī)構(gòu)服務(wù)器。圖中的可信第三方就是 CA 服務(wù)器。如同護(hù)照示例中的國(guó)家CA 負(fù)責(zé)創(chuàng)建、簽名、簽發(fā)和吊銷證書(shū)。信任的建立方式是在運(yùn)行 Docker Engine daemon 的主機(jī)上安裝 CA 的根證書(shū)然后 Docker Engine CLI 向 CA 服務(wù)器請(qǐng)求自己的證書(shū)由 CA 簽名后簽發(fā)給它。工作流程如下Docker Engine CLI 在發(fā)出命令前先把證書(shū)發(fā)送給 Docker Engine daemondaemon 檢查證書(shū)——由于 daemon 信任該 CA它會(huì)自動(dòng)信任任何由該 CA 簽名的證書(shū)假設(shè)證書(shū)有效未過(guò)期、未被吊銷等daemon 就接受來(lái)自這個(gè)可信 CLI 的命令。需要強(qiáng)調(diào)Docker Engine CLI 本質(zhì)上只是使用 Docker Engine API 與 daemon 通信的一個(gè)客戶端。任何使用 Docker Engine API 的客戶端都可以使用 TLS。例如 Docker Universal Control PlaneUCP內(nèi)置了 TLS 支持其他基于 Docker Engine API 的第三方產(chǎn)品也可以這樣配置。Docker 與 Swarm 的三種 TLS 配置模式根據(jù)承擔(dān) CA 角色的實(shí)體類型不同Docker Engine daemon 及其客戶端存在三種可能的 TLS 配置外部第三方 CAExternal 3rd party CA內(nèi)部企業(yè) CAInternal corporate CA自簽名證書(shū)Self-signed certificates外部第三方 CA外部 CA 是受信任的第三方公司提供創(chuàng)建、簽發(fā)、吊銷和管理證書(shū)的服務(wù)。說(shuō)它們「受信任」是因?yàn)樗鼈儽仨殱M足特定條件、保持高水準(zhǔn)的安全與商業(yè)實(shí)踐才能贏得你的業(yè)務(wù)同時(shí)你也需要安裝外部 CA 的根證書(shū)才能讓計(jì)算機(jī)和服務(wù)信任它們。使用外部第三方 CA 時(shí)證書(shū)的創(chuàng)建、簽名、簽發(fā)、吊銷與管理全部由它負(fù)責(zé)。這類服務(wù)通常收費(fèi)但被公認(rèn)為企業(yè)級(jí)、可擴(kuò)展的解決方案能提供較高程度的信任。內(nèi)部企業(yè) CA許多組織選擇搭建自己的 CA 與 PKI常見(jiàn)實(shí)現(xiàn)包括 OpenSSL 和 Microsoft Active Directory。這種情況下你的公司自己就是 CA需要承擔(dān) CA 的全部工作。好處是作為自己的 CA你對(duì) PKI 擁有更強(qiáng)的控制力。自建 CA 與 PKI 需要你自行提供外部第三方 CA 提供的全部服務(wù)包括創(chuàng)建、簽發(fā)、吊銷和管理證書(shū)。自己做這些事有相應(yīng)的成本與開(kāi)銷但對(duì)大型企業(yè)而言與使用外部第三方服務(wù)相比仍可能降低成本。假設(shè)你的內(nèi)部 CA 與 PKI 運(yùn)營(yíng)管理得當(dāng)內(nèi)部企業(yè) CA 可以是一種高度可擴(kuò)展、高度安全的選擇。自簽名證書(shū)顧名思義自簽名證書(shū)是用自己的私鑰簽名的證書(shū)而不是由受信任的 CA 簽名。這是低成本、易用的選擇。如果正確實(shí)現(xiàn)和管理自簽名證書(shū)它們比完全沒(méi)有證書(shū)要好。但由于自簽名證書(shū)缺少完整的 PKI擴(kuò)展性差也缺少其他兩種方案提供的許多優(yōu)勢(shì)。一個(gè)明顯的缺點(diǎn)是自簽名證書(shū)無(wú)法吊銷。由于這一點(diǎn)及其他限制自簽名證書(shū)被認(rèn)為是三種方案中最不安全的不建議在暴露于不受信任網(wǎng)絡(luò)的公網(wǎng)生產(chǎn)負(fù)載中使用。實(shí)戰(zhàn)為 Docker Swarm 集群配置 TLS九步全流程下面的流程將創(chuàng)建一個(gè)兩節(jié)點(diǎn)的 swarm 集群外加一個(gè) Docker Engine CLI、一個(gè) swarm manager 和一個(gè) CA 服務(wù)器如圖所示。所有 Docker Engine 主機(jī)client、swarm、node1、node2都擁有 CA 證書(shū)副本以及由 CA 簽發(fā)的各自密鑰對(duì)。流程包含以下步驟Step 1: 準(zhǔn)備前置條件Step 2: 創(chuàng)建 CA 服務(wù)器Step 3: 創(chuàng)建并簽發(fā)密鑰Step 4: 安裝密鑰Step 5: 為 Engine daemon 配置 TLSStep 6: 創(chuàng)建 swarm 集群Step 7: 使用 TLS 啟動(dòng) swarm managerStep 8: 測(cè)試 swarm manager 配置Step 9: 配置 Engine CLI 使用 TLS開(kāi)始之前的重要提示下文包含使用 OpenSSL 自建 CA 的步驟這與運(yùn)營(yíng)內(nèi)部企業(yè) CA 和 PKI 類似。但絕不能把這里的步驟當(dāng)作搭建生產(chǎn)級(jí)內(nèi)部 CA 與 PKI 的指南。這些步驟僅用于演示目的——讓沒(méi)有現(xiàn)成 CA 和證書(shū)的讀者也能跟著操作完成 Swarm 的 TLS 配置。Step 1: 準(zhǔn)備前置條件完成本流程需要準(zhǔn)備 5 臺(tái) Linux 服務(wù)器可以是物理機(jī)與虛擬機(jī)的任意組合可位于本地或公有云。各服務(wù)器的名稱與用途如下服務(wù)器名說(shuō)明ca充當(dāng) Certificate AuthorityCA服務(wù)器swarm充當(dāng) swarm managernode1充當(dāng) swarm 節(jié)點(diǎn)node2充當(dāng) swarm 節(jié)點(diǎn)client充當(dāng)遠(yuǎn)程 Docker Engine 客戶端確保你能通過(guò) SSH 訪問(wèn)全部 5 臺(tái)服務(wù)器且它們能通過(guò) DNS 名稱解析相互通信。特別要注意在 swarm manager 與 swarm 節(jié)點(diǎn)之間開(kāi)放 TCP 端口2376在 Docker Engine client 與 swarm manager 之間開(kāi)放 TCP 端口3376。如果這些端口已被占用可以選擇其他端口但本示例假設(shè)使用這些端口。每臺(tái)服務(wù)器必須運(yùn)行與 Docker Engine 兼容的操作系統(tǒng)為簡(jiǎn)便起見(jiàn)后續(xù)步驟假設(shè)所有服務(wù)器都運(yùn)行 Ubuntu 14.04 LTS。Step 2: 創(chuàng)建 CA 服務(wù)器注意如果你已經(jīng)擁有 CA 和證書(shū)且熟悉其使用可以跳過(guò)本步直接進(jìn)入下一步。本步把一臺(tái) Linux 服務(wù)器配置為 CA用它來(lái)創(chuàng)建和簽發(fā)密鑰。再次強(qiáng)調(diào)這只是為了讓沒(méi)有現(xiàn)成 CA 的讀者可以跟隨完成后續(xù)步驟不是生產(chǎn)級(jí) CA 的部署范本。登錄 CA 服務(wù)器的終端并提升為 root$ sudo su為 CA 創(chuàng)建私鑰ca-priv-key.pem# openssl genrsa -out ca-priv-key.pem 2048 Generating RSA private key, 2048 bit long modulus ........................................................... ..... e is 65537 (0x10001)為 CA 創(chuàng)建公鑰ca.pem。公鑰基于上一步創(chuàng)建的私鑰# openssl req -config /usr/lib/ssl/openssl.cnf -new -key ca-priv-key.pem -x509 -days 1825 -out ca.pem You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter ., the field will be left blank. ----- Country Name (2 letter code) [AU]:US output truncated這里的-days 1825意味著 CA 證書(shū)有效期約為 5 年1825 天。至此你已配置好一個(gè)擁有公私鑰對(duì)的 CA 服務(wù)器。可以檢查每個(gè)密鑰的內(nèi)容用openssl rsa -in ca-priv-key.pem -noout -text檢查私鑰用openssl x509 -in ca.pem -noout -text檢查公鑰證書(shū)。下面是 CA 公鑰的部分內(nèi)容# openssl x509 -in ca.pem -noout -text Certificate: Data: Version: 3 (0x2) Serial Number: 17432010264024107661 (0xf1eaf0f9f41eca8d) Signature Algorithm: sha256WithRSAEncryption Issuer: CUS, STCA, LSanfrancisco, ODocker Inc Validity Not Before: Jan 16 18:28:12 2016 GMT Not After : Jan 13 18:28:12 2026 GMT Subject: CUS, STCA, LSan Francisco, ODocker Inc Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:d1:fe:6e:55:d4:93:fc:c9:8a:04:07:2d:ba:f0: 55:97:c5:2c:f5:d7:1d:6a:9b:f0:f0:55:6c:5d:90: output truncated稍后你將用這張證書(shū)為基礎(chǔ)設(shè)施中的其他服務(wù)器簽發(fā)密鑰。Step 3: 創(chuàng)建并簽發(fā)密鑰現(xiàn)在 CA 已就緒你需要為 swarm manager、swarm 節(jié)點(diǎn)和遠(yuǎn)程 Docker Engine client 創(chuàng)建密鑰對(duì)。所有服務(wù)器的密鑰對(duì)創(chuàng)建命令與流程完全相同。涉及的關(guān)鍵文件如下文件說(shuō)明ca-priv-key.pemCA 的私鑰必須妥善保管。稍后用它為環(huán)境中其他節(jié)點(diǎn)簽發(fā)新密鑰。與ca.pem一起構(gòu)成 CA 的密鑰對(duì)。ca.pemCA 的公鑰即證書(shū)。安裝到環(huán)境中所有節(jié)點(diǎn)上使所有節(jié)點(diǎn)信任由該 CA 簽名的證書(shū)。與ca-priv-key.pem一起構(gòu)成 CA 的密鑰對(duì)。NODE_NAME.csr證書(shū)簽名請(qǐng)求CSR。CSR 本質(zhì)上是向 CA 申請(qǐng)為某個(gè)節(jié)點(diǎn)創(chuàng)建新密鑰對(duì)的申請(qǐng)單。CA 根據(jù) CSR 提供的信息生成該節(jié)點(diǎn)的公私鑰對(duì)。NODE_NAME-priv-key.pem由 CA 簽名的私鑰。節(jié)點(diǎn)用它向遠(yuǎn)程 Docker Engine 認(rèn)證自己的身份。與NODE_NAME-cert.pem一起構(gòu)成節(jié)點(diǎn)的密鑰對(duì)。NODE_NAME-cert.pem由 CA 簽名的證書(shū)。與NODE_NAME-priv-key.pem一起構(gòu)成節(jié)點(diǎn)的密鑰對(duì)。下面的命令演示如何為所有節(jié)點(diǎn)創(chuàng)建密鑰請(qǐng)?jiān)?CA 服務(wù)器上的一個(gè)工作目錄中執(zhí)行。登錄 CA 服務(wù)器終端并提升為 root$ sudo su為 swarm manager 創(chuàng)建私鑰swarm-priv-key.pem# openssl genrsa -out swarm-priv-key.pem 2048 Generating RSA private key, 2048 bit long modulus ............................................................ ........ e is 65537 (0x10001)用上一步創(chuàng)建的私鑰生成證書(shū)簽名請(qǐng)求CSRswarm.csr# openssl req -subj /CNswarm -new -key swarm-priv-key.pem -out swarm.csr注意這僅用于演示目的。真實(shí)生產(chǎn)環(huán)境中創(chuàng)建 CSR 的流程略有不同。這里-subj /CNswarm直接指定了證書(shū)的主體名Common Name為swarm即前面證書(shū)示例中Subject: CNswarm所對(duì)應(yīng)的身份?;谏弦徊絼?chuàng)建的 CSR 生成證書(shū)swarm-cert.pem# openssl x509 -req -days 1825 -in swarm.csr -CA ca.pem -CAkey ca-priv-key.pem -CAcreateserial -out swarm-cert.pem -extensions v3_req -extfile /usr/lib/ssl/openssl.cnf snip # openssl rsa -in swarm-priv-key.pem -out swarm-priv-key.pem至此你擁有了 swarm manager 的密鑰對(duì)。對(duì)其余節(jié)點(diǎn)node1、node2、client重復(fù)上述步驟。注意把swarm相關(guān)的取值替換為正在創(chuàng)建密鑰對(duì)的節(jié)點(diǎn)對(duì)應(yīng)的值服務(wù)器名私鑰CSR證書(shū)node1node1-priv-key.pemnode1.csrnode1-cert.pemnode2node2-priv-key.pemnode2.csrnode2-cert.pemclientclient-priv-key.pemclient.csrclient-cert.pem驗(yàn)證工作目錄包含以下文件# ls -l total 64 -rw-r--r-- 1 root root 1679 Jan 16 18:27 ca-priv-key.pem -rw-r--r-- 1 root root 1229 Jan 16 18:28 ca.pem -rw-r--r-- 1 root root 17 Jan 18 09:56 ca.srl -rw-r--r-- 1 root root 1086 Jan 18 09:56 client-cert.pem -rw-r--r-- 1 root root 887 Jan 18 09:55 client.csr -rw-r--r-- 1 root root 1679 Jan 18 09:56 client-priv-key.pem -rw-r--r-- 1 root root 1082 Jan 18 09:44 node1-cert.pem -rw-r--r-- 1 root root 887 Jan 18 09:43 node1.csr -rw-r--r-- 1 root root 1675 Jan 18 09:44 node1-priv-key.pem -rw-r--r-- 1 root root 1082 Jan 18 09:49 node2-cert.pem -rw-r--r-- 1 root root 887 Jan 18 09:49 node2.csr -rw-r--r-- 1 root root 1675 Jan 18 09:49 node2-priv-key.pem -rw-r--r-- 1 root root 1082 Jan 18 09:42 swarm-cert.pem -rw-r--r-- 1 root root 887 Jan 18 09:41 swarm.csr -rw-r--r-- 1 root root 1679 Jan 18 09:42 swarm-priv-key.pemca.srl是 CA 自動(dòng)生成的序列號(hào)文件由-CAcreateserial參數(shù)產(chǎn)生CA 用它記錄已簽發(fā)證書(shū)的序列號(hào)。你可以用openssl rsa -in key-name -noout -text檢查私鑰用openssl x509 -in key-name -noout -text檢查公鑰。下面是 swarm manager 公鑰swarm-cert.pem的部分內(nèi)容# openssl x509 -in ca.pem -noout -text Certificate: Data: Version: 3 (0x2) Serial Number: 9590646456311914051 (0x8518d2237ad49e43) Signature Algorithm: sha256WithRSAEncryption Issuer: CUS, STCA, LSanfrancisco, ODocker Inc Validity Not Before: Jan 18 09:42:16 2016 GMT Not After : Jan 15 09:42:16 2026 GMT Subject: CNswarm output truncated可以看到Subject: CNswarm對(duì)應(yīng)前面openssl req -subj /CNswarm設(shè)定的主體名。Step 4: 安裝密鑰本步把密鑰安裝到基礎(chǔ)設(shè)施中對(duì)應(yīng)的服務(wù)器上。每臺(tái)服務(wù)器需要三個(gè)文件CA 公鑰的副本ca.pem自己的私鑰自己的公鑰證書(shū)下面的步驟演示如何用scp把這些文件從 CA 服務(wù)器復(fù)制到各服務(wù)器。復(fù)制時(shí)按如下規(guī)則重命名文件原文件名復(fù)制后文件名ca.pemca.pemserver-cert.pemcert.pemserver-priv-key.pemkey.pem登錄 CA 服務(wù)器終端并提升為 root$ sudo su在 swarm manager 上創(chuàng)建~/.certs目錄。這里假設(shè)用戶賬戶是 ubuntu$ ssh ubuntuswarm mkdir -p /home/ubuntu/.certs把密鑰從 CA 復(fù)制到 swarm manager 服務(wù)器$ scp ./ca.pem ubuntuswarm:/home/ubuntu/.certs/ca.pem $ scp ./swarm-cert.pem ubuntuswarm:/home/ubuntu/.certs/cert.pem $ scp ./swarm-priv-key.pem ubuntuswarm:/home/ubuntu/.certs/key.pem注意scp命令可能需要提供認(rèn)證。例如 AWS EC2 實(shí)例使用基于證書(shū)的認(rèn)證。要把文件復(fù)制到與公鑰nigel.pem關(guān)聯(lián)的 EC2 實(shí)例scp命令需修改為scp -i /path/to/nigel.pem ./ca.pem ubuntuswarm:/home/ubuntu/.certs/ca.pem。對(duì)其余每臺(tái)服務(wù)器重復(fù)步驟 2 與 3node1node2client驗(yàn)證你的工作。復(fù)制完成后每臺(tái)機(jī)器都應(yīng)擁有以下密鑰基礎(chǔ)設(shè)施中的每個(gè)節(jié)點(diǎn)都應(yīng)在/home/ubuntu/.certs/目錄下?lián)碛幸韵挛募? ls -l /home/ubuntu/.certs/ total 16 -rw-r--r-- 1 ubuntu ubuntu 1229 Jan 18 10:03 ca.pem -rw-r--r-- 1 ubuntu ubuntu 1082 Jan 18 10:06 cert.pem -rw-r--r-- 1 ubuntu ubuntu 1679 Jan 18 10:06 key.pemStep 5: 為 Engine daemon 配置 TLS上一步你已在每個(gè) swarm 節(jié)點(diǎn)上創(chuàng)建并安裝了必要密鑰。本步把它們配置為監(jiān)聽(tīng)網(wǎng)絡(luò)且只接受 TLS 連接。完成后swarm 節(jié)點(diǎn)將監(jiān)聽(tīng) TCP 端口2376并且只接受使用 TLS 的連接。在node1和node2你的 swarm 節(jié)點(diǎn)上執(zhí)行以下操作打開(kāi)node1的終端并提升為 root$ sudo su向/etc/docker/daemon.json添加以下配置鍵。如果文件不存在則創(chuàng)建它{ hosts: [tcp://0.0.0.0:2376], tlsverify: true, tlscacert: /home/ubuntu/.certs/ca.pem, tlscert: /home/ubuntu/.certs/cert.pem, tlskey: /home/ubuntu/.certs/key.pem }重啟 Docker 使配置生效。如果文件不是合法 JSONDocker 將啟動(dòng)失敗并輸出錯(cuò)誤。各配置鍵含義如下配置鍵含義hostsdaemon 監(jiān)聽(tīng)的地址與端口tcp://0.0.0.0:2376表示在所有網(wǎng)卡上以 TLS 端口 2376 提供服務(wù)tlsverify置為true啟用 TLS 并強(qiáng)制驗(yàn)證客戶端證書(shū)雙向認(rèn)證tlscacertCA 根證書(shū)路徑daemon 用它驗(yàn)證客戶端證書(shū)鏈tlscertdaemon 自己的證書(shū)路徑tlskeydaemon 自己的私鑰路徑在node2上重復(fù)上述過(guò)程。從這里可以看出 TLS 的「雙向」特征daemon 不僅要向客戶端證明自己出示cert.pem/key.pem還要通過(guò)tlsverify與ca.pem反過(guò)來(lái)校驗(yàn)客戶端身份。這正是 cli/manage.go 中l(wèi)oadTLSConfig所體現(xiàn)的行為——verify為真時(shí)加載 CA 證書(shū)池并設(shè)置ClientAuth tls.RequireAndVerifyClientCert強(qiáng)制要求客戶端提供由該 CA 簽發(fā)的證書(shū)。Step 6: 創(chuàng)建 swarm 集群接下來(lái)創(chuàng)建 swarm 集群。本流程使用默認(rèn)的hosted discovery托管發(fā)現(xiàn)后端創(chuàng)建一個(gè)兩節(jié)點(diǎn) swarm 集群。默認(rèn)的 hosted discovery 后端使用 Docker Hub不建議用于生產(chǎn)環(huán)境。登錄 swarm manager 節(jié)點(diǎn)的終端。創(chuàng)建集群并把它的唯一 ID 導(dǎo)出到TOKEN環(huán)境變量$ sudo export TOKEN$(docker run --rm swarm create) Unable to find image swarm:latest locally latest: Pulling from library/swarm d681c900c6e3: Pulling fs layer snip 986340ab62f0: Pull complete a9975e2cc0a3: Pull complete Digest: sha256:c21fd414b0488637b1f05f13a59b032a3f9da5d818d31da1a4ca98a84c0c781b Status: Downloaded newer image for swarm:latestswarm create子命令會(huì)生成一個(gè)集群 token所有節(jié)點(diǎn)通過(guò)token://$TOKEN接入同一個(gè)集群。把node1加入集群。務(wù)必指定 TCP 端口2376而不是2375$ sudo docker run -d swarm join --addrnode1:2376 token://$TOKEN 7bacc98536ed6b4200825ff6f4004940eb2cec891e1df71c6bbf20157c5f9761把node2加入集群$ sudo docker run -d swarm join --addrnode2:2376 token://$TOKEN db3f49d397bad957202e91f0679ff84f526e74d6c5bf1b6734d834f5edcbca6cStep 7: 使用 TLS 啟動(dòng) swarm manager啟動(dòng)一個(gè)啟用 TLS 的新容器$ docker run -d -p 3376:3376 -v /home/ubuntu/.certs:/certs:ro swarm manage --tlsverify --tlscacert/certs/ca.pem --tlscert/certs/cert.pem --tlskey/certs/key.pem --host0.0.0.0:3376 token://$TOKEN這條命令基于swarm鏡像啟動(dòng)一個(gè)新容器并把服務(wù)器上的端口3376映射到容器內(nèi)的端口3376。這個(gè)映射確保發(fā)送到主機(jī)端口3376的 Docker Engine 命令會(huì)被轉(zhuǎn)發(fā)到容器內(nèi)的端口3376。容器以--tlsverify、--tlscacert、--tlscert和--tlskey選項(xiàng)運(yùn)行swarm manage進(jìn)程——這些選項(xiàng)強(qiáng)制進(jìn)行 TLS 驗(yàn)證并指定 swarm manager TLS 密鑰的位置。證書(shū)目錄/home/ubuntu/.certs以只讀方式掛載為容器內(nèi)/certs/certs/*.pem路徑即對(duì)應(yīng)上述三個(gè)--tls*參數(shù)。運(yùn)行docker ps驗(yàn)證 swarm manager 容器已啟動(dòng)并運(yùn)行$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 035dbf57b26e swarm /swarm manage --tlsv 7 seconds ago Up 7 seconds 2375/tcp, 0.0.0.0:3376-3376/tcp compassionate_lovelace源碼印證manage命令在 cli/manage.go 中先檢查--tls/--tlsverify標(biāo)志若指定了它們而未提供--tlscert/--tlskey則直接報(bào)錯(cuò)退出指定--tlsverify而未提供--tlscacert同樣報(bào)錯(cuò)反之若只提供了--tlscert/--tlskey/--tlscacert而沒(méi)開(kāi)--tls/--tlsverify也會(huì)被拒絕因?yàn)檫@些參數(shù)將被忽略。隨后 loadTLSConfig 會(huì)調(diào)用tls.LoadX509KeyPair加載證書(shū)私鑰并把 TLS 最低版本設(shè)為 TLS 1.2MinVersion: tls.VersionTLS12。校驗(yàn)啟用時(shí)還會(huì)把 CA 證書(shū)讀入證書(shū)池同時(shí)設(shè)置ClientAuth tls.RequireAndVerifyClientCert與ClientCAs實(shí)現(xiàn)雙向認(rèn)證。生成的tlsConfig最終被傳給 api.NewServer見(jiàn) cli/manage.go與 swarm.NewCluster。api.Server在 newListener 中檢測(cè)到tlsConfig ! nil時(shí)會(huì)設(shè)置NextProtos []string{http/1.1}并用tls.NewListener包裝監(jiān)聽(tīng)器——也就是說(shuō)Swarm 對(duì)外暴露的 HTTPS 端口正是由這份 TLS 配置支撐的。你的 swarm 集群現(xiàn)在已配置為使用 TLS。Step 8: 測(cè)試 swarm manager 配置集群已構(gòu)建并配置 TLS現(xiàn)在用 Docker Engine CLI 驗(yàn)證它是否工作。打開(kāi)client服務(wù)器的終端。執(zhí)行docker version命令。執(zhí)行時(shí)必須傳入客戶端證書(shū)的位置$ sudo docker --tlsverify --tlscacert/home/ubuntu/.certs/ca.pem --tlscert/home/ubuntu/.certs/cert.pem --tlskey/home/ubuntu/.certs/key.pem -H swarm:3376 version Client: Version: 1.9.1 API version: 1.21 Go version: go1.4.2 Git commit: a34a1d5 Built: Fri Nov 20 13:12:04 UTC 2015 OS/Arch: linux/amd64 Server: Version: swarm/1.0.1 API version: 1.21 Go version: go1.5.2 Git commit: 744e3a3 Built: OS/Arch: linux/amd64輸出中Server的版本顯示為 swarm/1.0.1說(shuō)明命令已成功發(fā)往 swarm manager。驗(yàn)證同一命令在不帶 TLS 時(shí)無(wú)法工作。這次不向 swarm manager 傳證書(shū)$ sudo docker -H swarm:3376 version : Version: 1.9.1 API version: 1.21 Go version: go1.4.2 Git commit: a34a1d5 Built: Fri Nov 20 13:12:04 UTC 2015 OS/Arch: linux/amd64 Get http://swarm:3376/v1.21/version: malformed HTTP response \x15\x03\x01\x00\x02\x02. * Are you trying to connect to a TLS-enabled daemon without TLS?輸出顯示命令被服務(wù)器拒絕。這是因?yàn)榉?wù)器swarm manager配置為只接受使用 TLS 的已認(rèn)證客戶端的連接。malformed HTTP response正是 TLS 握手失敗的典型特征客戶端用明文 HTTP 請(qǐng)求打到了一個(gè)只講 TLS 的端口上。源碼印證manager 通過(guò) api.Server 對(duì)外服務(wù)而 swarm manager 把來(lái)自客戶端的請(qǐng)求轉(zhuǎn)發(fā)給后端節(jié)點(diǎn)時(shí)同樣使用 TLS。在 cluster/engine.go 的Connect中NewHTTPClientTimeout(tcp://e.Addr, config, ...)會(huì)在配置了 TLS 時(shí)把 URL scheme 從http自動(dòng)切換為https見(jiàn) cluster/httpclient.go并把tlsConfig裝進(jìn)http.Transport此后 api/utils.go 的proxyAsync通過(guò)engine.HTTPClientAndScheme()取回這個(gè)帶 TLS 的客戶端完成對(duì)節(jié)點(diǎn)的反向代理。也就是說(shuō)無(wú)論manage是代理普通 API 調(diào)用如proxyContainer還是代理attach類長(zhǎng)連接hijack見(jiàn) api/handlers.go 中hijack(c.tlsConfig, ...)的調(diào)用TLS 配置都會(huì)貫穿 client → manager → node 的完整鏈路。Step 9: 配置 Engine CLI 使用 TLS你可以配置 Engine使每次執(zhí)行命令時(shí)無(wú)需再傳 TLS 參數(shù)。方法是在 Docker Engine 客戶端上把Docker Engine host與TLS設(shè)置配置為默認(rèn)值。具體做法把客戶端的密鑰放入~/.docker配置目錄。如果系統(tǒng)上有其他用戶使用 Engine 命令行也要配置他們的~/.docker。下面以 Docker Engine 客戶端上的ubuntu用戶為例。打開(kāi)client服務(wù)器的終端。如果不存在在ubuntu用戶主目錄創(chuàng)建.docker目錄$ mkdir /home/ubuntu/.docker把 Docker Engine 客戶端的密鑰從/home/ubuntu/.certs復(fù)制到/home/ubuntu/.docker$ cp /home/ubuntu/.certs/{ca,cert,key}.pem /home/ubuntu/.docker編輯該賬戶的~/.bash_profile。設(shè)置以下變量變量說(shuō)明DOCKER_HOST設(shè)置所有 Engine 命令要發(fā)送到的 Docker 主機(jī)與 TCP 端口。DOCKER_TLS_VERIFY告訴 Engine 使用 TLS。DOCKER_CERT_PATH指定 TLS 密鑰的位置。例如export DOCKER_HOSTtcp://swarm:3376 export DOCKER_TLS_VERIFY1 export DOCKER_CERT_PATH/home/ubuntu/.docker/保存并關(guān)閉文件。用source加載文件以拾取新變量$ source ~/.bash_profile執(zhí)行docker version驗(yàn)證配置生效$ docker version Client: Version: 1.9.1 API version: 1.21 Go version: go1.4.2 Git commit: a34a1d5 Built: Fri Nov 20 13:12:04 UTC 2015 OS/Arch: linux/amd64 Server: Version: swarm/1.0.1 API version: 1.21 Go version: go1.5.2 Git commit: 744e3a3 Built: OS/Arch: linux/amd64輸出中的服務(wù)器部分說(shuō)明你的 Docker 客戶端正在向 swarm manager 發(fā)送命令并使用 TLS。至此你已經(jīng)成功配置了一個(gè)使用 TLS 的 Docker swarm 集群。深入理解TLS 配置在 Swarm 源碼中的完整路徑結(jié)合前文九步實(shí)操?gòu)脑创a結(jié)構(gòu)可以梳理出 TLS 在 Docker Classic Swarm 中的完整作用鏈路參數(shù)解析與校驗(yàn)swarm manage的 TLS 相關(guān)命令行參數(shù)在 cli/flags.go 中定義為--tls、--tlscacert、--tlscert、--tlskey、--tlsverify五個(gè) flag。其中--tls的用法說(shuō)明是「use TLS; implied by --tlsverifytrue」--tlscacert被描述為「僅信任由此處給定 CA 簽名的證書(shū)的遠(yuǎn)端」。TLS 配置對(duì)象構(gòu)建manage函數(shù)在 cli/manage.go 完成上述校驗(yàn)后調(diào)用loadTLSConfigcli/manage.go構(gòu)建*tls.Config加載cert/key密鑰對(duì)設(shè)置最低 TLS 版本為 TLS 1.2--tlsverify開(kāi)啟時(shí)加載 CA 證書(shū)池并要求客戶端證書(shū)RequireAndVerifyClientCert未開(kāi)啟校驗(yàn)時(shí)則InsecureSkipVerify true。對(duì)外服務(wù)端manager 自身tlsConfig傳入 api.NewServerListenAndServe在 newListener 中用tls.NewListener包裝 TCP 監(jiān)聽(tīng)器使 manager 對(duì)外只接受 TLS 連接如0.0.0.0:3376。對(duì)內(nèi)連接端manager → 節(jié)點(diǎn)同一份tlsConfig傳入 swarm.NewCluster存入Cluster.TLSConfig節(jié)點(diǎn)經(jīng)發(fā)現(xiàn)服務(wù)注冊(cè)后validatePendingEngine調(diào)用engine.Connect(c.TLSConfig)cluster/swarm/cluster.go。Connect中NewHTTPClientTimeout會(huì)根據(jù)tlsConfig是否存在把節(jié)點(diǎn) URL 切換為httpscluster/httpclient.go隨后的所有 API 代理api/utils.go與 attach/hijack 長(zhǎng)連接api/handlers.go、api/utils.go都復(fù)用這份 TLS 配置。由此可見(jiàn)一份tlsConfig同時(shí)支撐了「客戶端 → swarm manager」與「swarm manager → 節(jié)點(diǎn) daemon」兩段加密鏈路這也是文檔要求同時(shí)在 manager 與節(jié)點(diǎn)上安裝ca.pem、cert.pem、key.pem三件套的根本原因。相關(guān)文檔Secure Docker Swarm with TLS本文理論基礎(chǔ)篇Configure Docker Swarm for TLS九步實(shí)操完整版Plan for Swarm in production生產(chǎn)環(huán)境端口規(guī)劃與網(wǎng)絡(luò)訪問(wèn)控制贊分享云原生后端微服務(wù)【免費(fèi)下載鏈接】classicswarmSwarm Classic: a container clustering system. Not to be confused with Docker Swarm which is at https://github.com/docker/swarmkit項(xiàng)目地址https://gitcode.com/gh_mirrors/cl/classicswarm點(diǎn)擊查看免費(fèi)下載相關(guān)推薦Docker Classic Swarm 配置 TLS基于 OpenSSL 自建 CA 的集群安全加固實(shí)戰(zhàn)Docker Classic Swarm 配置 TLS基于 OpenSSL 自建 CA 的集群安全加固實(shí)戰(zhàn) 本篇基于 docs/configure tls.m云原生后端微服務(wù)終極Docker Swarm TLS安全配置指南構(gòu)建企業(yè)級(jí)安全集群的完整教程 終極Docker Swarm TLS安全配置指南構(gòu)建企業(yè)級(jí)安全集群的完整教程 Docker Swarm是Docker官方提供的原生容器編排工具而TLS云原生后端微服務(wù)Docker OpenLDAP 安全最佳實(shí)踐TLS配置與證書(shū)管理Docker OpenLDAP 安全最佳實(shí)踐TLS配置與證書(shū)管理 在當(dāng)今企業(yè)級(jí)應(yīng)用中Docker OpenLDAP 已成為輕量級(jí)目錄服務(wù)的首選解決方案。然而上一篇jina-embedding-s-en-v1在聚類任務(wù)中的應(yīng)用Arxiv論文主題自動(dòng)分組實(shí)踐下一篇Foundation for Emails中的ZURB Stack技術(shù)棧解析創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考