Suscríbase al feed

OpenShift Virtualization ofrece una excelente solución para las aplicaciones que no están organizadas en contenedores, pero presenta algunos desafíos en comparación con los productos de virtualización heredados y los sistemas de servidores dedicados (bare metal). Uno de ellos es la interacción con máquinas virtuales (VM). OpenShift está orientado a las aplicaciones organizadas en contenedores, cuya configuración y gestión generalmente no necesita conexiones entrantes, al menos no el mismo tipo de conexiones que necesitaría una máquina virtual para su administración o uso.

En esta publicación de blog, se analizan varios métodos para acceder a las máquinas virtuales que se ejecutan en un entorno de OpenShift Virtualization. A continuación presentamos un breve resumen de ellos.

  • La interfaz de usuario (UI) de OpenShift

    Las conexiones de VNC a través de la interfaz de usuario que se obtienen por medio de OpenShift Virtualization proporcionan acceso directo a la consola de la máquina virtual. Las conexiones seriales a través de la interfaz de usuario no requieren ninguna configuración cuando se usan imágenes provistas por Red Hat. Estos métodos de conexión son útiles para solucionar los problemas con las máquinas virtuales.

  • El comando virtctl

    El comando virtctl usa WebSockets para establecer conexiones con una máquina virtual. Proporciona acceso a la consola de VNC, a la consola en serie y al SSH en la máquina virtual. OpenShift Virtualization proporciona el acceso a la consola de VNC y a la consola en serie como en la interfaz de usuario. Para el acceso a la consola de VNC se requiere un cliente de VNC en el cliente que ejecuta el comando virtctl . Para el acceso a la consola en serie, se necesita la misma configuración de máquina virtual que para el acceso a la consola en serie a través de la interfaz de usuario. Para el acceso al SSH, se requiere que el sistema operativo de la máquina virtual esté configurado para dicho acceso. Consulta la documentación sobre las imágenes de las máquinas virtuales para conocer sus requisitos en relación con SSH.

  • La red de pods

    La exposición de un puerto mediante un servicio permite las conexiones de red en una máquina virtual. Cualquier puerto en una máquina virtual se puede exponer con un servicio. Los puertos comunes son el 22 (SSH), el 5900+ (VNC) y el 3389 (RDP). En esta publicación, se muestran tres tipos diferentes de servicios.

    • ClusterIP

      Un servicio ClusterIP expone un puerto de una máquina virtual al interior de un clúster, de manera que las máquinas virtuales se pueden comunicar entre sí, pero no se permiten conexiones desde fuera del clúster.

    • NodePort

      Un servicio NodePort expone un puerto de una máquina virtual fuera del clúster a través de los nodos de este. El puerto de la máquina virtual se asigna a un puerto en los nodos, que generalmente no es el mismo que el puerto en la máquina virtual. Puedes acceder a la máquina virtual conectándote a la IP de un nodo y al número de puerto adecuado.

    • LoadBalancer (LB)

      Un servicio de equilibrio de carga (LoadBalancer) proporciona un conjunto de direcciones IP que pueden usar las máquinas virtuales. Este tipo de servicio expone el puerto de una máquina virtual al exterior del clúster. Para conectarse a la máquina virtual se utiliza un conjunto de direcciones IP obtenidas o especificadas.

  • Una interfaz de capa 2

    Se puede configurar una interfaz de red en los nodos del clúster como puente para permitir la conectividad de capa 2 a una máquina virtual. La interfaz de una máquina virtual se conecta al puente mediante NetworkAttachmentDefinition. Esto omite la stack de red del clúster y expone la interfaz de la máquina virtual directamente a la red con puente. Al omitir la stack de red del clúster, también omite su seguridad integrada. La máquina virtual debe protegerse de la misma manera que un servidor físico conectado a una red.

Información sobre el clúster

El clúster usado en esta publicación de blog se denomina wd y se encuentra en el dominio example.org . Consta de tres nodos de plano de control de servidores dedicados (bare metal) (wcp-0, wcp-1, wcp-2) y tres nodos de trabajo de servidores dedicados (bare metal) (wwk-0, wwk-1, wwk-2), que se encuentran en la red principal del clúster de 10.19.3.0/24.

NodoFunciónIPFQDN
wcp-0plano de control10.19.3.95wcp-0.wd.example.org
wcp-1plano de control10.19.3.94wcp-1.wd.example.org
wcp-2plano de control10.19.3.93wcp-2.wd.example.org
wwk-0nodo de trabajo10.19.3.92wwk-0.wd.example.org
wwk-1nodo de trabajo10.19.3.91wwk-1.wd.example.org
wwk-2nodo de trabajo10.19.3.90wwk-2.wd.example.org

MetalLB está configurado para proporcionar cuatro direcciones IP (10.19.3.112-115) a las máquinas virtuales desde esta red.

Los nodos del clúster tienen una interfaz de red secundaria en la red 10.19.136.0/24. Esta red secundaria tiene un servidor DHCP que proporciona direcciones IP.

El clúster tiene instalados los siguientes operadores. Todos los operadores son proporcionados por Red Hat, Inc.

OperadorMotivo de su instalación
Operador NMState de KubernetesSe usa para configurar la segunda interfaz en los nodos
OpenShift VirtualizationProporciona los mecanismos para ejecutar las máquinas virtuales.
Local StorageLo necesita el operador de OpenShift Data Foundation cuando se usan HDD locales.
Operador de MetalLBProporciona el servicio de equilibrio de carga que se utiliza en esta publicación de blog.
OpenShift Data FoundationProporciona almacenamiento para el clúster. El almacenamiento se crea con un segundo HDD en los nodos.

En el clúster se ejecutan algunas máquinas virtuales, en el espacio de nombres blog .

  • Una máquina virtual de Fedora 38 denominada fedora
  • Una máquina virtual de Red Hat Enterprise Linux 9 (RHEL9) denominada rhel9
  • Una máquina virtual de Windows 11 denominada win11

Conexión a través de la interfaz de usuario

Al ver una máquina virtual a través de la interfaz de usuario, hay varias pestañas disponibles. Todas ofrecen métodos para ver o configurar diversos aspectos relacionados con la máquina virtual. Una de ellas es la pestaña Console , la cual proporciona tres métodos para conectarse a la máquina virtual: consola de VNC, consola en serie o visor de escritorio (RDP). El método RDP solo se ofrece para las máquinas virtuales que ejecutan Microsoft Windows.

Consola de VNC

La consola de VNC siempre está disponible para cualquier máquina virtual. OpenShift Virtualization proporciona el servicio de VNC, que no requiere ninguna configuración del sistema operativo (SO) de las máquinas virtuales. Simplemente funciona.

Screenshot of VNC Console Windows 11

Consola en serie

La consola en serie debe configurarse dentro del sistema operativo de la máquina virtual. Si el sistema operativo no está configurado para enviar los resultados al puerto serial de la máquina virtual, este método de conexión no funcionará. Las imágenes de máquinas virtuales provistas por Red Hat están configuradas para enviar la información de arranque al puerto serial y proporcionar una solicitud de inicio de sesión cuando la máquina virtual finaliza su proceso de arranque. 

rhel9-serial-console-web-console-1

Visor de escritorio

Esta conexión requiere la instalación y la ejecución de un servicio de escritorio remoto (RDP) en la máquina virtual. Si eliges conectarte mediante un RDP en la pestaña "Console", el sistema indicará que actualmente no hay un servicio de RDP para la máquina virtual y te dará la opción de crear uno. Al seleccionar la opción, aparecerá una ventana emergente con la casilla de verificación "Expose RDP Service". Cuando marques esta casilla, se creará un servicio para la máquina virtual que permita las conexiones de RDP.

ui-rdp-enable-service-rdp1-win-1

Una vez creado el servicio, la pestaña "Console" proporcionará la información para la conexión de RDP 

ui-rdp-enable-service-win-1

y el botón "Launch Remote Desktop" para iniciar el escritorio remoto. Al seleccionarlo, se descargará un archivo denominado console.rdp. Si el explorador está configurado para abrir archivos .rdp , deberías poder abrir el archivo console.rdp en un cliente RDP.

Conexión mediante el comando virtctl

El comando virtctl proporciona a la VNC, a la consola en serie y al SSH acceso a la máquina virtual mediante un túnel de red a través del protocolo WebSocket.

  • El usuario que ejecuta el comando virtctl debe iniciar sesión en el clúster desde la línea de comandos.
  • Si el usuario no está en el mismo espacio de nombres que la máquina virtual, se debe especificar la opción --namespace .

La versión correcta del comando virtctl y otros clientes se puede descargar del clúster desde una URL similar a https://console-openshift-console.apps.CLUSTERNAME.CLUSTERDOMAIN/command-line-tools. También se puede descargar haciendo clic en el ícono de signo de interrogación ubicado en la parte superior de la interfaz de usuario y seleccionando Command line tools.

Consola de VNC

El comando virtctl se conecta al servidor de VNC provisto por OpenShift Virtualization. El sistema que ejecuta el comando virtctl necesita que estén instalados el comando virtctl y un cliente de VNC.

La apertura de una conexión de VNC se realiza simplemente ejecutando el comando virtctl vnc . La información sobre la conexión se muestra en el terminal, junto a la nueva sesión de la consola de VNC. 

virtctl-vnc-win11-1

Consola en serie

La conexión a la consola en serie mediante el comando virtctl se realiza ejecutando el comando virtctl console. Si la máquina virtual está configurada para enviar los resultados a su puerto serial, como se analizó anteriormente, debería aparecer el resultado del proceso de arranque o una solicitud de inicio de sesión.

$ virtctl console rhel9
Successfully connected to rhel9 console. The escape sequence is ^]


[ 8.463919] cloud-init[1145]: Cloud-init v. 22.1-7.el9_1 running 'modules:config' at Wed, 05 Apr 2023 19:05:38 +0000. Up 8.41 seconds.
[ OK ] Finished Apply the settings specified in cloud-config.
Starting Execute cloud user/final scripts...
[ 8.898813] cloud-init[1228]: Cloud-init v. 22.1-7.el9_1 running 'modules:final' at Wed, 05 Apr 2023 19:05:38 +0000. Up 8.82 seconds.
[ 8.960342] cloud-init[1228]: Cloud-init v. 22.1-7.el9_1 finished at Wed, 05 Apr 2023 19:05:38 +0000. Datasource DataSourceNoCloud [seed=/dev/vdb][dsmode=net]. Up 8.95 seconds
[ OK ] Finished Execute cloud user/final scripts.
[ OK ] Reached target Cloud-init target.
[ OK ] Finished Crash recovery kernel arming.

Red Hat Enterprise Linux 9.1 (Plow)
Kernel 5.14.0-162.18.1.el9_1.x86_64 on an x86_64

Activate the web console with: systemctl enable --now cockpit.socket

rhel9 login: cloud-user
Password:
Last login: Wed Apr 5 15:05:15 on ttyS0
[cloud-user@rhel9 ~]$

SSH

El cliente SSH se invoca con el comando virtctl ssh.  La opción -i para este comando permite al usuario especificar una clave privada para usar.

$ virtctl ssh cloud-user@rhel9-one -i ~/.ssh/id_rsa_cloud-user
Last login: Wed May 3 16:06:41 2023

[cloud-user@rhel9-one ~]$

También existe el comando virtctl scp que se puede usar para transferir archivos a una máquina virtual. Lo menciono aquí porque funciona de manera similar al comando virtctl ssh .

Reenvío de puertos

El comando virtctl también puede reenviar tráfico desde los puertos locales de un usuario hasta un puerto en la máquina virtual. Consulta la documentación de OpenShift para obtener información sobre su funcionamiento.

Uno de sus usos consiste en reenviar tu cliente OpenSSH local a la máquina virtual, ya que es más sólido y puede sustituir el cliente SSH integrado del comando virtctl.  Consulta la documentación de Kubevirt para ver un ejemplo de cómo hacerlo.

También puede resultar útil para conectarse a un servicio en una máquina virtual cuando no deseas crear un servicio de OpenShift para exponer el puerto.

Por ejemplo, tengo una máquina virtual llamada fedora-proxy con el servidor web NGINX instalado. Un script personalizado en la máquina virtual escribe algunas estadísticas en un archivo denominado process-status.out. Soy la única persona interesada en el contenido del archivo, pero me gustaría ver este archivo a lo largo del día. Puedo usar el comando virtctl port-forward para reenviar un puerto local en mi computadora portátil o de escritorio al puerto 80 de la máquina virtual. Puedo escribir un script corto que pueda recopilar los datos cuando yo lo desee.

#! /bin/bash

# Create a tunnel
virtctl port-forward vm/fedora-proxy 22080:80 &

# Need to give a little time for the tunnel to come up
sleep 1

# Get the data
curl http://localhost:22080/process-status.out

# Stop the tunnel
pkill -P $$

La ejecución del script me proporciona los datos que quiero y los limpia después de ejecutarse.

$ gather_stats.sh 
{"component":"","level":"info","msg":"forwarding tcp 127.0.0.1:22080 to 80","pos":"portforwarder.go:23","timestamp":"2023-05-04T14:27:54.670662Z"}
{"component":"","level":"info","msg":"opening new tcp tunnel to 80","pos":"tcp.go:34","timestamp":"2023-05-04T14:27:55.659832Z"}
{"component":"","level":"info","msg":"handling tcp connection for 22080","pos":"tcp.go:47","timestamp":"2023-05-04T14:27:55.689706Z"}

Test Process One Status: Bad
Test Process One Misses: 125

Test Process Two Status: Good
Test Process Two Misses: 23

Conexión a través de un puerto expuesto en la red de pods (servicios)

Servicios

Con los servicios en OpenShift, se exponen los puertos de una máquina virtual para el tráfico entrante, el cual puede provenir de otras máquinas virtuales y pods o de una fuente externa al clúster.

En esta publicación, se muestra la manera de crear tres tipos de servicios: ClusterIP, NodePort y LoadBalancer. El tipo de servicio ClusterIP no permite el acceso externo a las máquinas virtuales. Los tres tipos proporcionan acceso interno entre las máquinas virtuales y los pods. Este es el método preferido para que las máquinas virtuales dentro del clúster se comuniquen entre sí. En la siguiente tabla, se enumeran los tres tipos de servicio y su alcance de accesibilidad.

TipografíaAlcance interno del DNS interno del clústerAlcance externo
ClusterIP<service-name>.<namespace>.svc.cluster.localNinguno
NodePort<service-name>.<namespace>.svc.cluster.localDirección IP de un nodo del clúster
LoadBalancer<service-name>.<namespace>.svc.cluster.localDirección IP externa a los objetos IPAddressPools de los LoadBalancers

Los servicios se pueden crear usando el comando virtctl expose o definiéndolo en YAML. La creación de un servicio con YAML se puede realizar desde la línea de comandos o la interfaz de usuario.

Primero, definamos un servicio con el comando virtctl.

Creación de un servicio con el comando virtctl

Al usar el comando virtctl , el usuario debe iniciar sesión en el clúster. Si el usuario no está en el mismo espacio de nombres que la máquina virtual, se puede usar la opción --namespace para especificar el espacio de nombres en el que se encuentra aquella.

El comando virtctl expose vm crea un servicio que se puede usar para exponer el puerto de una máquina virtual. A continuación se presentan opciones comunes que se usan con el comando virtctl expose al crear un servicio.

  
--nameEs el nombre del servicio que se creará.
--typeEspecifica el tipo de servicio que se creará: ClusterIP, NodePort, LoadBalancer.
--portEs el número de puerto por el cual el servicio recibe el tráfico.
--target-portEs opcional. Este es el puerto de la máquina virtual que se va a exponer. Si no se especifica, es el mismo que --port.
--protocolEs opcional. Es el protocolo que el servicio debe seguir. El valor predeterminado es TCP.

El siguiente comando crea un servicio para el acceso SSH a una máquina virtual denominada RHEL9.

$ virtctl expose vm rhel9 --name rhel9-ssh --type NodePort --port 22

Observa el servicio para determinar el puerto que se usará para acceder a la máquina virtual desde fuera del clúster.

$ oc get service

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
rhel9-ssh NodePort 172.30.244.228 <none> 22:32317/TCP 3s

Eliminemos el puerto por ahora.

$ oc delete service rhel9-ssh
service "rhel9-ssh" deleted

Creación de un servicio con YAML

La creación de un servicio con YAML se puede realizar desde la línea de comandos con el comando oc create -f o con un editor en la interfaz de usuario. Cualquiera de los métodos funciona y cada uno tiene sus propias ventajas. Con la línea de comandos es más fácil crear scripts, pero la interfaz de usuario proporciona información sobre el esquema utilizado para definir un servicio.

Primero analicemos el archivo YAML, ya que es el mismo para ambos métodos.

Una definición del servicio puede exponer un solo puerto o varios. El siguiente archivo YAML es un ejemplo de definición de servicio que expone dos puertos, uno para el tráfico SSH y otro para el tráfico VNC. Los puertos se exponen como NodePort. Las explicaciones de los elementos clave se enumeran después del archivo YAML.

apiVersion: v1
kind: Service
metadata:
name: rhel-services
namespace: blog
spec:
ports:
- name: ssh
protocol: TCP
nodePort: 31798
port: 22000
targetPort: 22
- name: vnc
protocol: TCP
nodePort: 31799
port: 22900
targetPort: 5900
type: NodePort
selector:
kubevirt.io/domain: rhel9

Estas son algunas configuraciones importantes del archivo:

  
metadata.nameEs el nombre del servicio, el cual es único en su espacio de nombres.
metadata.namespaceSe refiere al espacio de nombres en el que se encuentra el servicio.
spec.ports.nameEspecifica un nombre para el puerto que se está definiendo.
spec.ports.protocolEs el protocolo del tráfico de red, TCP o UDP.
spec.ports.nodePortEs el puerto que se expone fuera del clúster y es único dentro de este.
spec.ports.portEs un puerto que se usa internamente dentro de la red de clústeres.
spec.ports.targetPortEs el puerto que expone la máquina virtual. Varias máquinas virtuales pueden exponer el mismo puerto.
spec.typeEste es el tipo de servicio que se creará. En este ejemplo usamos NodePort.
spec.selectorEs un selector que se usa para vincular el servicio a una máquina virtual. El ejemplo se vincula a una máquina virtual denominada fedora.
Creación de un servicio desde la línea de comandos

Vamos a crear los dos servicios en el archivo YAML desde la línea de comandos. El comando que se debe usar es oc create -f.

$ oc create -f service-two.yaml 
service/rhel-services created

$ oc get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
rhel-services NodePort 172.30.11.97 <none> 22000:31798/TCP,22900:31799/TCP 4s

Podemos ver que se exponen dos puertos en un solo servicio. Ahora, eliminemos el servicio con el comando oc delete service .

$ oc delete service rhel-services
service "rhel-services" deleted
Creación de un servicio desde la interfaz de usuario

Vamos a crear el mismo servicio con la interfaz de usuario. Para hacerlo, dirígete a "Networking" -> "Services" y selecciona "Create Service". Se abrirá un editor con una definición de servicio rellenada previamente y una referencia al esquema. Pega el YAML de arriba en el editor y selecciona Create para crear un servicio.

service-ui-two

Después de seleccionar Create, se mostrarán los detalles del servicio. 

service-rhel-services

Los servicios conectados a una máquina virtual también se pueden ver en la pestaña "VMs Details" o desde la línea de comandos con el comando oc get service como lo hicimos antes. Eliminaremos el servicio igual que la vez anterior.

$ oc get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
rhel-services NodePort 172.30.11.97 <none> 22000:31798/TCP,22900:31799/TCP 4s

$ oc delete service rhel-services
service "rhel-services" deleted

Creación sencilla de servicios SSH y RDP

La interfaz de usuario ofrece métodos sencillos para crear servicios SSH y RDP en máquinas virtuales.

Para habilitar SSH fácilmente, hay un menú desplegable SSH service type en la pestaña "Details" de la máquina virtual. Este menú también permite crear de manera sencilla los servicios NodePort o LoadBalancer. 

ssh-ui-dropdown

Solo debes seleccionar el tipo de servicio que quieres crear. Lo verás en la interfaz de usuario, donde también se muestra un comando que se puede usar para conectarse al servicio. 

lb-service-enabled-1

La habilitación de RDP se realiza a través de la pestaña "Console" de la máquina virtual. Si se trata de una máquina virtual basada en Windows, aparece la opción Desktop viewer en el menú desplegable de la consola. 

rdp-viewer-dropdown

Cuando la seleccionas, ves la opción Create RDP Service . 

create-rdp-ui-1

Al seleccionarla, aparecerá una ventana emergente para confirmar  Expose RDP Service. 

rdp-popup

Una vez que se crea el servicio, la pestaña "Console" muestra la información de conexión. 

rdp-connection-info

Ejemplo de conexión con un servicio ClusterIP

Los servicios de tipo ClusterIP permiten que las máquinas virtuales se conecten entre sí internamente al clúster. Esto resulta útil si una máquina virtual proporciona un servicio a otras máquinas virtuales, como una instancia de base de datos. En lugar de configurar una base de datos en una máquina virtual, expongamos el puerto SSH en la máquina virtual Fedora usando un servicio ClusterIP.

Vamos a crear un archivo YAML que crea un servicio que expone el puerto SSH de la máquina virtual Fedora internamente al clúster.

apiVersion: v1
kind: Service
metadata:
name: fedora-internal-ssh
namespace: blog
spec:
ports:
- protocol: TCP
port: 22
selector:
kubevirt.io/domain: fedora
type: ClusterIP

Apliquemos la configuración.

$ oc create -f service-fedora-ssh-clusterip.yaml 
service/fedora-internal-ssh created

$ oc get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
fedora-internal-ssh ClusterIP 172.30.202.64 <none> 22/TCP 7s

Con la máquina virtual RHEL9, podemos ver que es posible conectarse a la máquina virtual Fedora mediante SSH.

$ virtctl console rhel9
Successfully connected to rhel9 console. The escape sequence is ^]

rhel9 login: cloud-user
Password:
Last login: Wed May 10 10:20:23 on ttyS0

[cloud-user@rhel9 ~]$ ssh fedora@fedora-internal-ssh.blog.svc.cluster.local
The authenticity of host 'fedora-internal-ssh.blog.svc.cluster.local (172.30.202.64)' can't be established.
ED25519 key fingerprint is SHA256:ianF/CVuQ4kxg6kYyS0ITGqGfh6Vik5ikoqhCPrIlqM.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'fedora-internal-ssh.blog.svc.cluster.local' (ED25519) to the list of known hosts.
Last login: Wed May 10 14:25:15 2023
[fedora@fedora ~]$

Ejemplo de conexión con un servicio NodePort

Para este ejemplo, expongamos el RDP desde la máquina virtual windows11 usando un servicio NodePort para que podamos conectarnos a su escritorio y nos resulte más sencillo que usando la pestaña "Console". Esta conexión será para que la utilicen los usuarios de confianza, ya que conocerán las IP de los nodos del clúster.

Nota sobre OVNKubernetes

La última versión del instalador de OpenShift usa de manera predeterminada la stack de red de OVNKubernetes. Si el clúster ejecuta la stack de red de OVNKubernetes y se usa un servicio NodePort, el tráfico de salida de las máquinas virtuales no funcionará hasta que se habilite routingViaHost .

Se puede aplicar un sencillo parche en el clúster para habilitar el tráfico de salida cuando se usa un servicio NodePort.

$ oc patch network.operator cluster -p '{"spec": {"defaultNetwork": {"ovnKubernetesConfig": {"gatewayConfig": {"routingViaHost": true}}}}}' --type merge

$ oc get network.operator cluster -o yaml
apiVersion: operator.openshift.io/v1
kind: Network
spec:
defaultNetwork:
ovnKubernetesConfig:
gatewayConfig:
routingViaHost: true
...

Este parche no se necesita si el clúster usa la stack de red de OpenShiftSDN o se utiliza un servicio MetalLB.

Ejemplo de conexión con un servicio NodePort

Para crear el servicio NodePort, primero definámoslo en un archivo YAML.

apiVersion: v1
kind: Service
metadata:
name: win11-rdp-np
namespace: blog
spec:
ports:
- name: rdp
protocol: TCP
nodePort: 32389
port: 22389
targetPort: 3389
type: NodePort
selector:
kubevirt.io/domain: windows11

Ahora crea el servicio.

$ oc create -f service-windows11-rdp-nodeport.yaml 
service/win11-rdp-np created

$ oc get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
win11-rdp-np NodePort 172.30.245.211 <none> 22389:32389/TCP 5s

Dado que se trata de un servicio NodePort, podemos conectarnos a él mediante la IP de cualquier nodo. El comando oc get nodes muestra las direcciones IP de los nodos.

$ oc get nodes -o=custom-columns=Name:.metadata.name,IP:status.addresses[0].address
Name IP
wcp-0 10.19.3.95
wcp-1 10.19.3.94
wcp-2 10.19.3.93
wwk-0 10.19.3.92
wwk-1 10.19.3.91
wwk-2 10.19.3.90

El programa xfreerdp es un programa cliente que se puede usar para las conexiones RDP. Le indicaremos que se conecte al nodo wcp-0 mediante el puerto RDP expuesto en el clúster.

$ xfreerdp /v:10.19.3.95:32389 /u:cnvuser /p:hiddenpass

[14:32:43:813] [19743:19744] [WARN][com.freerdp.crypto] - Certificate verification failure 'self-signed certificate (18)' at stack position 0
[14:32:43:813] [19743:19744] [WARN][com.freerdp.crypto] - CN = DESKTOP-FCUALC4
[14:32:44:118] [19743:19744] [INFO][com.freerdp.gdi] - Local framebuffer format PIXEL_FORMAT_BGRX32
[14:32:44:118] [19743:19744] [INFO][com.freerdp.gdi] - Remote framebuffer format PIXEL_FORMAT_BGRA32
[14:32:44:130] [19743:19744] [INFO][com.freerdp.channels.rdpsnd.client] - [static] Loaded fake backend for rdpsnd
[14:32:44:130] [19743:19744] [INFO][com.freerdp.channels.drdynvc.client] - Loading Dynamic Virtual Channel rdpgfx
[14:32:45:209] [19743:19744] [WARN][com.freerdp.core.rdp] - pduType PDU_TYPE_DATA not properly parsed, 562 bytes remaining unhandled. Skipping.

Tenemos una conexión a la máquina virtual. 

freerdp-nodeport

Ejemplo de conexión con un servicio LoadBalancer

Primero, definamos el servicio LoadBalancer en un archivo YAML. Usaremos la máquina virtual de Windows y expondremos RDP.

apiVersion: v1
kind: Service
metadata:
name: win11-rdp-lb
namespace: blog
spec:
ports:
- name: rdp
protocol: TCP
port: 3389
targetPort: 3389
type: LoadBalancer
selector:
kubevirt.io/domain: windows11

Ahora crea el servicio. Observa que obtiene una dirección IP automáticamente.

$ oc create -f service-windows11-rdp-loadbalancer.yaml 
service/win11-rdp-lb created

$ oc get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
win11-rdp-lb LoadBalancer 172.30.125.205 10.19.3.112 3389:31258/TCP 3s

Podemos ver que nos conectamos a EXTERNAL-IP desde el servicio y el puerto RDP estándar de 3389 que expusimos mediante el servicio. El resultado del comando xfreerdp muestra que la conexión se realizó de manera correcta.

$ xfreerdp /v:10.19.3.112 /u:cnvuser /p:changeme
[15:51:21:333] [25201:25202] [WARN][com.freerdp.crypto] - Certificate verification failure 'self-signed certificate (18)' at stack position 0
[15:51:21:333] [25201:25202] [WARN][com.freerdp.crypto] - CN = DESKTOP-FCUALC4
[15:51:23:739] [25201:25202] [INFO][com.freerdp.gdi] - Local framebuffer format PIXEL_FORMAT_BGRX32
[15:51:23:739] [25201:25202] [INFO][com.freerdp.gdi] - Remote framebuffer format PIXEL_FORMAT_BGRA32
[15:51:23:752] [25201:25202] [INFO][com.freerdp.channels.rdpsnd.client] - [static] Loaded fake backend for rdpsnd
[15:51:23:752] [25201:25202] [INFO][com.freerdp.channels.drdynvc.client] - Loading Dynamic Virtual Channel rdpgfx
[15:51:24:922] [25201:25202] [WARN][com.freerdp.core.rdp] - pduType PDU_TYPE_DATA not properly parsed, 562 bytes remaining unhandled. Skipping.

No se adjunta ninguna captura de pantalla porque es la misma captura anterior.

Conexión a través de una interfaz de capa 2

Si la interfaz de la máquina virtual se usará de forma interna y no necesita exponerse públicamente, la conexión mediante NetworkAttachmentDefinition y una interfaz puente en los nodos puede ser una buena opción. Este método omite la stack de red de clústeres, lo que significa que esta no necesita procesar cada paquete de datos, lo que puede mejorar el rendimiento del tráfico de red.

Sin embargo, e método tiene algunos inconvenientes, ya que las máquinas virtuales están expuestas directamente a una red y no están protegidas por ninguna de las medidas de seguridad de los clústeres. Si una máquina virtual se ve comprometida, un intruso podría obtener acceso a las redes a las que está conectada la máquina virtual. En caso de que uses este método, debes prestar atención para garantizar la seguridad adecuada dentro del sistema operativo de la máquina virtual.

NMState

El operador NMState que proporciona Red Hat se puede usar para configurar interfaces físicas en los nodos después de implementar el clúster. Se pueden aplicar diversas configuraciones, incluidos puentes, VLAN, enlaces y más. Lo usaremos para configurar un puente en una interfaz no utilizada en cada nodo del clúster. Consulta la documentación de OpenShift para obtener más información sobre el uso del operador NMState.

Configuremos un puente sencillo en una interfaz no utilizada de los nodos. La interfaz está conectada a una red que proporciona DHCP y distribuye direcciones en la red 10.19.142.0. El siguiente archivo YAML crea un puente denominado brint en la interfaz de red ens5f1. 

---
apiVersion: nmstate.io/v1
kind: NodeNetworkConfigurationPolicy
metadata:
name: brint-ens5f1
spec:
nodeSelector:
node-role.kubernetes.io/worker: ""
desiredState:
interfaces:
- name: brint
description: Internal Network Bridge
type: linux-bridge
state: up
ipv4:
enabled: false
bridge:
options:
stp:
enabled: false
port:
- name: ens5f1

Aplica el archivo YAML para crear el puente en los nodos de trabajo.

$ oc create -f brint.yaml 
nodenetworkconfigurationpolicy.nmstate.io/brint-ens5f1 created

Usa el comando oc get nncp para ver el estado de la política NodeNetworkConfigurationPolicy y el comando oc get nnce para ver el estado de la configuración de los nodos individuales. Una vez que se aplica la configuración, el STATUS de ambos comandos muestra Available y la REASON muestra SuccesslyConfigured.

$ oc get nncp
NAME STATUS REASON
brint-ens5f1 Progressing ConfigurationProgressing

$ oc get nnce
NAME STATUS REASON
wwk-0.brint-ens5f1 Pending MaxUnavailableLimitReached
wwk-1.brint-ens5f1 Available SuccessfullyConfigured
wwk-2.brint-ens5f1 Progressing ConfigurationProgressing

NetworkAttachmentDefinition

Las máquinas virtuales no pueden conectarse directamente al puente que creamos, pero pueden conectarse a una NetworkAttachmentDefinition (NAD). El siguiente script crea una NAD denominada nad-brint que se conecta al puente brint creado en el nodo. Consulta la documentación de OpenShift para obtener una explicación sobre cómo crear la NAD.

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: nad-brint
annotations:
k8s.v1.cni.cncf.io/resourceName: bridge.network.kubevirt.io/brint
spec:
config: '{
"cniVersion": "0.3.1",
"name": "nad-brint",
"type": "cnv-bridge",
"bridge": "brint",
"macspoofchk": true
}'

Después de aplicar el archivo YAML, la NAD se puede ver usando el comando oc get network-attachment-definition .

$ oc create -f brint-nad.yaml 
networkattachmentdefinition.k8s.cni.cncf.io/nad-brint created

$ oc get network-attachment-definition
NAME AGE
nad-brint 19s

La NAD también se puede crear desde la interfaz de usuario seleccionando "Networking" -> "NetworkAttachmentDefinitions".

Ejemplo de conexión con una interfaz de capa 2

Una vez creada la NAD, se puede agregar una interfaz de red a la máquina virtual o modificar una interfaz actual para usarla. Para agregar una nueva interfaz, dirígete a los detalles de la máquina virtual y selecciona la pestaña "Network interfaces". Selecciona la opción Add network interface. Puedes modificar una interfaz que ya exista seleccionando el menú de tres puntos ubicado a la derecha. 

ui-attach-nad-1

Después de reiniciar la máquina virtual, la pestaña "Overview" de los detalles de la máquina virtual muestra la dirección IP recibida de DHCP. 

ui-rhel9-ip

Ahora podemos conectarnos a la máquina virtual usando la dirección IP que adquirió de un servidor DHCP en la interfaz puente.

$ ssh cloud-user@10.19.142.213 -i ~/.ssh/id_rsa_cloud-user

The authenticity of host '10.19.142.213 (10.19.142.213)' can't be established.
ECDSA key fingerprint is SHA256:0YNVhGjHmqOTL02mURjleMtk9lW5cfviJ3ubTc5j0Dg.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.19.142.213' (ECDSA) to the list of known hosts.

Last login: Wed May 17 11:12:37 2023
[cloud-user@rhel9 ~]$

El tráfico SSH pasa desde la máquina virtual a través del puente y sale de la interfaz de red física. El tráfico omite la red del pod y parece estar en la red en la que se ubica la interfaz puente. Cuando se conecta de esta manera, la máquina virtual no está protegida por ningún firewally se puede acceder a todos sus puertos, incluso aquellos utilizados para SSH y VNC.

Conclusión

Hemos visto diversos métodos de conexión a máquinas virtuales que se ejecutan dentro de OpenShift Virtualization. Estos métodos proporcionan modos de solucionar los problemas de las máquinas virtuales que no funcionan de forma correcta, así como de conectarse a ellas para el uso diario. Las máquinas virtuales pueden interactuar entre sí localmente dentro del clúster o los sistemas externos al clúster pueden acceder a ellas de forma directa o mediante la red de pods de clústeres. Esto facilita el traslado de los sistemas físicos y las máquinas virtuales ubicados en otras plataformas a OpenShift Virtualization.


Sobre el autor

UI_Icon-Red_Hat-Close-A-Black-RGB

Navegar por canal

automation icon

Automatización

Las últimas novedades en la automatización de la TI para los equipos, la tecnología y los entornos

AI icon

Inteligencia artificial

Descubra las actualizaciones en las plataformas que permiten a los clientes ejecutar cargas de trabajo de inteligecia artificial en cualquier lugar

open hybrid cloud icon

Nube híbrida abierta

Vea como construimos un futuro flexible con la nube híbrida

security icon

Seguridad

Vea las últimas novedades sobre cómo reducimos los riesgos en entornos y tecnologías

edge icon

Edge computing

Conozca las actualizaciones en las plataformas que simplifican las operaciones en el edge

Infrastructure icon

Infraestructura

Vea las últimas novedades sobre la plataforma Linux empresarial líder en el mundo

application development icon

Aplicaciones

Conozca nuestras soluciones para abordar los desafíos más complejos de las aplicaciones

Original series icon

Programas originales

Vea historias divertidas de creadores y líderes en tecnología empresarial