Exemplos de UDNs de rede local para virtualização d Red Hat OpenShift
Conecte máquinas virtuais de virtualização do OpenShift às sub-redes do IBM Cloud VPC usando redes CUDN Localnet para tráfego baseado em VLAN e isolado por namespace.
Este tutorial mostra como criar um exemplo de aplicativo de três camadas usando sub-redes da Nuvem Privada Virtual (VPC), Redes Definidas pelo Usuário em Cluster (CUDNs), localnets e namespaces no Red Hat OpenShift on IBM Cloud em IBM Cloud. O exemplo demonstra como conectar servidores virtuais que rodam na virtualização d Red Hat OpenShift diretamente às sub-redes da VPC, utilizando redes localnet baseadas em redes de área local virtual (VLAN). Para obter mais informações sobre tipos de rede, consulte a seção “Redes Open Virtual Network(OVN)” em Red Hat OpenShift, destinada aos administradores do vSphere®.
Visão geral
O exemplo implementa uma aplicação de três camadas com segmentos de rede separados para as camadas web, banco de dados e aplicação. Cada camada utiliza uma sub-rede VPC dedicada e uma rede local CUDN com um ID de VLAN exclusivo. As camadas da
web e do banco de dados estão localizadas em um único namespace (green), enquanto a camada de aplicação está localizada em um namespace separado (red) para demonstrar o isolamento baseado em namespace.
Detalhes da rede, do namespace e do servidor virtual
A tabela a seguir resume o exemplo de layout de rede.
| Localnet CUDN | Namespace: | ID de VLAN | Sub-rede de VPC | Servidores virtuais |
|---|---|---|---|---|
vlan20-prod |
green |
20 | 198.18.0.0/24 | plant-web00, plant-web01 |
vlan21-db |
green |
21 | 198.18.1.0/24 | plant-db00, plant-db01 |
vlan22-app |
red |
22 | 198.18.2.0/24 | plant-app00, plant-app01 |
Diagrama da configuração final
Cada bloco de código do guia pode ser copiado para um arquivo e aplicado com o comando oc apply -f
O guia utiliza “ ic ” como abreviação de “ ibmcloud ” nos comandos da CLI do IBM Cloud. Defina alias ic=ibmcloud no seu shell ou substitua ibmcloud por ic nos comandos a seguir.
Antes de Iniciar
Certifique-se de que os seguintes itens estejam disponíveis:
- Uma conta do IBM Cloud com permissão para gerenciar recursos do VPC e do Red Hat OpenShift.
- A CLI do IBM Cloud está instalada.
- Os plug-ins
container-serviceevpc-infrastructureestão instalados.
O plug-in “ container-service ” fornece os comandos “ ic ks ” que o guia utiliza para conectar interfaces de rede virtuais (VNIs) de VLAN ao cluster. O plug-in “ vpc-infrastructure ” fornece os comandos
“ ic is ” que o guia utiliza para criar sub-redes VPC, interfaces de rede virtual (VNIs) e outros componentes de infraestrutura.
Se você precisar instalar os plug-ins necessários para a CLI, use os comandos a seguir.
ibmcloud plugin install container-service
ibmcloud plugin install vpc-infrastructure
Verificar os pré-requisitos de rede
Se você estiver usando o Red Hat OpenShift on IBM Cloud, verifique os pré-requisitos de rede do OVN UDN/CUDN em Red Hat OpenShift on IBM Cloud antes de começar. O Serviço de Virtualização Red Hat OpenShift inclui esses pré-requisitos por padrão.
Criação de um namespace e de uma rede secundária CUDN Localnet para o nível verde
As redes Localnet podem coexistir com redes primárias Layer 2, redes secundárias Layer 2 e outras redes Localnet em um namespace. Cada rede local requer um VLAN ID. Atualmente, é possível usar apenas uma
sub-rede por VLAN.
A VLAN não cria um domínio de “ Layer 2 ” entre os trabalhadores. A VLAN é utilizada dentro de cada nó de trabalho, e não dentro da VPC.
Crie o namespace green e as redes vlan20-prod e vlan21-db. Aplique o manifesto com o comando oc apply -f step1.yml``.
---
apiVersion: v1
kind: Namespace
metadata:
name: green
---
apiVersion: k8s.ovn.org/v1
kind: ClusterUserDefinedNetwork
metadata:
name: "vlan20-prod"
spec:
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- "green"
network:
topology: Localnet
localnet:
role: "Secondary"
physicalNetworkName: "vpc-vlans"
ipam:
mode: Disabled
vlan:
mode: Access
access:
id: 20
---
apiVersion: k8s.ovn.org/v1
kind: ClusterUserDefinedNetwork
metadata:
name: "vlan21-db"
spec:
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- "green"
network:
topology: Localnet
localnet:
role: "Secondary"
physicalNetworkName: "vpc-vlans"
ipam:
mode: Disabled
vlan:
mode: Access
access:
id: 21
Tenha em mente as seguintes considerações:
- A sub-rede não está definida na configuração do
Localnet. - Não utilize
VLAN 1. - Utilize VLANs no intervalo de 2 a 500. As VLANs 501 a 4094 estão restritas no momento.
Criação de outro namespace e de uma rede secundária CUDN Localnet para o nível vermelho
Crie o namespace red e a rede vlan22-app. Aplique o manifesto com o comando oc apply -f step2.yml``.
---
apiVersion: v1
kind: Namespace
metadata:
name: red
---
apiVersion: k8s.ovn.org/v1
kind: ClusterUserDefinedNetwork
metadata:
name: "vlan22-app"
spec:
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- "red"
network:
topology: Localnet
localnet:
role: "Secondary"
physicalNetworkName: "vpc-vlans"
ipam:
mode: Disabled
vlan:
mode: Access
access:
id: 22
Criação de IPs reservados e VNIs na sua conta VPC
Esta etapa cria um endereço IP reservado em cada sub-rede; em seguida, cria o VNI usando esse endereço IP reservado e atribui um endereço de interface de rede virtual ( MAC address ) a cada interface de rede virtual (VNI).
Tenha em mente as seguintes considerações:
- O “
VLAN ID” não é anexado nesta etapa. - Você deve verificar qual grupo de segurança deve ser usado nesta etapa. Execute o comando
ic is sgspara listar os grupos de segurança disponíveis. - É possível executar essa etapa em lote.
- O limite é de 256 VNIs por host. Mantenha a utilização abaixo de 85% para permitir o failover e as migrações de outros hosts.
Criação de endereços IP reservados em cada sub-rede
Primeiro, crie um endereço IP reservado em cada sub-rede para seus servidores virtuais:
ic is subnet-reserved-ip-create zone1-vm-prod --address 198.18.0.20 --name zone1-web00 --auto-delete false
ic is subnet-reserved-ip-create zone1-vm-db --address 198.18.1.20 --name zone1-db00 --auto-delete false
ic is subnet-reserved-ip-create zone1-vm-app --address 198.18.2.20 --name zone1-app00 --auto-delete false
Criação de VNIs usando os endereços IP reservados
Agora, crie as VNIs usando os nomes de IP reservados na etapa anterior:
ic is virtual-network-interface-create --name zone1-web00 --allow-ip-spoofing false --auto-delete false --protocol-state-filtering-mode disabled --enable-infrastructure-nat true --subnet zone1-vm-prod --vpc my-vpc --rip zone1-web00 --sgs handclap-roundworm-clique-eccentric --resource-group-name Default
ic is virtual-network-interface-create --name zone1-db00 --allow-ip-spoofing false --auto-delete false --protocol-state-filtering-mode disabled --enable-infrastructure-nat true --subnet zone1-vm-db --vpc my-vpc --rip zone1-db00 --sgs handclap-roundworm-clique-eccentric --resource-group-name Default
ic is virtual-network-interface-create --name zone1-app00 --allow-ip-spoofing false --auto-delete false --protocol-state-filtering-mode disabled --enable-infrastructure-nat true --subnet zone1-vm-app --vpc my-vpc --rip zone1-app00 --sgs handclap-roundworm-clique-eccentric --resource-group-name Default
Anexando o VNI da VLAN ao cluster
Obtenha o ID de cada VNI que você criou na etapa anterior e, em seguida, use o plug-in “ IBM Cloud ” container-service para associar o VNI ao cluster. Você precisa do ID do cluster, que pode ser obtido executando o comando ic
ks cluster ls``.
Tenha em mente as seguintes considerações:
- Se um trabalhador ultrapassar sua cota de VNI, a operação associada falhará.
- As VNIs podem ser conectadas ao cluster (também conhecido como “
floating”) ou a um worker específico.
Procure os IDs do VNI.
ic is vni zone1-web00 | awk '$1 ~ /^ID/ {print $NF}'
ic is vni zone1-db00 | awk '$1 ~ /^ID/ {print $NF}'
ic is vni zone1-app00 | awk '$1 ~ /^ID/ {print $NF}'
Conecte cada VNI ao cluster com o ID de VLAN correspondente. Substitua o ID do cluster e os IDs de VNI pelos valores do seu ambiente.
ic ks vni attach baremetal -c <CLUSTER_ID> --vni <VNI_ID_web00> --vlan 20
ic ks vni attach baremetal -c <CLUSTER_ID> --vni <VNI_ID_db00> --vlan 21
ic ks vni attach baremetal -c <CLUSTER_ID> --vni <VNI_ID_app00> --vlan 22
Adicionando servidores virtuais aos namespaces
O manifesto a seguir é um exemplo básico de YAML para criar um servidor virtual. Você pode atualizar esse manifesto para cada namespace e rede. Você precisa do arquivo MAC address para
cada VNI que criou. Execute o comando ic is vnis para listá-los e atualize o campo macAddress no modelo para que DHCP funcione
corretamente.
Use os seguintes comandos para localizar o arquivo MAC address para cada VNI``.
ic is vni zone1-web00 | awk '/^Mac Address/ {print $NF}'
ic is vni zone1-db00 | awk '/^Mac Address/ {print $NF}'
ic is vni zone1-app00 | awk '/^Mac Address/ {print $NF}'
Exemplo de saída para cada VNI. Seus valores são diferentes:
02:00:01:00:98:A0
02:00:02:00:98:A5
02:00:02:00:98:AA
Tenha em mente as seguintes considerações antes de aplicar os manifestos:
- Atualize a senha em cada manifesto.
- Você precisa inserir uma chave pública SSH válida no campo “
ssh_authorized_keys” para fazer o login. - Não é possível usar o SSH com senha.
- Substitua todos os valores “
macAddress” pelo endereço MAC do VNI correspondente que você consultou nos comandos anteriores. O endereço de interface de rede (macAddress) deve corresponder ao VNI para que o servidor de nomes de rede (DHCP) atribua o endereço IP esperado.
Aplique cada um dos seguintes manifestos com o comando oc apply -f
- Servidor virtual
plant-web00no namespacegreenemvlan20-prod - Servidor virtual
plant-db00no namespacegreenemvlan21-db - Servidor virtual
plant-app00no namespaceredemvlan22-app
Servidor virtual plant-web00 no namespace green em vlan20-prod
# Bare YAML to stand up a Red Hat OpenShift on IBM Cloud virtual machine
---
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: "plant-web00"
namespace: "green"
annotations:
description: "example vm plant-web00"
labels:
app: "plant-web00-green-server"
kubevirt.io/dynamic-credentials-support: 'true'
vm.kubevirt.io/template: "centos-stream9-server-small"
vm.kubevirt.io/template.namespace: openshift
vm.kubevirt.io/template.revision: '1'
vm.kubevirt.io/template.version: v0.34.0
spec:
dataVolumeTemplates:
- apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
creationTimestamp: null
name: "plant-web00-green-server"
spec:
sourceRef:
kind: DataSource
name: "centos-stream9"
namespace: openshift-virtualization-os-images
storage:
resources:
requests:
storage: 30Gi
runStrategy: RerunOnFailure
template:
metadata:
annotations:
vm.kubevirt.io/flavor: "small"
vm.kubevirt.io/os: "centos-stream9"
vm.kubevirt.io/workload: "server"
labels:
kubevirt.io/domain: example
kubevirt.io/size: "small"
spec:
domain:
cpu:
cores: 1
sockets: 1
threads: 1
devices:
disks:
- disk:
bus: virtio
name: rootdisk
- disk:
bus: virtio
name: cloudinitdisk
interfaces:
- model: virtio
name: default
state: up
bridge: {}
macAddress: 02:00:01:00:98:A0 # <- replace with the MAC of VNI zone1-web00
networkInterfaceMultiqueue: true
rng: {}
memory:
guest: "2Gi"
hostname: "plant-web00"
networks:
- name: default
multus:
networkName: vlan20-prod
terminationGracePeriodSeconds: 180
volumes:
- dataVolume:
name: "plant-web00-green-server"
name: rootdisk
- cloudInitNoCloud:
userData: |-
#cloud-config
user: admin
password: "aRandomPassword9292"
ssh_authorized_keys:
- "ssh-ed25519 AAAA....BBBB....CCCCC.....DDDD put-your-key-here@example.local"
chpasswd: { expire: False }
runcmd:
- [ dnf, install, -y, epel-release ]
- [ dnf, install, -y, iperf3, nmap-ncat, darkhttpd ]
name: cloudinitdisk
Servidor virtual plant-db00 no namespace green em vlan21-db
---
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: "plant-db00"
namespace: "green"
annotations:
description: "example vm plant-db00"
labels:
app: "plant-db00-green-server"
kubevirt.io/dynamic-credentials-support: 'true'
vm.kubevirt.io/template: "centos-stream9-server-small"
vm.kubevirt.io/template.namespace: openshift
vm.kubevirt.io/template.revision: '1'
vm.kubevirt.io/template.version: v0.34.0
spec:
dataVolumeTemplates:
- apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
creationTimestamp: null
name: "plant-db00-green-server"
spec:
sourceRef:
kind: DataSource
name: "centos-stream9"
namespace: openshift-virtualization-os-images
storage:
resources:
requests:
storage: 30Gi
runStrategy: RerunOnFailure
template:
metadata:
annotations:
vm.kubevirt.io/flavor: "small"
vm.kubevirt.io/os: "centos-stream9"
vm.kubevirt.io/workload: "server"
labels:
kubevirt.io/domain: example
kubevirt.io/size: "small"
spec:
domain:
cpu:
cores: 1
sockets: 1
threads: 1
devices:
disks:
- disk:
bus: virtio
name: rootdisk
- disk:
bus: virtio
name: cloudinitdisk
interfaces:
- model: virtio
name: default
state: up
bridge: {}
macAddress: 02:00:01:00:98:A5 # <- replace with the MAC of VNI zone1-db00
networkInterfaceMultiqueue: true
rng: {}
memory:
guest: "2Gi"
hostname: "plant-db00"
networks:
- name: default
multus:
networkName: vlan21-db
terminationGracePeriodSeconds: 180
volumes:
- dataVolume:
name: "plant-db00-green-server"
name: rootdisk
- cloudInitNoCloud:
userData: |-
#cloud-config
user: admin
password: "aRandomPassword9292"
ssh_authorized_keys:
- "ssh-ed25519 AAAA....BBBB....CCCCC.....DDDD put-your-key-here@example.local"
chpasswd: { expire: False }
runcmd:
- [ dnf, install, -y, epel-release ]
- [ dnf, install, -y, iperf3, nmap-ncat, darkhttpd ]
name: cloudinitdisk
Servidor virtual plant-app00 no namespace red em vlan22-app
---
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: "plant-app00"
namespace: "red"
annotations:
description: "example vm plant-app00"
labels:
app: "plant-app00-red-server"
kubevirt.io/dynamic-credentials-support: 'true'
vm.kubevirt.io/template: "centos-stream9-server-small"
vm.kubevirt.io/template.namespace: openshift
vm.kubevirt.io/template.revision: '1'
vm.kubevirt.io/template.version: v0.34.0
spec:
dataVolumeTemplates:
- apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
creationTimestamp: null
name: "plant-app00-red-server"
spec:
sourceRef:
kind: DataSource
name: "centos-stream9"
namespace: openshift-virtualization-os-images
storage:
resources:
requests:
storage: 30Gi
runStrategy: RerunOnFailure
template:
metadata:
annotations:
vm.kubevirt.io/flavor: "small"
vm.kubevirt.io/os: "centos-stream9"
vm.kubevirt.io/workload: "server"
labels:
kubevirt.io/domain: example
kubevirt.io/size: "small"
spec:
domain:
cpu:
cores: 1
sockets: 1
threads: 1
devices:
disks:
- disk:
bus: virtio
name: rootdisk
- disk:
bus: virtio
name: cloudinitdisk
interfaces:
- model: virtio
name: default
state: up
bridge: {}
macAddress: 02:00:01:00:98:AA # <- replace with the MAC of VNI zone1-app00
networkInterfaceMultiqueue: true
rng: {}
memory:
guest: "2Gi"
hostname: "plant-app00"
networks:
- name: default
multus:
networkName: vlan22-app
terminationGracePeriodSeconds: 180
volumes:
- dataVolume:
name: "plant-app00-red-server"
name: rootdisk
- cloudInitNoCloud:
userData: |-
#cloud-config
user: admin
password: "aRandomPassword9292"
ssh_authorized_keys:
- "ssh-ed25519 AAAA....BBBB....CCCCC.....DDDD put-your-key-here@example.local"
chpasswd: { expire: False }
runcmd:
- [ dnf, install, -y, epel-release ]
- [ dnf, install, -y, iperf3, nmap-ncat, darkhttpd ]
name: cloudinitdisk
Testando a configuração da rede
IBM recomenda que você utilize um host de salto do Linux® na mesma VPC que o cluster para esses testes. No servidor host, use o SSH para se conectar a cada servidor virtual com a chave pública que você especificou na configuração do servidor virtual.
Configure o encaminhamento do agente SSH ou use uma nova chave hospedada no host de trânsito. Não copie sua chave privada entre sistemas.
Em uma sessão de terminal, use o SSH para se conectar ao servidor virtual da camada web:
ssh admin@198.18.0.20
Em outra sessão de terminal, use o SSH para se conectar ao servidor virtual da camada de banco de dados:
ssh admin@198.18.1.20
Em outra sessão de terminal, use o SSH para se conectar ao servidor virtual da camada de aplicativos:
ssh admin@198.18.2.20
Testes
Execute os testes a seguir para verificar a configuração da rede.
-
Inicie um servidor simples do tipo “ HTTP ” em cada servidor virtual.
- No site
198.18.0.20, acessedarkhttpd /usr/share/doc/bash --daemon. - No site
198.18.1.20, acessedarkhttpd /usr/share/doc/bash --daemon. - No site
198.18.2.20, acessedarkhttpd /usr/share/doc/bash --daemon.
- No site
-
No site
198.18.0.20, acessecurl -v http://198.18.1.20:8080. -
No site
198.18.1.20, acessecurl -v http://198.18.0.20:8080. -
No servidor virtual “jump”, execute
curl -v http://198.18.2.20:8080. -
No site
198.18.1.20, inicie um servidoriperf3:iperf3 -s -p 9090. -
No
198.18.0.20, conecte-se ao servidoriperf3no namespacegreen:iperf3 -c 198.18.1.20 -p 9090. -
Faça um ping de
198.18.1.20para198.18.0.20e vice-versa. -
Execute novamente as tarefas anteriores usando
198.18.2.20e o endereço IP do servidor virtual jump.
Aplicação de uma política de múltiplas redes e repetição dos testes
Aplique uma política de múltiplas redes que permita apenas o acesso TCP na porta 8080 para a rede vlan20-prod. Salve o manifesto a seguir em um arquivo chamado my-policy.yml. Em seguida, execute o comando oc
apply -f my-policy.yml para aplicá-lo.
---
apiVersion: k8s.ovn.org/v1alpha1
kind: MultiNetworkPolicy
metadata:
name: allow-8080-tcp
namespace: green
annotations:
k8s.v1.cni.cncf.io/policy-for: vlan20-prod
spec:
podSelector: {}
ingress:
- ports:
- protocol: TCP
port: 8080
egress:
- ports:
- protocol: TCP
port: 8080
policyTypes:
- Ingress
- Egress
Execute novamente os testes no endereço plant-web00, disponível em vlan20-prod. TCP A porta 8080 ainda funciona, mas outros tipos de tráfego, como ping e o teste iperf3 na porta 9090, não funcionam mais nessa conexão de rede.
Execute o comando oc delete -f my-policy.yml para remover a política e restaurar a conectividade. Os testes foram aprovados novamente.