diff --git a/content/zh/docs/concepts/services-networking/network-policies.md b/content/zh/docs/concepts/services-networking/network-policies.md index 784455922a..6ea89e28f4 100644 --- a/content/zh/docs/concepts/services-networking/network-policies.md +++ b/content/zh/docs/concepts/services-networking/network-policies.md @@ -10,19 +10,43 @@ content_type: concept weight: 50 --> -{{< toc >}} - +如果你希望在 IP 地址或端口层面(OSI 第 3 层或第 4 层)控制网络流量, +则你可以考虑为集群中特定应用使用 Kubernetes 网络策略(NetworkPolicy)。 +NetworkPolicy 是一种以应用为中心的结构,允许你设置如何允许 +{{< glossary_tooltip text="Pod" term_id="pod">}} 与网络上的各类网络“实体” +(我们这里使用实体以避免过度使用诸如“端点”和“服务”这类常用术语, +这些术语在 Kubernetes 中有特定含义)通信。 -网络策略(NetworkPolicy)是一种关于 {{< glossary_tooltip text="Pod" term_id="pod">}} 间及与其他网络端点间所允许的通信规则的规范。 + +Pod 可以通信的 Pod 是通过如下三个标识符的组合来辩识的: + +1. 其他被允许的 Pods(例外:Pod 无法阻塞对自身的访问) +2. 被允许的名字空间 +3. IP 组块(例外:与 Pod 运行所在的节点的通信总是被允许的, + 无论 Pod 或节点的 IP 地址) + + +在定义基于 Pod 或名字空间的 NetworkPolicy 时,你会使用 +{{< glossary_tooltip text="选择算符" term_id="selector">}} 来设定哪些流量 +可以进入或离开与该算符匹配的 Pod。 + +同时,当基于 IP 的 NetworkPolicy 被创建时,我们基于 IP 组块(CIDR 范围) +来定义策略。 @@ -31,12 +55,11 @@ NetworkPolicy 资源使用 {{< glossary_tooltip text="标签" term_id="label">}} Network policies are implemented by the [network plugin](/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/). To use network policies, you must be using a networking solution which supports NetworkPolicy. Creating a NetworkPolicy resource without a controller that implements it will have no effect. --> - -## 前提 +## 前置条件 {#prerequisites} 网络策略通过[网络插件](/zh/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/) -来实现。要使用网络策略,用户必须使用支持 NetworkPolicy 的网络解决方案。 -创建一个资源对象,而没有控制器来使它生效的话,是没有任何作用的。 +来实现。要使用网络策略,你必须使用支持 NetworkPolicy 的网络解决方案。 +创建一个 NetworkPolicy 资源对象而没有控制器来使它生效的话,是没有任何作用的。 -## 隔离和非隔离的 Pod +## 隔离和非隔离的 Pod {#isolated-and-non-isolated-pods} 默认情况下,Pod 是非隔离的,它们接受任何来源的流量。 -Pod 可以通过相关的网络策略进行隔离。一旦命名空间中有网络策略选择了特定的 Pod, -该 Pod 会拒绝网络策略所不允许的连接。 -(命名空间下其他未被网络策略所选择的 Pod 会继续接收所有的流量) +Pod 在被某 NetworkPolicy 选中时进入被隔离状态。 +一旦名字空间中有 NetworkPolicy 选择了特定的 Pod,该 Pod 会拒绝该 NetworkPolicy +所不允许的连接。 +(名字空间下其他未被 NetworkPolicy 所选择的 Pod 会继续接受所有的流量) 网络策略不会冲突,它们是累积的。 如果任何一个或多个策略选择了一个 Pod, 则该 Pod 受限于这些策略的 -ingress/egress 规则的并集。因此评估的顺序并不会影响策略的结果。 +入站(Ingress)/出站(Egress)规则的并集。因此评估的顺序并不会影响策略的结果。 - ## NetworkPolicy 资源 {#networkpolicy-resource} -查看 [NetworkPolicy](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#networkpolicy-v1-networking-k8s-io) 来了解完整的资源定义。 +参阅 [NetworkPolicy](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#networkpolicy-v1-networking-k8s-io) +来了解资源的完整定义。 下面是一个 NetworkPolicy 的示例: @@ -127,27 +151,41 @@ and [Object Management](/docs/concepts/overview/working-with-objects/object-mana __spec__: NetworkPolicy [spec](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status) has all the information needed to define a particular network policy in the given namespace. __podSelector__: Each NetworkPolicy includes a `podSelector` which selects the grouping of pods to which the policy applies. The example policy selects pods with the label "role=db". An empty `podSelector` selects all pods in the namespace. +--> +__必需字段__:与所有其他的 Kubernetes 配置一样,NetworkPolicy 需要 `apiVersion`、 +`kind` 和 `metadata` 字段。关于配置文件操作的一般信息,请参考 +[使用 ConfigMap 配置容器](/zh/docs/tasks/configure-pod-container/configure-pod-configmap/), +和[对象管理](/zh/docs/concepts/overview/working-with-objects/object-management)。 +__spec__:NetworkPolicy [规约](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status) +中包含了在一个名字空间中定义特定网络策略所需的所有信息。 + +__podSelector__:每个 NetworkPolicy 都包括一个 `podSelector`,它对该策略所 +适用的一组 Pod 进行选择。示例中的策略选择带有 "role=db" 标签的 Pod。 +空的 `podSelector` 选择名字空间下的所有 Pod。 + + -__必填字段__: 与所有其他的 Kubernetes 配置一样,NetworkPolicy 需要 `apiVersion`、`kind` 和 `metadata` 字段。 - 关于配置文件操作的一般信息,请参考 [使用 ConfigMap 配置容器](/zh/docs/tasks/configure-pod-container/configure-pod-configmap/), - 和[对象管理](/zh/docs/concepts/overview/working-with-objects/object-management)。 +__policyTypes__: 每个 NetworkPolicy 都包含一个 `policyTypes` 列表,其中包含 +`Ingress` 或 `Egress` 或两者兼具。`policyTypes` 字段表示给定的策略是应用于 +进入所选 Pod 的入站流量还是来自所选 Pod 的出站流量,或两者兼有。 +如果 NetworkPolicy 未指定 `policyTypes` 则默认情况下始终设置 `Ingress`; +如果 NetworkPolicy 有任何出口规则的话则设置 `Egress`。 -__spec__: NetworkPolicy [规约](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status) 中包含了在一个命名空间中定义特定网络策略所需的所有信息。 +__ingress__: 每个 NetworkPolicy 可包含一个 `ingress` 规则的白名单列表。 +每个规则都允许同时匹配 `from` 和 `ports` 部分的流量。示例策略中包含一条 +简单的规则: 它匹配某个特定端口,来自三个来源中的一个,第一个通过 `ipBlock` +指定,第二个通过 `namespaceSelector` 指定,第三个通过 `podSelector` 指定。 -__podSelector__: 每个 NetworkPolicy 都包括一个 `podSelector` ,它对该策略所应用的一组 Pod 进行选择。示例中的策略选择带有 "role=db" 标签的 Pod。空的 `podSelector` 选择命名空间下的所有 Pod。 - -__policyTypes__: 每个 NetworkPolicy 都包含一个 `policyTypes` 列表,其中包含 `Ingress` 或 `Egress` 或两者兼具。`policyTypes` 字段表示给定的策略是否应用于进入所选 Pod 的入口流量或者来自所选 Pod 的出口流量,或两者兼有。如果 NetworkPolicy 未指定 `policyTypes` 则默认情况下始终设置 `Ingress`,如果 NetworkPolicy 有任何出口规则的话则设置 `Egress`。 - -__ingress__: 每个 NetworkPolicy 可包含一个 `ingress` 规则的白名单列表。每个规则都允许同时匹配 `from` 和 `ports` 部分的流量。示例策略中包含一条简单的规则: 它匹配一个单一的端口,来自三个来源中的一个, 第一个通过 `ipBlock` 指定,第二个通过 `namespaceSelector` 指定,第三个通过 `podSelector` 指定。 - -__egress__: 每个 NetworkPolicy 可包含一个 `egress` 规则的白名单列表。每个规则都允许匹配 `to` 和 `port` 部分的流量。该示例策略包含一条规则,该规则将单个端口上的流量匹配到 `10.0.0.0/24` 中的任何目的地。 +__egress__: 每个 NetworkPolicy 可包含一个 `egress` 规则的白名单列表。 +每个规则都允许匹配 `to` 和 `port` 部分的流量。该示例策略包含一条规则, +该规则将指定端口上的流量匹配到 `10.0.0.0/24` 中的任何目的地。 - 所以,该网络策略示例: -1. 隔离 "default" 命名空间下 "role=db" 的 Pod (如果它们不是已经被隔离的话)。 -2. (Ingress 规则)允许以下 Pod 连接到 "default" 命名空间下的带有 “role=db” 标签的所有 Pod 的 6379 TCP 端口: +1. 隔离 "default" 名字空间下 "role=db" 的 Pod (如果它们不是已经被隔离的话)。 +2. (Ingress 规则)允许以下 Pod 连接到 "default" 名字空间下的带有 "role=db" + 标签的所有 Pod 的 6379 TCP 端口: - * "default" 命名空间下任意带有 "role=frontend" 标签的 Pod - * 带有 "project=myproject" 标签的任意命名空间中的 Pod - * IP 地址范围为 172.17.0.0–172.17.0.255 和 172.17.2.0–172.17.255.255(即,除了 172.17.1.0/24 之外的所有 172.17.0.0/16) -3. (Egress 规则)允许从带有 "role=db" 标签的命名空间下的任何 Pod 到 CIDR 10.0.0.0/24 下 5978 TCP 端口的连接。 + * "default" 名字空间下带有 "role=frontend" 标签的所有 Pod + * 带有 "project=myproject" 标签的所有名字空间中的 Pod + * IP 地址范围为 172.17.0.0–172.17.0.255 和 172.17.2.0–172.17.255.255 + (即,除了 172.17.1.0/24 之外的所有 172.17.0.0/16) -查看[声明网络策略](/zh/docs/tasks/administer-cluster/declare-network-policy/) 来进行更多的示例演练。 +3. (Egress 规则)允许从带有 "role=db" 标签的名字空间下的任何 Pod 到 CIDR + 10.0.0.0/24 下 5978 TCP 端口的连接。 + +参阅[声明网络策略](/zh/docs/tasks/administer-cluster/declare-network-policy/)演练 +了解更多示例。 +## 选择器 `to` 和 `from` 的行为 {#behavior-of-to-and-from-selectors} -## 选择器 `to` 和 `from` 的行为 +可以在 `ingress` 的 `from` 部分或 `egress` 的 `to` 部分中指定四种选择器: -可以在 `ingress` `from` 部分或 `egress` `to` 部分中指定四种选择器: +__podSelector__: 此选择器将在与 NetworkPolicy 相同的名字空间中选择特定的 +Pod,应将其允许作为入站流量来源或出站流量目的地。 -__podSelector__: 这将在与 NetworkPolicy 相同的命名空间中选择特定的 Pod,应将其允许作为入口源或出口目的地。 +__namespaceSelector__:此选择器将选择特定的名字空间,应将所有 Pod 用作其 +入站流量来源或出站流量目的地。 -__namespaceSelector__: 这将选择特定的命名空间,应将所有 Pod 用作其输入源或输出目的地。 - -__namespaceSelector__ *和* __podSelector__: 一个指定 `namespaceSelector` 和 `podSelector` 的 `to`/`from` 条目选择特定命名空间中的特定 Pod。注意使用正确的 YAML 语法;这项策略: +__namespaceSelector__ *和* __podSelector__: 一个指定 `namespaceSelector` +和 `podSelector` 的 `to`/`from` 条目选择特定名字空间中的特定 Pod。 +注意使用正确的 YAML 语法;下面的策略: ```yaml ... @@ -213,7 +258,8 @@ __namespaceSelector__ *和* __podSelector__: 一个指定 `namespaceSelector` -在 `from` 数组中仅包含一个元素,只允许来自标有 `role=client` 的 Pod 且该 Pod 所在的命名空间中标有 `user=alice` 的连接。但是 *这项* 策略: +在 `from` 数组中仅包含一个元素,只允许来自标有 `role=client` 的 Pod 且 +该 Pod 所在的名字空间中标有 `user=alice` 的连接。但是 *这项* 策略: ```yaml ... @@ -230,7 +276,11 @@ contains a single `from` element allowing connections from Pods with the label ` +在 `from` 数组中包含两个元素,允许来自本地名字空间中标有 `role=client` 的 +Pod 的连接,*或* 来自任何名字空间中标有 `user=alice` 的任何 Pod 的连接。 + - -在 `from` 数组中包含两个元素,允许来自本地命名空间中标有 `role=client` 的 Pod 的连接,*或* 来自任何命名空间中标有 `user = alice` 的任何 Pod 的连接。 - 如有疑问,请使用 `kubectl describe` 查看 Kubernetes 如何解释该策略。 -__ipBlock__: 这将选择特定的 IP CIDR 范围以用作入口源或出口目的地。 这些应该是群集外部 IP,因为 Pod IP 存在时间短暂的且随机产生。 +__ipBlock__: 此选择器将选择特定的 IP CIDR 范围以用作入站流量来源或出站流量目的地。 +这些应该是集群外部 IP,因为 Pod IP 存在时间短暂的且随机产生。 -群集的入口和出口机制通常需要重写数据包的源 IP 或目标 IP。在发生这种情况的情况下,不确定在 NetworkPolicy 处理之前还是之后发生,并且对于网络插件,云提供商,`Service` 实现等的不同组合,其行为可能会有所不同。 +集群的入站和出站机制通常需要重写数据包的源 IP 或目标 IP。 +在发生这种情况时,不确定在 NetworkPolicy 处理之前还是之后发生, +并且对于网络插件、云提供商、`Service` 实现等的不同组合,其行为可能会有所不同。 -在进入的情况下,这意味着在某些情况下,您可以根据实际的原始源 IP 过滤传入的数据包,而在其他情况下,NetworkPolicy 所作用的 `源IP` 则可能是 `LoadBalancer` 或 Pod 的节点等。 +对入站流量而言,这意味着在某些情况下,你可以根据实际的原始源 IP 过滤传入的数据包, +而在其他情况下,NetworkPolicy 所作用的 `源IP` 则可能是 `LoadBalancer` 或 +Pod 的节点等。 -对于出口,这意味着从 Pod 到被重写为集群外部 IP 的 `Service` IP 的连接可能会或可能不会受到基于 `ipBlock` 的策略的约束。 +对于出站流量而言,这意味着从 Pod 到被重写为集群外部 IP 的 `Service` IP +的连接可能会或可能不会受到基于 `ipBlock` 的策略的约束。 +## 默认策略 {#default-policies} -## 默认策略 - -默认情况下,如果命名空间中不存在任何策略,则所有进出该命名空间中的 Pod 的流量都被允许。以下示例使您可以更改该命名空间中的默认行为。 +默认情况下,如果名字空间中不存在任何策略,则所有进出该名字空间中 Pod 的流量都被允许。 +以下示例使你可以更改该名字空间中的默认行为。 +### 默认拒绝所有入站流量 -### 默认拒绝所有入口流量 - -您可以通过创建选择所有容器但不允许任何进入这些容器的入口流量的 NetworkPolicy 来为命名空间创建 "default" 隔离策略。 +你可以通过创建选择所有容器但不允许任何进入这些容器的入站流量的 NetworkPolicy +来为名字空间创建 "default" 隔离策略。 {{< codenew file="service/networking/network-policy-default-deny-ingress.yaml" >}} -这样可以确保即使容器没有选择其他任何 NetworkPolicy,也仍然可以被隔离。此策略不会更改默认的出口隔离行为。 +这样可以确保即使容器没有选择其他任何 NetworkPolicy,也仍然可以被隔离。 +此策略不会更改默认的出口隔离行为。 +### 默认允许所有入站流量 -### 默认允许所有入口流量 - -如果要允许所有流量进入某个命名空间中的所有 Pod(即使添加了导致某些 Pod 被视为“隔离”的策略),则可以创建一个策略来明确允许该命名空间中的所有流量。 +如果要允许所有流量进入某个名字空间中的所有 Pod(即使添加了导致某些 Pod 被视为 +“隔离”的策略),则可以创建一个策略来明确允许该名字空间中的所有流量。 {{< codenew file="service/networking/network-policy-allow-all-ingress.yaml" >}} @@ -305,10 +359,10 @@ If you want to allow all traffic to all pods in a namespace (even if policies ar You can create a "default" egress isolation policy for a namespace by creating a NetworkPolicy that selects all pods but does not allow any egress traffic from those pods. --> +### 默认拒绝所有出站流量 -### 默认拒绝所有出口流量 - -您可以通过创建选择所有容器但不允许来自这些容器的任何出口流量的 NetworkPolicy 来为命名空间创建 "default" egress 隔离策略。 +你可以通过创建选择所有容器但不允许来自这些容器的任何出站流量的 NetworkPolicy +来为名字空间创建 "default" egress 隔离策略。 {{< codenew file="service/networking/network-policy-default-deny-egress.yaml" >}} @@ -316,18 +370,18 @@ You can create a "default" egress isolation policy for a namespace by creating a This ensures that even pods that aren't selected by any other NetworkPolicy will not be allowed egress traffic. This policy does not change the default ingress isolation behavior. --> - -这样可以确保即使没有被其他任何 NetworkPolicy 选择的 Pod 也不会被允许流出流量。此策略不会更改默认的 ingress 隔离行为。 +此策略可以确保即使没有被其他任何 NetworkPolicy 选择的 Pod 也不会被允许流出流量。 +此策略不会更改默认的入站流量隔离行为。 +### 默认允许所有出站流量 -### 默认允许所有出口流量 - -如果要允许来自命名空间中所有 Pod 的所有流量(即使添加了导致某些 Pod 被视为“隔离”的策略),则可以创建一个策略,该策略明确允许该命名空间中的所有出口流量。 +如果要允许来自名字空间中所有 Pod 的所有流量(即使添加了导致某些 Pod 被视为“隔离”的策略), +则可以创建一个策略,该策略明确允许该名字空间中的所有出站流量。 {{< codenew file="service/networking/network-policy-allow-all-egress.yaml" >}} @@ -336,41 +390,91 @@ If you want to allow all traffic from all pods in a namespace (even if policies You can create a "default" policy for a namespace which prevents all ingress AND egress traffic by creating the following NetworkPolicy in that namespace. --> +### 默认拒绝所有入口和所有出站流量 -### 默认拒绝所有入口和所有出口流量 - -您可以为命名空间创建 "default" 策略,以通过在该命名空间中创建以下 NetworkPolicy 来阻止所有入站和出站流量。 +你可以为名字空间创建“默认”策略,以通过在该名字空间中创建以下 NetworkPolicy +来阻止所有入站和出站流量。 {{< codenew file="service/networking/network-policy-default-deny-all.yaml" >}} - -这样可以确保即使没有被其他任何 NetworkPolicy 选择的 Pod 也不会被允许进入或流出流量。 +此策略可以确保即使没有被其他任何 NetworkPolicy 选择的 Pod 也不会被 +允许入站或出站流量。 ## SCTP 支持 -{{< feature-state for_k8s_version="v1.12" state="alpha" >}} +{{< feature-state for_k8s_version="v1.19" state="beta" >}} -要启用此特性,你(或你的集群管理员)需要通过为 API server 指定 `--feature-gates=SCTPSupport=true,…` -来启用 `SCTPSupport` [特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)。 -启用该特性开关后,用户可以将 NetworkPolicy 的 `protocol` 字段设置为 `SCTP`。 +作为一个 Beta 特性,SCTP 支持默认是被启用的。 +要在集群层面禁用 SCTP,你(或你的集群管理员)需要为 API 服务器指定 +`--feature-gates=SCTPSupport=false,...` +来禁用 `SCTPSupport` [特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)。 +启用该特性门控后,用户可以将 NetworkPolicy 的 `protocol` 字段设置为 `SCTP`。 {{< note >}} -必须使用支持 SCTP 协议网络策略的 {{< glossary_tooltip text="CNI" term_id="cni" >}} 插件。 +你必须使用支持 SCTP 协议网络策略的 {{< glossary_tooltip text="CNI" term_id="cni" >}} 插件。 {{< /note >}} + +## 你通过网络策略(至少目前还)无法完成的工作 + +到 Kubernetes v1.20 为止,NetworkPolicy API 还不支持以下功能,不过 +你可能可以使用操作系统组件(如 SELinux、OpenVSwitch、IPTables 等等) +或者第七层技术(Ingress 控制器、服务网格实现)或准入控制器来实现一些 +替代方案。 +如果你对 Kubernetes 中的网络安全性还不太了解,了解使用 NetworkPolicy API +还无法实现下面的用户场景是很值得的。 +对这些用户场景中的一部分(而非全部)的讨论扔在进行,或许在将来 NetworkPolicy +API 中会给出一定支持。 + + +- 强制集群内部流量经过某公用网关(这种场景最好通过服务网格或其他代理来实现); +- 与 TLS 相关的场景(考虑使用服务网格或者 Ingress 控制器); +- 特定于节点的策略(你可以使用 CIDR 来表达这一需求不过你无法使用节点在 + Kubernetes 中的其他标识信息来辩识目标节点); +- 基于名字来选择名字空间或者服务(不过,你可以使用 {{< glossary_tooltip text="标签" term_id="label" >}} + 来选择目标 Pod 或名字空间,这也通常是一种可靠的替代方案); +- 创建或管理由第三方来实际完成的“策略请求”; + +- 实现适用于所有名字空间或 Pods 的默认策略(某些第三方 Kubernetes 发行版本 + 或项目可以做到这点); +- 高级的策略查询或者可达性相关工具; +- 在同一策略声明中选择目标端口范围的能力; +- 生成网络安全事件日志的能力(例如,被阻塞或接收的连接请求); +- 显式地拒绝策略的能力(目前,NetworkPolicy 的模型默认采用拒绝操作, + 其唯一的能力是添加允许策略); +- 禁止本地回路或指向宿主的网络流量(Pod 目前无法阻塞 localhost 访问, + 它们也无法禁止来自所在节点的访问请求)。 + ## {{% heading "whatsnext" %}} - -- 查看 [声明网络策略](/zh/docs/tasks/administer-cluster/declare-network-policy/) - 来进行更多的示例演练 -- 有关 NetworkPolicy 资源启用的常见场景的更多信息,请参见 +- 参阅[声明网络策略](/zh/docs/tasks/administer-cluster/declare-network-policy/) + 演练了解更多示例; +- 有关 NetworkPolicy 资源所支持的常见场景的更多信息,请参见 [此指南](https://github.com/ahmetb/kubernetes-network-policy-recipes)。