K8s 网络策略仅限制一个端点的出口

K8s network policy restrict egress for one endpoint only

我需要为我的 pod 创建一个 NetwrokPolicy 从网络方面需要 访问集群外的只有一个特定端点,只有这个端点。

端点如下所示。 https://140.224.232.236:8088

在将以下网络策略应用到 pod 之前(图像基于 alpine)和 运行 ping www.google.com 它按预期工作,

然而,当我应用网络策略时,我尝试 ping google.com 我得到了 ping: bad address 'www.google.com' 但是当我像

一样 ping 到 ip 时
  1. ping 140.224.232.236
  2. ping 140.224.232.236:8080

它卡住了,在我能够看到类似这样的东西之前

64 bytes from 140.224.232.236: seq=518 ttl=245 time=137.603 ms
64 bytes from 140.224.232.236: seq=519 ttl=245 time=137.411 ms
64 bytes from 140.224.232.236: seq=520 ttl=245 time=137.279 ms
64 bytes from 140.224.232.236: seq=521 ttl=245 time=137.138 ms
....

现在就卡在这个上面了,有什么想法吗?

ping 140.224.232.236
PING 140.224.232.236 (140.224.232.236): 56 data bytes

仅此而已,这是什么意思?

我做的是下面的

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
    name: test-network-policy
    namespace: dev
spec:
    podSelector:
      matchLabels:
        app.kubernetes.io/name: foo
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 140.224.232.236/32
    ports:
    - protocol: TCP
      port: 8088 
  1. 我已经在 pod 的同一个 ns 上应用了它。
  2. pod 选择器标签的名称取自我要应用网络策略并具有以下内容的 pod。 app.kubernetes.io/name: foo

您允许通过 TCP 而不是 ICMP 到端口 8088 的出口流量。 Ping 无法使用该应用。

如果要允许 non-TPC 或 UDP 协议使用 vanilla 的 Kubernetes API 作为网络策略,则需要省略端口定义

您还可以使用 Calico 的网络策略 API 来解决这个问题。

这为在集群中配置网络策略提供了更大的灵活性。

正如您定义的出口端口:

ports:
- protocol: TCP
  port: 8080

这意味着允许连接到 ip 140.224.232.236 TCP 端口 8080.

但是,ping(ICMP) 不知道该端口。每次Ping都会失败。

  1. ping 是一种网络实用程序,用于通过 Internet 协议 (IP) 测试远程主机的可达性。 ping 实用程序通过向远程主机发送一系列 Internet 控制消息协议 (ICMP) 回显请求数据包来做到这一点。

  2. 无法用ping命令探测特定端口因为ICMP属于层- 3 IP 层,不是第 4 层传输层(例如,TCP/UDP)。

  3. 为了 ping 远程主机的特定端口,您需要使用具有端口号概念的 第 4 层传输协议,其中许多 command-line 工具,例如:

您的网络政策是完美的。您不能使用 ping 来测试您的 TCP 端口,因为 ping 使用 ICMP 协议。

有很多方法可以在不更改网络策略的情况下测试您的配置。

例如:-

  1. 执行 pod 和 运行 这个 one liner。你应该得到 'Port is open'
$  </dev/tcp/140.224.232.236/8088 && echo Port is open || echo Port is closed
Port is open

/dev/tcp/host/port
    If host is a valid hostname or Internet address, and port is an integer port number
    or service name, bash attempts to open a TCP connection to the corresponding socket.
/dev/udp/host/port
    If host is a valid hostname or Internet address, and port is an integer port number
    or service name, bash attempts to open a UDP connection to the corresponding socket.
  1. 如果安装了 curl/wget,运行 cur/wget 通过执行 pod
curl -k https://140.224.232.236:8088
wget --no-check-certificate https://140.224.232.236:8088
  1. 如果网络工具 nc 存在,执行 pod 和 运行 这个命令,如果 '0' 是 returned 它工作。
nc 140.224.232.236 8088 &> /dev/null; echo $?
0

或以下命令应 return 'succeeded'

nc -zv 140.224.232.236 8088 
Connection to 140.224.232.236 8088 port [tcp/*] succeeded!