网络


Red Hat build of MicroShift 4.15

配置和管理集群网络

Red Hat OpenShift Documentation Team

摘要

本文档提供有关配置和管理 MicroShift 集群网络的说明,包括 DNS、ingress 和 Pod 网络。

第 1 章 关于 OVN-Kubernetes 网络插件

OVN-Kubernetes Container Network Interface (CNI)插件是 MicroShift 集群的默认网络解决方案。OVN-Kubernetes 是 pod 和基于 Open Virtual Network (OVN) 的服务的虚拟网络。

  • 默认网络配置和连接会在 MicroShift 中在安装过程中自动应用 microshift-networking RPM。
  • 使用 OVN-Kubernetes 网络插件的集群也会在节点上运行 Open vSwitch (OVS)。
  • OVN-K 在节点上配置 OVS,以实施声明的网络配置。
  • 默认情况下,主机物理接口不绑定到 OVN-K 网关网桥 br-ex。您可以使用主机上的标准工具来管理默认网关,如 Network Manager CLI (nmcli)。
  • MicroShift 不支持更改 CNI。

使用配置文件或自定义脚本,您可以配置以下网络设置:

  • 您可以使用子网 CIDR 范围为 pod 分配 IP 地址。
  • 您可以更改最大传输单元(MTU)值。
  • 您可以配置防火墙入口和出口。
  • 您可以在 MicroShift 集群中定义网络策略,包括入口和出口规则。

1.1. MicroShift 网络自定义列表

下表总结了作为默认值、配置支持或未通过 MicroShift 服务提供的网络功能和功能的状态:

表 1.1. MicroShift 网络功能和自定义状态
网络功能可用性支持的自定义

公告地址

[1]

Kubernetes 网络策略

Kubernetes 网络策略日志

不可用

N/A

负载平衡

多播 DNS

[2]

网络代理

[3]

CRI-O

网络性能

MTU 配置

出口 IP

不可用

N/A

出口防火墙

不可用

N/A

出口路由器

不可用

N/A

防火墙

没有 [4]

硬件卸载

不可用

N/A

混合网络

不可用

N/A

集群内通信的 IPsec 加密

不可用

N/A

IPv6

不可用 [5]

N/A

  1. 如果未设置,则默认值会在服务网络后设置为下一个即时子网。例如,当服务网络为 10.43.0.0/16 时,广告地址 被设置为 10.44.0.0/32
  2. 多播 DNS 协议 (mDNS) 允许使用在 5353/UDP 端口上公开的多播进行名称解析和服务发现。
  3. MicroShift 中没有内置透明代理的出口流量。出口必须手动配置。
  4. RHEL for Edge 支持设置 firewalld 服务。
  5. 任何配置中都不提供 IPv6。

1.1.1. 默认设置

如果没有创建 config.yaml 文件,则使用默认值。以下示例显示了默认配置设置。

  • 要查看默认值,请运行以下命令:

    $ microshift show-config

    YAML 格式的默认值示例

    dns:
      baseDomain: microshift.example.com 1
    network:
      clusterNetwork:
        - 10.42.0.0/16 2
      serviceNetwork:
        - 10.43.0.0/16 3
      serviceNodePortRange: 30000-32767 4
    node:
      hostnameOverride: "" 5
      nodeIP: "" 6
    apiServer:
      advertiseAddress: 10.44.0.0/32 7
      subjectAltNames: [] 8
    debugging:
      logLevel: "Normal" 9

    1
    集群的基域。所有管理的 DNS 记录都将是这个基础的子域。
    2
    从中分配 Pod IP 地址的 IP 地址块。
    3
    Kubernetes 服务的虚拟 IP 地址块。
    4
    端口范围允许用于 NodePort 类型的 Kubernetes 服务。
    5
    节点的名称。默认值为 hostname。
    6
    节点的 IP 地址。默认值是默认路由的 IP 地址。
    7
    指定 API 服务器公告给集群成员的 IP 地址的字符串。默认值根据服务网络的地址计算。
    8
    API 服务器证书的主题备用名称。
    9
    日志详细程度。此字段的有效值为 Normal,Debug,Trace, 或 TraceAll

1.2. 网络功能

MicroShift 4.15 提供的网络功能包括:

  • Kubernetes 网络策略
  • 动态节点 IP
  • 自定义网关接口
  • 第二个网关接口
  • 指定主机接口上的集群网络
  • 阻止对特定主机接口上的 NodePort 服务的外部访问

MicroShift 4.15 不提供网络功能:

  • Egress IP/firewall/QoS: disabled
  • 混合网络:不支持
  • IPsec: 不支持
  • 硬件卸载:不支持

1.3. IP 转发

启动时,ovnkube-master 容器会自动启用主机网络 sysctl net.ipv4.ip_forward 内核参数。这需要将传入的流量转发到 CNI。例如,如果禁用了 ip_forward,则从集群外部访问 NodePort 服务会失败。

1.4. 网络性能优化

默认情况下,将三个性能优化应用到 OVS 服务,以最大程度降低资源消耗:

  • ovs-vswitchd.serviceovsdb-server.service 的 CPU 关联性
  • no-mlockallopenvswitch.service
  • 将处理程序和 revalidator 线程限制为 ovs-vswitchd.service

1.5. MicroShift 网络组件和服务

本简要概述在 MicroShift 中描述了网络组件及其操作。microshift-networking RPM 是一个软件包,可自动拉取任何与网络相关的依赖项和 systemd 服务来初始化网络,例如 microshift-ovs-init systemd 服务。

NetworkManager
NetworkManager 需要在 MicroShift 节点上设置初始网关网桥。NetworkManager 和 NetworkManager-ovs RPM 软件包作为依赖项安装到 microshift-networking RPM 软件包,该软件包包含必要的配置文件。MicroShift 中的 NetworkManager 使用 keyfile 插件,并在安装 microshift-networking RPM 软件包后重新启动。
microshift-ovs-init
microshift-ovs-init.servicemicroshift-networking RPM 软件包安装,作为依赖的 systemd 服务到 microshift.service。它负责设置 OVS 网关网桥。
OVN 容器

两个 OVN-Kubernetes 守护进程集由 MicroShift 渲染和应用。

  • ovnkube-master 包含 northd,nbdb,sbdbovnkube-master 容器。
  • ovnkube-node ovnkube-node 包含 OVN-Controller 容器。

    MicroShift 启动后,OVN-Kubernetes 守护进程集会在 openshift-ovn-kubernetes 命名空间中部署。

打包

OVN-Kubernetes 清单和启动逻辑内置在 MicroShift 中。microshift-networking RPM 中包含的 systemd 服务和配置有:

  • /etc/NetworkManager/conf.d/microshift-nm.conf for NetworkManager.service
  • /etc/systemd/system/ovs-vswitchd.service.d/microshift-cpuaffinity.conf 用于 ovs-vswitchd.service
  • /etc/systemd/system/ovsdb-server.service.d/microshift-cpuaffinity.conf 用于 ovs-server.service
  • /usr/bin/configure-ovs-microshift.sh for microshift-ovs-init.service
  • /usr/bin/configure-ovs.sh for microshift-ovs-init.service
  • /etc/crio/crio.conf.d/microshift-ovn.conf 用于 CRI-O 服务

1.6. 网桥映射

网桥映射允许提供商网络流量访问物理网络。流量离开提供商网络,到达 br-int 网桥。br-intbr-ex 之间的跳接端口允许流量遍历提供商网络和边缘网络。Kubernetes pod 通过虚拟以太网对连接到 br-int 网桥:一个虚拟以太网对端附加到 pod 命名空间,另一个端点连接到 br-int 网桥。

1.7. 网络拓扑

OVN-Kubernetes 提供基于 overlay 的网络实现。此覆盖包括基于 OVS 的服务和 NetworkPolicy 实施。覆盖网络使用 Geneve (Generic Network Virtualization Encapsulation) 隧道协议。如果 Geneve 隧道没有配置,则 Geneve 隧道的 pod 最大传输单元(MTU)被设置为默认路由 MTU。

要配置 MTU,您必须设置等于或小于主机上物理接口的 MTU 的值。MTU 的 less-than 值为传输前添加到隧道头所需的信息留出空间。

OVS 作为 systemd 服务在 MicroShift 节点上运行。OVS RPM 软件包作为对 microshift-networking RPM 软件包的依赖项安装。安装了 microshift-networking RPM 时,OVS 会立即启动。

MicroShift 网络拓扑

317 RHbM OVN topology 0923

1.7.1. 虚拟化网络的 OVN 逻辑组件描述

OVN 节点交换机

一个名为 <node-name> 的虚拟交换机。OVN 节点交换机根据节点的主机名命名。

  • 在本例中,node-namemicroshift-dev
OVN 集群路由器

名为 ovn_cluster_router 的虚拟路由器,也称为分布式路由器。

  • 在本例中,集群网络是 10.42.0.0/16
OVN join 开关
名为 join 的虚拟交换机。
OVN 网关路由器
名为 GR_<node-name> 的虚拟路由器,也称为外部网关路由器。
OVN 外部交换机
名为 ext_<node-name>. 的虚拟交换机。

1.7.2. 网络拓扑图中的连接描述

  • 网络服务和 OVN 外部交换机 ext_microshift-dev 之间的南北流量由网关网桥 br-ex 通过主机内核提供。
  • OVN 网关路由器 GR_microshift-dev 通过逻辑路由器端口 4 连接到外部网络交换机 ext_microshift-dev。端口 4 附加到节点 IP 地址 192.168.122.14。
  • join 交换机 join 将 OVN 网关路由器 GR_microshift-dev 连接到 OVN 集群路由器 ovn_cluster_router。IP 地址范围为 100.62.0.0/16。

    • OVN 网关路由器 GR_microshift-dev 通过逻辑路由器端口 3 连接到 OVN join 交换机。端口 3 与内部 IP 地址 100.64.0.2 连接。
    • OVN 集群路由器 ovn_cluster_router 通过逻辑路由器端口 2 连接到 join 交换机。端口 2 与内部 IP 地址 100.64.0.1 连接。
  • OVN 集群路由器 ovn_cluster_router 通过逻辑路由器端口 1 连接到节点交换机 microshift-dev。端口 1 与 OVN 集群网络 IP 地址 10.42.0.1 附加。
  • pod 和网络服务之间的东西流量由 OVN 集群路由器 ovn_cluster_router 和节点交换机 microshift-dev 提供。IP 地址范围为 10.42.0.0/24。
  • pod 之间的东西流量由节点交换机 microshift-dev 提供,而无需网络地址转换 (NAT)。
  • pod 和外部网络之间的南北流量由 OVN 集群路由器 ovn_cluster_router 和主机网络提供。此路由器通过 ovn-kubernetes 管理端口 ovn-k8s-mp0 连接,IP 地址为 10.42.0.2。
  • 所有 pod 都通过其接口连接到 OVN 节点交换机。

    • 在本例中,Pod 1 和 Pod 2 通过 Interface 1Interface 2 连接到节点交换机。

第 2 章 了解网络设置

了解如何将网络自定义和默认设置应用到 MicroShift 部署。每个节点都包含在一个机器和单个 MicroShift 中,因此每个部署都需要单独的配置、Pod 和设置。

集群管理员有几个选项用于公开集群内的应用程序到外部流量并确保网络连接:

  • 服务,如 NodePort
  • API 资源,如 IngressRoute

默认情况下,Kubernetes 为 pod 内运行的应用分配内部 IP 地址。Pod 及其容器之间可以有网络流量,但集群外的客户端无法直接访问容器集,除非通过一个服务(如 NodePort)公开。

注意

要排除 NodePort 服务的连接问题,请阅读发行注记中的已知问题。

2.1. 创建 OVN-Kubernetes 配置文件

如果没有创建 OVN-Kubernetes 配置文件,MicroShift 将使用内置默认 OVN-Kubernetes 值。您可以将 OVN-Kubernetes 配置文件写入 /etc/microshift/ovn.yaml。为您的配置提供了一个示例文件。

流程

  1. 要创建 ovn.yaml 文件,请运行以下命令:

    $ sudo cp /etc/microshift/ovn.yaml.default /etc/microshift/ovn.yaml
  2. 要列出您创建的配置文件的内容,请运行以下命令:

    $ cat /etc/microshift/ovn.yaml

    带有默认最大传输单元(MTU)值的 YAML 文件示例

    mtu: 1400

  3. 要自定义配置,您可以更改 MTU 值。以下列表提供了详情:

    表 2.1. 支持 MicroShift 的可选 OVN-Kubernetes 配置
    字段类型Default(默认)描述Example

    mtu

    uint32

    auto

    用于 pod 的 MTU 值

    1300

    重要

    如果更改了 ovn.yaml 文件中的 mtu 配置值,您必须重启 MicroShift 运行的主机以应用更新的设置。

    自定义 ovn.yaml 配置文件示例

    mtu: 1300

2.2. 重启 ovnkube-master pod

以下流程重启 ovnkube-master pod。

先决条件

  • 已安装 OpenShift CLI (oc)。
  • 使用具有 cluster-admin 角色的用户访问集群。
  • 在使用 OVN-Kubernetes 网络插件配置的基础架构上安装集群。
  • KUBECONFIG 环境变量被设置。

流程

使用以下步骤重启 ovnkube-master pod。

  1. 运行以下命令来访问远程集群:

    $ export KUBECONFIG=$PWD/kubeconfig
  2. 运行以下命令,查找您要重启的 ovnkube-master pod 的名称:

    $ pod=$(oc get pods -n openshift-ovn-kubernetes | awk -F " " '/ovnkube-master/{print $1}')
  3. 运行以下命令来删除 ovnkube-master pod:

    $ oc -n openshift-ovn-kubernetes delete pod $pod
  4. 使用以下命令确认新的 ovnkube-master pod 正在运行:

    $ oc get pods -n openshift-ovn-kubernetes

    正在运行的 Pod 列表显示新的 ovnkube-master pod 名称和年龄。

2.3. 在 HTTP 或 HTTPS 代理后部署 MicroShift

在您要向 pod 添加基本匿名和安全措施时,在 HTTP 或 HTTPS 代理后部署 MicroShift 集群。

在代理后面部署 MicroShift 时,您必须将主机操作系统配置为使用代理服务以及启动 HTTP 或 HTTPS 请求的所有组件。

所有特定于用户的工作负载或带有出口流量的 pod (如访问云服务)都必须配置为使用代理。MicroShift 中没有内置透明代理的出口流量。

2.4. 使用 RPM-OStree HTTP 或 HTTPS 代理

要在 RPM-OStree 中使用 HTTP 或 HTTPS 代理,您必须在配置文件中添加 Service 部分,并为 rpm-ostreed 服务设置 http_proxy 环境变量

流程

  1. 将此设置添加到 /etc/systemd/system/rpm-ostreed.service.d/00-proxy.conf 文件中:

    [Service]
    Environment="http_proxy=http://$PROXY_USER:$PROXY_PASSWORD@$PROXY_SERVER:$PROXY_PORT/"
  2. 接下来,重新加载配置设置并重新启动服务以应用您的更改。

    1. 运行以下命令来重新载入配置设置:

      $ sudo systemctl daemon-reload
    2. 运行以下命令重启 rpm-ostreed 服务:

      $ sudo systemctl restart rpm-ostreed.service

2.5. 在 CRI-O 容器运行时中使用代理

要在 CRI-O 中使用 HTTP 或 HTTPS 代理,您必须在配置文件中添加 Service 部分并设置 HTTP_PROXYHTTPS_PROXY 环境变量。您还可以设置 NO_PROXY 变量,将主机列表排除在代理之外。

流程

  1. 如果配置文件不存在,请为配置文件创建该目录:

    $ sudo mkdir /etc/systemd/system/crio.service.d/
  2. /etc/systemd/system/crio.service.d/00-proxy.conf 文件中添加以下设置:

    [Service]
    Environment=NO_PROXY="localhost,127.0.0.1"
    Environment=HTTP_PROXY="http://$PROXY_USER:$PROXY_PASSWORD@$PROXY_SERVER:$PROXY_PORT/"
    Environment=HTTPS_PROXY="http://$PROXY_USER:$PROXY_PASSWORD@$PROXY_SERVER:$PROXY_PORT/"
    重要

    您必须为环境变量定义配置文件的 Service 部分,或者代理设置无法应用。

  3. 重新载入配置设置:

    $ sudo systemctl daemon-reload
  4. 重启 CRI-O 服务:

    $ sudo systemctl restart crio
  5. 重启 MicroShift 服务以应用设置:

    $ sudo systemctl restart microshift

验证

  1. 运行以下命令检查输出来验证 pod 是否已启动:

    $ oc get all -A
  2. 运行以下命令并检查输出,验证 MicroShift 是否可以拉取容器镜像:

    $ sudo crictl images

2.6. 从正在运行的集群获取 OVS 接口的快照

快照代表 OVS 接口在特定时间点的状态和数据。

流程

  • 要查看正在运行的 MicroShift 集群中 OVS 接口的快照,请使用以下命令:

    $ sudo ovs-vsctl show

    正在运行的集群中的 OVS 接口示例

    9d9f5ea2-9d9d-4e34-bbd2-dbac154fdc93
        Bridge br-ex
            Port br-ex
                Interface br-ex
                    type: internal
            Port patch-br-ex_localhost.localdomain-to-br-int 1
                Interface patch-br-ex_localhost.localdomain-to-br-int
                    type: patch
                    options: {peer=patch-br-int-to-br-ex_localhost.localdomain} 2
        Bridge br-int
            fail_mode: secure
            datapath_type: system
            Port patch-br-int-to-br-ex_localhost.localdomain
                Interface patch-br-int-to-br-ex_localhost.localdomain
                    type: patch
                    options: {peer=patch-br-ex_localhost.localdomain-to-br-int}
            Port eebee1ce5568761
                Interface eebee1ce5568761 3
            Port b47b1995ada84f4
                Interface b47b1995ada84f4 4
            Port "3031f43d67c167f"
                Interface "3031f43d67c167f" 5
            Port br-int
                Interface br-int
                    type: internal
            Port ovn-k8s-mp0 6
                Interface ovn-k8s-mp0
                    type: internal
        ovs_version: "2.17.3"

    1
    patch-br-ex_localhost.localdomain-to-br-intpatch-br-int-to-br-ex_localhost.localdomain 是连接 br-exbr-int 的 OVS 补丁端口。
    2
    patch-br-ex_localhost.localdomain-to-br-intpatch-br-int-to-br-ex_localhost.localdomain 是连接 br-exbr-int 的 OVS 补丁端口。
    3
    pod 接口 eebee1ce5568761 使用 pod 沙盒 ID 的前 15 位命名,并插入到 br-int 网桥。
    4
    pod 接口 b47b1995ada84f4 使用 pod 沙盒 ID 的前 15 位命名,并插入到 br-int 网桥中。
    5
    pod 接口 3031f43d67c167f 使用 pod 沙盒 ID 的前 15 位命名,并插入到 br-int 网桥中。
    6
    hairpin 流量的 OVS 内部端口,ovn-k8s-mp0ovnkube-master 容器创建。

2.7. 为工作负载部署负载均衡器

MicroShift 具有网络负载均衡器的内置实现。以下示例使用节点 IP 地址作为 LoadBalancer 服务配置文件的外部 IP 地址。您可以使用此示例作为如何为工作负载部署负载均衡器的指导。

先决条件

  • 已安装 OpenShift CLI (oc)。
  • 您可以使用具有集群管理角色的用户访问集群。
  • 在使用 OVN-Kubernetes 网络插件配置的基础架构上安装集群。
  • KUBECONFIG 环境变量被设置。

流程

  1. 运行以下命令验证您的 pod 是否正在运行:

    $ oc get pods -A
  2. 运行以下命令来创建示例命名空间:

    $ NAMESPACE=nginx-lb-test
    $ oc create ns $NAMESPACE
  3. 以下示例在命名空间中部署测试 nginx 应用程序的三个副本:

    $ oc apply -n $NAMESPACE -f - <<EOF
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx
    data:
      headers.conf: |
        add_header X-Server-IP  \$server_addr always;
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - image: quay.io/packit/nginx-unprivileged
            imagePullPolicy: Always
            name: nginx
            ports:
            - containerPort: 8080
            volumeMounts:
            - name: nginx-configs
              subPath: headers.conf
              mountPath: /etc/nginx/conf.d/headers.conf
            securityContext:
              allowPrivilegeEscalation: false
              seccompProfile:
                type: RuntimeDefault
              capabilities:
                drop: ["ALL"]
              runAsNonRoot: true
          volumes:
            - name: nginx-configs
              configMap:
                name: nginx
                items:
                  - key: headers.conf
                    path: headers.conf
    EOF
  4. 您可以运行以下命令来验证三个副本是否已成功启动:

    $ oc get pods -n $NAMESPACE
  5. 使用以下示例命令为 nginx 测试应用程序创建 LoadBalancer 服务:

    $ oc create -n $NAMESPACE -f - <<EOF
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
    spec:
      ports:
      - port: 81
        targetPort: 8080
      selector:
        app: nginx
      type: LoadBalancer
    EOF
    注意

    您必须确保 port 参数是一个没有被其他 LoadBalancer 服务或 MicroShift 组件占用的主机端口。

  6. 运行以下命令,验证服务文件是否存在,是否正确分配了外部 IP 地址,并且外部 IP 与节点 IP 相同:

    $ oc get svc -n $NAMESPACE

    输出示例

    NAME    TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
    nginx   LoadBalancer   10.43.183.104   192.168.1.241   81:32434/TCP   2m

验证

  • 以下命令使用 LoadBalancer 服务配置的外部 IP 地址形成五个到示例 nginx 应用程序的连接。命令的结果是这些服务器 IP 地址的列表。使用以下命令验证负载均衡器是否向所有正在运行的应用程序发送请求:

    EXTERNAL_IP=192.168.1.241
    seq 5 | xargs -Iz curl -s -I http://$EXTERNAL_IP:81 | grep X-Server-IP

    如果负载均衡器成功将流量分发到应用程序,则上一命令的输出包含不同的 IP 地址,例如:

    输出示例

    X-Server-IP: 10.42.0.41
    X-Server-IP: 10.42.0.41
    X-Server-IP: 10.42.0.43
    X-Server-IP: 10.42.0.41
    X-Server-IP: 10.42.0.43

2.8. 阻止对特定主机接口上 NodePort 服务的外部访问

OVN-Kubernetes 不限制可从 MicroShift 节点外部访问 NodePort 服务的主机接口。以下流程解释了如何在特定主机接口上阻止 NodePort 服务并限制外部访问。

先决条件

  • 您必须具有具有 root 特权的帐户。

流程

  1. 运行以下命令,将 NODEPORT 变量更改为分配给 Kubernetes NodePort 服务的主机端口号:

    # export NODEPORT=30700
  2. INTERFACE_IP 值从您要阻止的主机接口更改为 IP 地址。例如:

    # export INTERFACE_IP=192.168.150.33
  3. nat 表 PREROUTING 链中插入一条新规则,以丢弃与目标端口和 IP 地址匹配的所有数据包。例如:

    $ sudo nft -a insert rule ip nat PREROUTING tcp dport $NODEPORT ip daddr $INTERFACE_IP drop
  4. 运行以下命令列出新规则:

    $ sudo nft -a list chain ip nat PREROUTING
    table ip nat {
    	chain PREROUTING { # handle 1
    		type nat hook prerouting priority dstnat; policy accept;
    		tcp dport 30700 ip daddr 192.168.150.33 drop # handle 134
    		counter packets 108 bytes 18074 jump OVN-KUBE-ETP # handle 116
    		counter packets 108 bytes 18074 jump OVN-KUBE-EXTERNALIP # handle 114
    		counter packets 108 bytes 18074 jump OVN-KUBE-NODEPORT # handle 112
    	}
    }
    注意

    请记录下新添加的规则的 handle 号。您需要删除以下步骤中的 handle 号。

  5. 使用以下示例命令删除自定义规则:

    $ sudo nft -a delete rule ip nat PREROUTING handle 134

2.9. 多播 DNS 协议

多播 DNS 协议 (mDNS) 允许使用在 5353/UDP 端口上公开的多播进行名称解析和服务发现。

MicroShift 包括一个嵌入式 mDNS 服务器用于部署场景,在这种情况下,无法重新配置权威 DNS 服务器来将客户端指向 MicroShift 上的服务。嵌入式 DNS 服务器允许 MicroShift 公开的 .local 域由 LAN 上的其他元素发现。

2.10. 审计公开的网络端口

在 MicroShift 上,可以在以下情况下由工作负载打开主机端口。您可以检查日志以查看网络服务。

2.10.1. hostNetwork

当使用 hostNetwork:true 设置配置 pod 时,pod 在主机网络命名空间中运行。此配置可以独立打开主机端口。MicroShift 组件日志无法用于跟踪此问题单,端口会受到 firewalld 规则的约束。如果端口在 firewalld 中打开,您可以查看 firewalld 调试日志中打开的端口。

先决条件

  • 有访问构建主机的 root 用户。

流程

  1. 可选:您可以使用以下示例命令检查 ovnkube-node pod 中是否设置了 hostNetwork:true 参数:

    $ sudo oc get pod -n openshift-ovn-kubernetes <ovnkube-node-pod-name> -o json | jq -r '.spec.hostNetwork' true
  2. 运行以下命令,在 firewalld 日志中启用 debug:

    $ sudo vi /etc/sysconfig/firewalld
    FIREWALLD_ARGS=--debug=10
  3. 重启 firewalld 服务:

    $ sudo systemctl restart firewalld.service
  4. 要验证 debug 选项是否已正确添加,请运行以下命令:

    $ sudo systemd-cgls -u firewalld.service

    firewalld 调试日志存储在 /var/log/firewalld 路径中。

    添加端口打开规则时的日志示例:

    2023-06-28 10:46:37 DEBUG1: config.getZoneByName('public')
    2023-06-28 10:46:37 DEBUG1: config.zone.7.addPort('8080', 'tcp')
    2023-06-28 10:46:37 DEBUG1: config.zone.7.getSettings()
    2023-06-28 10:46:37 DEBUG1: config.zone.7.update('...')
    2023-06-28 10:46:37 DEBUG1: config.zone.7.Updated('public')

    当删除端口打开规则时的日志示例:

    2023-06-28 10:47:57 DEBUG1: config.getZoneByName('public')
    2023-06-28 10:47:57 DEBUG2: config.zone.7.Introspect()
    2023-06-28 10:47:57 DEBUG1: config.zone.7.removePort('8080', 'tcp')
    2023-06-28 10:47:57 DEBUG1: config.zone.7.getSettings()
    2023-06-28 10:47:57 DEBUG1: config.zone.7.update('...')
    2023-06-28 10:47:57 DEBUG1: config.zone.7.Updated('public')

2.10.2. hostPort

您可以在 MicroShift 中访问 hostPort 设置日志。以下日志是 hostPort 设置的示例:

流程

  • 您可以运行以下命令来访问日志:

    $ journalctl -u crio | grep "local port"

    打开主机端口时 CRI-O 日志示例:

    $ Jun 25 16:27:37 rhel92 crio[77216]: time="2023-06-25 16:27:37.033003098+08:00" level=info msg="Opened local port tcp:443"

    主机端口关闭时的 CRI-O 日志示例:

    $ Jun 25 16:24:11 rhel92 crio[77216]: time="2023-06-25 16:24:11.342088450+08:00" level=info msg="Closing host port tcp:443"

2.10.3. NodePort 和 LoadBalancer 服务

OVN-Kubernetes 为 NodePortLoadBalancer 服务类型打开主机端口。这些服务添加 iptables 规则,该规则使用来自主机端口的入口流量并将其转发到 clusterIP。以下示例中显示了 NodePortLoadBalancer 服务的日志:

流程

  1. 要访问 ovnkube-master pod 的名称,请运行以下命令:

    $ oc get pods -n openshift-ovn-kubernetes | awk '/ovnkube-master/{print $1}'

    ovnkube-master pod 名称示例

    ovnkube-master-n2shv

  2. 您可以使用 ovnkube-master pod 访问 NodePortLoadBalancer 服务日志,并运行以下命令:

    $ oc logs -n openshift-ovn-kubernetes <ovnkube-master-pod-name> ovnkube-master | grep -E "OVN-KUBE-NODEPORT|OVN-KUBE-EXTERNALIP"

    NodePort 服务:

    当主机端口打开时,ovnkube-master pod 的 ovnkube-master 容器中的日志示例:

    $ I0625 09:07:00.992980 2118395 iptables.go:27] Adding rule in table: nat, chain: OVN-KUBE-NODEPORT with args: "-p TCP -m addrtype --dst-type LOCAL --dport 32718 -j DNAT --to-destination 10.96.178.142:8081" for protocol: 0

    当主机端口关闭时,ovnkube-master pod 的 ovnkube-master 容器中的日志示例:

    $ Deleting rule in table: nat, chain: OVN-KUBE-NODEPORT with args: "-p TCP -m addrtype --dst-type LOCAL --dport 32718 -j DNAT --to-destination 10.96.178.142:8081" for protocol: 0

    LoadBalancer 服务:

    当主机端口打开时,ovnkube-master pod 的 ovnkube-master 容器中的日志示例:

    $ I0625 09:34:10.406067  128902 iptables.go:27] Adding rule in table: nat, chain: OVN-KUBE-EXTERNALIP with args: "-p TCP -d 172.16.47.129 --dport 8081 -j DNAT --to-destination 10.43.114.94:8081" for protocol: 0

    当主机端口关闭时,ovnkube-master pod 的 ovnkube-master 容器中的日志示例:

    $ I0625 09:37:00.976953  128902 iptables.go:63] Deleting rule in table: nat, chain: OVN-KUBE-EXTERNALIP with args: "-p TCP -d 172.16.47.129 --dport 8081 -j DNAT --to-destination 10.43.114.94:8081" for protocol: 0

第 3 章 网络策略

3.1. 关于网络策略

了解网络策略对 MicroShift 的工作原理,以限制或允许到集群中的 pod 的网络流量。

3.1.1. 网络策略在 MicroShift 中如何工作

在使用 MicroShift 的默认 OVN-Kubernetes Container Network Interface (CNI)插件的集群中,网络隔离由 firewalld 控制,它在主机上配置,并由 MicroShift 中创建的 NetworkPolicy 对象。支持同时使用 firewalld 和 NetworkPolicy

  • 网络策略仅在 OVN-Kubernetes 控制的流量范围内工作,以便它们可以应用到除启用了 hostPort/hostNetwork 的 pod 以外的每个情况。
  • firewalld 设置也适用于启用了 hostPort/hostNetwork 的 pod。
注意

在强制任何 NetworkPolicy 之前运行 firewalld 规则。

警告

网络策略不适用于主机网络命名空间。启用主机网络的 Pod 不受网络策略规则的影响。但是,连接到 host-networked pod 的 pod 会受到网络策略规则的影响。

网络策略无法阻止来自 localhost 的流量。

默认情况下,MicroShift 节点中的所有 pod 都可从其他 pod 和网络端点访问。要隔离集群中的一个或多个 pod,您可以创建 NetworkPolicy 对象来指示允许的入站连接。您可以创建和删除 NetworkPolicy 对象。

如果一个 pod 由一个或多个 NetworkPolicy 对象中的选择器匹配,则 pod 只接受至少被其中一个 NetworkPolicy 对象允许的连接。未被任何 NetworkPolicy 对象选择的 pod 可以完全访问。

网络策略仅适用于 TCP、UDP、ICMP 和 SCTP 协议。其他协议不会受到影响。

以下示例 NetworkPolicy 对象演示了支持不同的情景:

  • 拒绝所有流量:

    要使项目默认为拒绝流量,请添加一个匹配所有 pod 但不接受任何流量的 NetworkPolicy 对象:

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: deny-by-default
    spec:
      podSelector: {}
      ingress: []
  • 允许来自默认路由器的连接,这是 MicroShift 中的入口:

    要允许 MicroShift 默认路由器的连接,请添加以下 NetworkPolicy 对象:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-from-openshift-ingress
    spec:
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              ingresscontroller.operator.openshift.io/deployment-ingresscontroller: default
      podSelector: {}
      policyTypes:
      - Ingress
  • 仅接受同一命名空间中的 pod 的连接:

    要使 pod 接受同一命名空间中其他 pod 的连接,但拒绝其他命名空间中所有 pod 的连接,请添加以下 NetworkPolicy 对象:

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: allow-same-namespace
    spec:
      podSelector: {}
      ingress:
      - from:
        - podSelector: {}
  • 仅允许基于 pod 标签的 HTTP 和 HTTPS 流量:

    要对带有特定标签(以下示例中的 role=frontend)的 pod 仅启用 HTTP 和 HTTPS 访问,请添加类似如下的 NetworkPolicy 对象:

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: allow-http-and-https
    spec:
      podSelector:
        matchLabels:
          role: frontend
      ingress:
      - ports:
        - protocol: TCP
          port: 80
        - protocol: TCP
          port: 443
  • 使用命名空间和 pod 选择器接受连接:

    要通过组合使用命名空间和 pod 选择器来匹配网络流量,您可以使用类似如下的 NetworkPolicy 对象:

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: allow-pod-and-namespace-both
    spec:
      podSelector:
        matchLabels:
          name: test-pods
      ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                project: project_name
            podSelector:
              matchLabels:
                name: test-pods

NetworkPolicy 对象是可添加的;也就是说,您可以组合多个 NetworkPolicy 对象来满足复杂的网络要求。

例如,对于上例中定义的 NetworkPolicy 对象,您可以定义 allow-same-namespaceallow-http-and-https 策略。该配置允许带有标签 role=frontend 的 pod 接受每个策略允许的任何连接。即,任何端口上来自同一命名空间中的 pod 的连接,以及端口 80443 上的来自任意命名空间中 pod 的连接。

3.1.2. 使用 OVN-Kubernetes 网络插件优化网络策略

在设计您的网络策略时,请参考以下指南:

  • 对于具有相同 spec.podSelector spec 的网络策略,使用带有多个 ingressegress 规则的一个网络策略比带有 ingressegress 子集的多个网络策略更高效。
  • 每个基于 podSelectornamespaceSelector spec 的 ingressegress 规则会生成一个的 OVS 流数量,它与由网络策略选择的 pod 数量 + 由 ingress 或 egress 选择的 pod 数量成比例因此,最好使用在一个规则中可以选择您所需的 pod 的 podSelectornamespaceSelector 规格,而不是为每个 pod 创建单独的规则。

    例如,以下策略包含两个规则:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: test-network-policy
    spec:
      podSelector: {}
      ingress:
      - from:
        - podSelector:
            matchLabels:
              role: frontend
      - from:
        - podSelector:
            matchLabels:
              role: backend

    以下策略表示这两个规则与以下相同的规则:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: test-network-policy
    spec:
      podSelector: {}
      ingress:
      - from:
        - podSelector:
            matchExpressions:
            - {key: role, operator: In, values: [frontend, backend]}

    相同的指南信息适用于 spec.podSelector spec。如果不同的网络策略有相同的 ingressegress 规则,则创建一个带有通用的 spec.podSelector spec 可能更有效率。例如,以下两个策略有不同的规则:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: policy1
    spec:
      podSelector:
        matchLabels:
          role: db
      ingress:
      - from:
        - podSelector:
            matchLabels:
              role: frontend
    ---
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: policy2
    spec:
      podSelector:
        matchLabels:
          role: client
      ingress:
      - from:
        - podSelector:
            matchLabels:
              role: frontend

    以下网络策略将这两个相同的规则作为一个:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: policy3
    spec:
      podSelector:
        matchExpressions:
        - {key: role, operator: In, values: [db, client]}
      ingress:
      - from:
        - podSelector:
            matchLabels:
              role: frontend

    当只有多个选择器表示为一个选择器时,您可以应用此优化。如果选择器基于不同的标签,则可能无法应用此优化。在这些情况下,请考虑为网络策略优化应用一些新标签。

3.2. 创建网络策略

您可以为命名空间创建网络策略。

3.2.1. 示例 NetworkPolicy 对象

下文解释了示例 NetworkPolicy 对象:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-27107 1
spec:
  podSelector: 2
    matchLabels:
      app: mongodb
  ingress:
  - from:
    - podSelector: 3
        matchLabels:
          app: app
    ports: 4
    - protocol: TCP
      port: 27017
1
NetworkPolicy 对象的名称。
2
描述策略应用到的 pod 的选择器。
3
与策略对象允许从中入口流量的 pod 匹配的选择器。选择器与 NetworkPolicy 在同一命名空间中的 pod 匹配。
4
接受流量的一个或多个目标端口的列表。

3.2.2. 使用 CLI 创建网络策略

要定义细致的规则来描述集群中命名空间允许的入口或出口网络流量,您可以创建一个网络策略。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您在网络策略要应用到的命名空间中。

流程

  1. 创建策略规则:

    1. 创建一个 <policy_name>.yaml 文件:

      $ touch <policy_name>.yaml

      其中:

      <policy_name>
      指定网络策略文件名。
    2. 在您刚才创建的文件中定义网络策略,如下例所示:

      拒绝来自所有命名空间中的所有 pod 的入口流量

      这是一个基本的策略,阻止配置其他网络策略所允许的跨 pod 流量以外的所有跨 pod 网络。

      kind: NetworkPolicy
      apiVersion: networking.k8s.io/v1
      metadata:
        name: deny-by-default
      spec:
        podSelector: {}
        policyTypes:
        - Ingress
        ingress: []

      允许来自所有命名空间中的所有 pod 的入口流量

      kind: NetworkPolicy
      apiVersion: networking.k8s.io/v1
      metadata:
        name: allow-same-namespace
      spec:
        podSelector:
        ingress:
        - from:
          - podSelector: {}

      允许从特定命名空间中到一个 pod 的入口流量

      此策略允许流量从在 namespace-y 中运行的容器集到标记 pod-a 的 pod。

      kind: NetworkPolicy
      apiVersion: networking.k8s.io/v1
      metadata:
        name: allow-traffic-pod
      spec:
        podSelector:
         matchLabels:
            pod: pod-a
        policyTypes:
        - Ingress
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                 kubernetes.io/metadata.name: namespace-y
  2. 运行以下命令来创建网络策略对象:

    $ oc apply -f <policy_name>.yaml -n <namespace>

    其中:

    <policy_name>
    指定网络策略文件名。
    <namespace>
    可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。

    输出示例

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

3.2.3. 创建默认拒绝所有网络策略

这是一个基本的策略,阻止其他部署网络策略允许的网络流量以外的所有跨 pod 网络。此流程强制使用默认 deny-by-default 策略。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您在网络策略要应用到的命名空间中。

流程

  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 1
    spec:
      podSelector: {} 2
      ingress: [] 3
    1
    namespace:default 将此策略部署到 default 命名空间。
    2
    podSelector: 为空,这意味着它与所有 pod 匹配。因此,该策略适用于 default 命名空间中的所有 pod。
    3
    没有指定 ingress 规则。这会导致传入的流量丢弃至所有 pod。
  2. 输入以下命令应用策略:

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

    输出示例

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

3.2.4. 创建网络策略以允许来自外部客户端的流量

使用 deny-by-default 策略,您可以继续配置策略,允许从外部客户端到带有标签 app=web 的 pod 的流量。

注意

在强制任何 NetworkPolicy 之前运行 firewalld 规则。

按照以下步骤配置策略,以直接从公共互联网允许外部服务,或使用 Load Balancer 访问 pod。只有具有标签 app=web 的 pod 才允许流量。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您在网络策略要应用到的命名空间中。

流程

  1. 创建策略,以直接从公共互联网的流量或使用负载均衡器访问 pod。将 YAML 保存到 web-allow-external.yaml 文件中:

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: web-allow-external
      namespace: default
    spec:
      policyTypes:
      - Ingress
      podSelector:
        matchLabels:
          app: web
      ingress:
        - {}
  2. 输入以下命令应用策略:

    $ oc apply -f web-allow-external.yaml

    输出示例

    networkpolicy.networking.k8s.io/web-allow-external created

3.2.5. 创建网络策略,允许从所有命名空间中到应用程序的流量

按照以下步骤配置允许从所有命名空间中的所有 pod 流量到特定应用程序的策略。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您在网络策略要应用到的命名空间中。

流程

  1. 创建一个策略,允许从所有命名空间中的所有 pod 流量到特定应用。将 YAML 保存到 web-allow-all-namespaces.yaml 文件中:

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: web-allow-all-namespaces
      namespace: default
    spec:
      podSelector:
        matchLabels:
          app: web 1
      policyTypes:
      - Ingress
      ingress:
      - from:
        - namespaceSelector: {} 2
    1
    仅将策略应用到 default 命名空间中的 app:web pod。
    2
    选择所有命名空间中的所有 pod。
    注意

    默认情况下,如果您省略了指定 namespaceSelector 而不是选择任何命名空间,这意味着策略只允许从网络策略部署到的命名空间的流量。

  2. 输入以下命令应用策略:

    $ oc apply -f web-allow-all-namespaces.yaml

    输出示例

    networkpolicy.networking.k8s.io/web-allow-all-namespaces created

验证

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

    $ oc run web --namespace=default --image=nginx --labels="app=web" --expose --port=80
  2. 运行以下命令在 secondary 命名空间中部署 alpine 镜像并启动 shell:

    $ oc run test-$RANDOM --namespace=secondary --rm -i -t --image=alpine -- sh
  3. 在 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>

3.2.6. 创建网络策略,允许从一个命名空间中到应用程序的流量

按照以下步骤配置允许从特定命名空间中到带有 app=web 标签的 pod 的策略。您可能需要进行以下操作:

  • 将流量限制为部署生产工作负载的命名空间。
  • 启用部署到特定命名空间的监控工具,以从当前命名空间中提取指标。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您在网络策略要应用到的命名空间中。

流程

  1. 创建一个策略,允许来自特定命名空间中所有 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 1
      policyTypes:
      - Ingress
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              purpose: production 2
    1
    仅将策略应用到 default 命名空间中的 app:web pod。
    2
    将流量仅限制为具有标签 purpose=production 的命名空间中的 pod。
  2. 输入以下命令应用策略:

    $ oc apply -f web-allow-prod.yaml

    输出示例

    networkpolicy.networking.k8s.io/web-allow-prod created

验证

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

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

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

    $ oc label namespace/prod purpose=production
  4. 运行以下命令来创建 dev 命名空间:

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

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

    $ oc run test-$RANDOM --namespace=dev --rm -i -t --image=alpine -- sh
  7. 在 shell 中运行以下命令,并观察请求是否被阻止:

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

    预期输出

    wget: download timed out

  8. 运行以下命令,在 prod 命名空间中部署 alpine 镜像并启动 shell:

    $ oc run test-$RANDOM --namespace=prod --rm -i -t --image=alpine -- sh
  9. 在 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>

3.3. 编辑网络策略

您可以编辑命名空间的现有网络策略。典型的编辑可能包括对策略应用到的 pod 的更改、允许的入口流量以及接受流量的目的地端口。在编辑 NetworkPolicy 对象时,不能更改 apiVersionkindname 字段,因为这些定义资源本身。

3.3.1. 编辑网络策略

您可以编辑命名空间中的网络策略。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您在网络策略所在的命名空间中。

流程

  1. 可选: 要列出一个命名空间中的网络策略对象,请输入以下命令:

    $ oc get networkpolicy

    其中:

    <namespace>
    可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。
  2. 编辑网络策略对象。

    • 如果您在文件中保存了网络策略定义,请编辑该文件并进行必要的更改,然后输入以下命令。

      $ oc apply -n <namespace> -f <policy_file>.yaml

      其中:

      <namespace>
      可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。
      <policy_file>
      指定包含网络策略的文件的名称。
    • 如果您需要直接更新网络策略对象,请输入以下命令:

      $ oc edit networkpolicy <policy_name> -n <namespace>

      其中:

      <policy_name>
      指定网络策略的名称。
      <namespace>
      可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。
  3. 确认网络策略对象已更新。

    $ oc describe networkpolicy <policy_name> -n <namespace>

    其中:

    <policy_name>
    指定网络策略的名称。
    <namespace>
    可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。

3.3.2. 示例 NetworkPolicy 对象

下文解释了示例 NetworkPolicy 对象:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-27107 1
spec:
  podSelector: 2
    matchLabels:
      app: mongodb
  ingress:
  - from:
    - podSelector: 3
        matchLabels:
          app: app
    ports: 4
    - protocol: TCP
      port: 27017
1
NetworkPolicy 对象的名称。
2
描述策略应用到的 pod 的选择器。
3
与策略对象允许从中入口流量的 pod 匹配的选择器。选择器与 NetworkPolicy 在同一命名空间中的 pod 匹配。
4
接受流量的一个或多个目标端口的列表。

3.4. 删除网络策略

您可以从命名空间中删除网络策略。

3.4.1. 使用 CLI 删除网络策略

您可以删除命名空间中的网络策略。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您在网络策略所在的命名空间中。

流程

  • 要删除网络策略对象,请输入以下命令:

    $ oc delete networkpolicy <policy_name> -n <namespace>

    其中:

    <policy_name>
    指定网络策略的名称。
    <namespace>
    可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。

    输出示例

    networkpolicy.networking.k8s.io/default-deny deleted

3.5. 查看网络策略

使用以下步骤查看命名空间的网络策略。

3.5.1. 使用 CLI 查看网络策略

您可以检查命名空间中的网络策略。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您在网络策略所在的命名空间中。

流程

  • 列出命名空间中的网络策略:

    • 要查看命名空间中定义的网络策略对象,请输入以下命令:

      $ oc get networkpolicy
    • 可选: 要检查特定的网络策略,请输入以下命令:

      $ oc describe networkpolicy <policy_name> -n <namespace>

      其中:

      <policy_name>
      指定要检查的网络策略的名称。
      <namespace>
      可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。

      例如:

      $ oc describe networkpolicy allow-same-namespace

      oc describe 命令的输出

      Name:         allow-same-namespace
      Namespace:    ns1
      Created on:   2021-05-24 22:28:56 -0400 EDT
      Labels:       <none>
      Annotations:  <none>
      Spec:
        PodSelector:     <none> (Allowing the specific traffic to all pods in this namespace)
        Allowing ingress traffic:
          To Port: <any> (traffic allowed to all ports)
          From:
            PodSelector: <none>
        Not affecting egress traffic
        Policy Types: Ingress

第 4 章 使用防火墙

MicroShift 中不需要防火墙,但使用防火墙可以防止对 MicroShift API 的不必要的访问权限。

4.1. 关于通过防火墙的网络流量

firewalld 是一个在后台运行并响应连接请求的网络服务,创建基于主机的动态自定义防火墙。如果您使用带有 MicroShift 的 Red Hat Enterprise Linux for Edge (RHEL for Edge),则应该已安装 firewalld,您只需要配置它。遵循的步骤中提供了详细信息。总体而言,当 firewalld 服务运行时,您必须明确允许以下 OVN-Kubernetes 流量:

CNI pod 到 CNI pod
CNI pod 到 Host-Network pod Host-Network pod 到 Host-Network pod
CNI pod
使用 CNI 网络的 Kubernetes pod
Host-Network pod
使用主机网络的 Kubernetes pod,您可以按照以下步骤配置 firewalld 服务。在大多数情况下,firewalld 是 RHEL for Edge 安装的一部分。如果没有 firewalld,您可以参照本节中的简单流程安装它。
重要

MicroShift pod 必须有权访问内部 CoreDNS 组件和 API 服务器。

4.2. 安装 firewalld 服务

如果您使用 RHEL for Edge,则应该安装 firewalld。要使用该服务,您可以简单地进行配置。如果您没有 firewalld,但希望使用它,则可以使用以下步骤。

使用以下步骤为 MicroShift 安装并运行 firewalld 服务。

流程

  1. 可选:运行以下命令来检查系统中的 firewalld :

    $ rpm -q firewalld
  2. 如果没有安装 firewalld 服务,请运行以下命令:

    $ sudo dnf install -y firewalld
  3. 要启动防火墙,请运行以下命令:

    $ sudo systemctl enable firewalld --now

4.3. 所需的防火墙设置

在防火墙配置过程中,必须启用集群网络的 IP 地址范围。您可以使用默认值或自定义 IP 地址范围。如果您选择从默认的 10.42.0.0/16 设置自定义集群网络 IP 地址范围,还必须在防火墙配置中使用相同的自定义范围。

表 4.1. 防火墙 IP 地址设置
IP 范围防火墙规则所需的描述

10.42.0.0/16

主机网络 pod 访问其他 pod

169.254.169.1

主机网络 pod 访问 MicroShift API 服务器

以下是防火墙配置强制设置的命令示例:

示例命令

  • 配置主机网络 pod 对其他 pod 的访问:

    $ sudo firewall-cmd --permanent --zone=trusted --add-source=10.42.0.0/16
  • 配置主机网络 pod 访问由主机端点支持的服务,如 MicroShift API:

    $ sudo firewall-cmd --permanent --zone=trusted --add-source=169.254.169.1

4.4. 使用可选端口设置

MicroShift 防火墙服务允许可选端口设置。

流程

  • 要在防火墙配置中添加自定义端口,请使用以下命令语法:

    $ sudo firewall-cmd --permanent --zone=public --add-port=<port number>/<port protocol>
    表 4.2. 可选端口
    端口协议描述

    80

    TCP

    用于通过 OpenShift Container Platform 路由器提供应用程序的 HTTP 端口。

    443

    TCP

    用于通过 OpenShift Container Platform 路由器提供应用程序的 HTTPS 端口。

    5353

    UDP

    mDNS 服务以响应 OpenShift Container Platform 路由 mDNS 主机。

    30000-32767

    TCP

    为 NodePort 服务保留的端口范围;可用于公开 LAN 上的应用程序。

    30000-32767

    UDP

    为 NodePort 服务保留的端口范围;可用于公开 LAN 上的应用程序。

    6443

    TCP

    MicroShift API 的 HTTPS API 端口。

以下是当要求从外部访问在 MicroShift 上运行的服务时使用的命令示例,如 API 服务器的端口 6443,例如通过路由器公开的应用程序的端口 80 和 443。

示例命令

  • 为 MicroShift API 服务器配置端口:

    $ sudo firewall-cmd --permanent --zone=public --add-port=6443/tcp

要关闭 MicroShift 实例中不必要的端口,请按照 "Closing unused 或 unnecessary port to enhance network security" 中的步骤操作。

4.5. 添加服务来打开端口

在 MicroShift 实例中,您可以使用 firewall-cmd 命令在端口上打开服务。

流程

  1. 可选:您可以通过运行以下命令来查看 firewalld 中的所有预定义服务

    $ sudo firewall-cmd --get-services
  2. 要在默认端口中打开您想要的服务,请运行以下命令:

    $ sudo firewall-cmd --add-service=mdns

4.6. 允许通过防火墙的网络流量

您可以通过配置 IP 地址范围并插入 DNS 服务器来允许网络流量通过防火墙,以允许通过网络网关从 pod 的内部流量。

流程

  1. 使用以下命令之一设置 IP 地址范围:

    1. 运行以下命令,使用默认值配置 IP 地址范围:

      $ sudo firewall-offline-cmd --permanent --zone=trusted --add-source=10.42.0.0/16
    2. 运行以下命令,使用自定义值配置 IP 地址范围:

      $ sudo firewall-offline-cmd --permanent --zone=trusted --add-source=<custom IP range>
  2. 要允许 pod 通过网络网关的内部流量,请运行以下命令:

    $ sudo firewall-offline-cmd --permanent --zone=trusted --add-source=169.254.169.1

4.6.1. 应用防火墙设置

要应用防火墙设置,请使用以下步骤步骤:

流程

  • 通过防火墙配置网络访问后,运行以下命令重启防火墙并应用设置:
$ sudo firewall-cmd --reload

4.7. 验证防火墙设置

重启防火墙后,您可以通过列出设置来验证设置。

流程

  • 要验证在默认公共区(如端口相关的规则)中添加的规则,请运行以下命令:

    $ sudo firewall-cmd --list-all
  • 要验证在可信区(如 IP-range 相关规则)中添加的规则,请运行以下命令:

    $ sudo firewall-cmd --zone=trusted --list-all

4.8. 公开服务时防火墙端口概述

当您在 MicroShift 上运行服务时,firewalld 通常处于活跃状态。这可能会中断 MicroShift 上的某些服务,因为防火墙可能会阻止到端口的流量。如果您希望从主机外部访问某些服务,则必须确保打开所需的防火墙端口。打开端口有几个选项:

  • NodePortLoadBalancer 类型的服务会自动用于 OVN-Kubernetes。

    在这些情况下,OVN-Kubernetes 添加 iptables 规则,以便到节点 IP 地址的流量传送到相关端口。这使用 PREROUTING 规则链完成,然后转发到 OVN-K 以绕过本地主机端口和服务的 firewalld 规则。iptables 和 firewalld 由 RHEL 9 中的 nftables 支持。iptables 生成的 nftables 规则始终优先于 firewalld 生成的规则。

  • 具有 HostPort 参数设置的 Pod 会自动可用。这还包括 router-default pod,它使用端口 80 和 443。

    对于 HostPort pod,CRI-O 配置将 iptables DNAT (Destination Network Address Translation)设置为 pod 的 IP 地址和端口。

这些方法对于客户端是位于同一主机还是远程主机上的功能。OVN-Kubernetes 和 CRI-O 添加的 iptables 规则附加到 PREROUTING 和 OUTPUT 链。本地流量通过 OUTPUT 链,接口设置为 lo 类型。DNAT 在它到达 INPUT 链中的填充规则之前运行。

由于 MicroShift API 服务器没有在 CRI-O 中运行,所以受防火墙配置约束。您可以在防火墙中打开端口 6443,以访问 MicroShift 集群中的 API 服务器。

4.9. 其他资源

4.10. 已知的防火墙问题

  • 为了避免在重新加载或重启的情况下破坏流量流,请在启动 RHEL 前执行防火墙命令。MicroShift 中的 CNI 驱动程序将 iptable 规则用于某些流量流,如使用 NodePort 服务的用户。iptable 规则由 CNI 驱动程序生成和插入,但在防火墙重新加载或重启时会被删除。缺少 iptable 规则会破坏流量流。如果需要在 MicroShift 运行后执行 firewall 命令,请手动重启 openshift-ovn-kubernetes 命名空间中的 ovnkube-master pod 来重置由 CNI 驱动程序控制的规则。

第 5 章 为完全断开连接的主机配置网络设置

了解如何应用网络自定义和设置,以便在完全断开连接的主机上运行 MicroShift。断开连接的主机应该是 Red Hat Enterprise Linux (RHEL)操作系统,版本 9.0+,无论是实际还是虚拟,在没有网络连接的情况下运行。

5.1. 为完全断开连接的主机准备网络

使用以下步骤在运行完全断开连接的操作系统的设备上启动并运行 MicroShift 集群。如果没有外部网络连接,MicroShift 主机被视为完全断开连接的。

通常,这意味着设备没有附加的网络接口控制器(NIC)来提供子网。这些步骤也可以在设置后删除的 NIC 的主机上完成。您还可以使用 Kickstart 文件的 %post 阶段在没有 NIC 的主机上自动化这些步骤。

重要

需要为断开连接的环境配置网络设置,因为 MicroShift 需要网络设备来支持集群通信。要满足此要求,您必须配置 MicroShift 网络设置,以使用您在设置过程中分配给系统回送设备的 "fake" IP 地址。

5.1.1. 步骤概述

要在断开连接的主机上运行 MicroShift,需要以下步骤:

准备主机
  • 如果当前正在运行,请停止 MicroShift,并清理该服务已对网络进行了更改。
  • 设置持久主机名。
  • 在回环接口上添加"fake"IP 地址。
  • 将 DNS 配置为使用假的 IP 作为本地名称服务器。
  • /etc/hosts 添加主机名条目。
更新 MicroShift 配置
  • nodeIP 参数定义为新的回环 IP 地址。
  • .node.hostnameOverride 参数设置为持久主机名。
要使更改生效
  • 如果附加,禁用默认 NIC。
  • 重启主机或设备。

启动后,MicroShift 使用 loopback 设备进行集群内通信运行。

5.2. 将 MicroShift 网络设置恢复到默认值

您可以通过停止 MicroShift 并运行清理脚本来删除网络并将网络返回到默认设置。

先决条件

  • RHEL 9 或更新版本。
  • MicroShift 4.14 或更新版本。
  • 访问主机 CLI。

流程

  1. 运行以下命令来停止 MicroShift 服务:

    $ sudo systemctl stop microshift
  2. 运行以下命令停止 kubepods.slice systemd 单元:

    $ sudo systemctl stop kubepods.slice
  3. MicroShift 会安装帮助程序脚本,以撤销 OVN-K 所做的网络更改。输入以下命令运行清理脚本:

    $ sudo /usr/bin/microshift-cleanup-data --ovn

5.3. 为完全断开连接的主机配置网络设置

要配置网络设置,以便在完全断开连接的主机上运行 MicroShift,您必须准备主机,更新网络配置,然后重启以应用新设置。所有命令都通过主机 CLI 执行。

先决条件

  • RHEL 9 或更新版本。
  • MicroShift 4.14 或更新版本。
  • 访问主机 CLI。
  • 选择一个有效的 IP 地址以避免在运行 MicroShift 时出现内部和外部 IP 冲突。
  • MicroShift 网络设置设置为默认值。
重要

以下流程适用于在设备部署到字段中后不需要访问 MicroShift 集群的用例。删除网络连接后没有远程集群访问。

流程

  1. 运行以下命令,在回环接口中添加假的 IP 地址:

    $ IP="10.44.0.1" 1
    $ sudo nmcli con add type loopback con-name stable-microshift ifname lo ip4 ${IP}/32
    1
    本例中使用的假的 IP 地址是 "10.44.0.1"。
    注意

    如果避免内部 MicroShift 和潜在的外部 IP 冲突,则任何有效的 IP 都可以正常工作。这可以是不与 MicroShift 节点子网冲突的任何子网,或者可由设备上的其他服务访问。

  2. 通过修改设置来忽略自动 DNS 并将其重置为本地名称服务器,将 DNS 接口配置为使用本地名称服务器:

    1. 运行以下命令来绕过自动 DNS:

      $ sudo nmcli conn modify stable-microshift ipv4.ignore-auto-dns yes
    2. 将 DNS 接口指向使用本地名称服务器:

      $ sudo nmcli conn modify stable-microshift ipv4.dns "10.44.1.1"
  3. 运行以下命令来获取该设备的主机名:

    $ NAME="$(hostnamectl hostname)"
  4. 运行以下命令,在 /etc/hosts 文件中为节点的主机名添加一个条目:

    $ echo "$IP $NAME" | sudo tee -a /etc/hosts >/dev/null
  5. 通过在 /etc/microshift/config.yaml 中添加以下 YAML 片断来更新 MicroShift 配置文件:

    sudo tee /etc/microshift/config.yaml > /dev/null <<EOF
    node:
      hostnameOverride: $(echo $NAME)
      nodeIP: $(echo $IP)
    EOF
  6. MicroShift 现在可以使用回送设备进行集群通信。完成设备准备以离线使用。

    1. 如果设备当前附加了 NIC,请断开设备与网络的连接。
    2. 关闭该设备并断开 NIC。
    3. 重启该设备以使离线配置生效。
  7. 运行以下命令重启 MicroShift 主机以应用配置更改:

    $ sudo systemctl reboot 1
    1
    此步骤重启集群。在实施验证前,等待 greenboot 健康检查报告系统健康状态。

验证

此时,对 MicroShift 主机的网络访问已被严重。如果可以访问主机终端,您可以使用主机 CLI 验证集群是否已以稳定状态启动。

  1. 输入以下命令验证 MicroShift 集群是否正在运行:

    $ export KUBECONFIG=/var/lib/microshift/resources/kubeadmin/kubeconfig
    $ sudo -E oc get pods -A

    输出示例

    NAMESPACE                  NAME                                       READY   STATUS    RESTARTS      AGE
    kube-system                csi-snapshot-controller-74d566564f-66n2f   1/1     Running   0             1m
    kube-system                csi-snapshot-webhook-69bdff8879-xs6mb      1/1     Running   0             1m
    openshift-dns              dns-default-dxglm                          2/2     Running   0             1m
    openshift-dns              node-resolver-dbf5v                        1/1     Running   0             1m
    openshift-ingress          router-default-8575d888d8-xmq9p            1/1     Running   0             1m
    openshift-ovn-kubernetes   ovnkube-master-gcsx8                       4/4     Running   1             1m
    openshift-ovn-kubernetes   ovnkube-node-757mf                         1/1     Running   1             1m
    openshift-service-ca       service-ca-7d7c579f54-68jt4                1/1     Running   0             1m
    openshift-storage          topolvm-controller-6d777f795b-bx22r        5/5     Running   0             1m
    openshift-storage          topolvm-node-fcf8l                         4/4     Running   0             1m

法律通告

Copyright © 2024 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.