documentation.suse.com / Documentação do SUSE Edge / Componentes / Rede de borda

12 Rede de borda

Esta seção descreve a abordagem de configuração de rede na solução SUSE Edge. Vamos mostrar como configurar o NetworkManager no SUSE Linux Micro de maneira declarativa e explicar como as ferramentas relacionadas são integradas.

12.1 Visão geral do NetworkManager

O NetworkManager é uma ferramenta que gerencia a conexão de rede principal e outras interfaces de conexão.

O NetworkManager armazena as configurações de rede como arquivos de conexão que contêm o estado desejado. Essas conexões são armazenadas como arquivos no diretório /etc/NetworkManager/system-connections/.

Os detalhes sobre o NetworkManager estão disponíveis na documentação do SUSE Linux Micro.

12.2 Visão geral do nmstate

O nmstate é uma biblioteca muito usada (com uma ferramenta CLI auxiliar) que oferece uma API declarativa para configurações de rede usando um esquema predefinido.

Os detalhes sobre o nmstate estão disponíveis na documentação upstream.

12.3 Inserir: NetworkManager Configurator (nmc)

As opções de personalização de rede no SUSE Edge são obtidas por uma ferramenta CLI chamada NetworkManager Configurator, ou nmc na forma abreviada, que aproveita a funcionalidade da biblioteca nmstate e, desse modo, é totalmente capaz de configurar endereços IP estáticos, servidores DNS, VLANs, vínculos, pontes etc. Essa ferramenta permite gerar configurações de rede com base em estados desejados predefinidos e aplicá-las a vários nós de maneira automatizada.

Os detalhes sobre o NetworkManager Configurator (nmc) estão disponíveis no repositório upstream.

12.4 Como o SUSE Edge usa o NetworkManager Configurator?

O SUSE Edge utiliza o nmc para as personalizações de rede em diversos modelos de provisionamento:

12.5 Configurando com o Edge Image Builder

O Edge Image Builder (EIB) é uma ferramenta que permite configurar vários hosts com uma única imagem de sistema operacional. Nesta seção, vamos mostrar como usar uma abordagem declarativa para descrever os estados da rede desejados, como eles são convertidos nas respectivas conexões do NetworkManager e, em seguida, aplicados durante o processo de provisionamento.

12.5.1 Pré-requisitos

Se você está seguindo este guia, já deve ter os seguintes itens disponíveis:

  • Host físico (ou máquina virtual) AMD64/Intel 64 com SLES 15 SP6 ou openSUSE Leap 15.6

  • Runtime de contêiner disponível (por exemplo, Podman)

  • Cópia da imagem RAW do SUSE Linux Micro 6.1 disponível aqui

12.5.2 Obtendo a imagem de contêiner do Edge Image Builder

A imagem de contêiner do EIB está disponível publicamente e pode ser baixada do registro SUSE Edge executando o seguinte comando:

podman pull registry.suse.com/edge/3.3/edge-image-builder:1.2.1

12.5.3 Criando o diretório de configuração de imagem

Vamos começar pela criação do diretório de configuração:

export CONFIG_DIR=$HOME/eib
mkdir -p $CONFIG_DIR/base-images

Agora vamos mover a cópia da imagem base baixada para o diretório de configuração:

mv /path/to/downloads/SL-Micro.x86_64-6.1-Base-GM.raw $CONFIG_DIR/base-images/
Nota
Nota

O EIB nunca modifica a entrada da imagem base, ele cria uma nova com as respectivas modificações.

Neste momento, o diretório de configuração deve ter a seguinte aparência:

└── base-images/
    └── SL-Micro.x86_64-6.1-Base-GM.raw

12.5.4 Criando o arquivo de definição de imagem

O arquivo de definição descreve a maioria das opções configuráveis que o Edge Image Builder suporta.

Vamos começar com um arquivo de definição bem básico para nossa imagem de sistema operacional:

cat << EOF > $CONFIG_DIR/definition.yaml
apiVersion: 1.2
image:
  arch: x86_64
  imageType: raw
  baseImage: SL-Micro.x86_64-6.1-Base-GM.raw
  outputImageName: modified-image.raw
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
EOF

A seção image é obrigatória e especifica a imagem de entrada, sua arquitetura e tipo, além do nome da imagem de saída. A seção operatingSystem é opcional e contém a configuração para permitir o login nos sistemas provisionados com nome de usuário/senha root/eib.

Nota
Nota

Você pode usar sua própria senha criptografada executando openssl passwd -6 <senha>.

Neste momento, o diretório de configuração deve ter a seguinte aparência:

├── definition.yaml
└── base-images/
    └── SL-Micro.x86_64-6.1-Base-GM.raw

12.5.5 Definindo as configurações de rede

As configurações de rede desejadas não fazem parte do arquivo de definição da imagem que acabamos de criar. Vamos agora preenchê-las no diretório especial network/. Para criá-lo:

mkdir -p $CONFIG_DIR/network

Como já foi mencionado, a ferramenta NetworkManager Configurator (nmc) espera uma entrada no formato de esquema predefinido. Você encontra como configurar uma ampla variedade de opções de rede na documentação de exemplos upstream do NMState.

Esse guia explica como configurar a rede em três nós diferentes:

  • Um nó que usa duas interfaces Ethernet

  • Um nó que usa vínculo de rede

  • Um nó que usa ponte de rede

Atenção
Atenção

O uso de configurações de rede completamente diferentes não é recomendado em builds de produção, especialmente na configuração de clusters Kubernetes. Em geral, as configurações de rede devem ser homogêneas entre os nós ou, pelo menos, entre as funções em um determinado cluster. Este guia inclui diversas opções apenas para servir como referência de exemplo.

Nota
Nota

No exemplo abaixo, foi considerada a rede padrão libvirt com um intervalo de endereços IP 192.168.122.1/24. Ajuste-a de acordo se for diferente em seu ambiente.

Vamos criar os estados desejados para o primeiro nó, que será chamado de node1.suse.com:

cat << EOF > $CONFIG_DIR/network/node1.suse.com.yaml
routes:
  config:
    - destination: 0.0.0.0/0
      metric: 100
      next-hop-address: 192.168.122.1
      next-hop-interface: eth0
      table-id: 254
    - destination: 192.168.122.0/24
      metric: 100
      next-hop-address:
      next-hop-interface: eth0
      table-id: 254
dns-resolver:
  config:
    server:
      - 192.168.122.1
      - 8.8.8.8
interfaces:
  - name: eth0
    type: ethernet
    state: up
    mac-address: 34:8A:B1:4B:16:E1
    ipv4:
      address:
        - ip: 192.168.122.50
          prefix-length: 24
      dhcp: false
      enabled: true
    ipv6:
      enabled: false
  - name: eth3
    type: ethernet
    state: down
    mac-address: 34:8A:B1:4B:16:E2
    ipv4:
      address:
        - ip: 192.168.122.55
          prefix-length: 24
      dhcp: false
      enabled: true
    ipv6:
      enabled: false
EOF

Nesse exemplo, definimos um estado desejado de duas interfaces Ethernet (eth0 e eth3), os endereços IP solicitados, o roteamento e a resolução DNS.

Atenção
Atenção

Garanta que os endereços MAC de todas as interfaces Ethernet sejam listados. Eles são usados durante o processo de provisionamento como identificadores dos nós e servem para determinar quais configurações devem ser aplicadas. É dessa forma que podemos configurar vários nós usando uma única imagem ISO ou RAW.

O próximo é o segundo nó que será chamado de node2.suse.com e usará vínculo de rede:

cat << EOF > $CONFIG_DIR/network/node2.suse.com.yaml
routes:
  config:
    - destination: 0.0.0.0/0
      metric: 100
      next-hop-address: 192.168.122.1
      next-hop-interface: bond99
      table-id: 254
    - destination: 192.168.122.0/24
      metric: 100
      next-hop-address:
      next-hop-interface: bond99
      table-id: 254
dns-resolver:
  config:
    server:
      - 192.168.122.1
      - 8.8.8.8
interfaces:
  - name: bond99
    type: bond
    state: up
    ipv4:
      address:
        - ip: 192.168.122.60
          prefix-length: 24
      enabled: true
    link-aggregation:
      mode: balance-rr
      options:
        miimon: '140'
      port:
        - eth0
        - eth1
  - name: eth0
    type: ethernet
    state: up
    mac-address: 34:8A:B1:4B:16:E3
    ipv4:
      enabled: false
    ipv6:
      enabled: false
  - name: eth1
    type: ethernet
    state: up
    mac-address: 34:8A:B1:4B:16:E4
    ipv4:
      enabled: false
    ipv6:
      enabled: false
EOF

Nesse exemplo, definimos um estado desejado de duas interfaces Ethernet (eth0 e eth1) que não habilitam endereçamento IP, além de um vínculo com política round robin e o respectivo endereço que será usado para encaminhar o tráfego de rede.

Por fim, vamos criar o terceiro e último arquivo de estado desejado, que usará uma ponte de rede e será chamado de node3.suse.com:

cat << EOF > $CONFIG_DIR/network/node3.suse.com.yaml
routes:
  config:
    - destination: 0.0.0.0/0
      metric: 100
      next-hop-address: 192.168.122.1
      next-hop-interface: linux-br0
      table-id: 254
    - destination: 192.168.122.0/24
      metric: 100
      next-hop-address:
      next-hop-interface: linux-br0
      table-id: 254
dns-resolver:
  config:
    server:
      - 192.168.122.1
      - 8.8.8.8
interfaces:
  - name: eth0
    type: ethernet
    state: up
    mac-address: 34:8A:B1:4B:16:E5
    ipv4:
      enabled: false
    ipv6:
      enabled: false
  - name: linux-br0
    type: linux-bridge
    state: up
    ipv4:
      address:
        - ip: 192.168.122.70
          prefix-length: 24
      dhcp: false
      enabled: true
    bridge:
      options:
        group-forward-mask: 0
        mac-ageing-time: 300
        multicast-snooping: true
        stp:
          enabled: true
          forward-delay: 15
          hello-time: 2
          max-age: 20
          priority: 32768
      port:
        - name: eth0
          stp-hairpin-mode: false
          stp-path-cost: 100
          stp-priority: 32
EOF

Neste momento, o diretório de configuração deve ter a seguinte aparência:

├── definition.yaml
├── network/
│   │── node1.suse.com.yaml
│   │── node2.suse.com.yaml
│   └── node3.suse.com.yaml
└── base-images/
    └── SL-Micro.x86_64-6.1-Base-GM.raw
Nota
Nota

Os nomes dos arquivos no diretório network/ são intencionais e correspondem aos nomes de host que serão definidos durante o processo de provisionamento.

12.5.6 Criando a imagem de sistema operacional

Agora que todas as configurações necessárias foram definidas, podemos criar a imagem executando simplesmente:

podman run --rm -it -v $CONFIG_DIR:/eib registry.suse.com/edge/3.3/edge-image-builder:1.2.1 build --definition-file definition.yaml

A saída deve ter uma aparência semelhante a esta:

Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Systemd ...................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Embedded Artifact Registry ... [SKIPPED]
Keymap ....................... [SUCCESS]
Kubernetes ................... [SKIPPED]
Certificates ................. [SKIPPED]
Building RAW image...
Kernel Params ................ [SKIPPED]
Image build complete!

O trecho acima nos informa que o componente Network foi configurado com sucesso, e podemos prosseguir com o provisionamento dos nós de borda.

Nota
Nota

É possível inspecionar um arquivo de registro (network-config.log) e os respectivos arquivos de conexão do NetworkManager no diretório _build resultante abaixo do diretório com a marcação de data e hora da execução da imagem.

12.5.7 Provisionando os nós de borda

Vamos copiar a imagem RAW resultante:

mkdir edge-nodes && cd edge-nodes
for i in {1..4}; do cp $CONFIG_DIR/modified-image.raw node$i.raw; done

Veja que copiamos a imagem criada quatro vezes, mas especificamos apenas as configurações de rede para três nós. O motivo para isso é que também queremos demonstrar o que acontece quando provisionamos um nó que não corresponde a nenhuma das configurações desejadas.

Nota
Nota

Este guia usará a virtualização nos exemplos de provisionamento de nós. Assegure que as extensões necessárias estejam habilitadas no BIOS (consulte aqui para obter detalhes).

Vamos usar virt-install para criar máquinas virtuais por meio dos discos brutos copiados. Cada máquina virtual usará 10 GB de RAM e 6 vCPUs.

12.5.7.1 Provisionando o primeiro nó

Vamos criar a máquina virtual:

virt-install --name node1 --ram 10000 --vcpus 6 --disk path=node1.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default,mac=34:8A:B1:4B:16:E1 --network default,mac=34:8A:B1:4B:16:E2 --virt-type kvm --import
Nota
Nota

É importante criar as interfaces de rede com os mesmos endereços MAC daqueles no estado desejado descrito acima.

Após o término da operação, veremos algo semelhante ao seguinte:

Starting install...
Creating domain...

Running text console command: virsh --connect qemu:///system console node1
Connected to domain 'node1'
Escape character is ^] (Ctrl + ])


Welcome to SUSE Linux Micro 6.0 (x86_64) - Kernel 6.4.0-18-default (tty1).

SSH host key: SHA256:XN/R5Tw43reG+QsOw480LxCnhkc/1uqMdwlI6KUBY70 (RSA)
SSH host key: SHA256:/96yGrPGKlhn04f1rb9cXv/2WJt4TtrIN5yEcN66r3s (DSA)
SSH host key: SHA256:Dy/YjBQ7LwjZGaaVcMhTWZNSOstxXBsPsvgJTJq5t00 (ECDSA)
SSH host key: SHA256:TNGqY1LRddpxD/jn/8dkT/9YmVl9hiwulqmayP+wOWQ (ED25519)
eth0: 192.168.122.50
eth1:


Configured with the Edge Image Builder
Activate the web console with: systemctl enable --now cockpit.socket

node1 login:

Agora podemos fazer login com o par de credenciais root:eib e também usar SSH para entrar no host, se for a preferência no lugar de virsh console apresentado aqui.

Após o login, vamos confirmar se todas as configurações estão corretas.

Verifique se o nome de host foi devidamente definido:

node1:~ # hostnamectl
 Static hostname: node1.suse.com
 ...

Verifique se o roteamento foi devidamente configurado:

node1:~ # ip r
default via 192.168.122.1 dev eth0 proto static metric 100
192.168.122.0/24 dev eth0 proto static scope link metric 100
192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.50 metric 100

Verifique se a conexão com a Internet está disponível:

node1:~ # ping google.com
PING google.com (142.250.72.78) 56(84) bytes of data.
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=1 ttl=56 time=13.2 ms
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=2 ttl=56 time=13.4 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 13.248/13.304/13.361/0.056 ms

Verifique se exatamente duas interfaces Ethernet foram configuradas e apenas uma delas está ativa:

node1:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e1 brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
    inet 192.168.122.50/24 brd 192.168.122.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e2 brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    altname ens3

node1:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME  UUID                                  TYPE      DEVICE  FILENAME
eth0  dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0    /etc/NetworkManager/system-connections/eth0.nmconnection
eth1  7e211aea-3d14-59cf-a4fa-be91dac5dbba  ethernet  --      /etc/NetworkManager/system-connections/eth1.nmconnection

Veja que a segunda interface é eth1 em vez do eth3 predefinido em nosso estado de rede desejado. O motivo é que o NetworkManager Configurator (nmc) é capaz de detectar que o sistema operacional forneceu um nome diferente para o NIC com o endereço MAC 34:8a:b1:4b:16:e2 e ele ajusta suas configurações de maneira apropriada.

Verifique se foi isso mesmo que aconteceu analisando a fase Combustion do provisionamento:

node1:~ # journalctl -u combustion | grep nmc
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Identified host: node1.suse.com
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Set hostname: node1.suse.com
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Processing interface 'eth0'...
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Processing interface 'eth3'...
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Using interface name 'eth1' instead of the preconfigured 'eth3'
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc] Successfully applied config

Vamos agora provisionar o restante dos nós, mas vamos mostrar apenas as diferenças na configuração final. Aplique qualquer uma ou todas as verificações acima a todos os nós que você vai provisionar.

12.5.7.2 Provisionando o segundo nó

Vamos criar a máquina virtual:

virt-install --name node2 --ram 10000 --vcpus 6 --disk path=node2.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default,mac=34:8A:B1:4B:16:E3 --network default,mac=34:8A:B1:4B:16:E4 --virt-type kvm --import

Com a máquina virtual em funcionamento, podemos confirmar se esse nó usa as interfaces vinculadas:

node2:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond99 state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e3 brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
3: eth1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond99 state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e3 brd ff:ff:ff:ff:ff:ff permaddr 34:8a:b1:4b:16:e4
    altname enp0s3
    altname ens3
4: bond99: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e3 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.60/24 brd 192.168.122.255 scope global noprefixroute bond99
       valid_lft forever preferred_lft forever

Confirme se o roteamento usa o vínculo:

node2:~ # ip r
default via 192.168.122.1 dev bond99 proto static metric 100
192.168.122.0/24 dev bond99 proto static scope link metric 100
192.168.122.0/24 dev bond99 proto kernel scope link src 192.168.122.60 metric 300

Garanta que os arquivos de conexão estáticos sejam devidamente utilizados:

node2:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME    UUID                                  TYPE      DEVICE  FILENAME
bond99  4a920503-4862-5505-80fd-4738d07f44c6  bond      bond99  /etc/NetworkManager/system-connections/bond99.nmconnection
eth0    dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0    /etc/NetworkManager/system-connections/eth0.nmconnection
eth1    0523c0a1-5f5e-5603-bcf2-68155d5d322e  ethernet  eth1    /etc/NetworkManager/system-connections/eth1.nmconnection

12.5.7.3 Provisionando o terceiro nó

Vamos criar a máquina virtual:

virt-install --name node3 --ram 10000 --vcpus 6 --disk path=node3.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default,mac=34:8A:B1:4B:16:E5 --virt-type kvm --import

Com a máquina virtual em funcionamento, podemos confirmar se esse nó usa uma ponte de rede:

node3:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master linux-br0 state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e5 brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
3: linux-br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.70/24 brd 192.168.122.255 scope global noprefixroute linux-br0
       valid_lft forever preferred_lft forever

Confirme se o roteamento usa a ponte:

node3:~ # ip r
default via 192.168.122.1 dev linux-br0 proto static metric 100
192.168.122.0/24 dev linux-br0 proto static scope link metric 100
192.168.122.0/24 dev linux-br0 proto kernel scope link src 192.168.122.70 metric 425

Garanta que os arquivos de conexão estáticos sejam devidamente utilizados:

node3:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME       UUID                                  TYPE      DEVICE     FILENAME
linux-br0  1f8f1469-ed20-5f2c-bacb-a6767bee9bc0  bridge    linux-br0  /etc/NetworkManager/system-connections/linux-br0.nmconnection
eth0       dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0       /etc/NetworkManager/system-connections/eth0.nmconnection

12.5.7.4 Provisionando o quarto nó

Por fim, vamos provisionar um nó que não corresponderá a nenhuma das configurações predefinidas por um endereço MAC. Nesse caso, vamos usar DHCP como padrão para configurar as interfaces de rede.

Vamos criar a máquina virtual:

virt-install --name node4 --ram 10000 --vcpus 6 --disk path=node4.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default --virt-type kvm --import

Com a máquina virtual em funcionamento, podemos confirmar se esse nó usa um endereço IP aleatório para a interface de rede:

localhost:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:56:63:71 brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
    inet 192.168.122.86/24 brd 192.168.122.255 scope global dynamic noprefixroute eth0
       valid_lft 3542sec preferred_lft 3542sec
    inet6 fe80::5054:ff:fe56:6371/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

Verifique se o NMC não consegue aplicar configurações estáticas a esse nó:

localhost:~ # journalctl -u combustion | grep nmc
Apr 23 12:15:45 localhost.localdomain combustion[1357]: [2024-04-23T12:15:45Z ERROR nmc] Applying config failed: None of the preconfigured hosts match local NICs

Verifique se a interface Ethernet foi configurada por DHCP:

localhost:~ # journalctl | grep eth0
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7801] manager: (eth0): new Ethernet device (/org/freedesktop/NetworkManager/Devices/2)
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7802] device (eth0): state change: unmanaged -> unavailable (reason 'managed', sys-iface-state: 'external')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7929] device (eth0): carrier: link connected
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7931] device (eth0): state change: unavailable -> disconnected (reason 'carrier-changed', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7944] device (eth0): Activation: starting connection 'Wired Connection' (300ed658-08d4-4281-9f8c-d1b8882d29b9)
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7945] device (eth0): state change: disconnected -> prepare (reason 'none', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7947] device (eth0): state change: prepare -> config (reason 'none', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7953] device (eth0): state change: config -> ip-config (reason 'none', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7964] dhcp4 (eth0): activation: beginning transaction (timeout in 90 seconds)
Apr 23 12:15:33 localhost.localdomain NetworkManager[704]: <info>  [1713874533.1272] dhcp4 (eth0): state changed new lease, address=192.168.122.86

localhost:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME              UUID                                  TYPE      DEVICE  FILENAME
Wired Connection  300ed658-08d4-4281-9f8c-d1b8882d29b9  ethernet  eth0    /var/run/NetworkManager/system-connections/default_connection.nmconnection

12.5.8 Configurações unificadas de nós

Há situações em que não é possível usar endereços MAC conhecidos. Nesses casos, podemos recorrer à configuração unificada, que permite especificar as configurações em um arquivo _all.yaml que será aplicado a todos os nós provisionados.

Vamos criar e provisionar um nó de borda usando uma estrutura de configuração diferente. Siga todas as etapas, desde a Seção 12.5.3, “Criando o diretório de configuração de imagem” até a Seção 12.5.5, “Definindo as configurações de rede”.

Neste exemplo, definimos um estado desejado de duas interfaces Ethernet (eth0 e eth1): uma usando DHCP e outra que recebeu um endereço IP estático.

mkdir -p $CONFIG_DIR/network

cat <<- EOF > $CONFIG_DIR/network/_all.yaml
interfaces:
- name: eth0
  type: ethernet
  state: up
  ipv4:
    dhcp: true
    enabled: true
  ipv6:
    enabled: false
- name: eth1
  type: ethernet
  state: up
  ipv4:
    address:
    - ip: 10.0.0.1
      prefix-length: 24
    enabled: true
    dhcp: false
  ipv6:
    enabled: false
EOF

Vamos criar a imagem:

podman run --rm -it -v $CONFIG_DIR:/eib registry.suse.com/edge/3.3/edge-image-builder:1.2.1 build --definition-file definition.yaml

Depois que a imagem for criada com sucesso, vamos criar uma máquina virtual com base nela:

virt-install --name node1 --ram 10000 --vcpus 6 --disk path=$CONFIG_DIR/modified-image.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default --network default --virt-type kvm --import

O processo de provisionamento pode levar alguns minutos. Depois que ele for concluído, faça login no sistema com as credenciais fornecidas.

Verifique se o roteamento foi devidamente configurado:

localhost:~ # ip r
default via 192.168.122.1 dev eth0 proto dhcp src 192.168.122.100 metric 100
10.0.0.0/24 dev eth1 proto kernel scope link src 10.0.0.1 metric 101
192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.100 metric 100

Verifique se a conexão com a Internet está disponível:

localhost:~ # ping google.com
PING google.com (142.250.72.46) 56(84) bytes of data.
64 bytes from den16s08-in-f14.1e100.net (142.250.72.46): icmp_seq=1 ttl=56 time=14.3 ms
64 bytes from den16s08-in-f14.1e100.net (142.250.72.46): icmp_seq=2 ttl=56 time=14.2 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 14.196/14.260/14.324/0.064 ms

Verifique se as interfaces Ethernet estão configuradas e ativas:

localhost:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:26:44:7a brd ff:ff:ff:ff:ff:ff
    altname enp1s0
    inet 192.168.122.100/24 brd 192.168.122.255 scope global dynamic noprefixroute eth0
       valid_lft 3505sec preferred_lft 3505sec
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:ec:57:9e brd ff:ff:ff:ff:ff:ff
    altname enp7s0
    inet 10.0.0.1/24 brd 10.0.0.255 scope global noprefixroute eth1
       valid_lft forever preferred_lft forever

localhost:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME  UUID                                  TYPE      DEVICE  FILENAME
eth0  dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0    /etc/NetworkManager/system-connections/eth0.nmconnection
eth1  0523c0a1-5f5e-5603-bcf2-68155d5d322e  ethernet  eth1    /etc/NetworkManager/system-connections/eth1.nmconnection

localhost:~ # cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
id=eth0
interface-name=eth0
type=802-3-ethernet
uuid=dfd202f5-562f-5f07-8f2a-a7717756fb70

[ipv4]
dhcp-client-id=mac
dhcp-send-hostname=true
dhcp-timeout=2147483647
ignore-auto-dns=false
ignore-auto-routes=false
method=auto
never-default=false

[ipv6]
addr-gen-mode=0
dhcp-timeout=2147483647
method=disabled

localhost:~ # cat /etc/NetworkManager/system-connections/eth1.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
id=eth1
interface-name=eth1
type=802-3-ethernet
uuid=0523c0a1-5f5e-5603-bcf2-68155d5d322e

[ipv4]
address0=10.0.0.1/24
dhcp-timeout=2147483647
method=manual

[ipv6]
addr-gen-mode=0
dhcp-timeout=2147483647
method=disabled

12.5.9 Configurações de rede personalizadas

Já abordamos a configuração de rede padrão do Edge Image Builder que usa o NetworkManager Configurator. No entanto, há também a opção de modificá-la por meio de um script personalizado. Essa opção é muito flexível e independente de endereço MAC, mas tem a limitação de que seu uso não é tão prático para inicializar vários nós com uma única imagem.

Nota
Nota

A recomendação é usar a configuração de rede padrão por meio dos arquivos que descrevem o estado da rede desejado no diretório /network. Crie scripts personalizados apenas quando esse comportamento não é cabível no seu caso de uso.

Vamos criar e provisionar um nó de borda usando uma estrutura de configuração diferente. Siga todas as etapas, desde a Seção 12.5.3, “Criando o diretório de configuração de imagem” até a Seção 12.5.5, “Definindo as configurações de rede”.

Neste exemplo, vamos criar um script personalizado que aplica a configuração estática da interface eth0 a todos os nós provisionados, além de remover e desabilitar as conexões com fio criadas automaticamente pelo NetworkManager. Isso é vantajoso nos casos em que você quer garantir que cada nó no cluster tenha uma configuração de rede idêntica e, sendo assim, você não precisa se preocupar com o endereço MAC de cada nó antes da criação da imagem.

Para começar, vamos armazenar o arquivo de conexão no diretório /custom/files:

mkdir -p $CONFIG_DIR/custom/files

cat << EOF > $CONFIG_DIR/custom/files/eth0.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
autoconnect-retries=1
id=eth0
interface-name=eth0
type=802-3-ethernet
uuid=dfd202f5-562f-5f07-8f2a-a7717756fb70
wait-device-timeout=60000

[ipv4]
dhcp-timeout=2147483647
method=auto

[ipv6]
addr-gen-mode=eui64
dhcp-timeout=2147483647
method=disabled
EOF

Com a configuração estática criada, vamos também criar nosso script de rede personalizado:

mkdir -p $CONFIG_DIR/network

cat << EOF > $CONFIG_DIR/network/configure-network.sh
#!/bin/bash
set -eux

# Remove and disable wired connections
mkdir -p /etc/NetworkManager/conf.d/
printf "[main]\nno-auto-default=*\n" > /etc/NetworkManager/conf.d/no-auto-default.conf
rm -f /var/run/NetworkManager/system-connections/* || true

# Copy pre-configured network configuration files into NetworkManager
mkdir -p /etc/NetworkManager/system-connections/
cp eth0.nmconnection /etc/NetworkManager/system-connections/
chmod 600 /etc/NetworkManager/system-connections/*.nmconnection
EOF

chmod a+x $CONFIG_DIR/network/configure-network.sh
Nota
Nota

Por padrão, o binário nmc ainda será incluído, para ser usado no script configure-network.sh se necessário.

Atenção
Atenção

O script personalizado deve sempre ser inserido em /network/configure-network.sh no diretório de configuração. Se estiver presente, todos os outros arquivos serão ignorados. NÃO é possível configurar uma rede trabalhando com as configurações estáticas no formato YAML e um script personalizado ao mesmo tempo.

Neste momento, o diretório de configuração deve ter a seguinte aparência:

├── definition.yaml
├── custom/
│   └── files/
│       └── eth0.nmconnection
├── network/
│   └── configure-network.sh
└── base-images/
    └── SL-Micro.x86_64-6.1-Base-GM.raw

Vamos criar a imagem:

podman run --rm -it -v $CONFIG_DIR:/eib registry.suse.com/edge/3.3/edge-image-builder:1.2.1 build --definition-file definition.yaml

Depois que a imagem for criada com sucesso, vamos criar uma máquina virtual com base nela:

virt-install --name node1 --ram 10000 --vcpus 6 --disk path=$CONFIG_DIR/modified-image.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default --virt-type kvm --import

O processo de provisionamento pode levar alguns minutos. Depois que ele for concluído, faça login no sistema com as credenciais fornecidas.

Verifique se o roteamento foi devidamente configurado:

localhost:~ # ip r
default via 192.168.122.1 dev eth0 proto dhcp src 192.168.122.185 metric 100
192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.185 metric 100

Verifique se a conexão com a Internet está disponível:

localhost:~ # ping google.com
PING google.com (142.250.72.78) 56(84) bytes of data.
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=1 ttl=56 time=13.6 ms
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=2 ttl=56 time=13.6 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 13.592/13.599/13.606/0.007 ms

Verifique se uma interface Ethernet foi configurada estaticamente usando nosso arquivo de conexão e se ela está ativa:

localhost:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:31:d0:1b brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
    inet 192.168.122.185/24 brd 192.168.122.255 scope global dynamic noprefixroute eth0

localhost:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME  UUID                                  TYPE      DEVICE  FILENAME
eth0  dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0    /etc/NetworkManager/system-connections/eth0.nmconnection

localhost:~ # cat  /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
autoconnect-retries=1
id=eth0
interface-name=eth0
type=802-3-ethernet
uuid=dfd202f5-562f-5f07-8f2a-a7717756fb70
wait-device-timeout=60000

[ipv4]
dhcp-timeout=2147483647
method=auto

[ipv6]
addr-gen-mode=eui64
dhcp-timeout=2147483647
method=disabled
Documentation survey