Kubernetes NetworkPolicy允许loadbalancer

时间:2017-11-16 10:43:29

标签: kubernetes google-kubernetes-engine

我在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,但是通过负载均衡器保持访问权限?

3 个答案:

答案 0 :(得分:2)

我在网络政策食谱库中讨论了这个问题:https://github.com/ahmetb/kubernetes-networkpolicy-tutorial/blob/a18f9e6e/08-allow-external-traffic.md

在DENYING本地流量时允许EXTERNAL负载均衡器”不是一个有意义的用例,因此无法使用网络策略。

要使Service type = LoadBalancer和Ingress资源有效,您必须允许所有流量通过这些资源选择的广告连接。

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

答案 1 :(得分:1)

我最近不得不做类似的事情。我需要一个不允许其他名称空间的Pod与产品对话的策略,但 did 允许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']

答案 2 :(得分:0)

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

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

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

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

解决方案:

我创建了一个额外的策略,只允许以 role=web 标签为目标的 Pod 的端口 80 流量。它使用允许/除外技巧仍然阻止来自其他命名空间的流量,但允许来自公共入口的流量。

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 时,这是一个有用的设置。