这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

为 Kubernetes 文档出一份力

Kubernetes 欢迎来自所有贡献者的改进,无论你是新人和有经验的贡献者!

本网站由 Kubernetes SIG Docs(文档特别兴趣小组)维护。

Kubernetes 文档项目的贡献者:

  • 改进现有内容
  • 创建新内容
  • 翻译文档
  • 管理并发布 Kubernetes 周期性发行版的文档

入门

任何人都可以提出文档方面的问题(issue),或贡献一个变更,用拉取请求(PR)的方式提交到 GitHub 上的 kubernetes/website 仓库。 当然你需要熟练使用 gitGitHub 才能在 Kubernetes 社区中有效工作。

如何参与文档编制:

  1. 签署 CNCF 的贡献者许可协议
  2. 熟悉文档仓库和网站的静态站点生成器
  3. 确保理解发起 PR审查变更的基本流程。
flowchart TB subgraph third[发起 PR] direction TB U[ ] -.- Q[改进现有内容] --- N[创建新内容] N --- O[翻译文档] O --- P[管理并发布 K8s
周期性发行版的文档] end subgraph second[评审] direction TB T[ ] -.- D[仔细查看
kubernetes/website
仓库] --- E[下载安装 Hugo
静态站点
生成器] E --- F[了解基本的
GitHub 命令] F --- G[评审待处理的 PR
并遵从变更审查
流程] end subgraph first[注册] direction TB S[ ] -.- B[签署 CNCF
贡献者
许可协议] --- C[加入 sig-docs
Slack 频道] C --- V[加入 kubernetes-sig-docs
邮件列表] V --- M[参加每周的
sig-docs 电话会议
或 slack 会议] end A([fa:fa-user 新的
贡献者]) --> first A --> second A --> third A --> H[提出问题!!!] classDef grey fill:#dddddd,stroke:#ffffff,stroke-width:px,color:#000000, font-size:15px; classDef white fill:#ffffff,stroke:#000,stroke-width:px,color:#000,font-weight:bold classDef spacewhite fill:#ffffff,stroke:#fff,stroke-width:0px,color:#000 class A,B,C,D,E,F,G,H,M,Q,N,O,P,V grey class S,T,U spacewhite class first,second,third white

图 1. 新手入门指示。

图 1 概述了新贡献者的路线图。 你可以遵从“注册”和“评审”所述的某些或全部步骤。 至此,你完成了发起 PR 的准备工作, 可以通过“发起 PR” 列出的事项实现你的贡献目标。 再次重申,欢迎随时提出问题!

有些任务要求 Kubernetes 组织内更高的信任级别和访问权限。 阅读参与 SIG Docs 工作,获取角色和权限的更多细节。

第一次贡献

你可以提前查阅几个步骤,来准备你的第一次贡献。 图 2 概述了后续的步骤和细节。

flowchart LR subgraph second[第一次贡献] direction TB S[ ] -.- G[查阅其他 K8s
成员发起的 PR] --> A[检索 kubernetes/website
问题列表是否有
good first 一类的 PR] --> B[发起一个 PR!!] end subgraph first[建议的准备工作] direction TB T[ ] -.- D[阅读贡献概述] -->E[阅读 K8s 内容
和风格指南] E --> F[了解 Hugo 页面
内容类型
和短代码] end first ----> second classDef grey fill:#dddddd,stroke:#ffffff,stroke-width:px,color:#000000, font-size:15px; classDef white fill:#ffffff,stroke:#000,stroke-width:px,color:#000,font-weight:bold classDef spacewhite fill:#ffffff,stroke:#fff,stroke-width:0px,color:#000 class A,B,D,E,F,G grey class S,T spacewhite class first,second white

图 2. 第一次贡献的准备工作。

下一步

参与 SIG Docs 工作

SIG Docs 是负责发布、维护 Kubernetes 文档的贡献者团体。 参与 SIG Docs 是 Kubernetes 贡献者(开发者和其他人员)对 Kubernetes 项目产生重大影响力的好方式。

SIG Docs 的几种沟通方式:

其他贡献方式

1 - 提出内容改进建议

如果你发现 Kubernetes 文档中存在问题或者你有一个关于新内容的想法, 可以考虑提出一个问题(issue)。你只需要具有 GitHub 账号和 Web 浏览器就可以完成这件事。

在大多数情况下,Kubernetes 文档的新工作都是开始于 GitHub 上的某个问题。 Kubernetes 贡献者会审阅这些问题并根据需要对其分类、打标签。 接下来,你或者别的 Kubernetes 社区成员就可以发起一个带有变更的拉取请求, 以解决这一问题。

创建问题

如果你希望就改进已有内容提出建议或者在文档中发现了错误,请创建一个问题(issue)。

  1. 点击右侧边栏的 提交文档问题 按钮。浏览器会重定向到一个 GitHub 问题页面, 其中包含了一些预先填充的内容。
  2. 请描述遇到的问题或关于改进的建议。尽可能提供细节信息。
  3. 点击 Submit new issue

提交之后,偶尔查看一下你所提交的问题,或者开启 GitHub 通知。 评审人(reviewers)和其他社区成员可能在针对所提问题采取行动之前,问一些问题。

关于新内容的建议

如果你对新内容有想法,但是你不确定这些内容应该放在哪里,你仍可以提出问题。

  • 在预期的节区中选择一个现有页面,点击 提交文档问题
  • 前往 GitHub Issues 页面, 直接记录问题。

如何更好地记录问题

在记录问题时,请注意以下事项:

  • 提供问题的清晰描述,描述具体缺失的内容、过期的内容、错误的内容或者需要改进的文字。
  • 解释该问题对用户的特定影响。
  • 将给定问题的范围限定在一个工作单位范围内。如果问题牵涉的领域较大,可以将其分解为多个小一点的问题。 例如:"Fix the security docs" 是一个过于宽泛的问题,而 "Add details to the 'Restricting network access' topic" 就是一个足够具体的、可操作的问题。
  • 搜索现有问题的列表,查看是否已经有相关的或者类似的问题已被记录。
  • 如果新问题与某其他问题或 PR 有关联,可以使用其完整 URL 或带 # 字符的 PR 编号来引用之。 例如:Introduced by #987654
  • 遵从行为准则。尊重同行贡献者。 例如,"The docs are terrible" 就是无用且无礼的反馈。

2 - 贡献新内容

本节包含你在贡献新内容之前需要知晓的信息。

flowchart LR subgraph second[开始之前] direction TB S[ ] -.- A[签署 CNCF CLA] --> B[选择 Git 分支] B --> C[每个 PR 一种语言] C --> F[检查贡献者工具] end subgraph first[基本知识] direction TB T[ ] -.- D[用 markdown 编写文档
并用 Hugo 构建网站] --- E[GitHub 源代码] E --- G['/content/../docs' 文件夹包含
多语言文档] G --- H[评审 Hugo 页面内容
类型和短代码] end first ----> second classDef grey fill:#dddddd,stroke:#ffffff,stroke-width:px,color:#000000, font-size:15px; classDef white fill:#ffffff,stroke:#000,stroke-width:px,color:#000,font-weight:bold classDef spacewhite fill:#ffffff,stroke:#fff,stroke-width:0px,color:#000 class A,B,C,D,E,F,G,H grey class S,T spacewhite class first,second white

插图 - 贡献新内容准备工作

上图描述了你在提交新内容之前需要知晓的信息。 详细信息见下文。

基本知识

  • 使用 Markdown 编写 Kubernetes 文档并使用 Hugo 构建网站。
  • Kubernetes 文档使用 CommonMark 作为 Markdown 的风格。
  • 源代码位于 GitHub 仓库中。 你可以在 /content/zh-cn/docs/ 目录下找到 Kubernetes 文档。 某些参考文档是使用位于 update-imported-docs/ 目录下的脚本自动生成的。
  • 页面内容类型使用 Hugo 描述文档内容的呈现。
  • 你可以使用 Docsy 短代码定制的 Hugo 短代码贡献 Kubernetes 文档。
  • 除了标准的 Hugo 短代码外, 我们还在文档中使用一些定制的 Hugo 短代码来控制内容的呈现。
  • 文档的源代码有多种语言形式,位于 /content/ 目录下。 每种语言都有一个自己的目录,用两个字母表示,这两个字母是基于 ISO 639-1 标准来确定的。 例如,英语文档的源代码位于 /content/en/docs/ 目录下。
  • 关于为多语言文档做贡献以及如何开始新翻译的详细信息, 可参考本地化文档

开始之前

签署 CNCF CLA

所有 Kubernetes 贡献者必须阅读贡献者指南签署贡献者授权同意书 (Contributor License Agreement, CLA)

若贡献者尚未签署 CLA,其发起的 PR 将无法通过自动化测试。 你所提供的姓名和邮件地址必须与 git config 中配置的完全相同, 而且你的 git 用户名和邮件地址必须与用来签署 CNCF CLA 的信息一致。

选择要使用的 Git 分支

在发起 PR 时,你需要预先知道基于哪个分支来开展工作。

场景分支
针对当前发行版本的,对现有英文内容的修改或新的英文内容main
针对功能特性变更的内容分支对应于功能特性变更的主要和次要版本,分支名称采用 dev-<version> 的模式。例如,如果某功能特性在 v1.31 版本发生变化,则对应的文档变化要添加到 dev-1.31 分支。
其他语言的内容(本地化)基于本地化团队的约定。参见本地化分支策略了解更多信息。

如果你仍不能确定要选择哪个分支,请在 Slack 的 #sig-docs 频道上提出问题。

每个 PR 牵涉的语言

请确保每个 PR 仅涉及一种语言。 如果你需要对多种语言下的同一代码示例进行相同的修改,也请为每种语言发起一个独立的 PR。

为贡献者提供的工具

kubernetes/website 仓库的文档贡献者工具目录中包含了一些工具, 有助于使你的贡献过程更为顺畅。

2.1 - 发起拉取请求(PR)

要贡献新的内容页面或者改进已有内容页面,请发起拉取请求(PR)。 请确保你满足了开始之前一节中所列举的所有要求。

如果你所提交的变更足够小,或者你对 git 工具不熟悉, 可以阅读使用 GitHub 提交变更以了解如何编辑页面。

如果所提交的变更较大, 请阅读基于本地克隆副本开展工作以学习如何在你本地计算机上进行修改。

使用 GitHub 提交变更

如果你在 git 工作流方面欠缺经验,这里有一种发起拉取请求的更为简单的方法。 图 1 勾勒了后续的步骤和细节。

flowchart LR A([fa:fa-user 新的
贡献者]) --- id1[(kubernetes/website
GitHub)] subgraph tasks[使用 GitHub 提交变更] direction TB 0[ ] -.- 1[1. 编辑此页] --> 2[2. 使用 GitHub markdown
编辑器进行修改] 2 --> 3[3. 填写 Propose file change] end subgraph tasks2[ ] direction TB 4[4. 选择 Propose file change] --> 5[5. 选择 Create pull request] --> 6[6. 填写 Open a pull request] 6 --> 7[7. 选择 Create pull request] end id1 --> tasks --> tasks2 classDef grey fill:#dddddd,stroke:#ffffff,stroke-width:px,color:#000000, font-size:15px; classDef white fill:#ffffff,stroke:#000,stroke-width:px,color:#000,font-weight:bold classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff; classDef spacewhite fill:#ffffff,stroke:#fff,stroke-width:0px,color:#000 class A,1,2,3,4,5,6,7 grey class 0 spacewhite class tasks,tasks2 white class id1 k8s

图 1. 使用 GitHub 发起一个 PR 的步骤。

  1. 在你发现问题的页面上,选择右侧导航面板中的编辑此页面选项。

  2. 在 GitHub 的 Markdown 编辑器中修改内容。

  3. 在编辑器的下方,填写 Propose file change 表单。 在第一个字段中,为你的提交消息取一个标题。 在第二个字段中,为你的提交写一些描述文字。

  1. 选择 Propose File Change

  2. 选择 Create pull request

  3. 出现 Open a pull request 界面。填写表单:

    • Subject 字段默认为提交的概要信息,你可以根据需要进行修改。
    • Body 字段包含更为详细的提交消息(如果你之前有填写过的话)和一些模板文字。 填写模板所要求的详细信息,之后删除多余的模板文字。
    • 确保 Allow edits from maintainers 复选框被勾选。
  1. 选择 Create pull request

在 GitHub 上处理反馈意见

在合并 PR 之前,Kubernetes 社区成员会评阅并批准它。 k8s-ci-robot 会基于页面中最近提及的属主来建议评阅人(reviewers)。 如果你希望特定某人来评阅,可以留下评论,提及该用户的 GitHub 用户名。

如果某个评阅人请你修改 PR:

  1. 前往 Files changed Tab 页面;
  2. 选择 PR 所修改的任何文件所对应的铅笔(edit)图标;
  3. 根据建议作出修改;
  4. 提交所作修改。

如果你希望等待评阅人的反馈,可以每 7 天左右联系一次。 你也可以在 #sig-docs Slack 频道发送消息。

当评阅过程结束,某个评阅人会合并你的 PR。 几分钟之后,你所做的变更就会上线了。

基于本地克隆副本开展工作

如果你有 git 的使用经验,或者你要提议的修改不仅仅几行,请使用本地克隆副本来开展工作。

首先要确保你在本地计算机上安装了 git。 你也可以使用 git 的带用户界面的应用。

图 2 显示了基于本地克隆副本开展工作的步骤。每个步骤的细节如下。

flowchart LR 1[派生 kubernetes/website
仓库] --> 2[创建本地克隆副本
并指定 upstream 仓库] subgraph changes[你的变更] direction TB S[ ] -.- 3[创建一个分支
例如: my_new_branch] --> 3a[使用文本编辑器
进行修改] --> 4["使用 Hugo 在本地
预览你的变更
(localhost:1313)
或构建容器镜像"] end subgraph changes2[提交 / 推送] direction TB T[ ] -.- 5[提交你的变更] --> 6[将提交推送到
origin/my_new_branch] end 2 --> changes --> changes2 classDef grey fill:#dddddd,stroke:#ffffff,stroke-width:px,color:#000000, font-size:15px; classDef white fill:#ffffff,stroke:#000,stroke-width:px,color:#000,font-weight:bold classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff; classDef spacewhite fill:#ffffff,stroke:#fff,stroke-width:0px,color:#000 class 1,2,3,3a,4,5,6 grey class S,T spacewhite class changes,changes2 white

图 2. 使用本地克隆副本进行修改。

派生 kubernetes/website 仓库

  1. 前往 kubernetes/website 仓库;
  2. 选择 Fork.

创建一个本地克隆副本并指定 upstream 仓库

  1. 打开终端窗口,克隆你所派生的副本,并更新 Docsy Hugo 主题

    git clone git@github.com/<github_username>/website
    cd website
    git submodule update --init --recursive --depth 1
    
  1. 前往新的 website 目录,将 kubernetes/website 仓库设置为 upstream 远端:

    cd website
    
    git remote add upstream https://github.com/kubernetes/website.git
    
  1. 确认你现在有两个仓库 originupstream

    git remote -v
    

    输出类似于:

    origin	git@github.com:<github_username>/website.git (fetch)
    origin	git@github.com:<github_username>/website.git (push)
    upstream	https://github.com/kubernetes/website.git (fetch)
    upstream	https://github.com/kubernetes/website.git (push)
    
  1. 从你的克隆副本取回 origin/main 分支,从 kubernetes/website 取回 upstream/main

    git fetch origin
    git fetch upstream
    

    这样可以确保你本地的仓库在开始工作前是最新的。

创建一个分支

  1. 决定你要基于哪个分支来开展工作:

    • 针对已有内容的改进,请使用 upstream/main
    • 针对已有功能特性的新文档内容,请使用 upstream/main
    • 对于本地化内容,请基于本地化的约定。 可参考本地化 Kubernetes 文档了解详细信息。
    • 对于在下一个 Kubernetes 版本中新功能特性的文档,使用独立的功能特性分支。 参考为发行版本撰写功能特性文档了解更多信息。
    • 对于很多 SIG Docs 共同参与的,需较长时间才完成的任务,例如内容的重构, 请使用为该任务创建的特性分支。

    如果你在选择分支上需要帮助,请在 #sig-docs Slack 频道提问。

  1. 基于第 1 步中选定的分支,创建新分支。 下面的例子假定基础分支是 upstream/main

    git checkout -b <my_new_branch> upstream/main
    
  1. 使用文本编辑器进行修改。

在任何时候,都可以使用 git status 命令查看你所改变了的文件列表。

提交你的变更

当你准备好发起拉取请求(PR)时,提交你所做的变更。

  1. 在你的本地仓库中,检查你要提交的文件:

    git status
    

    输出类似于:

    On branch <my_new_branch>
    Your branch is up to date with 'origin/<my_new_branch>'.
    
    Changes not staged for commit:
    (use "git add <file>..." to update what will be committed)
    (use "git checkout -- <file>..." to discard changes in working directory)
    
    modified:   content/en/docs/contribute/new-content/contributing-content.md
    
    no changes added to commit (use "git add" and/or "git commit -a")
    
  1. Changes not staged for commit 下列举的文件添加到提交中:

    git add <your_file_name>
    

    针对每个文件重复此操作。

  1. 添加完所有文件之后,创建一个提交(commit):

    git commit -m "Your commit message"
    
  1. 推送你本地分支及其中的新提交到你的远程派生副本库:

    git push origin <my_new_branch>
    

在本地预览你的变更

在推送变更或者发起 PR 之前在本地查看一下预览是个不错的主意。 通过预览你可以发现构建错误或者 Markdown 格式问题。

你可以构建网站的容器镜像或者在本地运行 Hugo。 构建容器镜像的方式比较慢,不过能够显示 Hugo 短代码(shortcodes), 因此对于调试是很有用的。

  1. 在本地构建容器镜像 如果你正在测试对 Hugo 工具本身的更改,则仅需要此步骤

    # 在终端窗口中执行(如果有需要)
    make container-image
    
  1. 在容器中启动 Hugo:

    # 在终端窗口中执行
    make container-serve
    
  1. 启动浏览器,浏览 https://localhost:1313。 Hugo 会监测文件的变更并根据需要重新构建网站。

  2. 要停止本地 Hugo 实例,可返回到终端并输入 Ctrl+C,或者关闭终端窗口。

另一种方式是,在你的本地计算机上安装并使用 hugo 命令:

  1. 安装 website/netlify.toml 文件中指定的 Hugo 版本。

  2. 如果你尚未更新你的网站仓库,则 website/themes/docsy 目录是空的。 如果本地缺少主题的副本,则该站点无法构建。 要更新网站主题,运行以下命令:

git submodule update --init --recursive --depth 1
  1. 启动一个终端窗口,进入 Kubernetes 网站仓库目录,启动 Hugo 服务器:

    cd <path_to_your_repo>/website
    hugo server --buildFuture
    
  1. 在浏览器的地址栏输入: https://localhost:1313。 Hugo 会监测文件的变更并根据需要重新构建网站。

  2. 要停止本地 Hugo 实例,返回到终端窗口并输入 Ctrl+C 或者关闭终端窗口。

从你的克隆副本向 kubernetes/website 发起拉取请求(PR)

图 3 显示了从你的克隆副本向 kubernetes/website 发起 PR 的步骤。 详细信息如下。

flowchart LR subgraph first[ ] direction TB 1[1. 前往 kubernetes/website 仓库] --> 2[2. 选择 New Pull Request] 2 --> 3[3. 选择 compare across forks] 3 --> 4[4. 从 head repository 下拉菜单
选择你的克隆副本] end subgraph second [ ] direction TB 5[5. 从 compare 下拉菜单
选择你的分支] --> 6[6. 选择 Create Pull Request] 6 --> 7[7. 为你的 PR
添加一个描述] 7 --> 8[8. 选择 Create pull request] end first --> second classDef grey fill:#dddddd,stroke:#ffffff,stroke-width:px,color:#000000, font-size:15px; classDef white fill:#ffffff,stroke:#000,stroke-width:px,color:#000,font-weight:bold class 1,2,3,4,5,6,7,8 grey class first,second white

图 3. 从你的克隆副本向 kubernetes/website 发起一个 PR 的步骤。

  1. 在 Web 浏览器中,前往 kubernetes/website 仓库;

  2. 点击 New Pull Request

  3. 选择 compare across forks

  4. head repository 下拉菜单中,选取你的派生仓库;

  5. compare 下拉菜单中,选择你的分支;

  6. 点击 Create Pull Request

  7. 为你的拉取请求添加一个描述:

    • Title (不超过 50 个字符):总结变更的目的;

    • Description:给出变更的详细信息;

      • 如果存在一个相关联的 GitHub Issue,可以在描述中包含 Fixes #12345Closes #12345。GitHub 的自动化设施能够在当前 PR 被合并时自动关闭所提及 的 Issue。如果有其他相关联的 PR,也可以添加对它们的链接。
      • 如果你特别希望获得某方面的建议,可以在描述中包含你希望评阅人思考的问题。
  8. 点击 Create pull request 按钮。

祝贺你!你的拉取请求现在出现在 Pull Requests 列表中了!

在发起 PR 之后,GitHub 会执行一些自动化的测试,并尝试使用 Netlify 部署一个预览版本。

  • 如果 Netlify 构建操作失败,可选择 Details 了解详细信息。
  • 如果 Netlify 构建操作成功,选择 Details 会打开 Kubernetes 的一个预览版本, 其中包含了你所作的变更。评阅人也使用这一功能来检查你的变更。

GitHub 也会自动为 PR 分派一些标签,以帮助评阅人。 如果有需要,你也可以向 PR 添加标签。 欲了解相关详细信息,可以参考 添加和删除 Issue 标签

在本地处理反馈

  1. 在本地完成修改之后,可以修补(amend)你之前的提交:

    git commit -a --amend
    
    • -a:提交所有修改
    • --amend:对前一次提交进行增补,而不是创建新的提交
  1. 如果有必要,更新你的提交消息;

  2. 使用 git push origin <my_new_branch> 来推送你的变更,重新触发 Netlify 测试。

来自评阅人的修改

有时评阅人会向你的 PR 中提交修改。在作出其他修改之前,请先取回这些提交。

  1. 从你的远程派生副本仓库取回提交,让你的工作分支基于所取回的分支:

    git fetch origin
    git rebase origin/<your-branch-name>
    
  1. 变更基线(rebase)操作完成之后,强制推送本地的新改动到你的派生仓库:

    git push --force-with-lease origin <your-branch-name>
    

合并冲突和重设基线

如果另一个贡献者在别的 PR 中提交了对同一文件的修改,这可能会造成合并冲突。 你必须在你的 PR 中解决所有合并冲突。

  1. 更新你的派生副本,重设本地分支的基线:

    git fetch origin
    git rebase origin/<your-branch-name>
    

    之后强制推送修改到你的派生副本仓库:

    git push --force-with-lease origin <your-branch-name>
    
  1. kubernetes/websiteupstream/main 分支取回更改,然后重设本地分支的基线:

    git fetch upstream
    git rebase upstream/main
    
  1. 检查重设基线操作之后的状态:

    git status
    

    你会看到一组存在冲突的文件。

  1. 打开每个存在冲突的文件,查找冲突标记:>>><<<===。 解决完冲突之后删除冲突标记。

  1. 添加文件到变更集合:

    git add <filename>
    
  1. 继续执行基线变更(rebase)操作:

    git rebase --continue
    
  1. 根据需要重复步骤 2 到 5。

    在应用完所有提交之后,git status 命令会显示 rebase 操作完成。

  1. 将分支强制推送到你的派生仓库:

    git push --force-with-lease origin <your-branch-name>
    

    PR 不再显示存在冲突。

压缩(Squashing)提交

如果你的 PR 包含多个提交(commits),你必须将其压缩成一个提交才能被合并。 你可以在 PR 的 Commits Tab 页面查看提交个数,也可以在本地通过 git log 命令查看提交个数。

  1. 启动一个交互式的 rebase 操作:

    git rebase -i HEAD~<number_of_commits_in_branch>
    

    压缩提交的过程也是一种重设基线的过程。 这里的 -i 开关告诉 git 你希望交互式地执行重设基线操作。 HEAD~<number_of_commits_in_branch 表明在 rebase 操作中查看多少个提交。

    输出类似于;

    pick d875112ca Original commit
    pick 4fa167b80 Address feedback 1
    pick 7d54e15ee Address feedback 2
    
    # Rebase 3d18sf680..7d54e15ee onto 3d183f680 (3 commands)
    
    ...
    
    # These lines can be re-ordered; they are executed from top to bottom.
    

    输出的第一部分列举了重设基线操作中的提交。 第二部分给出每个提交的选项。 改变单词 pick 就可以改变重设基线操作之后提交的状态。

    就重设基线操作本身,我们关注 squashpick 选项。

  1. 开始编辑文件。

    修改原来的文本:

    pick d875112ca Original commit
    pick 4fa167b80 Address feedback 1
    pick 7d54e15ee Address feedback 2
    

    使之成为:

    pick d875112ca Original commit
    squash 4fa167b80 Address feedback 1
    squash 7d54e15ee Address feedback 2
    

    以上编辑操作会压缩提交 4fa167b80 Address feedback 17d54e15ee Address feedback 2d875112ca Original commit 中,只留下 d875112ca Original commit 成为时间线中的一部分。

  1. 保存文件并退出编辑器。

  2. 推送压缩后的提交:

    git push --force-with-lease origin <branch_name>
    

贡献到其他仓库

Kubernetes 项目包含大约 50 多个仓库。 这些仓库中很多都有文档:提供给最终用户的帮助文本、错误信息、API 参考或者代码注释等。

如果你发现有些文本需要改进,可以使用 GitHub 来搜索 Kubernetes 组织下的所有仓库。 这样有助于发现要在哪里提交 Issue 或 PR。

每个仓库有其自己的流程和过程。在登记 Issue 或者发起 PR 之前, 记得阅读仓库可能存在的 README.mdCONTRIBUTING.mdcode-of-conduct.md 文件。

大多数仓库都有自己的 Issue 和 PR 模板。 通过查看一些待解决的 Issue 和 PR, 你可以大致了解协作的流程。 在登记 Issue 或提出 PR 时,务必尽量填充所给的模板,多提供详细信息。

接下来

  • 阅读评阅节,学习评阅过程。

2.2 - 为发行版本撰写功能特性文档

Kubernetes 的每个主要版本发布都会包含一些需要文档说明的新功能。 新的发行版本也会对已有功能特性和文档(例如将某功能特性从 Alpha 升级为 Beta)进行更新。

通常,负责某功能特性的 SIG 要为功能特性的文档草拟文档,并针对 kubernetes/website 仓库的合适的开发分支发起拉取请求。 SIG Docs 团队会提供文字方面的反馈意见,或者直接编辑文档草稿。 本节讨论两个小组在分支方面和发行期间所遵从的流程方面的约定。

对于文档贡献者

一般而言,文档贡献者不会为某个发行版本从头撰写文档。 相反,他们会与开发该功能特性的 SIG 团队一起,对文档草稿进行润色, 使之符合发布条件。

在你选定了某个功能特性,为其撰写文档(主笔或辅助),请在 #sig-docs Slack 频道、SIG Docs 的每周例会上, 或者在功能特性对应的 PR 上提出咨询。如果继续工作是没有问题的, 你可以使用提交到他人的 PR 所述的某个技巧参与 PR 的编辑工作。

了解即将发布的功能特性

要了解即将发布的功能特性,可以参加每周的 SIG Release 例会 (参考社区页面,了解即将召开的会议), 监视 kubernetes/sig-release 中与发行相关的文档。 每个发行版本在 /sig-release/tree/master/releases/ 下都有一个对应的子目录。 该子目录包含了发行版本的时间计划、发行公告的草稿以及列举发行团队名单的文档。

发行时间计划文件中包含到所有其他文档、会议、会议记录及发行相关的里程碑的链接。 其中也包含关于发行版本的目标列表、时间线,以及当前发行版本中就绪的特殊流程的信息。 文档末尾附近定义了若干与该发行版本有关的术语。

此文档也包含到 功能特性跟踪清单 的链接。 这一清单是了解哪些功能特性计划进入某发行版本的正式途径。

发行团队文档列举了哪些人扮演着各个发行版本的不同角色。 如果不清楚要联系谁来讨论特定的功能特性或者回答你的问题, 你可以参加发行团队的会议,提出你的问题,或者联系发行团队的牵头人, 这样他们就可以帮你找到正确的联系人。

发行说明草稿是用来发现与特定发行版本相关的功能特性、变更、废弃以及其他信息的好来源。 由于在发行周期的后段该文档的内容才会最终定稿,参考其中的信息时请谨慎。

特性跟踪清单

针对给定 Kubernetes 发行版本 特性跟踪清单中列举的是计划包含于该版本中的每个功能特性。 每一行中都包含特性的名称、特性对应的主要 GitHub Issue,其稳定性级别(ALpha、 Beta 或 Stable)、负责实现该特性的 SIG 和个人、是否该特性需要文档、 该特性的发行说明草稿以及该特性是否已经被合并等等。阅读此清单时请注意:

  • Beta 和 Stable 功能特性通常比 Alpha 特性更为需要文档支持。
  • 如果某功能特性尚未被合并,就很难测试或者为其撰写文档。 对于对应的 PR 而言,也很难讲特性是否完全实现。
  • 确定某个功能特性是否需要文档的过程是一个手动的过程。 即使某个功能特性没有标记需要文档,你仍可能需要为其提供文档。

针对开发人员或其他 SIG 成员

本节中的信息是针对为发行版本中新功能特性撰写文档的来自其他 Kubernetes SIG 的成员。

如果你是某个 SIG 的成员,负责为 Kubernetes 开发某一项新的功能特性,你需要与 SIG Docs 一起工作,确保这一新功能在发行之前已经为之撰写文档。 请参考特性跟踪清单或者 Kubernetes Slack 上的 #sig-release 频道,检查时间安排的细节以及截止日期。

提交占位 PR

  1. kubernetes/website 仓库上针对 dev-1.31 分支提交一个draft PR,其中包含较少的、待以后慢慢补齐的提交内容。 要创建一个草案(draft)状态的 PR,可以在 Create Pull Request 下拉菜单中选择 Create Draft Pull Request,然后点击 Draft Pull Request
  2. 编辑拉取请求描述以包括指向 kubernetes/kubernetes PR 和 kubernetes/enhancements 问题的链接。
  3. 在对应的 kubernetes/enhancements issue 上添加评论,附上新 PR 的链接以便管理此发行版本的人员能够得到通知, 了解特性的文档正在被撰写,在新的发行版本中要跟踪其进展。

如果对应的功能特性不需要任何类型的文档变更,请通过在 #sig-release Slack 频道声明这一点以确保 sig-release 团队了解。 如果功能特性确实需要文档,而没有对应的 PR 提交,该功能特性可能会被从里程碑中移除。

PR 准备好评阅

时机成熟时,你可以在你的占位 PR 中完成功能特性文档,并将 PR 的状态从草案状态更改为 Ready for Review。要将一个拉取请求标记为已准备好评阅, 转到页面的 merge 框,点击 Ready for review

尽可能为功能特性提供详尽文档以及使用说明。如果你需要文档组织方面的帮助, 请在 #sig-docs Slack 频道中提问。

当你已经完成内容撰写,指派给你的功能特性的文档贡献者会去评阅文档。 为了确保技术准确性,内容可能还需要相应 SIG 的技术审核。 尽量利用他们所给出的建议,改进文档内容以达到发布就绪状态。

如果你在处理的功能特性处于 Alpha 或 Beta 阶段并由某特性门控控制, 请确保在你的 PR 中,该特性门控被添加到 Alpha/Beta 特性门控表格中。 对于新的特性门控选项,需要为该特性门控提供一段描述。 如果所处理的功能特性已经进入正式发布(GA)状态或者被废弃, 请确保将其从 Alpha 和 Beta 状态的特性门控表格迁移到 已毕业和已废弃的特性门控, 并确保迁移后保留其 Alpha、Beta 版本变迁历史。

如果你的功能特性需要文档,而你未提交初版文档,该特性可能会被从里程碑中删除。

所有 PR 均经过评审且合并就绪

如果你的 PR 在发行截止日期之前尚未合并到 dev-1.31 分支, 请与负责管理该发行版本的文档团队成员一起合作,在截止期限之前将其合并。 如果功能特性需要文档,而文档并未就绪,该特性可能会被从里程碑中去除。

2.3 - 提交博客和案例分析

任何人都可以撰写博客并提交评阅。 案例分析则在被批准之前需要更多的评阅。

Kubernetes 博客

Kubernetes 博客用于项目发布新功能特性、 社区报告以及其他一些可能对整个社区很重要的新闻。 其读者包括最终用户和开发人员。 大多数博客的内容是关于核心项目中正在发生的事情, 不过我们也鼓励你提交一些有关生态系统中其他时事的博客。

任何人都可以撰写博客并提交评阅。

提交博文

博文不应该是商业性质的,应该包含广泛适用于 Kubernetes 社区的原创内容。 合适的博客内容包括:

  • Kubernetes 新能力
  • Kubernetes 项目更新信息
  • 来自特别兴趣小组(Special Interest Groups, SIG)的更新信息
  • 教程和演练
  • 有关 Kubernetes 的纲领性理念
  • Kubernetes 合作伙伴 OSS 集成信息
  • 仅限原创内容

不合适的博客内容包括:

  • 供应商产品推介
  • 不含集成信息和客户故事的合作伙伴更新信息
  • 已发表的博文(可刊登博文译稿)

要提交博文,你可以遵从以下步骤:

  1. 如果你还未签署 CLA,请先签署 CLA
  2. 查阅网站仓库中现有博文的 Markdown 格式。
  3. 在你所选的文本编辑器中撰写你的博文。
  4. 在第 2 步的同一链接上,点击 Create new file 按钮。 将你的内容粘贴到编辑器中。为文件命名,使其与提议的博文标题一致, 但不要在文件名中写日期。 博客评阅者将与你一起确定最终的文件名和发表博客的日期。
  5. 保存文件时,GitHub 将引导你完成 PR 流程。
  6. 博客评阅者将评阅你提交的内容,并与你一起处理反馈和最终细节。 当博文被批准后,博客将排期发表。

指导原则和期望

  • 博客内容不可以是销售用语。
    • 文章内容必须是对整个 Kubernetes 社区中很多人都有参考意义。 例如,所提交的文章应该关注上游的 Kubernetes 项目本身,而不是某个厂商特定的配置。 请参阅文档风格指南 以了解哪些内容是 Kubernetes 所允许的。
    • 链接应该主要指向官方的 Kubernetes 文档。 当引用外部信息时,链接应该是多样的。 例如,所提交的博客文章中不可以只包含指向某个公司的博客的链接。
    • 有些时候,这是一个比较棘手的权衡过程。 博客团队的存在目的即是为 Kubernetes 博客提供文章是否合适的指导意见。 所以,需要帮助的时候不要犹豫。
  • 博客内容并非在某特定日期发表。
    • 文章会交由社区自愿者评阅。我们会尽力满足特定的时限要求,只是无法就此作出承诺。
    • Kubernetes 项目的很多核心组件会在发布窗口期内提交博客文章,导致发表时间被推迟。 因此,请考虑在发布周期内较为平静的时间段提交博客文章。
    • 如果你希望就博文发表日期上进行较大范围的协调,请联系 CNCF 推广团队。 这也许是比提交博客文章更合适的一种选择。
    • 有时,博客的评审可能会堆积起来。如果你觉得你的文章没有引起该有的重视,你可以通过 #sig-docs-blog Slack 频道联系博客团队, 以获得实时反馈。
  • 博客内容应该对 Kubernetes 用户有用。
    • 与参与 Kubernetes SIG 活动相关,或者与这类活动的结果相关的主题通常是切题的。 请参考 贡献者沟通(Contributor Comms)团队的工作以获得对此类博文的支持。
    • Kubernetes 的组件都有意设计得模块化,因此使用类似 CNI、CSI 等集成点的工具通常都是切题的。
    • 关于其他 CNCF 项目的博客可能切题也可能不切题。 我们建议你在提交草稿之前与博客团队联系。
      • 很多 CNCF 项目有自己的博客。这些博客通常是更好的选择。 有些时候,某个 CNCF 项目的主要功能特性或者里程碑的变化可能是用户有兴趣在 Kubernetes 博客上阅读的内容。
    • 关于为 Kubernetes 项目做贡献的博客内容应该放在 Kubernetes 贡献者站点上。
  • 博客文章应该是原创内容。
    • 官方博客的目的不是将某第三方已发表的内容重新作为新内容发表。
    • 博客的授权协议 的确允许出于商业目的来使用博客内容;但并不是所有可以商用的内容都适合在这里发表。
  • 博客文章的内容应该在一段时间内不过期。
    • 考虑到项目的开发速度,我们希望读者看到的是不必更新就能保持长期准确的内容。
    • 有时候,在官方文档中添加一个教程或者进行内容更新都是比博客更好的选择。
      • 可以考虑在博客文章中将较长技术内容的重点放在鼓励读者自行尝试上, 或者放在问题域本身或者为什么读者应该关注某个话题上。

提交博客的技术考虑

所提交的内容应该是 Markdown 格式的,以便能够被 Hugo 生成器来处理。 关于如何使用相关技术,有很多可用的资源

我们知道这一需求可能给那些对此过程不熟悉的朋友们带来不便, 我们也一直在寻找降低难度的解决方案。 如果你有降低难度的好主意,请自荐帮忙。

SIG Docs 博客子项目负责管博客的评阅过程。 更多信息可参考提交博文

要提交博文,你可以遵从以下指南:

  • 发起一个包含新博文的 PR。 新博文要创建于 content/en/blog/_posts 目录下。

  • 确保你的博文遵从合适的命名规范,并带有下面的引言(元数据)信息:

    • Markdown 文件名必须符合格式 YYYY-MM-DD-Your-Title-Here.md。 例如,2020-02-07-Deploying-External-OpenStack-Cloud-Provider-With-Kubeadm.md

    • 不要在文件名中包含多余的句点。类似 2020-01-01-whats-new-in-1.19.md 这类文件名会导致文件无法正确打开。

    • 引言部分必须包含以下内容:

      ---
      layout: blog
      title: "Your Title Here"
      date: YYYY-MM-DD
      slug: text-for-URL-link-here-no-spaces
      ---
      
    • 第一个或者最初的提交的描述信息中应该包含一个所作工作的简单摘要, 并作为整个博文的一个独立描述。 请注意,对博文的后续修改编辑都会最终合并到此主提交中,所以此提交的描述信息 应该尽量有用。
      • 较好的提交消息(Commit Message)示例:
        • Add blog post on the foo kubernetes feature
        • blog: foobar announcement
      • 较差的提交消息示例:
        • Add blog post
        • .
        • initial commit
        • draft post
    • 博客团队会对 PR 内容进行评阅,为你提供一些评语以便修订。 之后,机器人会将你的博文合并并发表。
    • 如果博文的内容仅包含预期无需更新就能对读者保持精准的内容, 则可以将这篇博文标记为长期有效(evergreen), 且免除添加博文发表一年后内容过期的自动警告。
      • 要将一篇博文标记为长期有效,请在引言部分添加以下标记:

        evergreen: true
        
      • 不应标记为长期有效的内容示例:

        • 仅适用于特定发行版或版本而不是所有未来版本的教程
        • 对非正式发行(Pre-GA)API 或功能特性的引用

提交案例分析

案例分析用来概述组织如何使用 Kubernetes 解决现实世界的问题。 Kubernetes 市场化团队和 CNCF 成员会与你一起工作, 撰写所有的案例分析。

请查看现有案例分析的源码。

参考案例分析指南, 根据指南中的注意事项提交你的 PR 请求。

3 - 评阅变更

本节描述如何对内容进行评阅。

3.1 - 评审 PR

任何人均可评审文档的拉取请求。 访问 Kubernetes 网站仓库的 pull requests 部分, 可以查看所有待处理的拉取请求(PR)。

评审文档 PR 是将你自己介绍给 Kubernetes 社区的一种很好的方式。 它将有助于你学习代码库并与其他贡献者之间建立相互信任关系。

在评审之前,可以考虑:

准备工作

在你开始评审之前:

  • 阅读 CNCF 行为准则。 确保你会始终遵从其中约定。
  • 保持有礼貌、体谅他人,怀助人为乐初心。
  • 评论时若给出修改建议,也要兼顾 PR 的积极方面。
  • 保持同理心,多考虑他人收到评审意见时的可能反应。
  • 假定大家都是好意的,通过问问题澄清意图。
  • 如果你是有经验的贡献者,请考虑和新贡献者一起合作,提高其产出质量。

评审过程

一般而言,应该使用英语来评审 PR 的内容和样式。 图 1 概述了评审流程的各个步骤。 每个步骤的详细信息如下。

flowchart LR subgraph fourth[开始评审] direction TB S[ ] -.- M[添加评论] --> N[评审变更] N --> O[新手应该
选择 Comment] end subgraph third[选择 PR] direction TB T[ ] -.- J[阅读描述
和评论]--> K[通过 Netlify 预览构建
来预览变更] end A[查阅待处理的 PR 清单]--> B[通过标签过滤
待处理的 PR] B --> third --> fourth classDef grey fill:#dddddd,stroke:#ffffff,stroke-width:px,color:#000000, font-size:15px; classDef white fill:#ffffff,stroke:#000,stroke-width:px,color:#000,font-weight:bold classDef spacewhite fill:#ffffff,stroke:#fff,stroke-width:0px,color:#000 class A,B,J,K,M,N,O grey class S,T spacewhite class third,fourth white

图 1. 评审流程步骤。

  1. 前往 https://github.com/kubernetes/website/pulls, 你会看到所有针对 Kubernetes 网站和文档的待处理 PR。

  2. 使用以下标签(组合)对待处理 PR 进行过滤:

    • cncf-cla: yes (建议):由尚未签署 CLA 的贡献者所发起的 PR 不可以合并。 参考签署 CLA 以了解更多信息。
    • language/en (建议):仅查看英语语言的 PR。
    • size/<尺寸>:过滤特定尺寸(规模)的 PR。 如果你刚入门,可以从较小的 PR 开始。

    此外,确保 PR 没有标记为尚未完成(Work in Progress)。 包含 work in progress 的 PR 通常还没准备好被评审。

  1. 选定 PR 评审之后,可以通过以下方式理解所作的变更:

    • 阅读 PR 描述以理解所作变更,并且阅读所有关联的 Issues。
    • 阅读其他评审人给出的评论。
    • 点击 Files changed Tab 页面,查看被改变的文件和代码行。
    • 滚动到 Conversation Tab 页面下端的 PR 构建检查节区, 预览 Netlify 预览构建中的变更。 以下是一个屏幕截图(这显示了 GitHub 的桌面版外观; 如果你在平板电脑或智能手机设备上进行评审, GitHub 的 Web UI 会略有不同):
      GitHub PR 详细信息,包括 Netlify 预览链接
      要打开预览,请点击 deploy/netlify 行的 Details 链接。
  1. 前往 Files changed Tab 页面,开始你的评审工作。

    1. 点击你希望评论的行旁边的 + 号。

    2. 填写你对该行的评论, 之后选择 Add single comment(如果你只有一条评论) 或者 Start a review(如果你还有其他评论要添加)。

    3. 评论结束时,点击页面顶部的 Review changes。 这里你可以添加你的评论结语(记得留下一些正能量的评论!)、 根据需要批准 PR、请求作者进一步修改等等。 新手应该选择 Comment

      • 避免在完成审查后点击 "Request changes(请求修改)"按钮。 如果在完成进一步修改之前你想阻止某 PR 被合并。你可以在评论中留下一个 “/hold”。 同时在评论中说明你为什么要设置 Hold,并且在必要时指定在什么条件下可以由你或其他评审人取消 Hold。
      • 避免在完成审查后直接点击 "Approve(批准)"按钮。 在大多数情况下,建议在评论区留下一个"/approve(批准)"的评论。

评审清单

评审 PR 时可以从下面的条目入手。

语言和语法

  • 是否存在明显的语言或语法错误?对某事的描述有更好的方式?
    • 关注作者正在更改的页面部分的语言和语法。除非作者明确打算更新整个页面,否则他们没有义务修复页面上的所有问题。
    • 当一个 PR 更新现有页面时,你应专注于评审正在更新的页面部分。你应评审所更改内容的技术和编辑的正确性。 如果你发现页面上的一些错误与 PR 作者尝试解决的问题没有直接关系, 则应将其视为一个单独的 Issue(首先检查是否存在与此相关的 Issue)。
    • 要特别注意那些 移动 内容的 PR。如果作者重命名一个页面或合并两个页面, 我们(Kubernetes SIG Docs)通常应避免要求该作者修复可能在所移动的内容中发现的所有语法或拼写错误。
  • 是否存在一些过于复杂晦涩的用词,本可以用简单词汇来代替?
  • 是否有些用词、术语或短语可以用不带歧视性的表达方式代替?
  • 用词和大小写方面是否遵从了样式指南
  • 是否有些句子太长,可以改得更短、更简单?
  • 是否某些段落过长,可以考虑使用列表或者表格来表达?

内容

  • Kubernetes 网站上是否别处已经存在类似的内容?
  • 内容本身是否过度依赖于网站范畴之外、独立供应商或者非开源的文档?

网站

  • PR 是否改变或者删除了某页面的标题、slug/别名或者链接锚点? 如果是这样,PR 是否会导致出现新的失效链接? 是否有其他的办法,比如改变页面标题但不改变其 slug?

  • PR 是否引入新的页面?如果是:

    • 该页面是否使用了正确的页面内容类型 及相关联的 Hugo 短代码(shortcodes)?
    • 该页面能否在对应章节的侧面导航中显示?显示得正确么?
    • 该页面是否应出现在网站主页面的列表中?
  • 变更是否正确出现在 Netlify 预览中了? 要对列表、代码段、表格、注释和图像等元素格外留心。

其他

  • 查阅 Trivial Edits; 如果你看到某个变更在你看来是一个 Trivial Edit,请向作者指明这项政策(如果该变更确实会有所改进,那仍然可以接受)。
  • 鼓励作者们在第一次发 PR 时修复一些空格相关的问题,在随后的 PR 中增加其他更改。 这样更便于合并和评审。尤其要注意在单个 commit 中大量空格清理附带的微小变更(如果你看到,请鼓励作者进行修复)。

作为一名 Reviewer,如果你发现 PR 有一些无关紧要的小问题,例如拼写错误或不正确的空格, 可以在你的评论前面加上 nit:。这样做可以让作者知道该问题不是一个不得了的大问题。

如果你正在考虑批准一个 PR,并且所有剩余的反馈都被标记为 nit,那么你确实可以合并该 PR。 在这种情况下,你需要针对剩余的 nit 发帖登记一个 Issue。 考虑一下是否能把这些新 Issue 标记为 Good First Issue。 如果可以,这就是这类 Issue 的良好来源。

3.2 - 评阅人和批准人文档

SIG Docs 评阅人(Reviewers)批准人(Approvers) 在对变更进行评审时需要做一些额外的事情。

每周都有一个特定的文档批准人自愿负责对 PR 进行分类和评阅。 此角色称作该周的“PR 管理者(PR Wrangler)”。 相关信息可参考 PR Wrangler 排班表。 要成为 PR Wangler,需要参加每周的 SIG Docs 例会,并自愿报名。 即使当前这周排班没有轮到你,你仍可以评阅那些尚未被积极评阅的 PRs。

除了上述的轮值安排,后台机器人也会为基于所影响的文件来为 PR 指派评阅人和批准人。

评阅 PR

Kubernetes 文档遵循 Kubernetes 代码评阅流程

评阅 PR 文档中所描述的所有规程都适用, 不过评阅人和批准人还要做以下工作:

  • 根据需要使用 Prow 命令 /assign 指派特定的评阅人。如果某个 PR 需要来自代码贡献者的技术审核时,这一点非常重要。

  • 确保 PR 遵从内容指南样式指南; 如果 PR 没有达到要求,指引作者阅读指南中的相关部分。

  • 适当的时候使用 GitHub Request Changes 选项,建议 PR 作者实施所建议的修改。

  • 当你所提供的建议被采纳后,在 GitHub 中使用 /approve/lgtm Prow 命令,改变评审状态。

提交到他人的 PR

为 PR 留下评语是很有用的,不过有时候你需要向他人的 PR 提交内容。

除非他人明确请求你的帮助或者你希望重启一个被放弃很久的 PR,不要“接手”他人的工作。 尽管短期看来这样做可以提高效率,但是也剥夺了他人提交贡献的机会。

你所要遵循的流程取决于你需要编辑已经在 PR 范畴的文件,还是 PR 尚未触碰的文件。

如果处于下列情况之一,你不可以向别人的 PR 提交内容:

  • 如果 PR 作者是直接将自己的分支提交到 https://github.com/kubernetes/website/ 仓库。只有具有推送权限的评阅人才可以向他人的 PR 提交内容。

  • PR 作者明确地禁止批准人编辑他/她的 PR。

评阅用的 Prow 命令

Prow 是基于 Kubernetes 的 CI/CD 系统,基于拉取请求(PR)的触发运行不同任务。 Prow 使得我们可以使用会话机器人一样的命令跨整个 Kubernetes 组织处理 GitHub 动作,例如添加和删除标签、关闭 Issues 以及指派批准人等等。你可以使用 /<命令名称> 的形式以 GitHub 评论的方式输入 Prow 命令。

评阅人和批准人最常用的 Prow 命令有:

评阅用 Prow 命令
Prow 命令角色限制描述
/lgtm组织成员用来表明你已经完成 PR 的评阅并对其所作变更表示满意
/approve批准人批准某 PR 可以合并
/assign任何人指派某人来评阅或批准某 PR
/close组织成员关闭 Issue 或 PR
/hold任何人添加 do-not-merge/hold 标签,用来表明 PR 不应被自动合并
/hold cancel任何人去掉 do-not-merge/hold 标签

要查看可以在 PR 中使用的命令,请参阅 Prow 命令指南

对 Issue 进行诊断和分类

一般而言,SIG Docs 遵从 Kubernetes issue 判定 流程并使用相同的标签。

此 GitHub Issue 过滤器 可以用来查找需要评判的 Issues。

评判 Issue

  1. 验证 Issue 的合法性
  • 确保 Issue 是关于网站文档的。某些 Issue 可以通过回答问题或者为报告者提供 资源链接来快速关闭。 参考请求支持或代码缺陷报告 节以了解详细信息。
  • 评估该 Issue 是否有价值。
  • 如果 Issue 缺少足够的细节以至于无法采取行动,或者报告者没有通过模版提供 足够信息,可以添加 triage/needs-information 标签。
  • 如果 Issue 同时标注了 lifecycle/staletriage/needs-information 标签,可以直接关闭。
  1. 添加优先级标签( Issue 判定指南中有优先级标签的详细定义)
Issue 标签
标签描述
priority/critical-urgent应马上处理
priority/important-soon应在 3 个月内处理
priority/important-longterm应在 6 个月内处理
priority/backlog可无限期地推迟,可在人手充足时处理
priority/awaiting-more-evidence占位符,标示 Issue 可能是一个不错的 Issue,避免该 Issue 被忽略或遗忘
help or good first issue适合对 Kubernetes 或 SIG Docs 经验较少的贡献者来处理。更多信息可参考需要帮助和入门候选 Issue 标签

基于你自己的判断,你可以选择某 Issue 来处理,为之发起 PR (尤其是那些可以很快处理或与你已经在做的工作相关的 Issue)。

如果你对 Issue 评判有任何问题,可以在 #sig-docs Slack 频道或者 kubernetes-sig-docs 邮件列表 中提问。

添加和删除 Issue 标签

要添加标签,可以用以下形式对 PR 进行评论:

  • /<要添加的标签> (例如, /good-first-issue
  • /<标签类别> <要添加的标签> (例如,/triage needs-information/language ja

要移除某个标签,可以用以下形式对 PR 进行评论:

  • /remove-<要移除的标签> (例如,/remove-help
  • /remove-<标签类别> <要移除的标签> (例如,/remove-triage needs-information

在以上两种情况下,标签都必须合法存在。如果你尝试添加一个尚不存在的标签, 对应的命令会被悄悄忽略。

关于所有标签的完整列表,可以参考 Website 仓库的标签节。 实际上,SIG Docs 并没有使用全部标签。

Issue 生命周期标签

Issues 通常都可以快速创建并关闭。 不过也有些时候,某个 Issue 被创建之后会长期处于非活跃状态。 也有一些时候,即使超过 90 天,某个 Issue 仍应保持打开状态。

Issue 生命周期标签
标签描述
lifecycle/stale过去 90 天内某 Issue 无人问津,会被自动标记为停滞状态。如果 Issue 没有被 /remove-lifecycle stale 命令重置生命期,就会被自动关闭。
lifecycle/frozen对应的 Issue 即使超过 90 天仍无人处理也不会进入停滞状态。用户手动添加此标签给一些需要保持打开状态超过 90 天的 Issue,例如那些带有 priority/important-longterm 标签的 Issue。

处理特殊的 Issue 类型

SIG Docs 常常会遇到以下类型的 Issue,因此对其处理方式描述如下。

重复的 Issue

如果针对同一个问题有不止一个打开的 Issue,可以将其合并为一个 Issue。 你需要决定保留哪个 Issue 为打开状态(或者重新登记一个新的 Issue), 然后将所有相关的信息复制过去并提供对关联 Issues 的链接。 最后,将所有其他描述同一问题的 Issue 标记为 triage/duplicate 并关闭之。 保持只有一个 Issue 待处理有助于减少困惑,避免在同一问题上发生重复劳动。

如果失效链接是关于 API 或者 kubectl 文档的,可以将其标记为 /priority critical-urgent,直到问题原因被弄清楚为止。 对于其他的链接失效问题,可以标记 /priority important-longterm, 因为这些问题都需要手动处理。

博客问题

我们预期 Kubernetes 博客条目随着时间推移都会过期。 因此,我们只维护一年内的博客条目。 如果某个 Issue 是与某个超过一年的博客条目有关的,可以直接关闭 Issue,不必修复。

请求支持或代码缺陷报告

某些文档 Issues 实际上是关于底层代码的 Issue 或者在某方面请求协助的问题, 例如某个教程无法正常工作。 对于与文档无关的 Issues,关闭它并打上标签 kind/support,可以通过评论 告知请求者其他支持渠道(Slack、Stack Overflow)。 如果有相关的其他仓库,可以告诉请求者应该在哪个仓库登记与功能特性相关的 Issues (通常会是 kubernetes/kubernetes)。

下面是对支持请求的回复示例:

This issue sounds more like a request for support and less
like an issue specifically for docs. I encourage you to bring
your question to the `#kubernetes-users` channel in
[Kubernetes slack](https://slack.k8s.io/). You can also search
resources like
[Stack Overflow](https://stackoverflow.com/questions/tagged/kubernetes)
for answers to similar questions.

You can also open issues for Kubernetes functionality in
https://github.com/kubernetes/kubernetes.

If this is a documentation issue, please re-open this issue.

对代码缺陷 Issue 的回复示例:

This sounds more like an issue with the code than an issue with
the documentation. Please open an issue at
https://github.com/kubernetes/kubernetes/issues.

If this is a documentation issue, please re-open this issue.

4 - 本地化 Kubernetes 文档

此页面描述如何为其他语言的文档提供 本地化版本。

为现有的本地化做出贡献

你可以帮助添加或改进现有本地化的内容。在 Kubernetes Slack 中, 你能找到每个本地化的频道。还有一个通用的 SIG Docs Localizations Slack 频道, 你可以在这里打个招呼。

找到两个字母的语言代码

首先,有关本地化的两个字母的语言代码,请参考 ISO 639-1 标准。 例如,韩语的两个字母代码是 ko

一些语言使用 ISO-3166 定义的国家代码的小写版本及其语言代码。 例如,巴西葡萄牙语代码是 pt-br

派生(fork)并且克隆仓库

首先,为 kubernetes/website 仓库 创建你自己的副本

然后,克隆你的 website 仓库副本并通过 cd 命令进入 website 目录:

git clone https://github.com/<username>/website
cd website

网站内容目录包括每种语言的子目录。你想要助力的本地化位于 content/<two-letter-code> 中。

建议更改

根据英文原件创建或更新你选择的本地化页面。 有关更多详细信息,请参阅翻译内容

如果你发现上游(英文)文档存在技术错误或其他问题, 你应该先修复上游文档,然后通过更新你正在处理的本地化来重复等效的修复。

请将 PR 限制为单个语言版本,因为多语言的 PR 内容修改可能难以审查。

按照内容改进建议提出对该本地化的更改。 该过程与提议更改上游(英文)内容非常相似。

开始新的本地化

如果你希望将 Kubernetes 文档本地化为一种新语言,你需要执行以下操作。

因为贡献者不能批准他们自己的拉取请求,你需要 至少两个贡献者 来开始本地化。

所有本地化团队都必须能够自我维持。 Kubernetes 网站很乐意托管你的作品,但要由你来翻译它并使现有的本地化内容保持最新。

你需要知道你的语言的两个字母的语言代码。 请查阅 ISO 639-1 标准 以查找你的本地化的两字母语言代码。例如,韩语的两字母代码是 ko

如果你开始本地化的语言在不同地方使用,并且变体之间存在显着差异, 则将小写的 ISO-3166 国家/地区代码与语言双字母代码结合起来可能是有意义的。 例如,巴西葡萄牙语被本地化为 pt-br

当你开始新的本地化时,你必须先本地化所有最少要求的内容, Kubernetes 项目才能将你的更改发布到当前网站。

SIG Docs 可以帮助你在单独的分支上工作,以便你可以逐步实现该目标。

找到社区

让 Kubernetes SIG Docs 知道你有兴趣创建本地化! 加入 SIG Docs Slack 频道SIG Docs Localizations Slack 频道。 其他本地化团队很乐意帮助你入门并回答你的问题。

也请考虑参加 SIG Docs 本地化小组的会议。 SIG Docs 本地化小组的任务是与 SIG Docs 本地化团队合作, 共同定义和记录创建本地化贡献指南的流程。 此外,SIG Docs 本地化小组将寻找机会在本地化团队中创建和共享通用工具, 并为 SIG Docs 领导团队确定新要求。如果你对本次会议有任何疑问,请在 SIG Docs Localizations Slack 频道中提问。

你还可以在 kubernetes/community 仓库中为你的本地化创建一个 Slack 频道。 有关添加 Slack 频道的示例, 请参阅为波斯语添加频道的 PR。

加入到 Kubernetes GitHub 组织

提交本地化 PR 后,你可以成为 Kubernetes GitHub 组织的成员。 团队中的每个人都需要在 kubernetes/org 仓库中创建自己的组织成员申请

在 GitHub 中添加你的本地化团队

接下来,将你的 Kubernetes 本地化团队添加到 sig-docs/teams.yaml。 有关添加本地化团队的示例,请参见添加西班牙本地化团队的 PR。

@kubernetes/sig-docs-**-owners 成员可以批准更改对应本地化目录 /content/**/ 中内容的 PR,并仅限这类 PR。 对于每个本地化,@kubernetes/sig-docs-**-reviews 团队被自动分派新 PR 的审阅任务。 @kubernetes/website-maintainers 成员可以创建新的本地化分支来协调翻译工作。 @kubernetes/website-milestone-maintainers 成员可以使用 /milestone Prow 命令为 issues 或 PR 设定里程碑。

配置工作流程

接下来,在 kubernetes/test-infra 仓库中为你的本地化添加一个 GitHub 标签。 标签可让你过滤 issues 和针对特定语言的 PR。

有关添加标签的示例,请参见添加意大利语标签的 PR。

修改站点配置

Kubernetes 网站使用 Hugo 作为其 Web 框架。网站的 Hugo 配置位于 hugo.toml文件中。 为了支持新的本地化,你需要修改 hugo.toml

在现有的 [languages] 下,将新语言的配置添加到 hugo.toml 中。 例如,下面是德语的配置示例:

[languages.de]
title = "Kubernetes"
description = "Produktionsreife Container-Verwaltung"
languageName = "Deutsch (German)"
languageNameLatinScript = "Deutsch"
contentDir = "content/de"
weight = 8

语言选择栏列出了 languageName 的值。 将 languageName 赋值为“本地脚本中的语言名称(拉丁脚本中的语言名称)”。 例如,languageName = "한국어 (Korean)"languageName = "Deutsch (German)"

languageNameLatinScript 可用于访问拉丁脚本中的语言名称并在主题中使用。 将 languageNameLatinScript 赋值为“拉丁脚本中的语言名称”。 例如,languageNameLatinScript ="Korean"languageNameLatinScript = "Deutsch"

为你的语言块分配一个 weight 参数时,找到权重最高的语言块并将其加 1。

有关 Hugo 多语言支持的更多信息,请参阅"多语言模式"。

添加一个新的本地化目录

将特定语言的子目录添加到仓库中的 content 文件夹下。 例如,德语的两个字母的代码是 de

mkdir content/de

你还需要在 data/i18n 中为 localized strings 创建一个目录; 以现有的本地化为例。要使用这些新字符串, 你还必须创建从 i18n/<localization>.tomldata/i18n/<localization>/<localization>.toml 中实际字符串配置的符号链接(记得提交符号链接关联)。

例如,对于德语,字符串位于 data/i18n/de/de.toml 中, 而 i18n/de.toml 是指向 data/i18n/de/de.toml 的符号链接。

本地化社区行为准则

cncf/foundation 仓库提交 PR,添加你所用语言版本的行为准则。

设置 OWNERS 文件

要设置每个对本地化做出贡献用户的角色,请在特定于语言的子目录内创建一个 OWNERS 文件,其中:

有关 OWNERS 文件的更多信息,请访问 go.k8s.io/owners

语言代码为 es西班牙语 OWNERS 文件看起来像:

# See the OWNERS docs at https://go.k8s.io/owners

# This is the localization project for Spanish.
# Teams and members are visible at https://github.com/orgs/kubernetes/teams.

reviewers:
- sig-docs-es-reviews

approvers:
- sig-docs-es-owners

labels:
- language/es

添加了特定语言的 OWNERS 文件之后,使用新的 Kubernetes 本地化团队、 sig-docs-**-ownerssig-docs-**-reviews 列表更新 根目录下的 OWNERS_ALIAES 文件。

对于每个团队,请按字母顺序添加 在 GitHub 中添加你的本地化团队 中所请求的 GitHub 用户列表。

--- a/OWNERS_ALIASES
+++ b/OWNERS_ALIASES
@@ -48,6 +48,14 @@ aliases:
     - stewart-yu
     - xiangpengzhao
     - zhangxiaoyu-zidif
+  sig-docs-es-owners: # Admins for Spanish content
+    - alexbrand
+    - raelga
+  sig-docs-es-reviews: # PR reviews for Spanish content
+    - alexbrand
+    - electrocucaracha
+    - glo-pena
+    - raelga
   sig-docs-fr-owners: # Admins for French content
     - perriea
     - remyleone

发起拉取请求

接下来,发起拉取请求(PR) 将本地化添加到 kubernetes/website 存储库。 PR 必须包含所有最低要求内容才能获得批准。

有关添加新本地化的示例, 请参阅启用法语文档的 PR。

添加本地化的 README 文件

为了指导其他本地化贡献者,请在 kubernetes/website 的根目录添加一个新的 README-**.md, 其中 ** 是两个字母的语言代码。例如,德语 README 文件为 README-de.md

在本地化的 README-**.md 文件中为本地化贡献者提供指导。包含 README.md 中包含的相同信息,以及:

  • 本地化项目的联系人
  • 任何特定于本地化的信息

创建本地化的 README 文件后,请在英语版文件 README.md 中添加指向该文件的链接, 并给出英文形式的联系信息。你可以提供 GitHub ID、电子邮件地址、 Slack 频道或其他联系方式。你还必须提供指向本地化的社区行为准则的链接。

启动你的新本地化

一旦本地化满足工作流程和最小输出的要求,SIG Docs 将:

翻译文档

本地化所有 Kubernetes 文档是一项艰巨的任务。从小做起,循序渐进。

最低要求内容

所有本地化至少必须包括:

描述网址
主页所有标题和副标题网址
安装所有标题和副标题网址
教程Kubernetes 基础, Hello Minikube
网站字符串所有网站字符串
发行版本所有标题和副标题 URL

翻译后的文档必须保存在自己的 content/**/ 子目录中,否则将遵循与英文源相同的 URL 路径。 例如,要准备将 Kubernetes 基础教程翻译为德语, 请在 content/de/ 文件夹下创建一个子文件夹并复制英文源:

mkdir -p content/de/docs/tutorials
cp content/en/docs/tutorials/kubernetes-basics.md content/de/docs/tutorials/kubernetes-basics.md

翻译工具可以加快翻译过程。例如,某些编辑器提供了用于快速翻译文本的插件。

为了确保语法和含义的准确性,本地化团队的成员应在发布之前仔细检查所有由机器生成的翻译。

源文件

本地化必须基于本地化团队所针对的特定发行版本中的英文文件。 每个本地化团队可以决定要针对哪个发行版本,在下文中称作 目标版本(target version)

要查找你的目标版本的源文件:

  1. 导航到 Kubernetes website 仓库,网址为 https://github.com/kubernetes/website
  2. 从下面的表格中选择你的目标版本分支:
目标版本分支
最新版本main
上一个版本release-1.29
下一个版本dev-1.31

main 分支中保存的是当前发行版本 v1.30 的内容。 发行团队会在下一个发行版本 v1.31 出现之前创建 release-1.30 分支。

i18n/ 中的网站字符串

本地化必须在新的语言特定文件中包含 data/i18n/en/en.toml 的内容。以德语为例:data/i18n/de/de.toml

将新的本地化文件和目录添加到 data/i18n/。例如德语 (de):

mkdir -p data/i18n/de
cp data/i18n/en/en.toml data/i18n/de/de.toml

修改文件顶部的注释以适合你的本地化,然后翻译每个字符串的值。 例如,这是搜索表单的德语占位符文本:

[ui_search_placeholder]
other = "Suchen"

本地化网站字符串允许你自定义网站范围的文本和特性:例如每个页面页脚中的版权声明文本。

特定语言的本地化指南

作为本地化团队,你可以通过创建特定语言的本地化指南来正式确定团队需遵循的最佳实践。 请参见中文本地化指南

特定语言的 Zoom 会议

如果本地化项目需要单独的会议时间, 请联系 SIG Docs 联合主席或技术主管以创建新的重复 Zoom 会议和日历邀请。 仅当团队维持在足够大的规模并需要单独的会议时才需要这样做。

根据 CNCF 政策,本地化团队必须将他们的会议上传到 SIG Docs YouTube 播放列表。 SIG Docs 联合主席或技术主管可以帮助完成该过程,直到 SIG Docs 实现自动化。

分支策略

因为本地化项目是高度协同的工作, 特别是在刚开始本地化并且本地化尚未生效时,我们鼓励团队基于共享的本地化分支工作。

在本地化分支上协作需要:

  1. @kubernetes/website-maintainers 中的团队成员从 https://github.com/kubernetes/website 原有分支新建一个本地化分支。

    当你给 kubernetes/org 仓库添加你的本地化团队时, 你的团队批准人便加入了 @kubernetes/website-maintainers 团队。

    我们推荐以下分支命名方案:

    dev-<source version>-<language code>.<team milestone>

    例如,一个德语本地化团队的批准人基于 Kubernetes v1.12 版本的源分支, 直接新建了 kubernetes/website 仓库的本地化分支 dev-1.12-de.1

  1. 个人贡献者基于本地化分支创建新的特性分支。

    例如,一个德语贡献者新建了一个拉取请求, 并将 username:local-branch-name 更改为 kubernetes:dev-1.12-de.1

  2. 批准人审查功能分支并将其合并到本地化分支中。

  3. 批准人会定期发起并批准新的 PR,将本地化分支合并到其源分支。 在批准 PR 之前,请确保先 squash commits。

根据需要重复步骤 1-4,直到完成本地化工作。例如,随后的德语本地化分支将是: dev-1.12-de.2dev-1.12-de.3 等等。

团队必须将本地化内容合入到发布分支中,该发布分支是内容的来源。例如:

  • 源于 main 分支的本地化分支必须被合并到 main
  • 源于 release-{{ skew "prevMinorVersion" }} 的本地化分支必须被合并到 release-{{ skew "prevMinorVersion" }}

在团队每个里程碑的开始时段,创建一个 issue 来比较先前的本地化分支和当前的本地化分支之间的上游变化很有帮助。 现在有两个脚本用来比较上游的变化。

虽然只有批准人才能创建新的本地化分支并合并 PR, 任何人都可以为新的本地化分支提交一个拉取请求(PR)。不需要特殊权限。

有关基于派生或直接从仓库开展工作的更多信息,请参见 "派生和克隆"

上游贡献

Sig Docs 欢迎对英文原文的上游贡献和修正。

5 - 参与 SIG Docs

SIG Docs 是 Kubernetes 项目 特别兴趣小组 中的一个,负责编写、更新和维护 Kubernetes 的总体文档。 参见社区 GitHub 仓库中 SIG Docs 以进一步了解该 SIG。

SIG Docs 欢迎所有贡献者提供内容和审阅。任何人可以提交拉取请求(PR)。 欢迎所有人对文档内容创建 Issue 和对正在处理中的 PR 进行评论。

你也可以成为成员(member)评阅人(reviewer) 或者 批准人(approver)。 这些角色拥有更高的权限,且需要承担批准和提交变更的责任。 有关 Kubernetes 社区中的成员如何工作的更多信息,请参见 社区成员身份

本文档的其余部分概述了这些角色在 SIG Docs 中发挥作用的一些独特方式。 SIG Docs 负责维护 Kubernetes 最面向公众的方面之一 —— Kubernetes 网站和文档。

SIG Docs 主席

每个 SIG,包括 SIG Docs,都会选出一位或多位成员作为主席。 主席会成为 SIG Docs 和其他 Kubernetes 组织的联络接口人。 他们需要了解整个 Kubernetes 项目的架构,并明白 SIG Docs 如何在其中运作。 如需查询当前的主席名单,请查阅 领导人员

SIG Docs 团队和自动化

SIG 文档中的自动化服务依赖于两种不同的机制: GitHub 团队和 OWNERS 文件。

GitHub 团队

GitHub 上有两类 SIG Docs 团队:

  • @sig-docs-{language}-owners 包含批准人和牵头人
  • @sig-docs-{language}-reviews 包含评阅人

可以在 GitHub 的评论中使用团队的名称 @name 来与团队成员沟通。

有时候 Prow 所定义的团队和 GitHub 团队有所重叠,并不完全一致。 对于指派 Issue、PR 和批准 PR,自动化工具使用来自 OWNERS 文件的信息。

OWNERS 文件和扉页

Kubernetes 项目使用名为 prow 的自动化工具来自动处理 GitHub issue 和 PR。 Kubernetes website 仓库 使用了两个 prow 插件

  • blunderbuss
  • approve

这两个插件使用位于 kubernetes/website 仓库顶层的 OWNERS 文件和 OWNERS_ALIASES 文件来控制 prow 在仓库范围的工作方式。

OWNERS 文件包含 SIG Docs 评阅人和批准人的列表。 OWNERS 文件也可以存在于子目录中,可以在子目录层级重新设置哪些人可以作为评阅人和 批准人,并将这一设定传递到下层子目录。 关于 OWNERS 的更多信息,请参考 OWNERS 文档。

此外,每个独立的 Markdown 文件都可以在其前言部分列出评阅人和批准人, 每一项可以是 GitHub 用户名,也可以是 GitHub 组名。

结合 OWNERS 文件及 Markdown 文件的前言信息,自动化系统可以给 PR 作者可以就应该 向谁请求技术和文字评阅给出建议。

PR 是怎样被合并的

当某个拉取请求(PR)被合并到用来发布内容的分支,对应的内容就会被发布到 http://kubernetes.io。 为了确保我们所发布的内容的质量足够好,合并 PR 的权限仅限于 SIG Docs 批准人。下面是合并的工作机制:

  • 当某个 PR 同时具有 lgtmapprove 标签,没有 hold 标签且通过所有测试时, 该 PR 会被自动合并。
  • Kubernetes 组织的成员和 SIG Docs 批准人可以添加评论以阻止给定 PR 的自动合并, 即通过 /hold 评论或者收回某个 /lgtm 评论实现这点。
  • 所有 Kubernetes 成员可以通过 /lgtm 评论添加 lgtm 标签。
  • 只有 SIG Docs 批准人可以通过评论 /approve 合并 PR。 某些批准人还会执行一些其他角色,例如 PR 管理者SIG Docs 主席等。

接下来

关于贡献 Kubernetes 文档的更多信息,请参考:

5.1 - 角色与责任

任何人都可以为 Kubernetes 作出贡献。随着你对 SIG Docs 的贡献增多,你可以申请 社区内不同级别的成员资格。 这些角色使得你可以在社区中承担更多的责任。 每个角色都需要更多的时间和投入。具体包括:

  • 任何人(Anyone):为 Kubernetes 文档作出贡献的普通贡献者。
  • 成员(Members):可以对 Issue 进行分派和判别,对 PR 提出无约束性的评审意见。
  • 评审人(Reviewers):可以领导对文档 PR 的评审,可以对变更的质量进行判别。
  • 批准人(Approvers):可以领导对文档的评审并合并变更。

任何人(Anyone)

任何拥有 GitHub 账号的人都可以对 Kubernetes 作出贡献。SIG Docs 欢迎所有新的贡献者。

任何人都可以:

签署了 CLA 之后,任何人还可以:

  • 发起拉取请求(PR),改进现有内容、添加新内容、撰写博客或者案例分析
  • 创建示意图、图形资产或者嵌入式的截屏和视频内容

进一步的详细信息,可参见贡献新内容

成员(Members)

成员是指那些对 kubernetes/website 提交很多拉取请求(PR)的人。 成员都要加入 Kubernetes GitHub 组织

成员可以:

  • 执行任何人节区所列举操作

  • 使用 /lgtm 评论添加 LGTM (looks good to me(我觉得可以)) 标签到某个 PR

  • 利用 /hold 评论来阻止某个 PR 被合并

  • 使用 /assign 评论为某个 PR 指定评审人

  • 对 PR 提供非约束性的评审意见

  • 使用自动化机制来对 Issue 进行判别和分类

  • 为新功能特性撰写文档

成为一个成员

在你成功地提交至少 5 个 PR 并满足 相关条件 之后:

  1. 找到两个评审人批准人为你的成员身份提供 担保

    通过 Kubernetes Slack 上的 #sig-docs 频道 或者 SIG Docs 邮件列表 来寻找为你担保的人。

  2. kubernetes/org 仓库 使用 Organization Membership Request Issue 模板登记一个 Issue。

  1. 告知你的担保人你所创建的 Issue,你可以:

    • 在 Issue 中 @<GitHub-username> 提及他们的 GitHub 用户名
    • 通过 Slack 或 email 直接发送给他们 Issue 链接

    担保人会通过 +1 投票来批准你的请求。一旦你的担保人批准了该请求, 某个 Kubernetes GitHub 管理员会将你添加为组织成员。恭喜!

    如果你的成员请求未被接受,你会收到一些反馈。 当处理完反馈意见之后,可以再次发起申请。

  2. 登录你的邮件账户,接受来自 Kubernetes GitHub 组织发出的成员邀请。

评审人(Reviewers)

评审人负责评审悬决的 PR。 与成员所给的反馈不同,身为 PR 作者必须处理评审人的反馈。 评审人是 @kubernetes/sig-docs-{language}-reviews GitHub 团队的成员。

评审人可以:

  • 执行任何人成员节区所列举的操作

  • 评审 PR 并提供具约束性的反馈信息

  • 编辑代码中用户可见的字符串

  • 改进代码注释

你可以是 SIG Docs 的评审人,也可以是某个主题领域的文档的评审人。

为 PR 指派评审人

自动化引擎会为每个 PR 自动指派评审人。 你可以通过为 PR 添加评论 /assign [@_github_handle] 来请求某个特定评审人来评审。

如果所指派的评审人未能及时评审,其他的评审人也可以参与进来。 你可以根据需要指派技术评审人。

使用 /lgtm

LGTM 代表的是 “Looks Good To Me (我觉得可以)”,用来标示某个 PR 在技术上是准确的,可以被合并。 所有 PR 都需要来自某评审人的 /lgtm 评论和来自某批准人的 /approve 评论。

来自评审人的 /lgtm 评论是具有约束性的,会触发自动化引擎添加 lgtm 标签。

成为评审人

当你满足相关条件时, 你可以成为一个 SIG Docs 评审人。 来自其他 SIG 的评审人必须为 SIG Docs 单独申请评审人资格。

申请流程如下:

  1. 发起 PR,将你的 GitHub 用户名添加到 kubernetes/website 仓库中 OWNERS_ALIASES 文件的对应节区。

  2. 将 PR 指派给一个或多个 SIG Docs 批准人(sig-docs-{language}-owners 下列举的用户名)。

申请被批准之后,SIG Docs Leads 之一会将你添加到合适的 GitHub 团队。 一旦添加完成,@k8s-ci-robot 会在处理未来的 PR 时,将 PR 指派给你或者建议你来评审某 PR。

批准人(Approvers)

批准人负责评审和批准 PR 以将其合并。 批准人是 @kubernetes/sig-docs-{language}-owners GitHub 团队的成员。

批准人可以执行以下操作:

  • 执行列举在任何人成员评审人节区的操作
  • 通过使用 /approve 评论来批准、合并 PR,发布贡献者所贡献的内容。
  • 就样式指南给出改进建议
  • 对文档测试给出改进建议
  • 对 Kubernetes 网站或其他工具给出改进建议

如果某个 PR 已有 /lgtm 标签,或者批准人再回复一个 /lgtm,则这个 PR 会自动合并。 SIG Docs 批准人应该只在不需要额外的技术评审的情况下才可以标记 /lgtm

批准 PR

只有批准人和 SIG Docs Leads 可以将 PR 合并到网站仓库。 这意味着以下责任:

  • 批准人可以使用 /approve 命令将 PR 合并到仓库中。

  • 确保所提议的变更满足文档内容指南要求。

    如果有问题或者疑惑,可以根据需要请他人帮助评审。

  • /approve PR 之前,须验证 Netlify 测试是否正常通过。

    批准之前必须通过 Netlify 测试
  • 在批准之前,请访问 Netlify 的页面预览来确保变更内容可正常显示。

  • 参与 PR 管理者轮值排班 执行时长为一周的 PR 管理。SIG Docs 期望所有批准人都参与到此轮值工作中。 更多细节可参见 PR 管理者

成为批准人

当你满足一定条件时,可以成为一个 SIG Docs 批准人。 来自其他 SIG 的批准人也必须在 SIG Docs 独立申请批准人资格。

申请流程如下:

  1. 发起一个 PR,将自己添加到 kubernetes/website 仓库中 OWNERS_ALIASES 文件的对应节区。

  2. 将 PR 指派给一个或多个 SIG Docs 批准人。

请求被批准之后,SIG Docs Leads 之一会将你添加到对应的 GitHub 团队。 一旦添加完成,K8s-ci-robot 会在处理未来的 PR 时,将 PR 指派给你或者建议你来评审某 PR。

接下来

  • 阅读 PR 管理者,了解所有批准人轮值的角色。

5.2 - PR 管理者

SIG Docs 的批准人(Approvers)们每周轮流负责 管理仓库的 PR

本节介绍 PR 管理者的职责。关于如何提供较好的评审意见, 可参阅评审变更

职责

在为期一周的轮值期内,PR 管理者要:

  • 每天对新增的 Issues 判定和打标签。参见 对 Issues 进行判定和分类 以了解 SIG Docs 如何使用元数据的详细信息。

  • 检查悬决的 PR 的质量并确保它们符合 样式指南内容指南要求。

    • 首先查看最小的 PR(size/XS),然后逐渐扩展到最大的 PR(size/XXL),尽可能多地评审 PR。
  • 确保贡献者完成 CLA 签署。
    • 使用此脚本自动提醒尚未签署 CLA 的贡献者签署 CLA。
  • 针对提供提供反馈,请求其他 SIG 的成员进行技术审核。
    • 为 PR 所建议的内容更改提供就地反馈。
    • 如果你需要验证内容,请在 PR 上发表评论并要求贡献者提供更多细节。
    • 设置相关的 sig/ 标签。
    • 如果需要,根据文件开头的 reviewers: 块来指派评审人。
    • 你也可以通过在 PR 上作出 @kubernetes/<sig>-pr-reviews 的评论以标记需要某个 SIG 来评审。
  • 使用 /approve 评论来批准可以合并的 PR,在 PR 就绪时将其合并。
    • PR 在被合并之前,应该有来自其他成员的 /lgtm 评论。
    • 可以考虑接受那些技术上准确,但文风上不满足 风格指南要求的 PR。 批准变更时,可以登记一个新的 Issue 来解决文档风格问题。 你通常可以将这些风格修复问题标记为 good first issue
    • 将风格修复事项标记为 good first issue 可以很好地确保向新加入的贡献者分派一些比较简单的任务, 这有助于接纳新的贡献者。

对管理者有用的 GitHub 查询

执行管理操作时,以下查询很有用。完成以下这些查询后,剩余的要审阅的 PR 列表通常很小。 这些查询都不包含本地化的 PR,并仅包含主分支上的 PR(除了最后一个查询)。

  • 未签署 CLA,不可合并的 PR: 提醒贡献者签署 CLA。如果机器人和审阅者都已经提醒他们,请关闭 PR,并提醒他们在签署 CLA 后可以重新提交。

    在作者没有签署 CLA 之前,不要审阅他们的 PR!

  • 需要 LGTM: 列举需要来自成员的 LGTM 评论的 PR。 如果需要技术审查,请告知机器人所建议的审阅者。 如果 PR 继续改进,就地提供更改建议或反馈。

  • 已有 LGTM标签,需要 Docs 团队批准: 列举需要 /approve 评论来合并的 PR。

  • 快速批阅: 列举针对主分支的、没有明确合并障碍的 PR。 在浏览 PR 时,可以将 "XS" 尺寸标签更改为 "S"、"M"、"L"、"XL"、"XXL"。

  • 非主分支的 PR: 如果 PR 针对 dev- 分支,则表示它适用于即将发布的版本。 请添加带有 /assign @<负责人的 github 账号>,将其指派给 发行版本负责人。 如果 PR 是针对旧分支,请帮助 PR 作者确定是否所针对的是最合适的分支。

对管理者有用的 Prow 命令

# 添加 English 标签
/language en

# 如果 PR 包含多个提交(commits),添加 squash 标签
/label tide/merge-method-squash

# 使用 Prow 来为 PR 重设标题(例如一个正在处理 [WIP] 的 PR 或为 PR 提供更好的细节信息)
/retitle [WIP] <TITLE>

何时关闭 PR

审查和批准是缩短和更新我们的 PR 队列的一种方式;另一种方式是关闭 PR。

当以下条件满足时,可以关闭 PR:

  • 作者两周内未签署 CLA。 PR 作者可以在签署 CLA 后重新打开 PR,因此这是确保未签署 CLA 的 PR 不会被合并的一种风险较低的方法。

  • 作者在两周或更长时间内未回复评论或反馈。

不要害怕关闭 PR。贡献者可以轻松地重新打开并继续工作。 通常,关闭通知会激励作者继续完成其贡献。

要关闭 PR,请在 PR 上输入 /close 评论。

PR 管理者影子计划

2021 下半年,SIG Docs 推出了 PR 管理者影子计划(PR Wrangler Shadow Program)。 该计划旨在帮助新的贡献者们了解 PR 管理流程。

成为一名影子

6 - 更新参考文档

本节的主题是描述如何生成 Kubernetes 参考指南。 要生成参考文档,请参考下面的指南:

6.1 - 参考文档快速入门

本页讨论如何使用 update-imported-docs.py 脚本来生成 Kubernetes 参考文档。 此脚本将构建的配置过程自动化,并为某个发行版本生成参考文档。

准备开始

需求

  • 你的 PATH 环境变量必须包含所需要的构建工具,例如 Go 程序和 python

  • 你需要知道如何为一个 GitHub 仓库创建拉取请求(PR)。 这牵涉到创建仓库的派生(fork)副本。 有关信息可进一步查看基于本地副本开展工作

获取文档仓库

确保你的 website 派生仓库与 GitHub 上的 kubernetes/website 远程仓库(main 分支)保持同步, 并克隆你的派生仓库。

mkdir github.com
cd github.com
git clone git@github.com:<your_github_username>/website.git

确定你的克隆副本的根目录。例如,如果你按照前面的步骤获取了仓库,你的根目录 会是 github.com/website。接下来的步骤中,<web-base> 用来指代你的根目录。

update-imported-docs 的概述

脚本 update-imported-docs.py 位于 <web-base>/update-imported-docs/ 目录下, 能够生成以下参考文档:

  • Kubernetes 组件和工具的参考页面
  • kubectl 命令参考文档
  • Kubernetes API 参考文档

脚本 update-imported-docs.py 基于 Kubernetes 源代码生成参考文档。 过程中会在你的机器的 /tmp 目录下创建临时目录,克隆所需要的仓库 kubernetes/kuberneteskubernetes-sigs/reference-docs 到此临时目录。 脚本会将 GOPATH 环境变量设置为指向此临时目录。 此外,脚本会设置三个环境变量:

  • K8S_RELEASE
  • K8S_ROOT
  • K8S_WEBROOT

脚本需要两个参数才能成功运行:

  • 一个 YAML 配置文件(reference.yml
  • 一个发行版本字符串,例如:1.17

配置文件中包含 generate-command 字段,其中定义了一系列来自于 kubernetes-sigs/reference-docs/Makefile 的构建指令。 变量 K8S_RELEASE 用来确定所针对的发行版本。

脚本 update-imported-docs.py 执行以下步骤:

  1. 克隆配置文件中所指定的相关仓库。就生成参考文档这一目的而言,要克隆的仓库默认为 kubernetes-sigs/reference-docs
  2. 在所克隆的仓库下运行命令,准备文档生成器,之后生成 HTML 和 Markdown 文件。
  3. 将所生成的 HTML 和 Markdown 文件复制到 <web-base> 本地克隆副本中, 放在配置文件中所指定的目录下。
  4. 更新 kubectl.md 文件中对 kubectl 命令文档的链接,使之指向 kubectl 命令参考中对应的节区。

当所生成的文件已经被放到 <web-base> 目录下,你就可以将其提交到你的派生副本中, 并基于所作提交发起拉取请求(PR)到 kubernetes/website 仓库。

配置文件格式

每个配置文件可以包含多个被导入的仓库。当必要时,你可以通过手工编辑此文件进行定制。 你也可以通过创建新的配置文件来导入其他文档集合。 下面是 YAML 配置文件的一个例子:

repos:
- name: community
  remote: https://github.com/kubernetes/community.git
  branch: master
  files:
  - src: contributors/devel/README.md
    dst: docs/imported/community/devel.md
  - src: contributors/guide/README.md
    dst: docs/imported/community/guide.md

通过工具导入的单页面的 Markdown 文档必须遵从文档样式指南

定制 reference.yml

打开 <web-base>/update-imported-docs/reference.yml 文件进行编辑。 在不了解参考文档构造命令的情况下,不要更改 generate-command 字段的内容。 你一般不需要更新 reference.yml 文件。不过也有时候上游的源代码发生变化, 导致需要对配置文件进行更改(例如:Golang 版本依赖或者第三方库发生变化)。 如果你遇到类似问题,请在 Kubernetes Slack 的 #sig-docs 频道 联系 SIG-Docs 团队。

reference.yml 文件中,files 属性包含了一组 srcdst 字段。 src 字段给出在所克隆的 kubernetes-sigs/reference-docs 构造目录中生成的 Markdown 文件的位置,而 dst 字段则给出了对应文件要复制到的、所克隆的 kubernetes/website 仓库中的位置。例如:

repos:
- name: reference-docs
  remote: https://github.com/kubernetes-sigs/reference-docs.git
  files:
  - src: gen-compdocs/build/kube-apiserver.md
    dst: content/en/docs/reference/command-line-tools-reference/kube-apiserver.md
  ...

注意,如果从同一源目录中有很多文件要复制到目标目录,你可以在为 src 所设置的值中使用通配符。这时,为 dst 所设置的值必须是目录名称。例如:

  files:
  - src: gen-compdocs/build/kubeadm*.md
    dst: content/en/docs/reference/setup-tools/kubeadm/generated/

运行 update-imported-docs 工具

你可以用如下方式运行 update-imported-docs.py 工具:

cd <web-base>/update-imported-docs
./update-imported-docs.py <configuration-file.yml> <release-version>

例如:

./update-imported-docs.py reference.yml 1.17

配置文件 release.yml 中包含用来修复相对链接的指令。 若要修复导入文件中的相对链接,将 gen-absolute-links 属性设置为 true。你可以在 release.yml 文件中找到示例。

添加并提交 kubernetes/website 中的变更

枚举新生成并复制到 <web-base> 的文件:

cd <web-base>
git status

输出显示新生成和已修改的文件。取决于上游源代码的修改多少, 所生成的输出也会不同。

生成的 Kubernetes 组件文档

content/en/docs/reference/command-line-tools-reference/cloud-controller-manager.md
content/en/docs/reference/command-line-tools-reference/kube-apiserver.md
content/en/docs/reference/command-line-tools-reference/kube-controller-manager.md
content/en/docs/reference/command-line-tools-reference/kube-proxy.md
content/en/docs/reference/command-line-tools-reference/kube-scheduler.md
content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm.md
content/en/docs/reference/kubectl/kubectl.md

生成的 kubectl 命令参考文件

static/docs/reference/generated/kubectl/kubectl-commands.html
static/docs/reference/generated/kubectl/navData.js
static/docs/reference/generated/kubectl/scroll.js
static/docs/reference/generated/kubectl/stylesheet.css
static/docs/reference/generated/kubectl/tabvisibility.js
static/docs/reference/generated/kubectl/node_modules/bootstrap/dist/css/bootstrap.min.css
static/docs/reference/generated/kubectl/node_modules/highlight.js/styles/default.css
static/docs/reference/generated/kubectl/node_modules/jquery.scrollto/jquery.scrollTo.min.js
static/docs/reference/generated/kubectl/node_modules/jquery/dist/jquery.min.js
static/docs/reference/generated/kubectl/css/font-awesome.min.css

生成的 Kubernetes API 参考目录与文件

static/docs/reference/generated/kubernetes-api/v1.26/index.html
static/docs/reference/generated/kubernetes-api/v1.26/js/navData.js
static/docs/reference/generated/kubernetes-api/v1.26/js/scroll.js
static/docs/reference/generated/kubernetes-api/v1.26/js/query.scrollTo.min.js
static/docs/reference/generated/kubernetes-api/v1.26/css/font-awesome.min.css
static/docs/reference/generated/kubernetes-api/v1.26/css/bootstrap.min.css
static/docs/reference/generated/kubernetes-api/v1.26/css/stylesheet.css
static/docs/reference/generated/kubernetes-api/v1.26/fonts/FontAwesome.otf
static/docs/reference/generated/kubernetes-api/v1.26/fonts/fontawesome-webfont.eot
static/docs/reference/generated/kubernetes-api/v1.26/fonts/fontawesome-webfont.svg
static/docs/reference/generated/kubernetes-api/v1.26/fonts/fontawesome-webfont.ttf
static/docs/reference/generated/kubernetes-api/v1.26/fonts/fontawesome-webfont.woff
static/docs/reference/generated/kubernetes-api/v1.26/fonts/fontawesome-webfont.woff2

运行 git addgit commit 提交文件。

创建拉取请求

接下来创建一个对 kubernetes/website 仓库的拉取请求(PR)。 监视所创建的 PR,并根据需要对评阅意见给出反馈。 继续监视该 PR 直到其被合并为止。

当你的 PR 被合并几分钟之后,你所做的对参考文档的变更就会出现 发布的文档上。

接下来

要手动设置所需的构造仓库,执行构建目标,以生成各个参考文档,可参考下面的指南:

6.2 - 为上游 Kubernetes 代码库做出贡献

此页面描述如何为上游 kubernetes/kubernetes 项目做出贡献,如修复 Kubernetes API 文档或 Kubernetes 组件(例如 kubeadmkube-apiserverkube-controller-manager 等) 中发现的错误。

如果你仅想从上游代码重新生成 Kubernetes API 或 kube-* 组件的参考文档。请参考以下说明:

准备开始

  • 你必须设置 GOPATH 环境变量,并且 etcd 的位置必须在 PATH 环境变量中。

基本说明

Kubernetes API 和 kube-* 组件(例如 kube-apiserverkube-controller-manager)的参考文档 是根据上游 Kubernetes 中的源代码自动生成的。

当你在生成的文档中看到错误时,你可能需要考虑创建一个 PR 用来在上游项目中对其进行修复。

克隆 Kubernetes 代码仓库

如果你还没有 kubernetes/kubernetes 代码仓库,请参照下列命令获取:

mkdir $GOPATH/src
cd $GOPATH/src
go get github.com/kubernetes/kubernetes

确定你的 kubernetes/kubernetes 代码仓库克隆的根目录。 例如,如果按照前面的步骤获取代码仓库,则你的根目录为 $GOPATH/src/github.com/kubernetes/kubernetes。 接下来其余步骤将你的根目录称为 <k8s-base>

确定你的 kubernetes-sigs/reference-docs 代码仓库克隆的根目录。 例如,如果按照前面的步骤获取代码仓库,则你的根目录为 $GOPATH/src/github.com/kubernetes-sigs/reference-docs。 接下来其余步骤将你的根目录称为 <rdocs-base>

编辑 Kubernetes 源代码

Kubernetes API 参考文档是根据 OpenAPI 规范自动生成的,该规范是从 Kubernetes 源代码生成的。 如果要更改 API 参考文档,第一步是更改 Kubernetes 源代码中的一个或多个注释。

kube-* 组件的文档也是从上游源代码生成的。你必须更改与要修复的组件相关的代码,才能修复生成的文档。

更改上游 Kubernetes 源代码

以下在 Kubernetes 源代码中编辑注释的示例。

在你本地的 kubernetes/kubernetes 代码仓库中,检出默认分支,并确保它是最新的:

cd <k8s-base>
git checkout master
git pull https://github.com/kubernetes/kubernetes master

假设默认分支中的下面源文件中包含拼写错误 "atmost":

kubernetes/kubernetes/staging/src/k8s.io/api/apps/v1/types.go

在你的本地环境中,打开 types.go 文件,然后将 "atmost" 更改为 "at most"。

以下命令验证你已经更改了文件:

git status

输出显示你在 master 分支上,types.go 源文件已被修改:

On branch master
...
    modified:   staging/src/k8s.io/api/apps/v1/types.go

提交已编辑的文件

运行 git addgit commit 命令提交到目前为止所做的更改。 在下一步中,你将进行第二次提交,将更改分成两个提交很重要。

生成 OpenAPI 规范和相关文件

进入 <k8s-base> 目录并运行以下脚本:

hack/update-generated-swagger-docs.sh
hack/update-openapi-spec.sh
hack/update-generated-protobuf.sh

运行 git status 命令查看生成的文件。

On branch master
...
    modified:   api/openapi-spec/swagger.json
    modified:   api/openapi-spec/v3/apis__apps__v1_openapi.json
    modified:   pkg/generated/openapi/zz_generated.openapi.go
    modified:   staging/src/k8s.io/api/apps/v1/generated.proto
    modified:   staging/src/k8s.io/api/apps/v1/types_swagger_doc_generated.go

查看 api/openapi-spec/swagger.json 的内容,以确保拼写错误已经被修正。 例如,你可以运行 git diff -a api/openapi-spec/swagger.json 命令。 这很重要,因为 swagger.json 是文档生成过程中第二阶段的输入。

运行 git addgit commit 命令来提交你的更改。现在你有两个提交(commits): 一种包含编辑的 types.go 文件,另一种包含生成的 OpenAPI 规范和相关文件。 将这两个提交分开独立。也就是说,不要 squash 你的提交。

将你的更改作为 PR 提交到 kubernetes/kubernetes 代码仓库的 master 分支。 关注你的 PR,并根据需要回复 reviewer 的评论。继续关注你的 PR,直到 PR 被合并为止。

PR 57758 是修复 Kubernetes 源代码中的拼写错误的拉取请求的示例。

将你的提交 Cherrypick 到发布分支

在上一节中,你在 master 分支中编辑了一个文件,然后运行了脚本用来生成 OpenAPI 规范和相关文件。 然后用 PR 将你的更改提交到 kubernetes/kubernetes 代码仓库的 master 分支中。 现在,需要将你的更改反向移植到已经发布的分支。 例如,假设 master 分支被用来开发 Kubernetes 1.30 版, 并且你想将更改反向移植到 release-1.29 分支。

回想一下,你的 PR 有两个提交:一个用于编辑 types.go,一个用于由脚本生成的文件。 下一步是将你的第一次提交 cherrypick 到 release-1.29 分支。 这样做的原因是仅 cherrypick 编辑了 types.go 的提交, 而不是具有脚本运行结果的提交。 有关说明,请参见提出 Cherry Pick

当你发起 PR 将你的一个提交 cherry pick 到 release-1.29 分支中时, 下一步是在本地环境的 release-1.29 分支中运行如下脚本。

hack/update-generated-swagger-docs.sh
hack/update-openapi-spec.sh
hack/update-generated-protobuf.sh
hack/update-api-reference-docs.sh

现在将提交添加到你的 Cherry-Pick PR 中,该 PR 中包含最新生成的 OpenAPI 规范和相关文件。 关注你的 PR,直到其合并到 release-1.29 分支中为止。

此时,master 分支和 release-1.29 分支都具有更新的 types.go 文件和一组生成的文件, 这些文件反映了对 types.go 所做的更改。 请注意,生成的 OpenAPI 规范和其他 release-1.29 分支中生成的文件不一定与 master 分支中生成的文件相同。 release-1.29 分支中生成的文件仅包含来自 Kubernetes 1.29 的 API 元素。 master 分支中生成的文件可能包含不在 1.29 中但正在为 1.30 开发的 API 元素。

生成已发布的参考文档

上一节显示了如何编辑源文件然后生成多个文件,包括在 kubernetes/kubernetes 代码仓库中的 api/openapi-spec/swagger.jsonswagger.json 文件是 OpenAPI 定义文件,可用于生成 API 参考文档。

现在,你可以按照 生成 Kubernetes API 的参考文档 指南来生成 已发布的 Kubernetes API 参考文档

接下来

6.3 - 为 Kubernetes API 生成参考文档

本页面显示了如何更新 Kubernetes API 参考文档。

Kubernetes API 参考文档是从 Kubernetes OpenAPI 规范 构建的, 且使用kubernetes-sigs/reference-docs 生成代码。

如果你在生成的文档中发现错误,则需要在上游修复

如果你只需要从 OpenAPI 规范中重新生成参考文档,请继续阅读此页。

准备开始

需求

  • 你的 PATH 环境变量必须包含所需要的构建工具,例如 Go 程序和 python

  • 你需要知道如何为一个 GitHub 仓库创建拉取请求(PR)。 这牵涉到创建仓库的派生(fork)副本。 有关信息可进一步查看基于本地副本开展工作

配置本地仓库

创建本地工作区并设置你的 GOPATH

mkdir -p $HOME/<workspace>
export GOPATH=$HOME/<workspace>

获取以下仓库的本地克隆:

go get -u github.com/kubernetes-sigs/reference-docs

go get -u github.com/go-openapi/loads
go get -u github.com/go-openapi/spec

如果你还没有下载过 kubernetes/website 仓库,现在下载:

git clone https://github.com/<your-username>/website $GOPATH/src/github.com/<your-username>/website

克隆 kubernetes/kubernetes 仓库作为 k8s.io/kubernetes:

git clone https://github.com/kubernetes/kubernetes $GOPATH/src/k8s.io/kubernetes
  • kubernetes/kubernetes 仓库克隆后的根目录为 $GOPATH/src/k8s.io/kubernetes。 后续步骤将此目录称为 <k8s-base>
  • kubernetes/website 仓库克隆后的根目录为 $GOPATH/src/github.com/<your username>/website。后续步骤将此目录称为 <web-base>
  • kubernetes-sigs/reference-docs 仓库克隆后的基本目录为 $GOPATH/src/github.com/kubernetes-sigs/reference-docs.。 后续步骤将此目录称为 <rdocs-base>

生成 API 参考文档

本节说明如何生成已发布的 Kubernetes API 参考文档

设置构建变量

  • 设置 K8S_ROOT<k8s-base>.
  • 设置 K8S_WEBROOT<web-base>.
  • 设置 K8S_RELEASE 为要构建的文档的版本。 例如,如果你想为 Kubernetes 1.17.0 构建文档,请将 K8S_RELEASE 设置为 1.17.0。

例如:

export K8S_WEBROOT=${GOPATH}/src/github.com/<your-username>/website
export K8S_ROOT=${GOPATH}/src/k8s.io/kubernetes
export K8S_RELEASE=1.17.0

创建版本目录并复制 OpenAPI 规范

构建目标 updateapispec 负责创建版本化的构建目录。 目录创建了之后,从 <k8s-base> 仓库取回 OpenAPI 规范文件。 这些步骤确保配置文件的版本和 Kubernetes OpenAPI 规范的版本与发行版本匹配。 版本化目录的名称形式为 v<major>_<minor>

<rdocs-base> 目录中,运行以下命令来构建:

cd <rdocs-base>
make updateapispec

构建 API 参考文档

构建目标 copyapi 会生成 API 参考文档并将所生成文件复制到 <web-base 中的目录下。 在 <rdocs-base> 目录中运行以下命令:

cd <rdocs-base>
make copyapi

验证是否已生成这两个文件:

[ -e "<rdocs-base>/gen-apidocs/build/index.html" ] && echo "index.html built" || echo "no index.html"
[ -e "<rdocs-base>/gen-apidocs/build/navData.js" ] && echo "navData.js built" || echo "no navData.js"

进入本地 <web-base> 目录,检查哪些文件被更改:

cd <web-base>
git status

输出类似于:

static/docs/reference/generated/kubernetes-api/v1.26/css/bootstrap.min.css
static/docs/reference/generated/kubernetes-api/v1.26/css/font-awesome.min.css
static/docs/reference/generated/kubernetes-api/v1.26/css/stylesheet.css
static/docs/reference/generated/kubernetes-api/v1.26/fonts/FontAwesome.otf
static/docs/reference/generated/kubernetes-api/v1.26/fonts/fontawesome-webfont.eot
static/docs/reference/generated/kubernetes-api/v1.26/fonts/fontawesome-webfont.svg
static/docs/reference/generated/kubernetes-api/v1.26/fonts/fontawesome-webfont.ttf
static/docs/reference/generated/kubernetes-api/v1.26/fonts/fontawesome-webfont.woff
static/docs/reference/generated/kubernetes-api/v1.26/fonts/fontawesome-webfont.woff2
static/docs/reference/generated/kubernetes-api/v1.26/index.html
static/docs/reference/generated/kubernetes-api/v1.26/js/jquery.scrollTo.min.js
static/docs/reference/generated/kubernetes-api/v1.26/js/navData.js
static/docs/reference/generated/kubernetes-api/v1.26/js/scroll.js

更新 API 参考索引页面

在为新发行版本生成参考文档时,需要更新下面的文件,使之包含新的版本号: <web-base>/content/en/docs/reference/kubernetes-api/api-index.md

  • 打开并编辑 <web-base>/content/en/docs/reference/kubernetes-api/api-index.md, API 参考的版本号。例如:

    title: v1.17
    [Kubernetes API v1.17](/docs/reference/generated/kubernetes-api/v1.17/)
    
  • 打开编辑 <web-base>/content/en/docs/reference/_index.md,添加指向最新 API 参考 的链接,删除最老的 API 版本。 通常保留最近的五个版本的 API 参考的链接。

在本地测试 API 参考

发布 API 参考的本地版本。 检查本地预览

cd <web-base>
git submodule update --init --recursive --depth 1 # if not already done
make container-serve

提交更改

<web-base> 中运行 git addgit commit 来提交更改。

基于你所生成的更改创建 PR, 提交到 kubernetes/website 仓库。 监视你提交的 PR,并根据需要回复 reviewer 的评论。继续监视你的 PR,直到合并为止。

接下来

6.4 - 为 kubectl 命令集生成参考文档

本页面描述了如何生成 kubectl 命令参考。

准备开始

需求

  • 你的 PATH 环境变量必须包含所需要的构建工具,例如 Go 程序和 python

  • 你需要知道如何为一个 GitHub 仓库创建拉取请求(PR)。 这牵涉到创建仓库的派生(fork)副本。 有关信息可进一步查看基于本地副本开展工作

配置本地仓库

创建本地工作区并设置你的 GOPATH

mkdir -p $HOME/<workspace>
export GOPATH=$HOME/<workspace>

获取以下仓库的本地克隆:

go get -u github.com/spf13/pflag
go get -u github.com/spf13/cobra
go get -u gopkg.in/yaml.v2
go get -u kubernetes-incubator/reference-docs

如果你还没有获取过 kubernetes/website 仓库,现在获取之:

git clone https://github.com/<your-username>/website $GOPATH/src/github.com/<your-username>/website

克隆 kubernetes/kubernetes 仓库作为 k8s.io/kubernetes:

git clone https://github.com/kubernetes/kubernetes $GOPATH/src/k8s.io/kubernetes

$GOPATH/src/k8s.io/kubernetes/vendor/github.com 中移除 spf13 软件包。

rm -rf $GOPATH/src/k8s.io/kubernetes/vendor/github.com/spf13

kubernetes/kubernetes 仓库提供对 kubectl 和 kustomize 源代码的访问。

  • 确定 kubernetes/kubernetes 仓库的本地主目录。 例如,如果按照前面的步骤来获取该仓库,则主目录是 $GOPATH/src/k8s.io/kubernetes.。 下文将该目录称为 <k8s-base>
  • 确定 kubernetes/website 仓库的本地主目录。 例如,如果按照前面的步骤来获取该仓库,则主目录是 $GOPATH/src/github.com/<your-username>/website。 下文将该目录称为 <web-base>
  • 确定 kubernetes-sigs/reference-docs 仓库的本地主目录。例如,如果按照前面的步骤来获取该仓库,则主目录是 $GOPATH/src/github.com/kubernetes-sigs/reference-docs。 下文将该目录称为 <rdocs-base>

在本地的 k8s.io/kubernetes 仓库中,检出感兴趣的分支并确保它是最新的。例如, 如果你想要生成 Kubernetes 1.29.0 的文档,可以使用以下命令:

cd <k8s-base>
git checkout v1.29.0
git pull https://github.com/kubernetes/kubernetes 1.29.0

如果不需要编辑 kubectl 源码,请按照说明配置构建变量

编辑 kubectl 源码

kubectl 命令的参考文档是基于 kubectl 源码自动生成的。如果想要修改参考文档,可以从修改 kubectl 源码中的一个或多个注释开始。在本地 kubernetes/kubernetes 仓库中进行修改,然后向 github.com/kubernetes/kubernetes 的 master 分支提交 PR。

PR 56673 是一个对 kubectl 源码中的笔误进行修复的 PR 示例。

跟踪你的 PR,并回应评审人的评论。继续跟踪你的 PR,直到它合入到 kubernetes/kubernetes 仓库的目标分支中。

以 cherry-pick 方式将你的修改合入已发布分支

你的修改已合入 master 分支中,该分支用于开发下一个 Kubernetes 版本。 如果你希望修改部分出现在已发布的 Kubernetes 版本文档中,则需要提议将它们以 cherry-pick 方式合入已发布分支。

例如,假设 master 分支正用于开发 Kubernetes 1.26 版本, 而你希望将修改合入到 release-1.29 版本分支。 相关的操作指南,请参见 提议一个 cherry-pick

跟踪你的 cherry-pick PR,直到它合入到已发布分支中。

设置构建变量

进入 <rdocs-base> 目录, 打开 Makefile 进行编辑:

  • 设置 K8S_ROOT<k8s-base>
  • 设置 K8S_WEBROOT<web-base>
  • 设置 K8S_RELEASE 为要构建文档的版本。 例如,如果你想为 Kubernetes 1.29 构建文档, 请将 K8S_RELEASE 设置为 1.29。

例如:

export K8S_WEBROOT=$(GOPATH)/src/github.com/<your-username>/website
export K8S_ROOT=$(GOPATH)/src/k8s.io/kubernetes
export K8S_RELEASE=1.29

创建版本目录

构建目标 createversiondirs 会生成一个版本目录并将 kubectl 参考配置文件复制到该目录中。 版本目录的名字模式为 v<major>_<minor>

<rdocs-base> 目录下,执行下面的命令:

cd <rdocs-base>
make createversiondirs

从 kubernetes/kubernetes 检出一个分支

在本地 <k8s-base> 仓库中,检出你想要生成文档的、包含 Kubernetes 版本的分支。 例如,如果希望为 Kubernetes 1.29.0 版本生成文档, 请检出 v1.29 标记。 确保本地分支是最新的。

cd <k8s-base>
git checkout v1.29.0
git pull https://github.com/kubernetes/kubernetes v1.29.0

运行文档生成代码

在本地的 <rdocs-base> 目录下,运行 copycli 构建目标。此命令以 root 账号运行:

cd <rdocs-base>
make copycli

copycli 命令将清理暂存目录,生成 kubectl 命令文件,并将整理后的 kubectl 参考 HTML 页面和 文件复制到 <web-base>

找到生成的文件

验证是否已生成以下两个文件:

[ -e "<rdocs-base>/gen-kubectldocs/generators/build/index.html" ] && echo "index.html built" || echo "no index.html"
[ -e "<rdocs-base>/gen-kubectldocs/generators/build/navData.js" ] && echo "navData.js built" || echo "no navData.js"

找到复制的文件

确认所有生成的文件都已复制到你的 <web-base>

cd <web-base>
git status

输出应包括修改后的文件:

static/docs/reference/generated/kubectl/kubectl-commands.html
static/docs/reference/generated/kubectl/navData.js

此外,输出可能还包含:

static/docs/reference/generated/kubectl/scroll.js
static/docs/reference/generated/kubectl/stylesheet.css
static/docs/reference/generated/kubectl/tabvisibility.js
static/docs/reference/generated/kubectl/node_modules/bootstrap/dist/css/bootstrap.min.css
static/docs/reference/generated/kubectl/node_modules/highlight.js/styles/default.css
static/docs/reference/generated/kubectl/node_modules/jquery.scrollto/jquery.scrollTo.min.js
static/docs/reference/generated/kubectl/node_modules/jquery/dist/jquery.min.js
static/docs/reference/generated/kubectl/node_modules/font-awesome/css/font-awesome.min.css

在本地测试文档

在本地 <web-base> 中构建 Kubernetes 文档。

cd <web-base>
git submodule update --init --recursive --depth 1 # if not already done
make container-serve

查看本地预览

在 kubernetes/website 中添加和提交更改

运行 git addgit commit 提交修改文件。

创建 PR

kubernetes/website 仓库创建 PR。跟踪你的 PR,并根据需要回应评审人的评论。 继续跟踪你的 PR,直到它被合入。

在 PR 合入的几分钟后,你更新的参考主题将出现在已发布文档中。

接下来

6.5 - 为 Kubernetes 组件和工具生成参考文档

本页面描述如何构造 Kubernetes 组件和工具的参考文档。

准备开始

阅读参考文档快速入门指南中的准备工作节。

按照参考文档快速入门 指引,生成 Kubernetes 组件和工具的参考文档。

接下来

6.6 -

需求

  • 你的 PATH 环境变量必须包含所需要的构建工具,例如 Go 程序和 python

  • 你需要知道如何为一个 GitHub 仓库创建拉取请求(PR)。 这牵涉到创建仓库的派生(fork)副本。 有关信息可进一步查看基于本地副本开展工作

7 - 文档样式概述

本节的主题是提供有关写作风格、内容格式和组织以及如何使用 特定于 Kubernetes 文档的 Hugo 定制代码的指导。

7.1 - 文档内容指南

本页包含 Kubernetes 文档的一些指南。

如果你不清楚哪些事情是可以做的,请加入到 Kubernetes Slack#sig-docs 频道提问! 你可以在 https://slack.k8s.io 注册到 Kubernetes Slack。

关于为 Kubernetes 文档创建新内容的更多信息, 可参考样式指南

概述

Kubernetes 网站(包括其文档)源代码位于 kubernetes/website 仓库中。

kubernetes/website/content/<语言代码>/docs 目录下, 绝大多数 Kubernetes 文档都是特定于 Kubernetes 项目的。

可以发布的内容

只有当以下条件满足时,Kubernetes 文档才允许第三方项目的内容:

  • 内容所描述的软件在 Kubernetes 项目内
  • 内容所描述的软件不在 Kubernetes 项目内,却是让 Kubernetes 正常工作所必需的
  • 内容是被 kubernetes.io 域名收编的,或者是其他位置的标准典型内容

第三方内容

Kubernetes 文档包含 Kubernetes 项目下的多个项目的应用示例。 这里的 Kubernetes 项目指的是 KubernetesKubernetes SIGs GitHub 组织下的那些项目。

链接到 Kubernetes 项目中活跃的内容是一直允许的。

Kubernetes 需要某些第三方内容才能正常工作。例如容器运行时(containerd、CRI-O、Docker)、 联网策略(CNI 插件)、 Ingress 控制器 以及日志等。

只有对应的第三方开源软件(OSS)是运行 Kubernetes 所必需的, 才可以在文档中包含指向这些 Kubernetes 项目之外的软件的链接。

双重来源的内容

只要有可能,Kubernetes 文档就应该指向标准典型的信息源而不是直接托管双重来源的内容。

双重来源的内容需要双倍(甚至更多)的投入才能维护,而且通常很快就会变得停滞不前。

更多信息

如果你对允许出现的内容有疑问,请加入到 Kubernetes Slack#sig-docs 频道提问!

接下来

7.2 - 文档样式指南

本页讨论 Kubernetes 文档的样式指南。 这些仅仅是指南而不是规则。 你可以自行决定,且欢迎使用 PR 来为此文档提供修改意见。

关于为 Kubernetes 文档贡献新内容的更多信息, 可以参考文档内容指南

样式指南的变更是 SIG Docs 团队集体决定。 如要提议更改或新增条目,请先将其添加到下一次 SIG Docs 例会的议程表上,并按时参加会议讨论。

语言

Kubernetes 文档已经被翻译为多个语种 (参见 本地化 READMEs)。

本地化 Kubernetes 文档描述了如何为一种新的语言提供本地化文档。

英语文档使用美国英语的拼写和语法。

文档格式标准

对 API 对象使用大写驼峰式命名法

当你与指定的 API 对象进行交互时, 使用大写驼峰式命名法, 也被称为帕斯卡拼写法(PascalCase)。 你可以在 API 参考中看到不同的大小写形式,例如 "configMap"。 在编写通用文档时,最好使用大写驼峰形式,将之称作 "ConfigMap"。

通常在讨论 API 对象时,使用 句子式大写

下面的例子关注的是大小写问题。关于如何格式化 API 对象名称的更多信息, 可参考相关的代码风格指南。

使用 Pascal 风格大小写来给出 API 对象的约定
可以不可以
该 HorizontalPodAutoscaler 负责...该 Horizontal pod autoscaler 负责...
每个 PodList 是一个 Pod 组成的列表。每个 Pod List 是一个由 Pod 组成的列表。
该 Volume 对象包含一个 hostPath 字段。此卷对象包含一个 hostPath 字段。
每个 ConfigMap 对象都是某个名字空间的一部分。每个 configMap 对象是某个名字空间的一部分。
要管理机密数据,可以考虑使用 Secret API。要管理机密数据,可以考虑使用秘密 API。

在占位符中使用尖括号

用尖括号表示占位符,让读者知道占位符表示的是什么。例如:

显示有关 Pod 的信息:

kubectl describe pod <Pod 名称> -n <名字空间>

如果名字空间被忽略,默认为 default,你可以省略 '-n' 参数。

用粗体字表现用户界面元素

以粗体表示用户界面元素
可以不可以
点击 Fork点击 "Fork"。
选择 Other选择 "Other"。

定义或引入新术语时使用斜体

新术语约定
可以不可以
每个 集群 是一组节点 ...每个“集群”是一组节点 ...
这些组件构成了 控制面这些组件构成了 控制面

使用代码样式表现文件名、目录和路径

文件名、目录和路径约定
可以不可以
打开 envars.yaml 文件打开 envars.yaml 文件
进入到 /docs/tutorials 目录进入到 /docs/tutorials 目录
打开 /_data/concepts.yaml 文件打开 /_data/concepts.yaml 文件

在引号内使用国际标准标点

标点符号约定
可以不可以
事件记录中都包含对应的“stage”。事件记录中都包含对应的“stage。”
此副本称作一个“fork”。此副本称作一个“fork。”

行间代码格式

为行间代码、命令与 API 对象使用代码样式

对于 HTML 文档中的行间代码,使用 <code> 标记。 在 Markdown 文档中,使用反引号(`)。

行间代码、命令和 API 对象约定
可以不可以
kubectl run 命令会创建一个 Pod"kubectl run" 命令会创建一个 Pod。
每个节点上的 kubelet 都会获得一个 Lease每个节点上的 kubelet 都会获得一个 lease…
一个 PersistentVolume 代表持久存储一个 Persistent Volume 代表持久存储…
在声明式管理中,使用 kubectl apply在声明式管理中,使用 "kubectl apply"。
用三个反引号来(```)标示代码示例用其他语法来标示代码示例。
使用单个反引号来标示行间代码。例如:var example = true使用两个星号(**)或者一个下划线(_)来标示行间代码。例如:var example = true
在多行代码块之前和之后使用三个反引号标示隔离的代码块。使用多行代码块来创建示意图、流程图或者其他表示。
使用符合上下文的有意义的变量名。使用诸如 'foo'、'bar' 和 'baz' 这类无意义且无语境的变量名。
删除代码中行尾空白。在代码中包含行尾空白,因为屏幕抓取工具通常也会抓取空白字符。

为对象字段名和名字空间使用代码风格

对象字段名约定
可以不可以
在配置文件中设置 replicas 字段的值。在配置文件中设置 "replicas" 字段的值。
exec 字段的值是一个 ExecAction 对象。"exec" 字段的值是一个 ExecAction 对象。
kube-system 名字空间中以 DaemonSet 形式运行此进程。在 kube-system 名字空间中以 DaemonSet 形式运行此进程。

用代码样式书写 Kubernetes 命令工具和组件名

Kubernetes 命令工具和组件名
可以不可以
kubelet 维持节点稳定性。kubelet 负责维护节点稳定性。
kubectl 处理 API 服务器的定位和身份认证。kubectl 处理 API 服务器的定位和身份认证。
使用该证书运行进程 kube-apiserver --client-ca-file=FILENAME使用证书运行进程 kube-apiserver --client-ca-file=FILENAME。

用工具或组件名称开始一句话

工具或组件名称使用约定
可以不可以
The kubeadm tool bootstraps and provisions machines in a cluster.kubeadm tool bootstraps and provisions machines in a cluster.
The kube-scheduler is the default scheduler for Kubernetes.kube-scheduler is the default scheduler for Kubernetes.

尽量使用通用描述而不是组件名称

组件名称与通用描述
可以不可以
Kubernetes API 服务器提供 OpenAPI 规范。apiserver 提供 OpenAPI 规范。
聚合 API 是下级 API 服务器。聚合 API 是下级 APIServer。

使用普通样式表达字符串和整数字段值

对于字符串或整数,使用正常样式,不要带引号。

字符串和整数字段值约定
可以不可以
imagePullPolicy 设置为 Always。imagePullPolicy 设置为 "Always"。
image 设置为 nginx:1.16。image 设置为 nginx:1.16
replicas 字段值设置为 2。replicas 字段值设置为 2

引用 Kubernetes API 资源

本节讨论我们如何在文档中引用 API 资源。

有关 “资源” 的阐述

Kubernetes 使用 “resource” 一词来指代 API 资源,例如 poddeployment 等。 我们还使用 “resource” 来谈论 CPU 和内存请求和限制。 所以始终将 API 资源称为 “API resources” 以避免与 CPU 和内存资源混淆。

何时使用 Kubernetes API 术语

不同 Kubernetes API 术语的说明如下:

  • 资源类型:API URL 中使用的名称(如 podsnamespaces
  • 资源:资源类型的单个实例(如 podsecret
  • 对象:作为 “意向记录” 的资源。对象是集群特定部分的期望状态, 该状态由 Kubernetes 控制平面负责维护。

在文档中引用 API 资源时始终使用 “资源” 或 “对象”。 例如,使用 “一个 Secret 对象” 而不是 “一个 Secret”。

API 资源名称

始终使用大写驼峰式命名法 (PascalCase)和代码格式来表达 API 资源名称。

对于 HTML 文档中的内联代码,请使用 <code> 标记。 在 Markdown 文档中,使用反引号 (`)。

不要将 API 对象的名称切分成多个单词。 例如请使用 PodTemplateList 而非 Pod Template List

有关 PascalCase 和代码格式的更多信息, 请查看对 API 对象使用大写驼峰式命名法针对内嵌代码、命令与 API 对象使用代码样式

有关 Kubernetes API 术语的更多信息, 请查看 Kubernetes API 术语的相关指南。

代码段格式

不要包含命令行提示符

命令行提示符约定
可以不可以
kubectl get pods$ kubectl get pods

将命令和输出分开

例如:

验证 Pod 已经在你所选的节点上运行:

kubectl get pods --output=wide

输出类似于:

NAME     READY     STATUS    RESTARTS   AGE    IP           NODE
nginx    1/1       Running   0          13s    10.200.0.4   worker0

为 Kubernetes 示例给出版本

代码示例或者配置示例如果包含版本信息,应该与对应的文字描述一致。

如果所给的信息是特定于具体版本的,需要在 任务模板教程模板prerequisites 小节定义 Kubernetes 版本。 页面保存之后,prerequisites 小节会显示为 开始之前

如果要为任务或教程页面指定 Kubernetes 版本,可以在文件的前言部分包含 min-kubernetes-server-version 信息。

如果示例 YAML 是一个独立文件,找到并审查包含该文件的主题页面。 确认使用该独立 YAML 文件的主题都定义了合适的版本信息。 如果独立的 YAML 文件没有在任何主题中引用,可以考虑删除该文件, 而不是继续更新它。

例如,如果你在编写一个教程,与 Kubernetes 1.8 版本相关。那么你的 Markdown 文件的文件头应该开始起来像这样:

---
title: <教程标题>
min-kubernetes-server-version: v1.8
---

在代码和配置示例中,不要包含其他版本的注释信息。 尤其要小心不要在示例中包含不正确的注释信息,例如:

apiVersion: v1 # 早期版本使用...
kind: Pod
...

Kubernetes.io 术语列表

以下特定于 Kubernetes 的术语和词汇在使用时要保持一致性。

Kubernetes.io 词汇表
术语用法
KubernetesKubernetes 的首字母要保持大写。
DockerDocker 的首字母要保持大写。
SIG DocsSIG Docs 是正确拼写形式,不要用 SIG-DOCS 或其他变体。
On-premisesOn-premises 或 On-prem 而不是 On-premise 或其他变体。

短代码(Shortcodes)

Hugo 短代码(Shortcodes) 有助于创建比较漂亮的展示效果。我们的文档支持三个不同的这类短代码。 注意 {{< note >}}小心 {{< caution >}}警告 {{< warning >}}

  1. 将要突出显示的文字用短代码的开始和结束形式包围。

  2. 使用下面的语法来应用某种样式:

    {{< note >}}
    不需要前缀;短代码会自动添加前缀(注意:、小心:等)
    {{< /note >}}
    

    输出的样子是:

注释(Note)

使用短代码 {{< note >}} 来突出显示某种提示或者有助于读者的信息。

例如:

{{< note >}}
在这类短代码中仍然 _可以_ 使用 Markdown 语法。
{{< /note >}}

输出为:

你可以在列表中使用 {{< note >}}

1. 在列表中使用 note 短代码

1. 带嵌套 note 的第二个条目

   {{< note >}}
   警告、小心和注意短代码可以嵌套在列表中,但是要缩进四个空格。
   参见[常见短代码问题](#common-shortcode-issues)。
   {{< /note >}}

1. 列表中第三个条目

1. 列表中第四个条目

其输出为:

  1. 在列表中使用 note 短代码

  2. 带嵌套 note 的第二个条目

  3. 列表中第三个条目

  4. 列表中第四个条目

小心(Caution)

使用 {{< caution >}} 短代码来引起读者对某段信息的重视,以避免遇到问题。

例如:

{{< caution >}}
此短代码样式仅对标记之上的一行起作用。
{{< /caution >}}

其输出为:

警告(Warning)

使用 {{< warning >}} 来表明危险或者必须要重视的一则信息。

例如:

{{< warning >}}
注意事项
{{< /warning >}}

其输出为:

常见的短代码问题

编号列表

短代码会打乱编号列表的编号,除非你在信息和标志之前都缩进四个空格。

例如:

1. 预热到 350˚F
1. 准备好面糊,倒入烘烤盘
    {{< note >}}给盘子抹上油可以达到最佳效果。{{< /note >}}
1. 烘烤 20 到 25 分钟,或者直到满意为止。

其输出结果为:

  1. 预热到 350˚F
  2. 准备好面糊,倒入烘烤盘
  3. 烘烤 20 到 25 分钟,或者直到满意为止。

Include 语句

如果短代码出现在 include 语境中,会导致网站无法构建。 你必须将他们插入到上级文档中,分别将开始标记和结束标记插入到 include 语句之前和之后。 例如:

{{< note >}}
{{< include "task-tutorial-prereqs.md" >}}
{{< /note >}}

Markdown 元素

换行

使用单一换行符来隔离块级内容,例如标题、列表、图片、代码块以及其他元素。 这里的例外是二级标题,必须有两个换行符。 二级标题紧随一级标题(或标题),中间没有段落或文字。

两行的留白有助于在代码编辑器中查看整个内容的结构组织。

大标题和小标题

访问文档的读者可能会使用屏幕抓取程序或者其他辅助技术。 屏幕抓取器是一种线性输出设备, 它们每次输出页面上的一个条目。 如果页面上内容过多,你可以使用标题来为页面组织结构。 页面的良好结构对所有读者都有帮助,使得他们更容易浏览或者过滤感兴趣的内容。

标题约定
可以不可以
更新页面或博客在前言部分中的标题。使用一级标题。因为 Hugo 会自动将页面前言部分的标题转化为一级标题。
使用编号的标题以便内容组织有一个更有意义的结构。使用四级到六级标题,除非非常有必要这样。如果你要编写的内容有非常多细节,可以尝试拆分成多个不同页面。
在非博客内容页面中使用井号(#使用下划线 ---=== 来标记一级标题。
页面正文中的小标题采用正常语句的大小写。例如:Extend kubectl with plugins页面正文中的小标题采用首字母大写的大标题式样。例如:Extend Kubectl With Plugins
头部的页面标题采用大标题的式样。例如:title: Kubernetes API Server Bypass Risks头部的页面标题采用正常语句的大小写。例如不要使用 title: Kubernetes API server bypass risks

段落

段落约定
可以不可以
尝试不要让段落超出 6 句话。用空格来缩进第一段。例如,段落前面的三个空格⋅⋅⋅会将段落缩进。
使用三个连字符(---)来创建水平线。使用水平线来分隔段落内容。例如,在故事中切换场景或者在上下文中切换主题。使用水平线来装饰页面。
链接约定
可以不可以
插入超级链接时给出它们所链接到的目标内容的上下文。例如:你的机器上某些端口处于开放状态。参见检查所需端口了解更详细信息。使用“点击这里”等模糊的词语。例如:你的机器上某些端口处于打开状态。参见这里了解详细信息。
编写 Markdown 风格的链接:[链接文本](URL)。例如:[Hugo 短代码](/zh-cn/docs/contribute/style/hugo-shortcodes/#table-captions),输出是 Hugo 短代码编写 HTML 风格的超级链接:<a href="/media/examples/link-element-example.css" target="_blank">访问我们的教程!</a>,或者创建会打开新 Tab 页签或新窗口的链接。例如:[网站示例](https://example.com){target="_blank"}

列表

将一组相互关联的内容组织到一个列表中,以便表达这些条目彼此之间有先后顺序或者某种相互关联关系。 当屏幕抓取器遇到列表时,无论该列表是否有序,它会告知用户存在一组枚举的条目。 用户可以使用箭头键来上下移动,浏览列表中条目。 网站导航链接也可以标记成列表条目,因为说到底他们也是一组相互关联的链接而已。

  • 如果列表中一个或者多个条目是完整的句子,则在每个条目末尾添加句号。 出于一致性考虑,一般要么所有条目要么没有条目是完整句子。

  • 在编号列表中,使用数字 1(1.)。

  • 对非排序列表,使用加号(+)、星号(*)、或者减号(-)。

  • 在每个列表之后留一个空行。

  • 对于嵌套的列表,相对缩进四个空格(例如,⋅⋅⋅⋅)。

  • 列表条目可能包含多个段落。每个后续段落都要缩进或者四个空格或者一个制表符。

表格

数据表格的语义用途是呈现表格化的数据。 用户可以快速浏览表格,但屏幕抓取器需要逐行地处理数据。 表格标题可以用来给数据表提供一个描述性的标题。 辅助技术使用 HTML 表格标题元素来在页面结构中辨识表格内容。

内容最佳实践

本节包含一些建议的最佳实践,用来开发清晰、明确一致的文档内容。

使用现在时态

使用现在时态
可以不可以
此命令启动代理。此命令将启动一个代理。

例外:如果需要使用过去时或将来时来表达正确含义时,是可以使用的。

使用主动语态

使用主动语态
可以不可以
你可以使用浏览器来浏览 API。API 可以被使用浏览器来浏览。
YAML 文件给出副本个数。副本个数是在 YAML 文件中给出的。

例外:如果主动语态会导致句子很难构造时,可以使用被动语态。

使用简单直接的语言

使用简单直接的语言。避免不必要的短语,例如说“请”。

使用简单直接语言
可以不可以
要创建 ReplicaSet,...如果你想要创建 ReplicaSet,...
参看配置文件。请自行查看配置文件。
查看 Pod。使用下面的命令,我们将会看到 Pod。

将读者称为“你”

将读者称为“你”
可以不可以
你可以通过 ... 创建一个 Deployment。通过...我们将创建一个 Deployment。
在前面的输出中,你可以看到...在前面的输出中,我们可以看到...

避免拉丁短语

尽可能使用英语而不是拉丁语缩写。

避免拉丁语短语
可以不可以
例如,...e.g., ...
也就是说,...i.e., ...

例外:使用 etc. 表示等等。

应避免的模式

避免使用“我们”

在句子中使用“我们”会让人感到困惑,因为读者可能不知道这里的 “我们”指的是谁。

要避免的模式
可以不可以
版本 1.4 包含了 ...在 1.4 版本中,我们添加了 ...
Kubernetes 为 ... 提供了一项新功能。我们提供了一项新功能...
本页面教你如何使用 Pod。在本页中,我们将会学到如何使用 Pod。

避免使用俚语或行话

对某些读者而言,英语是其外语。 避免使用一些俚语或行话有助于他们更方便的理解内容。

避免使用俚语或行话
可以不可以
Internally, ...Under the hood, ...
Create a new cluster.Turn up a new cluster.

避免关于将来的陈述

要避免对将来作出承诺或暗示。如果你需要讨论的是 Alpha 功能特性, 可以将相关文字放在一个单独的标题下,标示为 Alpha 版本信息。

此规则的一个例外是对未来版本中计划移除的已废弃功能选项的文档。 此类文档的例子之一是已弃用 API 迁移指南

避免使用很快就会过时的表达

避免使用一些很快就会过时的陈述,例如“目前”、“新的”。 今天而言是新的功能,过了几个月之后就不再是新的了。

避免使用很快过时的表达
可以不可以
在版本 1.4 中,...在当前版本中,...
联邦功能特性提供 ...新的联邦功能特性提供 ...

避免使用隐含用户对某技术有一定理解的词汇

避免使用“只是”、“仅仅”、“简单”、“很容易地”、“很简单”这类词汇。 这些词并没有提升文档的价值。

避免无意义词汇的注意事项
可以不可以
在 ... 中包含一个命令只需要在... 中包含一个命令
运行容器 ...只需运行该容器...
你可以移除...你可以很容易地移除...
这些步骤...这些简单的步骤...

接下来

7.3 - 图表指南

本指南为你展示如何创建、编辑和分享基于 Mermaid JavaScript 库的图表。 Mermaid.js 允许你使用简单的、类似于 Markdown 的语法来在 Markdown 文件中生成图表。 你也可以使用 Mermaid 来创建 .svg.png 图片文件,将其添加到你的文档中。

本指南的目标受众是所有希望了解 Mermaid 的用户,以及那些想了解如何创建图表并将其添加到 Kubernetes 文档中的用户。

图 1 概要介绍的是本节所涉及的话题。

flowchart LR subgraph m[Mermaid.js] direction TB S[ ]-.- C[使用 markdown 来
构造图表] --> D[在线
编辑器] end A[为什么图表
很有用] --> m m --> N[3 种创建
图表的方法] N --> T[示例] T --> X[样式
与标题] X --> V[提示] classDef box fill:#fff,stroke:#000,stroke-width:1px,color:#000; classDef spacewhite fill:#ffffff,stroke:#fff,stroke-width:0px,color:#000 class A,C,D,N,X,m,T,V box class S spacewhite %% you can hyperlink Mermaid diagram nodes to a URL using click statements click A "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgc3ViZ3JhcGggbVtNZXJtYWlkLmpzXVxuICAgIGRpcmVjdGlvbiBUQlxuICAgICAgICBTWyBdLS4tXG4gICAgICAgIENbYnVpbGQ8YnI-ZGlhZ3JhbXM8YnI-d2l0aCBtYXJrZG93bl0gLS0-XG4gICAgICAgIERbb24tbGluZTxicj5saXZlIGVkaXRvcl1cbiAgICBlbmRcbiAgICBBW1doeSBhcmUgZGlhZ3JhbXM8YnI-dXNlZnVsP10gLS0-IG1cbiAgICBtIC0tPiBOWzMgeCBtZXRob2RzPGJyPmZvciBjcmVhdGluZzxicj5kaWFncmFtc11cbiAgICBOIC0tPiBUW0V4YW1wbGVzXVxuICAgIFQgLS0-IFhbU3R5bGluZzxicj5hbmQ8YnI-Y2FwdGlvbnNdXG4gICAgWCAtLT4gVltUaXBzXVxuICAgIFxuIFxuICAgIGNsYXNzRGVmIGJveCBmaWxsOiNmZmYsc3Ryb2tlOiMwMDAsc3Ryb2tlLXdpZHRoOjFweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzRGVmIHNwYWNld2hpdGUgZmlsbDojZmZmZmZmLHN0cm9rZTojZmZmLHN0cm9rZS13aWR0aDowcHgsY29sb3I6IzAwMFxuICAgIGNsYXNzIEEsQyxELE4sWCxtLFQsViBib3hcbiAgICBjbGFzcyBTIHNwYWNld2hpdGUiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOnRydWV9" _blank click C "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgc3ViZ3JhcGggbVtNZXJtYWlkLmpzXVxuICAgIGRpcmVjdGlvbiBUQlxuICAgICAgICBTWyBdLS4tXG4gICAgICAgIENbYnVpbGQ8YnI-ZGlhZ3JhbXM8YnI-d2l0aCBtYXJrZG93bl0gLS0-XG4gICAgICAgIERbb24tbGluZTxicj5saXZlIGVkaXRvcl1cbiAgICBlbmRcbiAgICBBW1doeSBhcmUgZGlhZ3JhbXM8YnI-dXNlZnVsP10gLS0-IG1cbiAgICBtIC0tPiBOWzMgeCBtZXRob2RzPGJyPmZvciBjcmVhdGluZzxicj5kaWFncmFtc11cbiAgICBOIC0tPiBUW0V4YW1wbGVzXVxuICAgIFQgLS0-IFhbU3R5bGluZzxicj5hbmQ8YnI-Y2FwdGlvbnNdXG4gICAgWCAtLT4gVltUaXBzXVxuICAgIFxuIFxuICAgIGNsYXNzRGVmIGJveCBmaWxsOiNmZmYsc3Ryb2tlOiMwMDAsc3Ryb2tlLXdpZHRoOjFweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzRGVmIHNwYWNld2hpdGUgZmlsbDojZmZmZmZmLHN0cm9rZTojZmZmLHN0cm9rZS13aWR0aDowcHgsY29sb3I6IzAwMFxuICAgIGNsYXNzIEEsQyxELE4sWCxtLFQsViBib3hcbiAgICBjbGFzcyBTIHNwYWNld2hpdGUiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOnRydWV9" _blank click D "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgc3ViZ3JhcGggbVtNZXJtYWlkLmpzXVxuICAgIGRpcmVjdGlvbiBUQlxuICAgICAgICBTWyBdLS4tXG4gICAgICAgIENbYnVpbGQ8YnI-ZGlhZ3JhbXM8YnI-d2l0aCBtYXJrZG93bl0gLS0-XG4gICAgICAgIERbb24tbGluZTxicj5saXZlIGVkaXRvcl1cbiAgICBlbmRcbiAgICBBW1doeSBhcmUgZGlhZ3JhbXM8YnI-dXNlZnVsP10gLS0-IG1cbiAgICBtIC0tPiBOWzMgeCBtZXRob2RzPGJyPmZvciBjcmVhdGluZzxicj5kaWFncmFtc11cbiAgICBOIC0tPiBUW0V4YW1wbGVzXVxuICAgIFQgLS0-IFhbU3R5bGluZzxicj5hbmQ8YnI-Y2FwdGlvbnNdXG4gICAgWCAtLT4gVltUaXBzXVxuICAgIFxuIFxuICAgIGNsYXNzRGVmIGJveCBmaWxsOiNmZmYsc3Ryb2tlOiMwMDAsc3Ryb2tlLXdpZHRoOjFweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzRGVmIHNwYWNld2hpdGUgZmlsbDojZmZmZmZmLHN0cm9rZTojZmZmLHN0cm9rZS13aWR0aDowcHgsY29sb3I6IzAwMFxuICAgIGNsYXNzIEEsQyxELE4sWCxtLFQsViBib3hcbiAgICBjbGFzcyBTIHNwYWNld2hpdGUiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOnRydWV9" _blank click N "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgc3ViZ3JhcGggbVtNZXJtYWlkLmpzXVxuICAgIGRpcmVjdGlvbiBUQlxuICAgICAgICBTWyBdLS4tXG4gICAgICAgIENbYnVpbGQ8YnI-ZGlhZ3JhbXM8YnI-d2l0aCBtYXJrZG93bl0gLS0-XG4gICAgICAgIERbb24tbGluZTxicj5saXZlIGVkaXRvcl1cbiAgICBlbmRcbiAgICBBW1doeSBhcmUgZGlhZ3JhbXM8YnI-dXNlZnVsP10gLS0-IG1cbiAgICBtIC0tPiBOWzMgeCBtZXRob2RzPGJyPmZvciBjcmVhdGluZzxicj5kaWFncmFtc11cbiAgICBOIC0tPiBUW0V4YW1wbGVzXVxuICAgIFQgLS0-IFhbU3R5bGluZzxicj5hbmQ8YnI-Y2FwdGlvbnNdXG4gICAgWCAtLT4gVltUaXBzXVxuICAgIFxuIFxuICAgIGNsYXNzRGVmIGJveCBmaWxsOiNmZmYsc3Ryb2tlOiMwMDAsc3Ryb2tlLXdpZHRoOjFweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzRGVmIHNwYWNld2hpdGUgZmlsbDojZmZmZmZmLHN0cm9rZTojZmZmLHN0cm9rZS13aWR0aDowcHgsY29sb3I6IzAwMFxuICAgIGNsYXNzIEEsQyxELE4sWCxtLFQsViBib3hcbiAgICBjbGFzcyBTIHNwYWNld2hpdGUiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOnRydWV9" _blank click T "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgc3ViZ3JhcGggbVtNZXJtYWlkLmpzXVxuICAgIGRpcmVjdGlvbiBUQlxuICAgICAgICBTWyBdLS4tXG4gICAgICAgIENbYnVpbGQ8YnI-ZGlhZ3JhbXM8YnI-d2l0aCBtYXJrZG93bl0gLS0-XG4gICAgICAgIERbb24tbGluZTxicj5saXZlIGVkaXRvcl1cbiAgICBlbmRcbiAgICBBW1doeSBhcmUgZGlhZ3JhbXM8YnI-dXNlZnVsP10gLS0-IG1cbiAgICBtIC0tPiBOWzMgeCBtZXRob2RzPGJyPmZvciBjcmVhdGluZzxicj5kaWFncmFtc11cbiAgICBOIC0tPiBUW0V4YW1wbGVzXVxuICAgIFQgLS0-IFhbU3R5bGluZzxicj5hbmQ8YnI-Y2FwdGlvbnNdXG4gICAgWCAtLT4gVltUaXBzXVxuICAgIFxuIFxuICAgIGNsYXNzRGVmIGJveCBmaWxsOiNmZmYsc3Ryb2tlOiMwMDAsc3Ryb2tlLXdpZHRoOjFweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzRGVmIHNwYWNld2hpdGUgZmlsbDojZmZmZmZmLHN0cm9rZTojZmZmLHN0cm9rZS13aWR0aDowcHgsY29sb3I6IzAwMFxuICAgIGNsYXNzIEEsQyxELE4sWCxtLFQsViBib3hcbiAgICBjbGFzcyBTIHNwYWNld2hpdGUiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOnRydWV9" _blank click X "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgc3ViZ3JhcGggbVtNZXJtYWlkLmpzXVxuICAgIGRpcmVjdGlvbiBUQlxuICAgICAgICBTWyBdLS4tXG4gICAgICAgIENbYnVpbGQ8YnI-ZGlhZ3JhbXM8YnI-d2l0aCBtYXJrZG93bl0gLS0-XG4gICAgICAgIERbb24tbGluZTxicj5saXZlIGVkaXRvcl1cbiAgICBlbmRcbiAgICBBW1doeSBhcmUgZGlhZ3JhbXM8YnI-dXNlZnVsP10gLS0-IG1cbiAgICBtIC0tPiBOWzMgeCBtZXRob2RzPGJyPmZvciBjcmVhdGluZzxicj5kaWFncmFtc11cbiAgICBOIC0tPiBUW0V4YW1wbGVzXVxuICAgIFQgLS0-IFhbU3R5bGluZzxicj5hbmQ8YnI-Y2FwdGlvbnNdXG4gICAgWCAtLT4gVltUaXBzXVxuICAgIFxuIFxuICAgIGNsYXNzRGVmIGJveCBmaWxsOiNmZmYsc3Ryb2tlOiMwMDAsc3Ryb2tlLXdpZHRoOjFweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzRGVmIHNwYWNld2hpdGUgZmlsbDojZmZmZmZmLHN0cm9rZTojZmZmLHN0cm9rZS13aWR0aDowcHgsY29sb3I6IzAwMFxuICAgIGNsYXNzIEEsQyxELE4sWCxtLFQsViBib3hcbiAgICBjbGFzcyBTIHNwYWNld2hpdGUiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOnRydWV9" _blank click V "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgc3ViZ3JhcGggbVtNZXJtYWlkLmpzXVxuICAgIGRpcmVjdGlvbiBUQlxuICAgICAgICBTWyBdLS4tXG4gICAgICAgIENbYnVpbGQ8YnI-ZGlhZ3JhbXM8YnI-d2l0aCBtYXJrZG93bl0gLS0-XG4gICAgICAgIERbb24tbGluZTxicj5saXZlIGVkaXRvcl1cbiAgICBlbmRcbiAgICBBW1doeSBhcmUgZGlhZ3JhbXM8YnI-dXNlZnVsP10gLS0-IG1cbiAgICBtIC0tPiBOWzMgeCBtZXRob2RzPGJyPmZvciBjcmVhdGluZzxicj5kaWFncmFtc11cbiAgICBOIC0tPiBUW0V4YW1wbGVzXVxuICAgIFQgLS0-IFhbU3R5bGluZzxicj5hbmQ8YnI-Y2FwdGlvbnNdXG4gICAgWCAtLT4gVltUaXBzXVxuICAgIFxuIFxuICAgIGNsYXNzRGVmIGJveCBmaWxsOiNmZmYsc3Ryb2tlOiMwMDAsc3Ryb2tlLXdpZHRoOjFweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzRGVmIHNwYWNld2hpdGUgZmlsbDojZmZmZmZmLHN0cm9rZTojZmZmLHN0cm9rZS13aWR0aDowcHgsY29sb3I6IzAwMFxuICAgIGNsYXNzIEEsQyxELE4sWCxtLFQsViBib3hcbiAgICBjbGFzcyBTIHNwYWNld2hpdGUiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOnRydWV9" _blank

图 1. 本节中涉及的话题。

开始使用 Mermaid 之前,你需要以下准备:

你为什么应该在代码中使用图表

图表可以增进文档的清晰度,便于理解。对于用户和贡献者而言都有好处。

用户获得的好处有:

  • 较为友好的初次体验:非常详尽的、只包含文本的欢迎页面对用户而言是蛮恐怖的, 尤其是初次接触 Kubernetes 的用户。
  • 快速理解概念:图表可以帮助用户理解复杂主题下的要点。 你的图表可以作为一种可视化的学习指南,将用户带入主题的细节。
  • 便于记忆:对某些人而言,图形(图像)要比文字更容易记忆。

对贡献者而言的好处有:

  • 帮助确立所贡献文档的结构和内容。例如, 你可以先提供一个覆盖所有顶层要点的图表,然后再逐步展开细节。
  • 培养用户社区并提升其能力。容易理解的文档,附以图表,能够吸引新的用户, 尤其是那些因为预见到复杂性而不愿参与的用户。

你需要考虑你的目标受众。除了一些有经验的 Kubernetes 用户外,你还会遇到很多刚接触 Kubernetes 的用户。即使一张简单的图表也可以帮助新用户吸收 Kubernetes 概念。 他们会变得更为大胆和自信,进一步地了解 Kubernetes 及其文档。

Mermaid

Mermaid 是一个开源的 JavaScript 库, 可以帮助你创建、编辑并很容易地分享图表。这些图表使用简单的、类似 Markdown 的语法开发,并可内嵌到 Markdown 文件中。

下面是 Mermaid 的一些特性:

  • 简单的编码语法
  • 包含基于 Web 的工具,便于你编制和预览你的图表
  • 支持包括流程图、状态图、时序图在内的多种格式
  • 可以通过共享图表的 URL 来与同事方便地合作
  • 有丰富的形状、线条、主题和样式可供选择

使用 Mermaid 的一些好处如下:

  • 不需要使用另外的、非 Mermaid 的图表工具
  • 与现有的 PR 工作流结合的很好。你可以将 Mermaid 代码视为你的 PR 中所包含的 Markdown 文本
  • 简单的工具生成简单的图表。你不需要精心制作或雕琢过于复杂或详尽的图片。 保持简单就好。

Mermaid 提供一种简单的、开放且透明的方法,便于 SIG 社区为新的或现有的文档添加、 编辑图表并展开协作。

在线编辑器

Mermaid 在线编辑器是一个基于 Web 的工具,允许你创建、编辑和审阅图表。

在线编辑器的功能主要有:

  • 显示 Mermaid 代码和渲染的图表。
  • 为所保存的每个图表生成一个 URL。该 URL 显示在你的浏览器的 URL 字段中。 你可以将 URL 分享给同事,便于他人访问和更改图表。
  • 提供将图表下载为 .svg.png 文件的选项。

创建图表的方法

图 2 给出三种生成和添加图表的方法。

graph TB A[贡献者] B[向 .md 文件

中内嵌
Mermaid 代码] C[Mermaid+SVG

将 Mermaid 所生成的
SVG 文件添加到 .md 文件] D[外部工具

添加外部工具
所生成的 SVG
文件到 .md 文件] A --> B A --> C A --> D classDef box fill:#fff,stroke:#000,stroke-width:1px,color:#000; class A,B,C,D box %% 你可以使用 click 语句为 Mermaid 节点设置指向某 URL 的超链接 click A "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggVEJcbiAgICBBW0NvbnRyaWJ1dG9yXVxuICAgIEJbSW5saW5lPGJyPjxicj5NZXJtYWlkIGNvZGU8YnI-YWRkZWQgdG8gLm1kIGZpbGVdXG4gICAgQ1tNZXJtYWlkK1NWRzxicj48YnI-QWRkIG1lcm1haWQtZ2VuZXJhdGVkPGJyPnN2ZyBmaWxlIHRvIC5tZCBmaWxlXVxuICAgIERbRXh0ZXJuYWwgdG9vbDxicj48YnI-QWRkIGV4dGVybmFsLXRvb2wtPGJyPmdlbmVyYXRlZCBzdmcgZmlsZTxicj50byAubWQgZmlsZV1cblxuICAgIEEgLS0-IEJcbiAgICBBIC0tPiBDXG4gICAgQSAtLT4gRFxuXG4gICAgY2xhc3NEZWYgYm94IGZpbGw6I2ZmZixzdHJva2U6IzAwMCxzdHJva2Utd2lkdGg6MXB4LGNvbG9yOiMwMDA7XG4gICAgY2xhc3MgQSxCLEMsRCBib3giLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ" _blank click B "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggVEJcbiAgICBBW0NvbnRyaWJ1dG9yXVxuICAgIEJbSW5saW5lPGJyPjxicj5NZXJtYWlkIGNvZGU8YnI-YWRkZWQgdG8gLm1kIGZpbGVdXG4gICAgQ1tNZXJtYWlkK1NWRzxicj48YnI-QWRkIG1lcm1haWQtZ2VuZXJhdGVkPGJyPnN2ZyBmaWxlIHRvIC5tZCBmaWxlXVxuICAgIERbRXh0ZXJuYWwgdG9vbDxicj48YnI-QWRkIGV4dGVybmFsLXRvb2wtPGJyPmdlbmVyYXRlZCBzdmcgZmlsZTxicj50byAubWQgZmlsZV1cblxuICAgIEEgLS0-IEJcbiAgICBBIC0tPiBDXG4gICAgQSAtLT4gRFxuXG4gICAgY2xhc3NEZWYgYm94IGZpbGw6I2ZmZixzdHJva2U6IzAwMCxzdHJva2Utd2lkdGg6MXB4LGNvbG9yOiMwMDA7XG4gICAgY2xhc3MgQSxCLEMsRCBib3giLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ" _blank click C "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggVEJcbiAgICBBW0NvbnRyaWJ1dG9yXVxuICAgIEJbSW5saW5lPGJyPjxicj5NZXJtYWlkIGNvZGU8YnI-YWRkZWQgdG8gLm1kIGZpbGVdXG4gICAgQ1tNZXJtYWlkK1NWRzxicj48YnI-QWRkIG1lcm1haWQtZ2VuZXJhdGVkPGJyPnN2ZyBmaWxlIHRvIC5tZCBmaWxlXVxuICAgIERbRXh0ZXJuYWwgdG9vbDxicj48YnI-QWRkIGV4dGVybmFsLXRvb2wtPGJyPmdlbmVyYXRlZCBzdmcgZmlsZTxicj50byAubWQgZmlsZV1cblxuICAgIEEgLS0-IEJcbiAgICBBIC0tPiBDXG4gICAgQSAtLT4gRFxuXG4gICAgY2xhc3NEZWYgYm94IGZpbGw6I2ZmZixzdHJva2U6IzAwMCxzdHJva2Utd2lkdGg6MXB4LGNvbG9yOiMwMDA7XG4gICAgY2xhc3MgQSxCLEMsRCBib3giLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ" _blank click D "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggVEJcbiAgICBBW0NvbnRyaWJ1dG9yXVxuICAgIEJbSW5saW5lPGJyPjxicj5NZXJtYWlkIGNvZGU8YnI-YWRkZWQgdG8gLm1kIGZpbGVdXG4gICAgQ1tNZXJtYWlkK1NWRzxicj48YnI-QWRkIG1lcm1haWQtZ2VuZXJhdGVkPGJyPnN2ZyBmaWxlIHRvIC5tZCBmaWxlXVxuICAgIERbRXh0ZXJuYWwgdG9vbDxicj48YnI-QWRkIGV4dGVybmFsLXRvb2wtPGJyPmdlbmVyYXRlZCBzdmcgZmlsZTxicj50byAubWQgZmlsZV1cblxuICAgIEEgLS0-IEJcbiAgICBBIC0tPiBDXG4gICAgQSAtLT4gRFxuXG4gICAgY2xhc3NEZWYgYm94IGZpbGw6I2ZmZixzdHJva2U6IzAwMCxzdHJva2Utd2lkdGg6MXB4LGNvbG9yOiMwMDA7XG4gICAgY2xhc3MgQSxCLEMsRCBib3giLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ" _blank

图 2. 创建图表的方法

内嵌(Inline)

图 3 给出的是使用内嵌方法来添加图表所遵循的步骤。

graph LR A[1. 使用在线编辑器
来创建或编辑
图表] --> B[2. 将图表的 URL
保存到某处] --> C[3. 将 Mermaid 代码
复制到 markdown 文件中] --> D[4. 添加图表标题] classDef box fill:#fff,stroke:#000,stroke-width:1px,color:#000; class A,B,C,D box %% 你可以使用 click 语句为 Mermaid 节点设置指向某 URL 的超链接 click A "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggTFJcbiAgICBBWzEuIFVzZSBsaXZlIGVkaXRvcjxicj4gdG8gY3JlYXRlL2VkaXQ8YnI-ZGlhZ3JhbV0gLS0-XG4gICAgQlsyLiBTdG9yZSBkaWFncmFtPGJyPlVSTCBzb21ld2hlcmVdIC0tPlxuICAgIENbMy4gQ29weSBNZXJtYWlkIGNvZGU8YnI-dG8gcGFnZSBtYXJrZG93biBmaWxlXSAtLT5cbiAgICBEWzQuIEFkZCBjYXB0aW9uXVxuIFxuXG4gICAgY2xhc3NEZWYgYm94IGZpbGw6I2ZmZixzdHJva2U6IzAwMCxzdHJva2Utd2lkdGg6MXB4LGNvbG9yOiMwMDA7XG4gICAgY2xhc3MgQSxCLEMsRCBib3hcbiAgICAiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ" _blank click B "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggTFJcbiAgICBBWzEuIFVzZSBsaXZlIGVkaXRvcjxicj4gdG8gY3JlYXRlL2VkaXQ8YnI-ZGlhZ3JhbV0gLS0-XG4gICAgQlsyLiBTdG9yZSBkaWFncmFtPGJyPlVSTCBzb21ld2hlcmVdIC0tPlxuICAgIENbMy4gQ29weSBNZXJtYWlkIGNvZGU8YnI-dG8gcGFnZSBtYXJrZG93biBmaWxlXSAtLT5cbiAgICBEWzQuIEFkZCBjYXB0aW9uXVxuIFxuXG4gICAgY2xhc3NEZWYgYm94IGZpbGw6I2ZmZixzdHJva2U6IzAwMCxzdHJva2Utd2lkdGg6MXB4LGNvbG9yOiMwMDA7XG4gICAgY2xhc3MgQSxCLEMsRCBib3hcbiAgICAiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ" _blank click C "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggTFJcbiAgICBBWzEuIFVzZSBsaXZlIGVkaXRvcjxicj4gdG8gY3JlYXRlL2VkaXQ8YnI-ZGlhZ3JhbV0gLS0-XG4gICAgQlsyLiBTdG9yZSBkaWFncmFtPGJyPlVSTCBzb21ld2hlcmVdIC0tPlxuICAgIENbMy4gQ29weSBNZXJtYWlkIGNvZGU8YnI-dG8gcGFnZSBtYXJrZG93biBmaWxlXSAtLT5cbiAgICBEWzQuIEFkZCBjYXB0aW9uXVxuIFxuXG4gICAgY2xhc3NEZWYgYm94IGZpbGw6I2ZmZixzdHJva2U6IzAwMCxzdHJva2Utd2lkdGg6MXB4LGNvbG9yOiMwMDA7XG4gICAgY2xhc3MgQSxCLEMsRCBib3hcbiAgICAiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ" _blank click D "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggTFJcbiAgICBBWzEuIFVzZSBsaXZlIGVkaXRvcjxicj4gdG8gY3JlYXRlL2VkaXQ8YnI-ZGlhZ3JhbV0gLS0-XG4gICAgQlsyLiBTdG9yZSBkaWFncmFtPGJyPlVSTCBzb21ld2hlcmVdIC0tPlxuICAgIENbMy4gQ29weSBNZXJtYWlkIGNvZGU8YnI-dG8gcGFnZSBtYXJrZG93biBmaWxlXSAtLT5cbiAgICBEWzQuIEFkZCBjYXB0aW9uXVxuIFxuXG4gICAgY2xhc3NEZWYgYm94IGZpbGw6I2ZmZixzdHJva2U6IzAwMCxzdHJva2Utd2lkdGg6MXB4LGNvbG9yOiMwMDA7XG4gICAgY2xhc3MgQSxCLEMsRCBib3hcbiAgICAiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ" _blank

图 3. 内嵌方法的步骤

下面是使用内嵌方法来添加图表时你要执行的步骤:

  1. 使用在线编辑器创建你的图表
  2. 将图表的 URL 保存在某处以便以后访问
  3. 将 Mermaid 代码复制到你的 .md 文件中你希望它出现的位置
  4. 使用 Markdown 文本在图表下方为其添加标题

Hugo 在构造(网站)过程中会运行 Mermaid 代码,将其转换为图表。

下面是一段包含在某 .md 文件中的示例代码片段:

---
title: 我的文档
---
图 17 给出从 A 到 B 的一个简单流程。
这里是其他 markdown 文本
...
{{< mermaid >}} 
    graph TB
    A --> B
{{< /mermaid >}}

图 17. 从 A 到 B

其他文本

有关添加图表标题的细节,参阅如何使用标题

使用内嵌方法的好处有:

  • 可以直接使用在线编辑器工具
  • 很容易在在线编辑器与你的 .md 文件之间来回复制 Mermaid 代码
  • 不需要额外处理 .svg 图片文件
  • 内容文字、图表代码和图表标题都位于同一个 .md 文件中。

你应该使用本地和 Netlify 预览来验证图表是可以正常渲染的。

Mermaid+SVG

图 4 给出的是使用 Mermaid+SVG 方法添加图表所要遵循的步骤:

flowchart LR A[1. 使用在线编辑器
创建或编辑
图表] B[2. 将图表的 URL
保存到别处] C[3. 生成 .svg 文件
并将其下载到
images/ 目录] subgraph w[ ] direction TB D[4. 使用 figure 短代码
来在 .md 文件中
引用 .svg 文件] --> E[5. 添加图表标题] end A --> B B --> C C --> w classDef box fill:#fff,stroke:#000,stroke-width:1px,color:#000; class A,B,C,D,E,w box click A "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVsxLiBVc2UgbGl2ZSBlZGl0b3I8YnI-IHRvIGNyZWF0ZS9lZGl0PGJyPmRpYWdyYW1dXG4gICAgQlsyLiBTdG9yZSBkaWFncmFtPGJyPlVSTCBzb21ld2hlcmVdXG4gICAgQ1szLiBHZW5lcmF0ZSAuc3ZnIGZpbGU8YnI-YW5kIGRvd25sb2FkIHRvPGJyPmltYWdlcy8gZm9sZGVyXVxuICAgIHN1YmdyYXBoIHdbIF1cbiAgICBkaXJlY3Rpb24gVEJcbiAgICBEWzQuIFVzZSBmaWd1cmUgc2hvcnRjb2RlPGJyPnRvIHJlZmVyZW5jZSAuc3ZnPGJyPmZpbGUgaW4gcGFnZTxicj4ubWQgZmlsZV0gLS0-XG4gICAgRVs1LiBBZGQgY2FwdGlvbl1cbiAgICBlbmRcbkEgLS0-IEJcbkIgLS0-IENcbkMgLS0-IHdcblxuICAgIGNsYXNzRGVmIGJveCBmaWxsOiNmZmYsc3Ryb2tlOiMwMDAsc3Ryb2tlLXdpZHRoOjFweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzIEEsQixDLEQsRSx3IGJveFxuICAgICIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6dHJ1ZX0" _blank click B "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVsxLiBVc2UgbGl2ZSBlZGl0b3I8YnI-IHRvIGNyZWF0ZS9lZGl0PGJyPmRpYWdyYW1dXG4gICAgQlsyLiBTdG9yZSBkaWFncmFtPGJyPlVSTCBzb21ld2hlcmVdXG4gICAgQ1szLiBHZW5lcmF0ZSAuc3ZnIGZpbGU8YnI-YW5kIGRvd25sb2FkIHRvPGJyPmltYWdlcy8gZm9sZGVyXVxuICAgIHN1YmdyYXBoIHdbIF1cbiAgICBkaXJlY3Rpb24gVEJcbiAgICBEWzQuIFVzZSBmaWd1cmUgc2hvcnRjb2RlPGJyPnRvIHJlZmVyZW5jZSAuc3ZnPGJyPmZpbGUgaW4gcGFnZTxicj4ubWQgZmlsZV0gLS0-XG4gICAgRVs1LiBBZGQgY2FwdGlvbl1cbiAgICBlbmRcbkEgLS0-IEJcbkIgLS0-IENcbkMgLS0-IHdcblxuICAgIGNsYXNzRGVmIGJveCBmaWxsOiNmZmYsc3Ryb2tlOiMwMDAsc3Ryb2tlLXdpZHRoOjFweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzIEEsQixDLEQsRSx3IGJveFxuICAgICIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6dHJ1ZX0" _blank click C "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVsxLiBVc2UgbGl2ZSBlZGl0b3I8YnI-IHRvIGNyZWF0ZS9lZGl0PGJyPmRpYWdyYW1dXG4gICAgQlsyLiBTdG9yZSBkaWFncmFtPGJyPlVSTCBzb21ld2hlcmVdXG4gICAgQ1szLiBHZW5lcmF0ZSAuc3ZnIGZpbGU8YnI-YW5kIGRvd25sb2FkIHRvPGJyPmltYWdlcy8gZm9sZGVyXVxuICAgIHN1YmdyYXBoIHdbIF1cbiAgICBkaXJlY3Rpb24gVEJcbiAgICBEWzQuIFVzZSBmaWd1cmUgc2hvcnRjb2RlPGJyPnRvIHJlZmVyZW5jZSAuc3ZnPGJyPmZpbGUgaW4gcGFnZTxicj4ubWQgZmlsZV0gLS0-XG4gICAgRVs1LiBBZGQgY2FwdGlvbl1cbiAgICBlbmRcbkEgLS0-IEJcbkIgLS0-IENcbkMgLS0-IHdcblxuICAgIGNsYXNzRGVmIGJveCBmaWxsOiNmZmYsc3Ryb2tlOiMwMDAsc3Ryb2tlLXdpZHRoOjFweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzIEEsQixDLEQsRSx3IGJveFxuICAgICIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6dHJ1ZX0" _blank click D "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVsxLiBVc2UgbGl2ZSBlZGl0b3I8YnI-IHRvIGNyZWF0ZS9lZGl0PGJyPmRpYWdyYW1dXG4gICAgQlsyLiBTdG9yZSBkaWFncmFtPGJyPlVSTCBzb21ld2hlcmVdXG4gICAgQ1szLiBHZW5lcmF0ZSAuc3ZnIGZpbGU8YnI-YW5kIGRvd25sb2FkIHRvPGJyPmltYWdlcy8gZm9sZGVyXVxuICAgIHN1YmdyYXBoIHdbIF1cbiAgICBkaXJlY3Rpb24gVEJcbiAgICBEWzQuIFVzZSBmaWd1cmUgc2hvcnRjb2RlPGJyPnRvIHJlZmVyZW5jZSAuc3ZnPGJyPmZpbGUgaW4gcGFnZTxicj4ubWQgZmlsZV0gLS0-XG4gICAgRVs1LiBBZGQgY2FwdGlvbl1cbiAgICBlbmRcbkEgLS0-IEJcbkIgLS0-IENcbkMgLS0-IHdcblxuICAgIGNsYXNzRGVmIGJveCBmaWxsOiNmZmYsc3Ryb2tlOiMwMDAsc3Ryb2tlLXdpZHRoOjFweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzIEEsQixDLEQsRSx3IGJveFxuICAgICIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6dHJ1ZX0" _blank click E "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVsxLiBVc2UgbGl2ZSBlZGl0b3I8YnI-IHRvIGNyZWF0ZS9lZGl0PGJyPmRpYWdyYW1dXG4gICAgQlsyLiBTdG9yZSBkaWFncmFtPGJyPlVSTCBzb21ld2hlcmVdXG4gICAgQ1szLiBHZW5lcmF0ZSAuc3ZnIGZpbGU8YnI-YW5kIGRvd25sb2FkIHRvPGJyPmltYWdlcy8gZm9sZGVyXVxuICAgIHN1YmdyYXBoIHdbIF1cbiAgICBkaXJlY3Rpb24gVEJcbiAgICBEWzQuIFVzZSBmaWd1cmUgc2hvcnRjb2RlPGJyPnRvIHJlZmVyZW5jZSAuc3ZnPGJyPmZpbGUgaW4gcGFnZTxicj4ubWQgZmlsZV0gLS0-XG4gICAgRVs1LiBBZGQgY2FwdGlvbl1cbiAgICBlbmRcbkEgLS0-IEJcbkIgLS0-IENcbkMgLS0-IHdcblxuICAgIGNsYXNzRGVmIGJveCBmaWxsOiNmZmYsc3Ryb2tlOiMwMDAsc3Ryb2tlLXdpZHRoOjFweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzIEEsQixDLEQsRSx3IGJveFxuICAgICIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6dHJ1ZX0" _blank

图 4. Mermaid+SVG 方法的步骤。

使用 Mermaid+SVG 方法来添加图表时你要遵从的步骤:

  1. 使用在线编辑器创建你的图表
  2. 将图表的 URL 保存到某处以便以后访问
  3. 为你的图表生成 .svg 文件,并将其下载到合适的 images/ 目录下
  4. 使用 {{< figure >}} 短代码在 .md 文件中引用该图表
  5. 使用 {{< figure >}} 短代码的 caption 参数为图表设置标题

例如,使用在线编辑器创建一个名为 boxnet 的图表。 将图表的 URL 保存到别处以便以后访问。生成 boxnet.svg 文件并将其下载到合适的 ../images/ 目录下。

在你的 PR 中的 .md 文件内使用 {{< figure >}} 短代码来引用 .svg 图片文件,并为之添加标题。

{{< figure src="/static/images/boxnet.svg" alt="Boxnet 示意图" class="diagram-large" caption="图 14. Boxnet 标题" >}}

关于图表标题的细节,可参阅如何使用标题

你应该使用文本编辑器以注释块的形式在 .svg 图片文件中添加在线编辑器的 URL。 例如,你应该在 .svg 图片文件的开头部分包含下面的内容:

<!-- 要查看或者编辑 Mermaid 代码,可访问下面的 URL:-->
<!-- https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb ... <URL 的其余部分> -->

使用 Mermaid+SVG 方法的好处有:

  • 可以直接使用在线编辑器工具
  • 在线编辑器支持的 Mermaid 特性集合最新
  • 可以利用 K8s 网站用来处理 .svg 图片文件的现有方法
  • 工作环境不需要 Mermaid 支持

要使用本地和 Netlify 预览来检查你的图表可以正常渲染。

外部工具

图 5 给出使用外部工具来添加图表时所遵循的步骤。

首先,要使用你的外部工具来创建图表,并将其保存为一个 .svg 文件或 .png 图片文件。 之后,使用 Mermaid+SVG 方法中相同的步骤添加 .svg.png)文件。

flowchart LR A[1. 使用外部工具
来创建或编辑
图表] B[2. 如果可能保存
图表位置供
其他贡献者访问] C[3. 生成 .svg 文件
或 .png 文件
并将其下载到
合适的 images/ 目录] subgraph w[ ] direction TB D[4. 使用 figure 短代码
在你的 .md 文件中
引用该 SVG 或 PNG
文件] --> E[5. 为图表添加标题] end A --> B B --> C C --> w classDef box fill:#fff,stroke:#000,stroke-width:1px,color:#000; class A,B,C,D,E,w box click A "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVsxLiBVc2UgZXh0ZXJuYWw8YnI-dG9vbCB0byBjcmVhdGUvZWRpdDxicj5kaWFncmFtXVxuICAgIEJbMi4gSWYgcG9zc2libGUsIHNhdmU8YnI-ZGlhZ3JhbSBjb29yZGluYXRlczxicj5mb3IgY29udHJpYnV0b3I8YnI-YWNjZXNzXVxuICAgIENbMy4gR2VuZXJhdGUgLnN2ZyA8YnI-b3IucG5nIGZpbGU8YnI-YW5kIGRvd25sb2FkIHRvPGJyPmFwcHJvcHJpYXRlPGJyPmltYWdlcy8gZm9sZGVyXVxuICAgIHN1YmdyYXBoIHdbIF1cbiAgICBkaXJlY3Rpb24gVEJcbiAgICBEWzQuIFVzZSBmaWd1cmUgc2hvcnRjb2RlPGJyPnRvIHJlZmVyZW5jZSBzdmcgb3I8YnI-cG5nIGZpbGUgaW48YnI-cGFnZSAubWQgZmlsZV0gLS0-XG4gICAgRVs1LiBBZGQgY2FwdGlvbl1cbiAgICBlbmRcbiAgICBBIC0tPiBCXG4gICAgQiAtLT4gQ1xuICAgIEMgLS0-IHdcbiAgICBjbGFzc0RlZiBib3ggZmlsbDojZmZmLHN0cm9rZTojMDAwLHN0cm9rZS13aWR0aDoxcHgsY29sb3I6IzAwMDtcbiAgICBjbGFzcyBBLEIsQyxELEUsdyBib3hcbiAgICAiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ" click B "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVsxLiBVc2UgZXh0ZXJuYWw8YnI-dG9vbCB0byBjcmVhdGUvZWRpdDxicj5kaWFncmFtXVxuICAgIEJbMi4gSWYgcG9zc2libGUsIHNhdmU8YnI-ZGlhZ3JhbSBjb29yZGluYXRlczxicj5mb3IgY29udHJpYnV0b3I8YnI-YWNjZXNzXVxuICAgIENbMy4gR2VuZXJhdGUgLnN2ZyA8YnI-b3IucG5nIGZpbGU8YnI-YW5kIGRvd25sb2FkIHRvPGJyPmFwcHJvcHJpYXRlPGJyPmltYWdlcy8gZm9sZGVyXVxuICAgIHN1YmdyYXBoIHdbIF1cbiAgICBkaXJlY3Rpb24gVEJcbiAgICBEWzQuIFVzZSBmaWd1cmUgc2hvcnRjb2RlPGJyPnRvIHJlZmVyZW5jZSBzdmcgb3I8YnI-cG5nIGZpbGUgaW48YnI-cGFnZSAubWQgZmlsZV0gLS0-XG4gICAgRVs1LiBBZGQgY2FwdGlvbl1cbiAgICBlbmRcbiAgICBBIC0tPiBCXG4gICAgQiAtLT4gQ1xuICAgIEMgLS0-IHdcbiAgICBjbGFzc0RlZiBib3ggZmlsbDojZmZmLHN0cm9rZTojMDAwLHN0cm9rZS13aWR0aDoxcHgsY29sb3I6IzAwMDtcbiAgICBjbGFzcyBBLEIsQyxELEUsdyBib3hcbiAgICAiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ" click C "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVsxLiBVc2UgZXh0ZXJuYWw8YnI-dG9vbCB0byBjcmVhdGUvZWRpdDxicj5kaWFncmFtXVxuICAgIEJbMi4gSWYgcG9zc2libGUsIHNhdmU8YnI-ZGlhZ3JhbSBjb29yZGluYXRlczxicj5mb3IgY29udHJpYnV0b3I8YnI-YWNjZXNzXVxuICAgIENbMy4gR2VuZXJhdGUgLnN2ZyA8YnI-b3IucG5nIGZpbGU8YnI-YW5kIGRvd25sb2FkIHRvPGJyPmFwcHJvcHJpYXRlPGJyPmltYWdlcy8gZm9sZGVyXVxuICAgIHN1YmdyYXBoIHdbIF1cbiAgICBkaXJlY3Rpb24gVEJcbiAgICBEWzQuIFVzZSBmaWd1cmUgc2hvcnRjb2RlPGJyPnRvIHJlZmVyZW5jZSBzdmcgb3I8YnI-cG5nIGZpbGUgaW48YnI-cGFnZSAubWQgZmlsZV0gLS0-XG4gICAgRVs1LiBBZGQgY2FwdGlvbl1cbiAgICBlbmRcbiAgICBBIC0tPiBCXG4gICAgQiAtLT4gQ1xuICAgIEMgLS0-IHdcbiAgICBjbGFzc0RlZiBib3ggZmlsbDojZmZmLHN0cm9rZTojMDAwLHN0cm9rZS13aWR0aDoxcHgsY29sb3I6IzAwMDtcbiAgICBjbGFzcyBBLEIsQyxELEUsdyBib3hcbiAgICAiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ" click D "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVsxLiBVc2UgZXh0ZXJuYWw8YnI-dG9vbCB0byBjcmVhdGUvZWRpdDxicj5kaWFncmFtXVxuICAgIEJbMi4gSWYgcG9zc2libGUsIHNhdmU8YnI-ZGlhZ3JhbSBjb29yZGluYXRlczxicj5mb3IgY29udHJpYnV0b3I8YnI-YWNjZXNzXVxuICAgIENbMy4gR2VuZXJhdGUgLnN2ZyA8YnI-b3IucG5nIGZpbGU8YnI-YW5kIGRvd25sb2FkIHRvPGJyPmFwcHJvcHJpYXRlPGJyPmltYWdlcy8gZm9sZGVyXVxuICAgIHN1YmdyYXBoIHdbIF1cbiAgICBkaXJlY3Rpb24gVEJcbiAgICBEWzQuIFVzZSBmaWd1cmUgc2hvcnRjb2RlPGJyPnRvIHJlZmVyZW5jZSBzdmcgb3I8YnI-cG5nIGZpbGUgaW48YnI-cGFnZSAubWQgZmlsZV0gLS0-XG4gICAgRVs1LiBBZGQgY2FwdGlvbl1cbiAgICBlbmRcbiAgICBBIC0tPiBCXG4gICAgQiAtLT4gQ1xuICAgIEMgLS0-IHdcbiAgICBjbGFzc0RlZiBib3ggZmlsbDojZmZmLHN0cm9rZTojMDAwLHN0cm9rZS13aWR0aDoxcHgsY29sb3I6IzAwMDtcbiAgICBjbGFzcyBBLEIsQyxELEUsdyBib3hcbiAgICAiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ" click E "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVsxLiBVc2UgZXh0ZXJuYWw8YnI-dG9vbCB0byBjcmVhdGUvZWRpdDxicj5kaWFncmFtXVxuICAgIEJbMi4gSWYgcG9zc2libGUsIHNhdmU8YnI-ZGlhZ3JhbSBjb29yZGluYXRlczxicj5mb3IgY29udHJpYnV0b3I8YnI-YWNjZXNzXVxuICAgIENbMy4gR2VuZXJhdGUgLnN2ZyA8YnI-b3IucG5nIGZpbGU8YnI-YW5kIGRvd25sb2FkIHRvPGJyPmFwcHJvcHJpYXRlPGJyPmltYWdlcy8gZm9sZGVyXVxuICAgIHN1YmdyYXBoIHdbIF1cbiAgICBkaXJlY3Rpb24gVEJcbiAgICBEWzQuIFVzZSBmaWd1cmUgc2hvcnRjb2RlPGJyPnRvIHJlZmVyZW5jZSBzdmcgb3I8YnI-cG5nIGZpbGUgaW48YnI-cGFnZSAubWQgZmlsZV0gLS0-XG4gICAgRVs1LiBBZGQgY2FwdGlvbl1cbiAgICBlbmRcbiAgICBBIC0tPiBCXG4gICAgQiAtLT4gQ1xuICAgIEMgLS0-IHdcbiAgICBjbGFzc0RlZiBib3ggZmlsbDojZmZmLHN0cm9rZTojMDAwLHN0cm9rZS13aWR0aDoxcHgsY29sb3I6IzAwMDtcbiAgICBjbGFzcyBBLEIsQyxELEUsdyBib3hcbiAgICAiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ"

图 5. 外部工具方法步骤.

使用外部工具方法来添加图表时,你要遵从的步骤如下:

  1. 使用你的外部工具来创建图表。
  2. 将图表的位置保存起来供其他贡献者访问。例如,你的工具可能提供一个指向图表的链接, 或者你可以将源码文件(例如一个 .xml 文件)放置到一个公开的仓库, 以便其他贡献者访问。
  3. 生成图表并将其下载为 .svg.png 图片文件,保存到合适的 ../images/ 目录下。
  4. 使用 {{< figure >}} 短代码从 .md 文件中引用该图表。
  5. 使用 {{< figure >}} 短代码的 caption 参数为图表设置标题。

下面是一个用于 images/apple.svg 图表的 {{< figure >}} 短代码:

{{< figure src="/static/images/apple.svg" alt="red-apple-figure" class="diagram-large" caption="图 9. 一个大红苹果" >}} 

如果你的外部绘图工具支持:

  • 你可以将多个 .svg.png 商标、图标或图片整合到你的图表中。 不过,你需要确保你查看了版权并遵守了 Kubernetes 文档关于使用第三方内容的 指南
  • 你应该将图表的源位置保存起来,以便其他贡献者访问。 例如,你的工具可能提供指向图表文件的链接,或者你应该将源代码文件 (例如一个 .xml 文件)放到某处以便其他贡献者访问。

关于 K8s 和 CNCF 商标与图片的详细信息,可参阅 CNCF Artwork

使用外部工具的好处有:

  • 贡献者对外部工具更为熟悉
  • 图表可能需要 Mermaid 所无法提供的细节

不要忘记使用本地 和 Netlify 预览来检查你的图表可以正常渲染。

示例

本节给出 Mermaid 的若干样例。

示例 1 - Pod 拓扑分布约束

图 6 展示的是 Pod 拓扑分布约束 页面所出现的图表。

graph TB subgraph "zoneB" n3(Node3) n4(Node4) end subgraph "zoneA" n1(Node1) n2(Node2) end classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000; classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff; classDef cluster fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5; class n1,n2,n3,n4 k8s; class zoneA,zoneB cluster; click n3 "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggVEJcbiAgICBzdWJncmFwaCBcInpvbmVCXCJcbiAgICAgICAgbjMoTm9kZTMpXG4gICAgICAgIG40KE5vZGU0KVxuICAgIGVuZFxuICAgIHN1YmdyYXBoIFwiem9uZUFcIlxuICAgICAgICBuMShOb2RlMSlcbiAgICAgICAgbjIoTm9kZTIpXG4gICAgZW5kXG5cbiAgICBjbGFzc0RlZiBwbGFpbiBmaWxsOiNkZGQsc3Ryb2tlOiNmZmYsc3Ryb2tlLXdpZHRoOjRweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzRGVmIGs4cyBmaWxsOiMzMjZjZTUsc3Ryb2tlOiNmZmYsc3Ryb2tlLXdpZHRoOjRweCxjb2xvcjojZmZmO1xuICAgIGNsYXNzRGVmIGNsdXN0ZXIgZmlsbDojZmZmLHN0cm9rZTojYmJiLHN0cm9rZS13aWR0aDoycHgsY29sb3I6IzMyNmNlNTtcbiAgICBjbGFzcyBuMSxuMixuMyxuNCBrOHM7XG4gICAgY2xhc3Mgem9uZUEsem9uZUIgY2x1c3RlcjtcbiIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6dHJ1ZX0" _blank click n4 "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggVEJcbiAgICBzdWJncmFwaCBcInpvbmVCXCJcbiAgICAgICAgbjMoTm9kZTMpXG4gICAgICAgIG40KE5vZGU0KVxuICAgIGVuZFxuICAgIHN1YmdyYXBoIFwiem9uZUFcIlxuICAgICAgICBuMShOb2RlMSlcbiAgICAgICAgbjIoTm9kZTIpXG4gICAgZW5kXG5cbiAgICBjbGFzc0RlZiBwbGFpbiBmaWxsOiNkZGQsc3Ryb2tlOiNmZmYsc3Ryb2tlLXdpZHRoOjRweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzRGVmIGs4cyBmaWxsOiMzMjZjZTUsc3Ryb2tlOiNmZmYsc3Ryb2tlLXdpZHRoOjRweCxjb2xvcjojZmZmO1xuICAgIGNsYXNzRGVmIGNsdXN0ZXIgZmlsbDojZmZmLHN0cm9rZTojYmJiLHN0cm9rZS13aWR0aDoycHgsY29sb3I6IzMyNmNlNTtcbiAgICBjbGFzcyBuMSxuMixuMyxuNCBrOHM7XG4gICAgY2xhc3Mgem9uZUEsem9uZUIgY2x1c3RlcjtcbiIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6dHJ1ZX0" _blank click n1 "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggVEJcbiAgICBzdWJncmFwaCBcInpvbmVCXCJcbiAgICAgICAgbjMoTm9kZTMpXG4gICAgICAgIG40KE5vZGU0KVxuICAgIGVuZFxuICAgIHN1YmdyYXBoIFwiem9uZUFcIlxuICAgICAgICBuMShOb2RlMSlcbiAgICAgICAgbjIoTm9kZTIpXG4gICAgZW5kXG5cbiAgICBjbGFzc0RlZiBwbGFpbiBmaWxsOiNkZGQsc3Ryb2tlOiNmZmYsc3Ryb2tlLXdpZHRoOjRweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzRGVmIGs4cyBmaWxsOiMzMjZjZTUsc3Ryb2tlOiNmZmYsc3Ryb2tlLXdpZHRoOjRweCxjb2xvcjojZmZmO1xuICAgIGNsYXNzRGVmIGNsdXN0ZXIgZmlsbDojZmZmLHN0cm9rZTojYmJiLHN0cm9rZS13aWR0aDoycHgsY29sb3I6IzMyNmNlNTtcbiAgICBjbGFzcyBuMSxuMixuMyxuNCBrOHM7XG4gICAgY2xhc3Mgem9uZUEsem9uZUIgY2x1c3RlcjtcbiIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6dHJ1ZX0" _blank click n2 "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggVEJcbiAgICBzdWJncmFwaCBcInpvbmVCXCJcbiAgICAgICAgbjMoTm9kZTMpXG4gICAgICAgIG40KE5vZGU0KVxuICAgIGVuZFxuICAgIHN1YmdyYXBoIFwiem9uZUFcIlxuICAgICAgICBuMShOb2RlMSlcbiAgICAgICAgbjIoTm9kZTIpXG4gICAgZW5kXG5cbiAgICBjbGFzc0RlZiBwbGFpbiBmaWxsOiNkZGQsc3Ryb2tlOiNmZmYsc3Ryb2tlLXdpZHRoOjRweCxjb2xvcjojMDAwO1xuICAgIGNsYXNzRGVmIGs4cyBmaWxsOiMzMjZjZTUsc3Ryb2tlOiNmZmYsc3Ryb2tlLXdpZHRoOjRweCxjb2xvcjojZmZmO1xuICAgIGNsYXNzRGVmIGNsdXN0ZXIgZmlsbDojZmZmLHN0cm9rZTojYmJiLHN0cm9rZS13aWR0aDoycHgsY29sb3I6IzMyNmNlNTtcbiAgICBjbGFzcyBuMSxuMixuMyxuNCBrOHM7XG4gICAgY2xhc3Mgem9uZUEsem9uZUIgY2x1c3RlcjtcbiIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6dHJ1ZX0" _blank

图 6. Pod 拓扑分布约束

代码块:

graph TB
   subgraph "zoneB"
       n3(Node3)
       n4(Node4)
   end
   subgraph "zoneA"
       n1(Node1)
       n2(Node2)
   end
 
   classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000;
   classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff;
   classDef cluster fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5;
   class n1,n2,n3,n4 k8s;
   class zoneA,zoneB cluster;

示例 2 - Ingress

图 7 显示的是 Ingress 是什么 页面所出现的图表。

graph LR; client([客户端])-. Ingress 所管理的
负载均衡器 .->ingress[Ingress]; ingress-->|路由规则|service[服务]; subgraph cluster ingress; service-->pod1[Pod]; service-->pod2[Pod]; end classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000; classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff; classDef cluster fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5; class ingress,service,pod1,pod2 k8s; class client plain; class cluster cluster; click client "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggIExSXG4gIGNsaWVudChbY2xpZW50XSktLiBJbmdyZXNzLW1hbmFnZWQgPGJyPiBsb2FkIGJhbGFuY2VyIC4tPmluZ3Jlc3NbSW5ncmVzc107XG4gIGluZ3Jlc3MtLT58cm91dGluZyBydWxlfHNlcnZpY2VbU2VydmljZV07XG4gIHN1YmdyYXBoIGNsdXN0ZXJcbiAgaW5ncmVzcztcbiAgc2VydmljZS0tPnBvZDFbUG9kXTtcbiAgc2VydmljZS0tPnBvZDJbUG9kXTtcbiAgZW5kXG4gIGNsYXNzRGVmIHBsYWluIGZpbGw6I2RkZCxzdHJva2U6I2ZmZixzdHJva2Utd2lkdGg6NHB4LGNvbG9yOiMwMDA7XG4gIGNsYXNzRGVmIGs4cyBmaWxsOiMzMjZjZTUsc3Ryb2tlOiNmZmYsc3Ryb2tlLXdpZHRoOjRweCxjb2xvcjojZmZmO1xuICBjbGFzc0RlZiBjbHVzdGVyIGZpbGw6I2ZmZixzdHJva2U6I2JiYixzdHJva2Utd2lkdGg6MnB4LGNvbG9yOiMzMjZjZTU7XG4gIGNsYXNzIGluZ3Jlc3Msc2VydmljZSxwb2QxLHBvZDIgazhzO1xuICBjbGFzcyBjbGllbnQgcGxhaW47XG4gIGNsYXNzIGNsdXN0ZXIgY2x1c3RlcjtcbiIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6ZmFsc2V9" _blank click ingress "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggIExSXG4gIGNsaWVudChbY2xpZW50XSktLiBJbmdyZXNzLW1hbmFnZWQgPGJyPiBsb2FkIGJhbGFuY2VyIC4tPmluZ3Jlc3NbSW5ncmVzc107XG4gIGluZ3Jlc3MtLT58cm91dGluZyBydWxlfHNlcnZpY2VbU2VydmljZV07XG4gIHN1YmdyYXBoIGNsdXN0ZXJcbiAgaW5ncmVzcztcbiAgc2VydmljZS0tPnBvZDFbUG9kXTtcbiAgc2VydmljZS0tPnBvZDJbUG9kXTtcbiAgZW5kXG4gIGNsYXNzRGVmIHBsYWluIGZpbGw6I2RkZCxzdHJva2U6I2ZmZixzdHJva2Utd2lkdGg6NHB4LGNvbG9yOiMwMDA7XG4gIGNsYXNzRGVmIGs4cyBmaWxsOiMzMjZjZTUsc3Ryb2tlOiNmZmYsc3Ryb2tlLXdpZHRoOjRweCxjb2xvcjojZmZmO1xuICBjbGFzc0RlZiBjbHVzdGVyIGZpbGw6I2ZmZixzdHJva2U6I2JiYixzdHJva2Utd2lkdGg6MnB4LGNvbG9yOiMzMjZjZTU7XG4gIGNsYXNzIGluZ3Jlc3Msc2VydmljZSxwb2QxLHBvZDIgazhzO1xuICBjbGFzcyBjbGllbnQgcGxhaW47XG4gIGNsYXNzIGNsdXN0ZXIgY2x1c3RlcjtcbiIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6ZmFsc2V9" _blank click service "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggIExSXG4gIGNsaWVudChbY2xpZW50XSktLiBJbmdyZXNzLW1hbmFnZWQgPGJyPiBsb2FkIGJhbGFuY2VyIC4tPmluZ3Jlc3NbSW5ncmVzc107XG4gIGluZ3Jlc3MtLT58cm91dGluZyBydWxlfHNlcnZpY2VbU2VydmljZV07XG4gIHN1YmdyYXBoIGNsdXN0ZXJcbiAgaW5ncmVzcztcbiAgc2VydmljZS0tPnBvZDFbUG9kXTtcbiAgc2VydmljZS0tPnBvZDJbUG9kXTtcbiAgZW5kXG4gIGNsYXNzRGVmIHBsYWluIGZpbGw6I2RkZCxzdHJva2U6I2ZmZixzdHJva2Utd2lkdGg6NHB4LGNvbG9yOiMwMDA7XG4gIGNsYXNzRGVmIGs4cyBmaWxsOiMzMjZjZTUsc3Ryb2tlOiNmZmYsc3Ryb2tlLXdpZHRoOjRweCxjb2xvcjojZmZmO1xuICBjbGFzc0RlZiBjbHVzdGVyIGZpbGw6I2ZmZixzdHJva2U6I2JiYixzdHJva2Utd2lkdGg6MnB4LGNvbG9yOiMzMjZjZTU7XG4gIGNsYXNzIGluZ3Jlc3Msc2VydmljZSxwb2QxLHBvZDIgazhzO1xuICBjbGFzcyBjbGllbnQgcGxhaW47XG4gIGNsYXNzIGNsdXN0ZXIgY2x1c3RlcjtcbiIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6ZmFsc2V9" _blank click pod1 "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggIExSXG4gIGNsaWVudChbY2xpZW50XSktLiBJbmdyZXNzLW1hbmFnZWQgPGJyPiBsb2FkIGJhbGFuY2VyIC4tPmluZ3Jlc3NbSW5ncmVzc107XG4gIGluZ3Jlc3MtLT58cm91dGluZyBydWxlfHNlcnZpY2VbU2VydmljZV07XG4gIHN1YmdyYXBoIGNsdXN0ZXJcbiAgaW5ncmVzcztcbiAgc2VydmljZS0tPnBvZDFbUG9kXTtcbiAgc2VydmljZS0tPnBvZDJbUG9kXTtcbiAgZW5kXG4gIGNsYXNzRGVmIHBsYWluIGZpbGw6I2RkZCxzdHJva2U6I2ZmZixzdHJva2Utd2lkdGg6NHB4LGNvbG9yOiMwMDA7XG4gIGNsYXNzRGVmIGs4cyBmaWxsOiMzMjZjZTUsc3Ryb2tlOiNmZmYsc3Ryb2tlLXdpZHRoOjRweCxjb2xvcjojZmZmO1xuICBjbGFzc0RlZiBjbHVzdGVyIGZpbGw6I2ZmZixzdHJva2U6I2JiYixzdHJva2Utd2lkdGg6MnB4LGNvbG9yOiMzMjZjZTU7XG4gIGNsYXNzIGluZ3Jlc3Msc2VydmljZSxwb2QxLHBvZDIgazhzO1xuICBjbGFzcyBjbGllbnQgcGxhaW47XG4gIGNsYXNzIGNsdXN0ZXIgY2x1c3RlcjtcbiIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6ZmFsc2V9" _blank click pod2 "https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggIExSXG4gIGNsaWVudChbY2xpZW50XSktLiBJbmdyZXNzLW1hbmFnZWQgPGJyPiBsb2FkIGJhbGFuY2VyIC4tPmluZ3Jlc3NbSW5ncmVzc107XG4gIGluZ3Jlc3MtLT58cm91dGluZyBydWxlfHNlcnZpY2VbU2VydmljZV07XG4gIHN1YmdyYXBoIGNsdXN0ZXJcbiAgaW5ncmVzcztcbiAgc2VydmljZS0tPnBvZDFbUG9kXTtcbiAgc2VydmljZS0tPnBvZDJbUG9kXTtcbiAgZW5kXG4gIGNsYXNzRGVmIHBsYWluIGZpbGw6I2RkZCxzdHJva2U6I2ZmZixzdHJva2Utd2lkdGg6NHB4LGNvbG9yOiMwMDA7XG4gIGNsYXNzRGVmIGs4cyBmaWxsOiMzMjZjZTUsc3Ryb2tlOiNmZmYsc3Ryb2tlLXdpZHRoOjRweCxjb2xvcjojZmZmO1xuICBjbGFzc0RlZiBjbHVzdGVyIGZpbGw6I2ZmZixzdHJva2U6I2JiYixzdHJva2Utd2lkdGg6MnB4LGNvbG9yOiMzMjZjZTU7XG4gIGNsYXNzIGluZ3Jlc3Msc2VydmljZSxwb2QxLHBvZDIgazhzO1xuICBjbGFzcyBjbGllbnQgcGxhaW47XG4gIGNsYXNzIGNsdXN0ZXIgY2x1c3RlcjtcbiIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6ZmFsc2V9" _blank

图 7. Ingress

代码块:

graph LR;
 client([客户端])-. Ingress 所管理的<br>负载均衡器 .->ingress[Ingress];
 ingress-->|路由规则|service[服务];
 subgraph cluster
 ingress;
 service-->pod1[Pod];
 service-->pod2[Pod];
 end
 classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000;
 classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff;
 classDef cluster fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5;
 class ingress,service,pod1,pod2 k8s;
 class client plain;
 class cluster cluster;

示例 3 - K8s 系统流程

图 8 给出的是一个 Mermaid 时序图,展示启动容器时 K8s 组件间的控制流。

K8s system flow diagram

图 8. K8s 系统流程图

代码段:

%%{init:{"theme":"neutral"}}%%
sequenceDiagram
    actor me
    participant apiSrv as 控制面<br><br>api-server
    participant etcd as 控制面<br><br>etcd 数据存储
    participant cntrlMgr as 控制面<br><br>控制器管理器
    participant sched as 控制面<br><br>调度器
    participant kubelet as 节点<br><br>kubelet
    participant container as 节点<br><br>容器运行时
    me->>apiSrv: 1. kubectl create -f pod.yaml
    apiSrv-->>etcd: 2. 保存新状态
    cntrlMgr->>apiSrv: 3. 检查变更
    sched->>apiSrv: 4. 监视未分派的 Pod(s)
    apiSrv->>sched: 5. 通知 nodename=" " 的 Pod
    sched->>apiSrv: 6. 指派 Pod 到节点
    apiSrv-->>etcd: 7. 保存新状态
    kubelet->>apiSrv: 8. 查询新指派的 Pod(s)
    apiSrv->>kubelet: 9. 将 Pod 绑定到节点
    kubelet->>container: 10. 启动容器
    kubelet->>apiSrv: 11. 更新 Pod 状态
    apiSrv-->>etcd: 12. 保存新状态

如何设置图表样式

你可以使用大家都熟悉的 CSS 术语来为一个或多个图表元素设置渲染样式。 你可以在 Mermaid 代码中使用两种类型的语句来完成这一工作:

  • classDef 定义一类样式属性;
  • class 指定 class 所适用的一种或多种元素。

图 7 中,你可以看到这两种示例。

classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff; // 定义 k8s 类的样式
class ingress,service,pod1,pod2 k8s; // k8s 类会应用到 ingress、service、pod1 和 pod2 这些元素之上

你可以在你的图表中包含一个或多个 classDefclass 语句。 你也可以在你的图表中为 k8s 组件使用官方的 K8s #326ce5 十六进制颜色代码。

关于样式设置和类的更多信息,可参阅 Mermaid Styling and classes docs

如何使用标题

标题用来为图表提供简要的描述。标题或短描述都可以作为图表标题。 标题不是用来替换你在文档中要提供的解释性文字。 相反,它们是用来在文字与图表之间建立“语境连接”的。

将一些文字和带标题的图表组合到一起,可以为你所想要向用户传递的信息提供一种更为精确的表达。

没有标题的话,用户就必须在图表前后的文字中来回阅读,从而了解其含义。 这会让用户感觉到很沮丧。

图 9 给出合适的标题所需要具备的三要素:图表、图表标题和图表引用。

flowchart A[图表本身

内嵌 Mermaid 或
SVG 图片文件] B[图表标题

添加图表编号和
标题文字] C[图表引用

在文字中用图表
编号引用图表] classDef box fill:#fff,stroke:#000,stroke-width:1px,color:#000; class A,B,C box click A "https://mermaid-js.github.io/mermaid-live-editor/edit#eyJjb2RlIjoiZmxvd2NoYXJ0XG4gICAgQVtEaWFncmFtPGJyPjxicj5JbmxpbmUgTWVybWFpZCBvcjxicj5TVkcgaW1hZ2UgZmlsZXNdXG4gICAgQltEaWFncmFtIENhcHRpb248YnI-PGJyPkFkZCBGaWd1cmUgTnVtYmVyLiBhbmQ8YnI-Q2FwdGlvbiBUZXh0XVxuICAgIENbRGlhZ3JhbSBSZWZlcnJhbDxicj48YnI-UmVmZXJlbmVuY2UgRmlndXJlIE51bWJlcjxicj5pbiB0ZXh0XVxuXG4gICAgY2xhc3NEZWYgYm94IGZpbGw6I2ZmZixzdHJva2U6IzAwMCxzdHJva2Utd2lkdGg6MXB4LGNvbG9yOiMwMDA7XG4gICAgY2xhc3MgQSxCLEMgYm94IiwibWVybWFpZCI6IntcbiAgXCJ0aGVtZVwiOiBcImRlZmF1bHRcIlxufSIsInVwZGF0ZUVkaXRvciI6ZmFsc2UsImF1dG9TeW5jIjp0cnVlLCJ1cGRhdGVEaWFncmFtIjpmYWxzZX0" _blank click B "https://mermaid-js.github.io/mermaid-live-editor/edit#eyJjb2RlIjoiZmxvd2NoYXJ0XG4gICAgQVtEaWFncmFtPGJyPjxicj5JbmxpbmUgTWVybWFpZCBvcjxicj5TVkcgaW1hZ2UgZmlsZXNdXG4gICAgQltEaWFncmFtIENhcHRpb248YnI-PGJyPkFkZCBGaWd1cmUgTnVtYmVyLiBhbmQ8YnI-Q2FwdGlvbiBUZXh0XVxuICAgIENbRGlhZ3JhbSBSZWZlcnJhbDxicj48YnI-UmVmZXJlbmVuY2UgRmlndXJlIE51bWJlcjxicj5pbiB0ZXh0XVxuXG4gICAgY2xhc3NEZWYgYm94IGZpbGw6I2ZmZixzdHJva2U6IzAwMCxzdHJva2Utd2lkdGg6MXB4LGNvbG9yOiMwMDA7XG4gICAgY2xhc3MgQSxCLEMgYm94IiwibWVybWFpZCI6IntcbiAgXCJ0aGVtZVwiOiBcImRlZmF1bHRcIlxufSIsInVwZGF0ZUVkaXRvciI6ZmFsc2UsImF1dG9TeW5jIjp0cnVlLCJ1cGRhdGVEaWFncmFtIjpmYWxzZX0" _blank click C "https://mermaid-js.github.io/mermaid-live-editor/edit#eyJjb2RlIjoiZmxvd2NoYXJ0XG4gICAgQVtEaWFncmFtPGJyPjxicj5JbmxpbmUgTWVybWFpZCBvcjxicj5TVkcgaW1hZ2UgZmlsZXNdXG4gICAgQltEaWFncmFtIENhcHRpb248YnI-PGJyPkFkZCBGaWd1cmUgTnVtYmVyLiBhbmQ8YnI-Q2FwdGlvbiBUZXh0XVxuICAgIENbRGlhZ3JhbSBSZWZlcnJhbDxicj48YnI-UmVmZXJlbmVuY2UgRmlndXJlIE51bWJlcjxicj5pbiB0ZXh0XVxuXG4gICAgY2xhc3NEZWYgYm94IGZpbGw6I2ZmZixzdHJva2U6IzAwMCxzdHJva2Utd2lkdGg6MXB4LGNvbG9yOiMwMDA7XG4gICAgY2xhc3MgQSxCLEMgYm94IiwibWVybWFpZCI6IntcbiAgXCJ0aGVtZVwiOiBcImRlZmF1bHRcIlxufSIsInVwZGF0ZUVkaXRvciI6ZmFsc2UsImF1dG9TeW5jIjp0cnVlLCJ1cGRhdGVEaWFncmFtIjpmYWxzZX0" _blank

图 9. 标题要素

图表本身

Mermaid+SVG 和外部工具方法都会生成 .svg 图片文件。

下面的 {{< figure >}} 短代码是针对定义在保存于 /images/docs/components-of-kubernetes.svg 中的 .svg 图片文件的。

{{< figure src="/images/docs/components-of-kubernetes.svg" alt="运行于集群中的 Kubernetes Pod" class="diagram-large" caption="图 4. Kubernetes 结构组件" >}}

你需要将 srcaltclasscaption 取值传递给 {{< figure >}} 短代码。 你可以使用 diagram-largediagram-mediumdiagram-small 类来调整图表的尺寸。

关于创建图表的不同方法,可参阅创建图表的方法

图表标题

接下来,添加图表标题。

如果你使用 .svg 图片文件来定义你的图表,你就需要使用 {{< figure >}} 短代码的 caption 参数。

{{< figure src="/images/docs/components-of-kubernetes.svg" alt="运行于集群中的 Kubernetes Pod" class="diagram-large" caption="图 4. Kubernetes 架构组件" >}}

如果你使用内嵌的 Mermaid 代码来定义图表,则你需要使用 Markdown 文本来添加标题。

图 4. Kubernetes 架构组件

添加图表标题时需要考虑的问题:

  • 使用 {{< figure >}} 短代码来为 Mermaid+SVG 和外部工具方法制作的图表添加标题。
  • 对于内嵌方法制作的图表,使用简单的 Markdown 文本来为其添加标题。
  • 在你的图表标题前面添加 图 <编号>.. 你必须使用 字样, 并且编号必须对于文档页面中所有图表而言唯一。 在编号之后添加一个英文句号。
  • 将图表标题添加到 图 <编号>. 之后,并且在同一行。 你必须为图表标题添加英文句点作为其结束标志。尽量保持标题文字简短。
  • 图表标题要放在图表 之后

图表引用

最后,你可以添加图表引用。图表引用位于你的文档正文中,并且应该出现在图表之前。 这样,用户可以将你的文字与对应的图表关联起来。引用时所给的 图 <编号> 部分要与图表标题中对应部分一致。

你要避免使用空间上的相对引用,例如 ..下面的图片.. 或者 ..下面的图形..

以下是一个参考引用的示例。

图 10 展示的是 Kubernetes 体系结构。其控制面 ...

图表引用是可选的,在有些场合中,添加这类引用是不合适的。 如果你不是很确定,可以在文字中添加图表引用,以判断是否看起来、读起来比较通顺。 如果仍然不确定,可以使用图表引用。

完整全图

图 10 展示的是一个 Kubernetes 架构图表,其中包含了图表本身、图表标题和图表引用。 这里的 {{< figure >}} 短代码负责渲染图表,添加标题并包含可选的 link 参数,以便于你为图表提供超级链接。图表引用也被包含在段落中。

下面是针对此图表的 {{< figure >}} 短代码。

{{< figure src="/images/docs/components-of-kubernetes.svg" alt="运行在集群中的 Kubernetes Pod" class="diagram-large" caption="图 10. Kubernetes 架构" link="https://kubernetes.io/zh-cn/docs/concepts/overview/components/" >}}
运行在集群中的 Kubernetes Pod

图 10. Kubernetes 架构

提示

  • 总是使用在线编辑器来创建和编辑你的图表。

  • 总是使用 Hugo 本地和 Netlify 预览来检查图表在文档中的渲染效果。

  • 提供图表源代码指针,例如 URL、源代码位置或者标明代码时是说明的。

  • 总是提供图表标题。

  • 在问题报告或 PR 中包含 .svg.png 图片与/或 Mermaid 代码会很有帮助。

  • 对于 Mermaid+SVG 方法和外部工具方法而言,尽量使用 .svg 图片文件, 因为这类文件在被放大之后仍能清晰地显示。

  • 对于 .svg 文件的最佳实践是将其加载到一个 SVG 编辑工具中,并使用 “将文字转换为路径”功能完成转换。

  • Mermaid 不支持额外的图表或艺术形式。

  • Hugo Mermaid 短代码在在线编辑器中无法显示。

  • 如果你想要在在线编辑器中更改图表,你 必须 保存它以便为图表生成新的 URL。

  • 点击本节中的图表,你可以查看其源代码及其在在线编辑器中的渲染效果。

  • 查看本页的源代码,diagram-guide.md 文件,可以将其作为示例。

  • 查阅 Mermaid docs 以获得更多的解释和示例。

最重要的一点,保持图表简单。 这样做会节省你和其他贡献者的时间,同时也会方便新的以及有经验的用户阅读。

7.4 - 撰写新主题

本页面展示如何为 Kubernetes 文档库创建新主题。

准备开始

发起 PR中所述,创建 Kubernetes 文档库的派生副本。

选择页面类型

当你准备编写一个新的主题时,考虑一下最适合你的内容的页面类型:

选择页面类型的说明
类型描述
概念(Concept)概念页面负责解释 Kubernetes 的某方面。例如,概念页面可以描述 Kubernetes Deployment 对象,并解释当部署、扩展和更新时,它作为应用程序所扮演的角色。一般来说,概念页面不包括步骤序列,而是提供任务或教程的链接。概念主题的示例可参见 节点
任务(Task)任务页面展示如何完成特定任务。其目的是给读者提供一系列的步骤,让他们在阅读时可以实际执行。任务页面可长可短,前提是它始终围绕着某个主题展开。在任务页面中,可以将简短的解释与要执行的步骤混合在一起。如果需要提供较长的解释,则应在概念主题中进行。相关联的任务和概念主题应该相互链接。一个简短的任务页面的实例可参见 配置 Pod 使用卷存储。一个较长的任务页面的实例可参见 配置活跃性和就绪性探针
教程(Tutorial)教程页面展示如何实现某个目标,该目标将若干 Kubernetes 功能特性联系在一起。教程可能提供一些步骤序列,读者可以在阅读页面时实际执行这些步骤。或者它可以提供相关代码片段的解释。例如,教程可以提供代码示例的讲解。教程可以包括对 Kubernetes 几个关联特性的简要解释,但有关更深入的特性解释应该链接到相关概念主题。

创建一个新页面

为每个新页面选择其内容类型。 文档站提供了模板或 Hugo Archetypes 来创建新的内容页面。 要创建新类型的页面,请使用要创建的文件的路径,运行 hugo new 命令。例如:

hugo new docs/concepts/my-first-concept.md

选择标题和文件名

选择一个标题,确保其中包含希望搜索引擎发现的关键字。 确定文件名时请使用标题中的单词,由连字符分隔。 例如,标题为Using an HTTP Proxy to Access Kubernetes API 的主题的文件名为 http-proxy-access-api.md。 你不需要在文件名中加上 "kubernetes",因为 "kubernetes" 已经在主题的 URL 中了, 例如:

   /docs/tasks/extend-kubernetes/http-proxy-access-api/

在页面前言中添加主题标题

在你的主题中,在前言(front-matter) 中设置一个 title 字段。 前言是位于页面顶部三条虚线之间的 YAML 块。下面是一个例子:

---
title: 使用 HTTP 代理访问 Kubernetes API
---

选择目录

根据页面类型,将新文件放入其中一个子目录中:

  • /content/en/docs/tasks/
  • /content/en/docs/tutorials/
  • /content/en/docs/concepts/

你可以将文件放在现有的子目录中,也可以创建一个新的子目录。

将主题放在目录中

目录是使用文档源的目录结构动态构建的。 /content/en/docs/ 下的顶层目录用于创建顶层导航条目, 这些目录和它们的子目录在网站目录中都有对应条目。

每个子目录都有一个 _index.md 文件,它表示的是该子目录内容的主页面。 _index.md 文件不需要模板。它可以包含各子目录中主题的概述内容。

默认情况下,目录中的其他文件按字母顺序排序。这一般不是最好的顺序。 要控制子目录中主题的相对排序,请将页面头部的键 weight: 设置为整数值。 通常我们使用 10 的倍数,添加后续主题时 weight 值递增。 例如,weight10 的主题将位于 weight20 的主题之前。

在主题中嵌入代码

如果你想在主题中嵌入一些代码,可以直接使用 Markdown 代码块语法将代码嵌入到文件中。 建议在以下场合(并非详尽列表)使用嵌入代码:

  • 代码显示来自命令的输出,例如 kubectl get deploy mydeployment -o json | jq '.status'
  • 代码不够通用,用户无法验证。例如,你可以嵌入 YAML 文件来创建一个依赖于特定 FlexVolume 实现的 Pod。
  • 该代码是一个不完整的示例,因为其目的是突出展现某个大文件中的部分内容。 例如,在描述 RoleBinding 的方法时,你可以在主题文件中直接提供一个短的代码段。
  • 由于某些其他原因,该代码不适合用户验证。 例如,当使用 kubectl edit 命令描述如何将新属性添加到资源时, 你可以提供一个仅包含要添加的属性的简短示例。

引用来自其他文件的代码

在主题中引用代码的另一种方法是创建一个新的、完整的示例文件(或文件组), 然后在主题中引用这些示例。当示例是通用的和可重用的,并且你希望读者自己验证时, 使用此方法引用示例 YAML 文件。

添加新的独立示例文件(如 YAML 文件)时,将代码放在 <LANG>/examples/ 的某个子目录中, 其中 <LANG> 是该主题的语言。在主题文件中使用 codenew 短代码:

{{< codenew file="<RELPATH>/my-example-yaml>" >}}

<RELPATH> 是要引用的文件的路径,相对于 examples 目录。以下 Hugo 短代码引用了位于 /content/en/examples/pods/storage/gce-volume.yaml 的 YAML 文件。

{{< codenew file="pods/storage/gce-volume.yaml" >}}

显示如何从配置文件创建 API 对象

如果需要演示如何基于配置文件创建 API 对象,请将配置文件放在 <LANG>/examples 下的某个子目录中。

在主题中展示以下命令:

kubectl create -f https://k8s.io/examples/pods/storage/gce-volume.yaml

有关使用此技术的主题的示例,请参见 运行单实例有状态的应用

向主题添加图片

将图片文件放入 /images 目录。首选的图片格式是 SVG。

接下来

7.5 - 页面内容类型

Kubernetes 文档包含以下几种页面内容类型:

  • 概念(Concept)
  • 任务(Task)
  • 教程(Tutorial)
  • 参考(Reference)

内容章节

每种页面内容类型都有一些使用 Markdown 注释和 HTML 标题定义的章节。 你可以使用 heading 短代码将内容标题添加到你的页面中。 注释和标题有助于维护对应页面内容类型的结构组织。

定义页面内容章节的 Markdown 注释示例:

<!-- overview -->
<!-- body -->

要在内容页面中创建通用的标题,可以使用 heading 短代码加上标题字符串。

标题字符串示例:

  • whatsnext
  • prerequisites
  • objectives
  • cleanup
  • synopsis
  • seealso
  • options

例如,要创建一个 whatsnext 标题,添加 heading 短代码并指定 "whatsnext" 字符串:

## {{% heading "whatsnext" %}}

你可以像下面这样声明一个 prerequisites 标题:

## {{% heading "prerequisites" %}}

短代码 heading 需要一个字符串参数。 该字符串参数要与 i18n/<语言>.toml 文件中以其为前缀的某个变量匹配。 例如:

i18n/en.toml:

[whatsnext_heading]
other = "What's next"

i18n/ko.toml:

[whatsnext_heading]
other = "다음 내용"

内容类型

每种内容类型都非正式地定义了期望的页面结构组织。 请按照所建议的页面章节来创建内容页面。

概念

概念页面用来解释 Kubernetes 的某些方面。例如,概念页面可以用来描述 Kubernetes 中的 Deployment 对象,解释其作为应用的角色如何部署、扩缩和更新。 通常,概念页面不需要包含步骤序列,但包含指向任务或教程的链接。

要编写一个新的概念页面,在 /content/en/docs/concepts 目录下面的子目录中新建一个 Markdown 文件。 该文件具有以下特点。

概念页面分为三个章节:

页面章节
overview(概述)
body(正文)
whatsnext(接下来)

其中的 overviewbody 章节在概念页面中显示为注释。 你可以使用 heading 短代码向页面添加 wahtsnext 节。

在为每个章节撰写内容时,遵从一些规定:

  • 使用二级和三级标题(H2、H3)来组织内容;
  • overview 节中,使用一段文字概括当前主题的上下文;
  • body 节中,详细解释对应概念;
  • 对于 whatsnext 节,提供一个项目符号列表(最多 5 个),帮助读者进一步学习掌握概念。

注解页面是一个已经上线的概念页面的例子。

任务(Task)

任务页面讲解如何完成某项工作,通常包含由为数不多的几个步骤组成的序列。 任务页面的讲解文字很少,不过通常会包含指向概念主题的链接,以便读者能够了解相关的背景和知识。

编写新的任务页面时,在 /content/en/docs/tasks 目录下的子目录中创建一个新的 Markdown 文件。 该文件特点如下。

页面章节
overview(概述)
prerequisites(准备工作)
steps(步骤)
discussion(讨论)
whatsnext(接下来)

其中的 overviewstepsdiscussion 节在任务页面中显示为注释。 你可以使用 heading 短代码添加 prerequisiteswhatsnext 小节。

在每个小节内撰写内容时注意以下规定:

  • 最低使用二级标题(H2,标题行前带两个 # 字符)。每个小节都会由模板自动给出标题。
  • overview 节中,用一个段落为整个任务主题设定语境;
  • prerequisites 节中,尽可能使用项目符号列表。 额外的环境准备条件要加在 include 短代码之后。 默认的环境准备条件是拥有一个在运行的 Kubernetes 集群。
  • steps 节中,使用编号符号列表。
  • discussion 节中,使用正常文字内容来对 steps 节中内容展开叙述。
  • whatsnext 节中,使用项目符号列表(不超过 5 项),列举读者可能接下来有兴趣阅读的主题。

已上线的任务主题示例之一是使用 HTTP 代理访问 Kubernetes API

教程(Tutorial)

教程页面描述如果完成一个比单一任务规模更大的目标。通常教程页面会有多个小节, 每个小节由一系列步骤组成。例如,每个教程可能提供对代码示例的讲解, 便于用户了解 Kubernetes 的某个功能特性。教程可以包含表面层面的概念解释, 对于更深层面的概念主题应该使用链接。

撰写新的教程页面时,在 /content/en/docs/tutorials 目录下面的子目录中创建新的 Markdown 文件。该文件有以下特点。

页面节区
overview(概述)
prerequisites(环境准备)
objectives(目标)
lessoncontent(教程内容)
cleanup(清理工作)
whatsnext(接下来)

教程页面的 overviewobjectiveslessoncontent 小节显示为注释形式。 你可以使用 heading 短代码根据需要添加 prerequisitescleanupwhatsnext 小节。

在每个小节中编写内容时,请注意以下规定:

  • 最低使用二级标题(H2,标题前面有两个 # 字符)。模板会自动为每个小节设置标题。
  • overview 节中,用一个段落为整个主题设定语境;
  • prerequisites 节中,尽可能使用项目符号列表。 额外的环境准备条件要加在已包含的条件之后。
  • objectives 节中,使用项目符号列表。
  • lessoncontent 节中,结合使用编号符号列表和叙述性文字。
  • cleanup 节中,使用编号符号列表来描述任务结束后清理集群状态所需要的步骤。
  • whatsnext 节中,使用项目符号列表(不超过 5 项),列举读者可能接下来有兴趣阅读的主题。

已发布的教程主题的一个例子是 使用 Deployment 运行无状态应用.

参考(Reference)

组件工具的参考页面给出的是某个 Kubernetes 组件工具的描述和参数选项输出。 每个页面都是使用组件工具命令基于脚本生成的。

每个工具参考页面可能包含以下小节:

页面小节
synopsis(用法)
options(选项)
options from parent commands(从父命令集成的选项)
examples(示例)
seealso(参考)

已发布的工具参考页面示例包括:

接下来

7.6 - 内容组织

本网站使用了 Hugo。在 Hugo 中,内容组织是一个核心概念。

页面列表

页面顺序

文档侧方菜单、文档页面浏览器等以 Hugo 的默认排序顺序列出。Hugo 会按照权重(从 1 开始)、 日期(最新的排最前面)排序,最后按链接标题排序。

有鉴于此,如果你想将一个页面或一个章节前移,请在页面头部设置一个较高的权重:

title: My Page
weight: 10

文档主菜单

文档主菜单是从 docs/ 下面的章节构建的。 这些章节在其章节内容文件 _index.md 的头部设置了 main_menu 标志:

main_menu: true

注意,链接标题来自页面的 linkTitle 字段,因此如果希望它与页面标题不同,请在内容文件中更改它:

main_menu: true
title: Page Title
linkTitle: Title used in links

文档侧方菜单

文档侧方菜单是基于 docs/ 下面的 当前章节的内容树 构建的。

菜单默认显示所有的章节和它们的页面。

如果你不想列出某个章节或页面,请在页面头部将 toc_hide 标志设置为 true

toc_hide: true

当导航到具有内容的章节时,网站将显示出指定的章节或页面(例如 _index.md)。 否则,将显示该章节里的第一个页面。

文档浏览器

文档主页上的页面浏览器是基于 docs section 下一层的所有章节和页面构建的。

如果你不想列出某个章节或页面,请在页面头部将 toc_hide 标志设置为 true

toc_hide: true

主菜单

右上菜单中的网站链接(也出现在页脚中)是通过页面查找构建的。 这是为了确保页面实际存在。因此,如果案例分析章节在网站(或者其本地化版本)中不存在, 则不会出现对应的链接。

页面包

除了独立的内容页面(Markdown 文件), Hugo 还支持页面包

一个例子是定制的 Hugo 短代码(shortcodes)。 它被认为是 leaf bundle(叶子包)。 目录下的所有内容,包括 index.md,都是包的一部分。此外还包括页面间相对链接、可被处理的图像等:

zh-cn/docs/home/contribute/includes
├── example1.md
├── example2.md
├── index.md
└── podtemplate.json

另一个广泛使用的例子是 includes 包。 这类包在页面头部设置 headless: true,意味着它没有得到自己的 URL。它只用于其他页面。

zh-cn/includes
├── default-storage-class-prereqs.md
├── index.md
├── partner-script.js
├── partner-style.css
├── task-tutorial-prereqs.md
├── user-guide-content-moved.md
└── user-guide-migration-notice.md

有关包中文件的一些重要说明:

  • 已翻译的包会从上面的语言继承所有缺失的、非内容文件。这一设计可以避免重复。
  • 包中的所有文件都是 Hugo 所指的 Resources,即使某个语言不支持头部设置(YAML 文件等), 你也可以为每个语言提供诸如参数和标题等元数据。 参见页面资源元数据
  • Resource.RelPermalink 中获得的值是相对于当前页面的。 参见 Permalinks

样式

本网站的样式表的 SASS 源文件存放在 src/sass 下面,并通过 Hugo 自动构建。

接下来

7.7 - 定制 Hugo 短代码

本页面将介绍 Hugo 自定义短代码,可以用于 Kubernetes Markdown 文档书写。

关于短代码的更多信息可参见 Hugo 文档

功能状态

在本站的 Markdown 页面(.md 文件)中,你可以加入短代码来展示所描述的功能特性的版本和状态。

功能状态示例

下面是一个功能状态代码段的演示,表明这个功能已经在最新版 Kubernetes 中稳定了。

{{< feature-state state="stable" >}}

会转换为:

特性状态: Kubernetes v1.26 [stable]

state 的可选值如下:

  • alpha
  • beta
  • deprecated
  • stable

功能状态代码

所显示的 Kubernetes 默认为该页或站点版本。 修改 for_k8s_version 短代码参数可以调整要显示的版本。例如:

{{< feature-state for_k8s_version="v1.10" state="beta" >}}

会转换为:

特性状态: Kubernetes v1.10 [beta]

词汇

有两种词汇表提示:glossary_tooltipglossary_definition

你可以通过加入术语词汇的短代码,来自动更新和替换相应链接中的内容 (我们的词汇库) 在浏览在线文档时,术语会显示为超链接的样式,当鼠标移到术语上时,其解释就会显示在提示框中。

除了包含工具提示外,你还可以重用页面内容中词汇表中的定义。

词汇术语的原始数据保存在词汇目录, 每个内容文件对应相应的术语解释。

词汇演示

例如下面的代码在 Markdown 中将会转换为 cluster,然后在提示框中显示。

{{< glossary_tooltip text="cluster" term_id="cluster" >}}

这是一个简短的词汇表定义:

{{< glossary_definition prepend="A cluster is" term_id="cluster" length="short" >}}

呈现为:

A cluster is 一组工作机器,称为 节点, 会运行容器化应用程序。每个集群至少有一个工作节点。

你也可以包括完整的定义:

{{< glossary_definition term_id="cluster" length="all" >}}

呈现为:

一组工作机器,称为 节点, 会运行容器化应用程序。每个集群至少有一个工作节点。

工作节点会托管 Pod ,而 Pod 就是作为应用负载的组件。 控制平面管理集群中的工作节点和 Pod。 在生产环境中,控制平面通常跨多台计算机运行, 一个集群通常运行多个节点,提供容错性和高可用性。

你可以使用 api-reference 短代码链接到 Kubernetes API 参考页面,例如: Pod Pod 参考文件:

{{< api-reference page="workload-resources/pod-v1" >}}

本语句中 page 参数的内容是 API 参考页面的 URL 后缀。

你可以通过指定 anchor 参数链接到页面中的特定位置,例如到 PodSpec 参考,或页面的 environment-variables 部分:

{{< api-reference page="workload-resources/pod-v1" anchor="PodSpec" >}}
{{< api-reference page="workload-resources/pod-v1" anchor="environment-variables" >}}

你可以通过指定 text 参数来更改链接的文本,例如通过链接到页面的 环境变量 部分:

{{< api-reference page="workload-resources/pod-v1" anchor="environment-variables" text="环境变量" >}}

表格标题

通过添加表格标题,你可以让表格能够被屏幕阅读器读取。 要向表格添加标题(Caption), 可用 table 短代码包围表格定义,并使用 caption 参数给出表格标题。

下面是一个例子:

{{< table caption="配置参数" >}}
参数      | 描述        | 默认值
:---------|:------------|:-------
`timeout` | 请求的超时时长 | `30s`
`logLevel` | 日志输出的级别 | `INFO`
{{< /table >}}

所渲染的表格如下:

配置参数
参数描述默认值
timeout请求的超时时长30s
logLevel日志输出的级别INFO

如果你查看表格的 HTML 输出结果,你会看到 <table> 元素 后面紧接着下面的元素:

<caption style="display: none;">配置参数</caption>

标签页

在本站的 Markdown 页面(.md 文件)中,你可以加入一个标签页集来显示 某解决方案的不同形式。

标签页的短代码包含以下参数:

  • name: 标签页上显示的名字。
  • codelang: 如果要在 tab 短代码中加入内部内容,需要告知 Hugo 使用的是什么代码语言,方便代码高亮。
  • include: 标签页中所要包含的文件。如果标签页是在 Hugo 的 叶子包中定义, Hugo 会在包内查找文件(可以是 Hugo 所支持的任何 MIME 类型文件)。 否则,Hugo 会在当前路径的相对路径下查找所要包含的内容页面。 注意,在 include 页面中不能包含短代码内容,必须要使用自结束(self-closing)语法。 例如 {{< tab name="Content File #1" include="example1" />}}。 如果没有在 codelang 进行声明的话,Hugo 会根据文件名推测所用的语言。 默认情况下,非内容文件将会被代码高亮。
  • 如果内部内容是 Markdown,你必须要使用 % 分隔符来包装标签页。 例如,{{% tab name="Tab 1" %}}This is **markdown**{{% /tab %}}
  • 可以在标签页集中混合使用上面的各种变形。

下面是标签页短代码的示例。

标签页演示:代码高亮

{{< tabs name="tab_with_code" >}}
{{< tab name="Tab 1" codelang="bash" >}}
echo "This is tab 1."
{{< /tab >}}
{{< tab name="Tab 2" codelang="go" >}}
println "This is tab 2."
{{< /tab >}}
{{< /tabs >}}

会转换为:


echo "This is tab 1."


println "This is tab 2."

标签页演示:内联 Markdown 和 HTML

{{< tabs name="tab_with_md" >}}
{{% tab name="Markdown" %}}
这是 **一些 markdown。**
{{< note >}}
它甚至可以包含短代码。
{{< /note >}}
{{% /tab %}}
{{< tab name="HTML" >}}
<div>
	<h3>纯 HTML</h3>
	<p>这是一些 <i>纯</i> HTML。</p>
</div>
{{< /tab >}}
{{< /tabs >}}

会转换为:

这是 一些 markdown。

纯 HTML

这是一些 HTML。

标签页演示:文件嵌套

{{< tabs name="tab_with_file_include" >}}
{{< tab name="Content File #1" include="example1" />}}
{{< tab name="Content File #2" include="example2" />}}
{{< tab name="JSON File" include="podtemplate" />}}
{{< /tabs >}}

会转换为:

这是一个内容文件示例,位于一个includes叶子包中。

这是另一个内容文件示例,位于一个includes叶子包中。

  {
    "apiVersion": "v1",
    "kind": "PodTemplate",
    "metadata": {
      "name": "nginx"
    },
    "template": {
      "metadata": {
        "labels": {
          "name": "nginx"
        },
        "generateName": "nginx-"
      },
      "spec": {
         "containers": [{
           "name": "nginx",
           "image": "dockerfile/nginx",
           "ports": [{"containerPort": 80}]
         }]
      }
    }
  }

你可以使用 {{< codenew >}} 短代码将文件内容嵌入代码块中, 以允许用户下载或复制其内容到他们的剪贴板。 当示例文件的内容是通用的、可复用的,并且希望用户自己尝试使用示例文件时, 可以使用此短代码。

这个短代码有两个命名参数:languagefile, 必选参数 file 用于指定要显示的文件的路径, 可选参数 language 用于指定文件的编程语言。 如果未提供 language 参数,短代码将尝试根据文件扩展名推测编程语言。

{{< codenew language="yaml" file="application/deployment-scale.yaml" >}}

输出是:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 4 # 将副本数从 2 更新为 4
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.16.1
        ports:
        - containerPort: 80

添加新的示例文件(例如 YAML 文件)时,在 <LANG>/examples/ 子目录之一中创建该文件,其中 <LANG> 是页面的语言。 在你的页面的 markdown 文本中,使用 codenew 短代码:

{{< codenew file="<RELATIVE-PATH>/example-yaml>" >}}

其中 <RELATIVE-PATH> 是要包含的示例文件的路径,相对于 examples 目录。 以下短代码引用位于 /content/en/examples/configmap/configmaps.yaml 的 YAML 文件。

{{< codenew file="configmap/configmaps.yaml" >}}

第三方内容标记

运行 Kubernetes 需要第三方软件。例如:你通常需要将 DNS 服务器 添加到集群中,以便名称解析工作。

当我们链接到第三方软件或以其他方式提及它时,我们会遵循内容指南 并标记这些第三方项目。

使用这些短代码会向使用它们的任何文档页面添加免责声明。

列表

对于有关几个第三方项目的列表,请添加:

{{% thirdparty-content %}}

在包含所有项目的段落标题正下方。

项目

如果你有一个列表,其中大多数项目引用项目内软件(例如:Kubernetes 本身,以及单独的 Descheduler 组件),那么可以使用不同的形式。

在项目之前,或在特定项目的段落下方添加此短代码:

{{% thirdparty-content single="true" %}}

版本号信息

要在文档中生成版本号信息,可以从以下几种短代码中选择。每个短代码可以基于站点配置文件 hugo.toml 中的版本参数生成一个版本号取值。最常用的参数为 latestversion

{{< param "version" >}}

{{< param "version" >}} 短代码可以基于站点参数 version 生成 Kubernetes 文档的当前版本号取值。短代码 param 允许传入一个站点参数名称,在这里是 version

转换为:

v1.26

{{< latest-version >}}

{{< latest-version >}} 返回站点参数 latest 的取值。每当新版本文档发布时,该参数均会被更新。 因此,参数 latestversion 并不总是相同。

转换为:

v1.30

{{< latest-semver >}}

{{< latest-semver >}} 短代码可以生成站点参数 latest 不含前缀 v 的版本号取值。

转换为:

1.30

{{< version-check >}}

{{< version-check >}} 会检查是否设置了页面参数 min-kubernetes-server-version 并将其与 version 进行比较。

转换为:

要获知版本信息,请输入 kubectl version.

{{< latest-release-notes >}}

{{< latest-release-notes >}} 短代码基于站点参数 latest 生成不含前缀 v 的版本号取值,并输出该版本更新日志的超链接地址。

转换为:

https://git.k8s.io/kubernetes/CHANGELOG/CHANGELOG-1.30.md

接下来

8 - 进阶贡献

如果你已经了解如何贡献新内容评阅他人工作,并准备了解更多贡献的途径, 请阅读此文。你需要使用 Git 命令行工具和其他工具做这些工作。

提出改进建议

SIG Docs 的成员可以提出改进建议。

在对 Kubernetes 文档贡献了一段时间后,你可能会对样式指南内容指南、用于构建文档的工具链、网站样式、 评审和合并 PR 的流程或者文档的其他方面产生改进的想法。 为了尽可能透明化,这些提议都需要在 SIG Docs 会议或 kubernetes-sig-docs 邮件列表上讨论。 此外,在提出全面的改进之前,这些讨论能帮助我们了解有关“当前工作如何运作”和“以往的决定是为何做出”的背景。 想了解文档的当前运作方式,最快的途径是咨询 kubernetes.slack.com 中的 #sig-docs 聊天群组。

在进行了讨论并且 SIG 就期望的结果达成一致之后,你就能以最合理的方式处理改进建议了。 例如,样式指南或网站功能的更新可能涉及 PR 的新增,而与文档测试相关的更改可能涉及 sig-testing。

为 Kubernetes 版本发布协调文档工作

SIG Docs 的批准人(Approver) 可以为 Kubernetes 版本发布协调文档工作。

每一个 Kubernetes 版本都是由参与 sig-release 的 SIG(特别兴趣小组)的一个团队协调的。 指定版本的发布团队中还包括总体发布牵头人,以及来自 sig-testing 的代表等。 要了解更多关于 Kubernetes 版本发布的流程,请参考 https://github.com/kubernetes/sig-release

SIG Docs 团队的代表需要为一个指定的版本协调以下工作:

  • 通过特性跟踪表来监视新功能特性或现有功能特性的修改。 如果版本的某个功能特性的文档没有为发布做好准备,那么该功能特性不允许进入发布版本。
  • 定期参加 sig-release 会议并汇报文档的发布状态。
  • 评审和修改由负责实现某功能特性的 SIG 起草的功能特性文档。
  • 合入版本发布相关的 PR,并为对应发布版本维护 Git 特性分支。
  • 指导那些想学习并有意愿担当该角色的 SIG Docs 贡献者。这就是我们常说的“实习”。
  • 发布版本的组件发布时,相关的文档更新也需要发布。

协调一个版本发布通常需要 3-4 个月的时间投入,该任务由 SIG Docs 批准人轮流承担。

担任新的贡献者大使

SIG Docs 批准人(Approver) 可以担任新的贡献者大使。

新的贡献者大使欢迎 SIG-Docs 的新贡献者,对新贡献者的 PR 提出建议, 以及在前几份 PR 提交中指导新贡献者。

新的贡献者大使的职责包括:

  • 监听 Kubernetes #sig-docs 频道 上新贡献者的 Issue。
  • 与 PR 管理者合作为新参与者寻找合适的第一个 issue
  • 通过前几个 PR 指导新贡献者为文档存储库作贡献。
  • 帮助新的贡献者创建成为 Kubernetes 成员所需的更复杂的 PR。
  • 为贡献者提供保荐,使其成为 Kubernetes 成员。
  • 每月召开一次会议,帮助和指导新的贡献者。

当前新贡献者大使将在每次 SIG 文档会议上以及 Kubernetes #sig-docs 频道中宣布。

SIG Docs 的评审人(Reviewer) 可以为新的贡献者提供保荐。

新的贡献者针对一个或多个 Kubernetes 项目仓库成功提交了 5 个实质性 PR 之后, 就有资格申请 Kubernetes 组织的成员身份。 贡献者的成员资格需要同时得到两位评审人的保荐。

新的文档贡献者可以通过咨询 Kubernetes Slack 实例 上的 #sig-docs 频道或者 SIG Docs 邮件列表 来请求评审者保荐。如果你对申请人的工作充满信心,你自愿保荐他们。 当他们提交成员资格申请时,回复 “+1” 并详细说明为什么你认为申请人适合加入 Kubernetes 组织。

SIG Docs 成员(Member) 可以担任 SIG Docs 的联合主席。

前提条件

Kubernetes 成员必须满足以下要求才能成为联合主席:

职责范围

联合主席的角色提供以下服务:

  • 拓展贡献者规模
  • 处理流程和政策
  • 安排时间和召开会议
  • 安排 PR 管理员
  • 在 Kubernetes 社区中提出文档倡议
  • 确保文档在 Kubernetes 发布周期中符合预期
  • 让 SIG Docs 专注于有效的优先事项

职责范围包括:

  • 保持 SIG Docs 专注于通过出色的文档最大限度地提高开发人员的满意度
  • 以身作则,践行社区行为准则, 并要求 SIG 成员对自身行为负责
  • 通过更新贡献指南,为 SIG 学习并设置最佳实践
  • 安排和举行 SIG 会议:每周状态更新,每季度回顾/计划会议以及其他需要的会议
  • 在 KubeCon 活动和其他会议上安排和负责文档工作
  • CNCF 及其尊贵合作伙伴 (包括 Google、Oracle、Azure、IBM 和华为)一起以 SIG Docs 的身份招募和宣传
  • 负责 SIG 正常运行

召开高效的会议

为了安排和召开高效的会议,这些指南说明了如何做、怎样做以及原因。

坚持社区行为准则

  • 相互尊重地、包容地进行讨论。

设定明确的议程

  • 设定清晰的主题议程
  • 提前发布议程

对于每周一次的会议,请将前一周的笔记复制并粘贴到笔记的“过去的会议”部分中

通过协作,完成准确的记录

  • 记录会议讨论
  • 考虑委派笔记记录员的角色

清晰准确地分配执行项目

  • 记录操作项,分配给它的人员以及预期的完成日期

根据需要来进行协调

  • 如果讨论偏离议程,请让参与者重新关注当前主题
  • 为不同的讨论风格留出空间,同时保持讨论重点并尊重人们的时间

尊重大家的时间:

按时开始和结束会议

有效利用 Zoom

声明 Zoom 主持人角色

录制 Zoom 会议

准备开始录制时,请单击“录制到云”。

准备停止录制时,请单击“停止”。

视频会自动上传到 YouTube。

SIG 联合主席 (Emeritus) 离职

参见 k/community/sig-docs/offboarding.md

9 - 查看站点分析

此页面包含有关 kubernetes.io 分析仪表板的信息。

查看仪表板

此仪表板使用 Google Data Studio 构建,显示使用 Google Analytics 在 kubernetes.io 上收集的信息。

使用仪表板

默认情况下,仪表板显示过去 30 天收集的所有分析。 使用日期选择器查看来自不同日期范围的数据。 其他过滤选项允许你根据用户位置、用于访问站点的设备、所用文档的翻译等查看数据。

如果你发现此仪表板存在问题,或者想要请求任何改进, 请开启一个问题

10 - 中文本地化样式指南

本节详述文档中文本地化过程中须注意的事项。 这里列举的内容包含了中文本地化小组早期给出的指导性建议和后续实践过程中积累的经验。 在阅读、贡献、评阅中文本地化文档的过程中,如果对本文的指南有任何改进建议, 都请直接提出 PR。我们欢迎任何形式的补充和更正!

一般规定

本节列举一些译文中常见问题和约定。

英文原文的保留

为便于译文审查和变更追踪,所有中文本地化 Markdown 文件中都应使用 HTML 注释 <!----> 将英文原文逐段注释起来,后跟对应中文译文。例如:

<!--
This is English text ... 
-->
中文译文对应 ...

不建议采用下面的方式注释英文段落,除非英文段落非常非常短:

<!-- This is English text ...  -->
中文译文对应 ...

无论英文原文或者中文译文中,都不要保留过多的、不必要的空白行。

段落划分

请避免大段大段地注释和翻译。一般而言,每段翻译可对应两三个自然段。 段落过长会导致译文很难评阅。但也不必每个段落都单独翻译。例如:

<!--
## Overview

### Concept

First paragraph, not very long.
-->
## 概述 {#overview}

### 概念 {#concept}

第一段落,不太长。

以下风格是不必要的:

<!--
## Overview
-->
## 概述 {#overview}

<!--
### Concept
-->
### 概念 {#concept}

<!--
First paragraph, not very long.
-->
第一段落,不太长。

编号列表的处理

编号列表需要编号的连续性,处理不好的话可能导致输出结果错误。 由于有些列表可能很长,一次性等将整个列表注释掉再翻译也不现实。 推荐采用下面的方式。

假定英文为:

1. Prepare something
1. Followed by a long step with code snippets and notes ...
   this is a really long item
1. Another long item ...
   .. continues here
1. Almost done ...

本地化处理:

<!--
1. Prepare something
-->
1. 准备工作,...
   这里每行缩进 3 个空格

<!--
1. Followed by a long step with code snippets and notes ...
   this is a really long item
-->
2. 这里是第二个编号,但需要显式给出数字,不能沿用英文编号。
   缩进内容同上,3 个空格。
   即使有三个反引号的代码段或者短代码,都按 3 个空格缩进。

<!--
1. Another long item ...
   .. continues here
1. Almost done ...
-->
3. 继续列表。

   如果条目有多个段落,也要
   保持缩进对齐以确保排版正确。

4. 列表终于结束

Frontmatter 的处理

页面中的 Frontmatter 指的是文件头的两个 --- 中间的部分。 对这一部分,解析器有特殊处理,因此不能将英文部分放在前面,中文跟在后面。 需要将二者顺序颠倒。如下所示:

---
title: 译文标题
type: concept
weight: 30
---

<!--
title: English title
type: concept
reviewers:
  - john
  - doe
weight: 30
-->

这里要注意的是:

  • titledescription 的内容要翻译,其他字段一般不必(甚至不可)翻译。
  • reviewers 部分要删除,不然中文译文会转给英文作者来审阅。

短代码(shortcode)处理

通过 HTML 注释的短代码仍会被运行,因此需要额外小心。建议处理方式:

{{< note >}}
<!--
English text
-->
中文译文
{{< /note >}}

博客译者署名

翻译一篇博客需要花费大量的时间和精力,添加署名是对译者工作的认可, 也有利于激励贡献者同步英文博客,提升博客质量。 如要添加译者署名,可在作者下面一行添加译者相关内容。例如:

<!--
**Author**: Alice (Google)
-->
**作者** :Alice (Google)

**译者** :李明 (百度)  

译与不译

资源名称或字段不译

根据英文原文写作风格约定【也在持续修订改进】,对 Kubernetes 中的 API 资源均按其规范中所给的大小写形式书写,例如:英文中会使用 Deployment 而不是 deployment 来表示名为 "Deployment" 的 API 资源类型和对象实例。

对这类词语,一般不应翻译。

代码中的注释

一般而言,代码中的注释需要翻译,包括存放在 content/zh-cn/examples/ 目录下的清单文件中的注释。

如果超级链接的目标是 Kubernetes 网站之外的纯英文网页,链接中的内容可以不翻译。 例如:

<!--
Please check [installation caveats](https://acme.com/docs/v1/caveats) ...
-->
请参阅 [installation caveats](https://acme.com/docs/v1/caveats) ...

标点符号

  1. 译文中标点符号要使用全角字符,除非以下两种情况:

    • 标点符号是英文命令的一部分;
    • 标点符号是 Markdown 语法的一部分。
  2. 英文排比句式中采用的逗号,在译文中要使用顿号代替,以便符合中文书写习惯。

更新译文

由于整个文档站点会随着 Kubernetes 项目的开发进展而演化,英文版本的网站内容会不断更新。 鉴于中文站点的基本翻译工作在 1.19 版本已完成, 从 1.20 版本开始本地化的工作会集中在追踪英文内容变化上。

为确保准确跟踪中文化版本与英文版本之间的差异,中文内容的 PR 所包含的每个页面都必须是“最新的”。 这里的“最新”指的是对应的英文页面中的更改已全部同步到中文页面。 如果某中文 PR 中包含对 content/zh-cn/docs/foo/bar.md 的更改,且文件 bar.md 的上次更改日期是 2020-10-01 01:02:03 UTC,对应 GIT 标签 abcd1234, 则 bar.md 应包含自 abcd1234 以来 content/en/docs/foo/bar.md 的所有变更, 否则视此 PR 为不完整 PR,会破坏我们对上游变更的跟踪。

这一要求适用于所有更改,包括拼写错误、格式更正、链接修订等等。要查看文件 bar.md 上次提交以来发生的所有变更,可使用:

./scripts/lsync.sh content/zh-cn/docs/foo/bar.md

链接锚点

英文 Markdown 中的各级标题会自动生成锚点,以便从其他页面中链接。 在译为中文后,相应的链接必然会失效。为防止这类问题, 建议在翻译各级标题时,使用英文方式显式给出链接锚点。例如:

<!--
### Create a Pod
-->
### 创建 Pod   {#create-a-pod}

此类问题对于概念部分的页面最为突出,需要格外注意。

由于大部分页面已经完成中文本地化,这意味着很多链接可以使用中文版本作为目标。 例如:

<!--
For more information, please check [volumes](/docs/concepts/storage/)
...
-->
更多的信息可参考[卷](/zh-cn/docs/concepts/storage/)页面。

如果对应目标页面尚未本地化,建议登记一个 Issue。

排版格式

以下为译文 Markdown 排版格式要求:

  • 中英文之间留一个空格

    • 这里的“英文”包括以英文呈现的超级链接
    • 这里的中文、英文都不包括标点符号
  • 译文 Markdown 中不要使用长行,应适当断行。

    • 可根据需要在 80-120 列断行
    • 最好结合句子的边界断行,即一句话在一行,不必留几个字转到下一行
    • 不要在两个中文字符中间断行,因为这样会造成中文字符中间显示一个多余空格, 如果句子太长,可以从中文与非中文符号之间断行
    • 超级链接文字一般较长,可独立成行
  • 英文原文中可能通过 _text_ 或者 *text* 的形式用斜体突出部分字句。 考虑到中文斜体字非常不美观,在译文中应改为 **译文** 形式, 即用双引号语法生成加粗字句,实现突出显示效果。

特殊词汇

英文中 "you" 翻译成 "你",不必翻译为 "您" 以表现尊敬或谦卑。

术语拼写

按中文译文习惯,尽量不要在中文译文中使用首字母小写的拼写。例如:

列举所有 pods,查看其创建时间 ...       [No]
列举所有 Pod,查看其创建时间 ...        [Yes]

第一次使用首字母缩写时,应标注其全称和中文译文。例如:

你可以创建一个 Pod 干扰预算(Pod Disruption Budget,PDB)来解决这一问题。
所谓 PDB 实际上是 ...

对于某些特定于 Kubernetes 语境的术语,也应在第一次出现在页面中时给出其英文原文, 以便读者对照阅读。例如:

镜像策略(Image Policy)用来控制集群可拉取的镜像仓库(Image Registry)源。

术语对照

本节列举常见术语的统一译法。除极个别情况,对于专业术语应使用本节所列举的译法:

  • API Server,API 服务器
  • GA (general availability),正式发布
  • addons,插件
  • admission controller,准入控制器
  • affinity,亲和性
  • annotation,注解
  • anti-affinity,反亲和性
  • attach,挂接
  • authenticate,身份验证
  • authorize,授权或鉴权
    • 将权限授予某主体时,译为“授权”
    • 根据某些参数/条件来确定具有哪些权限时,译为“鉴权”
  • authorizer,鉴权器
  • autoscale,自动扩缩容
  • bearer token,持有者令牌
  • capabilities
    • 当泛指某主体执行某操作的能力时,可直译为“能力”
    • 当特指 Linux 操作系统上的权限控制机制时,译为“权能字”
  • certificate authority,证书机构
  • certificate,证书
  • claim,申领
  • cloud provider
    • 当用来指代下层云服务的提供厂商时,译为“云服务供应商”
    • 当特指 Kubernetes 中对不同云平台的支持时,可酌情译为“云驱动”
  • cluster,集群
  • condition
    • 大多数上下文中,可译为“条件”
    • 在讨论 Kubernetes 资源的 condition 时,应译为“状况”
  • control loop,控制回路
  • control plane,控制平面,或控制面
  • controller,控制器
  • controller manager,控制器管理器
  • credential,登录凭据,凭据
  • custom,定制,或自定义
  • daemon,守护进程
  • dashboard,仪表板
  • dependent,附属或附属者
  • deprecated,已弃用的
  • deprecation,弃用
  • desired,预期的
  • desired state,预期状态
  • detach,解除挂接
  • distribution,发行版本
  • disruption,干扰(请勿译为“中断”)
  • drain,腾空
  • endpoint,端点
  • egress,出站
  • evict,驱逐
  • eviction,驱逐
  • feature gate,特性门控
  • federation,联邦
  • flags,命令行参数,参数
  • grace period,宽限期限
  • graceful termination,体面终止
  • hairpin,发夹
  • hash,哈希
  • headless service,无头服务
  • healthcheck,健康检查
  • hook,回调
  • host,主机,宿主机
  • hosting,托管
  • idempotent,幂等的
  • image,镜像
  • image registry,镜像仓库
  • ingress,入站
  • init container,Init 容器
  • key
    • 在加密解密、安全认证上下文中,译为密钥
    • 在配置文件、数据结构上下文中,译为主键,或键
  • label,标签
  • label selector,标签选择算符
  • lifecycle,生命周期
  • limit,限制,限值
  • liveness probe,存活态探针
  • load balance,负载均衡
  • load balancer,负载均衡器
  • log flush,清刷日志数据
  • loopback,本地回路
  • manifest,清单,清单文件
  • master node,主控节点
  • metric
    • 用来指代被测量的数据源时,译为指标
    • 用来指代测量观测结果时,译为度量值
  • mount,挂载
  • namespace,名字空间,命名空间
  • orphans,孤立或孤立的
  • override,覆写
  • owner,所有者,属主
  • pending,悬决的
  • persistent volume,持久卷
  • persistent volume claim,持久卷申领
  • pipeline,流水线
  • prerequisites,依赖,前提条件(根据上下文判断)
  • priority class,优先级类
  • probe,探针
  • provision,供应
  • pull,拉取
  • push,推送
  • quota,配额
  • readiness probe,就绪态探针
  • replica,副本
  • repo,仓库
  • repository,仓库
  • revision,修订版本
  • role,角色
  • role binding,角色绑定
  • rolling update,滚动更新
  • rollout,上线
  • rotate,轮换
  • round robin,轮转
  • runtime,运行时
  • scale in/out,横向缩容/扩容
  • scale up/down,纵向扩容/缩容
  • scale
    • 做动词用时,译为“扩缩”,或者“改变...的规模”
    • 做名词用时,译为“规模”
  • scheduler,调度器
  • service,服务
  • service account,服务账号
  • service account token,服务账号令牌
  • service discovery,服务发现
  • service mesh,服务网格
  • session,会话
  • sidecar,边车
  • skew,偏移
  • spec,规约
  • specification,规约
  • startup probe,启动探针
  • stateless,无状态的
  • static pod,静态 Pod
  • stderr,标准错误输出
  • stdin,标准输入
  • stdout,标准输出
  • storage class,存储类
  • taint,污点
  • threshold,阈值
  • toleration,容忍度
  • topology,拓扑
  • topology spread constraint,拓扑分布约束
  • traffic,流量
    • 在某些上下文中,可以根据情况译为“服务请求”,“服务响应”
  • unmount,卸载
  • use case,用例,使用场景
  • volume,卷
  • worker node,工作节点
  • workload,工作负载