【GitOps·Flux篇】多集群与多租户:Tenant 模型与权限隔离

前言

当多个团队共享一个 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

六、本篇要点回顾

  1. Tenant 模型:每个团队独立命名空间 + ServiceAccount + RBAC
  2. serviceAccountName 是隔离关键------指定 Kustomization 用哪个 SA 执行
  3. RBAC + Namespace 限制 SA 只能操作特定命名空间
  4. NetworkPolicy 实现网络隔离,Tenant 之间不能互相访问
  5. 多集群:每个集群独立运行 Flux,从同一个 Git 仓库不同路径读取配置

下一篇预告:《通知与告警:Webhook 集成与事件通知》------学习如何让 Flux 在同步成功/失败时自动通知团队。

相关推荐
heimeiyingwang1 天前
【GitOps·Flux篇】核心概念:Source、Kustomization与HelmRelease
helm·flux·gitops
heimeiyingwang6 天前
【GitOps·ArgoCD篇】RBAC与多租户:团队权限隔离实战
argocd·gitops
heimeiyingwang6 天前
【GitOps·ArgoCD篇】健康检查与资源钩子:自定义健康状态
argocd·gitops
heimeiyingwang7 天前
【GitOps·ArgoCD篇】与 Kustomize 集成:多环境配置管理
kustomize·argocd·gitops
heimeiyingwang8 天前
【GitOps·ArgoCD篇】同步策略:自动同步、手动同步与同步钩子
argocd·gitops
heimeiyingwang12 天前
【GitOps·入门篇】工具生态:ArgoCD、Flux、Jenkins X 对比选型
jenkins·flux·argocd·gitops
BIG-HO3 个月前
AI绘画新选择:麦橘超然与主流模型对比实测
flux·图像生成·星图gpu·中文ai绘画
递归尽头是星辰3 个月前
云原生部署架构演进:基于 Helm 的 GitOps 落地选型
helm·gitops·云原生部署·ci/cd 架构·k8s 配置管理
zhao00664 个月前
flux + kubernetes + gitops + Kustomization
kubernetes·gitops