GKE网络策略和ExternalName

时间:2019-12-21 07:50:48

标签: google-kubernetes-engine kubernetes-networkpolicy

除了一个方向(例如yahho.com)外,我需要禁用命名空间中来自我的pod的所有出口流量 我的service.yaml看起来像:

kind: Service
apiVersion: v1
metadata:
 name: yahoo
 labels:
   output: allow
spec:
 type: ExternalName
 externalName: yahoo.com

我的网络策略文件阻止了所有输出流量:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: np-test
spec:
  podSelector: {}
  policyTypes:
  - Egress

我尝试将结构用于allow:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-yahoo
  namespace: np-test
spec:
  policyTypes:
  - Egress
  podSelector:
    matchLabels:
      name: test-ubuntu
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          namespace: np-test 
    - podSelector:
        matchLabels:
          output: allow
    ports:
    - protocol: TCP
      port: 443

您可以更正我的构造 podSelector 以通过流量吗?我在文档中找不到任何想法。

1 个答案:

答案 0 :(得分:0)

不幸的是,由于Calico的限制,GKE不支持“开箱即用”的基于DNS名称的出口过滤的网络策略:基于CIDR的过滤不灵活且容易出错,并且不适用于外部资源。 GitHub上有一个日期为2017年的Feature Request,用于在Kubernetes API中引入对新参数DNSSelector的支持。

就目前而言,第三方解决方案Cilium CNI插件提供了基于DNS的出口过滤。重要的是,它支持通配符。

简要步骤:

  1. 为当前项目启用GKE API(如果尚未完成)。
  2. 构建没有网络策略支持(带有kubenet)的标准3节点GKE集群。
  3. 连接到新创建的Kubernetes集群。
  4. 在GKE中创建cluster-admin-binding。
  5. 如有必要,为您的工作负载创建自定义名称空间。
  6. 如有必要,为外部资源创建无头服务。
  7. 运行Busybox容器以检查网络策略效果。
  8. 安装头盔。
  9. 使用头盔部署Cilium。
  10. 在应用网络策略之前,请检查外部资源的可用性。
  11. 创建和部署Cilium网络策略。
  12. 应用网络策略后检查外部资源的可用性。

在名称空间中创建第一个网络策略后,所有其他流量都将被拒绝。无需使用ExternalName类型的无头服务,但如果您更喜欢使用它,则通过这种服务进行的受限访问也将起作用。 kube-dns负责名称解析。网络策略授予对其的访问权限。

详细步骤:

  1. 为当前项目启用GKE API(如果尚未启用)。
$ gcloud services enable --project "mylab" container.googleapis.com
  1. 构建没有网络策略支持(带有kubenet)的标准3节点GKE集群。参数--username导致启用基本身份验证。
$ gcloud container --project "mylab" clusters create "standard-cluster-1" --username "admin" --zone "europe-west3-c"
  1. 连接到新创建的Kubernetes集群
$ gcloud auth list
$ gcloud auth login
$ gcloud container clusters get-credentials standard-cluster-1 --zone europe-west3-c --project mylab
$ kubectl config get-clusters
$ kubectl cluster-info`
  1. 在GKE中创建cluster-admin-binding。
$ kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user youraccount@google.com
  1. 为您的工作负载创建自定义名称空间np-test并将其标记为:
$ kubectl create namespace np-test
$ kubectl label namespace/np-test namespace=np-test
$ kubectl get namespace/np-test --show-labels`
  1. 根据需要为外部资源example.com创建无头服务。
$ vi example-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: example-service
  namespace: np-test
spec:
  type: ExternalName
  externalName: example.com

$ kubectl apply -f example-service.yaml
$ kubectl get services -n np-test
  1. 运行Busybox容器以检查网络策略效果。
$ vi busybox-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: busybox-pod
  namespace: np-test
  labels: 
    namespace: np-test
spec:
  containers:
  - image: radial/busyboxplus:curl
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox-container
  restartPolicy: Always

$ kubectl create -f ./busybox-pod.yaml
$ kubectl get pods -n np-test --show-labels
  1. 在CloudShell实例或您正在使用的工作站上安装Helm:
$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
$ chmod 700 get_helm.sh
$ ./get_helm.sh
$ helm version
  1. 使用头盔部署Cilium。
$ curl -LO https://github.com/cilium/cilium/archive/1.6.5.tar.gz
$ tar xzvf 1.6.5.tar.gz
$ cd cilium-1.6.5/install/kubernetes

生成所需的YAML文件:

$ helm template cilium \
  --namespace cilium \
  --set global.nodeinit.enabled=true \
  --set nodeinit.reconfigureKubelet=true \
  --set nodeinit.removeCbrBridge=true \
  --set global.cni.binPath=/home/kubernetes/bin \
  > cilium.yaml
$ kubectl create namespace cilium
$ kubectl get namespaces
$ kubectl create -f cilium.yaml

重新启动kube-system命名空间中的所有Pod,以便它们可以由Cilium管理:

$ kubectl delete pods -n kube-system $(kubectl get pods -n kube-system -o custom-columns=NAME:.metadata.name,HOSTNETWORK:.spec.hostNetwork --no-headers=true | grep '<none>' | awk '{ print $1 }') 
$ kubectl -n cilium get pods
  1. 在应用网络策略之前,先在Busybox窗格中检查外部资源的可用性。
$ kubectl exec -n np-test busybox-pod -- curl -kL google.com
$ kubectl exec -n np-test busybox-pod -- curl -kL yahoo.com
$ kubectl exec -n np-test busybox-pod -- curl -kL example.com
$ kubectl exec -n np-test busybox-pod -- curl -kL -H 'host: example.com' example-service
$ kubectl exec -n np-test busybox-pod -- nslookup example.com
$ kubectl exec -n np-test busybox-pod -- nslookup example-service

请注意,example-service被解析为与example.com相同的IP

  1. 创建和部署Cilium网络策略。现在该限制从Pod到Internet的访问,并只允许访问example.com
$ vi dns-policy.yaml

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "dns-policy"
  namespace: np-test
spec:
  endpointSelector:
    matchLabels: 
      namespace: np-test
  egress:
  - toFQDNs:
    - matchName: "example.com"  
  - toEndpoints:
    - matchLabels:
        "k8s:io.kubernetes.pod.namespace": kube-system
        "k8s:k8s-app": kube-dns
    toPorts:
    - ports:
      - port: "53"
        protocol: ANY
      rules:
        dns:
        - matchPattern: "*"

$ kubectl create -f dns-policy.yaml
$ kubectl get CiliumNetworkPolicy -n np-test
  1. 检查网络策略的效果。应用网络策略后, 从Busybox窗格中检查外部资源的可用性。
$ kubectl exec -n np-test busybox-pod -- ping -c 3 google.com
100% packet loss
$ kubectl exec -n np-test busybox-pod -- ping -c 3 yahoo.com
100% packet loss
$ kubectl exec -n np-test busybox-pod -- ping -c 3 example-service
0% packet loss
$ kubectl exec -n np-test busybox-pod -- ping -c 3 example.com
0% packet loss
$ kubectl exec -n np-test busybox-pod -- curl -kL google.com
Connection timed out
$ kubectl exec -n np-test busybox-pod -- curl -kL yahoo.com
Connection timed out
$ kubectl exec -n np-test busybox-pod -- curl -kL example.com
OK
$ kubectl exec -n np-test busybox-pod -- curl -kL -H 'host: example.com' example-service
OK

如您所见,Cilium网络策略允许直接或通过无头服务访问example.com,而限制访问其他站点。

此方法允许在GKE上获得基于DNS名称的出口过滤。

下面的链接提供了有关所描述解决方案的更多详细信息:

GKE: Network overview

Kubernetes Service: Headless Services

Kubernetes Service: Type ExternalName

Kubernetes Service: DNS entry

GKE: Creating a cluster network policy

Kubernetes: Network Policies

NetworkPolicy Egress with CIDRSelector and DNSSelector #50453

Kubernetes: Declare Network Policy

Open Source DNS-aware Kubernetes Network Policies Using Cilium

Installation of Cilium on Google GKE

Install Helm

Cilium: Locking down external access with DNS-based policies

相关问题