La arquitectura de red de Red Hat OpenShift proporciona un front-end sólido y adaptable para una gran cantidad de aplicaciones en contenedores. Los servicios proporcionan un balanceo de carga simple basado en etiquetas de pod, y las rutas exponen esos servicios a la red externa. Estos conceptos funcionan muy bien para los microservicios, pero pueden resultar desafiantes para las aplicaciones que se ejecutan en máquinas virtuales en OpenShift Virtualization, donde la infraestructura de administración de servidores existente ya está implementada y supone que el acceso completo a las máquinas virtuales está siempre disponible.
En un artículo anterior, demostré cómo instalar y configurar OpenShift Virtualization, y cómo ejecutar una máquina virtual básica. En este artículo, analizo diferentes opciones para configurar su clúster de OpenShift Virtualization para permitir que las máquinas virtuales accedan a la red externa de maneras muy similares a otros hipervisores populares.
Conexión de OpenShift a redes externas
OpenShift se puede configurar para acceder a redes externas además de la red interna del pod. Esto se logra mediante el operador NMState en un clúster de OpenShift. Puede instalar el operador NMState desde OpenShift Operator Hub.
El operador NMState funciona con Multus, un plugin de CNI para OpenShift que permite que los pods se comuniquen con varias redes. Debido a que ya tenemos al menos un excelente artículo sobre Multus, prescindiré de la explicación detallada aquí y me centraré en cómo usar NMState y Multus para conectar máquinas virtuales a varias redes.
Descripción general de los componentes de NMState
Después de instalar el operador NMState, se agregaron tres CustomResoureDefinitions (CRD) que le permiten configurar interfaces de red en los nodos del clúster. Usted interactúa con estos objetos cuando configura interfaces de red en los nodos de OpenShift.
NodeNetworkState
(
nodenetworkstates.nmstate.io
) establece un objeto NodeNetworkState (NNS) para cada nodo del clúster. El contenido del objeto detalla el estado actual de la red de ese nodo.NodeNetworkConfigurationPolicies
(
nodenetworkconfigurationpolicies.nmstate.io
) es una política que le indica al operador NMState cómo configurar diferentes interfaces de red en grupos de nodos. En resumen, representan los cambios de configuración en los nodos de OpenShift.NodeNetworkConfigurationEnactments
(
nodenetworkconfigurationenactments.nmstate.io
) almacena los resultados de cada NodeNetworkConfigurationPolicy (NNCP) aplicada en objetos NodeNetworkConfigurationEnactment (NNCE). Hay un NNCE para cada nodo, para cada NNCP.
Con esas definiciones ya cubiertas, puede pasar a configurar interfaces de red en sus nodos de OpenShift. La configuración de hardware del laboratorio que estoy usando para este artículo incluye tres interfaces de red. El primero es enp1s0, que ya fue configurado durante la instalación del clúster mediante el puente br-ex. Este es el puente y la interfaz que uso en la opción n.º 1 a continuación. La segunda interfaz, enp2s0, está en la misma red que enp1s0, y la uso para configurar el puente OVSbr0 en la opción n.º 2 a continuación. Por último, la interfaz enp8s0 está conectada a una red separada sin acceso a Internet y sin servidor DHCP. Uso esta interfaz para configurar el puente de Linuxbr1 en la opción #3 a continuación.

Opción n.º 1: uso de una red externa con un solo NIC
Si sus nodos de OpenShift solo tienen un único NIC para redes, su única opción para conectar máquinas virtuales a la red externa es reutilizar el puente br-ex que es el predeterminado en todos los nodos que se ejecutan en un clúster de OVN-Kubernetes. . Eso significa que es posible que esta opción no esté disponible para los clústeres que usan la OpenShift-SDN anterior.
Debido a que no es posible volver a configurar completamente el puente br-ex sin afectar negativamente el funcionamiento básico del clúster, debe agregar una red local a ese puente en su lugar. Puede lograr esto con la siguiente configuración deNodeNetworkConfigurationPolicy
:
$ cat br-ex-nncp.yaml
apiVersion: nmstate.io/v1
kind: NodeNetworkConfigurationPolicy
metadata:
name: br-ex-network
spec:
nodeSelector:
node-role.kubernetes.io/worker: ''
desiredState:
ovn:
bridge-mappings:
- localnet: br-ex-network
bridge: br-ex
state: present
En su mayor parte, el ejemplo anterior es el mismo en todos los entornos que agregan una red local al puente br-ex. Las únicas partes que comúnmente se cambiarían son el nombre del NNCP (.metadata.name) y el nombre de la red local (.spec.desiredstate.ovn.bridge-mappings). En este ejemplo, ambos son br-ex-network, pero los nombres son arbitrarios y no necesitan ser iguales entre sí. Cualquier valor que se use para localnet se necesita cuando configura NetworkAttachmentDefinition
, así que recuerde ese valor para más adelante.
Aplique la configuración de NNCP a los nodos del clúster:
$ oc apply -f br-ex-nncp.yaml
nodenetworkconfigurationpolicy.nmstate.io/br-ex-network
Verifique el progreso de NNCP y NNCE con estos comandos:
$ oc get nncp
NAME STATUS REASON
br-ex-network Progressing ConfigurationProgressing
$ oc get nnce
NAME STATUS STATUS AGE REASON
lt01ocp10.matt.lab.br-ex-network Progressing 1s ConfigurationProgressing
lt01ocp11.matt.lab.br-ex-network Progressing 3s ConfigurationProgressing
lt01ocp12.matt.lab.br-ex-network Progressing 4s ConfigurationProgressing
En este caso, el único NNCP denominado br-ex-network ha generado un NNCE para cada nodo. Después de unos segundos, el proceso se completa:
$ oc get nncp
NAME STATUS REASON
br-ex-network Available SuccessfullyConfigured
$ oc get nnce
NAME STATUS STATUS AGE REASON
lt01ocp10.matt.lab.br-ex-network Available 83s SuccessfullyConfigured
lt01ocp11.matt.lab.br-ex-network Available 108s SuccessfullyConfigured
lt01ocp12.matt.lab.br-ex-network Available 109s SuccessfullyConfigured
Ahora puede pasar aNetworkAttachmentDefinition
, que define cómo se conectan sus máquinas virtuales a la nueva red que acaba de crear.
Configuración de NetworkAttachmentDefinition
Para crear NetworkAttachmentDefinition
en la consola de OpenShift, seleccione el proyecto donde crea máquinas virtuales (vmtest en este ejemplo) y diríjase a Networking > NetworkAttachmentDefinitions. A continuación, haga clic en el botón azul con la etiqueta Create network Attachment Definition (Crear definición de conexión de red).

La consola presenta un formulario que puede usar para crear NetworkAttachmentDefinition:

El campo Name es arbitrario, pero en este ejemplo estoy usando el mismo nombre que usé para el NNCP (br-ex-network
). Para Network Type, debe elegir OVN Kubernetes second localnet network.
Para el campo Bridge mapping (Mapeo de puentes), ingrese el nombre de la red local que configuró anteriormente (que también es br-ex-network
en este ejemplo). Debido a que el campo solicita un "mapeo de puente", es posible que tenga la tentación de ingresar "br-ex", pero de hecho, debe usar la red local que creó, que ya está conectada abr-ex
.
De manera alternativa, puede crear NetworkAttachmentDefinition
con un archivo YAML en lugar de usar la consola:
$ cat br-ex-network-nad.yaml
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: br-ex-network
namespace: vmtest
spec:
config: '{
"name":"br-ex-network",
"type":"ovn-k8s-cni-overlay",
"cniVersion":"0.4.0",
"topology":"localnet",
"netAttachDefName":"vmtest/br-ex-network"
}'
$ oc apply -f br-ex-network-nad.yaml
networkattachmentdefinition.k8s.cni.cncf.io/br-ex-network created
EnNetworkAttachmentDefinition
YAML arriba, el campo name en .spec.config es el nombre de la red local de NNCP, y netAttachDefName es el espacio de nombres/nombre que debe coincidir con los dos campos idénticos en .metadata (en este caso,vmtest/br-ex-network).
Las máquinas virtuales usan IP estáticas o DHCP para el direccionamiento IP, por lo que la gestión de direcciones IP (IPAM) en NetworkAttachmentDefinition
Configuración de NIC de máquina virtual
Para usar la nueva red externa con una máquina virtual, modifique la sección Network interfaces de la máquina virtual y seleccione la nueva vmtest/br-ex-network como el tipo Network . También es posible personalizar la dirección MAC en este formulario.
Continúe creando la máquina virtual como lo haría normalmente. Después de que se inicia la máquina virtual, su NIC virtual se conecta a la red externa. En este ejemplo, la red externa tiene un servidor DHCP, por lo que se asigna automáticamente una dirección IP y se permite el acceso a la red.
Elimine NetworkAttachmentDefinition y localnet en br-ex.
Si alguna vez desea deshacer los pasos anteriores, primero asegúrese de que ninguna máquina virtual esté usandoNetworkAttachmentDefinition
y, luego, elimínelo con Console. Alternativamente, use el comando:
$ oc delete network-attachment-definition/br-ex-network -n vmtest
networkattachmentdefinition.k8s.cni.cncf.io "br-ex-network" deleted
A continuación, elimineNodeNetworkConfigurationPolicy
. ¡Eliminar la política no deshace los cambios en los nodos de OpenShift!
$ oc delete nncp/br-ex-network
nodenetworkconfigurationpolicy.nmstate.io "br-ex-network" deleted
Al eliminar el NNCP, también se eliminan todos los NNCE asociados:
$ oc get nnce
No resources found
Por último, modifique el archivo NNCP YAML que se usó antes, pero cambie el estado de mapeo de puentes depresente
aausente
:
$ cat br-ex-nncp.yaml
apiVersion: nmstate.io/v1
kind: NodeNetworkConfigurationPolicy
metadata:
name: br-ex-network
spec:
nodeSelector:
node-role.kubernetes.io/worker: ''
desiredState:
ovn:
bridge-mappings:
- localnet: br-ex-network
bridge: br-ex
state: absent # Changed from present
Vuelva a aplicar el NNCP actualizado:
$ oc apply -f br-ex-nncp.yaml
nodenetworkconfigurationpolicy.nmstate.io/br-ex-network
$ oc get nncp
NAME STATUS REASON
br-ex-network Available SuccessfullyConfigured
$ oc get nnce
NAME STATUS STATUS AGE REASON
lt01ocp10.matt.lab.br-ex-network Available 2s SuccessfullyConfigured
lt01ocp11.matt.lab.br-ex-network Available 29s SuccessfullyConfigured
lt01ocp12.matt.lab.br-ex-network Available 30s SuccessfullyConfigured
La configuración de localnet ahora se ha eliminado. Puede eliminar el NNCP de forma segura.
Opción n.º 2: uso de una red externa con un puente de OVS en un NIC dedicado
Los nodos de OpenShift se pueden conectar a varias redes que usan diferentes NIC físicas. Si bien existen muchas opciones de configuración (como vinculación y VLAN), en este ejemplo solo estoy usando un NIC dedicado para configurar un puente OVS. Para obtener más información sobre las opciones de configuración avanzadas, como la creación de enlaces o el uso de una VLAN, consulte nuestra documentación.
Puede ver todas las interfaces de nodos con este comando (la salida se trunca aquí por conveniencia):
$ oc get nns/lt01ocp10.matt.lab -o jsonpath='{.status.currentState.interfaces[3]}' | jq
{
…
"mac-address": "52:54:00:92:BB:00",
"max-mtu": 65535,
"min-mtu": 68,
"mtu": 1500,
"name": "enp2s0",
"permanent-mac-address": "52:54:00:92:BB:00",
"profile-name": "Wired connection 1",
"state": "up",
"type": "ethernet"
}
En este ejemplo, el adaptador de red no utilizado en todos los nodos es enp2s0.
Como en el ejemplo anterior, comience con un NNCP que crea un nuevo puente OVS denominado br0
en los nodos, usando un NIC no usado (enp2s0, en este ejemplo). El NNCP se ve así:
$ cat br0-worker-ovs-bridge.yaml
apiVersion: nmstate.io/v1
kind: NodeNetworkConfigurationPolicy
metadata:
name: br0-ovs
spec:
nodeSelector:
node-role.kubernetes.io/worker: ""
desiredState:
interfaces:
- name: br0
description: |-
A dedicated OVS bridge with enp2s0 as a port
allowing all VLANs and untagged traffic
type: ovs-bridge
state: up
bridge:
options:
stp: true
port:
- name: enp2s0
ovn:
bridge-mappings:
- localnet: br0-network
bridge: br0
state: present
Lo primero que debe tener en cuenta sobre el ejemplo anterior es el campo.metadata.name, que es arbitrario e identifica el nombre del NNCP. También puede ver, cerca del final del archivo, que está agregando un mapeo de puente localnet al nuevo puente br0, tal como lo hizo con br-ex en el ejemplo de NIC único.
En el ejemplo anterior que usa br-ex como puente, era seguro asumir que todos los nodos de OpenShift tienen un puente con este nombre, por lo que aplicó el NNCP a todos los nodos trabajadores. Sin embargo, en el escenario actual, es posible tener nodos heterogéneos con diferentes nombres de NIC para las mismas redes. En ese caso, debe agregar una etiqueta a cada tipo de nodo para identificar qué configuración tiene. Luego, con.spec.nodeSelector en el ejemplo anterior, puede aplicar la configuración solo a los nodos que funcionarán con esta configuración. Para otros tipos de nodos, puede modificar NNCP ynodeSelector
, y crear el mismo puente en esos nodos, incluso cuando el nombre de NIC subyacente es diferente.
En este ejemplo, los nombres de NIC son todos iguales, por lo que puede usar el mismo NNCP para todos los nodos.
Ahora aplique el NNCP, tal como lo hizo para el ejemplo de NIC único:
$ oc apply -f br0-worker-ovs-bridge.yaml
nodenetworkconfigurationpolicy.nmstate.io/br0-ovs created
Como antes, NNCP y NNCE tardan un tiempo en crearse y aplicarse correctamente. Puede ver el nuevo puente en el NNS:
$ oc get nns/lt01ocp10.matt.lab -o jsonpath='{.status.currentState.interfaces[3]}' | jq
{
…
"port": [
{
"name": "enp2s0"
}
]
},
"description": "A dedicated OVS bridge with enp2s0 as a port allowing all VLANs and untagged traffic",
…
"name": "br0",
"ovs-db": {
"external_ids": {},
"other_config": {}
},
"profile-name": "br0-br",
"state": "up",
"type": "ovs-bridge",
"wait-ip": "any"
}
Configuración de NetworkAttachmentDefinition
El proceso de creación de una NetworkAttachmentDefinition para un puente de OVS es idéntico al ejemplo anterior de uso de un solo NIC, ya que en ambos casos está creando una asignación de puente de OVN. En el ejemplo actual, el nombre de la asignación de puentes es br0-network
, así que eso es lo que usa en el formulario de creación NetworkAttachmenDefinition
:

De manera alternativa, puede crearNetworkAttachmentDefinition
con un archivo YAML:
$ cat br0-network-nad.yaml
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: br0-network
namespace: vmtest
spec:
config: '{
"name":"br0-network",
"type":"ovn-k8s-cni-overlay",
"cniVersion":"0.4.0",
"topology":"localnet",
"netAttachDefName":"vmtest/br0-network"
}'
$ oc apply -f br0-network-nad.yaml
networkattachmentdefinition.k8s.cni.cncf.io/br0-network created
Configuración de NIC de máquina virtual
Como antes, cree una máquina virtual como de costumbre, con la nueva NetworkAttachmentDefinition
denominada vmtest/br0-network
para la red NIC.

Cuando la máquina virtual arranca, el NIC usa el puente br0 en el nodo. En este ejemplo, el NIC dedicado para br0 está en la misma red que el puente br-ex, por lo que obtiene una dirección IP de la misma subred que antes, y se permite el acceso a la red.
Elimine NetworkAttachmentDefinition y el puente OVS
El proceso para eliminar NetworkAttachmentDefinition
y el puente OVS es prácticamente el mismo que el del ejemplo anterior. Asegúrese de que ninguna máquina virtual esté usando NetworkAttachmentDefinition
y, luego, elimínelo desde la consola o la línea de comandos:
$ oc delete network-attachment-definition/br0-network -n vmtest
networkattachmentdefinition.k8s.cni.cncf.io "br0-network" deleted
A continuación, elimine NodeNetworkConfigurationPolicy
(recuerde que la eliminación de la política no deshace los cambios en los nodos de OpenShift):
$ oc delete nncp/br0-ovs
nodenetworkconfigurationpolicy.nmstate.io "br0-ovs" deleted
Al eliminar el NNCP, también se elimina el NNCE asociado:
$ oc get nnce
No resources found
Por último, modifique el archivo NNCP YAML que se usó antes, pero cambie el estado de la interfaz de "up" a "absent" y el estado de mapeo de puentes de "present" a "absent":
$ cat br0-worker-ovs-bridge.yaml
apiVersion: nmstate.io/v1
kind: NodeNetworkConfigurationPolicy
metadata:
name: br0-ovs
spec:
nodeSelector:
node-role.kubernetes.io/worker: ""
desiredState:
Interfaces:
- name: br0
description: |-
A dedicated OVS bridge with enp2s0 as a port
allowing all VLANs and untagged traffic
type: ovs-bridge
state: absent # Change this from “up” to “absent”
bridge:
options:
stp: true
port:
- name: enp2s0
ovn:
bridge-mappings:
- localnet: br0-network
bridge: br0
state: absent # Changed from present
Vuelva a aplicar el NNCP actualizado. Después de que el NNCP se haya procesado correctamente, puede eliminarlo.
$ oc apply -f br0-worker-ovs-bridge.yaml
nodenetworkconfigurationpolicy.nmstate.io/br0-ovs created
Opción n.° 3: uso de una red externa con un puente de Linux en un NIC dedicado
En las redes de Linux, los puentes de OVS y los puentes de Linux tienen el mismo propósito. La decisión de utilizar uno en lugar de otro depende en última instancia de las necesidades del entorno. Hay innumerables artículos disponibles en Internet que analizan las ventajas y desventajas de ambos tipos de puentes. En resumen, los puentes de Linux son más maduros y simples que los puentes de OVS, pero no tienen tantas funciones, mientras que los puentes de OVS tienen la ventaja de ofrecer más tipos de túneles y otras funciones modernas que los puentes de Linux, pero son un poco más difíciles de solucionar. Para los fines de OpenShift Virtualization, probablemente deba usar puentes de OVS sobre puentes de Linux de manera predeterminada debido a cosas como MultiNetworkPolicy, pero las implementaciones pueden tener éxito con cualquiera de las dos opciones.
Tenga en cuenta que cuando una interfaz de máquina virtual está conectada a un puente OVS, la MTU predeterminada es 1400. Cuando una interfaz de máquina virtual está conectada a un puente de Linux, la MTU predeterminada es 1500.Puede encontrar más información sobre el tamaño de MTU del clúster en la documentación oficial.
Configuración de nodos
Como en el ejemplo anterior, estamos usando un NIC dedicado para crear un nuevo puente de Linux. Para mantener las cosas interesantes, estoy conectando el puente de Linux a una red que no tiene un servidor DHCP para que pueda ver cómo esto afecta a las máquinas virtuales conectadas a esa red.
En este ejemplo, estoy creando un puente de Linux denominado br1 en la interfaz enp8s0, que está conectado a la red 172.16.0.0/24 que no tiene acceso a Internet ni servidor DHCP. El NNCP se ve así:
$ cat br1-worker-linux-bridge.yaml
apiVersion: nmstate.io/v1
kind: NodeNetworkConfigurationPolicy
metadata:
name: br1-linux-bridge
spec:
nodeSelector:
node-role.kubernetes.io/worker: ""
desiredState:
interfaces:
- name: br1
description: Linux bridge with enp8s0 as a port
type: linux-bridge
state: up
bridge:
options:
stp:
enabled: false
port:
- name: enp8s0
$ oc apply -f br1-worker-linux-bridge.yaml
nodenetworkconfigurationpolicy.nmstate.io/br1-worker created
Como antes, NNCP y NNCE tardan unos segundos en crearse y aplicarse correctamente.
Configuración de NetworkAttachmentDefinition
El proceso de creación de NetworkAttachmentDefinition
para un puente de Linux es un poco diferente de los dos ejemplos anteriores porque esta vez no se está conectando a una red local de OVN. Para una conexión de puente de Linux, se conecta directamente al nuevo puente. Este es el formulario de creación de NetworkAttachmenDefinition
:

En este caso, seleccione Network Type de CNV Linux bridge
y coloque el nombre del puente real en el campo Bridge name, que es br1
en este ejemplo.
Configuración de NIC de máquina virtual
Ahora cree otra máquina virtual, pero use la nueva NetworkAttachmentDefinition
denominada vmtest/br1-network
para la red NIC. Esto conecta el NIC al nuevo puente de Linux.

Cuando la máquina virtual arranca, el NIC usa el puente br1 en el nodo. En este ejemplo, el NIC dedicado está en una red sin servidor DHCP y sin acceso a Internet, así que asigne al NIC una dirección IP manual con nmcli y valide la conectividad solo en la red local.
Elimine NetworkAttachmentDefinition y el puente de Linux
Al igual que con los ejemplos anteriores, para eliminar NetworkAttachmentDefinition
y el puente de Linux, primero asegúrese de que ninguna máquina virtual esté usando NetworkAttachmentDefinition
. Elimínelo desde la consola o la línea de comandos:
$ oc delete network-attachment-definition/br1-network -n vmtest
networkattachmentdefinition.k8s.cni.cncf.io "br1-network" deleted
A continuación, elimine NodeNetworkConfigurationPolicy:
$ oc delete nncp/br1-linux-bridge
nodenetworkconfigurationpolicy.nmstate.io "br1-linux-bridge" deleted
Eliminar el NNCP también elimina todos los NNCE asociados (recuerde que eliminar la política no deshace los cambios en los nodos de OpenShift):
$ oc get nnce
No resources found
Por último, modifique el archivo NNCP YAML y cambie el estado de la interfaz deup
aabsent
:
$ cat br1-worker-linux-bridge.yaml
apiVersion: nmstate.io/v1
kind: NodeNetworkConfigurationPolicy
metadata:
name: br1-linux-bridge
spec:
nodeSelector:
node-role.kubernetes.io/worker: ""
desiredState:
interfaces:
- name: br1
description: Linux bridge with enp8s0 as a port
type: linux-bridge
state: absent # Changed from up
bridge:
options:
stp:
enabled: false
port:
- name: enp8s0
Vuelva a aplicar el NNCP actualizado. Después de que el NNCP se haya procesado correctamente, se puede eliminar.
$ oc apply -f br1-worker-linux-bridge.yaml
nodenetworkconfigurationpolicy.nmstate.io/br1-worker created
Redes avanzadas en OpenShift Virtualization
Muchos usuarios de OpenShift Virtualization pueden beneficiarse de la variedad de funciones de red avanzadas que ya están integradas en Red Hat OpenShift. Sin embargo, a medida que se migran más cargas de trabajo desde los hipervisores tradicionales, es posible que desee aprovechar la infraestructura existente. Esto puede requerir que las cargas de trabajo de OpenShift Virtualization estén conectadas directamente a sus redes externas. El operador NMState, junto con las redes Multus, ofrece un método flexible para lograr el rendimiento y la conectividad que facilitan la transición de un hipervisor tradicional a Red Hat OpenShift Virtualization.
Para obtener más información sobre OpenShift Virtualization, puede consultar otra publicación de blog mía sobre el tema o echar un vistazo al producto en nuestro sitio web. Para obtener más información sobre los temas de redes que se abordan en este artículo, consulte la documentación de Red Hat OpenShift con todos los detalles que necesita. Por último, si desea ver una demostración o usar OpenShift Virtualization usted mismo, comuníquese con su ejecutivo de cuentas.
Sobre el autor
Matthew Secaur is a Red Hat Principal Technical Account Manager (TAM) for Canada and the Northeast United States. He has expertise in Red Hat OpenShift Platform, Red Hat OpenShift Virtualization, Red Hat OpenStack Platform, and Red Hat Ceph Storage.
Más similar
Navegar por canal
Automatización
Las últimas novedades en la automatización de la TI para los equipos, la tecnología y los entornos
Inteligencia artificial
Descubra las actualizaciones en las plataformas que permiten a los clientes ejecutar cargas de trabajo de inteligecia artificial en cualquier lugar
Nube híbrida abierta
Vea como construimos un futuro flexible con la nube híbrida
Seguridad
Vea las últimas novedades sobre cómo reducimos los riesgos en entornos y tecnologías
Edge computing
Conozca las actualizaciones en las plataformas que simplifican las operaciones en el edge
Infraestructura
Vea las últimas novedades sobre la plataforma Linux empresarial líder en el mundo
Aplicaciones
Conozca nuestras soluciones para abordar los desafíos más complejos de las aplicaciones
Programas originales
Vea historias divertidas de creadores y líderes en tecnología empresarial