K8s跨命名空间SSL认证解决方案:Reflector工具实战
在Kubernetes集群运维过程中,跨命名空间组件的SSL认证是一个常见的痛点。近期在工作中就遇到了这样的问题:集群内不同命名空间的组件需要通过SSL证书实现安全通信,但当前环境使用的cert-manager工具,其命名空间级别的Issuer资源无法跨命名空间复用,导致证书无法在多命名空间间共享。
经过查阅官方文档和实践验证,找到了一个高效的解决方案------使用Reflector工具实现跨命名空间Secret同步,完美解决了这一难题。今天就来详细分享整个过程,希望能帮助到有同样需求的小伙伴。
一、背景:cert-manager与跨命名空间认证的矛盾
首先简单回顾下cert-manager的工作原理,它是K8s生态中最常用的自动化证书管理工具,核心基于Kubernetes的自定义资源定义(CRD)机制,通过三个核心CRD资源实现证书的全生命周期管理:
- Certificate:定义证书的核心信息,比如证书对应的域名、有效期、密钥算法、存储证书的Secret名称等,是证书请求的"需求清单"。
- Issuer:命名空间级别的证书颁发机构(CA)配置,用于定义如何与CA交互、发起证书请求,仅能在自身所在的命名空间内使用,无法跨命名空间复用。
- ClusterIssuer :集群级别的CA配置,不受命名空间限制,可在全集群范围内使用,但本次环境中由于权限和配置限制,只能使用Issuer资源。
当我们在某个命名空间(比如openstack)通过Issuer创建了Certificate资源后,cert-manager会自动向该Issuer对应的CA发起证书请求,成功后将证书和私钥存储在该命名空间下的Secret中。但问题在于,其他命名空间的组件无法直接访问这个Secret,导致跨命名空间的SSL认证无法实现------这就是我们本次要解决的核心痛点。
经过查阅cert-manager官方文档和社区方案,发现Reflector工具可以完美解决这个问题。Reflector是Kubernetes的一个插件 ,专门用于监控Secret和ConfigMap的变化,并将其同步(反射)到同一集群的其他命名空间,正好契合我们跨命名空间共享证书(存储在Secret中)的需求
二、Reflector工具介绍
Reflector是由emberstack开源的K8s插件,核心功能是"资源反射"------监控指定的Secret或ConfigMap,当资源发生变化时,自动将其同步到其他命名空间的"镜像资源"中。
- 支持多架构:兼容amd64、arm、arm64架构,适配各种集群环境。
- 自动同步:实时监控源资源变化,同步更新镜像资源,无需手动干预。
- 灵活控制:可通过注解限制允许同步的命名空间,支持自动创建镜像资源或手动指定镜像资源。
- 无缝集成cert-manager :从cert-manager 1.5版本开始,可通过Certificate的secretTemplate配置注解,直接让cert-manager生成的证书Secret支持反射同步,无需额外操作
其工作逻辑很简单:通过注解标记源Secret/ConfigMap,Reflector控制器监听源资源的变化,然后根据注解配置,在目标命名空间创建或更新对应的镜像资源,确保源资源和镜像资源始终保持一致。
三、Reflector部署
Reflector支持两种部署方式:Helm部署(推荐,适合生产环境,便于后续升级和配置自定义)和手动部署(适合快速测试或无Helm环境)。下面详细介绍两种部署步骤,以及部署过程中的注意事项
3.1 前置条件
- Kubernetes集群版本 ≥ 1.22(Reflector对集群版本有最低要求)。
- 若使用Helm部署,需确保Helm版本 ≥ 3.8。
- 集群已安装cert-manager(本次实战基于cert-manager已部署完成的前提)
3.2 Helm部署
- 添加 Helm 仓库:
helm repo add emberstack https://emberstack.github.io/helm-charts。 - 更新仓库:helm repo update。
- 手动拉取镜像(重点注意):由于内网环境或镜像仓库权限限制,直接部署可能会出现镜像拉取失败的问题。本次环境中,需要手动拉取指定版本的Reflector镜像,命令如下(根据自身环境替换镜像地址):
docker pull af.hikvision.com.cn/docker-drpd/emberstack/kubernetes-reflector:7.1.288若集群有多个节点,需确保所有节点都拉取该镜像,避免Pod调度失败。 - 安装或升级:helm upgrade --install reflector emberstack/reflector,可通过修改 Values 自定义配置,如 nameOverride、image.repository 等参数。
3.3 手动部署
- 下载部署文件:从Reflector的GitHub Releases页面下载最新的部署文件reflector.yaml。
wget https://github.com/emberstack/kubernetes-reflector/releases/latest/download/reflector.yaml -
- 部署到集群:将部署文件应用到kube-system命名空间(推荐,便于集群级插件管理)。
kubectl -n kube-system apply -f reflector.yaml
部署完成后,执行以下命令验证Reflector是否正常运行,确保所有Pod都处于Running状态
- 部署到集群:将部署文件应用到kube-system命名空间(推荐,便于集群级插件管理)。
四、实战:Reflector + cert-manager 实现跨命名空间证书同步
部署完成Reflector后,核心操作就是在cert-manager的Certificate资源中添加对应的注解,即可实现证书Secret的跨命名空间同步。下面结合本次实战场景,详细讲解配置步骤和注意事项。
4.1 核心注解说明
Reflector通过注解控制Secret的反射行为,针对cert-manager的Certificate资源,我们需要在spec.secretTemplate.annotations中添加以下注解(secretTemplate用于定义cert-manager生成的Secret的注解和标签):
reflector.v1.k8s.emberstack.com/reflection-allowed: "true":核心注解,允许该Secret被反射(同步)到其他命名空间,必须设置为"true"。reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "xxx-xxxx":限制允许反射的命名空间,支持逗号分隔的命名空间列表或正则表达式(如"ns1,ns2,ns-[0-9]*")。若省略或设为空字符串,则允许所有命名空间。reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true":允许自动在目标命名空间创建同名的镜像Secret,无需手动创建镜像资源(需配合前一个注解使用,且前一个注解为"true")。reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "xxx-xxxx":指定自动创建镜像Secret的命名空间,支持逗号分隔列表或正则表达式,受前一个"允许反射的命名空间"注解限制。若省略或为空,则允许所有符合条件的命名空间
4.2 配置示例
在openstack命名空间创建一个用于RabbitMQ的SSL证书,通过Reflector自动同步到指定命名空间(如xxx-xxxx),供该命名空间的组件使用。以下是完整的Certificate配置文件(certificate.yaml)
yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: xxxxx-tls-rabbitmq # 证书名称,自定义
namespace: openstack # 证书所在的源命名空间
spec:
dnsNames: # 证书对应的域名,根据实际需求配置
- rabbitmq
- rabbitmq.openstack
- rabbitmq.openstack.svc.cluster.local
commonName: center-cmp-tls-rabbitmq # 证书通用名称,自定义
secretName: center-cmp-tls-rabbitmq # 存储证书的Secret名称,cert-manager会自动创建
duration: 876000h0m0s # 证书有效期,此处为10年
issuerRef: # 关联的Issuer(命名空间级,需在openstack命名空间存在)
name: openstack-ca-issuer
kind: Issuer
privateKey:
size: 2048 # 私钥长度,2048位足够满足安全需求
secretTemplate: # 关键配置:定义Secret的注解,用于Reflector反射
annotations:
# 允许该Secret被反射
reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
# 允许反射的命名空间,替换为实际需要的命名空间列表
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "xxx-xxxx"
# 允许自动在目标命名空间创建镜像Secret
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
# 自动创建镜像Secret的命名空间,与允许反射的命名空间一致
reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "xxx-xxxx"
4.3 应用配置并验证
- 应用Certificate配置 :执行以下命令创建Certificate资源,cert-manager会自动发起证书请求并创建Secret。
kubectl apply -f certificate.yaml - 验证源Secret是否创建成功 :在openstack命名空间查看Secret,确认证书已生成。
kubectl get secrets -n openstack | grep center-cmp-tls-rabbitmq若能看到对应的Secret,且状态正常,说明cert-manager已成功生成证书。 - 验证跨命名空间同步效果 :在目标命名空间(如xxx-xxxx)查看是否自动创建了同名的镜像Secret。
kubectl get secrets -n xxx-xxxx | grep center-cmp-tls-rabbitmq若能看到对应的Secret,说明Reflector已成功同步。此时,该命名空间的组件就可以通过挂载这个Secret,实现SSL认证了。
4.4 注意事项
- 自动同步的镜像Secret会与源Secret保持实时一致:当源Secret(cert-manager自动续期后会更新)发生变化时,Reflector会自动更新所有镜像Secret,无需手动干预。
- 源资源删除后,自动创建的镜像资源会被同步删除;若关闭反射功能(将reflection-allowed改为"false"),或目标命名空间不再符合允许条件,镜像资源也会被删除。
- 若目标命名空间已存在同名的Secret,Reflector会跳过该命名空间,并在日志中记录警告,避免覆盖已有资源。
- 若手动修改镜像Secret,需添加注解
reflector.v1.k8s.emberstack.com/reflected-version: "",否则Reflector会将其重置为与源Secret一致的内容。