|Index|SUSE Edge Documentação|Componentes|Rede de borda
Applies to SUSE Edge 3.6

9 Rede de borda

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

9.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 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/.

Detalhes sobre o NetworkManager podem ser encontrados na documentação do SUSE Linux Micro.

9.2 Visão geral do nmstate

O nmstate é uma biblioteca amplamente adotada (com uma ferramenta de CLI associada) que oferece uma API declarativa para configurações de rede por meio de um esquema predefinido.

Detalhes sobre o nmstate podem ser encontrados na documentação upstream.

9.3 Digite: NetworkManager Configurator (nmc)

As opções de personalização de rede disponíveis no SUSE Edge são obtidas por meio de uma ferramenta de CLI chamada NetworkManager Configurator ou nmc, para abreviar. Ela aproveita a funcionalidade fornecida pela biblioteca nmstate e, como tal, é totalmente capaz de configurar endereços IP estáticos, servidores DNS, VLANs, vínculo de rede, bridges, etc. Esta ferramenta nos permite gerar configurações de rede a partir de estados desejados predefinidos e aplicá-las em muitos nós diferentes de forma automatizada.

Detalhes sobre o NetworkManager Configurator (nmc) podem ser encontrados no repositório upstream.

9.4 Como o SUSE Edge usa o NetworkManager Configurator?

O SUSE Edge utiliza o nmc para as personalizações de rede nos vários modelos de provisionamento diferentes: * Configurações estáticas declarativas nos cenários de Provisionamento Baseado em Imagem (Chapter 2, Clusters autônomos com o Edge Image Builder)

9.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 SO. Nesta seção, mostraremos como você pode usar uma abordagem declarativa para descrever os estados de rede desejados, como eles são convertidos para as respectivas conexões do NetworkManager e, em seguida, aplicados durante o processo de provisionamento.

9.5.1 Pré-requisitos

Se você está seguindo este guia, presume-se que você já tenha o seguinte disponível:

  • Um AMD64/Intel 64 host físico (ou máquina virtual) executando o SLES 15 SP6 ou openSUSE Leap 15.6

  • Um tempo de execução do contêiner disponível (por exemplo, Podman)

  • Uma cópia da imagem RAW do SUSE Linux Micro 6.2 encontrada aqui

9.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:

podman pull registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1

9.5.3 Criando o diretório de configuração da imagem

Vamos começar criando o diretório de configuração:

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

Agora, garantiremos que a cópia da imagem base baixada seja movida para o diretório de configuração:

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

O EIB nunca modificará a entrada da imagem base. Ele criará uma nova imagem com suas modificações.

O diretório de configuração neste ponto deve estar assim:

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

9.5.4 Criando o arquivo de definição da 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 SO:

cat << EOF > $CONFIG_DIR/definition.yaml
apiVersion: 1.3
image:
  arch: x86_64
  imageType: raw
  baseImage: SL-Micro.x86_64-6.2-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, bem como o nome que a imagem de saída terá. A seção operatingSystem é opcional e contém a configuração para habilitar o login nos sistemas provisionados com o nome de usuário/senha root/eib.

Note
Note

Sinta-se à vontade para usar sua própria senha criptografada executando openssl passwd -6 <password>.

O diretório de configuração neste ponto deve estar assim:

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

9.5.5 Definindo as configurações de rede

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

mkdir -p $CONFIG_DIR/network

Como mencionado anteriormente, a ferramenta NetworkManager Configurator (nmc) espera uma entrada na forma de um esquema predefinido. Você pode encontrar como configurar uma ampla variedade de diferentes opções de rede na documentação de exemplos upstream do NMState.

Este guia explicará 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 uma ponte de rede

Warning
Warning

O uso de configurações de rede completamente diferentes não é recomendado em compilações de produção, especialmente se estiver configurando clusters Kubernetes. As configurações de rede geralmente devem ser homogêneas entre os nós ou, pelo menos, entre as funções dentro de um determinado cluster. Este guia inclui várias opções diferentes apenas para servir como uma referência de exemplo.

Note
Note

O seguinte pressupõe uma rede libvirt padrão com um intervalo de endereços IP 192.168.122.1/24. Ajuste de acordo se isso for diferente em seu ambiente.

Vamos criar os estados desejados para o primeiro nó que chamaremos 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: 192.168.122.1
      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

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

Warning
Warning

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

A seguir, temos o segundo nó, que chamaremos de node2.suse.com e que 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: 192.168.122.1
      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

Neste exemplo, definimos um estado desejado de duas interfaces Ethernet (eth0 e eth1) que não estão habilitando o endereçamento IP, bem como um vínculo de rede com uma política round-robin e seu respectivo endereço, que será usado para encaminhar o tráfego de rede.

Por último, criaremos o terceiro e último arquivo de estado desejado, que utilizará uma ponte de rede e que chamaremos 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: 192.168.122.1
      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

O diretório de configuração neste ponto deve estar assim:

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

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

9.5.6 Criando a imagem do SO

Agora que todas as configurações necessárias estão no lugar, podemos criar a imagem simplesmente executando:

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

A saída deve ser similar ao seguinte:

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 diz que o componente Network foi configurado com sucesso, e podemos prosseguir com o provisionamento de nossos nós de borda.

Note
Note

Um arquivo de log (network-config.log) e os respectivos arquivos de conexão do NetworkManager podem ser inspecionados no diretório _build resultante, dentro de um diretório com carimbo de data/hora para a execução da imagem.

9.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

Você notará que copiamos a imagem criada quatro vezes, mas especificamos as configurações de rede apenas para três nós. Isso ocorre porque também queremos mostrar o que acontecerá se provisionarmos um nó que não corresponda a nenhuma das configurações desejadas.

Note
Note

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

Usaremos o virt-install para criar máquinas virtuais usando os discos brutos copiados. Cada máquina virtual usará 10 GB de RAM e 6 vCPUs.

9.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
Note
Note

É importante que criemos as interfaces de rede com os mesmos endereços MAC que os descritos no estado desejado acima.

Assim que a operação for concluída, 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. Também podemos acessar o host via SSH se preferirmos isso em vez do virsh console que nos é apresentado aqui.

Uma vez logado, vamos confirmar se todas as configurações estão no lugar.

Verifique se o nome do host está definido corretamente:

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

Verifique se o roteamento está configurado corretamente:

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 estão 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

Você notará que a segunda interface é eth1 em vez da eth3 predefinida em nosso estado de rede desejado. Isso ocorre porque o Configurador do NetworkManager (nmc) é capaz de detectar que o SO deu um nome diferente para a NIC com endereço MAC 34:8a:b1:4b:16:e2 e ajusta suas configurações de acordo.

Verifique se isso realmente aconteceu inspecionando a fase de 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

Provisionaremos agora o restante dos nós, mas mostraremos apenas as diferenças na configuração final. Sinta-se à vontade para aplicar qualquer uma ou todas as verificações acima para todos os nós que você está prestes a provisionar.

9.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

Assim que a máquina virtual estiver em execução, podemos confirmar que este nó está usando interfaces de vínculo.

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 que o roteamento está usando a interface de 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ática sejam utilizados corretamente:

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

9.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

Assim que a máquina virtual estiver em execução, podemos confirmar que este nó está usando 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 que o roteamento está usando 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ática sejam utilizados corretamente:

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

9.5.7.4 Provisionando o quarto nó

Por último, provisionaremos um nó que não corresponderá a nenhuma das configurações predefinidas por um endereço MAC. Nestes casos, usaremos o DHCP por 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

Assim que a máquina virtual estiver em execução, podemos confirmar que este nó está usando um endereço IP aleatório para sua 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 falhou ao aplicar configurações estáticas para este 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 via 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

9.5.8 Configurações de nó unificadas

Existem ocasiões em que depender de endereços MAC conhecidos não é uma opção. Nestes casos, podemos optar pela chamada configuração unificada, que nos permite especificar configurações em um arquivo _all.yaml que serão então aplicadas a todos os nós provisionados.

Vamos construir e provisionar um nó de borda usando uma estrutura de configuração diferente. Siga todos os passos começando de Section 9.5.3, “Criando o diretório de configuração da imagem” até Section 9.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 com um endereço IP estático atribuído.

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 construir a imagem:

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

Assim que a imagem for construída com sucesso, vamos criar uma máquina virtual usando-a:

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. Assim que terminar, faça login no sistema com as credenciais fornecidas.

Verifique se o roteamento está configurado corretamente:

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

9.5.9 Configurações de rede personalizadas

Já cobrimos a configuração de rede padrão para o Edge Image Builder, que depende do NetworkManager Configurator. No entanto, também existe a opção de modificá-la por meio de um script personalizado. Embora essa opção seja muito flexível e também não dependa do endereço MAC, sua limitação decorre do fato de que usá-la é muito menos conveniente ao inicializar vários nós com uma única imagem.

Note
Note

Recomenda-se usar a configuração de rede padrão por meio de arquivos que descrevem os estados de rede desejados no diretório /network. Opte pelo script personalizado apenas quando esse comportamento não for aplicável ao seu caso de uso.

Vamos construir e provisionar um nó de borda usando uma estrutura de configuração diferente. Siga todos os passos começando de Section 9.5.3, “Criando o diretório de configuração da imagem” até Section 9.5.5, “Definindo as configurações de rede”.

Neste exemplo, criaremos um script personalizado que aplica uma configuração estática para a interface eth0 em todos os nós provisionados, além de remover e desabilitar as conexões com fio criadas automaticamente pelo NetworkManager. Isso é benéfico em situações em que você deseja garantir que cada nó em seu cluster tenha uma configuração de rede idêntica e, como tal, você não precisa se preocupar com o endereço MAC de cada nó antes da criação da imagem.

Vamos começar armazenando 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

Agora que a configuração estática foi criada, também criaremos 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
Note
Note

O binário nmc ainda será incluído por padrão, portanto, ele também pode ser usado no script configure-network.sh, se necessário.

Warning
Warning

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

O diretório de configuração neste ponto deve estar assim:

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

Vamos construir a imagem:

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

Assim que a imagem for construída com sucesso, vamos criar uma máquina virtual usando-a:

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. Assim que terminar, faça login no sistema com as credenciais fornecidas.

Verifique se o roteamento está configurado corretamente:

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 está configurada estaticamente usando nosso arquivo de conexão e se 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