带TPM的单节点Kubernetes集群:容器安全访问TPM私钥建TLS连接
Linux环境下基于TPM的容器TLS私钥安全访问方案
针对单节点K8s集群场景,下面提供三种可落地的实现方案,核心思路都是让容器无需接触明文私钥,直接通过TPM完成TLS握手的密钥操作:
方案一:TPM设备直通 + OpenSSL TPM引擎
这是最直接的方案,让容器直接访问宿主机TPM设备,通过OpenSSL的TPM引擎调用密钥。
- 宿主机前置配置:
- 先装好
tpm2-tools和tpm2-openssl,加载TPM内核模块(modprobe tpm_tis或modprobe tpm_crb)。 - 调整TPM设备权限,让K8s容器能访问:
chgrp root /dev/tpmrm0,也可以写udev规则持久化这个配置。
- 先装好
- 容器镜像准备:
在应用镜像里预装TPM工具和OpenSSL引擎,以Ubuntu为例:RUN apt update && apt install -y tpm2-tools tpm2-openssl - 密钥导入与配置:
- 在宿主机用TPM生成并持久化密钥对,导出证书:
# 创建主密钥上下文 tpm2_createprimary -C o -c primary.ctx # 生成RSA密钥对 tpm2_create -G rsa -u key.pub -r key.priv -C primary.ctx # 加载密钥到TPM tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx # 持久化密钥到TPM(重启后不丢失) tpm2_evictcontrol -C o -c key.ctx 0x81000001 # 生成证书(也可以用CA签名) tpm2_certify -C primary.ctx -c key.ctx -o cert.pem -s sha256 - 把证书
cert.pem存入K8s ConfigMap(证书是公开信息,无需保密),同时准备OpenSSL配置文件指定TPM引擎:[openssl_init] engines = engine_section [engine_section] tpm2 = tpm2_section [tpm2_section] engine_id = tpm2 dynamic_path = /usr/lib/x86_64-linux-gnu/engines-1.1/tpm2.so
- 在宿主机用TPM生成并持久化密钥对,导出证书:
- Pod部署配置:
挂载TPM设备、证书ConfigMap和OpenSSL配置文件:spec: containers: - name: your-app image: your-app-image volumeMounts: - name: tpm-device mountPath: /dev/tpmrm0 - name: cert-config mountPath: /etc/certs - name: openssl-config mountPath: /etc/ssl/openssl.cnf subPath: openssl.cnf volumes: - name: tpm-device hostPath: path: /dev/tpmrm0 type: CharDevice - name: cert-config configMap: name: tls-cert - name: openssl-config configMap: name: openssl-config - 应用适配:
应用通过OpenSSL指定TPM引擎调用密钥,比如用curl测试:curl --engine tpm2 --cert /etc/certs/cert.pem --key 0x81000001 https://target-server
方案二:TPM CSI驱动(K8s原生方案)
用CSI驱动封装TPM交互,让容器通过PVC安全访问密钥,无需直接接触TPM设备。
- 部署TPM CSI驱动:
给单节点集群部署社区的tpm-csi驱动,驱动会在宿主机侧和TPM交互,为Pod提供密钥访问接口。 - 创建存储类和PVC:
定义指向TPM CSI的存储类,再创建PVC请求密钥资源:apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: tpm-storage provisioner: tpm-csi.io parameters: keyType: rsa keySize: 2048 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: tpm-key-pvc spec: storageClassName: tpm-storage accessModes: - ReadOnlyMany resources: requests: storage: 1Mi # 仅占位,实际不占用磁盘空间 - Pod部署配置:
挂载PVC,容器内会拿到证书文件和密钥引用:spec: containers: - name: your-app image: your-app-image volumeMounts: - name: tpm-key-volume mountPath: /etc/tpm-keys volumes: - name: tpm-key-volume persistentVolumeClaim: claimName: tpm-key-pvc - 应用适配:
应用读取/etc/tpm-keys/cert.pem作为证书,密钥操作通过CSI提供的接口完成,无需直接操作TPM。
方案三:Sidecar容器代理TPM操作
用Sidecar封装所有TPM操作,主容器通过本地通信调用Sidecar完成签名/加密,彻底隔离TPM设备访问。
- Sidecar开发:
写一个轻量Sidecar(比如Go或Python),封装tpm2-tools命令,提供Unix socket或HTTP接口,支持证书获取、签名等操作。比如让Sidecar监听/tmp/tpm.sock,主容器通过socket发送请求获取结果。 - Pod部署配置:
Sidecar挂载TPM设备,主容器和Sidecar共享socket所在的emptyDir:spec: containers: - name: tpm-proxy image: tpm-proxy-image volumeMounts: - name: tpm-device mountPath: /dev/tpmrm0 - name: socket-volume mountPath: /tmp - name: your-app image: your-app-image volumeMounts: - name: socket-volume mountPath: /tmp volumes: - name: tpm-device hostPath: path: /dev/tpmrm0 type: CharDevice - name: socket-volume emptyDir: {} - 应用适配:
应用通过Unix socket向Sidecar请求签名结果,完成TLS握手,全程无需接触TPM或私钥。
关键注意事项
- 权限控制:严格限制容器对TPM设备的访问权限,避免未授权Pod使用TPM密钥。
- 密钥持久化:必须用
tpm2_evictcontrol将密钥持久化到TPM,防止重启后密钥丢失。 - 证书管理:证书可以放心存在ConfigMap,因为证书本身是公开信息。
内容的提问来源于stack exchange,提问作者appcoder
相关产品推荐
相关产品推荐

