OpenShift Virtualization - 从集群外部访问集群中的 VM(附视频)

《OpenShift / RHEL / DevSecOps 汇总目录》
说明:本文已经在 OpenShift 4.12 的环境中验证

文章目录

  • 方法1:通过 Service 的 NodePort 访问 VM
  • 方法2:通过外部 IP 访问 VM
    • 确认 OpenShift 集群环境
    • 为 Worker 节点添加 Linux Bridge
    • 创建使用 Linux Bridge 的 NetworkAttachmentDefinition
    • 在 VM 中使用附加网络
      • 自动获得 IP 的 VM
      • 指定固定 IP 的 VM
      • 修改 VM 的外部固定 IP
  • 演示视频
  • 参考

可以使用以下两种方法实现从 OpenShift 集群外部访问运行在容器 VM 中的服务:

方法1:通过 Service 的 NodePort 访问 VM

缺省情况下运行在 OpenShift Virtualization 中的 VM 使用的是 Pod 网络,因此只能通过 Pod 网络实现从 OpenShift 集群外部访问 VM 或从 VM 访问外部资源。由于每次 VM 重启后其对应的 Pod 都会变更其 IP,因此即便是在集群内部也无法直接用 IP 地址访问 VM。如果只需要从集群内部访问 VM,使用 Service 对应 Pod 即可,但如果需要从 OpenShift 集群外部访问 VM,还需要为 Service 绑定 NodePort 才可以。

可参考《OpenShift 4 - 通过 SSH 远程访问 OpenShift Virtualization 的虚拟机》一文。该文以运行在 22 端口的 SSH 服务为例,也适用于其他服务。

方法2:通过外部 IP 访问 VM

为了能够以固定 IP 访问OpenShift Virtualization 中 VM,我们可以为运行在 OpenShift Virtualization 中的 VM 配置第二个 Network Interface,并将其 IP 配置到外部网络(例如外部主机网段)。

为了实现该场景,需要以下配置步骤:
OpenShift Virtualization - 从集群外部访问集群中的 VM(附视频)_第1张图片

  1. 安装 NMStat Operator
  2. 首先在 OpenShift 中使用 NodeNetworkConfigurationPolicy 对象为 Worker 节点添加 Linux Bridge,这些 Linux Bridge 即可使用主机节点的 IP 网段地址。
  3. 然后在 OpenShift 中创建一个使用该 Linux Bridge 的 NetworkAttachmentDefinition 对象
  4. 最后在 VM 中添加第二个 Network Interface,将其配置到 NetworkAttachmentDefinition 对象,这样 VM 就可以通过 Linux Bridge 使用外部的主机 IP 网段地址了。

此种方法虽然需要在 OpenShift 上进行单独的配置,但由于可通过外部主机使用的 IP 网段直接访问 VM,因此具有更高的网络性能。此方法另外的优势是由于该 VM 在第二个 Network Interface 上使用了外部 IP,因此当 VM 重启后,第二个 Network Interface 对应的 IP 地址不会发生变化。

VM 使用的外部 IP 可以是通过集群外部的 DHCP 分配的,也可是通过手动直接配置的。另外该 IP 的 DNS 解析也需要通过集群外部的 DNS 完成。

确认 OpenShift 集群环境

以下为 BareMetal 部署模式的 OpenShift 集群。

  1. 从“裸机主机” 中确认 Worker 节点的配置中有 enp3s0 的 nic 配置和对应的网段,该外网段为外部主机网段。
    OpenShift Virtualization - 从集群外部访问集群中的 VM(附视频)_第2张图片
  2. 由于每个 Node 运行在对应的裸机主机上,因此每个 Worker Node 也有 enp3s0 网络接口。
    OpenShift Virtualization - 从集群外部访问集群中的 VM(附视频)_第3张图片
  3. 创建一个运行 VM 的项目。
$ oc new-project my-vm
  1. 执行命令,查看节点相关的 “192.168” 网段 IP 地址。注意此时只有 enp2s0 网络接口有该网段地址。
$ oc debug node/<WORKER_NODE_NAME> -- ip a | grep -B 2 192.168
Temporary namespace openshift-debug-f5gxs is created for debugging node...
Starting pod/ocp4-worker1aioexamplecom-debug ...
To use host binaries, run `chroot /host`

3: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:00:00:04 brd ff:ff:ff:ff:ff:ff
    inet 192.168.123.104/24 brd 192.168.123.255 scope global dynamic noprefixroute enp2s0

为 Worker 节点添加 Linux Bridge

  1. 使用默认配置安装 Kubernetes NMState Operator。
  2. 在安装好的 Kubernetes NMState Operator 中使用默认配置创建一个 NMState 实例。
  3. 创建以下配置的 NodeNetworkConfigurationPolicy 对象,它将在节点名为 enp3s0 的 NIC 上创建 linux-bridge。注意:这里的 ipv4 的 dhcp 和 enabled、bridge 的 enabled 都为 true。
apiVersion: nmstate.io/v1
kind: NodeNetworkConfigurationPolicy
metadata:
  name: br-flat
spec:
  nodeSelector:
    node-role.kubernetes.io/worker: ""
  desiredState:
    interfaces:
      - name: br-flat
        description: Linux bridge with enp3s0 as a port
        type: linux-bridge
        state: up
        ipv4:
          dhcp: true
          enabled: true
        bridge:
          options:
            stp:
              enabled: true
          port:
            - name: enp3s0
  1. 由于使用了 nodeSelector,因此完成创建后确认在 Worker 节点完成了配置。
    OpenShift Virtualization - 从集群外部访问集群中的 VM(附视频)_第4张图片
  2. 完成后可以执行以下命令,可以找到 br-flat 网桥相关配置。注意:如果前面 NodeNetworkConfigurationPolicy 对象的 ipv4 和 bridge 设的是 false,则以下 br-flat 不会获得 IP 地址 192.168.3.108。
$ oc debug node/ocp4-worker1.aio.example.com -- ip a | grep -A 1 br-flat
Temporary namespace openshift-debug-z5w2p is created for debugging node...
Starting pod/ocp4-worker1aioexamplecom-debug ...
To use host binaries, run `chroot /host`

4: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br-flat state UP group default qlen 1000
    link/ether 52:54:00:00:01:04 brd ff:ff:ff:ff:ff:ff
9: br-flat: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 52:54:00:00:01:04 brd ff:ff:ff:ff:ff:ff
    inet 192.168.3.108/24 brd 192.168.3.255 scope global dynamic noprefixroute br-flat
       valid_lft 2307sec preferred_lft 2307sec

$ oc debug node/ocp4-worker1.aio.example.com -- ip a | grep 192.168
Temporary namespace openshift-debug-lzqjb is created for debugging node...
Starting pod/ocp4-worker1aioexamplecom-debug ...
To use host binaries, run `chroot /host`
    inet 192.168.123.104/24 brd 192.168.123.255 scope global dynamic noprefixroute enp2s0
    inet 192.168.3.108/24 brd 192.168.3.255 scope global dynamic noprefixroute br-flat

$ oc debug node/ocp4-worker1.aio.example.com -- cat /host/etc/sysconfig/network-scripts/ifcfg-enp3s0
Temporary namespace openshift-debug-v6pms is created for debugging node...
Starting pod/ocp4-worker1aioexamplecom-debug ...
To use host binaries, run `chroot /host`

TYPE=Ethernet
NAME=enp3s0
DEVICE=enp3s0
ONBOOT=yes
BRIDGE_PORT_VLANS=2-4094
UUID=63aa2036-8665-f54d-9a92-c3035bad03f7
LLDP=no
BRIDGE_UUID=1d670e6a-944c-427b-994f-b4d2690e00b2
BRIDGE=br-flat

创建使用 Linux Bridge 的 NetworkAttachmentDefinition

  1. 进入 OpenShift 控制台的“网络-NetworkAttachmentDefinition”菜单,然后在 my-vm 项目下点击“创建 Network Attachment Definition”。
    OpenShift Virtualization - 从集群外部访问集群中的 VM(附视频)_第5张图片
  2. 在 Create Network Attachment Definition 页面中按下图创建 NetworkAttachmentDefinition 对象。
    OpenShift Virtualization - 从集群外部访问集群中的 VM(附视频)_第6张图片

在 VM 中使用附加网络

自动获得 IP 的 VM

  1. 在 OpenShift 中创建一个 VM,在它的 Network Interfaces 栏中点击 Add network interface。
    OpenShift Virtualization - 从集群外部访问集群中的 VM(附视频)_第7张图片
  2. 在 Add network interface 配置窗口中按照下图指定其类型和使用的 Network。
    OpenShift Virtualization - 从集群外部访问集群中的 VM(附视频)_第8张图片
  3. 创建并运行 VM。启动 VM 后确认该 VM 的第二个网络接口的 IP 地址,并可从外部 ping 通该 IP。
    OpenShift Virtualization - 从集群外部访问集群中的 VM(附视频)_第9张图片
[fedora@fedora-1 ~] $ ip a show dev eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 02:9e:7c:00:00:01 brd ff:ff:ff:ff:ff:ff
    altname enp2s0
    inet 192.168.3.103/24 brd 192.168.3.255 scope global dynamic noprefixroute eth1
       valid_lft 2905sec preferred_lft 2905sec
    inet6 fe80::9fe3:1227:d23:1d9b/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

[fedora@fedora-1 ~] $ nmcli con show 'Wired connection 1' | grep DHCP4
DHCP4.OPTION[1]:                        broadcast_address = 192.168.3.255
DHCP4.OPTION[2]:                        dhcp_client_identifier = 01:02:9e:7c:00:00:01
DHCP4.OPTION[3]:                        dhcp_lease_time = 3600
DHCP4.OPTION[4]:                        dhcp_server_identifier = 192.168.3.1
DHCP4.OPTION[5]:                        domain_name_servers = 192.168.3.1
DHCP4.OPTION[6]:                        expiry = 1684047661
DHCP4.OPTION[7]:                        host_name = fedora-1
DHCP4.OPTION[8]:                        ip_address = 192.168.3.103
DHCP4.OPTION[9]:                        next_server = 192.168.3.1
DHCP4.OPTION[10]:                       requested_broadcast_address = 1
DHCP4.OPTION[11]:                       requested_domain_name = 1
DHCP4.OPTION[12]:                       requested_domain_name_servers = 1
DHCP4.OPTION[13]:                       requested_domain_search = 1
DHCP4.OPTION[14]:                       requested_host_name = 1
DHCP4.OPTION[15]:                       requested_interface_mtu = 1
DHCP4.OPTION[16]:                       requested_ms_classless_static_routes = 1
DHCP4.OPTION[17]:                       requested_nis_domain = 1
DHCP4.OPTION[18]:                       requested_nis_servers = 1
DHCP4.OPTION[19]:                       requested_ntp_servers = 1
DHCP4.OPTION[20]:                       requested_rfc3442_classless_static_routes = 1
DHCP4.OPTION[21]:                       requested_root_path = 1
DHCP4.OPTION[22]:                       requested_routers = 1
DHCP4.OPTION[23]:                       requested_static_routes = 1
DHCP4.OPTION[24]:                       requested_subnet_mask = 1
DHCP4.OPTION[25]:                       requested_time_offset = 1
DHCP4.OPTION[26]:                       requested_wpad = 1
DHCP4.OPTION[27]:                       routers = 192.168.3.1
DHCP4.OPTION[28]:                       subnet_mask = 255.255.255.0

指定固定 IP 的 VM

在上一步正式运行 fedora-1 前先进入 VM 的 YAML,在 cloudInitNoCloud 下面增加以下使用固定 IP 的网卡配置,保存后再创建 VM。

            networkData: |
              version: 2
              ethernets:
                eth1:
                  addresses:
                  - 192.168.3.201/24

OpenShift Virtualization - 从集群外部访问集群中的 VM(附视频)_第10张图片

修改 VM 的外部固定 IP

  1. 重启 VM,然后确认第二个网络接口的 IP 地址不会变化。
  2. 执行命令进入 VM 的 Console 并登录 VM。注意命令提示的退出 VM Console 的方式。
$ virtctl console fedora-1
Successfully connected to fedora-1 console. The escape sequence is ^]

fedora-1 login:
  1. 在 VM 中查看 eth1 的 IP 地址,例如 192.168.3.103。
[fedora@fedora-1 ~] ip a show eth1
  1. 执行命令,将 VM 使用的外部 IP 地址修改为 192.168.3.201/24。
[fedora@fedora-1 ~] nmcli con show
[fedora@fedora-1 ~] sudo nmcli con modify "Wired connection 1" +ipv4.addresses 192.168.3.201/24
[fedora@fedora-1 ~] sudo nmcli con modify "Wired connection 1" -ipv4.addresses 192.168.3.103/24
[fedora@fedora-1 ~] sudo nmcli con down "Wired connection 1"
[fedora@fedora-1 ~] sudo nmcli con up "Wired connection 1"
  1. 在 VM 中安装 NginX。
[fedora@fedora-1 ~] sudo yum install -y nginx
[fedora@fedora-1 ~] sudo systemctl start nginx
  1. 退出 VM Console。
  2. 然后确认可以从外部 ping 通 VM 新的 IP 地址并能访问 NginX,而且在重启 VM 后 IP 地址也不会变化。
$ ping 192.168.3.201
$ curl 192.168.3.201
  1. 删除 VM 的 default 的网络接口,然后确认还可从外部访问 ping 通主机和访问 NginX。

演示视频

视频

参考

https://www.cnblogs.com/djlsunshine/p/9733182.html
http://kubevirt.io/2023/OVN-kubernetes-secondary-networks.html
https://cloud.redhat.com/blog/using-the-multus-cni-in-openshift
https://github.com/nmstate/kubernetes-nmstate/blob/main/docs/examples/static-ip.yaml

你可能感兴趣的:(openshift,虚拟化,VM,kubernetes,运维)