用 Kubernetes 与 GitOps 搭建云原生内部开发者平台:从集群到软件供应链的安全闭环

2026-05-29 34 预计阅读时间:1 分钟
来源:cncf.io AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:10 分钟

现代软件交付的瓶颈早已不在应用代码本身——它卡在跑代码的平台上。团队写好了服务,却要花大量时间处理集群配置、权限审批、镜像签名、环境漂移。内部开发者平台(Internal Developer Platform,IDP)的目标就是把这些摩擦抹掉:开发者声明"我要一个生产环境的前端服务",平台自动完成从集群分配到镜像构建到安全校验到部署的全链路。

下面拆解一个基于 Kubernetes + GitOps + 供应链安全的 IDP 设计,并给出可直接改造的配置示例。

平台的核心抽象:从"申请机器"到"声明工作负载"

传统模式下,开发者提工单申请虚拟机、配网络、装运行时。云原生 IDP 把这一切收进 Kubernetes 的声明式 API 里:

  • 工作负载:Deployment / StatefulSet / CronJob,开发者只关心容器镜像与资源需求。
  • 环境边界:Namespace + RBAC + NetworkPolicy,平台自动生成,开发者不需要手动划分。
  • 交付流程:GitOps 仓库里的 manifest 即最终状态,集群只是执行者。

关键转变——开发者不再操作集群,而是操作 Git 仓库里的声明文件。平台负责把声明翻译成集群状态并持续校验。

GitOps 交付:ArgoCD + 多仓库分层

GitOps 的核心承诺:Git 仓库是唯一可信源,集群状态必须与仓库内容一致。在 IDP 中,推荐把仓库拆成两层:

层级 仓库内容 谁修改
应用层 服务镜像版本、环境变量、副本数 开发者 / CI
平台层 Namespace 模板、RBAC、限流策略、安全策略 平台团队

ArgoCD 监听两个仓库,用 AppSetApplication 把它们组合起来推送到集群。这样做的好处:平台团队改安全策略,不需要逐个通知应用团队——ArgoCD 自动同步。

一个最小化的 ArgoCD ApplicationSet 示例:

# argocd-appset.yaml — 按集群+环境自动生成 Application
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: frontend-services
  namespace: argocd
spec:
  generators:
    - matrix:
        generators:
          - list:
              elements:
                - cluster: dev
                  url: https://k8s-dev.example.com
                - cluster: staging
                  url: https://k8s-staging.example.com
                - cluster: prod
                  url: https://k8s-prod.example.com
          - git:
              repoURL: https://git.example.com/platform/env-templates
              files:
                - path: "frontend/**/*.yaml"
  template:
    metadata:
      name: '{{cluster}}-frontend-{{path.basename}}'
    spec:
      project: frontend
      source:
        repoURL: https://git.example.com/apps/frontend
        targetRevision: main
        path: '{{path.basename}}'
      destination:
        server: '{{url}}'
        namespace: frontend-{{cluster}}
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
          - CreateNamespace=true

部署这个 ApplicationSet:

# 在已安装 ArgoCD 的集群上执行
kubectl apply -f argocd-appset.yaml

# 查看生成的 Applications
argocd app list --project frontend

开发者只需在应用仓库更新镜像标签,ArgoCD 就会把变更同步到对应集群。平台团队在 env-templates 仓库里加一条 NetworkPolicy,所有环境自动生效。

供应链安全:从镜像构建到集群准入的三道门

GitOps 解决了"怎么部署",但没回答"部署的东西是否可信"。供应链安全在 IDP 里至少要覆盖三个环节:

第一道门:镜像构建时签名

CI 流程用 Cosign 对镜像签名,证明"这个镜像由这条流水线产出":

# CI 中构建并推送镜像后,用 Cosign 签名
export COSIGN_EXPERIMENTAL=1
cosign sign \
  --key cosign.key \
  registry.example.com/frontend:v1.2.3

# 签名记录会存入 OCI registry 的 referrers tag
cosign verify \
  --key cosign.pub \
  registry.example.com/frontend:v1.2.3

cosign.pub 放进平台层的 GitOps 仓库,集群准入策略引用这个公钥。

第二道门:集群准入控制(Kyverno / OPA Gatekeeper)

用 Kyverno 策略强制:只有经过可信签名且来自允许 registry 的镜像才能运行:

# kyverno-verify-image.yaml — 阻止未签名镜像启动
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-frontend-images
spec:
  validationFailureAction: Enforce
  background: false
  rules:
    - name: verify-signature
      match:
        any:
          - resources:
              kinds:
                - Deployment
                - StatefulSet
              namespaces:
                - frontend-dev
                - frontend-staging
                - frontend-prod
      verifyImages:
        - imageReferences:
            - "registry.example.com/frontend/*"
          attestors:
            - entries:
                - keys:
                    public: |-
                      -----BEGIN PUBLIC KEY-----
                      MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
                      -----END PUBLIC KEY-----
          attestations:
            - type: https://example.com/provenance
              conditions:
                - all:
                    - key: "{{ ci_pipeline }}"
                      operator: Equals
                      value: "frontend-ci"
# 安装 Kyverno(如果集群尚未安装)
kubectl create namespace kyverno
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno kyverno/kyverno -n kyverno

# 部署准入策略
kubectl apply -f kyverno-verify-image.yaml

# 测试:部署一个未签名镜像,应被拒绝
kubectl run test-unsigned --image=registry.example.com/frontend:v0.0.1 -n frontend-dev
# 预期输出:Error from server: admission webhook "verify-frontend-images.kyverno.svc" denied the request

第三道门:SBOM 与漏洞扫描准入

在 CI 中生成 SBOM 并用 Cosign atttach 为镜像附加 provenance attestation。集群准入策略可以进一步校验 attestation 里的漏洞扫描结果是否在阈值内。这一层实现成本较高,建议先落地签名准入,再逐步叠加 SBOM 校验。

开发者自助:Backstage 统一入口

GitOps 仓库 + Kyverno 策略构成了平台的"后端"。开发者需要一个不碰 YAML 的入口——Backstage(Spotify 开源的开发者门户)在这里出场:

  • 软件模板:开发者点"创建新服务",Backstage 调用模板引擎在 GitOps 应用仓库里生成骨架项目 + ArgoCD Application。
  • 服务目录:展示所有服务在 dev / staging / prod 的运行状态,直接从 ArgoCD API 拉取。
  • TechDocs:每个服务的文档随仓库走,Backstage 自动聚合。

一个 Backstage 软件模板的简化定义(放在 templates/ 目录):

# backstage-template.yaml — 创建新前端服务的模板
apiVersion: scaffolder.backstage.io/v1
kind: Template
metadata:
  name: frontend-service
  title: Frontend Service Template
spec:
  owner: platform-team
  type: service
  parameters:
    - title: Service Info
      required:
        - serviceName
        - owner
      properties:
        serviceName:
          title: Service Name
          type: string
          pattern: '^[a-z][a-z0-9-]{4,20}$'
        owner:
          title: Team
          type: string
          ui:field: OwnerPicker
  steps:
    - id: scaffold
      name: Generate Skeleton
      action: fetch:template
      input:
        url: ./skeleton
        values:
          serviceName: '{{parameters.serviceName}}'
          owner: '{{parameters.owner}}'
    - id: publish
      name: Push to Git
      action: publish:gitlab
      input:
        repoUrl: 'gitlab.example.com?owner=apps&repo={{parameters.serviceName}}'
    - id: register
      name: Register in Backstage
      action: catalog:register
      input:
        catalogInfoUrl: 'https://gitlab.example.com/apps/{{parameters.serviceName}}/catalog-info.yaml'
  output:
    links:
      - title: Open Repo
        url: 'https://gitlab.example.com/apps/{{parameters.serviceName}}'

开发者填表 → Backstage 生成代码骨架 → 推到 GitOps 仓库 → ArgoCD 检测到新路径自动同步 → Kyverno 校验镜像签名 → 服务上线。全程开发者没有碰 kubectl

落地路线与取舍

阶段 做什么 先不做什么
第一阶段 ArgoCD + 双仓库分层 + Namespace 自动创建 SBOM 准入、复杂 RBAC 自动化
第二阶段 Cosign 签名 + Kyverno 签名准入 多集群联邦、跨云迁移
第三阶段 Backstage 软件模板 + TechDocs 自定义 UI、插件生态
第四阶段 SBOM attestation + 漏洞阈值准入 全链路 SLSA Level 3

几个容易踩的坑:

  1. ArgoCD selfHeal 与手动操作的冲突:如果开发者绕过 GitOps 直接 kubectl edit,ArgoCD 的 selfHeal 会把手动改动回滚。要么禁止直接操作集群,要么在特定 Namespace 关闭 selfHeal。
  2. 签名密钥管理:Cosign 的私钥不能放在 CI 环境变量里。用 KMS 后端(HashiCorp Vault / AWS KMS)托管,CI 通过 KMS API 签名。
  3. Kyverno 策略过严:初期建议 validationFailureAction: Audit,观察一段时间再切换到 Enforce。直接拦截会导致开发者无法快速调试。

云原生 IDP 不是买一个产品装上就完事——它是 Kubernetes 声明式能力 + GitOps 同步机制 + 供应链安全校验的组合拳。先从 ArgoCD 双仓库分层起步,让开发者习惯"改 Git 而不是改集群";再叠加镜像签名与准入策略,把信任链从 CI 延伸到运行时;最后用 Backstage 把自助能力暴露给团队。每一层都有可复制的配置可以上手,不需要一步到位。


相关推荐