MiniO KES(密钥加密服务) 是由 MinIO 开发的服务,用于弥合在 Kubernetes 中运行的应用程序与集中式密钥管理服务 (KMS) 之间的差距。中央 KMS 服务器包含所有状态信息,而 KES 在需要执行与获取新密钥或更新现有密钥相关的任何操作时与 KMS 交谈。获取密钥后,只要不需要更新或删除,它就会缓存在 KES 中,因此后续调用将快得多。
那么为什么使用 KES 而不是直接使用 KMS 呢?根据使用的 KMS 以及它需要处理的负载,有时 KMS 系统没有能力或支持来处理大型部署,在大型部署中,它必须来回管理数百甚至数千个密钥,而 Kubernetes 集群会对它们施加巨大的负载。 在这些情况下,使用 KES 至关重要,因为它可以非常轻松地横向扩展,这与传统的 KMS 系统不同。
所有应用程序<->KES 和 KES<->KMS 之间的 KES 操作都使用 mTLS 身份验证来执行身份验证和授权功能。 这是使用一对公钥/私钥和 X.509 证书完成的。 证书的问题在于,它们有一个非常常见的问题,它们往往会过期,并且当它们过期时,周围的所有服务都会以很少的道理而壮观地失败。 这是什么意思呢?
我们的意思是,一旦证书过期,您将开始在 KES 日志中看到以下错误
{"message":"2024/01/04 02:23:21 http: TLS handshake error from 10.244.2.9:32816: remote error: tls: bad certificate"}
{"message":"2024/01/04 02:23:28 http: TLS handshake error from 10.244.3.11:53456: remote error: tls: bad certificate"}
{"message":"2024/01/04 02:23:28 http: TLS handshake error from 10.244.1.9:56722: remote error: tls: bad certificate"}
{"message":"2024/01/04 02:23:28 http: TLS handshake error from 10.244.4.11:34152: remote error: tls: bad certificate"}
{"message":"2024/01/04 02:23:28 http: TLS handshake error from 10.244.2.9:55300: remote error: tls: bad certificate"}
{"message":"2024/01/04 02:23:28 http: TLS handshake error from 10.244.4.11:34160: remote error: tls: bad certificate"}
…
此外,当 MinIO 尝试执行周期性 IAM 刷新时,这些也会失败,并在 MinIO 日志中显示以下消息
错误:IAM 周期性刷新失败(耗时 0.03 秒):Post "https://kes-tenant-kes-hl-svc.default.svc.cluster.local:7373/v1/key/decrypt/my-minio-key": x509: 证书已过期或尚未生效:当前时间 2024-01-04T02:27:31Z 在 2024-01-04T02:12:40Z 之后 (*errors.errorString)
如果您幸运,您会看到一条明显的消息,例如 证书已过期
。 其他时候,它并不那么明显,您还可能在尝试创建或删除密钥等一系列其他问题中看到边缘情况问题。 最快的解决方案是尽快更新 KES 并使用新证书对其进行更新。 在这篇文章中,我们将向您展示如何做到这一点。
如何续订 首先,让我们从创建一个新的私钥开始
openssl genrsa -out private.key 2048
创建一个名为 cert.cnf
的文件,它将由 openssl
用于创建证书签名请求 (CSR)
[req]
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no
[req_distinguished_name]
O = "system:nodes"
C = US
CN = "system:node:*.kes-tenant-kes-hl-svc.default.svc.cluster.local"
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = kes-tenant-kes-0.kes-tenant-kes-hl-svc.default.svc.cluster.local
DNS.2 = kes-tenant-kes-hl-svc.default.svc.cluster.local
确保修改公用名 CN
和主题备用名称 SAN
(在 [alt_names]
下)以匹配 KES 节点的 FQDN。 确保使用正确的 FQDN 而不是 IP 地址。
使用以下命令创建 CSR
openssl req - new -config cert.cnf -key private.key -out kes.csr
将 CSR 转换为编码字符串,以便它可以作为 CertificateSigningRequest
资源添加到 Kubernetes 中。
cat kes.csr | base64 | tr -d "\n"
使用以下内容创建一个名为 kes-csr.yaml
的文件,并将上面的编码 CSR 粘贴到 request
字段中。 证书已被截断,因此您可以看到整个 yaml。
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata
name: kes-csr
spec
expirationSeconds: 604800
groups
- system:serviceaccounts
- system:serviceaccounts:minio-operator
- system:authenticated
- system:nodes
request: LS0tLS1CRUdJTiBDRV…FUVVFU1QtLS0tLQo=
signerName: kubernetes.io/kubelet-serving
usages
- digital signature
- key encipherment
- server auth
username: system:serviceaccount:minio-operator:minio-operator
确保将 expirationSeconds
更新为一个较高的值,这样它就不会很快过期。
在添加编码 CSR 并设置其他设置后,应用 yaml。
kubectl apply -f kes-csr.yaml
确保批准上面创建的 kes-csr
CSR
kubectl certificate approve kes-csr
从 csr
资源获取公钥证书
kubectl get csr kes-csr -o jsonpath= '{.status.certificate}' | base64 -d > public.crt
将 private.key
(来自流程开始)和 public.crt
(来自上一步)都转换为编码字符串。
cat private.key | base64 | tr -d "\n"
cat public.crt | base64 | tr -d "\n"
使用上面的编码字符串,我们将更新现有的 Secret
kes-tenant-kes-tls
,为此,请按照以下步骤操作。
复制包含现有已过期证书的现有秘密。
kubectl get secret kes-tenant-kes-tls -o yaml > kes-tls-secret.yaml
备份现有秘密后,将其删除
kubectl delete secret kes-tenant-kes-tls
打开包含已过期证书的 kes-tls-secret.yaml
,并将以下两个字段替换为各自的 base64 编码字符串。
data
private.key: >-
LS0tLS1CRUd…ZLS0tLS0
public.crt: >-
LS0tLS1CRUdJTi…tLS0K
在添加新证书后,应用 Secret
,它将重新创建 kes-tenant-kes-tls
kubectl apply -f kes-tls-secret.yaml
添加有效证书后,确保重新启动 KES 服务,您应该会看到以下输出
'http://vault.default.svc.cluster.local:8200' ...
Endpoint: https://127.0.0.1:7373 https://10.244.4.16:7373
Admin: _ [ disabled ]
Auth: 关闭 [ 任何客户端都可以连接,但策略仍然适用 ]
Keys: Hashicorp Vault: http://vault.default.svc.cluster.local:8200
CLI: export KES_SERVER=https://127.0.0.1:7373
export KES_CLIENT_KEY= // 例如 $HOME/root.key
export KES_CLIENT_CERT= // 例如 $HOME/root.cert
kes --help
MinIO 日志也应该干净,并且不应该再显示任何 TLS 错误。
等待所有 MinIO 子系统初始化.. 互斥锁获取成功
根据系统可用内存自动配置每个节点的 API 请求数量:221
所有 MinIO 子系统在 15.44125ms 内成功初始化
MinIO 对象存储服务器
版权:2015-2024 MinIO, Inc.
许可证:GNU AGPLv3
版本:RELEASE.2024-01-04T09-40-09Z (go1.19.4 linux/arm64)
状态: 4 在线,0 离线。
API: https://minio.default.svc.cluster.local
控制台: https://10.244.3.12:9443 https://127.0.0.1:9443
文档:https://min-io.cn/docs/minio/linux/index.html
最终想法 KES 是管理用于加密对象的密钥不可或缺的一部分。重要的是,对象能够以最快的速度进行加密和解密,因为执行这些操作的每一纳秒都会导致最终用户获得对象的延迟。是的,最终,低效和缓慢的 KMS 系统会降低整体集群性能。因此,确保执行这些操作的服务快速、精简、高效且可扩展至关重要。MinIO 的 KES 使任何 KMS 能够成为高性能和可扩展的服务,而无需对现有 KMS 进行任何修改。通过遵循上述步骤,您可以立即让 KES 恢复到拥有有效的未过期证书状态!
如果您对 KES 有任何疑问,请务必在 Slack 上与我们联系!