本文已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

在 Ingress 控制器中使用 Kubernetes 裝置外掛程式和 RuntimeClass 的硬體加速 SSL/TLS 終止

摘要

Kubernetes Ingress 是一種將叢集服務連接到叢集外部世界的方式。為了正確地將流量路由到服務後端,叢集需要 Ingress 控制器。Ingress 控制器負責根據 Ingress API 物件的資訊設定正確的後端目的地。實際的流量通過代理伺服器路由,該伺服器負責負載平衡和 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,libcrypto 實作了加密功能。在相當長的一段時間裡(首次在 0.9.6 版本中引入),OpenSSL 提供了一個 ENGINE 概念,允許將這些加密操作卸載到專用的加密加速硬體。稍後,一個特殊的動態 ENGINE 啟用了加密硬體特定的部分,使其可以在獨立的可載入模組中實作,該模組可以在 OpenSSL 程式碼庫之外開發並單獨發布。從應用程式的角度來看,這也是理想的,因為它們不需要知道如何使用硬體的細節,並且當硬體可用時,可以載入/使用硬體特定的模組。

由於 SSL 操作中的硬體加速處理(如討論),基於硬體的加密可以極大地提高雲端應用程式的效能,並且可以提供其他加密服務,如金鑰/隨機數生成。雲端可以使用動態 ENGINE 輕鬆地提供硬體,並且存在幾個可載入模組實作,例如 CloudHSMIBMCAQAT Engine

對於雲端部署,理想的場景是將這些模組作為容器工作負載的一部分發布。工作負載將排程在提供模組需要存取的底層硬體的節點上。另一方面,工作負載應以相同的方式運行,並且無論加密加速硬體是否可用,都無需修改程式碼。OpenSSL 動態引擎啟用了這一點。下面的圖 1 說明了這兩種場景,以典型的 Ingress Controller 容器為例。紅色方框表示啟用加密硬體引擎的容器與 “標準” 容器之間的差異。值得指出的是,顯示的配置更改不一定需要另一個版本的容器,因為可以使用 ConfigMaps 等方式管理配置。

Figure 1. Examples of Ingress controller containers

圖 1. Ingress 控制器容器範例

硬體資源和隔離

為了能夠部署具有硬體依賴性的工作負載,Kubernetes 提供了出色的擴展和可配置性機制。讓我們更仔細地看看 Kubernetes 的 裝置外掛程式框架(1.14 版為 beta)和 RuntimeClass(1.14 版為 beta),並了解如何利用它們將加密硬體公開給工作負載。

裝置外掛程式框架最初在 Kubernetes 1.8 中引入,為硬體供應商提供了一種註冊和分配節點硬體資源給 Kubelet 的方法。外掛程式實作了硬體特定的初始化邏輯和資源管理。Pod 可以在其 PodSpec 中請求硬體資源,這也保證了 Pod 被排程在可以提供這些資源的節點上。

容器的裝置資源分配並非易事。對於處理安全性的應用程式,硬體層級的隔離至關重要。基於 PCIe 的加密加速裝置功能可以受益於 IO 硬體虛擬化,透過 I/O 記憶體管理單元 (IOMMU) 來提供隔離:裝置所屬的 IOMMU 群組 為工作負載提供隔離的資源(假設加密卡不與其他裝置共用 IOMMU 群組)。如果 PCIe 裝置支援單根 I/O 虛擬化 (SR-IOV) 規範,則可以進一步增加隔離資源的數量。SR-IOV 允許 PCIe 裝置進一步拆分為從 物理功能 (PF) 裝置派生的虛擬功能 (VF),並且每個虛擬功能都屬於自己的 IOMMU 群組。為了將這些 IOMMU 隔離的裝置功能公開給使用者空間和容器,主機核心應將它們綁定到特定的裝置驅動程式。在 Linux 中,此驅動程式是 vfio-pci,它透過使用者空間中的字元裝置使每個裝置可用。核心 vfio-pci 驅動程式為使用者空間應用程式提供對 PCIe 裝置和功能的直接、IOMMU 支援的存取,使用稱為 PCI passthrough 的機制。使用者空間框架(例如資料平面開發套件 (DPDK))可以利用此介面。此外,虛擬機器 (VM) 監控程式可以將這些使用者空間裝置節點提供給 VM,並將它們作為 PCI 裝置公開給客體核心。假設客體核心支援,VM 可以近乎原生效能地直接存取底層主機裝置。

為了將這些裝置資源廣告給 Kubernetes,我們可以有一個簡單的 Kubernetes 裝置外掛程式,它運行初始化(即綁定),呼叫 kubelet 的 Registration gRPC 服務,並實作 DevicePlugin gRPC 服務,kubelet 呼叫該服務,例如,在 Pod 建立時 Allocate 資源。

裝置分配和 Pod 部署

此時,您可能會問容器可以使用 VFIO 裝置節點做什麼?答案在我們首先快速了解 Kubernetes RuntimeClass 後揭曉。

建立 Kubernetes RuntimeClass 是為了更好地控制和配置叢集中可用的各種執行時(早期的 部落格文章 詳細介紹了它的需求、狀態和藍圖)。本質上,RuntimeClass 為叢集使用者提供了更好的工具,可以選擇和使用最適合 Pod 用例的執行時。

OCI 相容的 Kata Containers 執行時 為工作負載提供了硬體虛擬化的隔離層。除了工作負載隔離之外,Kata Containers VM 還具有額外的附帶好處,即裝置外掛程式 Allocate 的 VFIO 裝置可以作為硬體隔離裝置傳遞到容器。唯一的要求是 Kata Containers 核心具有為公開裝置啟用的驅動程式。

這就是為容器工作負載啟用硬體加速加密所需的全部工作。總結一下

  1. 叢集需要在提供硬體的節點上運行裝置外掛程式
  2. 裝置外掛程式使用 VFIO 驅動程式將硬體公開給使用者空間
  3. Pod 在 PodSpec 中請求裝置資源和 Kata Containers 作為 RuntimeClass
  4. 容器具有硬體適配程式庫和 OpenSSL 引擎模組

圖 2 顯示了使用先前說明的容器 A 的整體設定。

Figure 2. Deployment overview

圖 2. 部署概述

參考設定

最後,我們描述了在圖 2 中建立功能設定的必要建構區塊和步驟,該設定可在 Ingress Controller 中使用 Intel® QuickAssist Technology (QAT) PCIe 裝置啟用硬體加速 SSL 終止。應注意,用例不限於 Ingress 控制器,而是可以加速任何基於 OpenSSL 的工作負載。

叢集配置

  • Kubernetes 1.14(RuntimeClassDevicePlugin 功能閘道已啟用(在 1.14 中均為 true))
  • RuntimeClass 就緒執行時和 Kata Containers 已配置

主機配置

  • Intel® QAT 驅動程式發布,其中為主機核心和 Kata Containers 核心安裝了核心驅動程式(或作為可載入模組在 rootfs 上)
  • QAT 裝置外掛程式 DaemonSet 已部署

Ingress 控制器配置和部署

  • HAproxy-ingress ingress 控制器在修改後的容器中,該容器具有
    • QAT HW HAL 使用者空間程式庫(Intel® QAT SW 發布的一部分)和
    • 內建 OpenSSL QAT Engine
  • Haproxy-ingress ConfigMap 以啟用 QAT 引擎使用
    • ssl-engine=”qat”
    • ssl-mode-async=true
  • Haproxy-ingress 部署 .yaml
    • 請求 qat.intel.com: n 資源
    • 請求 runtimeClassName: kata-containers(名稱值取決於叢集配置)
  • (每個請求的裝置資源的 QAT 裝置配置文件,其中配置了 OpenSSL 引擎,可在容器中使用)

一旦建構區塊可用,就可以按照 TLS 終止範例 步驟來測試硬體加速的 SSL/TLS。為了驗證是否使用了硬體,您可以檢查主機上的 /sys/kernel/debug/*/fw_counters 檔案,因為它們會被 Intel® QAT 韌體更新。

之所以使用 Haproxy-ingress 和 HAproxy,是因為 HAproxy 可以直接配置為使用 OpenSSL 引擎,方法是使用 ssl-engine <name> [algo ALGOs] 配置標誌,而無需修改全域 openssl 配置文件。此外,HAproxy 可以使用異步呼叫 (使用 ssl-mode-async) 卸載配置的演算法,以進一步提高效能。

行動呼籲

在這篇部落格文章中,我們展示了如何使用 Kubernetes Device Plugins 和 RuntimeClass 為 Pod 中的應用程式提供隔離的硬體存取,以將加密操作卸載到硬體加速器。硬體加速器可用於加速加密操作,還可以為其他任務節省 CPU 週期。我們示範了使用 HAproxy 的設定,HAproxy 已經支援使用 OpenSSL 進行異步加密卸載。

我們團隊的下一步是對 Envoy 重複相同的操作(使用基於 OpenSSL 的 TLS 傳輸套接字作為擴展)。此外,我們正在努力增強 Envoy,使其能夠將 BoringSSL 異步私鑰操作 卸載到加密加速硬體。歡迎任何評論意見或幫助!

當將加密處理卸載到專用加速器時,您的加密應用程式可以為其他任務節省多少 CPU 週期?