1. 程式人生 > >Kubernetes 最佳實踐:映射外部服務

Kubernetes 最佳實踐:映射外部服務

password googl 最終 重構 選擇 spec 差異 計算 簡單

文 / 開發技術推廣工程師 Sandeep Dinesh

大多數 Kubernetes 用戶都有可能用到集群外部的服務。例如,您可能使用 Twillio API 發送短信,或使用 Google Cloud Vision API 進行圖像分析。

如果位於不同環境中的應用連接相同的外部端點,並且您不打算將外部服務引入 Kubernetes 集群,那麽在代碼中直接使用外部服務端點是完全可以的。然而,很多時候情況並非如此。

數據庫就是一個很好的例子。雖然一些雲原生數據庫(如 Cloud Firestore 或 Cloud Spanner)對所有訪問均使用一個端點,但大多數數據庫對不同實例都有單獨的端點。

說到這裏,您可能會認為,就查找端點而言,ConfigMap 是個不錯的解決方案。只需將端點地址存儲在 ConfigMap 中,並將其作為環境變量用於代碼中。此解決方案的確有效,但也存在一些缺點。您需要修改部署以包含 ConfigMap 並編寫額外的代碼以從環境變量中讀取。但最重要的是,如果端點地址發生變化,您可能需要重啟所有正在運行的容器以獲取更新後的端點地址。

在本集的 “Kubernetes 最佳實踐” 中,我們會學習如何將 Kubernetes 內置服務發現機制運用於集群外部運行的服務,像使用集群內的服務一樣使用外部服務!通過這種方式,您可以在開發環境和生產環境中實現相同的功能,如果您最終將服務移入集群內,則不需要更改任何代碼。

技術分享圖片

場景 1:具有 IP 地址的集群外數據庫

其中一個常見場景是在集群外部托管自己的數據庫,例如在 Google 計算引擎實例中。如果您在 Kubernetes 內部和外部分別運行一些服務,或者需要在 Kubernetes 允許的基礎上獲得更多定制或控制,通常可采用上述這種方式。

希望未來某個時候您可以將所有服務都移入集群內,但在此之前將是“內外混用”的狀態。幸運的是,您可以使用靜態 Kubernetes 服務來緩解上述痛點。

在本例中,我使用 Cloud Launcher 創建了一個 MongoDB 服務器。由於此服務器在與 Kubernetes 集群相同的網絡(或 VPC)中創建,因此可以使用高性能的內部 IP 地址訪問。在 Google Cloud 中,這是默認設置,因此無需進行任何特殊配置。

技術分享圖片

現在我們有了 IP 地址,那麽第一步就是創建服務:

kind: Service

apiVersion: v1

metadata:

?name: mongo

Spec:

?type: ClusterIP

?ports:

?- port: 27017

? ?targetPort:?27017

您可能會註意到此服務沒有 Pod 選擇器。此操作將創建一個服務,但它不知道往哪裏發送流量。這樣一來,您可以手動創建一個將從此服務接收流量的 Endpoints 對象。

kind: Endpoints

apiVersion: v1

metadata:

?name: mongo

subsets:

?- addresses:

? ? ?- ip: 10.240.0.4

? ?ports:

? ? ?- port: 27017

您可以看到 Endpoints 手動定義了數據庫的 IP 地址,並且使用的名稱與服務名稱相同。Kubernetes 將 Endpoints 中定義的所有 IP 地址視為與常規 Kubernetes Pod 一樣。現在您可以用一個簡單的連接字符串訪問數據庫:

mongodb://mongo

> 根本不需要在代碼中使用 IP 地址!如果以後 IP 地址發生變化,您可以為端點更新 IP 地址,而應用無需進行任何更改。

場景 2:具有 URI 的遠程托管數據庫

如果您使用的是來自第三方的托管數據庫服務,它們可能會為您提供可用於連接的統一資源標識符 (URI)。如果它們為您提供 IP 地址,則可以使用場景 1 中的方法。

在本例中,我在 mLab 上托管了兩個 MongoDB 數據庫。一個是我的開發數據庫,另一個是生產數據庫。

技術分享圖片

這些數據庫的連接字符串如下所示:

mongodb://<dbuser>:<dbpassword>@ds149763.mlab.com:49763/devmongodb://<dbuser>:<dbpassword>@ds145868.mlab.com:45868/prodmLab?

為您提供了動態 URI 和動態端口,您可以看到兩者都不同。我們來使用 Kubernetes 基於這些差異創建一個抽象層。在本例中,我們將連接開發數據庫。

您可以創建一個 “ExternalName” Kubernetes 服務,此服務為您提供將流量重定向到外部服務的靜態 Kubernetes 服務。此服務在內核級別執行簡單的 CNAME 重定向,因此對性能的影響非常小。

服務的 YAML 如下所示:

kind: Service

apiVersion: v1

metadata:

?name: mongo

spec:

?type: ExternalName

?externalName: ds149763.mlab.com

現在,您可以使用更簡化的連接字符串:

mongodb://<dbuser>:<dbpassword>@mongo:<port>/dev

由於 “ExternalName” 使用 CNAME 重定向,因此無法執行端口重映射。對於使用靜態端口的服務來說,這可能不成問題,然而本例中使用的是動態端口。mLab 免費版為您提供了動態端口號,並且不允許更改。這意味著您需要對開發和生產數據庫使用其他連接字符串。

但如果您可以獲取 IP 地址,就可以執行端口重映射,關於此內容,我將在下一部分進行介紹。

場景 3:具有 URI 和端口重映射功能的遠程托管數據庫

CNAME 重定向對於每個環境均使用相同端口的服務非常有效,但如果每個環境的不同端點使用不同的端口,CNAME 重定向就略顯不足。幸運的是我們可以使用一些基本工具來解決這個問題。

第一步是從 URI 獲取 IP 地址。

對 URI 運行 nslookup、hostname 或 ping 命令即可獲取數據庫的 IP 地址。

技術分享圖片

您現在可以創建一個重新映射 mLab 端口的服務,並為此 IP 地址創建端點。

kind: Service

apiVersion: v1

metadata:

?name: mongo

spec:

?ports:

?- port: 27017

? ?targetPort: 49763

---

kind: Endpoints

apiVersion: v1

metadata:

?name: mongo

subsets:

?- addresses:

? ? ?- ip: 35.188.8.12

? ?ports:

? ? ?- port: 49763

註:URI 可以使用 DNS 在多個 IP 地址之間進行負載平衡,因此,如果 IP 地址發生變化,這個方法可能會有風險!如果您通過上述命令獲取多個 IP 地址,則可以將所有這些地址都包含在 Endpoints YAML 中,並且 Kubernetes 會在所有 IP 地址之間進行流量的負載平衡。

通過這種方式,您無需指定端口即可連接到遠程數據庫。Kubernetes 老年服飾服務重映射端口的過程完全透明!

mongodb://<dbuser>:<dbpassword>@mongo/dev

結論

將外部服務映射到內部服務可讓您未來靈活地將這些服務納入集群,同時最大限度地減少重構工作。即使您今天不打算將服務加入集群,以後可能也會這樣做!而且,這樣一來,您可以更輕松地管理和了解組織所使用的外部服務。

如果外部服務具有有效域名,並且您不需要重新映射端口,那麽使用 “ExternalName” 服務類型將外部服務映射到內部服務十分簡便、快捷。如果您沒有域名或需要執行端口重映射,只需將 IP 地址添加到端點並使用即可。

更多 AI 相關閱讀:

·?通過安全瀏覽保護 WebView

·?通過視頻著色進行自監督跟蹤

·?通過機器學習讓醫療數據更好用


文章來源:https://blog.csdn.net/jILRvRTrc/article/details/81117261

Kubernetes 最佳實踐:映射外部服務