模型下载因 HTTPS 证书验证错误失败

问题描述

Alauda Container Platform (ACP) 配置为使用 用户提供的 HTTPS 证书 时,模型下载可能失败,原因是无法验证 HTTPS 证书。在这种情况下,下载模型的工作负载(例如推理服务启动时拉取模型工件)可能会遇到 TLS 验证错误,导致无法获取模型工件。

典型症状包括类似以下错误:

  • x509: certificate signed by unknown authority
  • certificate verify failed

根本原因

dex.tls secret(位于 Global 集群)包含 tls.crt。HTTPS 证书验证错误可能发生在以下任一情况:

  • tls.crt 不包含 完整的证书链,导致客户端无法从服务器证书构建到受信任根 CA 的信任链。
  • 证书已 过期(当前时间不在 Not Before / Not After 范围内)。

tls.crt 必须是一个单一的 PEM 文件,按顺序连接服务器证书、可选的中间证书和根 CA 证书(服务器 → 中间证书 → 根证书,根 CA 证书放最后)。

检查当前 dex.tls 证书

应在 Global 集群的 cpaas-system 命名空间中检查 dex.tls secret。

本地导出 tls.crt

kubectl get secret dex.tls -n cpaas-system -o jsonpath='{.data.tls\.crt}' | base64 -d > tls.crt

期望的 tls.crt 格式

导出后,打开 tls.crt,确认它是一个 PEM 文件,包含 多个 证书块按顺序连接(服务器 → 中间证书 → 根证书)。中间 CA 证书可能缺失,视 CA 配置而定。

至少,tls.crt 应包含 至少两个 证书:服务器证书和根 CA 证书。

-----BEGIN CERTIFICATE-----
... 服务器证书 ...
-----END CERTIFICATE-----

# (可选)中间 CA 证书可能缺失
-----BEGIN CERTIFICATE-----
... 中间证书 ...
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
... 根证书 ...
-----END CERTIFICATE-----

快速检查

grep -n "BEGIN CERTIFICATE" tls.crt

如果少于两个 BEGIN CERTIFICATE 块,说明证书链不完整。

使用 OpenSSL 解析证书

要详细检查证书,将其以 PEM 格式粘贴并用 OpenSSL 解析:

echo '-----BEGIN CERTIFICATE-----
xxxxxx
-----END CERTIFICATE-----' | openssl x509 -text -noout

检查颁发者/主题链

对每个证书,检查 IssuerSubject

  • 对服务器证书,Issuer 中的 CN 应与下一张证书的 Subject 中的 CN 匹配。
  • 重复此 CN 匹配步骤,直到到达根 CA 证书。
  • 根 CA 证书为自签名证书,IssuerSubject 匹配,特别是 IssuerSubject 中的 CN 应相同。

检查证书有效期

证书过期也会导致 HTTPS 验证失败。检查 Not Before / Not After,确认当前时间在有效期内。

示例:构建完整链 PEM 文件

假设证书以单独 PEM 文件形式存在:

  • server.crt:服务器证书
  • intermediate.crt:中间证书(可选,可能有多个)
  • root.crt:根证书

创建完整链文件 fullchain.crt

cat server.crt intermediate.crt root.crt > fullchain.crt

如果有多个中间证书:

cat server.crt intermediate-1.crt intermediate-2.crt root.crt > fullchain.crt

更新 dex.tls Secret

步骤 1. 将证书链合并为单个文件:

cat server.crt intermediate.crt root.crt > fullchain.crt

如果没有中间 CA 证书:

cat server.crt root.crt > fullchain.crt

步骤 2. 替换 dex.tls secret:

TLS_CRT_B64="$(base64 < fullchain.crt | tr -d '\n')"
kubectl patch secret dex.tls -n cpaas-system \
  --type merge \
  -p "{\"data\":{\"tls.crt\":\"${TLS_CRT_B64}\"}}"

同步与重试

dex.tls 更新后,会同步到推理服务所在的命名空间(可能需要几分钟)。

Secret 同步完成后,重启推理服务以触发模型下载重试:

  • 停止推理服务。
  • 启动推理服务。

或者,从命令行重启工作负载:

kubectl rollout restart deploy/<deployment-name> -n <inference-namespace>

服务重启后,检查日志中是否还有 TLS 相关错误,以确认问题已解决。