为什么我的 K8s 网络策略在应该通过匹配标签来拒绝访问时拒绝访问

问题描述 投票:0回答:1

我正在尝试实施一项出口网络策略,仅允许出口到未按预期工作的特定 Pod,我不确定如何在保持最低权限的同时解决此问题。

我有一个标签为

networking/client: auth-api-postgresdb
的 PostgreSQL 数据库(服务、statefulset、pod),并且我有一个标签为
networking/client: auth-api-postgresdb-migrations
的迁移作业,这两个作业都有网络策略。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: auth-api-postgres
spec:
  policyTypes:
    - Ingress
  podSelector:
    matchLabels:
      networking/client: auth-api-postgresdb
  ingress:
    - ports:
        - protocol: TCP
          port: 5432
      from:
        - podSelector:
            matchLabels:
              networking/client: auth-api-postgresdb-migrations

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: auth-api-postgresdb-migrations
spec:
  policyTypes:
    - Egress
  podSelector:
    matchLabels:
      networking/client: auth-api-postgresdb-migrations
  egress:
    - ports:
        - protocol: TCP
          port: 5432
      to:
        - podSelector:
            matchLabels:
              networking/client: auth-api-postgresdb

数据库策略按预期工作,但迁移出口不是,在当前状态下,它不允许 5432 上的出站流量到数据库,但是,如果我将 podSelector 更新为

{}
保持端口限制,那么它可以到达数据库。

看来出口在连接到数据库之前必须尝试访问某些其他服务或 Pod,但我无法弄清楚它是什么。这是运行作业之前在命名空间中运行的所有内容,无论是否带有标签过滤器。我还使用 PostgreSQL 客户端测试了 Debain 映像,这也有同样的问题,但我确实发现我可以直接连接到 pod,但仍然无法连接到服务。

$>k get all -n test -l networking/client=auth-api-postgresdb
NAME                                   READY   STATUS    RESTARTS   AGE
pod/auth-api-postgresdb-postgresql-0   2/2     Running   0          3m42s

NAME                                             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/auth-api-postgresdb-postgresql           ClusterIP   172.20.130.101   <none>        5432/TCP   3m42s
service/auth-api-postgresdb-postgresql-hl        ClusterIP   None             <none>        5432/TCP   3m42s
service/auth-api-postgresdb-postgresql-metrics   ClusterIP   172.20.134.229   <none>        9187/TCP   3m42s

NAME                                              READY   AGE
statefulset.apps/auth-api-postgresdb-postgresql   1/1     3m42s
$>k get all -n test
NAME                                   READY   STATUS    RESTARTS   AGE
pod/auth-api-postgresdb-postgresql-0   2/2     Running   0          4m13s

NAME                                             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/auth-api-postgresdb-postgresql           ClusterIP   172.20.130.101   <none>        5432/TCP   4m13s
service/auth-api-postgresdb-postgresql-hl        ClusterIP   None             <none>        5432/TCP   4m13s
service/auth-api-postgresdb-postgresql-metrics   ClusterIP   172.20.134.229   <none>        9187/TCP   4m13s

NAME                                              READY   AGE
statefulset.apps/auth-api-postgresdb-postgresql   1/1     4m13s

错误看起来像这样:

...
Opening connection to database 'identity' on server 'tcp://auth-api-postgresdb-postgresql:5432'
...
Npgsql.NpgsqlException (0x80004005): Failed to connect to 172.20.130.101:5432
...

为了获得更多证据,命名空间具有默认拒绝策略、核心 DNS 策略和 Istio 代理策略,尽管我禁用了 Istio 注入来排除这种情况。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-access
spec:
  podSelector:
    matchLabels: {}
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-istio-proxy-access
spec:
  podSelector:
    matchLabels: {}
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: istio-system
          podSelector:
            matchLabels:
              app: istiod
      ports:
        - protocol: TCP
          port: 15012
kubernetes kubernetes-networkpolicy
1个回答
0
投票

使用服务选择器验证

auth-api-postgresdb-postgresql
服务是否与 PostgreSQL pod 标签准确匹配。服务选择器 (
auth-api-postgresdb
) 需要匹配网络/客户端。

检查您的迁移 Pod 是否能够使用 DNS 访问来解析 DNS。尽管

allow-dns-access policy
看起来是有序的,但请确保将其应用于需要 DNS 访问的所有 pod。

标签匹配: 验证您的出口策略是否正确引用

networking/client: auth-api-postgresdb
并且迁移作业 Pod 具有正确的标签
networking/client: auth-api-postgresdb-migrations

测试连接:识别并消除错误,以检查与服务 IP (

172.20.130.101
) 和服务名称 (
auth-api-postgresdb-postgresql
) 的连接。您可以运行来管理它:

kubectl exec -it <debug-pod-name> -- curl 172.20.130.101:5432
kubectl exec -it <debug-pod-name> -- curl auth-api-postgresdb-postgresql:5432

暂时清空选择器: 如果您将出口策略中的 Pod 选择器更改为

{}
并授予访问权限,迁移作业可能会尝试访问其他 Pod 或服务。逐步重新引入限制,看看哪些内容被阻止。

出口策略示例

确保您的出口政策如下所示:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: auth-api-postgresdb-migrations
spec:
  podSelector:
    matchLabels:
      networking/client: auth-api-postgresdb-migrations
  policyTypes:
    - Egress
  egress:
    - to:
        - podSelector:
            matchLabels:
              networking/client: auth-api-postgresdb
      ports:
        - protocol: TCP
          port: 5432

请参阅官方 Kubernetes 文档和 网络策略配置文档以获取更多信息

© www.soinside.com 2019 - 2024. All rights reserved.