25.4. 使用 ovnkube-trace 追踪 Openflow

OVN 和 OVS 流量流可以在一个名为 ovnkube-trace 的单个实用程序中模拟。ovnkube-trace 实用程序运行 ovn-traceovs-appctl ofproto/traceovn-detrace,并在单个输出中关联这些信息。

您可以从专用容器执行 ovnkube-trace 二进制文件。对于 OpenShift Container Platform 4.7 后的版本,您还可以将该二进制文件复制到本地主机中,并从该主机执行它。

注意

Quay 镜像中的二进制文件目前不适用于 Dual IP 堆栈或 IPv6 环境。对于这些环境,您必须从源进行构建。

25.4.1. 在本地主机上安装 ovnkube-trace

ovnkube-trace 工具跟踪在 OVN-Kubernetes 驱动的 OpenShift Container Platform 集群中点之间的任意 UDP 或 TCP 流量的数据包模拟。将 ovnkube-trace 二进制文件复制到本地主机,使其可以针对集群运行。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。

流程

  1. 使用以下命令创建 pod 变量:

    $  POD=$(oc get pods -n openshift-ovn-kubernetes -l app=ovnkube-master -o name | head -1 | awk -F '/' '{print $NF}')
  2. 在本地主机上运行以下命令从 ovnkube-master pod 中复制二进制文件:

    $  oc cp -n openshift-ovn-kubernetes $POD:/usr/bin/ovnkube-trace ovnkube-trace
  3. 运行以下命令,使 ovnkube-trace 可执行:

    $  chmod +x ovnkube-trace
  4. 运行以下命令,显示 ovnkube-trace 可用的选项:

    $  ./ovnkube-trace -help

    预期输出

    I0111 15:05:27.973305  204872 ovs.go:90] Maximum command line arguments set to: 191102
    Usage of ./ovnkube-trace:
      -dst string
        	dest: destination pod name
      -dst-ip string
        	destination IP address (meant for tests to external targets)
      -dst-namespace string
        	k8s namespace of dest pod (default "default")
      -dst-port string
        	dst-port: destination port (default "80")
      -kubeconfig string
        	absolute path to the kubeconfig file
      -loglevel string
        	loglevel: klog level (default "0")
      -ovn-config-namespace string
        	namespace used by ovn-config itself
      -service string
        	service: destination service name
      -skip-detrace
        	skip ovn-detrace command
      -src string
        	src: source pod name
      -src-namespace string
        	k8s namespace of source pod (default "default")
      -tcp
        	use tcp transport protocol
      -udp
        	use udp transport protocol

    支持的命令行参数是熟悉的 Kubernetes 构造,如命名空间、Pod、服务,因此您不需要查找 MAC 地址、目标节点的 IP 地址或 ICMP 类型。

    日志级别为:

    • 0 (最小输出)
    • 2 (显示 trace 命令结果的详细输出)
    • 5 (调试输出)

25.4.2. 运行 ovnkube-trace

运行 ovn-trace 以模拟 OVN 逻辑网络内的数据包转发。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 您已在本地主机上安装了 ovnkube-trace

示例:测试 DNS 解析是否适用于部署的 pod

本例演示了如何从部署的 pod 测试 DNS 解析到集群中运行的核心 DNS pod。

流程

  1. 输入以下命令在 default 命名空间中启动 web 服务:

    $ oc run web --namespace=default --image=nginx --labels="app=web" --expose --port=80
  2. 列出在 openshift-dns 命名空间中运行的 pod:

    oc get pods -n openshift-dns

    输出示例

    NAME                  READY   STATUS    RESTARTS   AGE
    dns-default-467qw     2/2     Running   0          49m
    dns-default-6prvx     2/2     Running   0          53m
    dns-default-fkqr8     2/2     Running   0          53m
    dns-default-qv2rg     2/2     Running   0          49m
    dns-default-s29vr     2/2     Running   0          49m
    dns-default-vdsbn     2/2     Running   0          53m
    node-resolver-6thtt   1/1     Running   0          53m
    node-resolver-7ksdn   1/1     Running   0          49m
    node-resolver-8sthh   1/1     Running   0          53m
    node-resolver-c5ksw   1/1     Running   0          50m
    node-resolver-gbvdp   1/1     Running   0          53m
    node-resolver-sxhkd   1/1     Running   0          50m

  3. 运行以下 ovn-kube-trace 命令来验证 DNS 解析是否正常工作:

    $ ./ovnkube-trace \
      -src-namespace default \ 1
      -src web \ 2
      -dst-namespace openshift-dns \ 3
      -dst dns-default-467qw \ 4
      -udp -dst-port 53 \ 5
      -loglevel 0 6
    1
    源 pod 的命名空间
    2
    源 pod 名称
    3
    目标 pod 的命名空间
    4
    目标 pod 名称
    5
    使用 udp 传输协议。端口 53 是 DNS 服务使用的端口。
    6
    将日志级别设置为 1 (0 为 minimal,5 为 debug)

    预期输出

    I0116 10:19:35.601303   17900 ovs.go:90] Maximum command line arguments set to: 191102
    ovn-trace source pod to destination pod indicates success from web to dns-default-467qw
    ovn-trace destination pod to source pod indicates success from dns-default-467qw to web
    ovs-appctl ofproto/trace source pod to destination pod indicates success from web to dns-default-467qw
    ovs-appctl ofproto/trace destination pod to source pod indicates success from dns-default-467qw to web
    ovn-detrace source pod to destination pod indicates success from web to dns-default-467qw
    ovn-detrace destination pod to source pod indicates success from dns-default-467qw to web

    ouput 表示从部署的 pod 到 DNS 端口的成功,也表示它已成功返回其他方向。因此,如果我的 Web pod 想要从核心 DNS 进行 dns 解析,则 UDP 端口 53 上支持双向流量。

例如,如果 无法正常工作,并且您想要获取 ovn-traceovs-appctl ofproto/traceovn-detrace,更多调试类型信息会将日志级别增加到 2,然后再次运行命令,如下所示:

$ ./ovnkube-trace \
  -src-namespace default \
  -src web \
  -dst-namespace openshift-dns \
  -dst dns-default-467qw \
  -udp -dst-port 53 \
  -loglevel 2

这个日志级别的输出太大,无法在此处列出。在故障情况下,此命令的输出显示哪个流丢弃了该流量。例如,可以在不允许该流量的集群中配置 egress 或 ingress 网络策略。

示例:使用 debug 输出来验证配置的默认拒绝

本例演示了如何使用入口默认拒绝策略阻断流量的 debug 输出来识别。

流程

  1. 创建以下 YAML,以定义 deny-by-default 策略,以拒绝所有命名空间中的所有 pod 的入口流量。将 YAML 保存到 deny-by-default.yaml 文件中:

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: deny-by-default
      namespace: default
    spec:
      podSelector: {}
      ingress: []
  2. 输入以下命令应用策略:

    $ oc apply -f deny-by-default.yaml

    输出示例

    networkpolicy.networking.k8s.io/deny-by-default created

  3. 输入以下命令在 default 命名空间中启动 web 服务:

    $ oc run web --namespace=default --image=nginx --labels="app=web" --expose --port=80
  4. 运行以下命令来创建 prod 命名空间:

    $ oc create namespace prod
  5. 运行以下命令来标记 prod 命名空间:

    $ oc label namespace/prod purpose=production
  6. 运行以下命令,在 prod 命名空间中部署 alpine 镜像并启动 shell:

    $ oc run test-6459 --namespace=prod --rm -i -t --image=alpine -- sh
  7. 打开另一个终端会话。
  8. 在这个新终端会话中,运行 ovn-trace 以验证在命名空间 prod 中运行的源 pod test-6459 与在 default 命名空间中的目标 pod 之间的通信失败:

    $ ./ovnkube-trace \
     -src-namespace prod \
     -src test-6459 \
     -dst-namespace default \
     -dst web \
     -tcp -dst-port 80 \
     -loglevel 0

    预期输出

    I0116 14:20:47.380775   50822 ovs.go:90] Maximum command line arguments set to: 191102
    ovn-trace source pod to destination pod indicates failure from test-6459 to web

  9. 运行以下命令,将日志级别增加到 2 以公开失败的原因:

    $ ./ovnkube-trace \
     -src-namespace prod \
     -src test-6459 \
     -dst-namespace default \
     -dst web \
     -tcp -dst-port 80 \
     -loglevel 2

    预期输出

    ct_lb_mark /* default (use --ct to customize) */
    ------------------------------------------------
     3. ls_out_acl_hint (northd.c:6092): !ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0, priority 4, uuid 32d45ad4
        reg0[8] = 1;
        reg0[10] = 1;
        next;
     4. ls_out_acl (northd.c:6435): reg0[10] == 1 && (outport == @a16982411286042166782_ingressDefaultDeny), priority 2000, uuid f730a887 1
        ct_commit { ct_mark.blocked = 1; };

    1
    因为默认的 deny 策略被到位,所以入口流量会被阻止
  10. 创建一个策略,允许来自特定命名空间中所有 pod 的流量,其标签为 purpose=production。将 YAML 保存到 web-allow-prod.yaml 文件中:

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: web-allow-prod
      namespace: default
    spec:
      podSelector:
        matchLabels:
          app: web
      policyTypes:
      - Ingress
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              purpose: production
  11. 输入以下命令应用策略:

    $ oc apply -f web-allow-prod.yaml
  12. 输入以下命令运行 ovnkube-trace 来验证现在允许的流量:

    $ ./ovnkube-trace \
     -src-namespace prod \
     -src test-6459 \
     -dst-namespace default \
     -dst web \
     -tcp -dst-port 80 \
     -loglevel 0

    预期输出

    I0116 14:25:44.055207   51695 ovs.go:90] Maximum command line arguments set to: 191102
    ovn-trace source pod to destination pod indicates success from test-6459 to web
    ovn-trace destination pod to source pod indicates success from web to test-6459
    ovs-appctl ofproto/trace source pod to destination pod indicates success from test-6459 to web
    ovs-appctl ofproto/trace destination pod to source pod indicates success from web to test-6459
    ovn-detrace source pod to destination pod indicates success from test-6459 to web
    ovn-detrace destination pod to source pod indicates success from web to test-6459

  13. 在 open shell 中运行以下命令:

     wget -qO- --timeout=2 http://web.default

    预期输出

    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>

25.4.3. 其他资源