diff --git a/docs/en/solutions/Alauda_DevOps_Best_Practices_Overview.md b/docs/en/solutions/Alauda_DevOps_Best_Practices_Overview.md
index 92907537b..2fd94ae4d 100644
--- a/docs/en/solutions/Alauda_DevOps_Best_Practices_Overview.md
+++ b/docs/en/solutions/Alauda_DevOps_Best_Practices_Overview.md
@@ -6,6 +6,7 @@ kind:
- Best Practices
ProductsVersion:
- 4.x
+id: KB261000020
---
# Alauda DevOps Best Practices: Overview and Scenario Guide
diff --git a/docs/en/solutions/From_Commit_to_Production_on_ACP.md b/docs/en/solutions/From_Commit_to_Production_on_ACP.md
index d24900956..ebef2cab6 100644
--- a/docs/en/solutions/From_Commit_to_Production_on_ACP.md
+++ b/docs/en/solutions/From_Commit_to_Production_on_ACP.md
@@ -6,6 +6,7 @@ kind:
- Best Practices
ProductsVersion:
- 4.x
+id: KB261000023
---
# From Commit to Production on ACP: Choosing Triggers, Deployment, and Release Controls
diff --git a/docs/en/solutions/Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md b/docs/en/solutions/Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md
index edd64834d..cbe828ca5 100644
--- a/docs/en/solutions/Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md
+++ b/docs/en/solutions/Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md
@@ -6,6 +6,7 @@ kind:
- Best Practices
ProductsVersion:
- 4.x
+id: KB261000025
---
# Managing Platform Configuration and Onboarding Isolated Projects with Argo CD and Tekton on ACP
diff --git a/docs/zh/solutions/Alauda_DevOps_Best_Practices_Overview.md b/docs/zh/solutions/Alauda_DevOps_Best_Practices_Overview.md
new file mode 100644
index 000000000..f99d35206
--- /dev/null
+++ b/docs/zh/solutions/Alauda_DevOps_Best_Practices_Overview.md
@@ -0,0 +1,193 @@
+---
+products:
+ - Alauda Container Platform
+ - Alauda DevOps
+kind:
+ - Best Practices
+ProductsVersion:
+ - 4.x
+id: KB261000020
+sourceSHA: 33733012cccdfec1c058e61b87b7c180ce897a5b15a18412a7e35341e7e4131e
+---
+
+# Alauda DevOps 最佳实践:概述与场景指南
+
+一个从一个代码库开始的团队通常需要首先获得构建和测试结果。一旦这项工作完成,问题就会改变:经过测试的镜像如何到达生产环境,谁来批准它,以及在另一个团队可以使用相同流程之前,平台必须准备什么?本系列将按顺序解决这些问题。它解释了如何选择和组合功能,然后指向实现选择所需的产品说明和参考文件。
+
+配置基线是 Alauda DevOps Pipelines 4.15、Artifact Hub Shim 1.0、Connectors 1.14 和 Alauda Container Platform GitOps 4.4,适用于兼容的 ACP 安装。在选择软件包时,请遵循每个组件的兼容性要求。示例使用 GitLab、Harbor、Nexus 和 SonarQube。参考设计要求在生产使用之前进行环境准备和验收检查。
+
+## 如何使用本指南
+
+根据您当前面临的问题选择一个条目:
+
+| 您的起点 | 您需要决定的事项 | 接下来阅读 |
+| ------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| 您有一个代码库,或一个没有代码库的简单作业,并希望有一个可工作的管道。 | 定义存放在哪里以及如何启动它。 | [启动管道](#start-a-pipeline)。 |
+| 管道已经在运行,但构建、测试和发布是分开的手动活动。 | 如何在环境之间传递相同的镜像,以及在哪里引入发布控制。 | [连接交付阶段](#connect-the-delivery-stages),然后 [从提交到生产](./From_Commit_to_Production_on_ACP.md)。 |
+| 多个团队将共享平台,每个项目都需要重复的管理。 | 在将平台交给项目之前,哪些设置和责任需要标准化。 | [准备共享平台](#prepare-a-shared-platform),然后 [管理平台配置和引导隔离项目](./Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md)。 |
+
+下面的每个场景解释了何时某个功能有帮助,它如何与其他功能相适应,以及在哪里继续。交付和平台文章详细说明了选择、配置点和预期结果。有关应用工作流的指导实现,请使用 [原生应用 CI/CD 教程](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/tutorials/index.html)。
+
+[伴随示例](https://github.com/AlaudaDevops/devops-best-practices-samples)包含一个平台代码库、项目声明、引导管道、项目 GitOps 模板、原生应用 CI/CD 和验收脚本。它们是需要适应的参考文件。在使用之前,请替换示例地址、镜像、身份和加密凭证占位符。文章解释了决策和边界,因此阅读文件并不是理解设计的先决条件。
+
+## 整体设计
+
+该设计有三个层次。**交付层**跟踪从源到运行应用程序的一个变化。**平台层**提供定义、工具访问和项目环境,使该路径可重复。**控制层**在路径的特定点放置授权和证据检查。
+
+```mermaid
+flowchart TB
+ subgraph Controls[控制层]
+ Policy[管道和镜像准入]
+ Approval[发布批准]
+ Audit[运行和日志保留]
+ end
+ subgraph Delivery[交付层]
+ Source[源代码库] --> Trigger[PaC 或触发器]
+ Trigger --> Build[构建和扫描]
+ Build --> Image[由摘要标识的镜像]
+ Image --> Test[测试部署]
+ Test --> Promote[提升所选摘要]
+ Promote --> Production[生产 GitOps 变更]
+ end
+ subgraph Platform[平台层]
+ Catalog[版本化目录管道和任务]
+ Connectors[项目和管理员连接器]
+ Git[平台配置和项目声明]
+ end
+ Policy -.-> Trigger
+ Policy -.-> Production
+ Approval -.-> Promote
+ Audit -.-> Build
+ Catalog -.-> Build
+ Connectors -.-> Build
+ Git -.-> Connectors
+```
+
+| 层级 | 这里包含的内容 | 决策者 |
+| ------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
+| 交付 | 源、触发器、构建和扫描结果、镜像摘要、测试部署和生产变更。 | 应用开发人员和项目维护者。 |
+| 平台 | 组件设置、版本化目录内容、管理员连接器、加密凭证、项目声明和部署边界。 | 平台管理员。 |
+| 控制 | 所需的合并检查、发布批准、提升访问、镜像准入和保留的审计证据。 | 平台管理员和指定的发布批准者。 |
+
+这些层级有不同的协调所有者。Argo CD 协调在平台或项目 GitOps 代码库中跟踪的对象。引导创建或协调命名空间、项目连接器和外部工具租户;Argo CD 不会自动管理这些外部操作。ACP 创建与其项目同名的命名空间,引导采用该命名空间。为每个资源或字段分配一个所有者,以避免两个控制器反复相互撤销。
+
+分离构建和发布身份也很重要。开发人员可以生成候选镜像;发布决策在检查其构建和测试证据后授权特定摘要。签名、批准和生产 Git 更改各自建立该记录的不同部分。
+
+
+
+## 启动管道
+
+对于单个应用程序,首先决定谁应该维护定义,以及定义更改是否需要与源更改相同的审查历史。一个简单的手动操作作业可以在集群中启动。希望进行合并请求检查的团队可以从 PaC 中受益。当多个项目共享相同的工作流时,集中实施并让项目提供输入。
+
+| 模型 | 定义和执行 | 选择它的时机 | 您承担的责任 |
+| ------------------------- | ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
+| 集群中的管道 | 在项目命名空间中维护管道;在运行模板中保存参数、工作区和集成。 | 少量作业需要简单的入口,包括没有代码库的作业。 | 通过平台流程维护定义历史和权限控制。 |
+| 代码作为管道 (PaC) | 将 PipelineRun 定义保存在 `.tekton/` 中;代码库事件启动运行并报告结果。 | 定义应随源演变,审查者需要在合并请求上进行检查。 | 必须管理对代码库的访问、Webhook 交付、定义来源和提议源可用凭证。 |
+| 集中管理的模板 | 发布版本化目录管道,或在受控命名空间中维护管道;项目引用它。 | 多个项目需要共享流程并进行有意识的升级。 | 平台拥有兼容性和发布版本;项目仍然拥有其输入和采用。 |
+
+这些选择可以共存。PaC 可以通过解析器引用中央管道,仅在 `.tekton/` 中保留触发器注释和项目输入。运行模板可以将同一集中维护的工作流暴露给手动、事件驱动和计划执行。因此,中央重用不需要放弃代码库的审查体验。
+
+从 [运行模板](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/how_to/run_template.html)、[配置 GitLab 代码库](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/guides/configure_gitlab_repo.html)、[配置 GitHub 代码库](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/guides/configure_github_repo.html) 或 [通过 Hub 管道和运行模板进行集中管理](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/how_to/hub_pipeline_run_template_centralized_management.html) 开始。交付文章解释了这两条事件路径如何连接到这些定义。
+
+### 选择工作开始的方式
+
+| 工作应开始的时机 | 入口 | 典型原因 |
+| ------------------------ | -------------------------------------------------- | ---------------------------------------------------------------- |
+| 有人请求它 | 从运行模板控制台或渲染的 PipelineRun。 | 首次验证、回归运行或发布决策。 |
+| 代码更改 | PaC,或带有运行模板的触发器。 | 验证合并请求或在合并后构建。 |
+| 发生工件事件 | Harbor 事件触发器。 | 将镜像摘要传递给后续阶段。 |
+| 间隔时间到达 | ScheduledTrigger。 | 协调工具资源、轮换凭证或进行定期检查。 |
+| 另一个系统请求它 | 传入 Webhook。 | 变更管理系统或内部门户启动工作。 |
+
+对于同一代码事件,请使用一种路径,PaC 或触发器。两者都可以创建运行,因此将两者连接到该事件可能会重复工作。当代码库审查体验是核心时,优先选择 PaC;当平台拥有事件映射和运行模板时,使用触发器。计划对于协调非常有用,因为它重用与手动恢复运行相同的输入和执行定义。
+
+对于来自合并请求的 PaC 重试,请在合并请求中评论 `/test branch:`。PaC 使用合并请求的源分支进行该评论;`branch:` 记录预期的源,但不会将合并请求切换到另一个分支。要运行不同的分支,请在该分支的最新提交上发布相同的命令。发布候选 `ci` 示例有一个额外的运行时限制,下面描述;它故意拒绝评论重试。有关完整语法,请参见 [触发 PaC 管道](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/how_to/trigger_pipeline.html)。
+
+对于传入的 Webhook,向 PaC 控制器的 `/incoming` 端点发送带有 JSON 主体的 HTTP `POST` 请求。五个字段标识代码库、命名空间、分支、PipelineRun 定义和共享密钥:
+
+```bash
+# PAC_CONTROLLER_URL is the platform-provided controller endpoint.
+curl -i -X POST "$PAC_CONTROLLER_URL/incoming" \
+ -H 'Content-Type: application/json' \
+ -d '{"repository":"","namespace":"","branch":"main","pipelinerun":"","secret":""}'
+```
+
+仅在返回 HTTP `202` 并且出现新的 PipelineRun 时,将请求视为已接受。空的 HTTP `200` 可能意味着没有匹配的运行,例如因为密钥不匹配。将密钥保存在调用者的凭证管理中。控制器配置、路由暴露和身份验证是平台先决条件;请参见 [传入 Webhooks](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/how_to/incoming_webhooks.html)。
+
+
+
+## 连接交付阶段
+
+一旦 CI 运行,接下来的问题是保持构建、测试和发布之间的关系。在阶段之间传递 `repository@sha256:`。标签有助于某人识别发布,但移动标签并不会改变在环境的部署配置中记录的摘要。
+
+对于开发或测试,直接工作负载更新可能就足够了。生产通常需要经过审查的期望状态记录,这使得 GitOps 变更成为有用的部署入口。将生产工件项目分离增加了另一个决策:谁可以将批准的候选项复制到该项目中?为每个决策添加相应的控制。
+
+| 情况 | 组合和原因 | 继续进行 |
+| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
+| 一次提交必须生成可追踪的、经过测试的镜像。 | 重用目录任务进行构建和扫描,然后保留结果摘要和运行证据。 | [从提交到生产](./From_Commit_to_Production_on_ACP.md)。 |
+| 测试应快速更新且其状态的 Git 历史不必要。 | 通过授权的工作负载或 Helm 任务直接部署摘要。 | [原生应用 CI/CD 教程](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/tutorials/index.html)。 |
+| 生产状态必须经过审查并可从 Git 恢复。 | 通过合并请求更新生产 GitOps 参考,然后让 Argo CD 进行协调。 | [GitOps](https://docs.alauda.io/gitops/4.4/)。 |
+| 构建和生产注册表访问必须分开。 | 将所选摘要复制到具有发布身份的私有生产项目中。 | [使用 Skopeo 复制提升工件](https://docs.alauda.io/alauda-devops-artifacthub-shim/1.0/catalog/how_to/promote_artifacts_with_skopeo_copy.html)。 |
+| 需要一个人授权发布并留下记录。 | 添加 ApprovalTask 并保留其响应;在需要时配置单独的 Git 审查。 | [手动批准门](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/how_to/manual_approval_gate.html)。 |
+| 部署必须检查平台控制的签名者。 | 在发布和准入之前集中配置 Chains 并验证摘要。 | [签名密钥配置](https://docs.alauda.io/alauda-devops-pipelines/4.15/chains/configure/signing_key_configuration.html)。 |
+| 注册表应将镜像传递给后续阶段。 | 将 Harbor 事件的摘要传递到下一个运行并检查其 CI 证据。 | [Harbor 事件触发器](https://docs.alauda.io/alauda-devops-pipelines/4.15/triggers/how_to/harbor_events.html)。 |
+
+镜像推送事件确认镜像已到达。提升确认字节通过选定路径复制。两者都不能确认 CI 通过。批准者必须将摘要与成功的受信任构建、扫描和测试部署相关联。签名建立配置的签名者的声明;其含义取决于谁控制密钥以及哪些定义和源被允许使用签名路径。
+
+### 交付示例的选择
+
+该示例在测试和生产中都使用 GitOps,以便测试使用与生产相同的同步路径。测试更改直接提交;生产更改提出合并请求。它使用单独的源和生产注册表项目,具有单独的发布身份和在复制之前的批准节点。这些是与您自己的审查和工件访问要求进行比较的示例选择。
+
+测试 CD、提升和生产 CD 在示例中手动启动,并采用前一阶段的摘要。这使每个交接都可见,同时建立工作流,但手动摘要输入是示例的后备,而不是目标操作模型。生产工作流应将摘要从受信任的 CI 结果传递到经过审查的触发输入。Harbor 驱动的自动化可以在事件身份验证、参数映射和 CI 结果关联配置后添加。第一次生产部署等待第一次提升的镜像及其经过审查的生产 GitOps 更改。
+
+对于此示例,受信任的 CI 结果是 `ci`,用于 `main` 上的 `push`。预构建检查读取实际的 PaC 事件和分支注释,并在构建之前拒绝评论触发的 `ci` 运行,包括对 `main` 的评论。合并请求使用单独的定义和临时镜像代码库。共享项目凭证仍覆盖两个代码库;需要单独的临时注册表项目和受限凭证,以防止提议的源写入发布候选项。
+
+
+
+## 准备共享平台
+
+随着更多团队的加入,重复的管理成为一个所有权问题。平台必须决定每个项目接收哪些定义、工具资源、凭证、政策和保留设置。在引导之前标准化这些决策,然后让项目在既定边界内选择其特定于应用程序的工作流。
+
+| 平台情况 | 方法和原因 | 详细指南 |
+| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| 管道需要工具而不分发管理员凭证。 | 使用项目连接器和代理工作负载令牌;单独跟踪剩余的长期凭证。 | [连接器代理](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors/concepts/connectors_proxy.html) 和 [CSI 驱动程序](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors/concepts/connectors_csi.html)。 |
+| 每个项目需要四个外部工具中的资源。 | 从经过审查的声明中协调四个连接器自动创建任务;为每个租户分配一个协调所有者。 | [引导和产品任务](./Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md#reuse-the-product-tasks)。 |
+| 平台设置仅存在于运行的集群中。 | 将组件设置、政策、加密凭证和项目声明保存在平台代码库中。 | [平台配置](./Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md)。 |
+| 团队不得更改彼此的环境或凭证。 | 分离命名空间和工具租户,限制部署身份,并验证有效访问。 | [项目边界](./Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md#accept-the-project-boundaries)。 |
+| 项目需要超出共享基线的限制。 | 将平台 ClusterPolicies 与项目政策结合;限制直接 TaskRun 和 CustomRun 创建,并可选地限制定义源。 | [管道执行约束](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/how_to/constrain_pipeline_execution_with_kyverno.html)。 |
+| 集群历史必须清理,同时审计证据保持可用。 | 选择 Pruner 设置和外部结果存储,并单独保留批准证据。 | [审计和恢复](./Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md#preserve-audit-records-and-plan-recovery)。 |
+| 凭证需要定期协调或更新。 | 调度相同的引导工作流,并设置故障警报和每个项目的并发锁。 | [ScheduledTrigger](https://docs.alauda.io/alauda-devops-pipelines/4.15/triggers/how_to/scheduledtriggers.html) 和 [协调](./Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md#reconcile-and-rotate-deliberately)。 |
+| 另一个系统启动工作。 | 暴露经过身份验证的传入 Webhook,并定义对调用者的接受和完成的含义。 | [传入 Webhooks](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/how_to/incoming_webhooks.html)。 |
+
+将 Kyverno `PolicyException` 的创建控制在平台管理员的控制之下。该例外可能削弱共享准入边界,因此不得留给本地项目政策或应用程序身份。
+
+代理工作负载令牌并未消除所有长期凭证的责任。镜像拉取密钥、PaC 克隆凭证和 Chains 注册表凭证仍需范围访问、轮换和恢复。可以在带有凭证的命名空间中创建 Pods 的项目所有者可以使用这些凭证。因此,管理员、发布和签名命名空间需要明确的运行创建边界。
+
+清理和归档也有共享后果。基于事件的 Pruner 默认设置可能会在第一次同步时影响每个命名空间,成功和失败的历史记录分别计算。在依赖于命名空间特定覆盖之前,将全局 Pruner 的 `enforcedConfigLevel` 设置为 `namespace`;否则,集群级别的值将保持有效。在启用删除之前,盘点租户及其保留需求。结果观察者可以在其观察范围内向完成的运行添加 `results.tekton.dev/*` 的最终处理程序;在启用之前定义该范围。禁用归档不会删除现有的最终处理程序。在清理之前遵循产品恢复程序,并验证在实时对象被修剪后仍然可以访问外部结果存储。
+
+[平台文章](./Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md) 解释了 18 项决策、其代码库层、引导输出、权限、轮换和接受。这些是管理员管理的设置;检查 [功能成熟度](https://docs.alauda.io/alauda-devops-pipelines/4.15/overview/feature_maturity.html) 并分阶段引入。平台代码库提供持久配置和审查记录。密钥、外部工具数据和结果存储需要单独备份。恢复项目注册可能会修剪 ACP 项目及其同名命名空间,因此请将该操作视为退役审查。
+
+## 选择采用路径
+
+| 团队现在需要什么 | 从哪里开始 | 当需求出现时添加 |
+| ------------------------------ | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
+| 少量作业。 | 集群管道和运行模板。 | PaC 用于源审查;当重用变得有价值时使用中央模板。 |
+| 可追踪的应用交付路径。 | 构建和扫描,传递摘要,并根据环境选择部署。 | 生产 Git 审查、批准、工件提升和根据发布边界的准入。 |
+| 用于隔离项目的平台。 | 共享基线、管理员先决条件和经过审查的项目声明。 | 调度协调、故意轮换、政策执行和在接受后保留审计证据。 |
+
+每一行都可以逐步采用。团队可以在集群中保留一个简单的作业,同时其主要应用程序使用 PaC 和共享目录管道。发布控制应满足环境的授权和证据要求。添加控制还会增加平台所有者、先决条件和操作恢复责任。
+
+## 在没有互联网访问的情况下操作
+
+通过批准的内部服务提供目录、固定工具和基础镜像、软件包依赖项、证书和漏洞数据库。运行时管道必须从本地目录或集群源解析任务和管道。示例将 Trivy 指向 `registry.example.com/mirror/trivy-db:2`;将其替换为可访问的数据库镜像并授予扫描器访问权限。
+
+网络隔离的程度、团队数量和所需的批准证据是平台团队的部署输入。容量规划、迁移和退役自动化、平台灾难恢复、客户变更管理集成和离线软件包分发程序需要自己的操作计划。本系列提供了开发这些计划的选择和配置边界。
+
+## 相关信息
+
+- [Pipelines 4.15](https://docs.alauda.io/alauda-devops-pipelines/4.15/)
+- [Artifact Hub Shim 1.0](https://docs.alauda.io/alauda-devops-artifacthub-shim/1.0/)
+- [Connectors 1.14](https://docs.alauda.io/alauda-devops-connectors/1.14/)
+- [GitOps 4.4](https://docs.alauda.io/gitops/4.4/)
+- [使用 Tekton 和 Kyverno 进行软件供应链安全](./Software_Supply_Chain_Security_of_Alauda_Container_Platform_with_Tekton_and_Kyverno.md)
+- [使用 Tekton 和 Kyverno 的管道政策约束](./Pipeline_Policy_Constraints_with_Tekton_and_Kyverno.md)
diff --git a/docs/zh/solutions/From_Commit_to_Production_on_ACP.md b/docs/zh/solutions/From_Commit_to_Production_on_ACP.md
new file mode 100644
index 000000000..aad3c1600
--- /dev/null
+++ b/docs/zh/solutions/From_Commit_to_Production_on_ACP.md
@@ -0,0 +1,493 @@
+---
+products:
+ - Alauda Container Platform
+ - Alauda DevOps
+kind:
+ - Best Practices
+ProductsVersion:
+ - 4.x
+id: KB261000023
+sourceSHA: d70d76330d3d8c63ee209b856ffaef9f532f1328f1c9e755325ac242accfa417
+---
+
+# 从提交到生产在 ACP 上:选择触发器、部署和发布控制
+
+在变更合并后,团队通常希望构建、检查并部署到测试环境,而不需要有人在系统之间传递镜像名称。生产环境引入了更多问题:应该发布哪个经过测试的镜像,谁可以授权它,以及应该在哪里记录所需的生产状态?
+
+当这些问题导致关于管道所有权、GitOps、批准或工件提升的选择时,请使用本文。它解释了替代方案及其后果,然后跟随伴随示例所做的选择。有关各个操作的指导实现,请参阅 [原生应用 CI/CD 教程](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/tutorials/index.html)。
+
+到最后,您应该能够解释:
+
+- 存储库的管道定义属于哪里,谁维护它,以及它是如何触发的。
+- 为什么每个环境使用直接部署或 GitOps,以及它如何接收所选的镜像摘要。
+- 生产环境是否需要工件复制、人为批准、批准门控凭证和部署接纳。
+- 每个控制生效的地方以及平台团队必须提供哪些前提条件。
+
+按照这个顺序处理这些决策。一个小项目可以通过手动运行启动,但目标工作流应该从受信任的 CI 结果中传递所选摘要,通过审核的输入。基于源的定义、中央模板和发布控制可以在其好处证明其所有权和运营成本时引入。
+
+这是 [Alauda DevOps 最佳实践](./Alauda_DevOps_Best_Practices_Overview.md) 的交付部分。其配置基线为 Pipelines 4.15、Artifact Hub Shim 1.0、Connectors 1.14 和 GitOps 4.4。项目命名空间、工具侧资源和 Connectors 必须已经存在;[平台文章](./Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md) 解释了它们的准备。
+
+[伴随示例](https://github.com/AlaudaDevops/devops-best-practices-samples) 使用一个虚构的 `shop` 项目。CI 在 `shop-build` 中运行;CD 和提升在 `shop-cd` 中运行;工作负载在 `shop-test` 和 `shop-prod` 中运行。示例仅绑定 `shop` 中的项目所有者组;应用 PaC 存储库、CD 和提升对象,以及启动它们的运行需要平台管理员或在 `shop-build` 和 `shop-cd` 中单独委派的授权。请参阅示例应用程序的 ["谁应用什么"](https://github.com/AlaudaDevops/devops-best-practices-samples/blob/main/sample-app/README.md#who-applies-what) 表。将每个示例地址、工具镜像、组、凭证占位符和策略身份替换为您的环境。确保漏洞数据库、工具镜像、基础镜像和依赖项在本地可用,以便进行离线执行。
+
+## 准备项目及其职责
+
+从一个工作项目管道和访问其代码及注册表开始。平台团队提供项目命名空间和 Connectors;它还将开发人员添加到 GitLab 租户组。入职创建该组,但不会同步其成员。没有所需组角色的开发人员无法创建应用程序存储库。
+
+将构建保留在单独的命名空间中,因为容器构建任务可能需要与应用程序工作负载不同的 Pod 安全级别。示例使用 `baseline` 作为 `shop-build`,并使用 `restricted` 作为工作负载命名空间。请参阅 [内置任务和受限标准](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/how_to/comply_with_pod_security_restricted.html#built-in-tasks-and-the-restricted-standard)。交付命名空间提供了一个单独的地方来控制发布执行;仅创建该命名空间并不会确定谁可以使用其凭证。
+
+本文保留每个交接的选择、前提条件、最小配置和证据在主要文本中。完整的任务参数和可执行的 PipelineRuns 存在于目录和伴随示例中。平台范围的设置、项目配置、保留和恢复在平台文章中描述。
+
+## 在工作流中跟踪一个镜像身份
+
+```mermaid
+flowchart TD
+ Commit[合并应用程序变更] --> CI[构建和扫描]
+ CI --> Source[按摘要从源注册表获取镜像]
+ Source --> Test[在测试中部署和验证]
+ Test --> Approve[批准所选摘要]
+ Approve --> Copy[将镜像复制到生产注册表]
+ Copy --> Sign[验证签名和来源]
+ Sign --> MR[审查生产 GitOps 变更]
+ MR --> Sync[Argo CD 同步和发布]
+```
+
+沿着这条路线的六个决策是定义所有权、触发、每个环境的部署、构建结果的转移、发布授权和执行。为一个步骤选择的工具并不决定其他步骤的决策。
+
+使用 `repository@sha256:` 进行部署、提升源、签名验证和审计关联。标签帮助人们识别发布;单独的标签无法识别不可变内容。记录存储库和摘要:当提升更改存储库时,内容身份可以保持不变,但权限和接纳规则依赖于该存储库。
+
+一个有用的起始设计是针对应用程序事件的 PaC、用于工作的目录任务、直接部署到测试和经过审核的 GitOps 变更用于生产。在发布边界需要它们的地方添加批准和工件复制。示例故意也在测试中使用 GitOps;原因在下面解释。Harbor 推送事件表明镜像已被推送。它并不表明成功的扫描、测试、签名或批准。
+
+当在已部署的镜像中发现漏洞时,修复它并使用相同的构建、提升和部署工作流发布新的摘要。保留构建证据和用发布记录替换易受攻击镜像的决策。
+
+## 选择定义的位置和运行的启动方式
+
+| 模型 | 定义位置 | 触发 | 适用场景 |
+| ----------------- | ---------------------------------------------------------------- | -------------------------------------------------- | ------------------------------------------------------ |
+| 集群管道 | 项目命名空间中的管道;运行模板中的执行设置 | 手动、触发器或计划触发器 | 少量集中操作的管道 |
+| 代码即管道 | 应用程序的 `.tekton/` 目录中的 PipelineRun 文件 | 推送和合并请求事件 | 与源和合并请求检查一起版本控制的定义 |
+| 中央模板 | 版本化的目录管道,或受控集群命名空间中的管道 | 运行模板或带有 `pipelineRef` 的 PaC PipelineRun | 跨项目共享标准 |
+
+### 当工作简单时,从集群管道开始
+
+项目命名空间中的管道适用于平台直接操作的少量工作,包括没有代码存储库的工作。将参数、工作区和集成保存在运行模板中,以便一个人、一个事件或一个计划可以调用相同的执行配置。如果工作需要源,`git-clone` 可以通过 Connector 获取它。
+
+好处是简单的入口和更少的存储库资源准备。缺点是定义审核和变更历史属于平台的配置过程。仅在实时集群中保留管道不会提供 Git 审核轨迹。此路径仍然可以构建相同的源并运行相同的任务。
+
+### 当工作流应随源演变时使用 PaC
+
+PaC 将 PipelineRun 定义保存在 `.tekton/` 中,选择它们用于存储库事件,并将结果报告给代码平台。这适合特定分支的行为和审核者应看到的检查。应用程序团队可以通过其正常审核流程提出定义更改。
+
+这种便利性将存储库访问、Webhook 交付、定义来源和合并前凭证暴露纳入范围。故意选择定义源;经过审核的定义仍然可以执行提议的应用程序代码。运行时凭证边界将在下面讨论。
+
+### 当项目共享流程时发布中央模板
+
+当许多存储库实现相同的构建和扫描序列时,将共享工作流维护与项目输入分开。平台发布一个版本化的目录管道,而每个项目提供其存储库、镜像位置和执行设置。当平台拥有其变更过程时,受控集群管道是另一个选择。
+
+好处是一个维护的工作流,具有一致的行为。成本是一个明确的兼容性合同:平台维护版本和任务,项目审核新版本的采用。发布新版本并不会升级每个消费者。中央模板可以通过运行模板或 PaC 使用;这是一个所有权选择,可以伴随任何触发路径。
+
+### 为每个工作选择一个事件路径
+
+原生应用 CI/CD 教程从集群管道和触发器开始。当源审核是自然入口时,PaC 提供了另一条路径。两者最终都会创建 PipelineRuns:
+
+```mermaid
+flowchart LR
+ Event[Git 或 Harbor 事件] --> Listener[事件监听器和拦截器]
+ Listener --> Binding[触发绑定和运行模板]
+ Schedule[计划触发器] --> Binding
+ Binding --> RunA[PipelineRun]
+ Code[Git 推送或合并请求] --> PaC[PaC 存储库和事件选择]
+ PaC --> RunB[来自 .tekton 的 PipelineRun]
+ RunA --> Shared[受控管道或目录版本]
+ RunB --> Shared
+```
+
+当平台拥有事件过滤和参数映射时使用触发器。当定义和检查应遵循存储库审核时使用 PaC。为相同事件和工作选择一条路径,因为启用两者可能会重复工作。同一项目可以在集群中保留简单工作,使用 PaC 进行其主要应用程序,并从两者中引用中央模板。
+
+对于从合并请求重试,请在合并请求上评论 `/test branch:`。PaC 使用该合并请求的源分支;`branch:` 参数记录源,但不选择其他分支。对于推送触发的运行,请在应运行的分支的最新提交上评论相同的形式。通过链接到 [触发 PAC 管道](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/how_to/trigger_pipeline.html) 保持完整语法在一个地方。
+
+仅当 Git 平台要求该检查通过时,失败的检查才会阻止合并。在 GitLab 上,启用 **管道必须成功**。如果 Auto DevOps 创建了一个额外的管道而没有运行器接管它,GitLab 管道可能会保持运行,合并请求继续显示正在运行的管道;对于这些存储库禁用 Auto DevOps 或提供一个运行器。
+
+### 将 PaC 与中央模板结合使用
+
+将事件注释和项目输入保留在 `.tekton/` 中。通过解析器和固定版本引用平台的管道。以下片段显示了应用程序示例使用的引用;这不是一个完整的 PipelineRun。使用示例的完整参数和工作区绑定。
+
+```yaml
+spec:
+ pipelineRef:
+ resolver: hub
+ params:
+ - name: catalog
+ value: catalog-pipelines
+ - name: kind
+ value: pipeline
+ - name: name
+ value: python-image-build-scan-deploy
+ - name: version
+ value: "0.3"
+```
+
+对于受控集群管道,使用 `resolver: cluster`。在 PaC 定义中避免使用裸 `pipelineRef.name`,当接纳必须检查定义的源时。请参阅 [解析器](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/concepts/resolver_concept.html) 和 [在 Git 中定义 PipelineRuns](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/how_to/maintain_pipeline_code.html)。
+
+通过审核更改其固定版本来升级目录管道。项目不会自动采用新发布的版本。为了可重现地回滚定义,保留审核版本并定义发布坐标是否不可变。运行模板的版本更改是对现有模板的更改,而不是创建另一个模板的理由。
+
+### 保护定义及其运行时凭证
+
+对于自管理的 GitLab 实例,在每个 PaC `Repository` 上设置 `spec.git_provider.url`。没有该 URL,本文中描述的 PaC 行为 [高级存储库配置](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/how_to/advanced_repository_config.html) 可能会将完成状态请求和存储库令牌发送到 `gitlab.com`。为应用程序、平台和项目 GitOps 存储库显式设置提供程序 URL。
+
+在预合并运行必须使用审核定义的地方设置 `spec.settings.pipelinerun_provenance: default_branch`。这选择定义,而不是受信任的应用程序代码:合并请求运行仍然使用该定义挂载的凭证构建提议的源。限制这些凭证,并将合并请求的镜像输出与发布候选分开。
+
+### 为什么示例将 PaC 和目录管道结合使用
+
+示例将触发器注释和项目输入保留在应用程序存储库中,并引用 `python-image-build-scan-deploy` 版本 `0.3`。审核者可以看到工作何时运行以及它写入的位置,而平台维护构建和扫描实现。版本引用使采用成为审核的项目变更,而不是立即在整个环境中推出。
+
+合并请求验证还会推送一个镜像,因为扫描器从注册表读取。因此,它需要一个单独的输出位置和短期保留策略。只有受信任的合并后路径旨在生成测试 CD 和提升的候选。示例将两个输出分开:
+
+| 定义 | 事件 | 镜像存储库 | 交付用途 |
+| ---------------------------------------- | -------------- | -------------------------------- | --------------------------------- |
+| `sample-app/.tekton/ci.yaml` | 推送到 `main` | `registry.example.com/shop/hello` | 测试 CD 和提升的源 |
+| `sample-app/.tekton/ci-merge-request.yaml` | 合并请求 | `registry.example.com/shop/hello-mr` | 临时合并请求工件 |
+
+发布候选定义还使用目录管道的预构建步骤,要求源和目标分支为 `main` 的 `push` 事件。它读取 PaC 的实际 Pod 注释,因为评论参数可以覆盖事件和分支模板变量。命名的 `/test ci` 命令可以绕过 PaC 事件注释,因此在 `build-image` 之前,它在运行时检查失败,即使在 `main` 上评论。使用新的审核推送重试发布候选 CI;使用 `ci-merge-request` 进行评论触发的验证。
+
+示例的 Harbor Connector 具有项目级访问权限。分离存储库名称并添加事件检查本身并不强制凭证边界:合并请求代码仍然使用可以写入该项目的凭证运行。为了更强的分离,使用一个不同的临时注册项目和一个不能写入发布候选镜像的凭证。在交付之前,将所选摘要与成功的受信任的 `main` CI 运行的 `IMAGE_DIGEST` 匹配,该运行的事件类型为 `push`,然后检查其扫描和测试证据。
+
+如果交付从 Harbor 事件开始,仅在 Harbor 可以访问并验证每个请求的 EventListener 中暴露它,例如使用拦截器比较 Webhook 的授权头与一个 Secret。没有源验证的 EventListener 会为任何到达它的请求启动运行。请参阅 [使用 Harbor 事件触发器](https://docs.alauda.io/alauda-devops-pipelines/4.15/triggers/how_to/harbor_events.html)。
+
+两个示例 CI 定义通过 `ca-bundle` 工作区绑定 Connector 代理 CA。即使上游注册表使用公共信任的证书,代理的 CA 也是必需的。对于离线扫描,将 `trivyExtraArgs` 设置为使用平台的镜像漏洞数据库,例如 `--db-repository registry.example.com/mirror/trivy-db:2`。扫描器必须能够拉取该镜像。
+
+平台和 GitOps 存储库验证示例组合 `git-clone` 和 `run-script` 内联。如果平台启用禁止内联 `pipelineSpec` 的策略,请将该验证流程发布为目录管道,并通过解析器引用它。
+
+## 为每个环境选择一个部署路径
+
+选择每个环境,而不是仅仅因为 CI 已经使用它而采用一条路径。主要问题是所需的环境状态应该在哪里存在,谁被允许更改它。
+
+| 路径 | 所选摘要如何到达环境 | 权衡 |
+| ------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------- |
+| 直接部署 | 任务如 `workload-apply`、`helm-upgrade` 或 `run-script` 更新工作负载。 | 移动部件更少;Git 不持有环境状态的第二份副本。 |
+| GitOps | 变更更新环境的镜像引用到 Git;Argo CD 进行协调。 | 可审核的环境状态和历史;需要一个存储库和同步路径。 |
+
+### 当集群更新足够时,优先选择直接部署
+
+直接部署适合应快速更新且不需要单独审核历史的开发和测试环境。管道可以使用 `workload-apply` 更新工作负载,使用 `helm-upgrade` 更新 Helm 发布,或使用 `run-script` 执行自定义逻辑。跨集群执行需要适当的 Kubernetes Connector 和授权。
+
+此路径具有更少的组件进行操作。其权衡是 Git 不持有环境状态的第二份副本;保留运行输入和日志,并定义如何恢复或重复部署。如果有人稍后编辑工作负载,此路径本身不会持续恢复预期状态。
+
+### 当所需状态需要审核和协调时,优先选择 GitOps
+
+GitOps 为环境提供版本化的所需状态和在 Argo CD 更改集群之前的审核点。这对于生产和预生产很有用,操作员需要回答哪个版本是预期的,谁更改了它,以及如何提议返回到早期版本。
+
+权衡是另一个存储库和同步路径需要操作。合并的变更仍然可能失败渲染、接纳、镜像拉取或发布。在同步后检查所选修订和工作负载。紧急实时编辑也可以通过自愈恢复;在依赖它之前建立基于 Git 的恢复路径。
+
+一个有用的起始点是开发或测试的直接部署和生产的 GitOps。这些路径可以在一个交付设计中共存。
+
+对于直接部署,在 `workloadContainers` 中使用摘要;使用小写的 `workloadKind`,例如 `deployment`。运行身份需要访问读取和更新目标工作负载。请咨询目录任务以获取其发布、超时、回滚和跨集群选项。
+
+对于 GitOps,使用一个目录和每个环境一个应用程序。将每个镜像摘要保留在一个地方,例如 Kustomize 的 `images` 条目:
+
+```text
+gitops/
+├── base/
+└── envs/
+ ├── test/kustomization.yaml
+ └── prod/kustomization.yaml
+```
+
+在代码平台中强制执行生产 Git 审核。使用受保护的分支,并在支持的地方,使用代码所有者批准。其他选项包括单独受保护的生产分支或存储库,或经过审核的服务器端策略。仅分支保护并不会创建目录级保护。移除可以绕过所选审核路径的直接生产写入访问。
+
+### 为什么示例在两个环境中都使用 GitOps
+
+示例使用 `envs/test` 和 `envs/prod`,每个都有自己的应用程序和自动同步、修剪和自愈。测试使用与生产将使用相同的渲染和同步路径。这种一致性在建立工作流时很有用,即使直接测试部署需要更少的组件。
+
+审核要求因环境而异。测试 CD 直接提交,使用 `submitMode: direct`;生产 CD 打开合并请求,使用 `submitMode: pr`。生产覆盖层已经包含生产注册表存储库,因此发布仅更改其摘要。这使得发布差异集中在所选内容上。测试使用 `kustomize edit set image`,可以重写其覆盖层;生产使用经过严格验证的 `sed` 更改并验证渲染结果。
+
+示例手动启动所有三个交接:测试 CD、提升和生产 CD。这使得输入和身份在设置工作流时可见。自动 Harbor 事件链需要额外的身份验证、映射和 CI 证据检查;这是对该示例的扩展。添加另一个环境还需要项目 GitOps 目录和验证路径。重新运行入职不会升级具有该目录的非空存储库。
+
+### 在构建、提升和 GitOps 之间传递结果
+
+保持明确的交接合同。CI 记录镜像存储库和 `IMAGE_DIGEST`;提升选择该不可变源并报告其目标摘要。下一阶段必须使用实际的前一个结果和目标存储库,而不替换可变标签或无关的成功运行。
+
+| 交接 | 传递的值 | 继续之前的检查 |
+| ----------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
+| 受信任的 CI 到测试 | 源存储库加上 `IMAGE_DIGEST`,格式为 `repository@sha256:`。 | `main` 上的 `push` 运行成功,其扫描结果与该摘要匹配。 |
+| 测试到提升 | 测试过的源引用和人类可读的发布标签。 | 测试运行了该确切镜像,发布记录包括其应用程序检查。 |
+| 复制到生产 CD | 目标存储库加上 `dst-IMAGE_DIGEST`;示例提升暴露 `promoted-digest`。 | 复制结果和注册表摘要与所选候选匹配。 |
+| 生产 CD 到 GitOps | 示例固定生产覆盖层中的裸目标摘要。 | 合并请求更改了预期环境,Kustomize 渲染了完整的生产引用。 |
+
+对于直接部署,将完整引用传递到部署任务的镜像参数中。对于 GitOps,启动 `gitops-repo-update` 并将值传递给更新脚本。它有自己的状态和身份;成功的构建并不意味着此后运行或其合并请求成功。将所选摘要作为参数传递给其更新脚本。每次运行使用新的源工作区卷和包含脚本使用的每个命令的镜像。`submitMode: pr` 还需要配置的 GitLab CLI 镜像和具有 API 访问权限的令牌。
+
+更新脚本必须在提交之前验证输入和渲染的镜像。示例的生产脚本要求 SHA-256 摘要和覆盖层中恰好一个摘要字段,然后仅更改该字段。将 GitOps 写入者与应用程序 CI 令牌分开,并限制其 Git 权限和可以使用的命名空间。下面的执行权限部分解释了示例的维护者令牌需要额外保护的原因。
+
+示例从渲染的 PipelineRun YAML 手动启动测试 CD、提升和生产 CD。替换模板参数,验证镜像映射、身份和工作区,并使用 `kubectl create` 提交。这条手动设置路径是示例的后备;目标工作流应该通过审核的触发输入从受信任的 CI 结果传递摘要,而不是要求操作员复制镜像引用。控制台运行模板表单暴露管道参数:在示例中,删除空的第三个 `updateArgs` 条目,使用完整的 `repository@sha256:digest` 进行测试 CD,并使用裸的 `sha256:digest` 进行生产 CD,因为生产存储库由种子覆盖层固定。限制谁可以在交付命名空间中创建 PipelineRuns;控制台表单可以暴露在渲染的 YAML 路径中固定的参数。使用 [运行模板](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/how_to/run_template.html) 进行其他执行条目。Harbor 事件自动化是额外的集成,不是示例的手动路径的一部分。
+
+### 将执行权限与存储库所有权分开分配
+
+应用程序团队维护 CD 和提升定义,但这并不自动授予应用或运行它们的权限。示例的所有者绑定在 `shop` 中;在构建和交付命名空间中的访问需要管理员或明确的委派授权。
+
+| 对象或操作 | 命名空间 | 责任方和权限 |
+| ------------------------------------------------------ | --------------------- | --------------------------------------------------------------------------------------------------------- |
+| 应用程序 PaC 存储库及其访问 Secret | `shop-build` | 平台管理员,或具有存储库和 Secret 写入访问权限的委派维护者。 |
+| 检查 CI 结果 | `shop-build` | PipelineRuns、TaskRuns 和所需日志的授权读取者。 |
+| 应用 CD 运行模板和提升管道 | `shop-cd` | 具有相应资源写入访问权限的管理员或委派维护者。 |
+| 启动 CD 或提升并检查其结果 | `shop-cd` | 具有 PipelineRun 创建和读取访问权限的授权发起者;评估该权限可访问的凭证。 |
+| 批准提升 | `shop-cd` | 配置的批准者组的成员,具有批准权限;控制台访问还需要可选的 ACP 角色绑定。 |
+| 授予生产 Connector 访问或管理其访问策略 | `platform-connectors` | 平台管理员,独立于应用程序管道编辑者。 |
+
+示例使用 `shop-delivery` 进行 GitOps 更新,使用 `shop-release` 进行提升。CI 使用命名空间的默认执行身份,除非 `TektonConfig` 配置了另一个默认值。更改该默认值时,更新示例的 Connector 绑定以匹配。命名的 Connector `get` 授权记录预期关系,但并不缩小更广泛的 ACP 默认读取权限。当其功能标志启用时,代理授权是一个单独的控制。
+
+在 `shop-cd` 中创建 Pod 或 PipelineRun 的权限也暴露了同一命名空间的 GitOps 写入者 Secret。在 Secret 保持在那里时保护该命名空间。为了在不交出写入者的情况下委派执行,将 Connector 及其 Secret 移动到受保护的命名空间,并授权受控的跨命名空间挂载。生产 Git 保护还必须限制写入者本身:示例的维护者组令牌可以更改保护设置。使用一个不能更改这些规则、直接写入生产或合并其自身生产变更的写入者,以及在需要时单独控制的生产分支或存储库。
+
+### 返回到先前的生产版本
+
+生产回滚遵循相同的审核边界。重建可能会产生不同的内容,因此选择一个保留的、先前提升的摘要并使用此 GitOps 路径:
+
+1. 在生产 Git 历史中找到先前的摘要。
+2. 确认它仍然在生产注册表中,验证其签名,并检查与当前配置和数据的兼容性。
+3. 创建一个分支,仅更改生产覆盖层的 `digest:` 行。
+4. 打开合并请求,等待验证,然后审核并合并它。
+5. 在 Argo CD 和部署中确认所选镜像,并等待发布完成。
+6. 如果需要返回到较新版本,请使用相同的审核单行更改。
+
+对于证据审核,保留预期的单行差异并明确验证实时对象:
+
+```bash
+git log -p -- envs/prod/kustomization.yaml
+kubectl -n argocd get application -prod -o yaml
+kubectl -n -prod get deployment -o jsonpath='{.spec.template.spec.containers[*].image}{"\n"}'
+kubectl -n -prod rollout status deployment/
+```
+
+Git 差异应仅更改生产摘要;应用程序和部署应报告相同的摘要,发布命令应成功完成。
+
+数据库和数据迁移需要特定于应用程序的回滚计划。在目标环境中排练完整的运行手册。配置 [Harbor 标签保留](https://goharbor.io/docs/2.14.0/working-with-projects/working-with-images/create-tag-retention-rules/) 和 [标签不可变性](https://goharbor.io/docs/2.14.0/working-with-projects/working-with-images/create-tag-immutability-rules/) 以确保所需的回滚镜像保持可用。
+
+## 选择发布控制
+
+发布可能需要几种类型的授权。在添加控制之前,决定每个控制必须回答哪个问题:复制工件、批准发布、发布凭证和接纳工作负载是单独的操作。
+
+### 决定是复制工件还是仅更新其引用
+
+当构建写入者不能是生产写入者,或者当生产内容需要自己的保留和访问策略时,单独的生产注册项目是有用的。复制经过测试的摘要而不重新构建它,然后更新生产 Git 引用。这增加了发布身份、注册表权限、复制证据和签名存储责任。
+
+如果两个环境故意使用相同的存储库,更新生产 Git 引用可能就足够了。然后,存储库允许列表无法区分测试候选和批准的生产摘要。在需要区分的地方,基于批准摘要证据添加接纳,而不是假设对共享存储库的访问表示发布批准。
+
+### 将发布批准与访问凭证分开
+
+ApprovalTask 记录一个人的决定,并可以在复制之前停止正常工作流。生产 Git 审核授权所需的环境状态。组织可以选择任一审核点或要求两者;示例要求两者,以便发布决策和生产变更保持可见,作为单独的记录。
+
+批准门控的 Connector 访问在生产凭证所有者和管道所有者是不同团队时很有用。它允许凭证所有者维护独立的批准者集。它还引入了全安装范围的代理权限前提和发布顺序。如果一个受信任的平台团队拥有两者,专用的发布身份、受保护的凭证命名空间和提升接纳可以提供一个更简单的起点。单独的批准节点并不会阻止另一个运行尝试使用相同的凭证。
+
+因此,提升、批准、凭证门控和镜像接纳解决以下决策:
+
+| 决策 | 推荐控制 |
+| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| 生产是否使用单独的工件项目? | 将所选摘要复制到该项目中,然后更新生产 Git 引用。如果测试和生产使用相同的镜像存储库,仅提升 Git 引用并仅接纳已批准的摘要,因为基于存储库的规则无法区分环境。 |
+| 谁授权所选发布? | 根据政策,使用 ApprovalTask、生产 Git 合并请求审核或两者。 |
+| 谁可以使用生产 Connector? | 专用的发布身份加上接纳和 RBAC 限制。当凭证所有者和管道所有者分开时,添加批准门控的代理访问。 |
+| 可以部署什么? | 针对允许的生产存储库、签名和任何所需的批准摘要证据的接纳政策。 |
+
+使用核心提升接纳规则 [使用 Kyverno 限制工件提升](https://docs.alauda.io/alauda-devops-artifacthub-shim/1.0/catalog/how_to/constrain_artifact_promotion_with_kyverno.html)。规则 1-3 限制提升执行路径。当提升管道在命名空间中维护时,添加规则 4,以控制对该定义的更改。伴随示例不安装这些提升规则或仅生产存储库的部署策略;平台管理员必须在使用参考设计作为生产控制之前添加它们。签名镜像证明拥有签名密钥,而不是该特定管道生成它。
+
+提升验证源和目标映射并复制字节。它不会查询 CI 以确定镜像是否通过。批准者必须将摘要与受信任的构建、扫描和测试证据关联。示例验证镜像映射是否首先,源是否使用 SHA-256 摘要,存储库和发布标签格式是否与配置的工作流匹配。可选的签名映射必须引用相同的镜像摘要。当启用提升接纳时,使用管道的 `imageMappings` 输入进行每个源到发布的映射:接纳规则识别该映射形式,因此单独提供的存储库或标签参数不是替代品。
+
+### 为什么示例将提升和生产 CD 分开
+
+示例有两个 Harbor 项目,`shop` 和 `shop-prod`。提升在批准后将所选候选复制到生产项目;稍后的生产 CD 运行使用生成的摘要来提议 Git 更改。复制使镜像可用于生产。合并和同步 Git 更改将其选择用于环境。在声明发布完成之前检查这两个结果。
+
+生产 Connector 生活在 `platform-connectors` 中,项目成员必须无法创建 Pods 或运行任意管道。始终需要现有的读取授权;生产 AccessPolicy 及其功能标志是可选的,直到平台选择批准门控的代理访问。在接受过程中保持该选择明确。
+
+### 添加批准节点
+
+在 `approvers` 中使用 ACP 组资源名称,而不是组的显示名称或个人名称。以下是任务片段;用实际资源名称替换示例组:
+
+```yaml
+- name: wait-for-approval
+ taskRef:
+ apiVersion: openshift-pipelines.org/v1alpha1
+ kind: ApprovalTask
+ timeout: "24h"
+ params:
+ - name: approvers
+ value:
+ - group:release-managers
+ - name: numberOfApprovalsRequired
+ value: "1"
+ - name: description
+ value: "Approve promotion into production"
+```
+
+PipelineRun 和任务超时预算必须包括批准前的工作、整个批准窗口和批准后的工作。将批准者组与允许启动或修改发布运行的身份分开。使用 [手动批准门](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/how_to/manual_approval_gate.html) 进行批准权限、组响应和超时配置。在对象被删除之前,单独保留 ApprovalTask 响应。
+
+不要假设批准响应仅仅因为其 `name` 字段包含批准者名称而可归因。示例期望手动批准门 Webhook 将响应绑定到经过身份验证的用户,并拒绝命名其他用户的补丁,但该行为必须通过在目标集群上安装的手动批准门版本进行验证。测试批准成员自己的响应和身份外的响应,然后再将 ApprovalTask 视为可审计的用户决策。在两个检查通过之前,单独保留经过身份验证的审计事件,并将 ApprovalTask 描述为提交输入的记录,而不是提交者的证明。
+
+批准者可以在控制台中或通过 `kubectl` 检查待处理工作。可选的示例 `promotion/optional/console-approver.yaml` 提供了一个自定义控制台角色和组绑定;它可以查看项目组和成员名称,但不能读取 Secrets,因此在应用之前审核该范围。可以使用目录的 `send-mail` 任务发送批准通知。电子邮件地址、SMTP 配置和凭证必须单独配置;示例不集成该通知步骤。
+
+要通过 Pipelines-as-Code Incoming Webhook 启动运行,向控制器的 `/incoming` 端点发送包含 `repository`、`namespace`、`branch`、`pipelinerun` 和 `secret` 的 JSON 主体的 `POST` 请求。仅当返回 HTTP `202` 并且出现新的 PipelineRun 时,才将调用视为成功;HTTP `200` 和空主体意味着没有启动运行,例如因为秘密不匹配。请参阅 [Incoming Webhooks](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/how_to/incoming_webhooks.html)。
+
+客户变更管理系统集成超出了本系列的范围。可用的构建块是批准节点和 [Incoming Webhooks](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/how_to/incoming_webhooks.html)。单独定义该集成的映射和审计合同。
+
+
+
+### 在批准后门控生产 Connector
+
+将生产 Connector 及其 Secret 保留在项目成员无法创建 Pods 或运行任意管道的命名空间中。Pod 可以从其自己的命名空间挂载 Secret,而无需单独的 Secret 读取授权检查。因此,在承载凭证的命名空间中创建 Pod 或 PipelineRun 的权限是凭证边界。在禁用 `enable-connectors-approval` 时,可以在 `shop-cd` 中创建 Pod 或 PipelineRun 的主体可以使用授予给发布身份的生产 Connector;ApprovalTask 并不保护该路径。将命名空间及其 ServiceAccounts 视为边界,直到代理批准启用并验证。
+
+示例发布 ServiceAccount `shop-release` 从 `platform-connectors` 挂载源和生产 Connectors。其现有授权在 `sample-app/promotion/standing-access.yaml` 中。两个注册表配置共享复制任务的代理环境;目标配置覆盖冲突的源设置。在此示例中,两端因此都使用生产 Connector 的代理凭证。生产机器人必须能够拉取暂存注册表以及写入生产注册表;入职授予两者。源挂载提供源 CA 包,并不建立单独的只读身份验证路径。即使注册表使用公共信任的证书,也要绑定 `src-ca-bundle` 和 `dst-ca-bundle`,因为代理重新签署 TLS。使用 RBAC 进行产品指南中描述的跨命名空间代理授权。
+
+批准门控使用两个全安装范围的功能标志。按以下顺序推出它们:
+
+1. 清点每个未经过批准的挂载 Connector 的身份。准备其读取授权和 `connectors/proxy` 权限,动词为 `*`。对 `connectors/proxy` 的 `get` 授权不足。不要直接授予生产 Connector 的代理访问权限,必须经过批准。
+2. 启用 `enable-connectors-approval`。立即创建所需的 AccessPolicies,包括管理员-Connector 授权和生产批准策略。在启用标志和创建策略之间的间隔内,不要启动受影响的运行。
+3. 保持提升管道的 ApprovalTask 和生产 AccessPolicy `approvers` 对齐。项目声明中的 `approvers` 字段仅为审核记录;入职不应用或比较它。将 AccessPolicy 保持在平台管理员控制下,以便管道编辑者无法更改门的两侧。删除任何其他匹配的默认或直接代理授权。
+4. 启用 `enable-connector-proxy-permissions`,这也将代理权限检查应用于请求。
+
+通过 `ConnectorsConfig` 设置功能标志。有关完整配置和验证路径,请参阅 [启用代理权限检查和批准门控](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors/how_to/enable_proxy_permissions_and_approval.html)、[AccessPolicy](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors/concepts/access_policy.html) 和 [Skopeo 复制连接器批准](https://docs.alauda.io/alauda-devops-artifacthub-shim/1.0/catalog/how_to/promote_artifacts_with_skopeo_copy.html#connector-approval)。
+
+`defaultPermission` 策略具有授权前提,并不是每个跨命名空间 RBAC 授权的替代品。用于挂载 Connector 的每个身份必须能够在其源命名空间中 `get` 指定的 Connector;名称范围的 `get` 角色记录该关系,但本身并不满足需要命名空间范围读取的策略。`defaultPermission` 策略仅适用于具有命名空间范围 `get` 的身份;其他身份可能会被静默跳过,该跳过仅在控制器日志中可见,而策略仍然可以报告 `Ready`。示例授予入职身份在管理命名空间中命名空间范围的 `get`,同时将代理权限限制在命名的管理员 Connectors;将更广泛的读取范围保持在管理命名空间中。单独的 Ready 策略并不建立有效的挂载。验证实际身份、Pod 事件、挂载配置和 AccessRequest 结果。
+
+### 按照实际顺序连接发布步骤
+
+预期顺序是识别候选及其 CI 和测试证据,验证其源和目标,获得批准,复制它,验证生产签名和来源,并提议生产 GitOps 变更。在需要源签名验证的地方,在复制之前执行它。等待批准不得默默更改候选;在运行输入和发布记录中保持摘要。
+
+Harbor 自动化可以在推送或扫描事件后启动后续运行,但需要四个额外的协议:可访问的监听器、经过身份验证的回调、与运行模板匹配的 TriggerBinding 参数,以及检查所选摘要是否属于成功的受信任 CI 运行。通知仅提醒批准者;它既不授予权限,也不提供该证据。
+
+Incoming Webhooks 为另一个系统提供了一个入口。调用者仍然需要运行识别、完成、失败和保留的证据的合同。接收请求和完成发布是两个独立的事件。
+
+## 签名和验证镜像
+
+### 选择签名应建立的内容
+
+在部署必须验证来自平台控制的签名者的声明时使用签名。决定哪个声明重要:候选在构建后被签名、复制的生产工件具有发布来源,还是其摘要已获得批准。仅签名检查建立配置的签名者声明。对该声明的信任取决于密钥的保护、执行身份和允许的定义。
+
+在提升之前的验证可以在源进入生产项目之前拒绝不合适的源。在工作负载接纳时检查请求集群要运行的镜像,包括正常发布路径以外的请求。这两者都可以使用。示例提供部署验证和单独的 cosign 接受检查;它不在复制步骤之前添加源验证任务。Chains 不会为包含 `CustomRun` 任务的 `PipelineRun` 创建运行级签名,因此将这些运行与其镜像摘要、TaskRun 证据和任何单独的批准记录关联。
+
+### 中央准备签名和注册表访问
+
+在中央配置 Chains 签名密钥,并仅将公共验证密钥分发给项目。保护签名 Secret 和在其命名空间中创建 Pods 的能力。应用程序团队不需要访问签名 Secret。
+
+在启用签名之前,检查每个项目身份的有效权限,包括自动创建的 EventListener ServiceAccounts 及其组。它们必须被拒绝 Secret 的 `get`、`list` 和 `watch`,以及在 Chains 命名空间中创建 Pod。检查集群范围的授权以及项目 RoleBindings。如果检查允许访问,请在入职之前缩小其平台管理源中的授权,或安装具有最低权限角色的组件版本;然后重复检查并确认拒绝使用独立项目令牌。内置的 Webhook Secret 验证在单独的 core-interceptors 身份下运行,因此不需要 EventListener 的集群范围 Secret 访问。在缩小权限后,验证经过身份验证的真实事件和不正确身份验证的负控制。示例 [Chains 前提条件](https://github.com/AlaudaDevops/devops-best-practices-samples/blob/main/sample-app/chains/README.md#check-project-access-before-enabling-signing) 提供了管理员命令。
+
+示例将签名和证明存储在镜像旁边。Chains 首先使用运行的 ServiceAccount 中匹配的注册凭证。在示例中,镜像拉取 Secret 也具有推送权限,并由 Chains 使用,因此它不是只读凭证;在强化部署中将只读工作负载 Secret 与签名凭证分开。这些凭证必须能够推送到镜像的注册项目。在缺少它们的地方,通过 `TektonConfig` 在 Chains 控制器上配置中央管理的注册凭证。Chains 不使用 Connector 的 CSI 代理工作区作为其注册凭证。保持 `shop-release` ServiceAccount 不带匹配的生产注册凭证;否则,Chains 将首先选择它,提升身份将获得直接的生产写入路径。当提升运行没有匹配的 ServiceAccount 凭证时,使用平台拥有的中央凭证。
+
+将 `signing-secrets` 视为平台拥有,并在轮换之前检查其 `immutable` 字段和拥有者引用。如果安装的 Chains 或安装程序将其标记为不可变或通过 SealedSecret 管理,请通过该组件的文档程序创建替换,并将验证密钥和接纳策略作为一个审核变更进行更新;不要在原地编辑生成的 Secret 数据。在每个使用旧密钥签名的镜像(包括保留的回滚镜像和正在运行的 Pods)被退役之前,将旧公共密钥保留在验证策略中与新密钥并列。在过渡期间使用两个密钥验证签名,然后在单独的审核变更中删除旧密钥。
+
+中央凭证由管理员创建,位于 Git 之外。将其限制为 Chains 必须读取和签名的注册项目。在入职项目时,平台团队必须将其源和生产注册项目添加到该凭证的访问中。轮换并限制其 Secret 和命名空间。在维护窗口中应用控制器配置更改,保留已配置的其他容器选项。
+
+### 独立验证存储的证据
+
+成功的 PipelineRun 不是存储签名的证明。检查 TaskRun 签名注释和事件,并独立验证镜像及其证明。此处的接受对象是镜像摘要和复制 TaskRun 的来源;批准历史是单独的证据。
+
+```bash
+# IMAGE is the selected repository@sha256:digest; the platform supplies cosign.pub.
+cosign verify --key cosign.pub "$IMAGE"
+cosign verify-attestation --key cosign.pub --type slsaprovenance "$IMAGE"
+```
+
+`--type` 值必须与 Chains 发出的来源谓词匹配。此示例期望 Chains `artifacts.taskrun.format: slsa/v1`,它发出 SLSA 证明 v0.2,因此使用 cosign `--type slsaprovenance`。`slsa/v1` 配置名称并不意味着 SLSA v1 谓词。不同的 Chains 格式需要相应的 cosign 类型和证明策略路径。
+
+对于配置为没有透明日志的离线安装,使用产品的离线验证设置,包括在需要时使用 `--insecure-ignore-tlog=true`。这跳过外部透明日志检查;保留签名和证明检查。对私有注册表进行身份验证,而不提交登录凭证。
+
+如果平台选择单独的签名存储库,请在中央配置 `storage.oci.repository`,并在验证和 Kyverno 中使用相应的 `COSIGN_REPOSITORY`。更改存储设置不会迁移现有附件。在切换之前单独保留现有 CI 证据,并在依赖它进行提升之前验证新签名的镜像在配置的位置。审核存储和覆盖行为,然后再将构建和提升证明合并到相同摘要中:根据注册表和 Chains 配置,提升签名可能与 CI 写入的附件共存或替换。捕获并验证 CI 签名和来源,然后在提升之前单独保留。提升期间复制构建签名附件是可选的;示例使用显式的 `.sig` 和 `.att` 映射以默认相同存储库布局。对于多架构镜像,遵循 Skopeo 复制任务合同,并在复制索引及其附件时设置 `multiArch: all`;不要假设单一镜像映射会自动覆盖索引。
+
+### 通过正面和负面控制引入部署验证
+
+在部署接纳时,启动图像验证策略,使用示例的 `mutateDigest: false` 设置,并在执行之前审核匹配的镜像和报告。对于私有发布注册表,在 Kyverno 接纳控制器运行的命名空间中创建仅拉取的 `kubernetes.io/dockerconfigjson` Secret,通过 `imageRegistryCredentials.secrets` 引用它,并为每个发布镜像及 OCI `.sig` 和 `.att` 附件提供拉取访问。如果 Chains 将附件存储在单独的签名存储库中,则相同的 Kyverno 凭证(或显式配置的等效物)也必须能够读取该存储库。工作站的 `skopeo login` 或 `cosign login` 仅对该客户端进行身份验证;它不提供 Kyverno 注册表访问。将 `UNAUTHORIZED`、`401` 或类似的注册表身份验证消息视为凭证或注册表配置失败,而不是证据表明镜像未签名。首先获取已知签名摘要的成功报告,然后运行未签名的负控制,并仅在两个结果都归因于签名验证后切换到执行。示例的生产镜像列表是明确的:将每个新入职的生产存储库添加到策略中。请参阅 [镜像签名验证](https://docs.alauda.io/alauda-devops-pipelines/4.15/chains/how_to/image_signature_verification.html)。
+
+签名策略明确选择生产镜像存储库。来自另一个存储库的镜像即使在生产命名空间中也可能不在该选择范围内。当平台的发布边界是源和摘要限制时,将验证与生产镜像源和摘要限制配对;示例未安装该附加限制。
+
+在签名密钥轮换期间,使用一个证明者,`count: 1`,并为旧公共密钥和新公共密钥分别设置 `entries`,包括每个密钥所需的离线验证选项。这接受来自任一密钥的签名。在替换签名者之前验证旧镜像接纳,然后验证新签名和接纳。在任何旧签名的部署或回滚镜像仍然需要时,保留旧条目。
+
+证明的管道标签可以帮助检测选择错误的工作流,但仅凭名称并不是唯一的执行身份:另一个命名空间可以包含同名的管道。示例的 SLSA v0.2 来源并不通过该标签建立命名空间。保护签名路径和接纳输入,而不是将标签视为特定平台拥有的管道的证明。
+
+## 在实际执行点检查控制
+
+| 工作流中的点 | 检查内容 | 剩余责任 |
+| ---------------------------------- | -------------------------------------------------- | -------------------------------------------- |
+| 存储库事件和定义解析 | 事件匹配和审核的定义源 | 限制可用于提议源代码的凭证。 |
+| PipelineRun 接纳 | 允许的定义源和配置的提升路径 | 限制谁可以编辑引用的定义和参数。 |
+| TaskRun 或 CustomRun 创建 | 直接运行限制的批准控制器身份 | 保护自动化身份及其 RBAC。 |
+| 批准 | 指定的批准者响应 | 将批准的摘要与 CI 和测试证据匹配。 |
+| 生产注册表写入 | 提升映射和凭证访问 | 控制其他写入者,包括签名身份。 |
+| 工作负载接纳 | 允许的注册表和所需的签名检查 | 移除绕过政策的直接部署路径。 |
+| 保留和清理 | 选定的运行/日志保留 | 导出批准证据并验证归档访问。 |
+
+使用平台 ClusterPolicies 作为基线,项目 Policies 作为附加限制。仅允许平台管理员创建 `PolicyException` 对象,或根据平台政策禁用例外;不要将此逃生口委派给项目身份。仅解析器类型的允许列表并不固定目录、存储库、命名空间、版本或定义内容。启用无内联策略时,必须明确处理内联验证例外。
+
+示例的解析器和裸运行策略排除了 `platform-connectors`,其中入职使用管理员 Connectors。保持该命名空间中的 Pod 和 PipelineRun 创建仅限于平台管理员和平台 ServiceAccount;策略排除并未创建该边界。
+
+使用一次性项目的证据推出策略。审核确定哪些请求将匹配;执行是证明拒绝的必要条件。首先验证允许的请求,然后验证不允许的请求,以便缺少注册凭证或 Pod 安全拒绝不会被误认为成功的签名测试。在执行基于 Webhook 的控制之前,准备高可用性和本地恢复程序。不可达的 Webhook 和 `failurePolicy: Fail` 可能会阻止匹配写入;有序的控制器关闭可以移除 Webhook 注册,因此不要假设每种形式的控制器不可用都有相同的接纳结果。
+
+### 将交付步骤与组件和工具匹配
+
+工作流结合了产品能力,而不是将每个功能放在一个组件中。工具访问通常使用项目 Connectors;PaC 的克隆 Secret、镜像拉取配置和 Chains 注册凭证具有独立的生命周期。
+
+| 交付步骤 | 能力和工具 | 配置或证据所有者 |
+| ----------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
+| 接收推送或合并请求 | PaC 或 Triggers 与 GitLab/GitHub。 | 平台准备路径;项目选择事件和所需的合并检查。 |
+| 获取源 | 使用 Git Connector 的 `git-clone`,或 PaC 提供的克隆凭证。 | 项目提供存储库和修订;平台管理凭证范围。 |
+| 获取依赖项 | 通过相关 Connector 和 Nexus 的 Maven、npm 或 PyPI 配置。 | 平台提供镜像和 CA;如果缺少所需的镜像配置,构建必须失败。 |
+| 检查代码质量 | 具有其项目 Connector 的 SonarQube 扫描任务。 | 项目选择适用的质量门并保留扫描结果。 |
+| 构建、推送和扫描镜像 | 目录构建/扫描任务与 Harbor 或其他 OCI 注册表。 | 平台提供任务、工具镜像、注册表访问和离线漏洞数据库。 |
+| 交接注册表事件 | Harbor EventListener、拦截器和 TriggerBinding。 | 平台进行身份验证并映射事件;工作流检查摘要的 CI 证据。 |
+| 更新环境 | `workload-apply`、`helm-upgrade` 或 `run-script`,或 Argo CD 同步。 | 执行身份需要目标授权;项目验证发布。 |
+| 提议 GitOps 变更 | `gitops-repo-update`,使用 Git 和 GitLab MR 创建 `submitMode: pr`。 | 项目提供更新脚本;平台保护写入者和生产审核路径。 |
+| 批准并复制 | ApprovalTask、`skopeo-copy` 和可选的 Connector AccessPolicy。 | 发布批准者授权摘要;凭证所有者控制访问。 |
+| 通知审批人 | 可选目录 `send-mail` 任务和 SMTP。 | 本地集成提供收件人、SMTP 配置和凭据。 |
+| 签署和验证 | 链、cosign 和 Kyverno 录取。 | 平台控制密钥、注册访问、受信任的镜像范围和策略发布。 |
+| 保留证据 | 结果存储和单独的审批记录导出。 | 平台定义保留;发布所有者在清理之前关联记录。 |
+
+有关依赖项设置,请参见
+[将 Maven 连接器用作 Maven 注册表镜像](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors-maven/how_to/using-as-maven-registry-mirror.html)。
+在任务需要的地方绑定相关连接器的 CA。直接工作负载
+操作和自定义应用逻辑由
+[使用 run-script 任务管理 ACP 应用](https://docs.alauda.io/alauda-devops-artifacthub-shim/1.0/catalog/how_to/manage_acp_application_with_run_script.html)覆盖。
+在每个决策部分使用产品链接以获取完整字段和支持的
+变体。
+
+## 接受交付工作流
+
+### 确定预期的交付记录
+
+完成的发布应连接经过审核的源修订、成功的受信任
+CI、扫描和测试结果、不可变的镜像引用、审批响应、
+复制结果、经过审核的生产 GitOps 修订和实际生产
+发布。保留连接这些记录的标识符;一组不相关的
+成功运行是不够的。
+
+| 结果 | 证明其存在的记录 |
+| -------------------------------------------- | ------------------------------------------------------------ |
+| 候选者来自预期的更改。 | 源修订和受信任的 `push` 运行,包括其确切的镜像结果。 |
+| 测试对该候选者进行了验证。 | 测试镜像引用、发布和应用检查。 |
+| 选择并授权了生产内容。 | 审批响应、源/目标映射和推广结果。 |
+| 生产期望状态已审核。 | 合并请求、验证结果和合并的 Git 修订。 |
+| 生产运行所选内容。 | Argo CD 修订、渲染的镜像、部署镜像和完成的发布。 |
+| 所需的控制保持有效。 | 独立的签名/来源检查和允许/拒绝的录取探针。 |
+
+样本的手动条目在设置过程中很有用,但每个操作员必须准确复制
+前面的结果。在自动化这些条目时,保留相同的
+交接检查和发布记录,而不是将事件与准备状态等同起来。
+
+### 运行接受并检查剩余证据
+
+在第一次推广、生产 GitOps 合并和完成发布后运行 `acceptance/01-commit-to-production.sh`。使用一个一次性的接受项目,具有自己的命名空间和 Harbor 生产存储库。`PROJECT` 是必需的;检查剩余的默认值并替换所有特定于环境的输入。该脚本在该项目的生产命名空间中创建临时录取探针。该表将其检查与您必须单独检查的发布证据区分开来。
+
+| 检查 | 脚本覆盖 | 需要单独检查的证据 |
+| --------------------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| CI 完成 | 使用提供的 `BUILD_DIGEST`;它不选择或验证 CI 运行。 | 受信任的 `push` 运行在 `main` 上成功;其存储库、摘要、扫描和测试结果与发布输入匹配。 |
+| 测试运行了所选镜像 | 比较完整的镜像引用并等待发布完成。 | 该部署的应用级测试结果。 |
+| 推广复制了该镜像 | 比较发布标签的注册表摘要与 `BUILD_DIGEST`。 | 推广运行的 `promoted-digest` 和目标映射与该摘要和存储库匹配。 |
+| 生产使用推广结果 | 检查应用同步/健康、确切的发布摘要和发布完成。 | 审查和合并预期的 GitOps 差异及其渲染的镜像。仅 `Synced` 可以描述较旧的修订。 |
+| 签名和来源存在 | 针对生产镜像运行两个 cosign 命令。 | 证明识别预期的复制 TaskRun;审批历史单独保留。 |
+| 录取报告或执行政策 | 首先检查签名的生产镜像,然后检查未签名的镜像;按探针 UID 和政策选择报告。 | 审计报告证明报告。仅在相同控制通过 Enforce 后才执行声明。区分签名拒绝与 Pod 安全和注册表访问失败。 |
+| 审批可归属 | 检查审批对象的所有权链和响应,包括组成员。 | 在清理之前,将这些响应、批准的摘要和相关运行标识符保存在发布记录中。 |
+
+### 调整对目标环境的引用
+
+替换示例项目和组资源名称、代码和注册表地址、
+集群目标、工具镜像、CA 源、签名密钥、镜像依赖项、
+和凭据。在验证政策和
+中央签名访问中注册新的生产存储库。一起审查环境目录、AppProject 目标、
+执行身份和实际 Git 平台的审查能力。
+
+在生产之前,解决示例的显式加固工作:限制 GitOps 写入者的命名空间,保护生产 Git 更改,安装推广核心规则,约束生产镜像源,并限制直接集群写入。不要授予项目成员在包含管理员或发布凭据的命名空间中创建 Pod 的权限。建立本地回滚和政策服务恢复运行手册。
+
+继续阅读 [管理平台配置和入驻隔离项目](./Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md),以获取此工作流背后的平台配置、项目声明和操作边界。
diff --git a/docs/zh/solutions/Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md b/docs/zh/solutions/Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md
new file mode 100644
index 000000000..0c0f7d696
--- /dev/null
+++ b/docs/zh/solutions/Managing_Platform_Configuration_and_Onboarding_Isolated_Projects_with_Argo_CD_and_Tekton_on_ACP.md
@@ -0,0 +1,606 @@
+---
+products:
+ - Alauda Container Platform
+ - Alauda DevOps
+kind:
+ - Best Practices
+ProductsVersion:
+ - 4.x
+id: KB261000025
+sourceSHA: 7b34e21aa8112cc57d2dcf20623e7ee00e4ccee35f7ddbde0c90c6a89c984662
+---
+
+# 使用 Argo CD 和 Tekton 在 ACP 上管理平台配置和入驻隔离项目
+
+当项目请求时,平台团队通常会首先配置集群中的组件并创建工具账户。随着项目数量的增加,回答哪些设置是有意的、如何一致地创建下一个项目以及在另一个环境中需要准备什么变得更加困难。
+
+当平台配置需要一个持久的审核来源时,当打开一个项目时在 GitLab、Harbor、Nexus 和 SonarQube 中重复管理时,或者当需要一起解释部署和凭证边界时,请使用本文。平台 Git 仓库记录共享意图。入驻管道将审核过的项目声明转化为命名空间和工具资源,然后通过合并请求提出项目的部署注册。
+
+这两种机制有不同的所有权。Argo CD 负责与 Git 所拥有的对象和字段进行协调。入驻任务负责协调它们创建的外部资源。任何机制都不能替代解密密钥、签名密钥、外部工具数据或结果存储的备份。撤销注册可能会删除资源,因此恢复需要的不仅仅是重放或还原 YAML。
+
+到最后,您应该能够:
+
+- 分离平台配置、共享模板和项目应用状态。
+- 解释 18 个平台决策、其所有者及其仓库层次。
+- 准备先决条件,审核项目声明,并通过其注册合并请求跟踪入驻。
+- 验证生成的项目边界,并计划协调、凭证轮换和配置恢复。
+
+本文是 [Alauda DevOps 最佳实践](./Alauda_DevOps_Best_Practices_Overview.md) 的平台部分。它假设一个 ACP 项目和每个项目的独立工具侧租户。其配置基线为 Pipelines 4.15、Artifact Hub Shim 1.0、Connectors 1.14 和 GitOps 4.4,适用于兼容的 ACP 安装。共享一个命名空间和一个工具租户的团队需要不同的边界模型。
+
+[伴随示例](https://github.com/AlaudaDevops/devops-best-practices-samples) 包含完整的参考文件。诸如 `shop`、`payments`、`platform-connectors` 和 `registry.example.com` 等名称是虚构的。请替换它们、图像占位符、组资源名称、策略身份和目标环境的加密 Secret 占位符。
+
+## 建立所有权模型
+
+保持三种类型的仓库分开:
+
+| 仓库 | 内容 | 所有者 |
+| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
+| 平台仓库 | 组件配置、准入政策、加密管理员凭证、项目声明和平台原生应用定义 | 平台团队 |
+| 模板仓库和目录 | 版本化的共享管道和任务;初始项目 GitOps 仓库内容 | 平台团队 |
+| 项目仓库 | 应用源和 `.tekton/`;项目 GitOps 仓库中的环境清单和摘要引用 | 项目团队 |
+
+这种分离使三种类型的审核变得易于理解。平台变更可能会改变多个项目的约束,并需要平台审核。目录版本更改可重用工作流,并需要兼容性和采用决策。应用发布更改项目自身的期望状态,并属于项目的发布过程。
+
+运行模板是项目命名空间中的执行设置,与版本化目录管道定义不同。它们保存特定管道使用的参数、工作区和集成。将应用清单保存在项目 GitOps 仓库中。项目可以添加命名空间策略,而共享基线仍由平台拥有。
+
+```mermaid
+flowchart TB
+ MR[审核平台变更] --> Git[平台仓库]
+ Git --> Argo[Argo CD]
+ Argo --> Components[组件设置]
+ Argo --> Policies[平台政策]
+ Argo --> Credentials[加密管理员凭证]
+ Argo --> Declarations[已发布项目声明]
+ Declarations --> Onboard[Tekton 入驻]
+ Onboard --> Tools[GitLab Harbor Nexus SonarQube]
+ Onboard --> Namespaces[项目命名空间和身份]
+ Onboard --> Seed[种子项目 GitOps 仓库]
+ Onboard --> Registration[提出平台注册 MR]
+ Registration --> Git
+ Seed --> ProjectArgo[项目应用]
+```
+
+该图描述了所有权和交接。合并后的 PaC 调度程序在等待其发布配置后开始处理已更改的声明;Argo CD 并不会仅通过同步 ConfigMap 来触发 Tekton。入驻稍后提出单独的注册更改,必须在项目应用生效之前进行审核。
+
+为每个资源或字段分配一个所有者。Argo CD 自我修复适用于它跟踪的对象;它不会协调集群中的每个对象或逆转外部工具操作。删除声明并不是自动退役程序。
+
+### 决定配置恢复应提供什么
+
+将配置保存在 Git 中提供了初始化的起点、审核轨迹和建议返回到早期设置的方法。它还允许审核者一起检查项目目的地、所有者和平台政策。这些好处依赖于明确的字段所有权和可恢复的先决条件集。
+
+| 预期好处 | 此设计提供的内容 | 操作后果 |
+| ------------------------------------ | ----------------------------------------------------------------- | ---------------------------------------------------------------- |
+| 一致地初始化另一个环境。 | 审核过的组件设置、政策、模板和项目声明。 | 安装兼容的控制器并在同步之前恢复凭证。 |
+| 解释平台变更。 | Git diff、审核和合并修订。 | 限制对平台仓库的直接集群写入和访问。 |
+| 修复跟踪漂移。 | 在启用和验证的层中自我修复。 | 操作员拥有的字段和凭证轮换需要自己的所有权规则。 |
+| 返回到先前的配置。 | 对早期 Git 内容的审核更改。 | 在将还原视为安全之前检查修剪和外部副作用。 |
+| 协调项目资源。 | 使用相同支持参数的重复入驻。 | 考虑令牌轮换、部分运行和项目锁定。 |
+
+注册表、数据库或身份系统可以保留 Git 中缺失的状态。定义恢复是否意味着恢复该状态或创建具有相同声明形状的新租户。此系列提供配置和入驻路径;完整的恢复运行手册必须在目标环境中执行。
+
+## 在引导之前准备平台
+
+使用其产品安装说明安装组件:
+
+- [Pipelines](https://docs.alauda.io/alauda-devops-pipelines/4.15/install.html),包括所需的 [PaC 组件](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/install/manage_pac.html) 和 [手动审批门](https://docs.alauda.io/alauda-devops-pipelines/4.15/how_to/manual_approval_gate_operator.html)。
+- [Connectors](https://docs.alauda.io/alauda-devops-connectors/1.14/install/install.html)。
+- [GitOps](https://docs.alauda.io/gitops/4.4/install_gitops/index.html)。
+- [Kyverno](https://docs.alauda.io/container_platform/4.4/security/security_and_compliance/compliance/install.html) 和密封密钥控制器。在同步政策和 SealedSecrets 之前,必须存在它们的 CRD。
+
+管理员创建管理命名空间,示例中的 `platform-connectors`,并在其中安装四个 Connectors 自动创建任务。这些任务是从 Connectors 文档中安装的;它们不是从一般任务目录中获取的。在提交之前准备对四个工具的管理员访问权限,并加密目标密封密钥控制器的凭证。
+
+在 Git 之外创建 Chains 签名密钥和中央注册凭证。中央注册凭证必须在同步挂载它的组件层之前存在。仅允许其访问 Chains 必须读取和签名的注册项目,并在项目入驻时更新该访问权限。
+
+在入驻之前,检查每个项目的 ServiceAccount,包括自动创建的 EventListener 身份及其实际组:Secret 的 `get`、`list` 和 `watch`,以及在 Chains 命名空间中创建 Pod 必须被拒绝。如果允许任何请求,则在其平台管理的源中缩小权限,或安装具有最小权限角色的组件版本,然后使用独立项目令牌重复检查。内置的 webhook Secret 验证使用单独的 core-interceptors 身份;EventListener 不需要集群范围的 Secret 读取。在权限更改后重新检查实际 webhook 接受和错误身份验证拒绝。遵循示例的 [项目访问检查](https://github.com/AlaudaDevops/devops-best-practices-samples/blob/main/sample-app/chains/README.md#check-project-access-before-enabling-signing)。
+
+使用 Argo CD 注册平台仓库,并为每个项目 GitOps 仓库提供读取访问权限。仓库凭证模板可以覆盖批准的 GitLab URL 前缀;每个项目必须添加更窄的模板。对于应用程序和 AppProject GitLab 引用,请使用以 `.git` 结尾的仓库 URL。对于应用程序目标和 AppProject 目标约束,请使用由 Alauda GitOps 注册的集群名称。
+
+通过平台在入驻之前创建 ACP 项目。管道导出该项目的清单以供后续注册。将现有项目导入 Git 需要与创建一个项目相同的审核:项目应用可以稍后修剪该资源。
+
+入驻创建 GitLab 组及其服务令牌;它不会决定哪些人类用户属于该组或授予他们 GitLab 项目创建权限。平台或项目管理员必须单独添加批准的成员并管理这些成员资格,而不是使用 Pipelines-as-Code 使用的令牌。
+
+平台管理员负责平台、项目 GitOps 和应用程序仓库的 webhook 设置和事件交付验证。当启用自动注册并配置 PaC 控制器 URL 时,创建 `Repository` 可能会导致注册控制器创建和删除项目 webhook。这需要一个集中式的 webhook 注册 GitLab 凭证,具有 `api` 范围和对项目的维护者访问权限,存储在控制器的命名空间中;PaC 仓库的开发者级别组令牌无法管理 webhook。配置控制器 URL,以便在 `pipelines-as-code-info` ConfigMap 中填充 `controller-url`,并在接受入驻之前验证仓库的注册状态和真实事件。有关产品特定凭证和控制器设置,请遵循 [高级仓库配置](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/how_to/advanced_repository_config.html) 和 [为 PAC 创建 Git Secret](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/how_to/create_git_secret.html)。
+
+合并调度程序在声明 ConfigMap 之外还有第二个就绪合同。在创建子入驻运行之前,`projects` 应用程序必须已在管理命名空间中发布确切的合并声明作为 `project-`,并且入驻应用程序必须在其中创建项目的 release-Connector `Role` 和 `RoleBinding`。示例将这两个对象命名为 `project-onboarding-release-connectors-`,并授予调度程序 ServiceAccount 名称范围的 `get` 访问权限。这些权限允许调度程序等待,而不授予其更改发布连接器的权限。因此,新项目需要其 release-Connector RBAC 文件及其在声明和 `projects/kustomization.yaml` 生成条目中的 `onboarding/kustomization.yaml` 条目。如果任一应用程序仍在赶上,调度程序必须等待或报告项目未准备好;在尝试协调发布连接器时,过早启动子运行可能会失败。在应用程序准备就绪后,从合并提交重试,只要它仍然是 `main` HEAD,使用 `/test onboard-changed-projects branch:main`。如果该提交不再是分支 HEAD,则改为启动受影响项目的入驻运行模板;在重试后检查父结果和每个子运行。
+
+保持 Harbor 项目私有。如果 Nexus 启用了匿名访问,并且其匿名角色可以读取租户仓库,则未经身份验证的用户可以读取由入驻任务创建的仓库,绕过租户凭证。入驻任务仅对匿名访问发出警告。禁用它(设置 → 安全 → 匿名访问)或删除匿名角色对租户仓库的访问权限,然后确认拒绝未经身份验证的读取。根据其任务指南,根据项目隔离要求配置 SonarQube 权限。不要仅仅根据单独凭证的存在推断隔离。
+
+对于离线环境,在运行管道之前准备本地目录内容、固定工具和基础镜像、依赖仓库、证书和漏洞数据库。
+
+## 决定 18 个平台基线
+
+项目不应各自决定如何暴露管理员凭证、审计历史存储在哪里或哪些控制器可以绕过共享政策。在移交平台之前解决这些问题。特定于应用程序的输入和额外限制可以保留在项目中。
+
+示例将决策分为四个 Git 所有权层:
+
+| 层级 | 它拥有的配置 | 单独层级的原因 |
+| ---------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
+| 组件 | TektonConfig 片段、Chains 选项、Pruner、Results 和监控设置。 | 共享控制器和单例字段需要操作员感知的同步。 |
+| 政策 | ClusterPolicies 和共享准入边界。 | 平台限制需要受控的推出和保护,以防项目更改。 |
+| 凭证 | 管理员 Connectors、加密 Secret 源和平台 PaC 注册。 | 凭证访问和轮换与应用状态有不同的生命周期。 |
+| 项目 | 声明和审核注册输出:应用程序、绑定和目标补丁。 | 每个项目请求的资源和部署范围可以一起审核。 |
+
+入驻安装是一个单独的应用程序,因为其执行权限和发布生命周期也需要审核。下面的层级列标识责任;四个自动创建任务仍然管理自己的外部资源。
+
+该表标识平台决策及其仓库层。值和详细步骤属于链接的产品文档。这些是由管理员管理的建议,其成熟度和先决条件由所选版本决定。
+
+| # | 何时重要 | 决策 | 共享的原因 | 层级和指导 |
+| -- | ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| 1 | 在入驻第一个仓库或更改 GitLab 提供者之前。 | 将仓库访问令牌与 webhook 管理分开;使用审核过的默认分支定义和明确的 GitLab 提供者 URL。 | 凭证范围和合并前执行信任应保持一致。 | 凭证和项目:[PaC 仓库配置](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/how_to/advanced_repository_config.html)。 |
+| 2 | 当团队需要可重复的合并请求或推送触发的重跑时。 | 对于合并请求运行,在合并请求上评论 `/test branch:`;对于推送触发的运行,在应运行的分支的最新提交上发布相同的形式。 | 团队使用一个受支持的条目并明确源分支。 | 项目模板:[触发 PAC 管道](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/how_to/trigger_pipeline.html)。 |
+| 3 | 当平台管理的地址或 Connector 必须在不编辑每个应用程序的情况下更改时。 | 将平台提供的仓库参数与应用程序输入分开。 | 地址和 Connector 名称有明确的所有者。 | 项目:[高级仓库配置](https://docs.alauda.io/alauda-devops-pipelines/4.15/pac/how_to/advanced_repository_config.html)。 |
+| 4 | 当外部注册表事件启动另一个管道时。 | 决定 Harbor 事件交接。 | 事件端点和验证需要一致的所有权。 | 组件:[Harbor 事件](https://docs.alauda.io/alauda-devops-pipelines/4.15/triggers/how_to/harbor_events.html)。 |
+| 5 | 当凭证或声明需要定期修复时。 | 安排协调和轮换,并设置故障警报。 | 平台拥有间隔和操作响应。 | 组件:[ScheduledTrigger](https://docs.alauda.io/alauda-devops-pipelines/4.15/triggers/how_to/scheduledtriggers.html)。 |
+| 6 | 在将 webhook 端点暴露到集群外部之前。 | 标准化 EventListener 暴露。 | TLS、路由和 webhook 验证属于平台。 | 组件:[自动暴露规则](https://docs.alauda.io/alauda-devops-pipelines/4.15/triggers/how_to/trigger-wrapper-config.html)。 |
+| 7 | 当新项目必须接收相同的工具侧资源时。 | 使用四个产品任务协调工具侧租户创建。 | 管理员保留工具范围的凭证。 | 凭证和项目:下面的工具任务指南。 |
+| 8 | 在第一个令牌达到其到期窗口之前。 | 为每个工具定义长期凭证轮换。 | 到期和续订行为因工具而异。 | 组件和凭证:[GitLab 自动创建任务](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors-gitlab/how_to/using_gitlab_connector_automatic_creation_task.html#step-by-step--rotate-in-place)、[Harbor 自动创建任务](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors-harbor/how_to/using_harbor_connector_automatic_creation_task.html#example-re-run-the-task-to-refresh-credentials-and-reconcile-resources)、[Nexus 自动创建任务](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors-nexus/how_to/using_nexus_connector_automatic_creation_task.html#re-run-to-add-repositories-or-rotate-credentials) 和 [SonarQube 自动创建任务](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors-sonarqube/how_to/using_sonarqube_connector_automatic_creation_task.html#rotation)。 |
+| 9 | 在生产注册表由 Kyverno 强制执行之前。 | 配置 Chains 签名密钥和镜像验证。 | 平台拥有签名者并分发其公钥。 | 组件、凭证、政策:[签名密钥](https://docs.alauda.io/alauda-devops-pipelines/4.15/chains/configure/signing_key_configuration.html)。 |
+| 10 | 当工作负载访问长期凭证必须被缩小时。 | 使用 Connector 代理访问,同时跟踪长期凭证例外。 | 访问边界和轮换需要一个中央所有者。 | 凭证:[Connectors Proxy](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors/concepts/connectors_proxy.html) 和 [CSI 驱动程序](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors/concepts/connectors_csi.html)。 |
+| 11 | 在构建工具和工作负载共享集群之前。 | 应用命名空间 Pod 安全性并分隔构建命名空间。 | 构建工具和工作负载具有不同的权限需求。 | 政策和项目:[受限标准](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/how_to/comply_with_pod_security_restricted.html)。 |
+| 12 | 在生产凭证或工件可以发布之前。 | 安装审批并定义受保护环境组和提升规则。 | 审批所有权是平台控制。 | 组件、项目、政策:[手动审批门](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/how_to/manual_approval_gate.html)。 |
+| 13 | 当项目需要额外限制而不削弱平台控制时。 | 建立平台和项目政策层。 | 项目可以添加限制,而不削弱平台基线。 | 政策:[限制管道执行](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/how_to/constrain_pipeline_execution_with_kyverno.html)。 |
+| 14 | 当集群无法从互联网获取任务或管道时。 | 拥有共享的、本地可用的目录。 | 重用和离线内容需要治理。 | 组件:[作者目录资源](https://docs.alauda.io/alauda-devops-artifacthub-shim/1.0/catalog/how_to/author_catalog_resources.html)。 |
+| 15 | 当多个项目使用相同的工作流时。 | 发布版本化的中央管道。 | 项目明确采用审核版本。 | 组件:[集中式管道管理](https://docs.alauda.io/alauda-devops-pipelines/4.15/pipelines/how_to/hub_pipeline_run_template_centralized_management.html)。 |
+| 16 | 在清理可以删除共享运行历史记录之前。 | 选择 Pruner 默认值和命名空间覆盖策略。 | 清理影响共享集群历史和容量。 | 组件:[Pruner 配置](https://docs.alauda.io/alauda-devops-pipelines/4.15/pruner/configure/pruner_configuration.html)。 |
+| 17 | 在实时 Tekton 对象被修剪之前。 | 定义结果存储、观察范围、身份验证和保留。 | 审计记录需要独立于实时对象的存储。 | 组件:[结果保留](https://docs.alauda.io/alauda-devops-pipelines/4.15/results/configure/retention_policy_configuration.html)。 |
+| 18 | 在没有控制器健康证据的情况下操作平台之前。 | 启用指标和操作监控。 | 操作员需要控制器和执行健康的证据。 | 组件:[指标收集](https://docs.alauda.io/alauda-devops-pipelines/4.15/configure/metrics_collection.html)。 |
+
+### 选择共享默认值而不隐藏其成本
+
+对于仓库访问和触发器,集中 webhook 管理,以便项目不需要 webhook 管理令牌。将较低权限的仓库令牌、审核过的定义源和明确的提供者 URL 与仓库配置保持在一起。标准重试命令有助于操作员,但发布工作流可以故意禁止评论重试:应用程序示例的 `ci` 需要在 `main` 上进行真实的 `push`。使用其单独的合并请求定义进行评论触发的检查。
+
+对于工具访问,管理员准备创建任务及其凭证一次;项目接收范围资源和 Connectors。代理工作负载令牌减少了对工具凭证的常规暴露。它们不会移除工具的后端凭证、PaC 克隆凭证、镜像拉取 Secret 或 Chains 注册表访问的轮换。构建命名空间分离和对 Pod 创建的限制是此选择的一部分,而不仅仅是资源上的标签。
+
+对于发布信任,平台拥有签名密钥、验证政策和受保护的生产凭证路径。项目选择哪个环境需要审批,并可以添加限制。单独安装审批组件并不能保护凭证。生产提升还需要核心准入规则和对已部署镜像源的限制,这些在交付文章中描述;这些附加内容并不是由此示例安装的。
+
+对于共享资产,通过本地服务发布目录任务和版本化管道。固定版本使采用可审核;平台还必须保留引用的内容并定义发布坐标是否可以更改。初始 GitOps 模板是种子,因此升级该模板需要对已经包含内容的仓库进行单独更改。
+
+对于操作,选择清理、归档和监控。清理节省集群容量,但删除实时证据。结果需要外部存储及其自己的读取授权,而审批响应需要单独保留。第一次 Pruner 同步和结果观察范围可能会影响现有租户,因此引入它们时需要进行清单和约定的保留限制。
+
+这些设置是平台决策,而不是承诺产品默认值已经启用预期控制。检查
+[功能成熟度](https://docs.alauda.io/alauda-devops-pipelines/4.15/overview/feature_maturity.html)
+以获取所选版本,并分阶段引入每个控制。
+
+### 将政策范围与定义信任分开
+
+使用平台 ClusterPolicies 进行共享控制,使用命名空间策略进行项目特定限制。项目可以缩小允许的模板、版本、镜像仓库或参数,而不削弱平台基线。这取决于防止项目授予自己例外或更改平台政策。
+
+通过实际提交身份限制直接 TaskRun 和 CustomRun 创建;仅依靠客户端提供的拥有者引用并不是授权边界。列举控制器身份并审核其权限。允许自动化身份创建直接运行会为任何可以使用该身份的人打开该入口。示例将管理命名空间排除在其解析器和直接运行策略之外,因此该命名空间的执行权限仍然至关重要。
+
+可选地限制 PipelineRun 引用为批准的解析器类型。此缩略政策仅说明源类型决策;为每个平台系统命名空间调整命名空间排除:
+
+```yaml
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+ name: pipelinerun-source-baseline
+spec:
+ background: false
+ rules:
+ - name: approved-resolver-only
+ match:
+ any:
+ - resources:
+ kinds: [tekton.dev/v1/PipelineRun]
+ operations: [CREATE]
+ exclude:
+ any:
+ - resources:
+ namespaces: [platform-connectors]
+ validate:
+ failureAction: Audit
+ message: "pipelineRef must use an approved resolver"
+ deny:
+ conditions:
+ all:
+ - key: "{{ request.object.spec.pipelineRef.resolver || '' }}"
+ operator: AnyNotIn
+ value: [cluster, hub, git]
+```
+
+这并不限制解析器的 URL、目录、命名空间、版本、定义内容或运行时凭证范围。它还在强制时拒绝内联 `pipelineSpec`。在为项目仓库启用该限制之前,将示例的内联验证流转换为目录管道。在 `Audit` 中,违反此解析器规则的 PipelineRun 仍然被接受,并应生成 PolicyReport;在 `Enforce` 中,相同的请求被拒绝。在依赖该政策之前,使用一次性项目身份测试这两种模式。仅允许平台管理员创建 `PolicyException` 对象,或根据平台政策禁用例外;不要将此逃生口委托给项目身份。
+
+### 限制项目部署而不替代 ACP 所有权
+
+示例的 `argocd-project-namespace-boundary` 政策从一开始就以 `Enforce` 安装。不要遵循此边界的审核优先推出:审核报告不会阻止项目身份写入受保护对象。该政策通过配置的 Argo CD 身份限制对标记项目命名空间中的 Role、RoleBinding、ResourceQuota、LimitRange、NetworkPolicy、Kyverno PolicyException 和 Connectors AccessPolicy 的写入。它允许平台拥有的注册路径,并要求 `allowExistingViolations: false`。根据目标集群调整两个 Argo CD 身份,并在依赖边界之前验证已安装 API 的预期允许和拒绝情况。平台 `projects` 应用程序的例外依赖于 Argo CD 的 `argocd.argoproj.io/tracking-id` 注释;仅基于标签的资源跟踪不受覆盖。限制其他身份创建例外和 AccessPolicy,并将任何平台例外命名空间保持在项目目标之外。在每个应适用该边界的目标集群上安装并验证该政策。
+
+当所有三个条件成立时,该政策拒绝受保护的写入:
+
+1. 写入者是实际的 Argo CD 身份之一:注册的集群身份或应用程序控制器的身份。
+2. 目标是标记为 `cpaas.io/project` 的命名空间,排除平台系统项目。
+3. 对象的跟踪注释未标识平台拥有的 `projects` 应用程序。
+
+这为平台注册提供了受控路径,同时防止项目应用程序利用部署权限重写其自身的权限、配额、网络边界、政策例外或 Connector 访问。它涵盖新对象和现有对象,因此使用实际身份测试创建、更新和删除请求。报告控制器还需要对匹配的 API 具有读取访问权限;示例包括 PolicyException 和 AccessPolicy 的聚合读取角色。
+
+被拒绝的对象使应用程序的同步失败,并显示政策消息。重试设置决定后续尝试。从项目源中删除被禁止的对象并同步更正的修订。保持此边界从首次安装时就处于 `Enforce` 状态;其目的是阻止项目身份更改受保护对象,因此审核推出将留下该空白。
+
+Kyverno 可用性和恢复是平台操作问题。对于用作准入门的政策,保持资源 webhook 注册为 `failurePolicy: Fail`;当 Kyverno 无法访问时,匹配的写入将被拒绝。这同样适用于审核政策:`failureAction: Audit` 控制 Kyverno 评估请求时的结果,但它不会使不可用的 Kyverno webhook 失败。在示例中,`no-bare-taskrun` 是一个审核政策,匹配集群中的直接 `TaskRun` 创建(除了其文档平台排除),因此 Kyverno 故障可能会阻止这些 TaskRuns 的创建,并可能停止依赖于它们的管道。对于此边界,失败还包括 Role、RoleBinding、ResourceQuota、LimitRange、NetworkPolicy、PolicyException 和 Connectors AccessPolicy 写入:入驻身份和集群管理员在 Kyverno 恢复之前被拒绝。缺失的 webhook 不提供强制执行,且有序的零规模可以删除资源 webhook 注册。保持 Kyverno 高可用,并保持受控的恢复程序,包括临时删除和稍后恢复 webhook 配置的条件。签名结果证明签名密钥,而不是生成图像的管道。将 ClusterPolicy、解析器、webhook 和 PolicyException 的更改限制为平台管理员。有关政策设计,请参见 [使用 Tekton 和 Kyverno 的管道政策约束](./Pipeline_Policy_Constraints_with_Tekton_and_Kyverno.md)。
+
+## 组织和同步平台仓库
+
+### 连接仓库、集群和所有权层
+
+Argo CD 需要三个独立的协议:仓库读取访问权限、注册的目标集群和允许源和目标的 AppProject。在调试工作负载清单之前完成这三项。使用只读平台仓库凭证和覆盖批准的项目 GitOps URL 前缀的仓库凭证模板。入驻创建应用程序,而不是那些 Argo CD 凭证。
+
+在应用程序和 AppProject 引用中使用以 `.git` 结尾的 GitLab URL,以避免 Argo CD 不遵循的重定向。使用来自 Alauda GitOps 注册的 `destination.name: `,并在 AppProject 目标中使用相同名称。默认的 `in-cluster` 条目可以限制为 Argo CD 命名空间;它不是 ACP 注册集群的可互换名称。当迁移使用 `destination.server` 的清单时,删除该字段,而不是在实时对象上保留 `name` 和 `server`。
+
+使用 `platform-repo/` 作为树根;仓库本身可以有任何名称。示例分为四个所有权层和入驻安装:
+
+```text
+platform-repo/
+├── argocd/apps/ # 根和子应用程序定义
+├── components/ # TektonConfig 和组件选项
+├── policies/ # 平台准入政策
+├── credentials/ # 管理员 Connectors 和密封占位符
+├── projects/ # 声明和审核注册输出
+├── templates/ # 注册渲染模板
+├── onboarding/ # 管道、运行模板、计划和 RBAC
+└── .tekton/ # 验证和更改项目调度
+```
+
+每个层级一个应用程序让审核者理解其路径和同步政策。一个层级中的渲染失败可能会阻止该应用程序中的所有对象;单独的应用程序减少受影响的范围,而控制器、凭证和运行之间的先决条件仍需得到尊重。示例具有根、四个所有权层和一个用于入驻的第五个子层。
+
+根据其 README 将 `onboarding/` 从示例复制到平台仓库根。将仓库以只读方式注册到 Argo CD,并为每个层使用一个子应用程序。根应用程序管理这些应用程序定义。在替换占位符并准备上述凭证和 CRD 后,从该仓库的根引导一次:
+
+```bash
+kubectl apply -k argocd/apps/
+```
+
+在 `projects/` 中已存在的声明在稍后的 `main` 更改之前不会被合并调度程序拾取。在应用程序同步后,为每个现有声明运行一次入驻运行模板。稍后的更改遵循审核过的 Git 和调度程序路径。
+
+### 根据资源生命周期选择同步行为
+
+自动同步应用新的 Git 修订。自我修复在没有新修订的情况下修复实时更改。修剪删除从 Git 中移除的跟踪资源。这些是单独的决策:启用一个并不意味着所有三个都适合某个层级。
+
+| 应用程序或层级 | 示例选择 | 原因和条件 |
+| ---------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
+| 根应用程序定义 | 自动同步、修剪和自我修复。 | Git 拥有子应用程序配置。在删除应用程序之前审核移除和最终处理程序。 |
+| 组件 | 自动同步;`prune: false`,`selfHeal: false`。 | 部分单例 TektonConfig 字段与操作员共存;移除片段不得删除单例。 |
+| 凭证 | 自动同步,自我修复禁用。 | 协调密封源、控制器管理字段和实时令牌轮换。 |
+| 政策、项目和入驻 | 示例中自动同步、修剪和自我修复。 | Git 拥有这些资源;注册删除对项目级别有影响。 |
+| 项目环境应用程序 | 自动同步、修剪和自我修复。 | Git 是期望的应用程序状态;测试和生产在 Git 审核要求上有所不同。 |
+
+对于部分单例组件配置,使用服务器端应用程序,以便平台仓库仅拥有指定字段。与之一起设置 `argocd.argoproj.io/compare-options: ServerSideDiff=true`;如果没有服务器端差异,应用程序可能保持 `OutOfSync`,自我修复可能会重复应用相同的明显漂移。在同步之前审核生成的差异和操作员的字段所有权。组件层使用 `prune: false`,以便移除片段时不会删除单例 TektonConfig,并以 `selfHeal: false` 开始。在启用持续自我修复之前,观察操作员的写回行为和有效所有权。自动同步新的 Git 修订和实时编辑的自我修复是单独的决策。
+
+凭证层不启用自我修复:密封 Secrets 控制器可能会将控制器管理的状态写回实时 Secret,因此 Argo CD 可能会看到必须不重复覆盖的字段级差异。为目标控制器密封凭证,并计划如何轮换更新实时 Secrets 和加密源。对于启用自我修复的层,必须通过平台仓库和审核过的合并更改来更改受管理的对象;直接的 `kubectl` 编辑是临时的,并将被协调。ACP 项目首先创建同名的内部命名空间;入驻标记并采用该命名空间,然后创建工作负载、构建和交付命名空间。不要使用 `CreateNamespace` 添加第二个命名空间创建者。
+
+### 审核有效的 AppProject 及其替代方案
+
+ACP 维护与 ACP 项目关联的 AppProject。注册补丁仅管理预期的仓库和目标字段。将有效目标与平台管理的条目协调,并使用准入边界进行对象类型限制。不要仅依赖应用程序的同步状态来证明部署边界。
+
+示例仅在 ACP 管理的 AppProject 上补丁 `sourceRepos` 和 `destinations`。ACP 还可以维护项目自身命名空间的目标条目,包括构建和交付。检查有效对象;注册补丁不是可达命名空间的独占列表。将单独命名的部署 AppProject 作为另一种选择,例如 `-deploy`,具有自己的源、目标和资源限制。它使 Argo CD 拥有该项目的限制,但使用它的应用程序在选择 `spec.project` 等于 ACP 项目名称时不会出现在 ACP 项目的 GitOps 列表中。操作员将使用 Argo CD 查看它们。根据所有权和所需的控制台体验进行选择。
+
+示例的平台 AppProject 允许广泛的注册操作。为了生产平台,缩小其源、目标和允许的类型;不要将其注册权限交给项目应用程序编写者。退役还需要单独检查和删除与 ACP 关联的 AppProject。
+
+### 将注册回滚视为生命周期操作
+
+仔细审核删除。还原注册提交或删除 `projects//` 及其 `resources` 条目可能会使 Argo CD 修剪注册的 ACP 项目。这可能会删除其同名命名空间以及其中的 Secrets、Connectors 和 Repository 对象。它不会逆转工具侧创建或自动删除每个构建、交付或环境命名空间。
+
+仅删除 `projects/.yaml` 是不同的:它不会退役项目,并且将其 `configMapGenerator` 条目保留在位置会使声明层渲染失败。使用单独的批准退役程序,涵盖工作负载、保留证据、外部租户、凭证、webhook 和每个命名空间。
+
+### 在合并之前验证更改
+
+在更改合并之前,渲染每个目录应用程序所需的内容。错误的 Kustomize 引用会阻止生成该应用程序的清单集,因此同一层中的不相关对象也可能停止同步。在合并请求验证中找到问题使其接近作者和差异。
+
+平台和项目 GitOps 模板都包含 `.tekton/validate.yaml`,它组合目录 `git-clone` 和 `run-script` 任务。用包含 `sh`、`kubectl` 和 `kubectl kustomize` 命令的本地可用镜像替换其工具镜像;仅具有独立 Kustomize 二进制文件的镜像不足以满足示例脚本的要求。在第一次合并请求运行之前建立其 webhook。通过默认分支定义来源,验证定义的更改在进入该分支后首次执行。
+
+验证每个应用程序拥有的目录,并将新目录添加到验证路径。使用 `/test validate branch:` 重新运行合并请求检查。PaC 使用合并请求的源分支,并忽略 `branch:` 以选择另一个 MR 分支;要运行另一个分支,请在其最新提交上评论。YAML 解析和 Kustomize 渲染不验证 CRD 准入行为;使用目标模式和隔离项目进行该接受步骤。
+
+验证状态仅在 Git 平台要求时阻止合并。在 GitLab 上,为平台和项目 GitOps 仓库启用 **管道必须成功**。如果 Auto DevOps 启动没有可用运行器的额外管道,则合并请求可能保持在运行状态;禁用这些仓库的 Auto DevOps 或提供运行器。
+
+使用 `pipelinerun_provenance: default_branch`,定义被审核,但验证仍然渲染提议的合并请求内容。示例的平台 Repository 和验证运行位于 `platform-connectors` 中,该位置也保存管理员 Secrets。该位置仅适合受信任的平台维护者:在那里创建运行的权限可能会暴露这些 Secrets。在接受不太可信的贡献之前,将 Repository、其有限令牌和验证执行移动到没有管理员凭证的命名空间。保持管理调度分开,仅授权审核过的调度路径以创建入驻运行。
+样本入职调度程序将推送的修订版与其第一个父级进行比较。使用合并或压缩工作流,确保在该比较中保留所有声明更改;包含多个独立提交的快进推送可能会导致早期的声明更改被遗漏。样本的 `on-path-change` 注释是 4.15 版本中的技术预览功能,因此在依赖它作为触发边界之前,请验证其成熟度和行为。
+
+## 声明项目并运行入职
+
+声明记录项目请求的内容:所有权组、环境、命名空间和工具租户。它不包含凭证或运行时生成的工具 ID。平台合并请求还提供了使请求可执行的命名权限和计划。
+
+该样本故意支持一种命名约定和所有四种工具。显式派生名称使审查者能够在不记住该约定的情况下查看请求的形状;入职验证器检查它们是否一致。声明不是通用的供应 API,更改名称可能会改变外部工具中的身份或凭证行为。
+
+声明是一个示例架构,而不是 ACP API。管道验证其支持的命名约定。完整的 `shop` 声明包括以下字段;使用样本的完整文件:
+
+```yaml
+name: shop
+platformProject: shop
+owners:
+ - shop-platform-owners
+environments: [test, prod]
+tools: [gitlab, harbor, nexus, sonarqube]
+approvers:
+ prod: group:release-managers
+imagePullFrom: []
+namespaces:
+ workloads: [shop, shop-test, shop-prod]
+ build: shop-build
+ delivery: shop-cd
+gitlab:
+ group: shop
+ subgroups: [apps, gitops]
+harbor:
+ projects: [shop, shop-prod]
+nexus:
+ repositories:
+ - name: shop-maven
+ format: maven2
+ type: hosted
+ - name: shop-npm
+ format: npm
+ type: hosted
+sonarqube:
+ project: shop
+```
+
+`owners` 包含没有 `group:` 前缀的 ACP 组资源名称;审批条目使用 `group:`。控制台显示名称不是资源名称。当需要固定组名称时,请将该组作为经过审核的 `auth.alauda.io/v1` `Group` 对象创建,并通过 ACP 组管理导入其用户成员;不要在每个声明中放置单个用户名。以下示例使用 ACP 的本地身份源。显示名称注释和身份源引用都是必需的;对于由其他身份提供者管理的组,请使用适当的引用。
+
+```yaml
+apiVersion: auth.alauda.io/v1
+kind: Group
+metadata:
+ name: shop-platform-owners
+ annotations:
+ cpaas.io/display-name: Shop platform owners
+spec:
+ refConnector:
+ id: local
+ type: local
+ users: []
+```
+
+组存在后,在控制台中添加已批准的成员,并通过 `kubectl get groups.auth.alauda.io` 验证资源名称。组成员资格的更改属于组管理,而不是在每个声明中编辑个人名称。
+
+`imagePullFrom` 是保留字段:该示例仅在设置时打印警告,并不授予跨项目拉取访问权限。
+
+声明的 `approvers` 字段仅是经过审核的记录:入职验证其形状,但不应用或比较它。生效的审批者是提升管道的 `ApprovalTask` 列表和生产 `AccessPolicy`;没有任何东西可以保持这三个来源的同步,因此请在一次审核更改中一起更新它们。将生产 `AccessPolicy` 保持在平台管理员控制之下,因为可以编辑管道的人可以在 AccessPolicy 继续执行其自己的审批者集的同时更改其 `ApprovalTask` 列表。签名结果记录配置的密钥,而不是生成图像的管道,且 Chains 不会为包含 `CustomRun` 任务的 `PipelineRun` 创建运行级签名;请在发布证据中保持该限制。
+
+### 审查项目合并请求中的所有输入
+
+包括声明、其 `configMapGenerator` 条目、项目的命名入职权限、其 ScheduledTrigger 和 Kustomize 条目,以及其生产图像验证存储库条目。这些内容是一起的,因为仅凭声明无法授予入职身份管理新的生产连接器或扩展验证策略。
+
+每个项目的权限文件是故意的:它们将发布连接器的写入限制在列出的名称内。从任何声明生成任意 RoleBindings 将需要更广泛的 `bind` 或 `escalate` 权限。在用更多自动化替换显式文件之前,请审查该安全成本。单独地,将新的注册表项目添加到平台拥有的中央 Chains 凭证的访问权限中。
+
+通过平台合并请求提交声明、项目特定的入职权限和计划。确认声明和入职原生应用已同步;在使用手动同步策略时手动同步它们。然后检查调度结果和每个子入职运行。成功的合并或调度本身并不建立完整的项目准备。
+
+合并检查并不替代入职验证。声明的结构和派生名称由合并后的入职运行检查,因此语法上有效但语义上无效的声明仍然可以合并,并且必须从该运行的结果中诊断。
+
+样本在合并后调度更改的声明。路径过滤器也可以允许没有相关声明更改的运行;调度程序负责选择实际声明。已删除的声明被跳过,而不是被解释为删除项目的指令。
+
+### 理解七个入职阶段
+
+在这些阶段之前,管道原子地获取项目的 ConfigMap 锁。然后在更改租户资源之前验证声明。在其他检查中,样本要求四个支持的工具、组形状的审批者、匹配的派生名称和不在平台保留名称之外的命名空间。它拒绝采用另一个项目的命名空间。例外是与 ACP 项目一起创建的同名内部命名空间,入职明确标记并采用。
+
+这七个阶段描述了责任;在命名空间准备好后,几个工具任务并行运行,注册步骤开始自己的子运行。
+
+| 阶段 | 工作 | 所有者或机制 |
+| ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
+| 1 | 导出现有的 ACP 项目而不带运行时元数据;创建或协调标记的命名空间和交付身份。工作负载使用受限的 Pod 安全;构建命名空间是分开的。 | 样本编排和 Kubernetes API |
+| 2 | 创建 GitLab 租户组和两个组访问令牌:用于项目操作的开发者令牌和用于 GitOps 交付的单独维护者令牌。 | GitLab 自动创建任务 |
+| 3 | 创建私有源和生产 Harbor 项目,分发图像拉取配置,并为发布创建单独的源读取和生产写入连接器。 | Harbor 自动创建任务 |
+| 4 | 创建 Nexus 存储库和一个范围用户,然后写入项目连接器。 | Nexus 自动创建任务 |
+| 5 | 创建 SonarQube 用户、令牌和项目权限模板,然后写入连接器。 | SonarQube 自动创建任务 |
+| 6 | 种子空项目 GitOps 存储库并创建其 PaC 存储库和访问密钥。单独完成并验证 webhook 配置。 | 样本模板播种和 PaC 资源 |
+| 7 | 渲染项目应用程序、AppProject 补丁、拥有者和连接器绑定,以及导出的 ACP 项目。打开平台注册合并请求。 | 单独的 `gitops-repo-update` PipelineRun |
+
+第一个和最后一个阶段是样本编排。四个外部工具使用产品自动创建任务,而存储库播种仅复制一次经过审核的模板。这种分离将工具特定的帐户和轮换行为保留在产品任务中,并将排序和注册保留在样本管道中。
+
+导出的 ACP 项目省略状态、服务器生成的元数据和 GitOps 跟踪标记。将运行时跟踪保持在 Git 之外,避免仅用于复制先前同步的元数据的注册合并请求。在工具任务需要它们之前,命名空间和交付身份已创建。构建命名空间使用 Pod 安全 `baseline`;工作负载和交付命名空间使用更严格的 `restricted` 级别。在应用命名空间标签时保持这种区别。
+
+Harbor 拉取配置分发到工作负载和构建命名空间。样本交付命名空间运行工具图像,并且不接收该项目拉取密钥。项目的四个连接器位于项目命名空间中;GitOps 写入者位于交付中;生产发布连接器位于管理中。检查每个凭证实际持有的权限,而不是从名称如“pull”或“readonly”推断它们。
+
+入职创建项目的 GitLab 组,但不向其中添加人员。在移交之前,平台管理员必须根据平台的访问政策将项目的开发人员添加到该组,并授予他们在该组中创建存储库的角色。
+
+注册步骤建议 Git 更改,而不是直接应用 Argo CD 资源。审查整个差异,包括 RBAC 和目标更改。提交一个平台合并请求,添加声明、其 `configMapGenerator` 条目在 `projects/kustomization.yaml` 中、项目的 release-Connector 角色和 RoleBinding 以及 ScheduledTrigger 文件,以及它们在 `onboarding/kustomization.yaml` 中的条目,以及项目在图像验证策略中的生产存储库。没有 `configMapGenerator` 条目,调度程序将等待项目的 ConfigMap,然后跳过该项目。没有 release-Connector RBAC 条目,调度程序无法确认子运行的连接器先决条件存在。为父运行和子运行保留足够的执行容量:等待的父运行仍然保留其 Pod 资源。取消和清理必须考虑独立创建的子运行。
+
+管道在管理命名空间中运行,使用管理员连接器。创建 Pods 或 PipelineRuns 的权限实际上是对这些凭证的访问,即使没有 API 权限读取 Secrets。将该命名空间和入职身份限制为平台自动化和管理员。
+
+
+
+### 重用产品任务
+
+为每个工具的租户资源、帐户、令牌和连接器输出使用产品任务。样本添加了声明解析、命名空间所有权、排序、锁定、播种和平台注册。在入职脚本中重新实现四个工具的帐户逻辑将重复它们的合同和轮换行为。
+
+这四个任务具有不同的参数和轮换行为。阅读它们的安装、访问和先决条件说明:
+
+- [GitLab 租户组和连接器](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors-gitlab/how_to/using_gitlab_connector_automatic_creation_task.html)。
+- [Harbor 资源和连接器](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors-harbor/how_to/using_harbor_connector_automatic_creation_task.html)。
+- [Nexus 资源和连接器](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors-nexus/how_to/using_nexus_connector_automatic_creation_task.html)。
+- [SonarQube 租户和连接器](https://docs.alauda.io/alauda-devops-connectors/1.14/connectors-sonarqube/how_to/using_sonarqube_connector_automatic_creation_task.html)。
+
+将目标 `connector` 设置为 `namespace/name`。明确设置 GitLab 访问级别:样本中的两个令牌都是组访问令牌,开发者用于项目操作,维护者用于 GitOps 写入。开发者令牌具有 `api`,因此缺少 `write_repository` 不会阻止基于 API 的存储库更改,而 `main` 是未受保护的;在将 `main` 保护之前,请先保护它。连接器 CSI 挂载使用 `connectors` 属性,并包含命名空间。
+
+样本仅使用显式授权的 ServiceAccount 写入当前集群。对于跨集群应用,请遵循每个任务的 Kubernetes 连接器和 `kubeconfig` 工作区说明。不要假设管理命名空间的默认 ServiceAccount 具有所需的写入权限。
+
+选择当前集群的 ServiceAccount 避免分发另一个管理员 kubeconfig,但代价是每个所需写入的显式 RBAC。使用 `generateName` 提交的 TaskRun 或 PipelineRun 使用 `kubectl create`。在运行它们的命名空间中安装任务,并在提交之前检查运行身份;未指定的默认 ServiceAccount 不是隐式管理员。
+
+替代产品工作流从命名空间事件创建项目连接器:[自动为项目创建连接器](https://docs.alauda.io/alauda-devops-connectors/1.14/how_to/automatically_create_connectors_for_a_project.html)。如果选择该路径,请为每个租户和资源分配一个创建者和轮换所有者。避免两个独立的调解器管理相同的凭证。
+
+## 注册存储库并验证事件
+
+在每个 PaC 存储库上设置自管理提供程序 URL 和经过审核的定义源。以下片段省略凭证数据;通过批准的凭证路径创建其引用的 Secret:
+
+```yaml
+apiVersion: pipelinesascode.tekton.dev/v1alpha1
+kind: Repository
+metadata:
+ name: shop-gitops
+ namespace: shop
+spec:
+ url: https://git.example.com/shop/gitops/config
+ git_provider:
+ type: gitlab
+ url: https://git.example.com
+ secret:
+ name: shop-gitops-auth
+ webhook_secret:
+ name: shop-gitops-auth
+ settings:
+ pipelinerun_provenance: default_branch
+```
+
+明确设置提供程序 URL,以便完成请求和存储库令牌使用预期的 GitLab 实例。PaC 存储库 URL 与 Argo CD 使用的 `.git` URL 不同。`gitops/config` 是位于 `gitops` 子组下的存储库,而不是与该子组名称冲突的存储库路径。
+
+项目的 PaC 存储库使用开发者级别的组访问令牌。当启用自动 webhook 注册时,控制器使用平台管理员配置的集中式 webhook 注册凭证来创建和删除 webhook;验证新事件及其结果运行。单独的 GitOps 写入者使用维护者级别的组访问令牌。在存储库退役后,保持 webhook 注册凭证可用,并在之后检查剩余的代码平台 webhook。应用程序的存储库属于构建命名空间,在那里 CI 执行。应用程序 CI 对象属于构建命名空间;CD 和提升运行模板及 PipelineRuns 属于交付命名空间,并需要管理员或明确的委托授权。
+
+如果省略 `git_provider.url`,PaC 可以将完成评论发送到公共的 `gitlab.com` 提供程序,而不是自管理的 GitLab 实例,因此预期的合并请求可能永远不会显示最终状态。始终为自管理安装设置提供程序 URL,并验证预期合并请求上的评论。
+
+### 将平台参数与应用输入分开
+
+入职流程将平台提供的值(例如注册表地址和连接器名称)写入生成的存储库的 `spec.params` 中。PaC 定义可以消费这些值,而应用程序提供自己的源修订和构建输入。这使得平台拥有的地址有明确的所有者,并避免在每个消费存储库参数的定义中重复它。
+
+该参数层不会重写所有现有配置。注册表和 Git 地址也出现在播种的 GitOps 内容、应用程序 CI/CD、提升映射、Argo CD 引用和验证策略中。地址迁移必须通过其自己的审核更改更新这些消费者。重新运行入职将保持非空的 GitOps 存储库不变。
+
+存储库访问和 webhook 管理也具有不同的生命周期。PaC 从存储库访问令牌生成每次运行的克隆凭证;即使运行没有接收 webhook 管理员令牌,这些凭证仍然是敏感的。单独测试注册、交付新事件、预期运行命名空间和完成状态。
+
+
+
+## 深思熟虑地调解和轮换
+
+### 区分调解与模板升级
+
+重复入职对于支持的声明更改、计划工具调解和在先决条件恢复后重建声明配置是有用的。它不是外部状态的全面回滚。任务可以在其他幂等资源操作中轮换或重新创建凭证。
+
+使用相同支持参数的重复运行进行调解。不要将连接器 `Ready=True` 等同于未过期的可用工具令牌;在轮换之前和之后执行授权工具请求或工作负载操作。
+
+| 更改 | 所需操作 |
+| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
+| 支持的声明字段更改 | 审查特定任务的重新创建和轮换效果,然后调解项目。 |
+| 添加新环境 | 通过项目合并请求添加其 GitOps 目录和验证路径,并更改声明。 |
+| 模板更改 | 分别建议更新现有项目存储库。播种仅复制到空存储库。 |
+| 凭证到期需要轮换 | 在到期减去安全边际的时间表上运行相关任务;在失败时发出警报并重试。 |
+| 凭证没有到期 | 按政策要求的间隔进行轮换;明确选择任务的刷新行为。 |
+
+样本支持的 GitLab 子组是 `apps` 和 `gitops`。更改该约定需要审核的管道更改,而不仅仅是声明编辑。工具侧身份更改可以重新创建帐户或凭证;在更改名称或项目集之前,请检查产品任务的合同。
+
+例如,添加 `staging` 需要审核的声明更改和项目 GitOps 更改,以提供 `envs/staging` 及其验证路径。注册输出可以指向真实目录。仅更新声明可能会创建无法渲染的应用程序。类似地,更改种子模板是对现有项目的升级提案,而不是覆盖其存储库的理由。
+
+注册是从经过审核的模板重新生成的。没有注册差异的重新运行不应创建另一个合并请求。检查生成的 Git 更改或没有更改;仅通用更新步骤结果并不能证明需要注册或已合并。
+
+### 序列化租户更改并恢复保留锁
+
+不要重叠同一租户的运行。这三个示例入口点——计划调解、合并调度和手动运行模板——使用相同的入职管道。它的第一个任务在任何租户更改之前原子地创建每个项目的 ConfigMap 锁;竞争运行失败。成功运行在最后一个任务中释放自己的锁。失败、取消或中断清理可能会将锁保留在原地。检查其记录的 PipelineRun 和任何独立启动的子运行,确认所有工作已停止,然后在重试之前移除锁。绝不要仅仅因为运行时间超过预期就清除锁。
+
+锁释放与拥有运行的 UID 相关联,因此竞争运行无法清理另一个运行的锁。没有基于超时的接管:慢速外部 API 或独立注册子运行在父运行看起来停滞后仍然可以工作。记录所有者,停止并检查所有相关运行,然后再移除保留的锁。重试使用相同的管道,必须再次获取该锁。
+
+### 在凭证到期之前规划轮换
+
+在活动管道窗口之外安排轮换,并在当前凭证到期之前监控失败的运行。CSI 工作负载令牌的发放与轮换工具的长期凭证是分开的。咨询任务指南以获取到期恢复;定义本地恢复程序,而不是依赖未观察到的自然到期路径。
+
+如果启用连接器审批,请为每个受影响的工作负载准备授权,启用 `enable-connectors-approval`,立即创建所需的 AccessPolicies,然后启用 `enable-connector-proxy-permissions`。样本的可选管理员 AccessPolicy 不包括在默认 Kustomization 中,仅在启用该功能后应用。使用 RBAC 进行文档化的跨命名空间授权,并保持审批门控的生产连接器不直接授予代理权限。有关完整的推出边界,请参见 [交付文章](./From_Commit_to_Production_on_ACP.md#gate-the-production-connector-after-approval)。
+
+## 理解六个项目边界
+
+入职创建可以建立隔离的资源。验证有效权限以及资源:单独的帐户仍然可以具有广泛的角色,项目标签并不限制每个写入者。
+
+| 边界 | 结果和剩余条件 |
+| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| 命名空间和 Pod 安全 | 工作负载、构建和交付具有不同的命名空间和安全级别。样本所有者绑定仅在项目命名空间中授予 `admin`。 |
+| 部署授权 | 有效的 AppProject 目标限制位置;平台入境边界限制由实际 Argo CD 身份写入的敏感类型。直接 Kubernetes 写入者仍然需要 RBAC 限制。 |
+| 管道路由 | 存储库和触发器将事件路由到预期项目。定义源和直接运行策略仅在安装和强制执行的地方限制执行。 |
+| 外部工具租赁 | GitLab 组、私有 Harbor 项目、Nexus 存储库/用户和 SonarQube 权限按项目范围。验证实例范围的匿名和可见性设置作为先决条件。 |
+| 凭证访问 | 项目用户无法在管理员或签名命名空间中创建工作负载。代理授权、原始 Secret 访问、PaC 凭证和 Chains 凭证分别进行审核。 |
+| 执行历史 | 实时清理和命名空间覆盖与保留的外部结果记录共存。审批响应具有单独的保留路径。 |
+
+该示例中的生产发布凭证可以读取暂存项目并写入生产,因为复制任务对两个端点使用目标代理配置。名为 source-readonly 的挂载提供源 CA;它不建立单独的身份验证路径。Chains 使用其平台拥有的中央注册凭证进行提升签名;不要给 `shop-release` 身份匹配的生产注册凭证,否则 Chains 将优先选择该凭证,发布身份将获得直接写入路径。交付文章解释了这种特定于复制的行为及其审批边界。
+
+当启用提升入境时,使用管道的 `imageMappings` 输入进行每个源到发布的映射。入境规则识别该映射形式;单独提供的存储库或标签参数不是替代品。验证每个摘要的构建来源,然后再批准提升。
+
+跨项目拉取访问需要单独审核的授权。声明的保留 `imagePullFrom` 字段在样本中仅发出警告;它不会创建 Harbor 权限或分发新的拉取凭证。保持项目私有,并在将省略的授权视为隔离之前演示拒绝。
+
+### 检查六个角色与实际授权的对比
+
+以下矩阵总结了六个角色以及此参考提供或要求的授权。Kubernetes 授权是累加的:缺失的样本绑定不会撤销从 ACP 或其他角色继承的权限。Git 权限和生产保护必须在 GitLab 中单独配置。
+
+| 角色 | 平台存储库 | 项目声明 | 项目命名空间 | 交付命名空间 | GitOps `envs/prod` | 生产 | 连接器 |
+| ------------------------------------- | --------------------- | --------------------- | ----------------------------------- | -------------------------------------------------- | ----------------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------- |
+| 平台管理员 | 写入,先决条件 | 写入,先决条件 | 管理员,先决条件 | 应用定义并启动运行 | 单独配置保护 | 管理员,先决条件 | 管理员连接器 |
+| 应用程序开发人员 / 项目所有者 | 未提供 Git 授权 | 未提供 Git 授权 | 在 `shop` 中获得 `admin` 的所有者组 | 无样本绑定 | 未提供 Git 授权 | 未提供工作负载绑定 | 可以通过 Pods 读取项目 Secrets 并使用凭证 `shop` |
+| 发布审批者 | 未提供授权 | 未提供授权 | 未提供绑定 | ApprovalTask 响应;可选控制台读取角色 | 未提供 Git 审查角色 | 未提供工作负载绑定 | 未提供挂载授权 |
+| CI ServiceAccount | 未提供访问 | 未提供访问 | 在 `shop-build` 中运行 | 未提供绑定 | 未提供写入者 | 未提供工作负载绑定 | 项目 Harbor、SonarQube、Nexus 的挂载/代理授权 |
+| 交付 ServiceAccount | 未提供访问 | 未提供访问 | 未提供绑定 | 执行 CD;未提供运行创建授权 | 通过写入连接器的维护者组令牌 | 更改 Git 引用,由 Argo CD 调解 | GitOps 写入者挂载/代理授权 |
+| 提升 ServiceAccount | 未提供访问 | 未提供访问 | 未提供绑定 | 执行提升;未提供运行创建授权 | 未提供写入者 | 通过连接器写入生产注册表 | 挂载两个注册连接器;仅对源的直接代理授权 |
+
+发布审批者并不自动成为 Git 代码所有者。如果需要两个审批,请单独配置 Git 审查角色。提供的维护者写入者可以更改 GitLab 保护设置;生产部署需要单独保护的分支或存储库以及更窄的写入者身份。在将交付命名空间的运行创建委托给项目所有者之前,验证实际用户和 ServiceAccounts 的有效权限。
+
+名称范围连接器 `get` 授权记录此工作流所需的挂载;它们不会删除 ACP 在项目内的更广泛默认连接器读取。特定于身份的代理限制需要 [交付文章](./From_Commit_to_Production_on_ACP.md#gate-the-production-connector-after-approval) 中描述的代理权限功能和授权。在审查此矩阵时,保持读取授权、代理授权和对原始 Secrets 的访问之间的区别。`defaultPermission` 策略仅选择在连接器上具有命名空间范围 `get` 的身份;名称范围的 `get` 不符合资格,其他身份在策略仍然可以报告 `Ready` 的同时被静默跳过。
+
+保持 CI、GitOps 交付和工件提升身份分开。具有执行凭证的运行时 ServiceAccount 并不意味着它可以创建自己的 PipelineRuns。同样,作为应用程序存储库维护者并不在构建或交付命名空间中建立 Kubernetes 授权。在将运行模板委托给项目所有者之前,检查两侧。
+
+可选的 ACP 控制台审批者角色提供了查找审批工作所需的读取访问,而不授予运行创建或 Secret 读取权限。它不会分配 Git 代码所有者角色,也不能证明审批者不能通过其他继承权限启动发布。审查实际组成员资格和有效权限,并保持发布发起者和审批者分开。
+
+
+
+## 接受项目边界
+
+### 在移交之前检查每个入职结果
+
+| 边界 | 必须证明的内容 |
+| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| 命名空间和 Pod 安全 | 工作负载命名空间具有预期的标签;构建和交付使用它们各自的命名空间和身份。 |
+| 部署范围 | 有效的 AppProject 目标和平台入境仅允许预期的项目部署路径。使用实际的 Argo CD 身份测试禁止的 RBAC 和配额写入。 |
+| 工具访问 | GitLab、Harbor、Nexus 和 SonarQube 授权与租户匹配。在进行负面跨项目测试之前使用正面控制。 |
+| 凭证访问 | 项目用户无法在管理员或签名命名空间中创建 Pods 或运行。分别清点图像拉取 Secrets、PaC 克隆凭证和中央 Chains 凭证。 |
+| 事件路由 | 新的存储库事件或合并请求重试在预期命名空间中产生预期的运行。 |
+| 轮换 | 成功的非重叠运行更新预期的凭证,并且授权操作在之后有效。 |
+
+从样本中在隔离的接受项目中运行 `acceptance/02-platform-and-onboarding.sh`。其伴随的交付脚本在第一次提升的生产部署后验证图像路径。接受脚本不检查入职运行:阅读调度程序的 `onboarding-runs` 结果,确认它为每个应入职的项目命名运行,并确认每个子运行的状态为 `Succeeded=True`。检查四个连接器、播种的存储库、注册合并请求和应用程序。初始占位符摘要不可部署;工作负载健康状态在第一次真实部署后跟随。平台 `projects` 应用程序可以在此设计中保持 `OutOfSync` 状态,以便于平台管理的字段;检查有效的目标和策略,而不是仅将该状态视为失败。当启用 `no-bare-taskrun.yaml` 时,创建一个一次性直接 TaskRun 作为项目身份,并确认 `Audit` 允许它通过 PolicyReport,而 `Enforce` 拒绝它;删除探测并保留报告作为证据。
+
+对于跨项目图像拒绝,首先验证确切的图像存在并可以在其自己的项目中拉取。然后测试未经授权的项目,区分 `unauthorized` 与 `not found` 和 Pod 安全拒绝,并使用存在于另一方向的图像重复测试。检查后删除临时探测资源。
+
+仅在接受项目中的一次性资源上测试自愈。入职呈现一个专用的 `-self-healing-probe` RoleBinding,没有主体,因此删除它不会移除任何人的访问权限。在运行检查之前合并并同步其注册;现有项目需要注册更新以获取它。该脚本要求其接受探测标签,并拒绝带有主体的绑定。它保存 UID 和恢复清单,删除探测,并要求 GitOps 使用不同的 UID 重新创建它;回退恢复被报告为失败。这与证明操作管理组件层的持续自动调解是分开的。
+
+### 知道哪些输出应该存在
+
+在审查和合并注册后,预期的输出是:
+
+| 位置 | 预期输出 |
+| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
+| 平台 Git | 每个项目一份声明、其注册的 Kustomize 条目和经过审核的项目注册文件。 |
+| Argo CD | 根和层应用程序、入职应用程序,以及每个项目环境的一个应用程序。 |
+| GitLab | 项目组、`apps` 和 `gitops` 子组、两个组访问令牌,以及播种的 `gitops/config` 存储库。 |
+| Harbor | 私有源和生产项目、一个项目机器人和两个发布路径机器人,以及所需的拉取配置。 |
+| Nexus | 声明的存储库及其范围用户。 |
+| SonarQube | 一个用户、令牌和项目权限模板;第一次扫描创建应用程序项目。 |
+| 项目 Kubernetes 资源 | 带标签的命名空间、交付身份、四个项目连接器、PaC 注册和经过审核的所有者/挂载绑定。 |
+| 管理 Kubernetes 资源 | 管理员和项目发布连接器、命名入职授权和调解计划。 |
+
+不要求每个应用程序立即报告相同的状态。
+占位符工作负载摘要不是可运行的图像;环境健康在第一次真实部署后跟随。`projects` AppProject 补丁可以保持 OutOfSync,因为 ACP 也维护字段。组件层的持续自愈在所有权验证之前被禁用。读取有效对象、修订、策略决策和工作负载状态,以对应每个接受声明。
+
+项目准备意味着其子入职运行成功,注册经过审核和同步,工具访问在预期租户内有效,新存储库事件到达正确的定义,并且禁止访问因预期原因被拒绝。交付准备还需要交付文章中描述的第一次真实构建和发布。成功的调度程序或四个准备好的连接器单独并不满足这些条件。
+
+
+
+## 保留审计记录并规划恢复
+
+### 选择清理和归档作为一个操作决策
+
+选择一种清理机制,并在启用之前审查其范围。根据全局和命名空间配置指南使用基于事件的 Pruner;在迁移时禁用较旧的定期机制。在目标环境中验证每种选择的保留模式,以便在其可以删除共享运行历史记录之前。
+
+全局值在第一次同步后适用于整个集群,包括其他租户的命名空间,除非应用命名空间覆盖,并且成功和失败的运行按命名空间分别计算。在共享集群上,在启用清理之前计算每个命名空间的完成 PipelineRuns 和独立 TaskRuns,选择高于最高计数的限制或与租户达成较低限制,并首先通知所有者。
+
+使用外部 PostgreSQL 和文档记录的日志存储来存储结果。定义观察范围、身份验证和一个保留策略以供参考配置。通过结果 API 验证读取授权,而不是从 Kubernetes 资源可见性推断。清理之前单独保留审批响应,以免删除 ApprovalTask 对象。
+
+在启用结果观察者之前确定范围:默认观察可能会影响跨命名空间的完成运行,并添加 `results.tekton.dev/*` 最终处理程序。禁用归档不会删除已经存在的最终处理程序。在删除之前遵循产品恢复程序,并在集群对象被修剪后将外部结果存储视为审计源。请参见 [S3 存储](https://docs.alauda.io/alauda-devops-pipelines/4.15/results/configure/s3_storage_configuration.html) 和 [结果保留](https://docs.alauda.io/alauda-devops-pipelines/4.15/results/configure/retention_policy_configuration.html)。
+
+### 在重放配置之前恢复先决条件
+
+Git 不会替换凭证和外部数据的备份。在平台重建之前,平台团队必须准备和排练恢复这些依赖项:
+
+1. 兼容的平台组件、Kyverno 和密封的 secrets CRD 和控制器。
+2. 密封的 secrets 解密密钥,或新控制器的重新密封凭证。
+3. Chains 签名密钥和中央注册凭证;与图像入境协调任何验证密钥更改。
+4. 管理命名空间和已安装的自动创建任务。
+5. Argo CD 存储库访问和项目存储库凭证模板,以及 PaC 访问和 webhook 配置。
+
+对于签名密钥轮换,首先在 `require-signed-images` 中配置一个 attestor,`count: 1`,并为旧的和新的公钥分别设置 `entries`。确认旧签名的图像仍然被接受,然后通过其支持的管理工作流替换签名者并验证新签名。在每个旧签名的图像(包括回滚版本)被退役之前,保留旧条目;在单独的审核更改中删除它。在替换之前检查签名 Secret 的不可变性、所有者和安装方法。
+
+在准备好这些依赖项后,同步平台层,运行入职以声明的项目,审查注册更改,并完成接受检查。这是依赖项大纲;完整的空集群或第二集群恢复运行手册必须在目标环境中进行演练。
+
+在重建过程中,注册对象可能在所有项目命名空间存在之前就存在。允许声明在命名空间依赖绑定之前同步,以便入职可以读取它们;不要将声明 ConfigMaps 放在被这些绑定阻塞的后续同步波中。检查失败的对象和重试,而不是将暂时不完整的层视为入职无法继续的证明。该依赖序列需要自己的恢复接受。
+
+### 深思熟虑地调整和操作平台
+
+替换工具地址、管理命名空间、项目/组命名约定、环境列表、Argo CD 集群名称、两个边界策略身份、签名公钥、加密凭证、本地图像、令牌生命周期和轮换间隔。验证每个目标集群边界在调整身份后。地址迁移还需要对已播种的存储库以及策略和提升输入进行更改;存储库参数只是该操作的一部分。
+
+在生产之前,完成样本的加固工作:将合并前验证与管理员凭证隔离,缩小用于项目注册的 AppProject,保护 GitOps 写入者的命名空间,安装提升核心规则,并限制生产图像源。限制直接集群写入,同时进行 Git 审查。模板升级、退役、容量规划、离线包分发和客户变更管理集成需要单独的操作程序。
+
+继续阅读 [从提交到生产](./From_Commit_to_Production_on_ACP.md) 以使用入职项目的构建、测试、提升和生产 GitOps 路径。