除了一个方向(例如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 以通过流量吗?我在文档中找不到任何想法。
答案 0 :(得分:0)
不幸的是,由于Calico的限制,GKE不支持“开箱即用”的基于DNS名称的出口过滤的网络策略:基于CIDR的过滤不灵活且容易出错,并且不适用于外部资源。 GitHub上有一个日期为2017年的Feature Request,用于在Kubernetes API中引入对新参数DNSSelector
的支持。
就目前而言,第三方解决方案Cilium CNI插件提供了基于DNS的出口过滤。重要的是,它支持通配符。
简要步骤:
kubenet
)的标准3节点GKE集群。在名称空间中创建第一个网络策略后,所有其他流量都将被拒绝。无需使用ExternalName
类型的无头服务,但如果您更喜欢使用它,则通过这种服务进行的受限访问也将起作用。 kube-dns
负责名称解析。网络策略授予对其的访问权限。
详细步骤:
$ gcloud services enable --project "mylab" container.googleapis.com
kubenet
)的标准3节点GKE集群。参数--username
导致启用基本身份验证。 $ gcloud container --project "mylab" clusters create "standard-cluster-1" --username "admin" --zone "europe-west3-c"
$ 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`
$ kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user youraccount@google.com
np-test
并将其标记为:$ kubectl create namespace np-test
$ kubectl label namespace/np-test namespace=np-test
$ kubectl get namespace/np-test --show-labels`
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
$ 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
$ 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
$ 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
$ 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
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
$ 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名称的出口过滤。
下面的链接提供了有关所描述解决方案的更多详细信息:
Kubernetes Service: Headless Services
Kubernetes Service: Type ExternalName
GKE: Creating a cluster network policy
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
Cilium: Locking down external access with DNS-based policies