NetworkPolicy是Kubernetes的一个新特性,它负责配置Pod组如何与彼此和其他网络端点进行通信。换句话说,它在运行于Kubernetes集群上的Pod间创建防火墙。
该特性在Kubernetes 1.7版中已较为稳定。本文将阐述NetworkPolicy在理论与实践中分别是如何工作的。
使用NetworkPolicy你可以做些什么
默认情况下,Kubernetes没有限制集群内pod之间的通信。这意味着集群内任意Pod之间都可以像没有防火墙一样直接进行通信。NetworkPolicy让我们可以规定有哪些Pod可以连接到其余Pod。
这些Policy可以被描述的更为细节:你可以指定哪些命名空间可以进行通信,或者更具体地说,你可以选择要执行每个Policy的端口号。
目前你不能使用这一特性强制执行来自pod的外发(出口)流量的Policy。这在Kubernetes 1.8的规划中。
同时,Istio开源项目也是一个支持出口策略和其他更多功能的替代方案。
为什么说NetworkPolicy很酷
数十年来,NetworkPolicy是用来计算ACL(访问控制列表)的独特方式。这是Kubernetes在Pod之间进行ACL的方式。就像任何其他Kubernetes资源一样,NetworkPolicy通过声明式文件配置。它们是应用程序的一部分,你可以在源存储库中对它们进行修改,并随着应用程序部署到Kubernetes中。
NetworkPolicy几乎是实时应用的。如果你在Pod之间建立了连接,则应用组织连接的NetworkPolicy将会导致连接立即被终止。这种近乎实时的好处是使网络损耗非常小。
使用案例示例
以下是NetworkPolicy一般使用案例的简单清单。
阻断到应用程序的所有流量
限制到应用程序的流量
在命名空间中阻断所有非白名单的流量
阻断来自其他命名空间的所有流量
允许来自其他命名空间的流量
允许来自外部客户端的流量
NetworkPolicy如何执行
NetworkPolicy的实现不是Kubernetes的核心功能。即使你可以提交一个NetworkPolicy对象到Kubernetes主节点,如果你的网络插件不能实现网络策略,它也不会被实现。
Google Container Engine (GCE)通过在集群中预装Calico网络插件提供了对网络策略的支持。
网络策略适用于连接,而不是网络数据包。请注意,一个连接允许网络数据包的双向传输。例如,如果Pod A可以连接到Pod B,那么Pod B会在相同的连接中响应Pod A。这并不意味着Pod B可以启动与Pod A的连接。
NetworkPolicy的结构
NetworkPolicy只是Kubernetes API的另一个对象。你可以为一个集群创建许多NetworkPolicy。一个NetworkPolicy有两个主要部分:
- 目标Pod:哪些Pod有通过NetworkPolicy执行的ingress网络连接?这些Pod通过它们的标签被选择。
- Ingress规则:哪些Pod可以连接到目标Pod?这些Pod通过它们的标签或者命名空间被选择。
如下是一个NetworkPolicy更具体的例子:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: api-allow spec: podSelector: matchLabels: app: bookstore role: api ingress: - from: - podSelector: matchLabels: app: bookstore - from: - podSelector: matchLabels: app: inventory
这个样例Policy允许拥有app=bookstore或app=inventory标签的Pod连接到拥有app=bookstore和role=api标签的Pod。你可以这样解读它:把bookstore应用程序访问的微服务指定给bookstore的API。
如何评价NetworkPolicy
NetworkPolicy的设计文档和API reference看起来比较复杂,我设法把它分解成几个简单的规则:
- 如果NetworkPolicy选择了一个Pod,那么到该Pod的流量将受到限制。
- 如果一个Pod没有NetworkPolicy,命名空间下的所有Pod都可以连接到此Pod。这意味着如果没有为一个Pod定义NetworkPolicy,就默认“允许所有”。
- 如果Pod A的流量被限制,但Pod B需要连接到Pod A,这应当至少有一个NetworkPolicy选择Pod A,且它具有选择Pod B的Ingress规则。
当包含跨命名空间网络时,事情就变得有些复杂了,简而言之,它是这样工作的:
- NetworkPolicy可以强制执行与部署在同一命名空间下的Pod的连接的规则。
- Ingress规则的podSelector只能选择部署NetworkPolicy的同一命名空间中的pod。
- 如果Pod A需要连接另一命名空间下的Pod B,并且Pod B的网络被强制执行,则需要在Pod B中有一个具有选择Pod A的namespaceSelector的Policy。
NetworkPolicy是否安全
NetworkPolicy限制Pod到Pod的网络,这是保护集群流量和应用程序的一部分。它们不是进行深度包检测的防火墙。
你不应该只依赖于NetworkPolicy保证集群pod间的安全通信。诸如TLS(传输层安全性)与相互认证的方法使你能够加密流量并在微服务之间进行身份验证。
本文转自中文社区-Kubernetes集群安全通信