如何使用 NetworkPolicy 将出站流量列入白名单,以不阻止 Apache Ignite 启动?

如何使用 NetworkPolicy 将出站流量列入白名单,以不阻止 Apache Ignite 启动?

我有一些或多或少复杂的微服务架构,其中 Apache Ignite 用作无状态数据库/缓存。Ignite是其中Pod唯一的,并且该架构必须通过安全审核,如果我不对流量应用最严格的限制,它将无法通过。它必须限制 Ignite 本身不需要的所有可能的流量。PodNamespaceNetworkPolicyegress

一开始我以为:很好,Ignite 不会将任何流量推送到其他Pod(其中没有其他 pod Namespace),因此这可以轻松完成限制只有 Ignite 的所有egress流量!NamespacePod...

嗯,结果并不理想:即使我允许流量到 Ignite 文档中提到的所有端口,
任何规则都会导致启动失败,并显示以下内容egressIgniteSpiException无法检索 Ignite Pod IP 地址Caused by: java.net.ConnectException: Operation timed out (Connection timed out)

问题似乎是TcpDiscoveryKubernetsIpFinder,尤其是该方法getRegisteredAddresses(...)显然会在 内部进行一些出站流量,Namespace以便注册 Ignite 节点的 IP 地址。当然允许发现端口 47500,但这不会改变情况。Ignite 与其他Pods的功能Namespace无需应用规则即可运行,这意味着(对我而言)有关、 、中的a 的egress配置以及 Ignite 本身的 xml 配置等似乎是正确的。甚至限制来自其他命名空间的流量的规则也按预期工作,允许所需的流量。ClusterRoleClusterRoleBindingServiceNamespaceingress

以下是我采用的政策:

[工作正常,仅拦截不需要的流量]

## Denies all Ingress traffic to all Pods in the Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress-in-cache-ns
  namespace: cache-ns
spec:
  # selecting nothing here will deny all traffic between pods in the namespace
  podSelector:
    matchLabels: {}
  # traffic routes to be considered, here: incoming exclusively
  policyTypes:
    - Ingress
## Allows necessary ingress traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: netpol-cache-ns
  namespace: cache-ns
# defines the pod(s) that this policy is targeting
spec:
  policyTypes:
    - Ingress
  podSelector:
    matchLabels:
      app: ignite
  # <----incoming traffic----
  ingress:
    - from:
      - namespaceSelector:
          matchLabels:
            zone: somewhere-else
        podSelector:
          matchExpressions:
            - key: app
              operator: In
              values: [some-pod, another-pod]  # dummy names, these Pods don't matter at all
      ports:
        - port: 11211   # JDBC
          protocol: TCP
        - port: 47100   # SPI communication
          protocol: TCP
        - port: 47500   # SPI discovery (CRITICAL, most likely...)
          protocol: TCP
        - port: 10800   # SQL
          protocol: TCP
# ----outgoing traffic---->
# NONE AT ALL

应用这两个后,一切都正常了,但安全审计会说类似这样的话
的限制在哪里egress?如果此节点通过允许的路由被黑客入侵,因为使用这些路由的其中一个 Pod 之前被黑客入侵过,该怎么办?那么它可能会调用 C&C 服务器!此配置将不被允许,请强化您的架构!

[阻止所需/必要的流量]

通常拒绝所有流量...

## Denies all traffic to all Pods in the Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-traffic-in-cache-ns
  namespace: cache-ns
spec:
  # selecting nothing here will deny all traffic between pods in the namespace
  podSelector:
    matchLabels: {}
  # traffic routes to be considered, here: incoming exclusively
  policyTypes:
    - Ingress
    - Egress   # <------ THIS IS THE DIFFERENCE TO THE WORKING ONE ABOVE

...然后允许特定路线

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: netpol-cache-ns-egress
  namespace: cache-ns
# defines the pod(s) that this policy is targeting
spec:
  policyTypes:
    - Egress
  podSelector:
    matchLabels:
      app: ignite
  ----outgoing traffic---->
  egress:
    # [NOT SUFFICIENT]
    # allow egress to this namespace at specific ports
    - to:
      - namespaceSelector:
          matchLabels:
            zone: cache-zone
      ports:
        - protocol: TCP
          port: 10800
        - protocol: TCP
          port: 47100   # SPI communication
        - protocol: TCP
          port: 47500
    # [NOT SUFFICIENT]
    # allow dns resolution in general (no namespace or pod restriction)
    - ports:
      - protocol: TCP
        port: 53
      - protocol: UDP
        port: 53
    # [NOT SUFFICIENT]
    # allow egress to the kube-system (label is present!)
    - to:
      - namespaceSelector:
          matchLabels:
            zone: kube-system
    # [NOT SUFFICIENT]
    # allow egress in this namespace and for the ignite pod
    - to:
      - namespaceSelector:
          matchLabels:
            zone: cache-zone
        podSelector:
          matchLabels:
            app: ignite
    # [NOT SUFFICIENT]
    # allow traffic to the IP address of the ignite pod
    - to:
      - ipBlock:
          cidr: 172.21.70.49/32  # won't work well since those addresses are dynamic
      ports:
        - port: 11211   # JDBC
          protocol: TCP
        - port: 47100   # SPI communication
          protocol: TCP
        - port: 47500   # SPI discovery (CRITICAL, most likely...)
          protocol: TCP
        - port: 49112   # JMX
          protocol: TCP
        - port: 10800   # SQL
          protocol: TCP
        - port: 8080    # REST
          protocol: TCP
        - port: 10900   # thin clients
          protocol: TCP

使用的 Apache Ignite 版本是 2.10.0

现在向所有读者提出的问题是:

如何限制Egress内部的绝对最小值,Namespace以便 Ignite 启动并正常工作?仅仅拒绝Egress集群外部就足够了吗?

如果您需要更多yamls 来进行有根据的猜测或提示,请随时在评论中提出请求。
如果标记看起来不合适,请原谅,因为我kubernetes-networkpolicy在 stackoverflow 上找不到该标记。

更新:

nslookup -debug kubernetes.default.svc.cluster.local从 ignite pod 内部执行,没有任何策略限制egress显示

BusyBox v1.29.3 (2019-01-24 07:45:07 UTC) multi-call binary.

Usage: nslookup HOST [DNS_SERVER]

Query DNS about HOST

一旦NetworkPolicy应用限制Egress特定端口、pod 和命名空间的(任何),Ignite pod 将拒绝启动,并且不再进行查找kubernetes.default.svc.cluster.local

Egress允许访问 DNS(UDP 53 到 k8s-app: kube-dns)⇒ 仍然无法进行 IP 查找

相关内容