【问题标题】:Kubernetes NetworkPolicy allow loadbalancerKubernetes NetworkPolicy 允许负载均衡器
【发布时间】:2017-11-16 10:43:29
【问题描述】:

我有一个在 Google Kubernetes Engine (GKE) 上运行并启用了网络策略支持的 Kubernetes 集群。 我为它创建了一个 nginx 部署和负载均衡器:

kubectl run nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=LoadBalancer

然后我创建了这个网络策略来确保集群中的其他 pod 将无法再连接到它:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-nginx
spec:
  podSelector:
    matchLabels:
      run: nginx
  ingress:
  - from:
      - namespaceSelector:
          matchLabels:
            name: kube-system
    ports:
    - protocol: TCP
      port: 80

现在我集群中的其他 pod 无法访问它(如预期的那样):

kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget --spider --timeout=1 nginx
Connecting to nginx (10.63.254.50:80)
wget: download timed out

然而,令我惊讶的是,使用我的外部浏览器我也无法通过负载平衡器连接到它:

open http://$(kubectl get svc nginx --output=jsonpath={.status.loadBalancer.ingress[0].ip})

如果我删除该策略,它会再次开始工作。

所以,我的问题是:如何阻止其他 pod 访问 nginx,但保持通过负载均衡器的访问处于打开状态?

【问题讨论】:

    标签: kubernetes google-kubernetes-engine


    【解决方案1】:

    我在Network Policy recipes repository 中谈到了这个。

    在拒绝本地流量时允许外部负载平衡器”不是一个有意义的用例,因此不可能使用网络策略。

    要使 Service type=LoadBalancer 和 Ingress 资源正常工作,您必须允许所有流量流向这些资源选择的 pod。

    如果您真的需要,可以使用 from.ipBlock.cidrfrom.ipBlock.cidr.except 资源来允许来自 0.0.0.0/0(所有 IPv4)的流量,然后排除 10.0.0.0/8(或 GKE 使用的任何私有 IP 范围)。

    【讨论】:

      【解决方案2】:

      我最近不得不做类似的事情。我需要一个不允许来自其他命名空间的 pod 与 prod 通信的策略,但 确实 允许 LoadBalancer 服务访问 prod 中的 pod。以下是有效的方法(基于 Ahmet 的帖子):

      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: isolate-prod
        namespace: prod
      spec:
        podSelector: {}
        ingress:
        - from:
          - podSelector: {}
        - from:
          - ipBlock:
              cidr: '0.0.0.0/0'
              except: ['10.0.0.0/8']
      

      【讨论】:

      • 谢谢!这正是我所需要的。我有一个包含 4 个命名空间的集群,其中 1 个是完全私有的,另外 3 个使用 Ingress 来允许特定的 HTTPS 流量。如果没有 ipBlock 异常,隔离规则会使 Ingress 无法访问任何 pod。
      【解决方案3】:

      我想分享基于 @ahmetb-google 和 @tammer-saleh 出色答案的解决方案

      情况: 1 个集群,4 个命名空间,3 个命名空间的公共 HTTPS 终止 Ingress,允许特定流量入站并适当路由。

      目标:阻止所有跨命名空间流量,只允许通过Ingress 进入的公共流量。

      问题:在部署“拒绝来自其他命名空间”规则时,它还拒绝了来自我的 Ingress 的流量,因此无法从外部访问 pod。

      解决方案:

      我创建了一个附加策略,仅允许端口 80 流量以标签为 role=web 的 pod 为目标。它使用 allow/except 技巧来阻止来自其他命名空间的流量,但允许来自公共入口。

      kind: NetworkPolicy
      apiVersion: networking.k8s.io/v1
      metadata:
        name: allow-http-from-ingress
      spec:
        podSelector:
          matchLabels:
            role: web
        ingress:
          - from:
            - ipBlock:
                cidr: '0.0.0.0/0'
                except: ['10.0.0.0/8']
            ports:
              - port: 80
      

      部署后,流量仍然从公众通过Ingress 流向网络服务 pod。所有命名空间间的流量都被阻止,包括 HTTP。

      例如,当您将命名空间用于不同的部署阶段(生产、测试​​、边缘等)并且您拥有不希望意外跨阶段访问的私有 HTTP API 时,这是一个有用的设置。

      【讨论】:

        猜你喜欢
        • 2019-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-07
        • 1970-01-01
        • 1970-01-01
        • 2022-10-23
        相关资源
        最近更新 更多