中标麒麟(NeoKylin)作为国产 Linux 发行版,在政务、金融和能源等信创项目中经常被用作 Kubernetes 节点操作系统。Istio 服务网格启用 HTTPS 接入时,入口网关需要维护 TLS 证书,如果由人工申请、替换,既低效又容易在证书到期后造成业务中断。cert-manager 是一个 Kubernetes 原生的证书管理控制器,它把证书签发、更新和吊销抽象为自定义资源,在中标麒麟环境中运行不需要单独修改内核参数,只要 Kubernetes 集群本身稳定即可。本文以内部 CA 为主,说明从环境检查、cert-manager 安装、Issuer 配置到 Istio Gateway 挂载的完整过程。

一、中标麒麟环境准备与兼容性检查
中标麒麟通常基于 RPM 包管理,和 CentOS 或 RHEL 的使用习惯接近,但默认安全策略和软件源配置可能有差异。cert-manager 不直接依赖操作系统发行版,而是依赖 Kubernetes API 和容器网络。因此在开始前需要确认集群控制平面正常、kubectl 可以连接,并且节点上的容器运行时有权限拉取并运行 cert-manager 镜像。对于信创离线环境,还需要提前准备 cert-manager 的镜像包,通过内部仓库或 load 方式导入。
执行下面的命令可以快速判断系统版本、内核、Kubernetes 版本和节点状态。内核版本只要满足 Kubernetes 的最低要求即可,一般 4.19 及以上都可用。值得留意的是,如果中标麒麟启用了 SELinux 或 firewalld,需要放行 API Server 到 cert-manager webhook 的访问,否则后续安装时会出现 webhook 调用超时。
cat /etc/os-release uname -m kubectl version --short kubectl get nodes sestatus
如果 kubectl get nodes 返回异常,需要先恢复 Kubernetes 控制平面,再继续安装 cert-manager。cert-manager 的 Webhook 默认使用 443 端口,在集群内部通过 Service 暴露,通常不需要在节点上开放公网端口,但要确保 Service 网络段和 Pod 网络之间的访问没有被网络策略拦截。
另外,后续生成证书会写入 Secret,因此无需额外创建 PVC。如果希望保存 ACME 账号信息,cert-manager 也会使用 Secret 存储,不会依赖存储类。这一点对中标麒麟上的轻量部署比较友好,减少了持久化卷的故障面。
二、安装 cert-manager 并创建内部 CA Issuer
cert-manager 的安装可以通过静态 YAML 或者 Helm 完成。对于离线或信创环境,建议先把官方镜像同步到内网仓库,然后修改部署清单中的镜像地址。核心组件包括 controller、webhook 和 cainjector,三者必须全部运行正常。以静态 YAML 方式为例,安装命令如下。
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.4/cert-manager.yaml && kubectl wait --for=condition=ready pod -l app=cert-manager -n cert-manager --timeout=120s
上述命令执行成功后,可以通过 kubectl get pods -n cert-manager 查看组件状态。如果镜像拉取失败,需要检查 containerd 或 Docker 的镜像仓库配置,并将对应镜像 tag 推送到内网地址。cert-manager 的 CRD 会随清单一并安装,安装后可以使用 kubectl api-resources | grep cert-manager 确认 Issuer、Certificate、CertificateRequest 等资源已经注册。
内部 CA 方案适合无公网的中标麒麟生产集群。先在 istio-system 命名空间创建一个自签名 Issuer,然后用它签发一个 CA 证书,最后创建基于该 CA 的 Issuer。这样的好处是后续所有网关证书都由内部 CA 签发,外部不需要信任该 CA,内部服务可以通过导入根证书建立信任链。下面是完整的三个资源定义。
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
namespace: istio-system
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: selfsigned-ca
namespace: istio-system
spec:
isCA: true
commonName: internal-ca
secretName: ca-key-pair
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: selfsigned-issuer
kind: Issuer
group: cert-manager.io
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: ca-issuer
namespace: istio-system
spec:
ca:
secretName: ca-key-pair
如果集群可以直接访问公网,也可以使用 ACME 类型的 ClusterIssuer 对接证书机构。不过在 Istio 网关场景中,HTTP01 验证要求临时 Pod 的流量能正确进入验证路径,配置相对繁琐;DNS01 验证则依赖 DNS 服务商的 API 权限。对信创内网来说,内部 CA 更稳定,也便于证书格式和有效期控制。
三、生成 Istio 网关证书并挂载到 Gateway
cert-manager 生成的 Secret 默认包含 tls.crt 和 tls.key 两个字段,这与 Istio Gateway 要求的证书格式完全一致。创建 Certificate 资源时需要指定域名、签发者、密钥类型和有效期。下面的示例为 api.ipipp.com 生成一张 90 天有效期的证书,并写入名为 istio-ingressgateway-certs 的 Secret。
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: istio-gateway-cert
namespace: istio-system
spec:
secretName: istio-ingressgateway-certs
duration: 2160h
renewBefore: 360h
dnsNames:
- api.ipipp.com
issuerRef:
name: ca-issuer
kind: Issuer
group: cert-manager.io
Certificate 创建后,cert-manager 会生成 CertificateRequest 并等待 Issuer 完成签名。可以通过 kubectl get certificate -n istio-system 查看 READY 状态。如果 READY 为 True,说明 Secret 已经生成;如果长时间处于 False,需要查看 Certificate 的事件和 CertificateRequest 的状态。
Istio Gateway 的 TLS 配置使用 credentialName 指向 Secret 名称,这样入口网关 Pod 会通过 SDS 机制自动加载证书。注意 Secret 必须位于 Gateway 所在的命名空间,本例统一放在 istio-system。下面是 Gateway 的定义。
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: public-gateway
namespace: istio-system
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: istio-ingressgateway-certs
hosts:
- api.ipipp.com
当证书 Secret 更新时,Istio 的 ingress gateway 会监听 Secret 变化并热加载,不需要手动重启 Pod。对于已经建立的 TLS 长连接,通常需要等待连接断开重连后新证书才会完全生效。若需要验证网关实际下发的证书,可以从外部执行 openssl s_client 命令,也可以在集群内通过 istioctl 查看代理证书。
kubectl get certificate -n istio-system kubectl get secret istio-ingressgateway-certs -n istio-system -o yaml kubectl logs -n istio-system deploy/istio-ingressgateway --tail=100
四、证书续期配置与常见问题排查
证书续期是 cert-manager 的核心能力之一。Certificate 资源中的 renewBefore 字段定义了在证书到期前多久启动续期,示例中设置为 360h,即 15 天。cert-manager 会在满足续期窗口后自动创建新的 CertificateRequest,并用同一 Issuer 完成签发。续期成功后,Secret 内容被替换,Istio Gateway 通过 SDS 自动感知到新证书。内部 CA 的根证书有效期通常比业务证书长,但也要关注根证书到期时间,否则所有下发证书都会失效。
使用内部 CA 时,如果 CA 证书过期,需要重新生成 CA 并更新 Issuer 引用。可以通过轮换机制提前创建新的 CA,再逐步迁移 Certificate 的 issuerRef,避免一次性替换造成大量网关同时中断。对于测试环境,可以缩短 duration 和 renewBefore,观察自动续期行为。命令 kubectl get certificaterequest -n istio-system 可以看到最近的请求记录。
kubectl get certificaterequest -n istio-system kubectl describe certificate istio-gateway-cert -n istio-system kubectl get events -n istio-system --sort-by=.lastTimestamp
常见问题中,webhook 调用失败通常表现为 Certificate 一直处于 False,但日志中出现 failed calling webhook。这时需要检查 cert-manager namespace 下的 Service 和 Endpoints 是否正常,并确认 API Server 到 Pod 的连通性。证书已经生成但 Istio 网关仍然使用旧证书,多是因为 Gateway 的 credentialName 与 Secret 名称不一致,或者 Secret 不在 Gateway 所在命名空间。域名不匹配则会导致浏览器告警,需要确认 Certificate 的 dnsNames 是否覆盖了所有访问域名。
安全方面建议 ECDSA P-256 证书以降低握手开销,避免把 CA 私钥与业务证书放在同一处。中标麒麟环境如果使用内部 PKI,根证书需要统一导入到客户端信任库。证书管理自动化后,告警重点应放在 Certificate 的 READY 状态、Secret 的更新时间和网关日志中的证书错误,而不是人工跟踪到期时间。
中标麒麟cert-managerIstio证书管理修改时间:2026-10-02 07:58:58