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有两个主要部分:
如下是一个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是否安全
NetworkPolicy限制Pod到Pod的网络,这是保护集群流量和应用程序的一部分。它们不是进行深度包检测的防火墙。
你不应该只依赖于NetworkPolicy保证集群pod间的安全通信。诸如TLS(传输层安全性)与相互认证的方法使你能够加密流量并在微服务之间进行身份验证。
本文译者:平凡, 微信公众号“容器时代”: CaaSOne