A arquitetura de rede do Red Hat OpenShift oferece um front-end robusto e escalável para inúmeras aplicações em containers. Os serviços fornecem balanceamento de carga simples com base em tags de pod e as rotas expõem esses serviços à rede externa. Esses conceitos funcionam muito bem para microsserviços, mas podem ser desafiadores para aplicativos executados em máquinas virtuais no OpenShift Virtualization, onde a infraestrutura de gerenciamento de servidor existente já está em vigor e pressupõe que o acesso total às máquinas virtuais está sempre disponível.
Em um artigo anterior, demonstrei como instalar e configurar o OpenShift Virtualization e como executar uma máquina virtual básica. Neste artigo, discuto diferentes opções para configurar seu cluster do OpenShift Virtualization para permitir que máquinas virtuais acessem a rede externa de maneiras muito semelhantes a outros hipervisores populares.
Conexão do OpenShift a redes externas
O OpenShift pode ser configurado para acessar redes externas além da rede interna do pod. Isso é feito usando o operador NMState em um cluster do OpenShift. Você pode instalar o operador NMState a partir do OpenShift Operator Hub.
O operador NMState funciona com o Multus, um plugin da CNI para o OpenShift que permite que os pods se comuniquem com várias redes. Como já temos pelo menos um ótimo artigo sobre o Multus, não vou dar a explicação detalhada aqui, mas vou me concentrar em como usar o NMState e o Multus para conectar máquinas virtuais a várias redes.
Visão geral dos componentes do NMState
Após instalar o operador NMState, há três CustomResoureDefinitions (CRD) adicionadas que permitem configurar interfaces de rede nos nós do cluster. Você interage com esses objetos quando configura interfaces de rede nos nós do OpenShift.
NodeNetworkState
(
nodenetworkstates.nmstate.io
) estabelece um objeto NodeNetworkState (NNS) para cada nó do cluster. O conteúdo do objeto detalha o estado atual da rede desse nó.NodeNetworkConfigurationPolicies
(
nodenetworkconfigurationpolicies.nmstate.io
) é uma política que informa ao operador NMState como configurar diferentes interfaces de rede em grupos de nós. Em resumo, eles representam as alterações de configuração nos nós do OpenShift.NodeNetworkConfigurationEnactments
(
nodenetworkconfigurationenactments.nmstate.io
) armazena os resultados de cada NodeNetworkConfigurationPolicy (NNCP) aplicada em objetos NodeNetworkConfigurationEnactment (NNCE). Há uma NNCE para cada nó, para cada NNCP.
Com essas definições resolvidas, você pode configurar as interfaces de rede nos nós do OpenShift. A configuração de hardware do laboratório que estou usando para este artigo inclui três interfaces de rede. O primeiro é enp1s0, já configurado durante a instalação do cluster usando a ponte br-ex. Essa é a bridge e a interface que uso na Option #1 abaixo. A segunda interface, enp2s0, está na mesma rede que enp1s0, e eu a uso para configurar a bridge OVS br0 na Option #2 abaixo. Por fim, a interfaceenp8s0 é conectada a uma rede separada sem acesso à Internet e sem servidor DHCP. Uso essa interface para configurar a bridge Linux br1 na Option #3 abaixo.

Opção 1: usar uma rede externa com uma única NIC
Se os nós do OpenShift tiverem apenas uma NIC para rede, sua única opção para conectar máquinas virtuais à rede externa será reutilizar a bridge br-ex, que é o padrão em todos os nós em execução em um cluster do OVN-Kubernetes. Isso significa que essa opção pode não estar disponível para clusters usando o Openshift-SDN mais antigo.
Como não é possível reconfigurar completamente a bridge br-ex sem afetar negativamente a operação básica do cluster, você deve adicionar uma rede local a essa bridge. Você pode fazer isso com a seguinte configuração NodeNetworkConfigurationPolicy
:
$ 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
Na maioria das vezes, o exemplo acima é o mesmo em todos os ambientes que adicionam uma rede local à bridge br-ex. As únicas partes que normalmente seriam alteradas são o nome da NNCP (.metadata.name) e o nome da localnet (.spec.desiredstate.ovn.bridge-mappings). Neste exemplo, ambos são br-ex-network, mas os nomes são arbitrários e não precisam ser iguais. Qualquer valor usado par alocalnet é necessário quando você configura o NetworkAttachmentDefinition
, então lembre-se desse valor para mais tarde!
Aplique a configuração da NNCP aos nós do cluster:
$ oc apply -f br-ex-nncp.yaml
nodenetworkconfigurationpolicy.nmstate.io/br-ex-network
Verifique o progresso da NNCP e da NNCE com estes 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
Nesse caso, a única NNCP chamada br-ex-network gerou uma NNCE para cada nó. Após alguns segundos, o processo é concluído:
$ 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
Agora você pode passar para o NetworkAttachmentDefinition
, que define como suas máquinas virtuais se conectam à nova rede que você acabou de criar.
Configuração NetworkAttachmentDefinition
Para criar umNetworkAttachmentDefinition
no console do OpenShift, selecione o projeto no qual você cria máquinas virtuais (vmtest neste exemplo) e navegue até Networking > NetworkAttachmentDefinitions. Em seguida, clique no botão azul com o rótulo Create Network Attachment Definition.

O Console apresenta um formulário que você pode usar para criar o NetworkAttachmentDefinition:

O campoName é arbitrário, mas, neste exemplo, estou usando o mesmo nome que usei para a NNCP (br-ex-network
). Para Network Type, você deve escolher rede localnet secundária OVN Kubernetes.
No campo Bridge mapping, digite o nome da rede local que você configurou anteriormente (que também é br-ex-network
neste exemplo). Como o campo está solicitando um "mapeamento de bridge", você pode ficar tentado a inserir "br-ex, mas, na verdade, deve usar o localnet que criou, já conectado a br-ex
.
Como alternativa, você pode criar o NetworkAttachmentDefinition
usando um arquivo YAML em vez de usar o console:
$ 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
No YAML NetworkAttachmentDefinition
acima, o campo name em .spec.config é o nome da localnet da NNCP, e netAttachDefName é o namespace/nome que deve corresponder aos dois campos idênticos no .metadata (neste caso,vmtest/br-ex-network).
As máquinas virtuais usam IPs estáticos ou DHCP para endereçamento IP, portanto, o IP Address Management (IPAM) em um NetworkAttachmentDefinition
Configuração de NIC de máquina virtual
Exclua o NetworkAttachmentDefinition e o localnet em br-ex
$ oc delete network-attachment-definition/br-ex-network -n vmtest
networkattachmentdefinition.k8s.cni.cncf.io "br-ex-network" deleted
$ oc delete nncp/br-ex-network
nodenetworkconfigurationpolicy.nmstate.io "br-ex-network" deleted
A exclusão da NNCP também exclui todas as NNCE associadas:
$ oc get nnce
No resources found
$ 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
Aplique novamente a NNCP atualizada:
$ 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
A configuração localnet foi removida. Você pode excluir com segurança a NNCP.
Opção 2: usar uma rede externa com uma bridge OVS em uma NIC dedicada
Os nós do OpenShift podem ser conectados a várias redes que usam diferentes NICs físicas. Embora existam muitas opções de configuração (como bonding e VLANs), neste exemplo estou apenas usando uma NIC dedicada para configurar uma bridge OVS. Para obter mais informações sobre opções de configuração avançadas, como a criação de vínculos ou o uso de uma VLAN, consulte nossadocumentação.
Você pode ver todas as interfaces de nó usando este comando (a saída é truncada aqui por conveniência):
$ 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"
}
Neste exemplo, o adaptador de rede não utilizado em todos os nós éenp2s0.
Como no exemplo anterior, comece com uma NNCP que cria uma nova bridge OVS chamadabr0
nos nós, usando uma NIC não utilizada (enp2s0, neste exemplo). A NNCP tem a seguinte aparência:
$ 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
A primeira coisa a observar sobre o exemplo acima é o campo .metadata.name, que é arbitrário e identifica o nome da NNCP. Você também pode ver, perto do final do arquivo, que está adicionando um mapeamento de bridge localnet à nova bridge br0, assim como fez com br-ex no exemplo de NIC única.
No exemplo anterior, usando br-ex como uma bridge, era seguro supor que todos os nós do OpenShift têm uma bridge com esse nome, então você aplicou a NNCP a todos os nós de trabalho. No entanto, no cenário atual, é possível ter nós heterogêneos com diferentes nomes de NIC para as mesmas redes. Nesse caso, você deve adicionar um rótulo a cada tipo de nó para identificar qual configuração ele tem. Em seguida, usando o .spec.nodeSelector no exemplo acima, você pode aplicar a configuração somente aos nós que funcionarão com essa configuração. Para outros tipos de nó, você pode modificar a NNCP e o nodeSelector
e criar a mesma bridge nesses nós, mesmo quando o nome da NIC subjacente for diferente.
Neste exemplo, os nomes de NIC são todos iguais, então você pode usar a mesma NNCP para todos os nós.
Agora aplique a NNCP, assim como você fez para o exemplo de NIC única:
$ oc apply -f br0-worker-ovs-bridge.yaml
nodenetworkconfigurationpolicy.nmstate.io/br0-ovs created
Como antes, a NNCP e a NNCE levam algum tempo para serem criadas e aplicadas com êxito. Você pode ver a nova bridge no 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"
}
Configuração de NetworkAttachmentDefinition
O processo de criação de um NetworkAttachmentDefinition para uma bridge OVS é idêntico ao do exemplo anterior de uso de uma única NIC, porque em ambos os casos você está criando um mapeamento de bridge OVN. No exemplo atual, o nome do mapeamento de bridge ébr0-network
, então é isso que você usará no formulário de criação NetworkAttachmenDefinition
:

Como alternativa, você pode criar o NetworkAttachmentDefinition
usando um arquivo 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
Configuração de NIC de máquina virtual
Como anteriormente, crie uma máquina virtual normalmente, usando o novo NetworkAttachmentDefinition
chamado vmtest/br0-network
para a rede NIC.

Quando a máquina virtual é inicializada, a NIC usa a bridge br0 no nó. Neste exemplo, a NIC dedicada para br0 está na mesma rede que a bridge br-ex, então você obtém um endereço IP da mesma sub-rede de antes, e o acesso à rede é permitido.
Exclua a ponte NetworkAttachmentDefinition e OVS
O processo para excluir a bridge NetworkAttachmentDefinition
e OVS é praticamente o mesmo do exemplo anterior. Certifique-se de que nenhuma máquina virtual está usando o NetworkAttachmentDefinition
e, em seguida, exclua-o do Console ou da linha de comando:
$ oc delete network-attachment-definition/br0-network -n vmtest
networkattachmentdefinition.k8s.cni.cncf.io "br0-network" deleted
Em seguida, exclua a NodeNetworkConfigurationPolicy
(lembre-se de que excluir a política não desfaz as alterações nos nós do OpenShift):
$ oc delete nncp/br0-ovs
nodenetworkconfigurationpolicy.nmstate.io "br0-ovs" deleted
A exclusão da NNCP também exclui a NNCE associada:
$ oc get nnce
No resources found
Por fim, modifique o arquivo YAML NNCP que foi usado antes, mas altere o estado da interface de “up” para “absent” e o estado do mapeamento de bridge de “present” para “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
Aplique novamente a NNCP atualizada. Depois que a NNCP for processada com êxito, você poderá excluí-la.
$ oc apply -f br0-worker-ovs-bridge.yaml
nodenetworkconfigurationpolicy.nmstate.io/br0-ovs created
Opção 3: usar uma rede externa com uma bridge Linux em uma NIC dedicada
Na rede Linux, as bridges OVS e Linux têm a mesma finalidade. A decisão de usar um em vez do outro se resume às necessidades do ambiente. Há uma infinidade de artigos disponíveis na internet que discutem as vantagens e desvantagens dos dois tipos de bridge. Em resumo, as bridges Linux são mais maduras e mais simples do que as bridges OVS, mas não são tão ricas em recursos. Enquanto as bridges OVS têm a vantagem de oferecer mais tipos de túnel e outros recursos modernos do que as bridges Linux, elas são um pouco mais difíceis de solucionar problemas. Para os fins do OpenShift Virtualization, você provavelmente deve usar como padrão o uso de bridges OVS em vez de bridges Linux devido a elementos como MultiNetworkPolicy, mas as implantações podem ser bem-sucedidas com qualquer uma das opções.
Observe que, quando uma interface de máquina virtual é conectada a uma bridge OVS, a MTU padrão é 1400. Quando uma interface de máquina virtual é conectada a uma bridge Linux, a MTU padrão é 1500. Mais informações sobre o tamanho da MTU do cluster podem ser encontradas na documentação oficial.
Configuração do nó
Como no exemplo anterior, estamos usando uma NIC dedicada para criar uma nova bridge Linux. Para manter as coisas interessantes, estou conectando a bridge Linux a uma rede que não tem um servidor DHCP para que você possa ver como isso afeta as máquinas virtuais conectadas a essa rede.
Neste exemplo, estou criando uma bridge Linux chamada br1 na interface enp8s0, que está anexada à rede 172.16.0.0/24 que não tem acesso à Internet ou servidor DHCP. A NNCP tem a seguinte aparência:
$ 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, a NNCP e a NNCE levam alguns segundos para serem criadas e aplicadas com êxito.
Configuração de NetworkAttachmentDefinition
O processo de criação de um NetworkAttachmentDefinition
para uma bridge Linux é um pouco diferente dos dois exemplos anteriores porque você não está se conectando a uma localnet OVN desta vez. Para uma conexão de bridge Linux, você se conecta diretamente à nova bridge. Aqui está o formulário de criação do NetworkAttachmenDefinition
:

Nesse caso, selecione o Network Type da CNV Linux bridge
e coloque o nome da bridge real no campo Bridge name, que é br1
neste exemplo.
Configuração de NIC de máquina virtual
Agora crie outra máquina virtual, mas use o novo NetworkAttachmentDefinition
chamado vmtest/br1-network
para a rede NIC. Isso conecta a NIC à nova bridge Linux.

Quando a máquina virtual é inicializada, a NIC usa a bridge br1 no nó. Neste exemplo, a NIC dedicada está em uma rede sem servidor DHCP e sem acesso à Internet. Por isso, dê à NIC um endereço IP manual usando nmcli e valide a conectividade somente na rede local.
Exclua o NetworkAttachmentDefinition e a bridge Linux
Como nos exemplos anteriores, para excluir o NetworkAttachmentDefinition
e a bridge Linux, primeiro certifique-se de que nenhuma máquina virtual esteja usando o NetworkAttachmentDefinition
. Exclua-o do Console ou da linha de comando:
$ oc delete network-attachment-definition/br1-network -n vmtest
networkattachmentdefinition.k8s.cni.cncf.io "br1-network" deleted
Em seguida, exclua a NodeNetworkConfigurationPolicy:
$ oc delete nncp/br1-linux-bridge
nodenetworkconfigurationpolicy.nmstate.io "br1-linux-bridge" deleted
Excluir a NNCP também exclui todas as NNCE associadas (lembre-se de que excluir a política não desfaz as alterações nos nós do OpenShift):
$ oc get nnce
No resources found
Por fim, modifique o arquivo YAML NNCP, alterando o estado da interface de up
para absent
:
$ 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
Aplique novamente a NNCP atualizada. Depois que a NNCP for processada com êxito, ela poderá ser excluída.
$ oc apply -f br1-worker-linux-bridge.yaml
nodenetworkconfigurationpolicy.nmstate.io/br1-worker created
Redes avançadas no OpenShift Virtualization
Muitos usuários do OpenShift Virtualization podem se beneficiar da variedade de funcionalidades avançadas de rede já integradas ao Red Hat OpenShift. No entanto, à medida que mais cargas de trabalho são migradas dos hipervisores tradicionais, convém aproveitar a infraestrutura existente. Isso pode exigir que as cargas de trabalho do OpenShift Virtualization sejam conectadas diretamente a suas redes externas. O operador NMState, em conjunto com a rede Multus, oferece um método flexível para obter desempenho e conectividade para facilitar a transição de um hipervisor tradicional para o Red Hat OpenShift Virtualization.
Para saber mais sobre o OpenShift Virtualization, confira outro post meu no blog sobre o tópicoou dê uma olhada na solução em nosso site. Para mais informações sobre os tópicos de rede abordados neste artigo, a documentação do Red Hat OpenShift tem todos os detalhes de que você precisa. Por fim, se você quiser assistir a uma demonstração ou usar o OpenShift Virtualization, entre em contato com seu executivo de contas.
Sobre o 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.
Mais como este
Navegue por canal
Automação
Últimas novidades em automação de TI para empresas de tecnologia, equipes e ambientes
Inteligência artificial
Descubra as atualizações nas plataformas que proporcionam aos clientes executar suas cargas de trabalho de IA em qualquer ambiente
Nuvem híbrida aberta
Veja como construímos um futuro mais flexível com a nuvem híbrida
Segurança
Veja as últimas novidades sobre como reduzimos riscos em ambientes e tecnologias
Edge computing
Saiba quais são as atualizações nas plataformas que simplificam as operações na borda
Infraestrutura
Saiba o que há de mais recente na plataforma Linux empresarial líder mundial
Aplicações
Conheça nossas soluções desenvolvidas para ajudar você a superar os desafios mais complexos de aplicações
Virtualização
O futuro da virtualização empresarial para suas cargas de trabalho on-premise ou na nuvem