1

我需要禁用命名空间中来自我的 pod 的所有出口流量,除了一个方向,例如 yahho.com 我的 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

我尝试使用允许的结构:

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以通过交通吗?我在文档中找不到任何想法。

4

1 回答 1

0

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

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

简要步骤:

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

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

详细步骤:

  1. 为当前项目启用 GKE API(如果尚未启用)。
$ gcloud services enable --project "mylab" container.googleapis.com
  1. 构建一个没有网络策略支持的标准 3 节点 GKE 集群(带有kubenet)。一个参数--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 中创建集群管理员绑定。
$ 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. 使用 Helm 部署 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

重新启动命名空间中的所有 pod,kube-system以便它们可以由 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 pod 中检查外部资源的可用性。
$ 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被解析为相同的IPexample.com

  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 pod 中检查外部资源的可用性。
$ 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:网络概览

Kubernetes 服务:无头服务

Kubernetes 服务:输入 ExternalName

Kubernetes 服务:DNS 入口

GKE:创建集群网络策略

Kubernetes:网络策略

带有 CIDRSelector 和 DNSSelector 的 NetworkPolicy Egress #50453

Kubernetes:声明网络策略

使用 Cilium 的开源 DNS 感知 Kubernetes 网络策略

在 Google GKE 上安装 Cilium

安装 Helm

Cilium:使用基于 DNS 的策略锁定外部访问

于 2020-01-10T14:05:56.293 回答