kubernetes-reflector 学习实验¶
这个组件是干什么的¶
kubernetes-reflector 用来把 Secret 和 ConfigMap 从一个命名空间同步到另一个命名空间。
它常见的用途有两类:
- 把共享配置同步给多个业务命名空间
- 把 TLS 证书、镜像拉取凭据这类共享密钥同步给多个命名空间
先记住这 4 条¶
- 只有
Secret和ConfigMap能被它处理。 - 源对象必须显式声明“允许被反射”。
- 手动镜像是“你先建目标对象,再让它指向源对象”。
- 自动镜像是“源对象一声明,Reflector 自动去目标命名空间创建同名对象”。
关键注解¶
reflector.v1.k8s.emberstack.com/reflection-allowed: "true"- 允许这个源对象被反射
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "ns1,ns2"- 只允许这些命名空间接收镜像
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces-selector: "team=demo"- 按命名空间标签选择允许接收镜像的命名空间
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"- 开启自动镜像
reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "ns1,ns2"- 自动镜像到这些命名空间
reflector.v1.k8s.emberstack.com/reflection-auto-namespaces-selector: "team=demo"- 按命名空间标签自动创建镜像
reflector.v1.k8s.emberstack.com/reflects: "源命名空间/源对象名"- 手动镜像时,目标对象用它指向源对象
安装¶
前提条件:
- Kubernetes 版本不低于
1.22 - Helm 版本不低于
3.8
安装命令:
helm upgrade --install reflector oci://ghcr.io/emberstack/helm-charts/reflector -n kube-system --create-namespace
kubectl -n kube-system get pods
如果想看控制器日志:
实验 1:手动镜像 ConfigMap¶
目标:理解 reflects 是怎么工作的。
应用实验文件:
#01-manual-configmap.yaml
apiVersion: v1
kind: Namespace
metadata:
name: reflector-source
---
apiVersion: v1
kind: Namespace
metadata:
name: app-a
---
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: reflector-source
annotations:
reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "app-a"
data:
color: red
version: v1
---
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-copy
namespace: app-a
annotations:
reflector.v1.k8s.emberstack.com/reflects: "reflector-source/app-config"
data: {}
会看到:
- 源对象在
reflector-source/app-config - 目标对象在
app-a/app-config-copy - 目标对象的数据会和源对象保持一致
继续做同步实验:
- 打开
01-manual-configmap.yaml - 把源
ConfigMap里的color: red改成color: blue - 把
version: v1改成version: v2 - 再次执行:
学习点:
- 手动镜像时,目标对象名字可以和源对象不同
- 真正的同步入口是目标对象上的
reflects
实验 2:自动镜像 Secret¶
目标:理解自动创建同名镜像的方式。
应用实验文件:
#02-auto-secret.yaml
apiVersion: v1
kind: Namespace
metadata:
name: shared-secrets
---
apiVersion: v1
kind: Namespace
metadata:
name: team-a
---
apiVersion: v1
kind: Namespace
metadata:
name: team-b
---
apiVersion: v1
kind: Secret
metadata:
name: shared-login
namespace: shared-secrets
annotations:
reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "team-a,team-b"
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "team-a,team-b"
type: Opaque
stringData:
username: demo
password: p1
kubectl apply -f 02-auto-secret.yaml
kubectl -n team-a get secret shared-login -o yaml
kubectl -n team-b get secret shared-login -o yaml
会看到:
- 源对象在
shared-secrets/shared-login team-a和team-b会自动出现同名Secret
继续做同步实验:
- 打开
02-auto-secret.yaml - 把源
Secret里的password: p1改成password: p2 - 再次执行:
kubectl apply -f 02-auto-secret.yaml
kubectl -n team-a get secret shared-login -o yaml
kubectl -n team-b get secret shared-login -o yaml
学习点:
- 自动镜像要求源对象开启
reflection-auto-enabled - 自动镜像创建出来的目标对象默认与源对象同名
- 自动镜像的目标命名空间必须同时满足“允许反射”和“自动反射”的约束
实验 3:按命名空间标签自动分发¶
目标:理解选择器模式,避免手写很多命名空间名。
应用实验文件:
#3-selector-configmap.yaml
apiVersion: v1
kind: Namespace
metadata:
name: selector-source
---
apiVersion: v1
kind: Namespace
metadata:
name: blue-team
labels:
shared-config: "true"
team: demo
color: blue
---
apiVersion: v1
kind: Namespace
metadata:
name: green-team
labels:
shared-config: "true"
team: demo
color: green
---
apiVersion: v1
kind: Namespace
metadata:
name: other-team
labels:
shared-config: "false"
team: other
---
apiVersion: v1
kind: ConfigMap
metadata:
name: shared-banner
namespace: selector-source
annotations:
reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces-selector: "shared-config=true"
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
reflector.v1.k8s.emberstack.com/reflection-auto-namespaces-selector: "shared-config=true"
data:
title: 统一公告
owner: 平台团队
kubectl apply -f 03-selector-configmap.yaml
kubectl -n blue-team get configmap shared-banner -o yaml
kubectl -n green-team get configmap shared-banner -o yaml
kubectl -n other-team get configmap shared-banner -o yaml
会看到:
blue-team和green-team能拿到镜像other-team拿不到,因为它的标签不匹配
学习点:
- 选择器语法遵循 Kubernetes 官方标签选择器规则
- 这比手写一长串命名空间更适合规模化管理
- 官方说明里,命名空间列表和选择器是“或”的关系
建议再做一个扩展实验¶
目标:观察自动镜像遇到同名资源冲突时的行为。
步骤:
- 先在
team-a手动创建一个名字也叫shared-login的Secret - 再应用
02-auto-secret.yaml - 查看日志:
理解:
- 自动镜像不会强制覆盖已有同名对象
- 生产环境里要先规划好共享资源命名
生产环境使用建议¶
- 对
Secret一定要缩小允许同步的命名空间范围 - 尽量优先用标签选择器,而不是人工维护很长的命名空间名单
- 如果是多租户集群,先验证租户边界,再决定是否允许跨命名空间复制密钥
官方来源¶
- 官方仓库:
https://github.com/emberstack/kubernetes-reflector - 官方 README:
https://raw.githubusercontent.com/emberstack/kubernetes-reflector/master/README.md - 官方 Helm 发布页:
https://artifacthub.io/packages/helm/emberstack/reflector - Kubernetes 官方标签选择器文档:
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/