【问题标题】:How to block traffic to db pod & service (DNS) from other namespaces in kubernates?如何阻止来自 kubernetes 中其他命名空间的 db pod 和服务(DNS)的流量?
【发布时间】:2020-10-09 11:39:43
【问题描述】:

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

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

如何隔离 db pod/service,即如何限制 pod/service 从他的命名空间访问其他租户的 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 数据库,而不是在其他命名空间中。

但问题是使用 DNS 限定的服务名称 (app-name.namespace-name.svc.cluster.local) 它允许访问彼此的db 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: []

【问题讨论】:

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


    【解决方案1】:
    • 您的 NetworkPolicy 对象是正确的,我用它们创建了一个示例,并将在下面演示。

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

    运行gcloud container clusters describe "CLUSTER_NAME" --zone "ZONE" 并查找这两个sn-ps:

    • 在描述的开头,如果 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 图像作为租户 1,gcr.io/google-samples/hello-app:2.0 用于租户 2,这样更容易查看它的连接位置,但我将使用您的环境名称:
    $ 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: []
    

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

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

    网络政策不冲突;它们是添加剂。如果任何一个或多个策略选择了一个 pod,则该 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
    
    • 现在进行最终测试,我将在tenant1 中登录grafana-app 并尝试在两个命名空间中访问postgres-app 并检查输出:
    $ kubectl exec -n tenant1 -it grafana-app -- /bin/sh
    / ### POSTGRES SAME NAMESPACE ###
    / # wget -O- postgres-app:8080
    Connecting to postgres-app:8080 (10.1.20.92:8080)
    Hello, world!
    Version: 1.0.0
    Hostname: postgres-app
    
    / ### GRAFANA OTHER NAMESPACE ###
    / # wget -O- --timeout=1 http://grafana-app.tenant2.svc.cluster.local:8080
    Connecting to grafana-app.tenant2.svc.cluster.local:8080 (10.1.17.50:8080)
    Hello, world!
    Version: 2.0.0
    Hostname: grafana-app
    
    / ### POSTGRES OTHER NAMESPACE ###
    / # wget -O- --timeout=1 http://postgres-app.tenant2.svc.cluster.local:8080
    Connecting to postgres-app.tenant2.svc.cluster.local:8080 (10.1.29.215:8080)
    wget: download timed out
    
    • 您可以看到 DNS 已解析,但 networkpolicy 阻止了对后端 pod 的访问。

    如果在 Master 和 Nodes 上再次检查 NetworkPolicy 启用后,您仍然遇到同样的问题,请在 cmets 中告诉我,我们可以进一步挖掘。

    【讨论】:

    • 谢谢我使用 gcr.io/google-samples/ images 尝试了你的回答。但就我而言,当我尝试时,两个 grafana 应用程序公共 ip 都被网络策略阻止。我无法在浏览器中加载这两个 grafana 应用程序。
    • 检查 grafana 应用是否需要任何其他连接。我会尝试用 grafana 图像重现,看看我是否得到相同的行为。
    猜你喜欢
    • 1970-01-01
    • 2016-11-10
    • 2021-09-30
    • 2022-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多