如何阻止从Kubernates中的其他命名空间到DB Pod&Service(DNS)的流量?

时间:2020-06-19 08:41:02

标签: postgresql kubernetes google-kubernetes-engine kubernetes-helm kubernetes-ingress

我在2个命名空间tenant1-namespace,tenant2-namespace中创建了2个租户(tenant1,tenant2)

每个租户都有db pod及其服务

如何隔离数据库容器/服务,即如何限制其名称空间中的容器/服务以访问其他租户数据库容器?

我已经为每个租户使用了服务帐户并应用了网络策略,以便隔离名称空间。

kubectl get svc --all-namespaces

tenant1-namespace   grafana-app            LoadBalancer   10.64.7.233    104.x.x.x   3000:31271/TCP   92m
tenant1-namespace   postgres-app           NodePort       10.64.2.80     <none>      5432:31679/TCP   92m
tenant2-namespace   grafana-app            LoadBalancer   10.64.14.38    35.x.x.x    3000:32226/TCP   92m
tenant2-namespace   postgres-app           NodePort       10.64.2.143    <none>      5432:31912/TCP   92m

所以

我想限制grafana-app仅在其命名空间中使用他的postgres db,而不在其他命名空间中使用。

但是问题是使用DNS限定服务名称(app-name.namespace-name.svc.cluster.local) 它允许彼此访问数据库Pod(名称空间tenant1-namespace中的grafana-app可以通过postgres-app.tenant2-namespace.svc.cluster.local

访问其他tenant2-namespace中的postgres db。

更新:网络政策

1)

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-from-other-namespaces
spec:
  podSelector:
    matchLabels:
  ingress:
  - from:
    - podSelector: {}

2)

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: web-allow-external
spec:
  podSelector:
    matchLabels:
      app: grafana-app
  ingress:
  - from: []

1 个答案:

答案 0 :(得分:1)

  • 您的NetworkPolicy对象正确,我用它们创建了一个示例,并将演示波纹管。

  • 如果您仍然可以使用FQDN访问其他名称空间上的服务,则您的NetworkPolicy可能未完全启用< / strong>在您的群集上。

运行gcloud container clusters describe "CLUSTER_NAME" --zone "ZONE"并查找以下两个片段:

  • 在描述的开头,它显示是否在主级别上启用了NetworkPolicy插件,它应该是这样的:
addonsConfig:
networkPolicyConfig: {}
  • 在说明的中间,您可以找到是否在节点上启用了NetworkPolicy 。它应该看起来像这样:
name: cluster-1
network: default
networkConfig:
  network: projects/myproject/global/networks/default
  subnetwork: projects/myproject/regions/us-central1/subnetworks/default
networkPolicy:
  enabled: true
  provider: CALICO

复制:

  • 我将创建一个简单的示例,我将gcr.io/google-samples/hello-app:1.0图像用于tenant1,将gcr.io/google-samples/hello-app:2.0用作tenant2,因此查看其连接位置更为简单,但我将使用您的环境名称:
$ kubectl create namespace tenant1
namespace/tenant1 created
$ kubectl create namespace tenant2
namespace/tenant2 created

$ kubectl run -n tenant1 grafana-app --generator=run-pod/v1 --image=gcr.io/google-samples/hello-app:1.0 
pod/grafana-app created
$ kubectl run -n tenant1 postgres-app --generator=run-pod/v1 --image=gcr.io/google-samples/hello-app:1.0 
pod/postgres-app created

$ kubectl run -n tenant2 grafana-app --generator=run-pod/v1 --image=gcr.io/google-samples/hello-app:2.0 
pod/grafana-app created
$ kubectl run -n tenant2 postgres-app --generator=run-pod/v1 --image=gcr.io/google-samples/hello-app:2.0 
pod/postgres-app created

$ kubectl expose pod -n tenant1 grafana-app --port=8080 --type=LoadBalancer
service/grafana-app exposed
$ kubectl expose pod -n tenant1 postgres-app --port=8080 --type=NodePort
service/postgres-app exposed

$ kubectl expose pod -n tenant2 grafana-app --port=8080 --type=LoadBalancer
service/grafana-app exposed
$ kubectl expose pod -n tenant2 postgres-app --port=8080 --type=NodePort
service/postgres-app exposed

$ kubectl get all -o wide -n tenant1
NAME               READY   STATUS    RESTARTS   AGE    IP          NODE                                         
pod/grafana-app    1/1     Running   0          100m   10.48.2.4   gke-cluster-114-default-pool-e5df7e35-ez7s
pod/postgres-app   1/1     Running   0          100m   10.48.0.6   gke-cluster-114-default-pool-e5df7e35-c68o

NAME                   TYPE           CLUSTER-IP   EXTERNAL-IP     PORT(S)          AGE   SELECTOR
service/grafana-app    LoadBalancer   10.1.23.39   34.72.118.149   8080:31604/TCP   77m   run=grafana-app
service/postgres-app   NodePort       10.1.20.92   <none>          8080:31033/TCP   77m   run=postgres-app

$ kubectl get all -o wide -n tenant2
NAME               READY   STATUS    RESTARTS   AGE    IP          NODE                                         
pod/grafana-app    1/1     Running   0          76m    10.48.4.8   gke-cluster-114-default-pool-e5df7e35-ol8n
pod/postgres-app   1/1     Running   0          100m   10.48.4.5   gke-cluster-114-default-pool-e5df7e35-ol8n

NAME                   TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)          AGE   SELECTOR
service/grafana-app    LoadBalancer   10.1.17.50    104.154.135.69   8080:30534/TCP   76m   run=grafana-app
service/postgres-app   NodePort       10.1.29.215   <none>           8080:31667/TCP   77m   run=postgres-app
  • 现在,让我们部署两个规则:第一个规则阻止来自命名空间外部的所有流量,第二个规则允许grafana-app从命名空间外部进入:
$ cat default-deny-other-ns.yaml 
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-from-other-namespaces
spec:
  podSelector:
    matchLabels:
  ingress:
  - from:
    - podSelector: {}

$ cat allow-grafana-ingress.yaml 
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: web-allow-external
spec:
  podSelector:
    matchLabels:
      run: grafana-app
  ingress:
  - from: []

默认情况下,吊舱是非隔离的;他们接受来自任何来源的流量。

通过具有选择它们的NetworkPolicy可以隔离它们。一旦在名称空间中选择了特定容器的任何NetworkPolicy,该容器将拒绝任何NetworkPolicy不允许的任何连接。 (名称空间中未被任何NetworkPolicy选择的其他Pod将继续接受所有流量。)

网络策略不冲突;它们是可加的。如果有任何一项或多项策略选择了某个广告连播,则该广告连播将被限制为这些政策的结合的入口/出口规则所允许的范围。因此,评估顺序不会影响策略结果。

  • 然后,我们将规则应用于两个名称空间,因为规则的范围是它分配给的名称空间:
$ kubectl apply -n tenant1 -f default-deny-other-ns.yaml 
networkpolicy.networking.k8s.io/deny-from-other-namespaces created
$ kubectl apply -n tenant2 -f default-deny-other-ns.yaml 
networkpolicy.networking.k8s.io/deny-from-other-namespaces created

$ kubectl apply -n tenant1 -f allow-grafana-ingress.yaml 
networkpolicy.networking.k8s.io/web-allow-external created
$ kubectl apply -n tenant2 -f allow-grafana-ingress.yaml 
networkpolicy.networking.k8s.io/web-allow-external created
  • 现在要进行最终测试,我将在grafana-app的{​​{1}}内部登录,并尝试在两个命名空间中均到达tenant1并检查输出:
postgres-app
  • 您可以看到DNS已解析,但是网络策略阻止了对后端Pod的访问。

如果在再次检查主服务器和节点上启用了NetworkPolicy之后,您仍然遇到相同的问题,请在评论中告诉我,我们可以进一步进行挖掘。