作者:郭栋 英特尔亚太研发有限公司
Envoy 是为微服务架构设计的一款高性能网络代理。在目前非常流行的 Service Mesh 项目 Istio 中,数据面便是通过 Envoy 来实现的。在 Istio 中,Envoy 可以承担两种角色:
接着我们来回顾一下 TLS。目前,随着网络安全技术的发展, TLS 已经成为网络通信的基石。一个 TLS 会话的处理过程总体上可分为握手阶段和数据传输阶段,握手阶段最重要的任务是使用非对称加密技术协商出一个会话密钥,然后在数据传输阶段,使用协商出的会话密钥对数据执行对称加密操作,再进行传输。
在微服务场景下,Envoy 无论是作为 Ingress Gateway 还是作为微服务的代理,都需要处理大量的 TLS 请求,尤其在握手阶段执行非对称加解密的操作时,需要消耗大量的 CPU 资源,在大规模微服务场景下这可能会成为一个瓶颈。本文会介绍 Intel 的两种加解密技术,采用这些技术后,可以加速 Envoy 中 TLS 的处理过程。
针对前文提出的问题,Intel 有两种用于加解密的技术,可以加速 TLS 的处理过程:
需要注意的是,在本文中我们重点关注对于 TLS 中非对称加密的加速和优化。这里提到的两种加解密技术除了包含非对称加密功能之外还包含很多其它功能,例如对称加密和压缩解压缩等,由于这些不是本文的重点,因此不会详细展开。
下面是第一种技术 QAT 在执行非对称加密时的性能数据,来源于 https://01.org/sites/default/files/downloads/intelr-quickassist-technology/337003-001-intelquickassisttechnologyandopenssl-110.pdf 。
下面是第二种技术 Multi-Buffer 的性能数据,来源于 https://newsroom.intel.com/articles/crypto-acceleration-enabling-path-future-computing/。
可以看出在使用了这两种加解密技术之后,效率会得到成倍的提升。更详尽的性能报告可参见对应的文档。
上面这两种技术通过一个名为 QAT Engine 的项目来向上提供接口。QAT Engine 是 OpenSSL 的一个扩展模块,任何使用了 OpenSSL 的项目都可以通过 QAT Engine 扩展模块来使用这两种加解密技术。
针对于 Envoy 的场景,为了使用以上两种技术来提升加解密的效率,进而提升 Envoy 数据面的性能,目前有两种方式:
上面的两种加解密技术和这两种使用方式进行组合,最终会生成四种不同的使用方案:
--- | Envoy+BoringSSL | Envoy+OpenSSL |
---|---|---|
QAT | 方案 1 | 方案 3 |
Multi-Buffer | 方案 2 | 方案 4 |
下面是关于这四种方案的架构图:
在本文中,我们主要关注第 1 种,即 Envoy + BoringSSL + QAT 的方案,即通过 Envoy 中的 Private Key Provider 特性来使用 QAT 技术实现数据面的加速。其余的三种方案会在后续的文章中和大家分享。
操作系统可以是 Ubuntu 18.04 或者 CentOS 7,其它版本的系统在编译驱动时可能需要做一些微调,本文中以 Ubuntu 18.04 操作系统为例进行说明。
# uname -a
Linux xxx 4.15.0-112-generic #113-Ubuntu SMP Thu Jul 9 23:41:39 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
# gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
硬件方面需要配备有 QAT 物理设备,可用以下命令进行验证。
# lspci | grep 'QuickAssist'
3d:00.0 Co-processor: Intel Corporation C62x Chipset QuickAssist Technology (rev 04)
3f:00.0 Co-processor: Intel Corporation C62x Chipset QuickAssist Technology (rev 04)
da:00.0 Co-processor: Intel Corporation C62x Chipset QuickAssist Technology (rev 04)
在保证上一步软硬件环境已经具备的情况下,可以进行 QAT 的 Driver 和 Library 的安装。首先安装编译工具和一些依赖包:
# apt install -y build-essential pkg-config libudev-dev
下载、编译并安装 QAT 的 Driver 和 Library:
# curl https://01.org/sites/default/files/downloads/qat1.7.l.4.10.0-00014.tar.gz --output qat1.7.l.4.10.0-00014.tar.gz
# ls -l qat1.7.l.4.10.0-00014.tar.gz
-rw-r--r-- 1 root root 5589683 6月 10 10:41 qat1.7.l.4.10.0-00014.tar.gz
# mkdir QAT
# tar xvf qat1.7.l.4.10.0-00014.tar.gz -C QAT
...
# cd QAT
QAT# ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
...
QAT# make
QAT# make install
安装过程中会在节点上部署一个 systemd 服务,可以通过查看服务状态来验证是否安装成功:
# systemctl status qat_service
● qat_service.service - LSB: modprobe the QAT modules, which loads dependant modules, before calling the user space utility to pass
Loaded: loaded (/etc/init.d/qat_service; generated)
Active: active (exited) since Tue xxx CST; 1 weeks 1 days ago
Docs: man:systemd-sysv-generator(8)
Tasks: 0 (limit: 11059)
CGroup: /system.slice/qat_service.service
6月 01 16:13:06 qat_service[13727]: Restarting all devices.
6月 01 16:13:06 qat_service[13727]: Processing /etc/c6xx_dev0.conf
6月 01 16:13:07 qat_service[13727]: Processing /etc/c6xx_dev1.conf
6月 01 16:13:07 qat_service[13727]: Processing /etc/c6xx_dev2.conf
6月 01 16:13:08 qat_service[13727]: Checking status of all devices.
6月 01 16:13:08 qat_service[13727]: There is 3 QAT acceleration device(s) in the system:
6月 01 16:13:08 qat_service[13727]: qat_dev0 - type: c6xx, inst_id: 0, node_id: 0, bsf: 0000:3d:00.0, #accel: 5 #engin
6月 01 16:13:08 qat_service[13727]: qat_dev1 - type: c6xx, inst_id: 1, node_id: 0, bsf: 0000:3f:00.0, #accel: 5 #engin
6月 01 16:13:08 qat_service[13727]: qat_dev2 - type: c6xx, inst_id: 2, node_id: 1, bsf: 0000:da:00.0, #accel: 5 #engin
6月 01 16:13:08 systemd[1]: Started LSB: modprobe the QAT modules, which loads dependant modules, before calling the user s
另外,安装包还附带了一个命令行工具,也可以用于查看服务状态以及执行重启等相关操作:
# adf_ctl status
Checking status of all devices.
There is 3 QAT acceleration device(s) in the system:
qat_dev0 - type: c6xx, inst_id: 0, node_id: 0, bsf: 0000:3d:00.0, #accel: 5 #engines: 10 state: up
qat_dev1 - type: c6xx, inst_id: 1, node_id: 0, bsf: 0000:3f:00.0, #accel: 5 #engines: 10 state: up
qat_dev2 - type: c6xx, inst_id: 2, node_id: 1, bsf: 0000:da:00.0, #accel: 5 #engines: 10 state: up
安装过程中会加载 QAT 相关的内核模块,使用下面的命令进行查看:
# lsmod | grep qat
qat_c62x 20480 0
intel_qat 204800 2 qat_c62x,usdm_drv
uio 20480 1 intel_qat
在云原生的大背景下,一般会在 Kubernetes 中使用 QAT 设备,就需要在 QAT 设备所在节点上安装 QAT Device Plugin,这样 QAT 设备可以通过 Kubelet 的 Device Plugin 机制提供给 Pod 使用。
QAT Device Plugin 的代码位于一个名为 intel-device-plugins-for-kubernetes[1] 的项目中,这个项目作为一个子项目被包含在 kubernetes-qat-envoy 项目中,使用以下命令进行 QAT Device Plugin 的安装。
$ git clone --recurse-submodules https://github.com/intel/kubernetes-qat-envoy.git
$ cd kubernetes-qat-envoy
$ kubectl apply -f ./intel-device-plugins-for-kubernetes/deployments/qat_plugin/base/intel-qat-kernel-plugin.yaml
默认情况下,yaml 文件中的 DaemonSet 中会使用 Intel 官方的 Image,也可以使用以下命令 build 自己的 Image 来使用。
cd intel-device-plugins-for-kubernetes
make intel-qat-plugin EXTRA_BUILD_ARGS="--build-arg TAGS_KERNELDRV=kerneldrv"
部署完成 QAT Device Plugin DaemonSet 后,可以使用以下命令来进行验证:
$ kubectl describe node <node-name>
...
Capacity:
cpu: 72
ephemeral-storage: 244568380Ki
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 528062636Ki
pods: 110
qat.intel.com/cy1_dc0: 48
Allocatable:
cpu: 24
ephemeral-storage: 225394218635
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 527960236Ki
pods: 110
qat.intel.com/cy1_dc0: 48
...
可以看出 QAT 设备已经像 CPU 和内存一样可以作为资源进行动态分配了。
Envoy + BoringSSL + QAT 的方案修改了 Envoy 的代码,主要包含两个部分,第一个部分是 Envoy 中使用 Private Key Provider 特性的框架,第二个部分是使用这个框架对接 QAT 的代码,可以认为是 QAT Plugin,它会调用底层的 QAT Library 完成具体的加解密操作。目前第一部分代码已经 Merge 到社区的 Envoy 中,第二部分由 Intel 进行维护。
我们首先需要编译出包含了上面两部分代码的 Envoy Docker Image,在 kubernetes-qat-envoy 项目中提供了一个 Dockerfile 来帮助自动完成这个操作:
$ docker image build -t envoy-boringssl-qat:devel -f Dockerfile.boringssl .
生成的 Docker Image 名称为 envoy-boringssl-qat:devel
,会在接下来的测试步骤中用到。
kubernetes-qat-envoy 项目提供了一个 yaml 文件用于测试,位于 deployments/boringssl-envoy-deployment.yaml
,其中最重要的是与 QAT 相关的 Envoy 配置:
listeners:
- address:
socket_address:
address: 0.0.0.0
port_value: 9000
filter_chains:
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_certificates:
certificate_chain: { "filename": "/etc/envoy/tls/tls.crt" }
private_key_provider:
provider_name: qat
typed_config:
"@type": "type.googleapis.com/envoy.extensions.private_key_operations_providers.qat.v3.QatPrivateKeyMethodConfig"
section_name: ${QAT_SECTION_NAME}
poll_delay: ${POLL_DELAY}
private_key: "/etc/envoy/tls/tls.key"
可以看出这里使用了 private key provider
特性。在执行时,Envoy 调用 BoringSSL 进行 TLS 握手,而 BoringSSL 则会通过回调函数来调用 QAT Library 进而调用 QAT 硬件设备完成相关的加解密操作。
下面是具体的测试步骤。
首先创建证书并使用证书创建 secret:
$ openssl req -x509 -new -batch -nodes -subj '/CN=localhost' -keyout key.pem -out cert.pem
$ kubectl create secret tls envoy-tls-secret --cert cert.pem --key key.pem
然后创建 Deployment 对象,在此过程中会将上文提到的 Envoy 配置文件存储到一个 ConfigMap 对象中,并将它挂载到 Pod 中。同时也会创建一个 Service 对象用于访问。
$ kubectl apply -f deployments/boringssl-envoy-deployment.yaml
service/helloenvoy created
configmap/boringssl-envoy-config created
deployment.apps/boringssl-envoy created
$ kubectl get pod | grep envoy
boringssl-envoy-67c8c6ddb5-jwpdc 1/1 Running 0 57s
$ kubectl get svc -o wide | grep envoy
helloenvoy NodePort x.x.x.x <none> 9000:32525/TCP 53s app=boringssl-envoy
使用创建的证书进行访问:
$ curl --cacert cert.pem https://localhost:32525 -v
* Rebuilt URL to: https://localhost:32525/
...
> GET / HTTP/1.1
> Host: localhost:32525
> User-Agent: curl/7.58.0
> Accept: */*
...
< HTTP/1.1 200 OK
...
可以看出返回值为 200,说明 Envoy 已经完成了 TLS 握手过程,可以正常进行 HTTPS 请求处理。
另外,也可以通过观察 QAT 设备的统计数据来验证 TLS 的加解密操作是由 QAT 设备完成的,在执行完 curl
命令后,这里的统计数据会增加。
# cat /sys/kernel/debug/qat_c6xx_0000:3d:00.0/fw_counters
+------------------------------------------------+
| FW Statistics for Qat Device |
+------------------------------------------------+
| Firmware Requests [AE 0]: 278192 |
| Firmware Responses[AE 0]: 278192 |
+------------------------------------------------+
| Firmware Requests [AE 1]: 278191 |
| Firmware Responses[AE 1]: 278191 |
+------------------------------------------------+
| Firmware Requests [AE 2]: 278191 |
| Firmware Responses[AE 2]: 278191 |
+------------------------------------------------+
| Firmware Requests [AE 3]: 278191 |
| Firmware Responses[AE 3]: 278191 |
+------------------------------------------------+
| Firmware Requests [AE 4]: 278191 |
| Firmware Responses[AE 4]: 278191 |
+------------------------------------------------+
| Firmware Requests [AE 5]: 278191 |
| Firmware Responses[AE 5]: 278191 |
+------------------------------------------------+
| Firmware Requests [AE 6]: 278191 |
| Firmware Responses[AE 6]: 278191 |
+------------------------------------------------+
| Firmware Requests [AE 7]: 278191 |
| Firmware Responses[AE 7]: 278191 |
+------------------------------------------------+
| Firmware Requests [AE 8]: 278191 |
| Firmware Responses[AE 8]: 278191 |
+------------------------------------------------+
| Firmware Requests [AE 9]: 278191 |
| Firmware Responses[AE 9]: 278191 |
+------------------------------------------------+
本文首先介绍了在大规模微服务场景下 Envoy 处理 TLS 请求过程中可能遇到的问题,然后介绍了两种 Intel 的加解密技术,用于加速 Envoy 中 TLS 的处理过程,以及使用这两种技术的四种方案。
接着详细说明了第一种使用方案的具体编译和部署过程,以及最终如何进行测试和使用。我们会在后续的文章中,针对其它几种方案进行分享。
如果大家在测试过程中有任何问题或者疑问,可在 https://github.com/intel/kubernetes-qat-envoy 中直接提 Issue,我们会在第一时间内解答,谢谢!
[1]
intel-device-plugins-for-kubernetes: https://github.com/intel/intel-device-plugins-for-kubernetes
[2]
英特尔 ® QuickAssist 技术(QAT)-英特尔 ® 官网: https://www.intel.cn/content/www/cn/zh/architecture-and-technology/intel-quick-assist-technology-overview.html
[3]
Intel® QuickAssist Technology | 01.org: https://01.org/intel-quickassist-technology
[4]
Crypto Acceleration: Enabling a Path to the Future of Computing: https://newsroom.intel.com/articles/crypto-acceleration-enabling-path-future-computing/
[5]
Intel® QuickAssist Technology (Intel® QAT) and OpenSSL-1.1.0: Performance: https://01.org/sites/default/files/downloads/intelr-quickassist-technology/337003-001-intelquickassisttechnologyandopenssl-110.pdf
点击【阅读原文】到达kubernetes-qat-envoy仓库。