网站搜索

使用 Pod 网络策略保护 Kubernetes 集群流量


默认情况下,Kubernetes Pod 可以相互自由通信。当您的集群用于多个应用程序或团队时,这会带来安全风险。一个 Pod 中的错误行为或恶意访问可能会将流量定向到集群中的其他 Pod。

本文将教您如何通过设置网络策略来避免这种情况。这些规则让您可以在 IP 地址级别(OSI 第 3 层或第 4 层)控制 Pod 到 Pod 的流量。您可以精确定义每个 Pod 允许的入口和出口源。

创建网络策略

网络策略是通过将 NetworkPolicy 对象添加到您的集群来创建的。每个策略都定义了它适用的 Pod 以及一个或多个入口和出口规则。这是一个基本的政策清单:

class="co3">apiVersionclass="sy2">: networking.k8s.io/v1class="co3">
kindclass="sy2">: NetworkPolicyclass="co4">
metadata:class="co3">
  nameclass="sy2">: network-policyclass="co3">
  namespaceclass="sy2">: appclass="co4">
spec:class="co4">
  podSelector:class="co4">
    matchLabels:class="co3">
      componentclass="sy2">: databaseclass="co4">
  policyTypesclass="sy2">:
    - Ingress
    - Egressclass="co4">
  ingress:class="co4">
    - from:class="co4">
      - podSelector:class="co4">
          matchLabels:class="co3">
            componentclass="sy2">: apiclass="co4">
  egress:class="co4">
    - to:class="co4">
        - podSelector:class="co4">
            matchLabels:class="co3">
              componentclass="sy2">: api

此网络策略适用于 app 命名空间中具有 component: database 标签的任何 Pod。它声明入口(传入)和出口(传出)流量只允许进出具有 component: api 标签的 Pod。任何来自其他 Pod 的请求,例如 component: web-frontend,都将被阻止。

通过使用 Kubectl,可以像应用任何其他对象一样应用网络策略。它们将在创建后立即生效。您可以在启动它选择的 Pod 之前添加网络策略。

$ kubectl apply -f policy.yaml
networkingpolicy.networking.k8s.io/network-policy created

网络策略如何运作

网络策略由集群的活动网络插件实施。如果您的插件不支持该功能,您的政策将不会产生任何影响。大多数流行的选项,如 Calico 和 Cilium,都启用了网络策略支持。

当网络策略应用于 Pod 时,插件将检查其流量以检查其是否符合策略要求。任何不符合条件的连接都将被禁止。尝试发起连接的 Pod 会发现远程主机无法访问,这可能是因为它试图访问被出口规则阻止的资源,或者因为远程 Pod 使用入口规则拒绝了传入连接。

只有当它们的网络策略都允许时,才能在两个 Pod 之间建立成功的连接。发起 Pod 的出口规则或目标上的入口规则可能会禁止连接。

网络策略在本质上总是附加。当多个策略选择同一个 Pod 时,允许的入口和出口源列表将是所有策略的组合。

示例网络策略

网络策略支持许多不同的选项来自定义它们定位的 Pod 和允许的连接类型。以下示例展示了几个常见的用例。

将策略应用于命名空间中的每个 Pod,仅允许来自特定 IP 地址块的入口流量

class="co3">apiVersionclass="sy2">: networking.k8s.io/v1class="co3">
kindclass="sy2">: NetworkPolicyclass="co4">
metadata:class="co3">
  nameclass="sy2">: network-policyclass="co3">
  namespaceclass="sy2">: appclass="co4">
spec:class="co3">
  podSelectorclass="sy2">: class="br0">{class="br0">}class="co4">
  policyTypesclass="sy2">:
    - Ingressclass="co4">
  ingress:class="co4">
    - from:class="co4">
        - ipBlock:class="co3">
            cidrclass="sy2">: 172.17.0.0/16

空的 podSelector 块意味着所有名称空间的 Pod 都是策略的目标。 ipBlock 规则限制进入 IP 地址在指定范围内的 Pod 的流量。出口流量未被阻止。

允许来自 IP 地址块的入口流量,但排除某些特定 IP

class="co3">apiVersionclass="sy2">: networking.k8s.io/v1class="co3">
kindclass="sy2">: NetworkPolicyclass="co4">
metadata:class="co3">
  nameclass="sy2">: network-policyclass="co3">
  namespaceclass="sy2">: appclass="co4">
spec:class="co3">
  podSelectorclass="sy2">: class="br0">{class="br0">}class="co4">
  policyTypesclass="sy2">:
    - Ingressclass="co4">
  ingress:class="co4">
    - from:class="co4">
        - ipBlock:class="co3">
            cidrclass="sy2">: 172.17.0.0/16class="co4">
            exceptclass="sy2">:
              - 172.17.0.1/24
              - 172.17.0.2/24
              - 172.17.0.3/24

ipBlock 规则支持 except 字段以排除源自或指向特定 IP 的流量。

允许来自命名空间中所有 Pod 的入口流量,但仅来自特定端口

class="co3">apiVersionclass="sy2">: networking.k8s.io/v1class="co3">
kindclass="sy2">: NetworkPolicyclass="co4">
metadata:class="co3">
  nameclass="sy2">: network-policyclass="co3">
  namespaceclass="sy2">: appclass="co4">
spec:class="co3">
  podSelectorclass="sy2">: class="br0">{class="br0">}class="co4">
  policyTypesclass="sy2">:
    - Ingressclass="co4">
  ingress:class="co4">
    - from:class="co3">
        - podSelectorclass="sy2">: class="br0">{class="br0">}class="co4">
          ports:class="co3">
            - protocolclass="sy2">: TCPclass="co3">
              portclass="sy2">: 443

ports 字段在入口和出口规则中可用。它定义了可以从中接收和发送流量的端口。除了 port (3000) 之外,您还可以通过设置 endPort 字段 (3500) 来选择性地指定端口范围,例如 3000 – 3500。

允许来自不同命名空间中具有特定标签的 Pod 的流量

class="co3">apiVersionclass="sy2">: networking.k8s.io/v1class="co3">
kindclass="sy2">: NetworkPolicyclass="co4">
metadata:class="co3">
  nameclass="sy2">: network-policyclass="co3">
  namespaceclass="sy2">: databaseclass="co4">
spec:class="co3">
  podSelectorclass="sy2">: class="br0">{class="br0">}class="co4">
  policyTypesclass="sy2">:
    - Ingressclass="co4">
  ingress:class="co4">
    - from:class="co4">
        - namespaceSelector:class="co4">
            matchLabels:class="co3">
              applicationclass="sy2">: demo-appclass="co4">
          podSelector:class="co4">
            matchLabels:class="co3">
              componentclass="sy2">: database

该策略声明任何标记为 component: database 的 Pod 都可以访问 database 命名空间中的所有 Pod,如果它自己的命名空间被标记为 demo-app .

通过创建仅包含 namespaceSelector 字段的规则,您可以允许来自外部命名空间中所有 Pod 的流量。

明确允许所有流量

有时您可能希望明确允许命名空间内特定类型的所有流量。在您的策略中包含类型,但提供一个空的 Pod 选择器并且没有规则:

class="co3">apiVersionclass="sy2">: networking.k8s.io/v1class="co3">
kindclass="sy2">: NetworkPolicyclass="co4">
metadata:class="co3">
  nameclass="sy2">: network-policyclass="co3">
  namespaceclass="sy2">: appclass="co4">
spec:class="co3">
  podSelectorclass="sy2">: class="br0">{class="br0">}class="co4">
  policyTypesclass="sy2">:
    - Ingress
    - Egressclass="co4">
  ingressclass="sy2">:
    - class="br0">{class="br0">}class="co4">
  egressclass="sy2">:
    - class="br0">{class="br0">}

命名空间中的所有 Pod 都可以自由通信,就像没有策略一样。无论如何创建策略都可以让您向其他集群用户表明您的意图。他们可能会质疑集群中是否存在具有不受限制的网络的名称空间,否则该名称空间将受到保护。

何时使用网络策略

应该为集群中的每个命名空间和 Pod 创建网络策略。这样可以更好地隔离您的 Pod 并让您控制流量。

尝试使您的策略尽可能细化。过多地扩大访问权限,例如允许在一个命名空间中的所有 Pod 之间进行访问,如果您的一个容器遭到破坏,您就会面临风险。考虑使用精确的选择器来识别敏感 Pod(例如身份验证服务、数据库和支付处理程序)的各个入口和出口远程。

默认情况下,Kubernetes 不启用任何可能允许疏忽的网络策略,即使您希望所有 Pod 都受策略保护。您可以通过向命名空间添加一个包罗万象的策略来减轻这种风险。该策略选择命名空间中的每个 Pod 并应用禁止所有网络通信的规则:

class="co3">apiVersionclass="sy2">: networking.k8s.io/v1class="co3">
kindclass="sy2">: NetworkPolicyclass="co4">
metadata:class="co3">
  nameclass="sy2">: deny-class="kw1">allclass="co3">
  namespaceclass="sy2">: appclass="co4">
spec:class="co3">
  podSelectorclass="sy2">: class="br0">{class="br0">}class="co4">
  policyTypesclass="sy2">:
    - Ingress
    - Egress

网络策略始终限定在命名空间范围内,因此您需要为每个命名空间创建一个单独的包罗万象。

概括

Kubernetes 允许集群中的所有 Pod 相互通信。这对于在多用途集群中运行的实际应用程序来说过于宽松。网络策略通过提供类似防火墙的系统来管理每个 Pod 接受的入口源和出口目标来解决这个问题。

在所有 Pod 上配置网络策略是一种很好的做法。这将保护您的集群,因此只允许合法的流量。网络策略只是 Kubernetes 安全的一部分,但是:其他保护机制(例如 RBAC 和 Pod 安全上下文)也是强化环境的重要工具。

相关文章:


版权所有。 © Linux-Console.net • 2019-2026