前言
当多个团队共享一个 Flux 实例时,需要隔离权限------A 团队不能操作 B 团队的应用。Flux 用 Tenant 模型实现这一点,通过命名空间隔离 + RBAC + ServiceAccount 实现。
一、Tenant 模型设计
隔离架构
Flux 实例(flux-system 命名空间)
│
├── Tenant: team-alpha
│ ├── 命名空间: team-alpha
│ ├── ServiceAccount: team-alpha-sa
│ ├── Role: 只能操作 team-alpha-* 命名空间
│ ├── GitRepository: team-alpha-repo
│ └── Kustomization: team-alpha-apps
│
├── Tenant: team-beta
│ ├── 命名空间: team-beta
│ ├── ServiceAccount: team-beta-sa
│ ├── Role: 只能操作 team-beta-* 命名空间
│ ├── GitRepository: team-beta-repo
│ └── Kustomization: team-beta-apps
│
└── Tenant: platform
├── 命名空间: platform
├── ServiceAccount: platform-sa
├── Role: 可以操作 kube-system 等命名空间
└── ...
隔离原理
1. 每个 Tenant 有独立的命名空间
2. 每个 Tenant 有独立的 ServiceAccount
3. Kustomization 通过 serviceAccountName 指定用哪个 SA 执行
4. RBAC 限制每个 SA 只能操作特定命名空间
5. 结果: team-alpha 的 Kustomization 只能部署到 team-alpha-* 命名空间
二、创建 Tenant
方式一:手动创建
yaml
# 1. 创建 Tenant 命名空间
apiVersion: v1
kind: Namespace
metadata:
name: team-alpha
labels:
fluxcd.io/tenant: team-alpha
---
# 2. 创建 ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: team-alpha-sa
namespace: team-alpha
---
# 3. 创建 Role(限制操作范围)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: team-alpha-role
namespace: team-alpha
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
# 这个 Role 只在 team-alpha 命名空间内有效
---
# 4. 绑定 Role 和 ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: team-alpha-binding
namespace: team-alpha
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: team-alpha-role
subjects:
- kind: ServiceAccount
name: team-alpha-sa
namespace: team-alpha
---
# 5. 跨命名空间权限(允许 team-alpha 部署到 team-alpha-apps-* 命名空间)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: team-alpha-apps-role
namespace: team-alpha-apps
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: team-alpha-apps-binding
namespace: team-alpha-apps
subjects:
- kind: ServiceAccount
name: team-alpha-sa
namespace: team-alpha
roleRef:
kind: Role
name: team-alpha-apps-role
方式二:用 Flux Tenant Helm Chart
yaml
# 用 HelmRelease 创建 Tenant
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: team-alpha-tenant
namespace: team-alpha
spec:
chart:
spec:
chart: flux-tenant
sourceRef:
kind: HelmRepository
name: fluxcd-extra
namespace: flux-system
values:
serviceAccountName: team-alpha-sa
namespaces:
- team-alpha
- team-alpha-apps
roleRules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
三、配置 Tenant 的 GitRepository 和 Kustomization
GitRepository
yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: team-alpha-repo
namespace: team-alpha # 在 Tenant 命名空间中
spec:
url: https://github.com/myorg/team-alpha-deploy.git
ref:
branch: main
interval: 30s
secretRef:
name: team-alpha-git-creds
Kustomization
yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: team-alpha-apps
namespace: team-alpha # 在 Tenant 命名空间中
spec:
serviceAccountName: team-alpha-sa # ← 关键:指定 Tenant 的 SA
sourceRef:
kind: GitRepository
name: team-alpha-repo
namespace: team-alpha
path: ./overlays/prod
interval: 1m
prune: true
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: myapp
namespace: team-alpha-apps # 部署到 team-alpha-apps 命名空间
踩坑提示 :
serviceAccountName是隔离的关键。如果不指定,Flux 用默认的 SA(有集群管理员权限),所有 Tenant 都能操作所有命名空间。必须为每个 Tenant 创建独立的 SA 并绑定限制性 Role。
四、Tenant 权限验证
测试隔离
bash
# 模拟 team-alpha 的 SA 尝试操作其他团队命名空间
kubectl auth can-i create deployments \
--as=system:serviceaccount:team-alpha:team-alpha-sa \
-n team-beta-apps
# 输出: no ← 正确!team-alpha 不能操作 team-beta
kubectl auth can-i create deployments \
--as=system:serviceaccount:team-alpha:team-alpha-sa \
-n team-alpha-apps
# 输出: yes ← 正确!team-alpha 可以操作自己的命名空间
网络隔离
yaml
# NetworkPolicy 进一步隔离 Tenant
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: team-alpha-isolation
namespace: team-alpha-apps
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
fluxcd.io/tenant: team-alpha
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53 # 允许 DNS
- to:
- namespaceSelector:
matchLabels:
fluxcd.io/tenant: team-alpha # 只能访问自己的命名空间
五、多集群管理
一个 Git 仓库管理多集群
deploy-repo/
├── clusters/
│ ├── prod-east/ # 华东生产集群
│ │ ├── flux-system/ # Flux 自身
│ │ ├── infrastructure/
│ │ └── apps/
│ ├── prod-west/ # 华西生产集群
│ │ ├── flux-system/
│ │ ├── infrastructure/
│ │ └── apps/
│ └── staging/ # 预发集群
│ ├── flux-system/
│ ├── infrastructure/
│ └── apps/
├── base/ # 共享配置
└── overlays/
每个集群独立 Bootstrap
bash
# 在 prod-east 集群
flux bootstrap github \
--owner=myorg \
--repository=myapp-deploy \
--path=clusters/prod-east
# 在 prod-west 集群
flux bootstrap github \
--owner=myorg \
--repository=myapp-deploy \
--path=clusters/prod-west
共享基础配置
yaml
# clusters/prod-east/apps/myapp.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: myapp
namespace: flux-system
spec:
sourceRef:
kind: GitRepository
name: flux-system
namespace: flux-system
# 引用共享的基础配置 + 集群特定覆盖
path: ./base/myapp # 共享基础
interval: 1m
prune: true
# 集群特定的补丁
patches:
- target:
kind: Deployment
name: myapp
patch: |
- op: replace
path: /metadata/annotations/cluster-region
value: east
六、本篇要点回顾
- Tenant 模型:每个团队独立命名空间 + ServiceAccount + RBAC
serviceAccountName是隔离关键------指定 Kustomization 用哪个 SA 执行- RBAC + Namespace 限制 SA 只能操作特定命名空间
- NetworkPolicy 实现网络隔离,Tenant 之间不能互相访问
- 多集群:每个集群独立运行 Flux,从同一个 Git 仓库不同路径读取配置
下一篇预告:《通知与告警:Webhook 集成与事件通知》------学习如何让 Flux 在同步成功/失败时自动通知团队。