本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

在 Kubernetes 中实施网络策略

编者按:这篇博文是关于Kubernetes 1.8新功能的系列深度文章之一。

Kubernetes 现在提供使用网络策略来强制执行 Pod 之间通信规则的功能。此功能已在 Kubernetes 1.7 中变得稳定,并可在受支持的网络插件中使用。Kubernetes 1.8 版本增强了此功能。

网络策略:它意味着什么?

在配置了默认设置的 Kubernetes 集群中,所有 Pod 都可以无限制地相互发现和通信。新的 Kubernetes 对象类型 NetworkPolicy 允许您允许和阻止流向 Pod 的流量。

如果您在 Kubernetes 集群中运行多个应用程序或在多个团队之间共享集群,创建允许 Pod 相互通信同时阻止其他网络流量的防火墙是最佳安全实践。网络策略对应于虚拟机世界中的安全组概念。

我如何向我的集群添加网络策略?

网络策略由网络插件实现。这些插件通常在您的集群中安装一个叠加网络以强制执行配置的网络策略。许多网络插件,包括 CalicoRomanaWeave Net,都支持使用网络策略。

Google Container Engine (GKE) 也为使用 Calico 网络插件的网络策略提供 Beta 支持,当您使用以下命令创建集群时:

gcloud beta container clusters create --enable-network-policy

我如何配置网络策略?

安装实现网络策略的网络插件后,您需要创建一个类型为 NetworkPolicy 的 Kubernetes 资源。此对象描述了两组基于标签的 Pod 选择器字段,匹配:

  1. 网络策略适用的 Pod 集合(必需)
  2. 允许相互访问的 Pod 集合(可选)。如果省略此字段,则不匹配任何 Pod;因此,不允许任何 Pod。如果您指定一个空的 Pod 选择器,则匹配所有 Pod;因此,允许所有 Pod。

示例:限制流向 Pod 的流量

以下网络策略示例阻止所有集群内流向一组 Web 服务器 Pod 的流量,除了策略配置允许的 Pod。

要实现此设置,请使用以下清单创建 NetworkPolicy:

kind: NetworkPolicy

apiVersion: networking.k8s.io/v1

metadata:

  name: access-nginx

spec:

  podSelector:

    matchLabels:

      app: nginx

  ingress:

  - from:

    - podSelector:

        matchLabels:

          app: foo

应用此配置后,只有带有标签 app: foo 的 Pod 才能与带有标签 app: nginx 的 Pod 通信。有关更详细的教程,请参阅 Kubernetes 文档

示例:默认情况下限制所有 Pod 之间的流量

如果将 spec.podSelector 字段指定为空,则网络策略匹配的 Pod 集合将是命名空间中的所有 Pod,默认情况下阻止所有 Pod 之间的流量。在这种情况下,您必须明确创建网络策略,将所有 Pod 之间的通信列入白名单。

您可以通过在 Kubernetes 集群中应用以下清单来启用此类策略:

apiVersion: networking.k8s.io/v1

kind: NetworkPolicy

metadata:

  name: default-deny

spec:

  podSelector:

其他网络策略功能

除了前面的示例,您还可以让网络策略 API 强制执行更复杂的规则:

  • 出站网络策略:在 Kubernetes 1.8 中引入,您可以限制您的工作负载建立与指定 IP 范围之外的资源的连接。
  • IP 块支持:除了使用 podSelector/namespaceSelector,您还可以使用 CIDR 块指定 IP 范围,以允许/拒绝入站或出站规则中的流量。
  • 跨命名空间策略:使用 ingress.namespaceSelector 字段,您可以为集群中的特定或所有命名空间强制执行网络策略。例如,您可以创建特权/系统命名空间,即使默认策略是阻止流量,它们也可以与 Pod 通信。
  • 限制流向端口号的流量:使用 ingress.ports 字段,您可以指定策略要强制执行的端口号。如果省略此字段,策略默认匹配所有端口。例如,您可以使用此功能允许监控 Pod 仅查询应用程序的监控端口号。
  • 单个策略上的多个入站规则:由于 spec.ingress 字段是一个数组,您可以使用相同的 NetworkPolicy 对象通过不同的 Pod 选择器授予对不同端口的访问权限。例如,一个 NetworkPolicy 可以有一个入站规则,授予带有标签 kind: monitoring 的 Pod 访问端口 9000 的权限,以及另一个入站规则,授予带有标签 app: foo 的 Pod 访问端口 80 的权限,而无需创建额外的 NetworkPolicy 资源。

了解更多