如何使用网络策略停止所有外部流量并仅允许命名空间内的 Pod 间网络调用?

Posted

技术标签:

【中文标题】如何使用网络策略停止所有外部流量并仅允许命名空间内的 Pod 间网络调用?【英文标题】:How to stop all external traffic and allow only inter pod network call within namespace using network policy? 【发布时间】:2019-01-18 13:36:31 【问题描述】:

我正在我的 kubernetes 集群中设置一个命名空间,以拒绝任何传出网络调用,如 http://company.com,但允许在我的命名空间内进行 pod 间通信,如 http://my-nginx 其中 my-nginx 是一个指向我的 nginx pod 的 kubernetes 服务.

如何使用网络策略来实现这一点。以下网络策略有助于阻止所有传出网络呼叫

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-all-egress
  namespace: sample
spec:
  policyTypes:
  - Egress
  podSelector: 

如何仅将 pod 间调用列入白名单?

【问题讨论】:

你已经阅读github.com/ahmetb/kubernetes-network-policy-recipes了吗? 感谢您的指出。这个特殊的例子适用于我github.com/ahmetb/kubernetes-network-policy-recipes/blob/master/…,但如果有一个端口为 53 的主机,它就不会停止调用,不是吗? 53 端口的主机是什么意思?服务在端口上运行。这将导致仅允许通过端口 53 进行的任何 Pod 间通信。 【参考方案1】:

我不确定您是否可以使用 Kubernetes NetworkPolicy 来做到这一点,但您可以通过启用 Istio 的 pod 来实现。

注意:首先确保您的集群上安装了 Istio。用于安装see。

参见Istio's documentation about Egress Traffic的报价。

默认情况下,启用 Istio 的服务无法访问外部 URL 集群的原因,因为 pod 使用 iptables 透明重定向 所有到 sidecar 代理的出站流量,它只处理 集群内目的地。

此外,您可以通过将 ServiceEntryVirtualService 添加到集群中来将集群外的域列入白名单,例如 Istio 文档中的 Configuring the external services。

希望对你有用。

【讨论】:

此引用在 1.1 中已更改。 this issue 提到【参考方案2】:

使用网络策略,您可以将命名空间中的所有 pod 列入白名单:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-egress-to-sample
  namespace: sample
spec:
  policyTypes:
  - Egress
  podSelector: 
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: sample

您可能已经知道,应用了至少一个网络策略的 pod 只能与应用到它们的任何网络策略允许的目标进行通信。

名字实际上并不重要。选择器(在这种情况下为命名空间选择器和 podSelector)只关心标签。标签是与资源关联的键值对。上面的示例假设名为 sample 的命名空间的标签为 name=sample

如果您想将名为http://my-nginx 的命名空间列入白名单,首先您需要为您的命名空间添加一个标签(如果还没有标签)。 name 是一个很好的 IMO 键,值可以是服务的名称,在这种特殊情况下为 http://my-nginx(不确定 :/ 是否可以成为标签的一部分)。然后,只需在您的网络策略中使用它,您就可以定位命名空间(用于入口或出口)

    - namespaceSelector:
        matchLabels:
          name: http://my-nginx

如果您想允许与名为my-nginx 的服务通信,则服务的名称并不重要。您需要使用 podSelector 选择目标 pod,这应该使用与服务用来知道哪些 pod 属于它的标签相同的标签来完成。检查您的服务以获取标签,并在网络策略中使用key: value。例如,对于 role=nginx 的 key=value 对,您应该使用

    - podSelector:
        matchLabels:
          role: nginx

【讨论】:

【参考方案3】:

这可以使用以下网络策略组合来完成:

# The same as yours
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-all-egress
  namespace: sample
spec:
  policyTypes:
  - Egress
  podSelector: 
---
# allows connections to all pods in your namespace from all pods in your namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-namespace-egress
  namespace: sample
spec:
  podSelector: 
  policyTypes:
  - Egress
  egress:
  - to:
    - podSelector:
        matchLabels: 
---
# allows connections from all pods in your namespace to all pods in your namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-namespace-internal
  namespace: sample
spec:
  podSelector: 
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels: 

假设您的网络策略实施实现了完整规范。

【讨论】:

这将实现原始请求,但会阻止对 Kubernetes DNS 服务(通常位于 kube-system 命名空间中)的访问。这将阻止来自“sample”命名空间中 pod 的所有通信。详情在这里:medium.com/@reuvenharrison/… @Mark true,但正如你所说,这不是所要求的,并非所有工作负载都需要访问 Kubernetes DNS - 可以通过进一步的策略轻松地允许访问 DNS 服务

以上是关于如何使用网络策略停止所有外部流量并仅允许命名空间内的 Pod 间网络调用?的主要内容,如果未能解决你的问题,请参考以下文章

ACL

k8s集群service外部流量策略如何优雅的处理Pod终止过程中的流量丢失问题?

k8s学习-CKA真题-网络策略NetworkPolicy

k8s学习-CKA真题-网络策略NetworkPolicy

精品k8s(kubernetes)的网络策略详networkpolicy实例精讲

using 用法拾忆