使用 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/24ipBlock 规则支持 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">: 443ports 字段在入口和出口规则中可用。它定义了可以从中接收和发送流量的端口。除了 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 保护代码的独特方法
- 在 Linux 服务器或桌面上保护 SSH 的 5 个技巧
- 保护开源生态系统:SBOM 不再是可选的
- 白宫与 OpenSSF 和 Linux 基金会一起保护开源软件
- 在 Ubuntu 上保护 Apache - 第 1 部分
- 在 Ubuntu 上保护 Apache – 第 2 部分
- 容器安全最佳实践:保护 Docker
- 使用 TCP 包装器保护 Linux:快速操作方法
- 为初学者保护 Linux 服务器的 6 个开源工具和技巧
- 保护 Django 应用程序的安全:最佳实践和技术
- 保护 SSH、设置主机名并启用网络服务
- 保护新的 Windows 服务器
- 在 IIS 中设置 HTTPS 重定向并保护您的 URL
- 保护您的 WordPress 安装
- 保护您的 Linux VPS 的介绍