本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
使用 Kubernetes Device Plugins 和 RuntimeClass 在 Ingress 控制器中實現硬體加速的 SSL/TLS 終止
摘要
Kubernetes Ingress 是一種將叢集服務連線到叢集外部世界的方式。為了正確地將流量路由到服務後端,叢集需要一個 Ingress 控制器。Ingress 控制器負責根據 Ingress API 物件的 S資訊為後端設定正確的目的地。實際流量透過代理伺服器路由,代理伺服器負責負載均衡和 SSL/TLS 終止(下文“SSL”指 SSL 或 TLS)。由於涉及加密操作,SSL 終止是 CPU 密集型操作。為了將一些 CPU 密集型工作從 CPU 中解除安裝,基於 OpenSSL 的代理伺服器可以利用 OpenSSL Engine API 和專用加密硬體。這可以釋放 CPU 週期用於其他任務,並提高代理伺服器的整體吞吐量。
在這篇博文中,我們將展示如何使用最近建立的一些 Kubernetes 構建塊(裝置外掛框架和 RuntimeClass)輕鬆地為執行 Ingress 控制器代理的容器提供硬體加速加密。最後,將給出一個使用 HAProxy 기반 Ingress 控制器並使用 Intel® QuickAssist Technology 卡進行加速的參考設定。
關於代理、OpenSSL Engine 和加密硬體
代理伺服器在 Kubernetes Ingress Controller 功能中扮演著至關重要的角色。它根據 Ingress 物件的路由將流量代理到後端。在繁重的流量負載下,效能變得至關重要,特別是當代理涉及 CPU 密集型操作(如 SSL 加密)時。
OpenSSL 專案提供了廣泛採用的庫來實現 SSL 協議。在 Kubernetes Ingress 控制器常用的代理伺服器中,Nginx 和 HAProxy 使用 OpenSSL。CNCF 畢業的 Envoy 代理使用 BoringSSL,但社群似乎對將 OpenSSL 作為其替代方案感興趣,詳見此處。
OpenSSL SSL 協議庫依賴於實現加密功能的 libcrypto。OpenSSL 提供了一個 ENGINE 概念(首次在 0.9.6 版本中引入)已經有一段時間了,它允許將這些加密操作解除安裝到專用加密加速硬體。後來,一個特殊的 *動態* ENGINE 使加密硬體的特定部分可以在獨立的可載入模組中實現,該模組可以在 OpenSSL 程式碼庫之外開發並單獨分發。從應用程式的角度來看,這也是理想的,因為它們不需要知道如何使用硬體的細節,並且當硬體可用時,硬體特定的模組可以被載入/使用。
正如所討論的,基於硬體的加密可以極大地提高雲應用程式的效能,因為它在 SSL 操作中實現了硬體加速處理,並且還可以提供其他加密服務,如金鑰/隨機數生成。雲可以使用動態 ENGINE 輕鬆提供硬體,並且存在多個可載入模組實現,例如 CloudHSM、IBMCA 或 QAT Engine。
對於雲部署,理想的情況是將這些模組作為容器工作負載的一部分進行交付。工作負載將在提供模組所需底層硬體的節點上進行排程。另一方面,無論加密加速硬體是否可用,工作負載都應以相同的方式執行,無需修改程式碼。OpenSSL 動態引擎實現了這一點。下圖 1 使用典型的 Ingress Controller 容器作為示例說明了這兩種情況。紅色框表示啟用加密硬體引擎的容器與“標準”容器之間的差異。值得指出的是,所顯示的配置更改不一定需要另一個版本的容器,因為配置可以透過 ConfigMaps 等方式進行管理。

圖 1. Ingress 控制器容器示例
硬體資源和隔離
為了部署具有硬體依賴性的工作負載,Kubernetes 提供了出色的擴充套件和可配置機制。讓我們更深入地瞭解 Kubernetes 裝置外掛框架(1.14 中的 Beta 版)和 RuntimeClass(1.14 中的 Beta 版),並瞭解如何利用它們將加密硬體暴露給工作負載。
裝置外掛框架最初在 Kubernetes 1.8 中引入,它為硬體供應商提供了一種將節點硬體資源註冊和分配給 Kubelet 的方式。外掛實現硬體特定的初始化邏輯和資源管理。Pod 可以在其 PodSpec 中請求硬體資源,這也可以保證 Pod 在能夠提供這些資源的節點上進行排程。
容器的裝置資源分配並非易事。對於處理安全性的應用程式來說,硬體級別隔離至關重要。基於 PCIe 的加密加速裝置功能可以透過 I/O 記憶體管理單元 (IOMMU) 實現 IO 硬體虛擬化,從而提供隔離:裝置所屬的 *IOMMU 組* 為工作負載提供隔離資源(假設加密卡不與其他裝置共享 IOMMU 組)。如果 PCIe 裝置支援單根 I/O 虛擬化 (SR-IOV) 規範,則可以進一步增加隔離資源的數量。SR-IOV 允許 PCIe 裝置進一步拆分為 *虛擬功能* (VF),這些虛擬功能源自 *物理功能* (PF) 裝置,並且每個功能都屬於自己的 IOMMU 組。為了將這些 IOMMU 隔離的裝置功能暴露給使用者空間和容器,主機核心應將它們繫結到特定的裝置驅動程式。在 Linux 中,此驅動程式是 vfio-pci,它透過使用者空間中的字元裝置使每個裝置可用。核心 vfio-pci 驅動程式使用一種稱為 *PCI 直通* 的機制,為使用者空間應用程式提供對 PCIe 裝置和功能的直接、IOMMU 支援的訪問。該介面可以被使用者空間框架(例如資料平面開發套件 (DPDK))利用。此外,虛擬機器 (VM) 管理程式可以將這些使用者空間裝置節點提供給 VM,並將它們作為 PCI 裝置暴露給來賓核心。假設來賓核心提供支援,VM 可以獲得接近原生效能的直接訪問底層主機裝置。
為了向 Kubernetes 宣傳這些裝置資源,我們可以有一個簡單的 Kubernetes 裝置外掛,它執行初始化(即繫結),呼叫 kubelet 的 `Registration` gRPC 服務,並實現 kubelet 呼叫以在 Pod 建立時 `Allocate` 資源等的 DevicePlugin gRPC 服務。
裝置分配與 Pod 部署
此時,您可能會問容器可以使用 VFIO 裝置節點做什麼?答案將在我們快速瞭解 Kubernetes RuntimeClass 之後揭曉。
Kubernetes RuntimeClass 的建立旨在更好地控制和配置叢集中各種 *執行時* (早期的部落格文章詳細介紹了其需求、狀態和路線圖)。本質上,RuntimeClass 為叢集使用者提供了更好的工具來選擇和使用最適合 Pod 用例的執行時。
OCI 相容的 Kata 容器執行時為工作負載提供硬體虛擬化隔離層。除了工作負載隔離之外,Kata 容器虛擬機器還有一個額外的優勢,即裝置外掛 `Allocate` 的 VFIO 裝置可以作為硬體隔離裝置直通給容器。唯一的要求是 Kata 容器核心必須啟用暴露裝置的驅動程式。
這就是為容器工作負載啟用硬體加速加密所需要的一切。總結如下:
- 叢集需要一個裝置外掛,執行在提供硬體的節點上
- 裝置外掛使用 VFIO 驅動程式將硬體暴露給使用者空間
- Pod 在 PodSpec 中請求裝置資源和 Kata Containers 作為 RuntimeClass
- 容器包含硬體適配庫和 OpenSSL 引擎模組
圖 2 顯示了使用前面示例中容器 A 的整體設定。

圖 2. 部署概覽
參考設定
最後,我們描述了構建圖 2 中功能設定所需的構建塊和步驟,該設定使用 Intel® QuickAssist Technology (QAT) PCIe 裝置在 Ingress 控制器中實現硬體加速 SSL 終止。需要注意的是,用例不僅限於 Ingress 控制器,任何基於 OpenSSL 的工作負載都可以加速。
叢集配置
- Kubernetes 1.14(已啟用 `RuntimeClass` 和 `DevicePlugin` 特性門控(在 1.14 中均為 `true`))
- RuntimeClass 就緒執行時和 Kata 容器已配置
主機配置
- 已安裝 QAT 裝置驅動程式版本,用於主機核心和 Kata 容器核心(或作為可載入模組安裝在根檔案系統上)
- QAT 裝置外掛 DaemonSet 已部署
Ingress 控制器配置和部署
- HAproxy-ingress Ingress 控制器在一個修改過的容器中,該容器具有
- QAT 硬體 HAL 使用者空間庫(Intel® QAT 軟體版本的一部分)和
- 內建的 OpenSSL QAT 引擎
- Haproxy-ingress ConfigMap 用於啟用 QAT 引擎使用
ssl-engine=”qat”
ssl-mode-async=true
- Haproxy-ingress 部署 `yaml` 檔案用於
- 請求 `qat.intel.com: n` 資源
- 請求 `runtimeClassName: kata-containers` (名稱值取決於叢集配置)
- (容器中為每個請求的裝置資源提供已配置 OpenSSL 引擎的 QAT 裝置配置檔案)
一旦構建塊可用,可以透過遵循 TLS 終止示例步驟來測試硬體加速的 SSL/TLS。為了驗證硬體是否被使用,您可以檢查主機上的 `/sys/kernel/debug/*/fw_counters` 檔案,因為它們會透過 Intel® QAT 韌體進行更新。
使用 Haproxy-ingress 和 HAProxy 是因為 HAProxy 可以直接配置為使用 OpenSSL 引擎,只需使用 `ssl-engine
行動呼籲
在這篇博文中,我們展示瞭如何使用 Kubernetes 裝置外掛和 RuntimeClass 為 Pod 中的應用程式提供隔離的硬體訪問,以將加密操作解除安裝到硬體加速器。硬體加速器可用於加速加密操作,併為其他任務節省 CPU 週期。我們使用 HAProxy 演示了該設定,HAProxy 已經支援使用 OpenSSL 進行非同步加密解除安裝。
我們團隊的下一步工作是為 Envoy 重複同樣的操作(使用基於 OpenSSL 的 TLS 傳輸套接字作為擴充套件)。此外,我們正在努力增強 Envoy,使其能夠將 BoringSSL 非同步私鑰操作解除安裝到加密加速硬體。歡迎任何評審反饋或幫助!
當將加密處理解除安裝到專用加速器時,您的加密應用程式可以為其他任務節省多少 CPU 週期?