18

Kubernetes Egress 网络策略指南-K8sMeetup 中国社区

 3 years ago
source link: https://blog.51cto.com/14133165/2512115
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Kubernetes Egress 网络策略指南

作者:Viswajith Venugopal

翻译:Bach才云

校对:bot才云)、星空下的文仔才云

Kubernetes 中的网络策略用于指定 Pod 组之间以及其与外部网络端点之间的通信,它就像是 Kubernetes 的防火墙。与大多数 Kubernetes 对象一样,网络策略非常灵活,功能也很强大。如果了解应用程序中服务的确切通信模式,我们就可以通过网络策略将通信限制在我们想要范围之内。

Ingress 与 Egress

网络策略可用于指定 Pod 的入口(Ingress)**流量出口(Egress)流量**,其规则如下:

  • 如果允许集群外部网络端点到 Pod 的通讯,那么该端点可以访问 Pod。

  • 如果允许 Pod 到集群外部网络端点的通讯,那么 Pod 也可以访问该端点。

  • 如果 Pod(A)到 Pod(B)的流量被允许,那么流量可以通过 A 的出口以及 B 的入口。注意这是单向的,流量从 B 到 A,那么只能从 B 的出口到 A 的入口。

设置 Ingress

在完成入**口网络策略的设置并成功运行后,我们再设置出口网络策略**。这样做的原因有两个:首先,一次执行两项操作比较困难,而且我们很难知道是由于入口还是出口配置导致的网络连接失败;其次,出口网络策略通常更难以实施。限制出口可能会引发各种错误,从而影响应用程序运行。

虽然确定网络端点到 Pod 的通讯非常简单,但要确定 Pod 到网络端点的连接方式会比较复杂。之所以出现这一问题,这是因为:

  • 作为常规功能的一部分,Deployment 通常会查询一堆外部服务,根据它们在访问这些服务时处理超时的方式,功能可能会受到一些细微而又难以观察的影响。

  • Deployment 需要能够与 DNS 服务器通信,以便和其他任何服务器通信,除非这些服务器直接通过 IP 与服务联系。

对 Pod Egress 进行隔离

每个网络策略都有一个 podSelector 字段,该字段会选择一组(0 个或多个)Pod。当网络策略选择了一个 Pod 时,就称该网络策略适用于该 Pod。

此外,每个网络策略都可以根据 policyTypes 字段的值应用于入口和出口。如果 YAML 中未指定此字段,它的值会基于策略中的入口、出口规则默认设置,但默认设置并不靠谱,我们最好进行明确的设置。

一般情况下,如果没有任何出口网络策略适用于 Pod,那么它就是非隔离的出口。这里要注意,隔离是针对入口和出口独立评估的。一个 Pod 的入口和出口可以都隔离,也可以都不隔离,甚至进行单个隔离。如果一个 Pod 的出口没有进行隔离,那么所有的流量都可以从这个 Pod 中出来。

当一个出口网络策略适用于某个 Pod 时,该 Pod 的出口就会被隔离。对于隔离的 Pod,只有在网络策略允许的情况下,才允许网络出口,也就是网络策略白名单。

设置出口网络策略的第一步是对 Pod 进行出口隔离。我们最好先应用“默认拒绝所有”的策略,将所有 Pod 的出口都隔离了。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all-egress
spec:
  podSelector: {}
  egress:
  - to:
    ports:
    - protocol: TCP
      port: 53
    - protocol: UDP
      port: 53
  policyTypes:
  - Egress

不过要注意,默认情况下这个策略允许流量连接到任意 IP 上的 53 端口,以方便 DNS 查找。因此,尽管它可以防止出口出现问题,但不能防止数据泄露,因为***者可以将数据发送到 53 端口。

如果想知道 Pod 使用的是哪些 DNS 服务器,我们可以通过缩小访问范围进行确定。例如,要将 DNS 范围缩小到仅提供 kube-dns 服务,可以执行以下操作:

标记 kube-system 命名空间:

kubectl label namespace kube-system networking/namespace=kube-system

应用以下网络策略:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all-egress
spec:
  podSelector: {}
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          networking/namespace: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: TCP
      port: 53
    - protocol: UDP
      port: 53
  policyTypes:
  - Egress

重要提示:由于网络策略是带命名空间资源,因此每个命名空间都需要创建此策略。我们可以运行以下命令:

kubectl -n <namespace> create -f <filename> 

另外,最好不要将其应用于 kube-system 命名空间,因为它可能会影响集群功能。

明确 Pod 到互联网的出口

在每个命名空间中都采用了 default-deny-all-egress (默认拒绝所有出口)策略后,Pod 将无法连接到互联网,但是在大多数的应用程序中,会有一些 Pod 需要连接到互联网。对此,有一种设置方法:为允许连接互联网的 Pod 指定标签,并创建一个针对这些标签的网络策略。例如,以下网络策略允许具有 networking/allow-internet-egress=true 标签的 Pod 发送流量至所有网络端点(包括集群外部的端点)。另外,还是要注意,我们必须为每个命名空间创建该策略:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: internet-egress
spec:
  podSelector:
    matchLabels:
      networking/allow-internet-egress: "true"
  egress:
  - {}
  policyTypes:
  - Egress

这个策略比默认设置具有更高的安全性。不过对于更严格的策略集,理想情况下最好指定更细粒度的 CIDR 块,并明确列出允许的端口和协议。

明确 Pod 间的点对点通信

如果将 Pod 隔离,然后明确 Pod 到 Pod 之间的通信之后,在应用正常工作时,我们会发现,在使用 default-deny-all-egress 策略后,所有的通信都被限制了。对此,我们在入口方向上将每个连接放入白名单后,还需要把出口方向上的连接也放入白名单。无论是遵循上面的建议,允许所有名称空间内部通信,还是将各个 Pod 之间的连接列入白名单,或者采用自定义的方法,对于构建的每个入口策略,都需要制定相应的出口策略。

补充出口网络策略

对于从一组 Pod 到另一组 Pod 之间进行通信的入口策略,构建对应的出口策略非常简单。首先,将 policyTypes 字段更改为仅包含 Egress 的数组,将 spec.podSelector 放在 spec.egress.to.podSelector 中,删除 ingress.from,并将从中提取的 ingress.from.podSelector 放到新的出口策略 spec.podSelector 中。这样就完成了命名空间内的一个入口策略。

至于跨命名空间的策略,如果已经用 network/namespace: 用标签标记了每个命名空间:

kubectl label namespace <name> networking/namespace=<name>

那么,我们需要在入口策略中选择 ingress.from.namespaceselector 的命名空间作为出口策略的 metadata.namespace,并将在入口策略的 metadata.namespace 中指定的命名空间,放到出口策略的 egress.to.namespaceSelector 字段中。

这是一个例子:

Kubernetes Egress 网络策略指南

最后,上述建议仅仅提供了一个学习网络策略的起点,实际上它会复杂得多。如果想更详细地对它们进行了解,最好多多查看 Kubernetes 教程以及更多的网络策略配置。

原文请点击:https://mp.weixin.qq.com/s/0FIe_5ojwF0NC8FviKFPCQ


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK