使用Kubernetes設備插件和RuntimeClass在入口控制器中實現硬體加速SSL/TLS終止

  • 2019 年 12 月 4 日
  • 筆記

作者:Mikko Ylinan(英特爾)

摘要

Kubernetes入口(Ingress)是一種將集群服務連接到集群外部的方法。為了正確地將流量路由到服務後端,集群需要一個入口控制器。Ingress控制器負責根據Ingress API對象的資訊為後端設置正確的目的地。實際流量通過代理伺服器路由,代理伺服器負責諸如負載平衡和SSL/TLS(稍後的「SSL」指SSL或TLS)終止等任務。由於涉及加密操作,SSL終止是一個CPU密集型操作。為了從CPU中卸載一些CPU密集型工作,基於OpenSSL的代理伺服器可以利用OpenSSL引擎API和專用加密硬體的優勢。這將為其他事情釋放CPU周期,並提高代理伺服器的總體吞吐量。

在這篇部落格文章中,我們將展示使用最近創建的Kubernetes構建塊(設備插件框架和RuntimeClass)為運行Ingress控制器代理的容器提供硬體加速加密是多麼容易。最後,給出了一個參考設置使用基於HAproxy的入口控制器加速使用英特爾®QuickAssist技術卡。

關於代理、OpenSSL引擎和加密硬體

代理伺服器在Kubernetes入口控制器功能中起著至關重要的作用。它將流量代理到每個入口對象路由的後端。在高流量負載下,性能變得至關重要,特別是當代理涉及到諸如SSL加密之類的CPU密集型操作時。

OpenSSL項目為實現SSL協議提供了廣泛採用的庫。Kubernetes入口控制器使用的常用代理伺服器中,Nginx和HAproxy使用OpenSSL。CNCF畢業項目Envoy使用BoringSSL,但是社區似乎也有興趣使用OpenSSL作為替代。

https://github.com/envoyproxy/envoy/pull/5161#issuecomment-446374130

OpenSSL SSL協議庫依賴於實現加密功能的libcrypto。很長一段時間以來(在0.9.6版本中首次引入),OpenSSL提供了一個引擎概念,允許將這些加密操作卸載到專用的加密加速硬體。後來,一個特殊的動態引擎使加密硬體的特定部分能夠在一個獨立的可載入模組中實現,該模組可以在OpenSSL程式碼庫之外開發並單獨分發。從應用程式的角度來看,這也是理想的,因為他們不需要知道如何使用硬體的細節,並且當硬體可用時,可以載入/使用特定於硬體的模組。

https://github.com/openssl/openssl/blob/master/README.ENGINE

如前所述,由於SSL操作中的硬體加速處理,基於硬體的加密可以極大地提高雲應用程式的性能,並且可以提供密鑰/隨機數生成等其他加密服務。雲可以使用動態引擎輕鬆地提供硬體,並且存在幾種可載入模組實現,例如CloudHSM、IBMCA或QAT引擎。

對於雲部署,理想的場景是將這些模組作為容器工作負載的一部分交付。工作負載將在提供模組需要訪問的底層硬體的節點上調度。另一方面,不管加密加速硬體是否可用,工作負載都應該以相同的方式運行,並且不需要修改程式碼。OpenSSL動態引擎支援這一點。下面的圖1以一個典型的Ingress Controller容器為例說明了這兩個場景。紅色的框表示啟用了加密硬體引擎的容器與「標準」容器之間的區別。值得指出的是,所顯示的配置更改並不一定需要容器的另一個版本,因為配置可以被管理,例如,使用ConfigMaps。

圖1. 入口控制器容器的例子

硬體資源和隔離

為了能夠部署具有硬體依賴關係的工作負載,Kubernetes提供了優秀的擴展和可配置機制。讓我們進一步研究Kubernetes設備插件框架(beta 1.14)和RuntimeClass (beta 1.14),並了解如何利用它們向工作負載暴露加密硬體。

在Kubernetes 1.8中首次引入的設備插件框架為硬體供應商提供了一種向Kubelets註冊和分配節點硬體資源的方法。插件實現了特定於硬體的初始化邏輯和資源管理。這些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驅動程式使用一種稱為PCI透傳(passthrough)的機制,為用戶空間應用程式提供了對PCIe設備和函數的直接、IOMMU支援的訪問。用戶空間框架,如數據平面開發工具包(Data Plane Development Kit,DPDK)可以利用該介面。此外,虛擬機(VM)管理程式可以向VM提供這些用戶空間設備節點,並將它們作為PCI設備暴露給客戶內核。假設有來自客戶內核的支援,VM將接近於直接訪問底層主機設備的本機性能。

為了向Kubernetes宣傳這些設備資源,我們可以使用一個簡單的Kubernetes設備插件來運行初始化(綁定),調用kublet的註冊(Registration)gRPC服務,並實現kublet調用的DevicePlugin gRPC服務,例如,在Pod創建時分配(Allocate)資源。

設備分配和Pod部署

此時,你可能會問容器可以使用VFIO設備節點做什麼?我們首先快速查看Kubernetes RuntimeClass之後,答案會出現。

創建Kubernetes RuntimeClass是為了對集群中可用的各種運行時提供更好的控制和可配置性(前面的一篇部落格文章詳細介紹了它的需求、狀態和路線圖)。本質上,RuntimeClass為集群用戶提供了更好的工具來選擇和使用最適合pod用例的運行時。

https://kubernetes.io/blog/2018/10/10/kubernetes-v1.12-introducing-runtimeclass/

OCI兼容的Kata容器運行時為工作負載提供了一個硬體虛擬化隔離層。除了工作負載隔離之外,Kata容器VM還有一個額外的好處,即VFIO設備,由設備插件分配(Allocate』d),可以作為硬體隔離設備傳遞給容器。惟一的要求是,Kata容器內核啟用了暴露設備的驅動程式。

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

  • 集群需要在提供硬體的節點上運行一個設備插件
  • 設備插件使用VFIO驅動程式向用戶空間暴露硬體
  • Pod請求設備資源和Kata容器作為PodSpec中的RuntimeClass
  • 該容器具有硬體適配庫和OpenSSL引擎模組

圖2顯示了使用前面演示的容器的總體設置。

圖2. 部署概述

參考設置

最後,我們描述構建圖2中描述的功能設置所需的構建塊和步驟,該功能設置使用Intel® QuickAssist技術(QAT) PCIe設備在入口控制器中啟用硬體加速SSL終止。應該注意的是,用例並不局限於Ingress控制器,任何基於OpenSSL的工作負載都可以加速。

集群配置:

  • Kubernetes 1.14(RuntimeClass和DevicePlugin特性門已啟用(兩者在1.14中都是true)
  • 配置了RuntimeClass就緒運行時和Kata容器

主機配置:

  • Intel® QAT驅動程式發行版,內核驅動程式同時安裝在主機內核和Kata容器內核(或在rootfs上作為可載入模組)
  • 已部署QAT設備插件DaemonSet

入口控制器配置和部署:

  • 一個修改後的HAproxy-ingress入口控制器的容器
    • QAT HW HAL用戶空間庫(Intel® QAT SW發行版的一部分)和
    • 內置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_counter文件,它們會由Intel® QAT韌體更新。

https://github.com/jcmoraisjr/haproxy-ingress/tree/master/examples/tls-termination

使用HAproxy-ingress和HAproxy,是因為可以使用ssl-engine <name> [algo ALGOs]配置標誌直接配置HAproxy來使用OpenSSL引擎,而無需修改全局OpenSSL配置文件。此外,HAproxy可以使用非同步調用(使用ssl-mode-async)卸載已配置的演算法,以進一步提高性能。

行動呼籲

在這篇部落格文章中,我們展示了Kubernetes設備插件和RuntimeClass如何為pod中的應用程式提供隔離的硬體訪問,以便將加密操作卸載給硬體加速器。硬體加速器可以用來加速加密操作,並將CPU周期節省到其他任務。我們演示了使用HAproxy的設置,它已經支援OpenSSL中的非同步加密卸載。

我們團隊的下一步是對Envoy重複相同的步驟(使用一個基於OpenSSL的TLS傳輸套接字作為擴展構建)。此外,我們正在努力增強Envoy功能,使其能夠將BoringSSL非同步私鑰操作卸載到加密加速硬體。感謝你的回饋和幫助!

https://github.com/envoyproxy/envoy/issues/6248

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