 --- title: 图表指南 linktitle: 图表指南 content_type: concept weight: 15 ---    本指南为你展示如何创建、编辑和分享基于 Mermaid Javascript 库的图表。 Mermaid.js 允许你使用简单的、类似于 Markdown 的语法来在 Markdown 文件中生成图表。 你也可以使用 Mermaid 来创建 `.svg` 或 `.png` 图片文件，将其添加到你的文档中。 本指南的目标受众是所有希望了解 Mermaid 的用户，以及那些想了解如何创建图表并将其添加到 Kubernetes 文档中的用户。 图 1 概要介绍的是本节所涉及的话题。 {{< mermaid >}} 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 {{< /mermaid >}}  图 1. 本节中涉及的话题.  开始使用 Mermaid 之前，你需要以下准备： * 对 Markdown 有一个基本的了解 * 使用 Mermaid 在线编辑器 * 使用 [Hugo 短代码（shortcode）](/zh/docs/contribute/style/hugo-shortcodes/) * 使用 [Hugo {{</* figure */>}} 短代码](https://gohugo.io/content-management/shortcodes/#figure) * 执行 [Hugo 本地预览](/zh/docs/contribute/new-content/open-a-pr/#preview-locally) * 熟悉[贡献新内容](/zh/docs/contribute/new-content/)的流程 {{< note >}}  你可以点击本节中的每个图表来查看其源代码，以及在 Mermaid 在线编辑器中渲染的图表结果。 {{< /note >}}   ## 你为什么应该在代码中使用图表 图表可以增进文档的清晰度，便于理解。对于用户和贡献者而言都有好处。  用户获得的好处有： * __较为友好的初次体验__：非常详尽的、只包含文本的欢迎页面对用户而言是蛮恐怖的， 尤其是初次接触 Kubernetes 的用户。 * __快速理解概念__：图表可以帮助用户理解复杂主题下的要点。 你的图表可以作为一种可视化的学习指南，将用户带入主题的细节。 * __便于记忆__：对某些人而言，图形（图像）要比文字更容易记忆。  对贡献者而言的好处有： * __帮助确立所贡献文档的结构和内容__。例如， 你可以先提供一个覆盖所有顶层要点的图表，然后再逐步展开细节。 * __培养用户社区并提升其能力__ 容易理解的文档，附以图表，能够吸引新的用户， 尤其是那些因为预见到复杂性而不愿参与的用户。  你需要考虑你的目标受众。除了一些有经验的 K8s 用户外，你还会遇到很多刚接触 Kubernetes 的用户。即使一张简单的图表也可以帮助新用户吸收 Kubernetes 概念。 他们会变得更为大胆和自信，进一步地了解 Kubernetes 及其文档。 ## Mermaid  [Mermaid](https://mermaid-js.github.io/mermaid/#/) 是一个开源的 JavaScript 库， 可以帮助你创建、编辑并很容易地分享图表。这些图表使用简单的、类似 Markdown 的语法开发，并可内嵌到 Markdown 文件中。  下面是 Mermaid 的一些特性： * 简单的编码语法 * 包含基于 Web 的工具，便于你编制和预览你的图表 * 支持包括流程图、状态图、时序图在内的多种格式 * 可以通过共享图表的 URL 来与同事方便地合作 * 有丰富的形状、线条、主题和样式可供选择  使用 Mermaid 的一些好处如下： * 不需要使用另外的、非 Mermaid 的图表工具 * 与现有的 PR 工作流结合的很好。你可以将 Mermaid 代码视为你的 PR 中所包含的 Markdown 文本 * 简单的工具生成简单的图表。你不需要精心制作或雕琢过于复杂或详尽的图片。 保持简单就好。  Mermaid 提供一种简单的、开放且透明的方法，便于 SIG 社区为新的或现有的文档添加、 编辑图表并展开协作。 {{< note >}}  即使你的工作环境中不支持，你仍然可以使用 Mermaid 来创建、编辑图表。 这种方法称作 __Mermaid+SVG__，在后文详细解释。 {{< /note >}}  ### 在线编辑器 [Mermaid 在线编辑器](https://mermaid-js.github.io/mermaid-live-editor)是一个基于 Web 的工具，允许你创建、编辑和审阅图表。  在线编辑器的功能主要有： * 显示 Mermaid 代码和渲染的图表。 * 为所保存的每个图表生成一个 URL。该 URL 显示在你的浏览器的 URL 字段中。 你可以将 URL 分享给同事，便于他人访问和更改图表。 * 提供将图表下载为 `.svg` 或 `.png` 文件的选项。 {{< note >}}  在线编辑器是创建和编辑 Mermaid 图表的最简单的，也是最快的方式。 {{< /note >}}  ## 创建图表的方法   {#methods-for-creating-diagrams} 图 2 给出三种生成和添加图表的方法。 {{< mermaid >}} 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 {{< /mermaid >}}  图 2. 创建图表的方法  ### 内嵌（Inline） 图 3 给出的是使用内嵌方法来添加图表所遵循的步骤。 {{< mermaid >}} 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 {{< /mermaid >}}  图 3. 内嵌方法的步骤  下面是使用内嵌方法来添加图表时你要执行的步骤： 1. 使用在线编辑器创建你的图表 1. 将图表的 URL 保存在某处以便以后访问 1. 将 Mermaid 代码复制到你的 `.md` 文件中你希望它出现的位置 1. 使用 Markdown 文本在图表下方为其添加标题  Hugo 在构造（网站）过程中会运行 Mermaid 代码，将其转换为图表。 {{< note >}}  你可能认为记录图表 URL 是一个麻烦的过程。如果确实如此，你可以在 `.md` 文件中作一个记录， 标明该 Mermaid 代码是自说明的。贡献者可以将 Mermaid 代码复制到在线编辑器中编辑， 或者将其从在线编辑器中复制出来。 {{< /note >}}  下面是一段包含在某 `.md` 文件中的示例代码片段： ``` --- title: 我的文档 --- Figure 17 给出从 A 到 B 的一个简单流程。 这里是其他 markdown 文本 ... {{</* mermaid */>}} graph TB A --> B {{</* /mermaid */>}} 图 17. 从 A 到 B 其他文本 ``` {{< note >}}  你必须在 Mermaid 代码块之前和之后分别添加 `{{</*  mermaid */>}}`、`{{</* /mermaid */>}}` 短代码标记，而且你应该在图表之后为其添加图表标题。 {{< /note >}}  有关添加图表标题的细节，参阅[如何使用标题](#how-to-use-captions)。  使用内嵌方法的好处有： * 可以直接使用在线编辑器工具 * 很容易在在线编辑器与你的 `.md` 文件之间来回复制 Mermaid 代码 * 不需要额外处理 `.svg` 图片文件 * 内容文字、图表代码和图表标题都位于同一个 `.md` 文件中。  你应该使用[本地](/zh/docs/contribute/new-content/open-a-pr/#preview-locally)和 Netlify 预览来验证图表是可以正常渲染的。 {{< caution >}}  Mermaid 在线编辑器的功能特性可能不支持 K8s 网站的 Mermaid 特性。 你可能在 Hugo 构建过程中看到语法错误提示或者空白屏幕。 如果发生这类情况，可以考虑使用 Mermaid+SVG 方法。 {{< /caution >}} ### Mermaid+SVG  图 4 给出的是使用 Mermaid+SVG 方法添加图表所要遵循的步骤： {{< mermaid >}} 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 {{< /mermaid >}}  图 4. Mermaid+SVG 方法的步骤。  使用 Mermaid+SVG 方法来添加图表时你要遵从的步骤： 1. 使用在线编辑器创建你的图表 1. 将图表的 URL 保存到某处以便以后访问 1. 为你的图表生成 `.svg` 文件，并将其下载到合适的 `images/` 目录下 1. 使用 `{{</* figure */>}}` 短代码在 `.md` 文件中引用该图表 1. 使用 `{{</* figure */>}}` 短代码的 `caption` 参数为图表设置标题  例如，使用在线编辑器创建一个名为 `boxnet` 的图表。 将图表的 URL 保存到别处以便以后访问。生成 `boxnet.svg` 文件并将其下载到合适的 `../images/` 目录下。  在你的 PR 中的 `.md` 文件内使用 `{{</* figure */>}}` 短代码来引用 `.svg` 图片文件，并为之添加标题。  ```json {{</* figure src="/static/images/boxnet.svg" alt="Boxnet 示意图" class="diagram-large" caption="图 14. Boxnet 标题" */>}} ```  关于图表标题的细节，可参阅[如何使用标题](#how-to-use-captions)。 {{< note >}}  使用 `{{</* figure */>}}` 短代码是向你的文档中添加 `.svg` 图片文件的优选方法。 你也可以使用标准的 markdown 图片语法，即 `![my boxnet diagram](static/images/boxnet.svg)`。 如果是后面这种，则需要在图表下面为其添加标题。 {{< /note >}}  你应该使用文本编辑器以注释块的形式在 `.svg` 图片文件中添加在线编辑器的 URL。 例如，你应该在 `.svg` 图片文件的开头部分包含下面的内容： ``` <!-- 要查看或者编辑 Mermaid 代码，可访问下面的 URL：--> <!-- https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb ... <URL 的其余部分> --> ```  使用 Mermaid+SVG 方法的好处有： * 可以直接使用在线编辑器工具 * 在线编辑器支持的 Mermaid 特性集合最新 * 可以利用 K8s 网站用来处理 `.svg` 图片文件的现有方法 * 工作环境不需要 Mermaid 支持  要使用[本地](/zh/docs/contribute/new-content/open-a-pr/#preview-locally)和 Netlify 预览来检查你的图表可以正常渲染。  ### 外部工具 图 5 给出使用外部工具来添加图表时所遵循的步骤。 首先，要使用你的外部工具来创建图表，并将其保存为一个 `.svg` 文件或 `.png` 图片文件。 之后，使用 __Mermaid+SVG__ 方法中相同的步骤添加 `.svg`（`.png`）文件。 {{< mermaid >}} 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" {{< /mermaid >}}  图 5. 外部工具方法步骤.  使用外部工具方法来添加图表时，你要遵从的步骤如下： 1. 使用你的外部工具来创建图表。 1. 将图表的位置保存起来供其他贡献者访问。例如，你的工具可能提供一个指向图表的链接， 或者你可以将源码文件（例如一个 `.xml` 文件）放置到一个公开的仓库， 以便其他贡献者访问。 1. 生成图表并将其下载为 `.svg` 或 `.png` 图片文件，保存到合适的 `../images/` 目录下。 1. 使用 `{{</* figure */>}}` 短代码从 `.md` 文件中引用该图表。 5. 使用 `{{</* figure */>}}` 短代码的 `caption` 参数为图表设置标题。  下面是一个用于 `images/apple.svg` 图表的 `{{</* figure */>}}` 短代码：  ```text {{</* figure src="/static/images/apple.svg" alt="red-apple-figure" class="diagram-large" caption="图 9. 一个大红苹果" */>}} ```  如果你的外部绘图工具支持： * 你可以将多个 `.svg` 或 `.png` 商标、图标或图片整合到你的图表中。 不过，你需要确保你查看了版权并遵守了 Kubernetes 文档关于使用第三方内容的 [指南](/zh/docs/contribute/style/content-guide/)。 * 你应该将图表的源位置保存起来，以便其他贡献者访问。 例如，你的工具可能提供指向图表文件的链接，或者你应该将源代码文件 （例如一个 `.xml` 文件）放到某处以便其他贡献者访问。  关于 K8s 和 CNCF 商标与图片的详细信息，可参阅 [CNCF Artwork](https://github.com/cncf/artwork)。  使用外部工具的好处有： * 贡献者对外部工具更为熟悉 * 图表可能需要 Mermaid 所无法提供的细节 不要忘记使用[本地](/zh/docs/contribute/new-content/open-a-pr/#preview-locally) 和 Netlify 预览来检查你的图表可以正常渲染。  ## 示例 本节给出 Mermaid 的若干样例。 {{< note >}}  代码块示例中忽略了 Hugo `{{</*  mermaid */>}}`、`{{</* /mermaid */>}}` 短代码标记。 这样，你就可以将这些代码段复制到在线编辑器中自行实验。 注意，在线编辑器无法识别 Hugo 短代码。 {{< /note >}}  ### 示例 1 - Pod 拓扑分布约束 图 6 展示的是 [Pod 拓扑分布约束](/zh/docs/concepts/workloads/pods/pod-topology-spread-constraints/#node-labels) 页面所出现的图表。 {{< mermaid >}} 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 {{< /mermaid >}}  图 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 是什么](/zh/docs/concepts/services-networking/ingress/#what-is-ingress) 页面所出现的图表。 {{< mermaid >}} 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 {{< /mermaid >}}  图 7. Ingress 代码块： ```mermaid 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 组件间的控制流。 {{< figure src="/docs/images/diagram-guide-example-3.svg" alt="K8s system flow diagram" class="diagram-large" caption="Figure 8. K8s system flow diagram" link="https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiJSV7aW5pdDp7XCJ0aGVtZVwiOlwibmV1dHJhbFwifX0lJVxuc2VxdWVuY2VEaWFncmFtXG4gICAgYWN0b3IgbWVcbiAgICBwYXJ0aWNpcGFudCBhcGlTcnYgYXMgY29udHJvbCBwbGFuZTxicj48YnI-YXBpLXNlcnZlclxuICAgIHBhcnRpY2lwYW50IGV0Y2QgYXMgY29udHJvbCBwbGFuZTxicj48YnI-ZXRjZCBkYXRhc3RvcmVcbiAgICBwYXJ0aWNpcGFudCBjbnRybE1nciBhcyBjb250cm9sIHBsYW5lPGJyPjxicj5jb250cm9sbGVyPGJyPm1hbmFnZXJcbiAgICBwYXJ0aWNpcGFudCBzY2hlZCBhcyBjb250cm9sIHBsYW5lPGJyPjxicj5zY2hlZHVsZXJcbiAgICBwYXJ0aWNpcGFudCBrdWJlbGV0IGFzIG5vZGU8YnI-PGJyPmt1YmVsZXRcbiAgICBwYXJ0aWNpcGFudCBjb250YWluZXIgYXMgbm9kZTxicj48YnI-Y29udGFpbmVyPGJyPnJ1bnRpbWVcbiAgICBtZS0-PmFwaVNydjogMS4ga3ViZWN0bCBjcmVhdGUgLWYgcG9kLnlhbWxcbiAgICBhcGlTcnYtLT4-ZXRjZDogMi4gc2F2ZSBuZXcgc3RhdGVcbiAgICBjbnRybE1nci0-PmFwaVNydjogMy4gY2hlY2sgZm9yIGNoYW5nZXNcbiAgICBzY2hlZC0-PmFwaVNydjogNC4gd2F0Y2ggZm9yIHVuYXNzaWduZWQgcG9kcyhzKVxuICAgIGFwaVNydi0-PnNjaGVkOiA1LiBub3RpZnkgYWJvdXQgcG9kIHcgbm9kZW5hbWU9XCIgXCJcbiAgICBzY2hlZC0-PmFwaVNydjogNi4gYXNzaWduIHBvZCB0byBub2RlXG4gICAgYXBpU3J2LS0-PmV0Y2Q6IDcuIHNhdmUgbmV3IHN0YXRlXG4gICAga3ViZWxldC0-PmFwaVNydjogOC4gbG9vayBmb3IgbmV3bHkgYXNzaWduZWQgcG9kKHMpXG4gICAgYXBpU3J2LT4-a3ViZWxldDogOS4gYmluZCBwb2QgdG8gbm9kZVxuICAgIGt1YmVsZXQtPj5jb250YWluZXI6IDEwLiBzdGFydCBjb250YWluZXJcbiAgICBrdWJlbGV0LT4-YXBpU3J2OiAxMS4gdXBkYXRlIHBvZCBzdGF0dXNcbiAgICBhcGlTcnYtLT4-ZXRjZDogMTIuIHNhdmUgbmV3IHN0YXRlIiwibWVybWFpZCI6IntcbiAgXCJ0aGVtZVwiOiBcImRlZmF1bHRcIlxufSIsInVwZGF0ZUVkaXRvciI6ZmFsc2UsImF1dG9TeW5jIjp0cnVlLCJ1cGRhdGVEaWFncmFtIjp0cnVlfQ" >}}  代码段： ``` %%{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](https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggIExSXG4gIGNsaWVudChbY2xpZW50XSktLiBJbmdyZXNzLW1hbmFnZWQgPGJyPiBsb2FkIGJhbGFuY2VyIC4tPmluZ3Jlc3NbSW5ncmVzc107XG4gIGluZ3Jlc3MtLT58cm91dGluZyBydWxlfHNlcnZpY2VbU2VydmljZV07XG4gIHN1YmdyYXBoIGNsdXN0ZXJcbiAgaW5ncmVzcztcbiAgc2VydmljZS0tPnBvZDFbUG9kXTtcbiAgc2VydmljZS0tPnBvZDJbUG9kXTtcbiAgZW5kXG4gIGNsYXNzRGVmIHBsYWluIGZpbGw6I2RkZCxzdHJva2U6I2ZmZixzdHJva2Utd2lkdGg6NHB4LGNvbG9yOiMwMDA7XG4gIGNsYXNzRGVmIGs4cyBmaWxsOiMzMjZjZTUsc3Ryb2tlOiNmZmYsc3Ryb2tlLXdpZHRoOjRweCxjb2xvcjojZmZmO1xuICBjbGFzc0RlZiBjbHVzdGVyIGZpbGw6I2ZmZixzdHJva2U6I2JiYixzdHJva2Utd2lkdGg6MnB4LGNvbG9yOiMzMjZjZTU7XG4gIGNsYXNzIGluZ3Jlc3Msc2VydmljZSxwb2QxLHBvZDIgazhzO1xuICBjbGFzcyBjbGllbnQgcGxhaW47XG4gIGNsYXNzIGNsdXN0ZXIgY2x1c3RlcjtcbiIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6dHJ1ZX0) 中，你可以看到这两种示例。  ``` classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff; // 定义 k8s 类的样式 class ingress,service,pod1,pod2 k8s; // k8s 类会应用到 ingress, service, pod1 and pod2 这些元素之上 ```  你可以在你的图表中包含一个或多个 `classDef` 和 `class` 语句。 你也可以在你的图表中为 k8s 组件使用官方的 K8s `#326ce5` 十六进制颜色代码。 关于样式设置和类的更多信息，可参阅 [Mermaid Styling and classes docs](https://mermaid-js.github.io/mermaid/#/flowchart?id=styling-and-classes)。  ## 如何使用标题   {#how-to-use-captions}  标题用来为图表提供简要的描述。标题或短描述都可以作为图表标题。 标题不是用来替换你在文档中要提供的解释性文字。 相反，它们是用来在文字与图表之间建立“语境连接”的。  将一些文字和带标题的图表组合到一起，可以为你所想要向用户传递的信息提供一种更为精确的表达。 没有标题的话，用户就必须在图表前后的文字中来回阅读，从而了解其含义。 这会让用户感觉到很沮丧。  图 9 给出合适的标题所需要具备的三要素：图表、图表标题和图表引用。 {{< mermaid >}} 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 {{< /mermaid >}}  图 9. 标题要素 {{< note >}}  你应该总是为文档中的每个图表添加标题。 {{< /note >}}  **图表本身** Mermaid+SVG 和外部工具方法都会生成 `.svg` 图片文件。 下面的 `{{</* figure */>}}` 短代码是针对定义在保存于 `/images/docs/components-of-kubernetes.svg` 中的 `.svg` 图片文件的。 ```none {{</* figure src="/images/docs/components-of-kubernetes.svg" alt="运行于集群中的 Kubernetes Pod" class="diagram-large" caption="图 4. Kubernetes 结构组件" */>}} ```  你需要将 `src`、`alt`、`class` 和 `caption` 取值传递给 `{{</* figure */>}}` 短代码。 你可以使用 `diagram-large`、`diagram-medium` 和 `diagram-small` 类来调整图表的尺寸。 {{< note >}}  使用内嵌方法来创建的图表不使用 `{{</* figure */>}}` 短代码。 Mermaid 代码定义该图表将如何在页面上渲染。 {{< /note >}}  关于创建图表的不同方法，可参阅[创建图表的方法](#methods-for-creating-diagrams)。  **图表标题** 接下来，添加图表标题。 如果你使用 `.svg` 图片文件来定义你的图表，你就需要使用 `{{</* figure */>}}` 短代码的 `caption` 参数。  ```none {{</* figure src="/images/docs/components-of-kubernetes.svg" alt="运行于集群中的 Kubernetes Pod" class="diagram-large" caption="图 4. Kubernetes 架构组件" */>}} ```  如果你使用内嵌的 Mermaid 代码来定义图表，则你需要使用 Markdown 文本来添加标题。 ```none 图 4. Kubernetes 架构组件 ```  添加图表标题时需要考虑的问题： * 使用 `{{</* figure */>}}` 短代码来为 Mermaid+SVG 和外部工具方法制作的图表添加标题。 * 对于内嵌方法制作的图表，使用简单的 Markdown 文本来为其添加标题。 * 在你的图表标题前面添加 `图 <编号>.`. 你必须使用 `图` 字样， 并且编号必须对于文档页面中所有图表而言唯一。 在编号之后添加一个英文句号。 * 将图表标题添加到 `图 <编号>.` 之后，并且在同一行。 你必须为图表标题添加英文句点作为其结束标志。尽量保持标题文字简短。 * 图表标题要放在图表 __之后__。  **图表引用** 最后，你可以添加图表引用。图表引用位于你的文档正文中，并且应该出现在图表之前。 这样，用户可以将你的文字与对应的图表关联起来。引用时所给的 `图 <编号>` 部分要与图表标题中对应部分一致。  你要避免使用空间上的相对引用，例如 `..下面的图片..` 或者 `..下面的图形..`。  ```text 图 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/docs/concepts/overview/components/" */>}} ```  {{
}}  ## 提示  {#tips} * 总是使用在线编辑器来创建和编辑你的图表。 * 总是使用 Hugo 本地和 Netlify 预览来检查图表在文档中的渲染效果。 * 提供图表源代码指针，例如 URL、源代码位置或者标明代码时是说明的。  * 总是提供图表标题。 * 在问题报告或 PR 中包含 `.svg` 或 `.png` 图片与/或 Mermaid 代码会很有帮助。 * 对于 Mermaid+SVG 方法和外部工具方法而言，尽量使用 `.svg` 图片文件， 因为这类文件在被放大之后仍能清晰地显示。 * 对于 `.svg` 文件的最佳实践是将其加载到一个 SVG 编辑工具中，并使用 “将文字转换为路径”功能完成转换。  * Mermaid 不支持额外的图表或艺术形式。 * Hugo Mermaid 短代码在在线编辑器中无法显示。 * 如果你想要在在线编辑器中更改图表，你 __必须__ 保存它以便为图表生成新的 URL。 * 点击本节中的图表，你可以查看其源代码及其在在线编辑器中的渲染效果。  * 查看本页的源代码，`diagram-guide.md` 文件，可以将其作为示例。 * 查阅 [Mermaid docs](https://mermaid-js.github.io/mermaid/#/) 以获得更多的解释和示例。  最重要的一点，__保持图表简单__。 这样做会节省你和其他贡献者的时间，同时也会方便新的以及有经验的用户阅读。


``` At the bottom of the output, there are messages indicating that the liveness <del> probes have failed, and the containers have been killed and recreated. </del> <ins> probes have failed, and the failed containers have been killed and recreated. </ins> ``` Type     Reason     Age                From               Message


kubectl get pod liveness-exec ``` <del> The output shows that `RESTARTS` has been incremented: </del> <ins> The output shows that `RESTARTS` has been incremented. Note that the `RESTARTS` counter increments as soon as a failed container comes back to the running state: </ins> ``` NAME            READY     STATUS    RESTARTS   AGE


EOF ``` <del> 1. Configure your kubelet on the node to use this directory by running it with </del> <ins> 1. Configure the kubelet on that node to set a `staticPodPath` value in the [kubelet configuration file](/docs/reference/config-api/kubelet-config.v1beta1/). See [Set Kubelet Parameters Via A Configuration File](/docs/tasks/administer-cluster/kubelet-config-file/) for more information. An alternative and deprecated method is to configure the kubelet on that node to look for static Pod manifests locally, using a command line argument. To use the deprecated approach, start the kubelet with the </ins> `--pod-manifest-path=/etc/kubernetes/manifests/` argument. <del> On Fedora, edit `/etc/kubernetes/kubelet` to include this line: ``` KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --pod-manifest-path=/etc/kubernetes/manifests/" ``` or add the `staticPodPath: <the directory>` field in the [kubelet configuration file](/docs/reference/config-api/kubelet-config.v1beta1/). </del> 1. Restart the kubelet. On Fedora, you would run: ```shell


## インフラストラクチャ * [KubeVirt](https://kubevirt.io/user-guide/#/installation/installation)は仮想マシンをKubernetes上で実行するためのアドオンです。通常、ベアメタルのクラスタで実行します。 <ins> * [node problem detector](https://github.com/kubernetes/node-problem-detector)はLinuxノード上で動作し、システムの問題を[Event](/docs/reference/kubernetes-api/cluster-resources/event-v1/)または[ノードのCondition](/ja/docs/concepts/architecture/nodes/#condition)として報告します。 </ins> ## レガシーなアドオン


## Create a CustomResourceDefinition When you create a new CustomResourceDefinition (CRD), the Kubernetes API Server <del> creates a new RESTful resource path for each version you specify. The CRD can be either namespaced or cluster-scoped, as specified in the CRD's `scope` field. As with existing built-in objects, deleting a namespace deletes all custom objects in that namespace. CustomResourceDefinitions themselves are non-namespaced and are available to all namespaces. </del> <ins> creates a new RESTful resource path for each version you specify. The custom resource created from a CRD object can be either namespaced or cluster-scoped, as specified in the CRD's `spec.scope` field. As with existing built-in objects, deleting a namespace deletes all custom objects in that namespace. CustomResourceDefinitions themselves are non-namespaced and are available to all namespaces. </ins> For example, if you save the following CustomResourceDefinition to `resourcedefinition.yaml`:


locality, inter-workload interference, and so on. --> 在做调度决定时需要考虑的因素包括：单独和整体的资源请求、硬件/软件/策略限制、 <del> 亲和以及反亲和要求、数据局域性、负载间的干扰等等。 </del> <ins> 亲和以及反亲和要求、数据局部性、负载间的干扰等等。 </ins> <!-- ## Scheduling with kube-scheduler {#kube-scheduler-implementation}


Finally if everything goes well, remove Docker. <del> {{< tabs name="tab-remove-docker-enigine" >}} </del> <ins> {{< tabs name="tab-remove-docker-engine" >}} </ins> {{% tab name="CentOS" %}} ```shell


{{% /tab %}} {{< /tabs >}} <ins> The preceding commands don't remove images, containers, volumes, or customized configuration files on your host. To delete them, follow Docker's instructions to [Uninstall Docker Engine](https://docs.docker.com/engine/install/ubuntu/#uninstall-docker-engine). {{< caution >}} Docker's instructions for uninstalling Docker Engine create a risk of deleting containerd. Be careful when executing commands. {{< /caution >}} </ins>


{{< note >}} To learn more about contributing to Kubernetes in general, see the [contributor documentation](https://www.kubernetes.dev/docs/). <ins> You can also read the {{< glossary_tooltip text="CNCF" term_id="cncf" >}} [page](https://contribute.cncf.io/contributors/projects/#kubernetes) about contributing to Kubernetes. </ins> {{< /note >}} <ins> --- </ins> This website is maintained by [Kubernetes SIG Docs](/docs/contribute/#get-involved-with-sig-docs). Kubernetes documentation contributors:


[javascript_required] other = "JavaScript must be [enabled](https://www.enable-javascript.com/) to view this content" <del> [katacoda_removal_warning] other = """This online tutorial on this page uses functionality that will [not be available](https://www.oreilly.com/online-learning/leveraging-katacoda-technology.html) past <time datetime="2022-06-15">June 15th, 2022</time>.""" </del> [latest_release] other = "Latest Release:"


{{ block "deprecated" . }} {{ partial "deprecation-warning.html" . }} {{ end }} <del> {{ if or ( .HasShortcode "kat-button" ) ( .HasShortcode "katacoda-tutorial" ) }} {{ block "katacoda-removal" . }} {{ partial "katacoda-removal.html" . }} {{ end }} {{ end }} </del> {{ block "main" . }}{{ end }} {{- if .HasShortcode "thirdparty-content" -}} {{ block "thirdparty-disclaimer" . }}


{{ T "katacoda_removal_warning" | markdownify }}


The Gateway API introduces a few new resource types: <del> - **[GatewayClasses](https://gateway-api.sigs.k8s.io/v1alpha1/references/spec/#networking.x-k8s.io/v1alpha1.GatewayClass)** are cluster-scoped resources that act as templates to explicitly define behavior for Gateways derived from them. This is similar in concept to StorageClasses, but for networking data-planes. - **[Gateways](https://gateway-api.sigs.k8s.io/v1alpha1/references/spec/#networking.x-k8s.io/v1alpha1.Gateway)** are the deployed instances of GatewayClasses. They are the logical representation of the data-plane which performs routing, which may be in-cluster proxies, hardware LBs, or cloud LBs. - **Routes** are not a single resource, but represent many different protocol-specific Route resources. The [HTTPRoute](https://gateway-api.sigs.k8s.io/v1alpha1/references/spec/#networking.x-k8s.io/v1alpha1.HTTPRoute) has matching, filtering, and routing rules that get applied to Gateways that can process HTTP and HTTPS traffic. Similarly, there are [TCPRoutes](https://gateway-api.sigs.k8s.io/v1alpha1/references/spec/#networking.x-k8s.io/v1alpha1.TCPRoute), [UDPRoutes](https://gateway-api.sigs.k8s.io/v1alpha1/references/spec/#networking.x-k8s.io/v1alpha1.UDPRoute), and [TLSRoutes](https://gateway-api.sigs.k8s.io/v1alpha1/references/spec/#networking.x-k8s.io/v1alpha1.TLSRoute) which also have protocol-specific semantics. This model also allows the Gateway API to incrementally expand its protocol support in the future. </del> <ins> - **[GatewayClasses](https://gateway-api.sigs.k8s.io/concepts/api-overview/#gatewayclass)** are cluster-scoped resources that act as templates to explicitly define behavior for Gateways derived from them. This is similar in concept to StorageClasses, but for networking data-planes. - **[Gateways](https://gateway-api.sigs.k8s.io/concepts/api-overview/#gateway)** are the deployed instances of GatewayClasses. They are the logical representation of the data-plane which performs routing, which may be in-cluster proxies, hardware LBs, or cloud LBs. - **Routes** are not a single resource, but represent many different protocol-specific Route resources. The [HTTPRoute](https://gateway-api.sigs.k8s.io/concepts/api-overview/#httproute) has matching, filtering, and routing rules that get applied to Gateways that can process HTTP and HTTPS traffic. Similarly, there are [TCPRoutes](https://gateway-api.sigs.k8s.io/concepts/api-overview/#tcproute-and-udproute), [UDPRoutes](https://gateway-api.sigs.k8s.io/concepts/api-overview/#tcproute-and-udproute), and [TLSRoutes](https://gateway-api.sigs.k8s.io/concepts/api-overview/#gateway) which also have protocol-specific semantics. This model also allows the Gateway API to incrementally expand its protocol support in the future. </ins> ![The resources of the Gateway API](gateway-api-resources.png)


admission controller. To get started with `cosigned` here are a few helpful resources: <del> * [Installation](https://github.com/sigstore/helm-charts/tree/main/charts/cosigned) </del> <ins> * [Installation](https://github.com/sigstore/cosign#installation) </ins> * [Configuration Options](https://github.com/sigstore/cosign/tree/main/config)


resources: * [Installation](https://github.com/sigstore/cosign#installation) <del> * [Configuration Options](https://github.com/sigstore/cosign/tree/main/config) </del> <ins> * [Configuration Options](https://github.com/sigstore/cosign/blob/main/USAGE.md#detailed-usage) </ins>


{{< note >}} Certificates created using the `certificates.k8s.io` API are signed by a <del> [dedicated CA](#a-note-to-cluster-administrators). It is possible to configure your cluster to use the cluster root </del> <ins> [dedicated CA](#configuring-your-cluster-to-provide-signing). It is possible to configure your cluster to use the cluster root </ins> CA for this purpose, but you should never rely on this. Do not assume that these certificates will validate against the cluster root CA. {{< /note >}}


## Trusting TLS in a cluster <del> Trusting the [custom CA](#a-note-to-cluster-administrators) from an application running as a pod usually requires </del> <ins> Trusting the [custom CA](#configuring-your-cluster-to-provide-signing) from an application running as a pod usually requires </ins> some extra application configuration. You will need to add the CA certificate bundle to the list of CA certificates that the TLS client or server trusts. For example, you would do this with a golang TLS config by parsing the certificate


<ins> --- layout: blog title: Kubernetes Gateway API 进入 Beta 阶段 date: 2022-07-13 slug: gateway-api-graduates-to-beta --- <!-- layout: blog title: Kubernetes Gateway API Graduates to Beta date: 2022-07-13 slug: gateway-api-graduates-to-beta canonicalUrl: https://gateway-api.sigs.k8s.io/blog/2022/graduating-to-beta/ --> <!-- **Authors:** Shane Utt (Kong), Rob Scott (Google), Nick Young (VMware), Jeff Apple (HashiCorp) --> **作者：** Shane Utt (Kong)、Rob Scott (Google)、Nick Young (VMware)、Jeff Apple (HashiCorp) <!-- We are excited to announce the v0.5.0 release of Gateway API. For the first time, several of our most important Gateway API resources are graduating to beta. Additionally, we are starting a new initiative to explore how Gateway API can be used for mesh and introducing new experimental concepts such as URL rewrites. We'll cover all of this and more below. --> 我们很高兴地宣布 Gateway API 的 v0.5.0 版本发布。 我们最重要的几个 Gateway API 资源首次进入 Beta 阶段。 此外，我们正在启动一项新的倡议，探索如何将 Gateway API 用于网格，还引入了 URL 重写等新的实验性概念。 下文涵盖了这部分内容和更多说明。 <!-- ## What is Gateway API? --> ## 什么是 Gateway API？ <!-- Gateway API is a collection of resources centered around [Gateway][gw] resources (which represent the underlying network gateways / proxy servers) to enable robust Kubernetes service networking through expressive, extensible and role-oriented interfaces that are implemented by many vendors and have broad industry support. --> Gateway API 是以 [Gateway][gw] 资源（代表底层网络网关/代理服务器）为中心的资源集合， Kubernetes 服务网络的健壮性得益于众多供应商实现、得到广泛行业支持且极具表达力、可扩展和面向角色的各个接口。 <!-- Originally conceived as a successor to the well known [Ingress][ing] API, the benefits of Gateway API include (but are not limited to) explicit support for many commonly used networking protocols (e.g. `HTTP`, `TLS`, `TCP`, `UDP`) as well as tightly integrated support for Transport Layer Security (TLS). The `Gateway` resource in particular enables implementations to manage the lifecycle of network gateways as a Kubernetes API. --> Gateway API 最初被认为是知名 [Ingress][ing] API 的继任者， Gateway API 的好处包括（但不限于）对许多常用网络协议的显式支持 （例如 `HTTP`、`TLS`、`TCP `、`UDP`) 以及对传输层安全 (TLS) 的紧密集成支持。 特别是 `Gateway` 资源能够实现作为 Kubernetes API 来管理网络网关的生命周期。 <!-- If you're an end-user interested in some of the benefits of Gateway API we invite you to jump in and find an implementation that suits you. At the time of this release there are over a dozen [implementations][impl] for popular API gateways and service meshes and guides are available to start exploring quickly. --> 如果你是对 Gateway API 的某些优势感兴趣的终端用户，我们邀请你加入并找到适合你的实现方式。 值此版本发布之时，对于流行的 API 网关和服务网格有十多种[实现][impl]，还提供了操作指南便于快速开始探索。 <!-- [gw]:https://gateway-api.sigs.k8s.io/api-types/gateway/ [ing]:https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/ [impl]:https://gateway-api.sigs.k8s.io/implementations/ --> [gw]:https://gateway-api.sigs.k8s.io/api-types/gateway/ [ing]:/zh-cn/docs/reference/kubernetes-api/service-resources/ingress-v1/ [impl]:https://gateway-api.sigs.k8s.io/implementations/ <!-- ### Getting started --> ### 入门 <!-- Gateway API is an official Kubernetes API like [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/). Gateway API represents a superset of Ingress functionality, enabling more advanced concepts. Similar to Ingress, there is no default implementation of Gateway API built into Kubernetes. Instead, there are many different [implementations][impl] available, providing significant choice in terms of underlying technologies while providing a consistent and portable experience. --> Gateway API 是一个类似 [Ingress](/zh-cn/docs/concepts/services-networking/ingress/) 的正式 Kubernetes API。Gateway API 代表了 Ingress 功能的一个父集，使得一些更高级的概念成为可能。 与 Ingress 类似，Kubernetes 中没有内置 Gateway API 的默认实现。 相反，有许多不同的[实现][impl]可用，在提供一致且可移植体验的同时，还在底层技术方面提供了重要的选择。 <!-- Take a look at the [API concepts documentation][concepts] and check out some of the [Guides][guides] to start familiarizing yourself with the APIs and how they work. When you're ready for a practical application open the [implementations page][impl] and select an implementation that belongs to an existing technology you may already be familiar with or the one your cluster provider uses as a default (if applicable). Gateway API is a [Custom Resource Definition (CRD)][crd] based API so you'll need to [install the CRDs][install-crds] onto a cluster to use the API. --> 查看 [API 概念文档][concepts] 并查阅一些[指南][guides]以开始熟悉这些 API 及其工作方式。 当你准备好一个实用的应用程序时， 请打开[实现页面][impl]并选择属于你可能已经熟悉的现有技术或集群提供商默认使用的技术（如果适用）的实现。 Gateway API 是一个基于 [CRD][crd] 的 API，因此你将需要[安装 CRD][install-crds] 到集群上才能使用该 API。 <!-- If you're specifically interested in helping to contribute to Gateway API, we would love to have you! Please feel free to [open a new issue][issue] on the repository, or join in the [discussions][disc]. Also check out the [community page][community] which includes links to the Slack channel and community meetings. --> 如果你对 Gateway API 做贡献特别有兴趣，我们非常欢迎你的加入！ 你可以随时在仓库上[提一个新的 issue][issue]，或[加入讨论][disc]。 另请查阅[社区页面][community]以了解 Slack 频道和社区会议的链接。 <!-- [crd]:https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/ [concepts]:https://gateway-api.sigs.k8s.io/concepts/api-overview/ [guides]:https://gateway-api.sigs.k8s.io/guides/getting-started/ [impl]:https://gateway-api.sigs.k8s.io/implementations/ [install-crds]:https://gateway-api.sigs.k8s.io/guides/getting-started/#install-the-crds [issue]:https://github.com/kubernetes-sigs/gateway-api/issues/new/choose [disc]:https://github.com/kubernetes-sigs/gateway-api/discussions [community]:https://gateway-api.sigs.k8s.io/contributing/community/ --> [crd]:/zh-cn/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/ [concepts]:https://gateway-api.sigs.k8s.io/concepts/api-overview/ [guides]:https://gateway-api.sigs.k8s.io/guides/getting-started/ [impl]:https://gateway-api.sigs.k8s.io/implementations/ [install-crds]:https://gateway-api.sigs.k8s.io/guides/getting-started/#install-the-crds [issue]:https://github.com/kubernetes-sigs/gateway-api/issues/new/choose [disc]:https://github.com/kubernetes-sigs/gateway-api/discussions [community]:https://gateway-api.sigs.k8s.io/contributing/community/ <!-- ## Release highlights ### Graduation to beta --> ## 发布亮点 ### 进入 Beta 阶段 <!-- The `v0.5.0` release is particularly historic because it marks the growth in maturity to a beta API version (`v1beta1`) release for some of the key APIs: --> `v0.5.0` 版本特别具有历史意义，因为它标志着一些关键 API 成长至 Beta API 版本（`v1beta1`）： - [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/) - [Gateway](https://gateway-api.sigs.k8s.io/api-types/gateway/) - [HTTPRoute](https://gateway-api.sigs.k8s.io/api-types/httproute/) <!-- This achievement was marked by the completion of several graduation criteria: - API has been [widely implemented][impl]. - Conformance tests provide basic coverage for all resources and have multiple implementations passing tests. - Most of the API surface is actively being used. - Kubernetes SIG Network API reviewers have approved graduation to beta. --> 这一成就的标志是达到了以下几个进入标准： - API 已[广泛实现][impl]。 - 合规性测试基本覆盖了所有资源且可以让多种实现通过测试。 - 大多数 API 接口正被积极地使用。 - Kubernetes SIG Network API 评审团队已批准其进入 Beta 阶段。 <!-- For more information on Gateway API versioning, refer to the [official documentation](https://gateway-api.sigs.k8s.io/concepts/versioning/). To see what's in store for future releases check out the [next steps](#next-steps) section. --> 有关 Gateway API 版本控制的更多信息，请参阅[官方文档](https://gateway-api.sigs.k8s.io/concepts/versioning/)。 要查看未来版本的计划，请查看[下一步](#next-steps)。 [impl]:https://gateway-api.sigs.k8s.io/implementations/ <!-- ### Release channels This release introduces the `experimental` and `standard` [release channels][ch] which enable a better balance of maintaining stability while still enabling experimentation and iterative development. --> ### 发布渠道 此版本引入了 `experimental` 和 `standard` [发布渠道][ch]， 这样能够更好地保持平衡，在确保稳定性的同时，还能支持实验和迭代开发。 <!-- The `standard` release channel includes: - resources that have graduated to beta - fields that have graduated to standard (no longer considered experimental) --> `standard` 发布渠道包括： - 已进入 Beta 阶段的资源 - 已进入 standard 的字段（不再被视为 experimental） <!-- The `experimental` release channel includes everything in the `standard` release channel, plus: - `alpha` API resources - fields that are considered experimental and have not graduated to `standard` channel --> `experimental` 发布渠道包括 `standard` 发布渠道的所有内容，另外还有： - `alpha` API 资源 - 视为 experimental 且还未进入 `standard` 渠道的字段 <!-- Release channels are used internally to enable iterative development with quick turnaround, and externally to indicate feature stability to implementors and end-users. --> 使用发布渠道能让内部实现快速流转的迭代开发，且能让外部实现者和最终用户标示功能稳定性。 <!-- For this release we've added the following experimental features: - [Routes can attach to Gateways by specifying port numbers](https://gateway-api.sigs.k8s.io/geps/gep-957/) - [URL rewrites and path redirects](https://gateway-api.sigs.k8s.io/geps/gep-726/) --> 本次发布新增了以下实验性的功能特性： - [路由通过指定端口号可以挂接到 Gateway](https://gateway-api.sigs.k8s.io/geps/gep-957/) - [URL 重写和路径重定向](https://gateway-api.sigs.k8s.io/geps/gep-726/) [ch]:https://gateway-api.sigs.k8s.io/concepts/versioning/#release-channels-eg-experimental-standard <!-- ### Other improvements For an exhaustive list of changes included in the `v0.5.0` release, please see the [v0.5.0 release notes](https://github.com/kubernetes-sigs/gateway-api/releases/tag/v0.5.0). --> ### 其他改进 有关 `v0.5.0` 版本中包括的完整变更清单，请参阅 [v0.5.0 发布说明](https://github.com/kubernetes-sigs/gateway-api/releases/tag/v0.5.0)。 <!-- ## Gateway API for service mesh: the GAMMA Initiative Some service mesh projects have [already implemented support for the Gateway API](https://gateway-api.sigs.k8s.io/implementations/). Significant overlap between the Service Mesh Interface (SMI) APIs and the Gateway API has [inspired discussion in the SMI community](https://github.com/servicemeshinterface/smi-spec/issues/249) about possible integration. --> ## 适用于服务网格的 Gateway API：GAMMA 倡议 某些服务网格项目[已实现对 Gateway API 的支持](https://gateway-api.sigs.k8s.io/implementations/)。 服务网格接口 (Service Mesh Interface，SMI) API 和 Gateway API 之间的显著重叠 [已激发了 SMI 社区讨论](https://github.com/servicemeshinterface/smi-spec/issues/249)可能的集成方式。 <!-- We are pleased to announce that the service mesh community, including representatives from Cilium Service Mesh, Consul, Istio, Kuma, Linkerd, NGINX Service Mesh and Open Service Mesh, is coming together to form the [GAMMA Initiative](https://gateway-api.sigs.k8s.io/contributing/gamma/), a dedicated workstream within the Gateway API subproject focused on Gateway API for Mesh Management and Administration. --> 我们很高兴地宣布，来自 Cilium Service Mesh、Consul、Istio、Kuma、Linkerd、NGINX Service Mesh 和 Open Service Mesh 等服务网格社区的代表汇聚一堂组成 [GAMMA 倡议小组](https://gateway-api.sigs.k8s.io/contributing/gamma/)， 这是 Gateway API 子项目内一个专门的工作流，专注于网格管理所用的 Gateway API。 <!-- This group will deliver [enhancement proposals](https://gateway-api.sigs.k8s.io/v1beta1/contributing/gep/) consisting of resources, additions, and modifications to the Gateway API specification for mesh and mesh-adjacent use-cases. This work has begun with [an exploration of using Gateway API for service-to-service traffic](https://docs.google.com/document/d/1T_DtMQoq2tccLAtJTpo3c0ohjm25vRS35MsestSL9QU/edit#heading=h.jt37re3yi6k5) and will continue with enhancement in areas such as authentication and authorization policy. --> 这个小组将交付[增强提案](https://gateway-api.sigs.k8s.io/v1beta1/contributing/gep/)， 包括对网格和网格相关用例适用的 Gateway API 规约的资源、添加和修改。 这项工作已从 [探索针对服务间流量使用 Gateway API](https://docs.google.com/document/d/1T_DtMQoq2tccLAtJTpo3c0ohjm25vRS35MsestSL9QU/edit#heading=h.jt37re3yi6k5) 开始，并将继续增强身份验证和鉴权策略等领域。 <!-- ## Next steps As we continue to mature the API for production use cases, here are some of the highlights of what we'll be working on for the next Gateway API releases: - [GRPCRoute][gep1016] for [gRPC][grpc] traffic routing - [Route delegation][pr1085] - Layer 4 API maturity: Graduating [TCPRoute][tcpr], [UDPRoute][udpr] and [TLSRoute][tlsr] to beta - [GAMMA Initiative](https://gateway-api.sigs.k8s.io/contributing/gamma/) - Gateway API for Service Mesh --> ## 下一步 随着我们不断完善用于生产用例的 API，以下是我们将为下一个 Gateway API 版本所做的一些重点工作： - 针对 [gRPC][grpc] 流量路由的 [GRPCRoute][gep1016] - [路由代理][pr1085] - 4 层 API 成熟度：[TCPRoute][tcpr]、[UDPRoute][udpr] 和 [TLSRoute][tlsr] 正进入 Beta 阶段 - [GAMMA 倡议](https://gateway-api.sigs.k8s.io/contributing/gamma/) - 针对服务网格的 Gateway API <!-- If there's something on this list you want to get involved in, or there's something not on this list that you want to advocate for to get on the roadmap please join us in the #sig-network-gateway-api channel on Kubernetes Slack or our weekly [community calls](https://gateway-api.sigs.k8s.io/contributing/community/#meetings). --> 如果你想参与此列表中的某些工作，或者你想倡导加入路线图的内容不在此列表中， 请通过 Kubernetes Slack 的 #sig-network-gateway-api 频道或我们每周的 [社区电话会议](https://gateway-api.sigs.k8s.io/contributing/community/#meetings)加入我们。 [gep1016]:https://github.com/kubernetes-sigs/gateway-api/blob/master/site-src/geps/gep-1016.md [grpc]:https://grpc.io/ [pr1085]:https://github.com/kubernetes-sigs/gateway-api/pull/1085 [tcpr]:https://github.com/kubernetes-sigs/gateway-api/blob/main/apis/v1alpha2/tcproute_types.go [udpr]:https://github.com/kubernetes-sigs/gateway-api/blob/main/apis/v1alpha2/udproute_types.go [tlsr]:https://github.com/kubernetes-sigs/gateway-api/blob/main/apis/v1alpha2/tlsroute_types.go [community]:https://gateway-api.sigs.k8s.io/contributing/community/ </ins>


requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: <del> - key: topology.kubernetes.io/zone </del> <ins> - key: kubernetes.io/os </ins> operator: In values: <del> - antarctica-east1 - antarctica-west1 </del> <ins> - linux </ins> preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference:


requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: <del> - key: kubernetes.io/os </del> <ins> - key: topology.kubernetes.io/zone </ins> operator: In values: <del> - linux </del> <ins> - antarctica-east1 - antarctica-west1 </ins> preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference:


* Cloning support is only available for dynamic provisioners. * CSI drivers may or may not have implemented the volume cloning functionality. * You can only clone a PVC when it exists in the same namespace as the destination PVC (source and destination must be in the same namespace). <del> * Cloning is only supported within the same Storage Class. - Destination volume must be the same storage class as the source - Default storage class can be used and storageClassName omitted in the spec </del> <ins> * Cloning is supported with a different Storage Class. - Destination volume can be the same or a different storage class as the source. - Default storage class can be used and storageClassName omitted in the spec. </ins> * Cloning can only be performed between two volumes that use the same VolumeMode setting (if you request a block mode volume, the source MUST also be block mode)


<ins> --- layout: blog title: "Security Profiles Operator v0.4.0 中的新功能" date: 2021-12-17 slug: security-profiles-operator --- <!-- layout: blog title: "What's new in Security Profiles Operator v0.4.0" date: 2021-12-17 slug: security-profiles-operator --> <!-- **Authors:** Jakub Hrozek, Juan Antonio Osorio, Paulo Gomes, Sascha Grunert --> **作者:** Jakub Hrozek, Juan Antonio Osorio, Paulo Gomes, Sascha Grunert --- <!-- The [Security Profiles Operator (SPO)](https://sigs.k8s.io/security-profiles-operator) is an out-of-tree Kubernetes enhancement to make the management of [seccomp](https://en.wikipedia.org/wiki/Seccomp), [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) and [AppArmor](https://en.wikipedia.org/wiki/AppArmor) profiles easier and more convenient. We're happy to announce that we recently [released v0.4.0](https://github.com/kubernetes-sigs/security-profiles-operator/releases/tag/v0.4.0) of the operator, which contains a ton of new features, fixes and usability improvements. --> [Security Profiles Operator (SPO)](https://sigs.k8s.io/security-profiles-operator) 是一种树外 Kubernetes 增强功能，用于更方便、更便捷地管理 [seccomp](https://en.wikipedia.org/wiki/Seccomp)、 [SELinux](https://zh.wikipedia.org/wiki/%E5%AE%89%E5%85%A8%E5%A2%9E%E5%BC%BA%E5%BC%8FLinux) 和 [AppArmor](https://zh.wikipedia.org/wiki/AppArmor) 配置文件。 我们很高兴地宣布，我们最近[发布了 v0.4.0](https://github.com/kubernetes-sigs/security-profiles-operator/releases/tag/v0.4.0) 的 Operator，其中包含了大量的新功能、缺陷修复和可用性改进。 <!-- ## What's new It has been a while since the last [v0.3.0](https://github.com/kubernetes-sigs/security-profiles-operator/releases/tag/v0.3.0) release of the operator. We added new features, fine-tuned existing ones and reworked our documentation in 290 commits over the past half year. --> ## 有哪些新特性 距离上次的 [v0.3.0](https://github.com/kubernetes-sigs/security-profiles-operator/releases/tag/v0.3.0) 的发布已经有一段时间了。在过去的半年里，我们增加了新的功能，对现有的功能进行了微调， 并且在过去的半年里，我们通过 290 个提交重新编写了文档。 <!-- One of the highlights is that we're now able to record seccomp and SELinux profiles using the operators [log enricher](https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#log-enricher-based-recording). This allows us to reduce the dependencies required for profile recording to have [auditd](https://linux.die.net/man/8/auditd) or [syslog](https://en.wikipedia.org/wiki/Syslog) (as fallback) running on the nodes. All profile recordings in the operator work in the same way by using the `ProfileRecording` CRD as well as their corresponding [label selectors](/docs/concepts/overview/working-with-objects/labels). The log enricher itself can be also used to gather meaningful insights about seccomp and SELinux messages of a node. Checkout the [official documentation](https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#using-the-log-enricher) to learn more about it. --> 亮点之一是我们现在能够使用 Operator 的[日志增强组件](https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#log-enricher-based-recording) 记录 seccomp 和 SELinux 的配置文件。 这使我们能够减少配置文件记录所需的依赖事项，使得仅剩的依赖变为在节点上运行 [auditd](https://linux.die.net/man/8/auditd) 或 [syslog](https://en.wikipedia.org/wiki/Syslog)（作为一种回退机制）。 通过使用 `ProfileRecording` CRD 及其对应的[标签选择算符](/zh-cn/concepts/overview/working-with-objects/labels)， Operator 中的所有配置文件记录都以相同的方式工作。 日志增强组件本身也可用于获得有关节点上的 seccomp 和 SELinux 消息的有意义的洞察。 查看[官方文档](https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#using-the-log-enricher) 了解更多信息。 <!-- ### seccomp related improvements Beside the log enricher based recording we now offer an alternative to record seccomp profiles by utilizing [ebpf](https://ebpf.io). This optional feature can be enabled by setting `enableBpfRecorder` to `true`. This results in running a dedicated container, which ships a custom bpf module on every node to collect the syscalls for containers. It even supports older Kernel versions which do not expose the [BPF Type Format (BTF)](https://www.kernel.org/doc/html/latest/bpf/btf.html) per default as well as the `amd64` and `arm64` architectures. Checkout [our documentation](https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#ebpf-based-recording) to see it in action. By the way, we now add the seccomp profile architecture of the recorder host to the recorded profile as well. --> ### 与 seccomp 有关的改进 除了基于日志丰富器的记录之外，我们现在还使用 [ebpf](https://ebpf.io) 作为记录 seccomp 配置文件的一种替代方法。可以通过将 `enableBpfRecorder` 设置为 `true` 来启用此可选功能。 启用之后会导致一个专用的容器被启动运行；该容器在每个节点上提供一个自定义 bpf 模块以收集容器的系统调用。 它甚至支持默认不公开 [BPF 类型格式 (BTF)](https://www.kernel.org/doc/html/latest/bpf/btf.html) 的旧内核版本以及 `amd64 ` 和 `arm64` 架构。查看 [我们的文档](https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#ebpf-based-recording) 以查看它的实际效果。顺便说一句，我们现在也将记录器主机的 seccomp 配置文件体系结构添加到记录的配置文件中。 <!-- We also graduated the seccomp profile API from `v1alpha1` to `v1beta1`. This aligns with our overall goal to stabilize the CRD APIs over time. The only thing which has changed is that the seccomp profile type `Architectures` now points to `[]Arch` instead of `[]*Arch`. --> 我们还将 seccomp 配置文件 API 从 `v1alpha1` 升级到 `v1beta1`。 这符合我们随着时间的推移稳定 CRD API 的总体目标。 唯一改变的是 seccomp 配置文件类型 `Architectures` 现在指向 `[]Arch` 而不是 `[]*Arch`。 <!-- ### SELinux enhancements Managing SELinux policies (an equivalent to using `semodule` that you would normally call on a single server) is not done by SPO itself, but by another container called selinuxd to provide better isolation. This release switched to using selinuxd containers from a personal repository to images located under [our team's quay.io repository](https://quay.io/organization/security-profiles-operator). The selinuxd repository has moved as well to [the containers GitHub organization](https://github.com/containers/selinuxd). --> ### SELinux 增强功能 管理 SELinux 策略（相当于使用通常在单个服务器上调用的 `semodule` ）不是由 SPO 本身完成的， 而是由另一个名为 selinuxd 的容器完成，以提供更好的隔离。此版本将所使用的 selinuxd 容器镜像从个人仓库迁移到位于[我们团队的 quay.io 仓库](https://quay.io/organization/security-profiles-operator)下的镜像。 selinuxd 仓库也已移至[GitHub 组织 containers](https://github.com/containers/selinuxd)。 <!-- Please note that selinuxd links dynamically to `libsemanage` and mounts the SELinux directories from the nodes, which means that the selinuxd container must be running the same distribution as the cluster nodes. SPO defaults to using CentOS-8 based containers, but we also build Fedora based ones. If you are using another distribution and would like us to add support for it, please file [an issue against selinuxd](https://github.com/containers/selinuxd/issues). --> 请注意，selinuxd 动态链接到 libsemanage 并挂载节点上的 SELinux 目录， 这意味着 selinuxd 容器必须与集群节点运行相同的发行版。SPO 默认使用基于 CentOS-8 的容器， 但我们也构建基于 Fedora 的容器。如果你使用其他发行版并希望我们添加对它的支持， 请[针对 selinuxd 提交 issue](https://github.com/containers/selinuxd/issues)。 <!-- #### Profile Recording This release adds support for recording of SELinux profiles. The recording itself is managed via an instance of a `ProfileRecording` Custom Resource as seen in an [example](https://github.com/kubernetes-sigs/security-profiles-operator/blob/main/examples/profilerecording-selinux-logs.yaml) in our repository. From the user's point of view it works pretty much the same as recording of seccomp profiles. --> #### 配置文件记录 此版本（0.4.0）增加了记录 SELinux 配置文件的支持。记录本身是通过 `ProfileRecording` 自定义资源的实例管理的， 如我们仓库中的[示例](https://github.com/kubernetes-sigs/security-profiles-operator/blob/main/examples/profilerecording-selinux-logs.yaml) 所示。从用户的角度来看，它的工作原理与记录 seccomp 配置文件几乎相同。 <!-- Under the hood, to know what the workload is doing SPO installs a special permissive policy called [selinuxrecording](https://github.com/kubernetes-sigs/security-profiles-operator/blob/main/deploy/base/profiles/selinuxrecording.cil) on startup which allows everything and logs all AVCs to `audit.log`. These AVC messages are scraped by the log enricher component and when the recorded workload exits, the policy is created. --> 在后台，为了知道工作负载在做什么，SPO 安装了一个名为 [selinuxrecording](https://github.com/kubernetes-sigs/security-profiles-operator/blob/main/deploy/base/profiles/selinuxrecording.cil) 的、限制宽松的策略，允许执行所有操作并将所有 AVC 记录到 `audit.log` 中。 这些 AVC 消息由日志增强组件抓取，当所记录的工作负载退出时，该策略被创建。 <!-- #### `SELinuxProfile` CRD graduation An `v1alpha2` version of the `SelinuxProfile` object has been introduced. This removes the raw Common Intermediate Language (CIL) from the object itself and instead adds a simple policy language to ease the writing and parsing experience. --> #### `SELinuxProfile` CRD 毕业 我们引入了 `SelinuxProfile` 对象的 `v1alpha2` 版本。 这个版本从对象中删除了原始的通用中间语言 (CIL)，并添加了一种简单的策略语言来简化编写和解析体验。 <!-- Alongside, a `RawSelinuxProfile` object was also introduced. This contains a wrapped and raw representation of the policy. This was intended for folks to be able to take their existing policies into use as soon as possible. However, on validations are done here. --> 此外，我们还引入了 `RawSelinuxProfile` 对象。该对象包含策略的包装和原始表示。 引入此对象是为了让人们能够尽快将他们现有的策略付诸实现。但是，策略的验证是在这里完成的。 <!-- ### AppArmor support This version introduces the initial support for AppArmor, allowing users to load and unload AppArmor profiles into cluster nodes by using the new [AppArmorProfile](https://github.com/kubernetes-sigs/security-profiles-operator/blob/main/deploy/base/crds/apparmorprofile.yaml) CRD. --> ### AppArmor 支持 0.4.0 版本引入了对 AppArmor 的初始支持，允许用户通过使用新的 [AppArmorProfile](https://github.com/kubernetes-sigs/security-profiles-operator/blob/main/deploy/base/crds/apparmorprofile.yaml) 在集群节点中 CRD 加载或卸载 AppArmor 配置文件。 <!-- To enable AppArmor support use the [enableAppArmor feature gate](https://github.com/kubernetes-sigs/security-profiles-operator/blob/main/examples/config.yaml#L10) switch of your SPO configuration. Then use our [apparmor example](https://github.com/kubernetes-sigs/security-profiles-operator/blob/main/examples/apparmorprofile.yaml) to deploy your first profile across your cluster. --> 要启用 AppArmor 支持，请使用 SPO 配置的 [enableAppArmor 特性门控](https://github.com/kubernetes-sigs/security-profiles-operator/blob/main/examples/config.yaml#L10)开关。 然后使用我们的 [apparmor 示例](https://github.com/kubernetes-sigs/security-profiles-operator/blob/main/examples/apparmorprofile.yaml) 在集群中部署你第一个配置文件。 <!-- ### Metrics The operator now exposes metrics, which are described in detail in our new [metrics documentation](https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#using-metrics). We decided to secure the metrics retrieval process by using [kube-rbac-proxy](https://github.com/brancz/kube-rbac-proxy), while we ship an additional `spo-metrics-client` cluster role (and binding) to retrieve the metrics from within the cluster. If you're using [OpenShift](https://www.redhat.com/en/technologies/cloud-computing/openshift), then we provide an out of the box working [`ServiceMonitor`](https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#automatic-servicemonitor-deployment) to access the metrics. --> ### 指标 Operator 现在能够公开在我们的新[指标文档](https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#using-metrics)中详细描述的指标。 我们决定使用 [kube-rbac-proxy](https://github.com/brancz/kube-rbac-proxy) 来保护指标检索过程， 同时我们提供了一个额外的 `spo-metrics-client` 集群角色（和绑定）以从集群内检索指标。 如果你使用 [OpenShift](https://www.redhat.com/en/technologies/cloud-computing/openshift)， 那么我们提供了一个开箱即用的 [`ServiceMonitor`](https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#automatic-servicemonitor-deployment) 来访问指标。 <!-- #### Debuggability and robustness Beside all those new features, we decided to restructure parts of the Security Profiles Operator internally to make it better to debug and more robust. For example, we now maintain an internal [gRPC](https://grpc.io) API to communicate within the operator across different features. We also improved the performance of the log enricher, which now caches results for faster retrieval of the log data. The operator can be put into a more [verbose log mode](https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#set-logging-verbosity) by setting `verbosity` from `0` to `1`. --> #### 可调试性和稳健性 除了所有这些新功能外，我们还决定在内部重组安全配置文件操作程序的部分内容，使其更易于调试和更稳健。 例如，我们现在维护了一个内部 [gRPC](https://grpc.io) API，以便在 Operator 内部跨不同功能组件进行通信。 我们还提高了日志增强组件的性能，现在它可以缓存结果，以便更快地检索日志数据。 Operator 可以通过将 `verbosity` 设置从 `0` 改为 `1`，启用更详细的日志模式(https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#set-logging-verbosity)。 <!-- We also print the used `libseccomp` and `libbpf` versions on startup, as well as expose CPU and memory profiling endpoints for each container via the [`enableProfiling` option](https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#enable-cpu-and-memory-profiling). Dedicated liveness and startup probes inside of the operator daemon will now additionally improve the life cycle of the operator. --> 我们还在启动时打印所使用的 `libseccomp` 和 `libbpf` 版本， 并通过 [`enableProfiling` 选项](https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#enable-cpu-and-memory-profiling) 公开每个容器的 CPU 和内存性能分析端点。 Operator 守护程序内部的专用的存活态探测和启动探测现在能进一步改善 Operator 的生命周期管理。 <!-- ## Conclusion Thank you for reading this update. We're looking forward to future enhancements of the operator and would love to get your feedback about the latest release. Feel free to reach out to us via the Kubernetes slack [#security-profiles-operator](https://kubernetes.slack.com/messages/security-profiles-operator) for any feedback or question. --> ## 总结 感谢你阅读这次更新。我们期待着 Operater 的未来改进，并希望得到你对最新版本的反馈。 欢迎通过 Kubernetes slack [#security-profiles-operator](https://kubernetes.slack.com/messages/security-profiles-operator) 与我们联系，提出任何反馈或问题。 </ins>


{{< /note >}} Both approaches are equivalent. After reloading your shell, kubectl autocompletion should be working. <ins> To enable bash autocompletion in current session of shell, source the ~/.bashrc file: ```bash source ~/.bashrc ``` </ins>


baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch enabled=1 gpgcheck=1 <del> gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg </del> <ins> gpgkey=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg </ins> exclude=kubelet kubeadm kubectl EOF


baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch enabled=1 gpgcheck=1 <del> gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg </del> <ins> gpgkey=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg </ins> EOF sudo yum install -y kubectl ```


## kind [`kind`](https://kind.sigs.k8s.io/) lets you run Kubernetes on <del> your local computer. This tool requires that you have [Docker](https://docs.docker.com/get-docker/) installed and configured. </del> <ins> your local computer. This tool requires that you have either [Docker](https://www.docker.com/) or [Podman](https://podman.io/) installed. </ins> The kind [Quick Start](https://kind.sigs.k8s.io/docs/user/quick-start/) page shows you what you need to do to get up and running with kind.


- [CSI provisioner](#vsphere-provisioner-csi): `csi.vsphere.vmware.com` - [vCP provisioner](#vcp-provisioner): `kubernetes.io/vsphere-volume` <del> In-tree provisioners are [deprecated](/blog/2019/12/09/kubernetes-1-17-feature-csi-migration-beta/#why-are-we-migrating-in-tree-plugins-to-csi). For more information on the CSI provisioner, see [Kubernetes vSphere CSI Driver](https://vsphere-csi-driver.sigs.k8s.io/) and [vSphereVolume CSI migration](/docs/concepts/storage/volumes/#csi-migration-5). </del> <ins> In-tree provisioners are [deprecated](/blog/2019/12/09/kubernetes-1-17-feature-csi-migration-beta/#why-are-we-migrating-in-tree-plugins-to-csi). For more information on the CSI provisioner, see [Kubernetes vSphere CSI Driver](https://vsphere-csi-driver.sigs.k8s.io/) and [vSphereVolume CSI migration](/docs/concepts/storage/volumes/#vsphere-csi-migration). </ins> #### CSI Provisioner {#vsphere-provisioner-csi}


The value for this annotation must be **true** to take effect. This annotation indicates that pods running as this service account may only reference Secret API objects specified in the service account's `secrets` field. <ins> ### node.kubernetes.io/exclude-from-external-load-balancer Example: `node.kubernetes.io/exclude-from-external-load-balancer` Used on: Node Kubernetes automatically enables the `ServiceNodeExclusion` feature gate on the clusters it creates. With this feature gate enabled on a cluster, you can add labels to particular worker nodes to exclude them from the list of backend servers. The following command can be used to exclude a worker node from the list of backend servers in a backend set- `kubectl label nodes <node-name> node.kubernetes.io/exclude-from-external-load-balancers=true` </ins> ### controller.kubernetes.io/pod-deletion-cost {#pod-deletion-cost} Example: `controller.kubernetes.io/pod-deletion-cost: "10"`


Example: `node.kubernetes.io/out-of-service:NoExecute` <del> A user can manually add the taint to a Node marking it out-of-service. If the `NodeOutOfServiceVolumeDetach` </del> <ins> A user can manually add the taint to a Node marking it out-of-service. If the `NodeOutOfServiceVolumeDetach` </ins> [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled on <del> `kube-controller-manager`, and a Node is marked out-of-service with this taint, the pods on the node will be forcefully deleted if there are no matching tolerations on it and volume detach operations for the pods terminating on the node will happen immediately. This allows the Pods on the out-of-service node to recover quickly on a different node. </del> <ins> `kube-controller-manager`, and a Node is marked out-of-service with this taint, the pods on the node will be forcefully deleted if there are no matching tolerations on it and volume detach operations for the pods terminating on the node will happen immediately. This allows the Pods on the out-of-service node to recover quickly on a different node. </ins> {{< caution >}} Refer to


{{< glossary_tooltip text="PersistentVolumeClaim" term_id="persistent-volume-claim" >}} is being created from a VolumeSnapshot. <del> Refer to [Converting the volume mode of a Snapshot](/docs/concepts/storage/volume-snapshots/#convert-volume-mode) </del> <ins> Refer to [Converting the volume mode of a Snapshot](/docs/concepts/storage/volume-snapshots/#convert-volume-mode) </ins> and the [Kubernetes CSI Developer Documentation](https://kubernetes-csi.github.io/docs/) for more information. ## Annotations used for audit


title: 코드 컨트리뷰터(Code Contributor) id: code-contributor date: 2018-04-12 <del> full_link: /ko/docs/community/devel/ </del> <ins> full_link: https://github.com/kubernetes/community/tree/master/contributors/devel </ins> short_description: > 쿠버네티스 오픈소스 코드베이스에 코드를 개발하고 기여하는 사람.


<ins> --- #reviewers: #- soltysh #- sttts #- ericchiang content_type: concept title: 감사(auditing) --- <!-- overview --> 쿠버네티스 _감사(auditing)_ 는 클러스터의 작업 순서를 문서화하는 보안 관련 시간별 레코드 세트를 제공한다. 클러스터는 사용자, 쿠버네티스 API를 사용하는 애플리케이션 및 컨트롤 플레인 자체에서 생성된 활동을 감사한다. 감사를 통해 클러스터 관리자는 다음 질문에 답할 수 있다. - 무슨 일이 일어났는지? - 언제 일어난 일인지? - 누가 시작했는지? - 어떤 일이 있었는지? - 어디서 관찰되었는지? - 어디서부터 시작되었는지? - 그래서 어디까지 갔는지? <!-- body --> 감사 기록은 [kube-apiserver](/docs/reference/command-line-tools-reference/kube-apiserver/) 컴포넌트 내에서 수명주기를 시작한다. 실행의 각 단계에서 각 요청은 감사 이벤트를 생성하고, 감사 이벤트는 특정 정책에 따라 사전 처리되고 백엔드에 기록된다. 정책은 기록된 내용을 결정하고 백엔드는 기록을 유지한다. 현재 백엔드 구현에는 로그 파일 및 웹훅이 포함된다. 각 요청들은 연관된 _단계(stage)_ 와 함께 기록될 수 있다. 정의된 단계는 다음과 같다. - `RequestReceived` - 감사 핸들러가 요청을 수신한 직후, 그리고 핸들러 체인으로 위임되기 전에 생성되는 이벤트에 대한 단계이다. - `ResponseStarted` - 응답 헤더는 전송되었지만, 응답 본문(body)은 전송되기 전인 단계이다. 이 단계는 오래 실행되는 요청(예: watch)에 대해서만 생성된다. - `ResponseComplete` - 응답 내용이 완료되었으며, 더 이상 바이트가 전송되지 않을 때의 단계이다. - `Panic` - 패닉이 발생했을 때 생성되는 이벤트이다. {{< note >}} [Audit Event configuration](/docs/reference/config-api/apiserver-audit.v1/#audit-k8s-io-v1-Event) 의 구성은 [Event](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#event-v1-core) API 오브젝트와는 다르다. {{< /note >}} 감사 로깅 기능은 감사에 필요한 일부 컨텍스트가 요청마다 저장되기 때문에 API 서버의 메모리 사용량을 증가시킨다. 메모리 소비량은 감사 로깅 구성에 따라 다르다. ## 감사 정책 감사 정책은 기록해야 하는 이벤트와 포함해야 하는 데이터에 대한 규칙을 정의한다. 감사 정책 오브젝트 구조는 [`audit.k8s.io` API 그룹](/docs/reference/config-api/apiserver-audit.v1/#audit-k8s-io-v1-Policy)에 정의되어 있다. 이벤트가 처리되면 규칙 목록과 순서대로 비교된다. 첫번째 일치 규칙은 이벤트의 _감사 수준(audit level)_ 을 설정한다. 정의된 감사 수준은 다음과 같다. - `None` - 이 규칙에 해당되는 이벤트는 로깅하지 않는다. - `Metadata` - 요청 메타데이터(요청하는 사용자, 타임스탬프, 리소스, 동사(verb) 등)는 로깅하지만 요청/응답 본문은 로깅하지 않는다. - `Request` - 이벤트 메타데이터 및 요청 본문을 로깅하지만 응답 본문은 로깅하지 않는다. 리소스 외의 요청에는 적용되지 않는다. - `RequestResponse` - 이벤트 메타데이터 및 요청/응답 본문을 로깅한다. 리소스 외의 요청에는 적용되지 않는다. `--audit-policy-file` 플래그를 사용하여 정책이 포함된 파일을 `kube-apiserver`에 전달할 수 있다. 플래그를 생략하면 이벤트가 기록되지 않는다. 감사 정책 파일에 `rules` 필드 **반드시** 가 제공되어야 한다. 규칙이 없는(0개인) 정책은 적절하지 않은(illegal) 것으로 간주된다. 다음은 감사 정책 파일의 예이다. {{< codenew file="audit/audit-policy.yaml" >}} 최소 감사 정책 파일을 사용하여 `Metadata` 수준에서 모든 요청을 기록할 수 있다. ```yaml # Log all requests at the Metadata level. apiVersion: audit.k8s.io/v1 kind: Policy rules: - level: Metadata ``` 자체 감사 프로필을 만드는 경우 Google Container-Optimized OS에 대한 감사 프로필을 시작점으로 사용할 수 있다. 감사 정책 파일을 생성하는 [configure-helper.sh](https://github.com/kubernetes/kubernetes/blob/master/cluster/gce/gci/configure-helper.sh) 스크립트를 확인하면 된다. 스크립트로 대부분의 감사 정책 파일을 볼 수 있다. 정의된 필드에 대한 자세한 내용은 [`Policy` configuration reference](/docs/reference/config-api/apiserver-audit.v1/#audit-k8s-io-v1-Policy)를 참조할 수도 있다. ## 감사 백엔드 감사 백엔드는 감사 이벤트를 외부 저장소에 유지한다. 기본적으로 kube-apiserver는 두 가지 백엔드를 제공한다. - 이벤트를 파일 시스템에 기록하는 로그 백엔드 - 이벤트를 외부 HTTP API로 보내는 Webhook 백엔드 모든 경우에 감사 이벤트는 쿠버네티스 API의 [`audit.k8s.io` API 그룹](/docs/reference/config-api/apiserver-audit.v1/#audit-k8s-io-v1-Event)에서 정의한 구조를 따른다. {{< note >}} 패치의 경우 요청 내용은 적절한 쿠버네티스 API 오브젝트를 포함하는 JSON 오브젝트가 아니라 패치 작업을 포함하는 JSON 배열이다. 예를 들어 다음 요청 내용은 `/apis/batch/v1/namespaces/some-namespace/jobs/some-job-name`에 대한 유효한 패치 요청이다. ```json [ { "op": "replace", "path": "/spec/parallelism", "value": 0 }, { "op": "remove", "path": "/spec/template/spec/containers/0/terminationMessagePolicy" } ] ``` {{< /note >}} ### 로그 백엔드 로그 백엔드는 감사이벤트를 [JSONlines](https://jsonlines.org/) 형식으로 파일에 기록한다. 다음의 `kube-apiserver` 플래그를 사용하여 로그 감사 백엔드를 구성할 수 있다. - `--audit-log-path` 는 로그 백엔드가 감사 이벤트를 쓰는 데 사용하는 로그 파일 경로를 지정한다. 이 플래그를 지정하지 않으면 로그 백엔드가 비활성화된다. `-` 는 표준 출력을 의미한다. - `--audit-log-maxage` 는 오래된 감사 로그 파일을 보관할 최대 일수를 정의한다. - `--audit-log-maxbackup` 은 보관할 감사 로그 파일의 최대 수를 정의한다. - `--audit-log-maxsize` 는 감사 로그 파일이 로테이트 되기 전의 최대 크기(MB)를 정의한다. 클러스터의 컨트롤 플레인이 kube-apiserver를 파드로 실행하는 경우 감사 레코드가 지속되도록 정책 파일 및 로그 파일의 위치에 `hostPath` 를 마운트 해야한다. 예를 들면 ```shell --audit-policy-file=/etc/kubernetes/audit-policy.yaml  --audit-log-path=/var/log/kubernetes/audit/audit.log ``` 그런 다음 볼륨을 마운트 한다. ```yaml ... volumeMounts: - mountPath: /etc/kubernetes/audit-policy.yaml name: audit readOnly: true - mountPath: /var/log/kubernetes/audit/ name: audit-log readOnly: false ``` 그리고 마지막으로 `hostPath` 를 구성한다. ```yaml ... volumes: - name: audit hostPath: path: /etc/kubernetes/audit-policy.yaml type: File - name: audit-log hostPath: path: /var/log/kubernetes/audit/ type: DirectoryOrCreate ``` ### 웹훅 백엔드 웹훅 감사 백엔드는 원격 웹 API로 감사 이벤트를 전송하는데, 이는 인증 수단을 포함하여 쿠버네티스 API의 한 형태로 간주된다. 다음 kube-apiserver 플래그를 사용하여 웹훅 감사 백엔드를 구성할 수 있다. - `--audit-webhook-config-file` 은 웹훅 구성이 있는 파일의 경로를 지정한다. 웹훅 구성은 효과적으로 전문화된 [kubeconfig](/docs/tasks/access-application-cluster/configure-access-multiple-cluster)이다. - `--audit-webhook-initial-backoff` 는 첫 번째 실패한 요청 후 다시 시도하기 전에 대기할 시간을 지정한다. 이후 요청은 지수의 백오프로 재시도 된다. 웹훅 구성 파일은 kubeconfig 형식을 사용하여 서비스의 원격 주소와 서비스에 연결하는 데 사용되는 자격 증명을 지정한다. ## 이벤트 배치 {#배치} 로그 및 웹 훅 백엔드는 모두 배치를 지원한다. 웹훅 사용을 예로 들면, 다음은 사용 가능한 플래그 목록이다. 로그 백엔드에 대해 동일한 플래그를 가져오려면 플래그 이름에 있는 `webhook` 을 `log` 로 바꾼다. 기본적으로 배치 기능은 `webhook` 에서 활성화되고 `log` 에서 비활성화된다. 마찬가지로, 기본적으로 쓰로틀링은 `webhook` 에서는 활성화되고 `log` 에서는 비활성화된다. - `--audit-webhook-mode` 은 버퍼링 전략을 정의한다. 다음 중 하나이다. - `batch` - 이벤트를 버퍼링하고 비동기식으로 배치한다. 이것이 기본값이다. - `blocking` - 각 개별 이벤트를 처리할 때 API 서버 응답을 차단한다. - `blocking-strict` - `blocking`과 동일하지만, RequestReceived 단계에서 감사 로깅 중에 오류가 발생하면 kube-apiserver에 대한 전체 요청이 실패한다. 다음 플래그는 `batch` 모드에서만 사용된다. - `--audit-webhook-batch-buffer-size` 는 배치하기 전에 버퍼링할 이벤트 수를 정의한다. 들어오는 이벤트의 비율이 버퍼를 초과하면 이벤트가 삭제된다. - `--audit-webhook-batch-max-size` 는 한 배치의 최대 이벤트 수를 정의한다. - `--audit-webhook-batch-max-wait` 는 대기열에서 이벤트를 무조건 배치하기 전에 대기할 최대 시간을 정의한다. - `--audit-webhook-batch-throttle-qps` 는 초당 생성되는 최대 평균 배치 수를 정의한다. - `--audit-webhook-batch-throttle-burst` 는 허용된 QPS가 이전에 충분히 활용되지 않은 경우 동시에 생성되는 최대 배치 수를 정의한다. ## 파라미터 튜닝 파라미터는 API 서버의 로드를 수용할 수 있도록 설정해야 한다. 예를 들어 kube-apiserver가 초당 100건의 요청을 수신하고 각 요청이 `ResponseStarted` 와 `ResponseComplete` 단계에서만 감사되는 경우 초당 생성되는 ≅200건의 감사 이벤트를 고려해야 한다. 일괄적으로 최대 100개의 이벤트가 있다고 가정할 때 초당 최소 2개의 쿼리 조절 수준을 설정해야 한다. 백엔드가 이벤트를 쓰는 데 최대 5초가 걸릴 수 있다고 가정하면 버퍼크기를 최대 5초의 이벤트를 보유하도록 설정해야 한다. 즉, 10개의 배치 또는 100개의 이벤트이다. 그러나 대부분의 경우 기본 매개 변수만 있으면 충분하며 수동으로 설정할 필요가 없다. kube-apiserver에서 노출된 다음과 같은 프로메테우스 메트릭과 로그에서 감사 하위 시스템의 상태를 모니터링할 수 있다. - `apiserver_audit_event_total` 의 메트릭에는 내보낸 감사 이벤트의 총 수가 포함된다. - `apiserver_audit_error_total` 의 메트릭에는 내보내기 중 오류로 인해 삭제된 총 이벤트 수가 포함된다. ### 로그 항목 자르기 {#truncate} 로그 및 웹훅 백엔드는 모두 로깅되는 이벤트의 크기 제한을 지원한다. 예를 들어 로그 백엔드에 사용할 수 있는 플래그 목록은 다음과 같다. - `audit-log-truncate-enabled` 는 이벤트 및 자르기 배치가 활성화 되었는지 여부를 나타낸다. - `audit-log-truncate-max-batch-size` 는 기본 백엔드로 전송되는 배치의 바이트 단위의 최대 크기이다. - `audit-log-truncate-max-event-size` 는 기본 백엔드로 전송된 감사 이벤트의 바이트 단위의 최대 크기이다. 기본적으로 `webhook` 과 `log` 모두에서 자르기 기능이 비활성화되어 있으므로 이 기능을 활성화 하기 위해 클러스터 관리자는 `audit-log-truncate-enabled` 또는 `audit-webhook-truncate-enabled` 를 설정해야 한다. ## {{% heading "whatsnext" %}} * [Mutating webhook auditing annotations](/docs/reference/access-authn-authz/extensible-admission-controllers/#mutating-webhook-auditing-annotations) 에 대해 알아보기. * [`Event`](/docs/reference/config-api/apiserver-audit.v1/#audit-k8s-io-v1-Event) 에 대해 알아보고 감사 구성 참조를 읽고 [`Policy`](/docs/reference/config-api/apiserver-audit.v1/#audit-k8s-io-v1-Policy) 리소스 유형 확인하기. </ins>