documentation.suse.com / Documentação do SUSE Edge / Documentação do produto / Provisionamento de rede direcionado totalmente automatizado

42 Provisionamento de rede direcionado totalmente automatizado

42.1 Introdução

O provisionamento de rede direcionado é um recurso que permite automatizar o provisionamento de clusters downstream. Ele é útil quando você tem que provisionar muitos clusters downstream e deseja automatizar o processo.

Um cluster de gerenciamento (Capítulo 40, Configurando o cluster de gerenciamento) automatiza a implantação dos seguintes componentes:

  • SUSE Linux Micro RT como sistema operacional. Dependendo do caso de uso, é possível personalizar configurações como rede, armazenamento, usuários e argumentos do kernel.

  • RKE2 como cluster Kubernetes. O plug-in de CNI padrão é Cilium. Dependendo do caso de uso, é possível usar determinados plug-ins de CNI, como Cilium+Multus.

  • SUSE Storage

  • SUSE Security

  • É possível usar o MetalLB como balanceador de carga para clusters de vários nós altamente disponíveis.

Nota
Nota

Para obter mais informações sobre o SUSE Linux Micro, consulte o Capítulo 9, SUSE Linux Micro. Para obter mais informações sobre o RKE2, consulte o Capítulo 16, RKE2. Para obter mais informações sobre o SUSE Storage, consulte o Capítulo 17, SUSE Storage. Para obter mais informações sobre o SUSE Security, consulte o Capítulo 18, SUSE Security.

As seguintes seções descrevem os diferentes fluxos de trabalho de provisionamento de rede direcionado e alguns recursos adicionais que podem ser incluídos no processo de provisionamento:

Nota
Nota

As seções a seguir mostram como preparar os diversos cenários para o fluxo de trabalho de provisionamento de rede direcionado usando o SUSE Edge for Telco. Para ver exemplos de opções de configurações diferentes para implantação (incluindo ambientes air-gapped, redes DHCP e sem DHCP, registros de contêiner particulares etc.), consulte o repositório SUSE do SUSE Edge for Telco.

42.2 Preparar uma imagem de cluster downstream para cenários conectados

O Edge Image Builder (Capítulo 11, Edge Image Builder) é usado para preparar uma imagem base do SLEMicro modificada que será provisionada aos hosts de cluster downstream.

Grande parte da configuração é possível pelo Edge Image Builder, mas neste guia, abordamos as configurações mínimas necessárias para preparar o cluster downstream.

42.2.1 Pré-requisitos para cenários conectados

  • É necessário um tempo de execução do contêiner, como Podman ou Rancher Desktop, para executar o Edge Image Builder.

  • A imagem base será criada conforme este guia Capítulo 28, Criando imagens atualizadas do SUSE Linux Micro com o Kiwi com o perfil Base-SelfInstall (ou Base-RT-SelfInstall para o kernel Real-Time). O processo é o mesmo para as duas arquiteturas (x86-64 e aarch64).

  • Para implantar clusters downstream aarch64, você deve definir o parâmetro deployArchitecture: arm64 no arquivo metal3.yaml antes da implantação do cluster de gerenciamento, o que está explicado na documentação sobre o cluster de gerenciamento (???). Isso é necessário para garantir o uso da arquitetura correta para o cluster downstream.

Nota
Nota

É necessário usar um host de build com a mesma arquitetura das imagens que estão sendo criadas. Em outras palavras, para criar uma imagem aarch64, é necessário usar um host de build aarch64, e vice-versa para x86-64 (não há suporte para builds cruzados no momento).

42.2.2 Configuração da imagem para cenários conectados

Ao executar o Edge Image Builder, um diretório é montado com base no host, portanto, é necessário criar uma estrutura de diretórios para armazenar os arquivos de configuração usados para definir a imagem de destino.

  • downstream-cluster-config.yaml é o arquivo de definição da imagem. Consulte o Capítulo 3, Clusters independentes com o Edge Image Builder para obter mais detalhes.

  • A pasta da imagem base inclui a imagem bruta de saída gerada conforme o guia Capítulo 28, Criando imagens atualizadas do SUSE Linux Micro com o Kiwi com o perfil Base-SelfInstall (ou Base-RT-SelfInstall para o kernel Real-Time) e deve ser copiada/movida para a pasta base-images.

  • A pasta network é opcional. Consulte a Seção 42.2.2.6, “Script adicional para configuração de rede avançada” para obter mais detalhes.

  • O diretório custom/scripts contém scripts para execução na primeira inicialização:

    1. O script 01-fix-growfs.sh é necessário para redimensionar a partição raiz do sistema operacional na implantação.

    2. O script 02-performance.sh é opcional e pode ser usado para configurar o sistema para ajuste de desempenho.

    3. O script 03-sriov.sh é opcional e pode ser usado para configurar o sistema para SR-IOV.

  • O diretório custom/files contém os arquivos performance-settings.sh e sriov-auto-filler.sh para copiar na imagem durante o processo de criação da imagem.

├── downstream-cluster-config.yaml
├── base-images/
│   └ SL-Micro.x86_64-6.1-Base-GM.raw
├── network/
|   └ configure-network.sh
└── custom/
    └ scripts/
    |   └ 01-fix-growfs.sh
    |   └ 02-performance.sh
    |   └ 03-sriov.sh
    └ files/
        └ performance-settings.sh
        └ sriov-auto-filler.sh

42.2.2.1 Arquivo de definição da imagem do cluster downstream

O downstream-cluster-config.yaml é o arquivo de configuração principal para a imagem do cluster downstream. Veja a seguir um exemplo mínimo de implantação por meio do Metal3:

apiVersion: 1.2
image:
  imageType: raw
  arch: x86_64
  baseImage: SL-Micro.x86_64-6.1-Base-GM.raw
  outputImageName: eibimage-output-telco.raw
operatingSystem:
  kernelArgs:
    - ignition.platform.id=openstack
    - net.ifnames=1
  systemd:
    disable:
      - rebootmgr
      - transactional-update.timer
      - transactional-update-cleanup.timer
      - fstrim
      - time-sync.target
  users:
    - username: root
      encryptedPassword: $ROOT_PASSWORD
      sshKeys:
      - $USERKEY1
  packages:
    packageList:
      - jq
    sccRegistrationCode: $SCC_REGISTRATION_CODE

Em que $SCC_REGISTRATION_CODE é o código de registro copiado do SUSE Customer Center, e a lista de pacotes inclui o jq, que é obrigatório.

$ROOT_PASSWORD é a senha criptografada do usuário root, que pode ser útil para teste/depuração. É possível gerá-la com o comando openssl passwd -6 PASSWORD.

Para os ambientes de produção, a recomendação é usar as chaves SSH que podem ser adicionadas ao bloco de usuários substituindo a $USERKEY1 pelas chaves SSH reais.

Nota
Nota

arch: x86_64 é a arquitetura da imagem. Para arm64, use arch: aarch64.

O net.ifnames=1 habilita a Nomenclatura de interface de rede previsível.

Isso corresponde à configuração padrão para o gráfico metal3, mas a configuração deve corresponder ao valor predictableNicNames do gráfico configurado.

Veja também que o ignition.platform.id=openstack é obrigatório. Sem esse argumento, a configuração do SLEMicro pelo ignition vai falhar no fluxo automatizado do Metal3.

42.2.2.2 Script growfs

Atualmente, é necessário um script personalizado (custom/scripts/01-fix-growfs.sh) para expandir o sistema de arquivos de acordo com o tamanho do disco na primeira inicialização após o provisionamento. O script 01-fix-growfs.sh contém as seguintes informações:

#!/bin/bash
growfs() {
  mnt="$1"
  dev="$(findmnt --fstab --target ${mnt} --evaluate --real --output SOURCE --noheadings)"
  # /dev/sda3 -> /dev/sda, /dev/nvme0n1p3 -> /dev/nvme0n1
  parent_dev="/dev/$(lsblk --nodeps -rno PKNAME "${dev}")"
  # Last number in the device name: /dev/nvme0n1p42 -> 42
  partnum="$(echo "${dev}" | sed 's/^.*[^0-9]\([0-9]\+\)$/\1/')"
  ret=0
  growpart "$parent_dev" "$partnum" || ret=$?
  [ $ret -eq 0 ] || [ $ret -eq 1 ] || exit 1
  /usr/lib/systemd/systemd-growfs "$mnt"
}
growfs /

42.2.2.3 Script de desempenho

O seguinte script opcional (custom/scripts/02-performance.sh) pode ser usado para configurar o sistema para ajuste de desempenho:

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/performance-settings

# copy the artifacts
cp performance-settings.sh /opt/performance-settings/

O conteúdo do custom/files/performance-settings.sh é um script que pode ser usado para configurar o sistema para ajuste de desempenho e pode ser baixado acessando este link.

42.2.2.4 Script SR-IOV

O seguinte script opcional (custom/scripts/03-sriov.sh) pode ser usado para configurar o sistema para SR-IOV:

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/sriov
# copy the artifacts
cp sriov-auto-filler.sh /opt/sriov/sriov-auto-filler.sh

O conteúdo do custom/files/sriov-auto-filler.sh é um script que pode ser usado para configurar o sistema para SR-IOV e pode ser baixado acessando este link.

Nota
Nota

Adicione seus próprios scripts personalizados para execução durante o processo de provisionamento usando a mesma abordagem. Para obter mais informações, consulte o Capítulo 3, Clusters independentes com o Edge Image Builder.

42.2.2.5 Configuração adicional para cargas de trabalho de telecomunicações

Para habilitar recursos de telecomunicações, como dpdk, sr-iov ou FEC, podem ser necessários pacotes adicionais, conforme mostrado no exemplo a seguir.

apiVersion: 1.2
image:
  imageType: raw
  arch: x86_64
  baseImage: SL-Micro.x86_64-6.1-Base-GM.raw
  outputImageName: eibimage-output-telco.raw
operatingSystem:
  kernelArgs:
    - ignition.platform.id=openstack
    - net.ifnames=1
  systemd:
    disable:
      - rebootmgr
      - transactional-update.timer
      - transactional-update-cleanup.timer
      - fstrim
      - time-sync.target
  users:
    - username: root
      encryptedPassword: $ROOT_PASSWORD
      sshKeys:
      - $user1Key1
  packages:
    packageList:
      - jq
      - dpdk
      - dpdk-tools
      - libdpdk-23
      - pf-bb-config
    sccRegistrationCode: $SCC_REGISTRATION_CODE

Em que $SCC_REGISTRATION_CODE é o código de registro copiado do SUSE Customer Center, e a lista de pacotes inclui os pacotes mínimos usados nos perfis de telecomunicações.

Nota
Nota

arch: x86_64 é a arquitetura da imagem. Para arm64, use arch: aarch64.

42.2.2.6 Script adicional para configuração de rede avançada

Se você precisa configurar IPs estáticos ou cenários de rede mais avançados, conforme descrito na Seção 42.6, “Configuração avançada de rede”, a configuração adicional abaixo é necessária.

Na pasta network, crie o seguinte arquivo configure-network.sh, que consome os dados da unidade de configuração na primeira inicialização e configura a rede do host usando a ferramenta NM Configurator.

#!/bin/bash

set -eux

# Attempt to statically configure a NIC in the case where we find a network_data.json
# In a configuration drive

CONFIG_DRIVE=$(blkid --label config-2 || true)
if [ -z "${CONFIG_DRIVE}" ]; then
  echo "No config-2 device found, skipping network configuration"
  exit 0
fi

mount -o ro $CONFIG_DRIVE /mnt

NETWORK_DATA_FILE="/mnt/openstack/latest/network_data.json"

if [ ! -f "${NETWORK_DATA_FILE}" ]; then
  umount /mnt
  echo "No network_data.json found, skipping network configuration"
  exit 0
fi

DESIRED_HOSTNAME=$(cat /mnt/openstack/latest/meta_data.json | tr ',{}' '\n' | grep '\"metal3-name\"' | sed 's/.*\"metal3-name\": \"\(.*\)\"/\1/')
echo "${DESIRED_HOSTNAME}" > /etc/hostname

mkdir -p /tmp/nmc/{desired,generated}
cp ${NETWORK_DATA_FILE} /tmp/nmc/desired/_all.yaml
umount /mnt

./nmc generate --config-dir /tmp/nmc/desired --output-dir /tmp/nmc/generated
./nmc apply --config-dir /tmp/nmc/generated

42.2.3 Criação de imagem

Depois que a estrutura de diretórios for preparada de acordo com as seções anteriores, execute o seguinte comando para criar a imagem:

podman run --rm --privileged -it -v $PWD:/eib \
 registry.suse.com/edge/3.3/edge-image-builder:1.2.1 \
 build --definition-file downstream-cluster-config.yaml

Esse procedimento cria o arquivo da imagem ISO de saída chamado eibimage-output-telco.raw, com base na definição descrita acima.

Em seguida, disponibilize a imagem de saída por um servidor web, ou o contêiner de servidor de mídia habilitado de acordo com as instruções na documentação sobre o cluster de gerenciamento (Nota) ou algum outro servidor acessível localmente. Nos exemplos abaixo, esse servidor é mencionado como imagecache.local:8080.

42.3 Preparar uma imagem de cluster downstream para cenários air-gapped

O Edge Image Builder (Capítulo 11, Edge Image Builder) é usado para preparar uma imagem base do SLEMicro modificada que será provisionada aos hosts de cluster downstream.

Grande parte da configuração é possível com o Edge Image Builder, mas neste guia, abordamos as configurações mínimas necessárias para preparar o cluster downstream em cenários air-gapped.

42.3.1 Pré-requisitos para cenários air-gapped

  • É necessário um tempo de execução do contêiner, como Podman ou Rancher Desktop, para executar o Edge Image Builder.

  • A imagem base será criada conforme este guia Capítulo 28, Criando imagens atualizadas do SUSE Linux Micro com o Kiwi com o perfil Base-SelfInstall (ou Base-RT-SelfInstall para o kernel Real-Time). O processo é o mesmo para as duas arquiteturas (x86-64 e aarch64).

  • Para implantar clusters downstream aarch64, você deve definir o parâmetro deployArchitecture: arm64 no arquivo metal3.yaml antes da implantação do cluster de gerenciamento, o que está explicado na documentação sobre o cluster de gerenciamento (???). Isso é necessário para garantir o uso da arquitetura correta para o cluster downstream.

  • Para usar SR-IOV ou qualquer outra carga de trabalho que exija uma imagem de contêiner, é necessário implantar e já configurar um registro particular local (com/sem TLS e/ou autenticação). Esse registro será usado para armazenar as imagens comuns e as imagens OCI de gráfico Helm.

Nota
Nota

É necessário usar um host de build com a mesma arquitetura das imagens que estão sendo criadas. Em outras palavras, para criar uma imagem aarch64, é necessário usar um host de build aarch64, e vice-versa para x86-64 (não há suporte para builds cruzados no momento).

42.3.2 Configuração da imagem para cenários air-gapped

Ao executar o Edge Image Builder, um diretório é montado com base no host, portanto, é necessário criar uma estrutura de diretórios para armazenar os arquivos de configuração usados para definir a imagem de destino.

  • downstream-cluster-airgap-config.yaml é o arquivo de definição da imagem, consulte o Capítulo 3, Clusters independentes com o Edge Image Builder para obter mais detalhes.

  • A pasta da imagem base inclui a imagem bruta de saída gerada conforme o guia Capítulo 28, Criando imagens atualizadas do SUSE Linux Micro com o Kiwi com o perfil Base-SelfInstall (ou Base-RT-SelfInstall para o kernel Real-Time) e deve ser copiada/movida para a pasta base-images.

  • A pasta network é opcional. Consulte a Seção 42.2.2.6, “Script adicional para configuração de rede avançada” para obter mais detalhes.

  • O diretório custom/scripts contém scripts para execução na primeira inicialização:

    1. O script 01-fix-growfs.sh é necessário para redimensionar a partição raiz do sistema operacional na implantação.

    2. O script 02-airgap.sh é necessário para copiar as imagens no local certo durante o processo de criação da imagem para ambientes air-gapped.

    3. O script 03-performance.sh é opcional e pode ser usado para configurar o sistema para ajuste de desempenho.

    4. O script 04-sriov.sh é opcional e pode ser usado para configurar o sistema para SR-IOV.

  • O diretório custom/files contém as imagens rke2 e cni para copiar na imagem durante o processo de criação da imagem. É possível também incluir os arquivos opcionais performance-settings.sh e sriov-auto-filler.sh.

├── downstream-cluster-airgap-config.yaml
├── base-images/
│   └ SL-Micro.x86_64-6.1-Base-GM.raw
├── network/
|   └ configure-network.sh
└── custom/
    └ files/
    |   └ install.sh
    |   └ rke2-images-cilium.linux-amd64.tar.zst
    |   └ rke2-images-core.linux-amd64.tar.zst
    |   └ rke2-images-multus.linux-amd64.tar.zst
    |   └ rke2-images.linux-amd64.tar.zst
    |   └ rke2.linux-amd64.tar.zst
    |   └ sha256sum-amd64.txt
    |   └ performance-settings.sh
    |   └ sriov-auto-filler.sh
    └ scripts/
        └ 01-fix-growfs.sh
        └ 02-airgap.sh
        └ 03-performance.sh
        └ 04-sriov.sh

42.3.2.1 Arquivo de definição da imagem do cluster downstream

O downstream-cluster-airgap-config.yaml é o principal arquivo de configuração da imagem do cluster downstream, e o conteúdo foi descrito na seção anterior (Seção 42.2.2.5, “Configuração adicional para cargas de trabalho de telecomunicações”).

42.3.2.2 Script growfs

Atualmente, é necessário um script personalizado (custom/scripts/01-fix-growfs.sh) para expandir o sistema de arquivos de acordo com o tamanho do disco na primeira inicialização após o provisionamento. O script 01-fix-growfs.sh contém as seguintes informações:

#!/bin/bash
growfs() {
  mnt="$1"
  dev="$(findmnt --fstab --target ${mnt} --evaluate --real --output SOURCE --noheadings)"
  # /dev/sda3 -> /dev/sda, /dev/nvme0n1p3 -> /dev/nvme0n1
  parent_dev="/dev/$(lsblk --nodeps -rno PKNAME "${dev}")"
  # Last number in the device name: /dev/nvme0n1p42 -> 42
  partnum="$(echo "${dev}" | sed 's/^.*[^0-9]\([0-9]\+\)$/\1/')"
  ret=0
  growpart "$parent_dev" "$partnum" || ret=$?
  [ $ret -eq 0 ] || [ $ret -eq 1 ] || exit 1
  /usr/lib/systemd/systemd-growfs "$mnt"
}
growfs /

42.3.2.3 Script air-gap

O seguinte script (custom/scripts/02-airgap.sh) é necessário para copiar as imagens no local certo durante o processo de criação da imagem:

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/rke2-artifacts
mkdir -p /var/lib/rancher/rke2/agent/images

# copy the artifacts
cp install.sh /opt/
cp rke2-images*.tar.zst rke2.linux-amd64.tar.gz sha256sum-amd64.txt /opt/rke2-artifacts/

42.3.2.4 Script de desempenho

O seguinte script opcional (custom/scripts/03-performance.sh) pode ser usado para configurar o sistema para ajuste de desempenho:

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/performance-settings

# copy the artifacts
cp performance-settings.sh /opt/performance-settings/

O conteúdo do custom/files/performance-settings.sh é um script que pode ser usado para configurar o sistema para ajuste de desempenho e pode ser baixado acessando este link.

42.3.2.5 Script SR-IOV

O seguinte script opcional (custom/scripts/04-sriov.sh) pode ser usado para configurar o sistema para SR-IOV:

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/sriov
# copy the artifacts
cp sriov-auto-filler.sh /opt/sriov/sriov-auto-filler.sh

O conteúdo do custom/files/sriov-auto-filler.sh é um script que pode ser usado para configurar o sistema para SR-IOV e pode ser baixado acessando este link.

42.3.2.6 Arquivos personalizados para cenários air-gapped

O diretório custom/files contém as imagens do rke2 e cni que devem ser copiadas para a imagem durante o processo de criação dela. Para gerar as imagens com facilidade, prepare-as no local usando o seguinte script e a lista de imagens aqui para gerar os artefatos necessários para incluir em custom/files. Você também pode fazer download do script rke2-install mais recente aqui.

$ ./edge-save-rke2-images.sh -o custom/files -l ~/edge-release-rke2-images.txt

Após o download das imagens, a estrutura de diretórios deve ter esta aparência:

└── custom/
    └ files/
        └ install.sh
        └ rke2-images-cilium.linux-amd64.tar.zst
        └ rke2-images-core.linux-amd64.tar.zst
        └ rke2-images-multus.linux-amd64.tar.zst
        └ rke2-images.linux-amd64.tar.zst
        └ rke2.linux-amd64.tar.zst
        └ sha256sum-amd64.txt

42.3.2.7 Pré-carregar seu registro particular com as imagens necessárias para cenários air-gapped e SR-IOV (opcional)

Para usar SR-IOV em seu cenário air-gapped ou qualquer outra imagem de carga de trabalho, você deve pré-carregar o registro particular local com as imagens seguindo as próximas etapas:

  • Faça download, extraia e envie as imagens OCI de gráfico Helm ao registro particular

  • Faça download, extraia e envie o restante das imagens necessárias ao registro particular

É possível usar os seguintes scripts para fazer download, extrair e enviar as imagens ao registro particular. Vamos mostrar um exemplo para pré-carregar as imagens SR-IOV, mas você também pode usar a mesma abordagem para pré-carregar qualquer outra imagem personalizada:

  1. Pré-carregamento com imagens OCI de gráfico Helm para SR-IOV:

    1. Você deve criar uma lista com as imagens OCI de gráfico Helm necessárias:

      $ cat > edge-release-helm-oci-artifacts.txt <<EOF
      edge/sriov-network-operator-chart:303.0.2+up1.5.0
      edge/sriov-crd-chart:303.0.2+up1.5.0
      EOF
    2. Gere um arquivo tarball local usando o seguinte script e a lista criada acima:

      $ ./edge-save-oci-artefacts.sh -al ./edge-release-helm-oci-artifacts.txt -s registry.suse.com
      Pulled: registry.suse.com/edge/charts/sriov-network-operator:303.0.2+up1.5.0
      Pulled: registry.suse.com/edge/charts/sriov-crd:303.0.2+up1.5.0
      a edge-release-oci-tgz-20240705
      a edge-release-oci-tgz-20240705/sriov-network-operator-chart-303.0.2+up1.5.0.tgz
      a edge-release-oci-tgz-20240705/sriov-crd-chart-303.0.2+up1.5.0.tgz
    3. Faça upload do arquivo tarball para seu registro particular (por exemplo, myregistry:5000) usando o seguinte script para pré-carregar o registro com as imagens OCI do gráfico Helm baixadas na etapa anterior:

      $ tar zxvf edge-release-oci-tgz-20240705.tgz
      $ ./edge-load-oci-artefacts.sh -ad edge-release-oci-tgz-20240705 -r myregistry:5000
  2. Pré-carregamento com o restante das imagens necessárias para SR-IOV:

    1. Nesse caso, devemos incluir as imagens do contêiner `sr-iov para cargas de trabalho de telecomunicações (por exemplo, como referência, você pode obtê-las dos valores de gráfico Helm)

      $ cat > edge-release-images.txt <<EOF
      rancher/hardened-sriov-network-operator:v1.3.0-build20240816
      rancher/hardened-sriov-network-config-daemon:v1.3.0-build20240816
      rancher/hardened-sriov-cni:v2.8.1-build20240820
      rancher/hardened-ib-sriov-cni:v1.1.1-build20240816
      rancher/hardened-sriov-network-device-plugin:v3.7.0-build20240816
      rancher/hardened-sriov-network-resources-injector:v1.6.0-build20240816
      rancher/hardened-sriov-network-webhook:v1.3.0-build20240816
      EOF
    2. Usando o seguinte script e a lista criada acima, você deve gerar localmente o arquivo tarball com as imagens necessárias:

      $ ./edge-save-images.sh -l ./edge-release-images.txt -s registry.suse.com
      Image pull success: registry.suse.com/rancher/hardened-sriov-network-operator:v1.3.0-build20240816
      Image pull success: registry.suse.com/rancher/hardened-sriov-network-config-daemon:v1.3.0-build20240816
      Image pull success: registry.suse.com/rancher/hardened-sriov-cni:v2.8.1-build20240820
      Image pull success: registry.suse.com/rancher/hardened-ib-sriov-cni:v1.1.1-build20240816
      Image pull success: registry.suse.com/rancher/hardened-sriov-network-device-plugin:v3.7.0-build20240816
      Image pull success: registry.suse.com/rancher/hardened-sriov-network-resources-injector:v1.6.0-build20240816
      Image pull success: registry.suse.com/rancher/hardened-sriov-network-webhook:v1.3.0-build20240816
      Creating edge-images.tar.gz with 7 images
    3. Faça upload do arquivo tarball para seu registro particular (por exemplo, myregistry:5000) usando o seguinte script para pré-carregar o registro particular com as imagens baixadas na etapa anterior:

      $ tar zxvf edge-release-images-tgz-20240705.tgz
      $ ./edge-load-images.sh -ad edge-release-images-tgz-20240705 -r myregistry:5000

42.3.3 Criação da imagem para cenários air-gapped

Depois que a estrutura de diretórios for preparada de acordo com as seções anteriores, execute o seguinte comando para criar a imagem:

podman run --rm --privileged -it -v $PWD:/eib \
 registry.suse.com/edge/3.3/edge-image-builder:1.2.1 \
 build --definition-file downstream-cluster-airgap-config.yaml

Esse procedimento cria o arquivo da imagem ISO de saída chamado eibimage-output-telco.raw, com base na definição descrita acima.

Em seguida, disponibilize a imagem de saída por um servidor web, ou o contêiner de servidor de mídia habilitado de acordo com as instruções na documentação sobre o cluster de gerenciamento (Nota) ou algum outro servidor acessível localmente. Nos exemplos abaixo, esse servidor é mencionado como imagecache.local:8080.

42.4 Provisionamento de cluster downstream com provisionamento de rede direcionado (nó único)

Esta seção descreve o fluxo de trabalho usado para automatizar o provisionamento de um cluster downstream de nó único usando o provisionamento de rede direcionado. Essa é a maneira mais fácil de automatizar o provisionamento de um cluster downstream.

Requisitos

Fluxo de trabalho

O diagrama a seguir mostra o fluxo de trabalho usado para automatizar o provisionamento de um cluster downstream de nó único por meio do provisionamento de rede direcionado:

nóúnico1 automatizado atip

Há duas etapas diferentes para automatizar o provisionamento de um cluster downstream de nó único por meio do provisionamento de rede direcionado:

  1. Registre o host bare metal para disponibilizá-lo ao processo de provisionamento.

  2. Provisione o host bare metal para instalar e configurar o sistema operacional e o cluster Kubernetes.

Registrar o host bare metal

A primeira etapa é registrar o novo host bare metal no cluster de gerenciamento para disponibilizá-lo para provisionamento. Para fazer isso, é necessário criar este arquivo (bmh-example.yaml) no cluster de gerenciamento, para especificar as credenciais que serão usadas do BMC e o objeto BaremetalHost para registro:

apiVersion: v1
kind: Secret
metadata:
  name: example-demo-credentials
type: Opaque
data:
  username: ${BMC_USERNAME}
  password: ${BMC_PASSWORD}
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: example-demo
  labels:
    cluster-role: control-plane
spec:
  online: true
  bootMACAddress: ${BMC_MAC}
  rootDeviceHints:
    deviceName: /dev/nvme0n1
  bmc:
    address: ${BMC_ADDRESS}
    disableCertificateVerification: true
    credentialsName: example-demo-credentials

em que:

  • ${BMC_USERNAME}: o nome de usuário para o BMC do novo host bare metal.

  • ${BMC_PASSWORD}: a senha para o BMC do novo host bare metal.

  • ${BMC_MAC}: o endereço MAC do novo host bare metal que será usado.

  • ${BMC_ADDRESS}: o URL do host bare metal BMC (por exemplo, redfish-virtualmedia://192.168.200.75/redfish/v1/Systems/1/). Para saber mais sobre as diversas opções disponíveis de acordo com o seu provedor de hardware, acesse este link.

Nota
Nota

Se não foi especificada uma configuração de rede para o host, seja no momento da criação da imagem, seja pela definição BareMetalHost, é usado um mecanismo de configuração automática (DHCP, DHCPv6, SLAAC). Para obter mais detalhes ou ver configurações mais complexas, consulte a Seção 42.6, “Configuração avançada de rede”.

Depois que o arquivo for criado, execute o seguinte comando no cluster de gerenciamento para iniciar o registro do novo host bare metal:

$ kubectl apply -f bmh-example.yaml

O novo objeto host bare metal será registrado, o que altera seu estado de "registrando" para "inspecionando" e "disponível". Para verificar as alterações, use o seguinte comando:

$ kubectl get bmh
Nota
Nota

O objeto BaremetalHost fica no estado registering até a validação das credenciais do BMC. Depois disso, o estado do objeto BaremetalHost muda para inspecting, e essa etapa pode levar algum tempo dependendo do hardware (até 20 minutos). Durante a fase de inspeção, as informações do hardware são recuperadas e o objeto Kubernetes é atualizado. Para verificar as informações, use o seguinte comando: kubectl get bmh -o yaml.

Etapa de provisionamento

Depois que o host bare metal for registrado e estiver disponível, a próxima etapa será provisioná-lo para instalar e configurar o sistema operacional e o cluster Kubernetes. Para fazer isso, é necessário criar este arquivo (capi-provisioning-example.yaml) no cluster de gerenciamento com as seguintes informações (é possível gerar o capi-provisioning-example.yaml unindo os blocos abaixo).

Nota
Nota

Apenas os valores entre $\{…​\} devem ser substituídos pelos valores reais.

O bloco a seguir é a definição do cluster, em que a rede pode ser configurada usando os blocos pods e services. Ele também contém as referências aos objetos de plano de controle e infraestrutura (usando o provedor Metal3) a serem usados.

apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  name: single-node-cluster
  namespace: default
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - 192.168.0.0/18
    services:
      cidrBlocks:
        - 10.96.0.0/12
  controlPlaneRef:
    apiVersion: controlplane.cluster.x-k8s.io/v1beta1
    kind: RKE2ControlPlane
    name: single-node-cluster
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3Cluster
    name: single-node-cluster

Para uma implantação com pods e serviços de pilha dupla, a alternativa é usar a seguinte definição:

apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  name: single-node-cluster
  namespace: default
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - 192.168.0.0/18
        - fd00:bad:cafe::/48
    services:
      cidrBlocks:
        - 10.96.0.0/12
        - fd00:bad:bad:cafe::/112
  controlPlaneRef:
    apiVersion: controlplane.cluster.x-k8s.io/v1beta1
    kind: RKE2ControlPlane
    name: single-node-cluster
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3Cluster
    name: single-node-cluster
Importante
Importante

As implantações de IPv6 e pilha dupla estão com status de prévia de tecnologia e não contam com suporte oficial.

O objeto Metal3Cluster especifica o endpoint do plano de controle (para substituir o ${DOWNSTREAM_CONTROL_PLANE_IP}) que será configurado e o noCloudProvider, pois é usado um nó bare metal.

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3Cluster
metadata:
  name: single-node-cluster
  namespace: default
spec:
  controlPlaneEndpoint:
    host: ${DOWNSTREAM_CONTROL_PLANE_IP}
    port: 6443
  noCloudProvider: true

O objeto RKE2ControlPlane especifica a configuração do plano de controle e o objeto Metal3MachineTemplate especifica a imagem do plano de controle que serão usadas. Ele também contém as informações sobre o número de réplicas (neste caso, uma) e o plug-in de CNI (neste caso, Cilium) que serão usados. O bloco agentConfig contém o formato do Ignition e o additionalUserData a serem usados para configurar o nó RKE2, com informações como um systemd chamado rke2-preinstall.service para substituir automaticamente o BAREMETALHOST_UUID e o node-name durante o processo de provisionamento usando as informações do Ironic. Para permitir o multus com o cilium, um arquivo é criado no diretório de manifestos do servidor rke2 chamado rke2-cilium-config.yaml com a configuração que será usada. O último bloco de informações inclui a versão do Kubernetes a ser usada. ${RKE2_VERSION} é a versão do RKE2 que substituirá esse valor (por exemplo, v1.32.4+rke2r1).

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3MachineTemplate
    name: single-node-cluster-controlplane
  replicas: 1
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  serverConfig:
    cni: cilium
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        systemd:
          units:
            - name: rke2-preinstall.service
              enabled: true
              contents: |
                [Unit]
                Description=rke2-preinstall
                Wants=network-online.target
                Before=rke2-install.service
                ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                [Service]
                Type=oneshot
                User=root
                ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                ExecStart=/bin/sh -c "sed -i \"s/BAREMETALHOST_UUID/$(jq -r .uuid /mnt/openstack/latest/meta_data.json)/\" /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                ExecStartPost=/bin/sh -c "umount /mnt"
                [Install]
                WantedBy=multi-user.target
        storage:
          files:
            # https://docs.rke2.io/networking/multus_sriov#using-multus-with-cilium
            - path: /var/lib/rancher/rke2/server/manifests/rke2-cilium-config.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChartConfig
                  metadata:
                    name: rke2-cilium
                    namespace: kube-system
                  spec:
                    valuesContent: |-
                      cni:
                        exclusive: false
              mode: 0644
              user:
                name: root
              group:
                name: root
    kubelet:
      extraArgs:
        - provider-id=metal3://BAREMETALHOST_UUID
    nodeName: "localhost.localdomain"

O objeto Metal3MachineTemplate especifica as seguintes informações:

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3MachineTemplate
metadata:
  name: single-node-cluster-controlplane
  namespace: default
spec:
  template:
    spec:
      dataTemplate:
        name: single-node-cluster-controlplane-template
      hostSelector:
        matchLabels:
          cluster-role: control-plane
      image:
        checksum: http://imagecache.local:8080/eibimage-output-telco.raw.sha256
        checksumType: sha256
        format: raw
        url: http://imagecache.local:8080/eibimage-output-telco.raw

O objeto Metal3DataTemplate especifica o metaData para o cluster downstream.

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3DataTemplate
metadata:
  name: single-node-cluster-controlplane-template
  namespace: default
spec:
  clusterName: single-node-cluster
  metaData:
    objectNames:
      - key: name
        object: machine
      - key: local-hostname
        object: machine
      - key: local_hostname
        object: machine

Após a criação do arquivo unindo os blocos anteriores, execute o seguinte comando no cluster de gerenciamento para iniciar o provisionamento do novo host bare metal:

$ kubectl apply -f capi-provisioning-example.yaml

42.5 Provisionamento de cluster downstream com provisionamento de rede direcionado (vários nós)

Esta seção descreve o fluxo de trabalho usado para automatizar o provisionamento de um cluster downstream de vários nós usando o provisionamento de rede direcionado e o MetalLB como estratégia de balanceador de carga. Essa é a maneira mais simples de automatizar o provisionamento de clusters downstream. O diagrama abaixo mostra o fluxo de trabalho usado para automatizar o provisionamento de um cluster downstream de vários nós usando o provisionamento de rede direcionado e o MetalLB.

Requisitos

Fluxo de trabalho

O diagrama a seguir mostra o fluxo de trabalho usado para automatizar o provisionamento de um cluster downstream de vários nós por meio do provisionamento de rede direcionado:

váriosnós1 automatizar atip
  1. Registre os três hosts bare metal para disponibilizá-los ao processo de provisionamento.

  2. Provisione os três hosts bare metal para instalar e configurar o sistema operacional e o cluster Kubernetes usando o MetalLB.

Registrar os hosts bare metal

A primeira etapa é registrar os três hosts bare metal no cluster de gerenciamento para disponibilizá-los para provisionamento. Para fazer isso, é necessário criar estes arquivos (bmh-example-node1.yaml, bmh-example-node2.yaml e bmh-example-node3.yaml) no cluster de gerenciamento, para especificar as credenciais que serão usadas do BMC e o objeto BaremetalHost para registro no cluster de gerenciamento.

Nota
Nota
  • Apenas os valores entre $\{…​\} devem ser substituídos pelos valores reais.

  • Vamos orientar você apenas pelo processo de um host. As mesmas etapas são válidas para os outros dois nós.

apiVersion: v1
kind: Secret
metadata:
  name: node1-example-credentials
type: Opaque
data:
  username: ${BMC_NODE1_USERNAME}
  password: ${BMC_NODE1_PASSWORD}
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: node1-example
  labels:
    cluster-role: control-plane
spec:
  online: true
  bootMACAddress: ${BMC_NODE1_MAC}
  bmc:
    address: ${BMC_NODE1_ADDRESS}
    disableCertificateVerification: true
    credentialsName: node1-example-credentials

Em que:

  • ${BMC_NODE1_USERNAME}: o nome de usuário para o BMC do primeiro host bare metal.

  • ${BMC_NODE1_PASSWORD}: a senha para o BMC do primeiro host bare metal.

  • ${BMC_NODE1_MAC}: o endereço MAC do primeiro host bare metal que será usado.

  • ${BMC_NODE1_ADDRESS}: o URL do primeiro host bare metal BMC (por exemplo, redfish-virtualmedia://192.168.200.75/redfish/v1/Systems/1/). Para saber mais sobre as diversas opções disponíveis de acordo com o seu provedor de hardware, acesse este link.

Nota
Nota
  • Se não foi especificada uma configuração de rede para o host, seja no momento da criação da imagem, seja pela definição BareMetalHost, é usado um mecanismo de configuração automática (DHCP, DHCPv6, SLAAC). Para obter mais detalhes ou ver configurações mais complexas, consulte a Seção 42.6, “Configuração avançada de rede”.

  • Ainda não há suporte para clusters de pilha dupla de vários nós ou somente IPv6.

Depois que o arquivo for criado, execute o seguinte comando no cluster de gerenciamento para iniciar o registro dos hosts bare metal:

$ kubectl apply -f bmh-example-node1.yaml
$ kubectl apply -f bmh-example-node2.yaml
$ kubectl apply -f bmh-example-node3.yaml

Os novos objetos host bare metal serão registrados, o que altera o estado deles de "registrando" para "inspecionando" e "disponíveis". Para verificar as alterações, use o seguinte comando:

$ kubectl get bmh -o wide
Nota
Nota

O objeto BaremetalHost fica no estado registering até a validação das credenciais do BMC. Depois disso, o estado do objeto BaremetalHost muda para inspecting, e essa etapa pode levar algum tempo dependendo do hardware (até 20 minutos). Durante a fase de inspeção, as informações do hardware são recuperadas e o objeto Kubernetes é atualizado. Para verificar as informações, use o seguinte comando: kubectl get bmh -o yaml.

Etapa de provisionamento

Depois que os três hosts bare metal forem registrados e estiverem disponíveis, a próxima etapa será provisioná-los para instalar e configurar o sistema operacional e o cluster Kubernetes, criando um balanceador de carga para gerenciá-los. Para fazer isso, é necessário criar este arquivo (capi-provisioning-example.yaml) no cluster de gerenciamento com as seguintes informações (é possível gerar o `capi-provisioning-example.yaml unindo os blocos abaixo).

Nota
Nota
  • Apenas os valores entre $\{…​\} devem ser substituídos pelos valores reais.

  • O endereço VIP é um IP reservado não atribuído a nenhum nó e usado para configurar o balanceador de carga.

Veja a seguir a definição do cluster, em que a rede do cluster pode ser configurada usando os blocos pods e services. Ela também contém as referências aos objetos de plano de controle e infraestrutura (usando o provedor Metal3) a serem usados.

apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  name: multinode-cluster
  namespace: default
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - 192.168.0.0/18
    services:
      cidrBlocks:
        - 10.96.0.0/12
  controlPlaneRef:
    apiVersion: controlplane.cluster.x-k8s.io/v1beta1
    kind: RKE2ControlPlane
    name: multinode-cluster
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3Cluster
    name: multinode-cluster

O objeto Metal3Cluster especifica o endpoint do plano de controle que usa o endereço VIP já reservado (para substituir o ${DOWNSTREAM_VIP_ADDRESS}) que será configurado e o noCloudProvider, pois são usados três nós bare metal.

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3Cluster
metadata:
  name: multinode-cluster
  namespace: default
spec:
  controlPlaneEndpoint:
    host: ${EDGE_VIP_ADDRESS}
    port: 6443
  noCloudProvider: true

O objeto RKE2ControlPlane especifica a configuração do plano de controle e o objeto Metal3MachineTemplate especifica a imagem do plano de controle que serão usadas.

  • O número de réplicas a ser usado (neste caso, três).

  • O modo de anúncio usado pelo balanceador de carga (address usa a implementação L2) e o endereço que será usado (substituindo o ${EDGE_VIP_ADDRESS} pelo endereço VIP).

  • O serverConfig com o plug-in de CNI usado (neste caso, Cilium) e o tlsSan usado para configurar o endereço VIP.

  • O bloco agentConfig inclui o formato usado do Ignition e o additionalUserData usado para configurar o nó RKE2 com informações como:

    • O serviço systemd chamado rke2-preinstall.service para substituir automaticamente o BAREMETALHOST_UUID e o node-name durante o processo de provisionamento com as informações do Ironic.

    • O bloco storage que contém os gráficos Helm que serão usados para instalar o MetalLB e o endpoint-copier-operator.

    • O arquivo de recurso personalizado metalLB com o IPaddressPool e o L2Advertisement que serão usados (substituindo ${EDGE_VIP_ADDRESS} pelo endereço VIP).

    • O arquivo endpoint-svc.yaml que será usado para configurar o serviço kubernetes-vip usado pelo MetalLB para gerenciar o endereço VIP.

  • Os último bloco de informações contém a versão do Kubernetes que será usada. A ${RKE2_VERSION} é a versão do RKE2 que será usada no lugar desse valor (por exemplo, v1.32.4+rke2r1).

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
  name: multinode-cluster
  namespace: default
spec:
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3MachineTemplate
    name: multinode-cluster-controlplane
  replicas: 3
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  registrationMethod: "control-plane-endpoint"
  registrationAddress: ${EDGE_VIP_ADDRESS}
  serverConfig:
    cni: cilium
    tlsSan:
      - ${EDGE_VIP_ADDRESS}
      - https://${EDGE_VIP_ADDRESS}.sslip.io
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        systemd:
          units:
            - name: rke2-preinstall.service
              enabled: true
              contents: |
                [Unit]
                Description=rke2-preinstall
                Wants=network-online.target
                Before=rke2-install.service
                ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                [Service]
                Type=oneshot
                User=root
                ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                ExecStart=/bin/sh -c "sed -i \"s/BAREMETALHOST_UUID/$(jq -r .uuid /mnt/openstack/latest/meta_data.json)/\" /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                ExecStartPost=/bin/sh -c "umount /mnt"
                [Install]
                WantedBy=multi-user.target
        storage:
          files:
            # https://docs.rke2.io/networking/multus_sriov#using-multus-with-cilium
            - path: /var/lib/rancher/rke2/server/manifests/rke2-cilium-config.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChartConfig
                  metadata:
                    name: rke2-cilium
                    namespace: kube-system
                  spec:
                    valuesContent: |-
                      cni:
                        exclusive: false
              mode: 0644
              user:
                name: root
              group:
                name: root
            - path: /var/lib/rancher/rke2/server/manifests/endpoint-copier-operator.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: endpoint-copier-operator
                    namespace: kube-system
                  spec:
                    chart: oci://registry.suse.com/edge/charts/endpoint-copier-operator
                    targetNamespace: endpoint-copier-operator
                    version: 303.0.0+up0.2.1
                    createNamespace: true
            - path: /var/lib/rancher/rke2/server/manifests/metallb.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: metallb
                    namespace: kube-system
                  spec:
                    chart: oci://registry.suse.com/edge/charts/metallb
                    targetNamespace: metallb-system
                    version: 303.0.0+up0.14.9
                    createNamespace: true

            - path: /var/lib/rancher/rke2/server/manifests/metallb-cr.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: metallb.io/v1beta1
                  kind: IPAddressPool
                  metadata:
                    name: kubernetes-vip-ip-pool
                    namespace: metallb-system
                  spec:
                    addresses:
                      - ${EDGE_VIP_ADDRESS}/32
                    serviceAllocation:
                      priority: 100
                      namespaces:
                        - default
                      serviceSelectors:
                        - matchExpressions:
                          - {key: "serviceType", operator: In, values: [kubernetes-vip]}
                  ---
                  apiVersion: metallb.io/v1beta1
                  kind: L2Advertisement
                  metadata:
                    name: ip-pool-l2-adv
                    namespace: metallb-system
                  spec:
                    ipAddressPools:
                      - kubernetes-vip-ip-pool
            - path: /var/lib/rancher/rke2/server/manifests/endpoint-svc.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: v1
                  kind: Service
                  metadata:
                    name: kubernetes-vip
                    namespace: default
                    labels:
                      serviceType: kubernetes-vip
                  spec:
                    ports:
                    - name: rke2-api
                      port: 9345
                      protocol: TCP
                      targetPort: 9345
                    - name: k8s-api
                      port: 6443
                      protocol: TCP
                      targetPort: 6443
                    type: LoadBalancer
    kubelet:
      extraArgs:
        - provider-id=metal3://BAREMETALHOST_UUID
    nodeName: "Node-multinode-cluster"

O objeto Metal3MachineTemplate especifica as seguintes informações:

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3MachineTemplate
metadata:
  name: multinode-cluster-controlplane
  namespace: default
spec:
  template:
    spec:
      dataTemplate:
        name: multinode-cluster-controlplane-template
      hostSelector:
        matchLabels:
          cluster-role: control-plane
      image:
        checksum: http://imagecache.local:8080/eibimage-output-telco.raw.sha256
        checksumType: sha256
        format: raw
        url: http://imagecache.local:8080/eibimage-output-telco.raw

O objeto Metal3DataTemplate especifica o metaData para o cluster downstream.

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3DataTemplate
metadata:
  name: multinode-cluster-controlplane-template
  namespace: default
spec:
  clusterName: multinode-cluster
  metaData:
    objectNames:
      - key: name
        object: machine
      - key: local-hostname
        object: machine
      - key: local_hostname
        object: machine

Após a criação do arquivo unindo os blocos anteriores, execute o seguinte comando no cluster de gerenciamento para iniciar o provisionamento dos três novos hosts bare metal:

$ kubectl apply -f capi-provisioning-example.yaml

42.6 Configuração avançada de rede

O fluxo de trabalho de provisionamento de rede direcionado permite fazer configurações de rede específicas nos clusters downstream, como IPs estáticos, vínculo, VLANs, IPv6 etc.

As seções a seguir descrevem as etapas adicionais necessárias para permitir o provisionamento de clusters downstream usando a configuração de rede avançada.

Requisitos

Configuração

Antes de continuar, consulte uma das seções a seguir para obter orientação sobre as etapas necessárias para registrar e provisionar os hosts:

É necessário aplicar uma configuração de rede avançada no momento do registro por meio de uma definição do host BareMetalHost e um segredo associado que contém um bloco networkData no formato nmstate. O arquivo de exemplo a seguir define um segredo com o networkData necessário que solicita um IP estático e a VLAN para o host do cluster downstream:

apiVersion: v1
kind: Secret
metadata:
  name: controlplane-0-networkdata
type: Opaque
stringData:
  networkData: |
    interfaces:
    - name: ${CONTROLPLANE_INTERFACE}
      type: ethernet
      state: up
      mtu: 1500
      identifier: mac-address
      mac-address: "${CONTROLPLANE_MAC}"
      ipv4:
        address:
        - ip:  "${CONTROLPLANE_IP}"
          prefix-length: "${CONTROLPLANE_PREFIX}"
        enabled: true
        dhcp: false
    - name: floating
      type: vlan
      state: up
      vlan:
        base-iface: ${CONTROLPLANE_INTERFACE}
        id: ${VLAN_ID}
    dns-resolver:
      config:
        server:
        - "${DNS_SERVER}"
    routes:
      config:
      - destination: 0.0.0.0/0
        next-hop-address: "${CONTROLPLANE_GATEWAY}"
        next-hop-interface: ${CONTROLPLANE_INTERFACE}

Como você pode ver, o exemplo mostra a configuração para habilitar a interface com os IPs estáticos e a VLAN usando a interface base, depois que as seguintes variáveis são substituídas pelos valores reais, de acordo com a sua infraestrutura:

  • ${CONTROLPLANE1_INTERFACE}: a interface do plano de controle que será usada para o cluster Edge (por exemplo, eth0). Incluindo o identifier: mac-address, o endereço MAC inspeciona automaticamente a nomenclatura para que qualquer nome de interface possa ser usado.

  • ${CONTROLPLANE1_IP}: o endereço IP usado como endpoint para o cluster de borda (deve corresponder ao endpoint do servidor kubeapi).

  • ${CONTROLPLANE1_PREFIX}: o CIDR usado para o cluster de borda (por exemplo, 24 para /24 ou 255.255.255.0).

  • ${CONTROLPLANE1_GATEWAY}: o gateway usado para o cluster de borda (por exemplo, 192.168.100.1).

  • ${CONTROLPLANE1_MAC}: o endereço MAC usado para a interface do plano de controle (por exemplo, 00:0c:29:3e:3e:3e).

  • ${DNS_SERVER}: o DNS usado para o cluster de borda (por exemplo, 192.168.100.2).

  • ${VLAN_ID}: o ID da VLAN usado para o cluster de borda (por exemplo, 100).

É possível usar qualquer outra definição adequada a nmstate para configurar a rede do cluster downstream de acordo com os requisitos específicos. Por exemplo, é possível especificar uma configuração de pilha dupla estática:

apiVersion: v1
kind: Secret
metadata:
  name: controlplane-0-networkdata
type: Opaque
stringData:
  networkData: |
    interfaces:
    - name: ${CONTROLPLANE_INTERFACE}
      type: ethernet
      state: up
      mac-address: ${CONTROLPLANE_MAC}
      ipv4:
        enabled: true
        dhcp: false
        address:
        - ip: ${CONTROLPLANE_IP_V4}
          prefix-length: ${CONTROLPLANE_PREFIX_V4}
      ipv6:
        enabled: true
        dhcp: false
        autoconf: false
        address:
        - ip: ${CONTROLPLANE_IP_V6}
          prefix-length: ${CONTROLPLANE_PREFIX_V6}
    routes:
      config:
      - destination: 0.0.0.0/0
        next-hop-address: ${CONTROLPLANE_GATEWAY_V4}
        next-hop-interface: ${CONTROLPLANE_INTERFACE}
      - destination: ::/0
        next-hop-address: ${CONTROLPLANE_GATEWAY_V6}
        next-hop-interface: ${CONTROLPLANE_INTERFACE}
    dns-resolver:
      config:
        server:
        - ${DNS_SERVER_V4}
        - ${DNS_SERVER_V6}

Assim como no exemplo anterior, substitua as seguintes variáveis pelos valores reais, de acordo com a sua infraestrutura:

  • ${CONTROLPLANE_IP_V4}: o endereço IPv4 para atribuir ao host

  • ${CONTROLPLANE_PREFIX_V4}: o prefixo IPv4 da rede à qual pertence o IP do host

  • ${CONTROLPLANE_IP_V6}: o endereço IPv6 para atribuir ao host

  • ${CONTROLPLANE_PREFIX_V6}: o prefixo IPv6 da rede à qual pertence o IP do host

  • ${CONTROLPLANE_GATEWAY_V4}: o endereço IPv4 do gateway para o tráfego correspondente à rota padrão

  • ${CONTROLPLANE_GATEWAY_V6}: o endereço IPv6 do gateway para o tráfego correspondente à rota padrão

  • ${CONTROLPLANE_INTERFACE}: o nome da interface à qual atribuir os endereços e que será usada para o tráfego de saída correspondente à rota padrão, para ambos IPv4 e IPv6

  • ${DNS_SERVER_V4} e/ou ${DNS_SERVER_V6}: os endereços IP dos servidores DNS, que podem ser especificados como uma única ou várias entradas. Há suporte para os endereços tanto IPv4 quanto IPv6

Importante
Importante

As implantações de IPv6 e pilha dupla estão com status de prévia de tecnologia e não contam com suporte oficial.

Nota
Nota

Acesse o repositório de exemplos do SUSE Edge for Telco para ver exemplos mais complexos, incluindo configurações somente IPv6 e de pilha dupla.

Por fim, sejam quais forem os detalhes da configuração de rede, garanta que o segredo seja referenciado anexando preprovisioningNetworkDataName ao objeto BaremetalHost para registrar o host no cluster de gerenciamento com sucesso.

apiVersion: v1
kind: Secret
metadata:
  name: example-demo-credentials
type: Opaque
data:
  username: ${BMC_USERNAME}
  password: ${BMC_PASSWORD}
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: example-demo
  labels:
    cluster-role: control-plane
spec:
  online: true
  bootMACAddress: ${BMC_MAC}
  rootDeviceHints:
    deviceName: /dev/nvme0n1
  bmc:
    address: ${BMC_ADDRESS}
    disableCertificateVerification: true
    credentialsName: example-demo-credentials
  preprovisioningNetworkDataName: controlplane-0-networkdata
Nota
Nota
  • Se você precisa implantar um cluster de vários nós, siga o mesmo processo para cada nó.

  • Atualmente, o Metal3DataTemplate, o networkData e o Metal3 IPAM não são suportados. Apenas a configuração por meio de segredos estáticos conta com suporte total.

42.7 Recursos de telecomunicações (DPDK, SR-IOV, isolamento de CPU, HugePages, NUMA etc.)

O fluxo de trabalho de provisionamento de rede direcionado permite automatizar os recursos de telecomunicações que serão usados nos clusters downstream para executar as cargas de trabalho de telecomunicações nesses servidores.

Requisitos

Configuração

Use as duas seções a seguir como base para registrar e provisionar os hosts:

Os recursos de telecomunicações abordados nesta seção são:

  • DPDK e criação de VFs

  • Alocação de SR-IOV e VFs para as cargas de trabalho usarem

  • Isolamento de CPU e ajuste de desempenho

  • Configuração do HugePages

  • Ajuste de parâmetros do kernel

Nota
Nota

Para obter mais informações sobre os recursos de telecomunicações, consulte o Capítulo 41, Configuração dos recursos de telecomunicações.

As alterações necessárias para habilitar os recursos de telecomunicações mostrados acima estão todas no bloco RKE2ControlPlane do arquivo de provisionamento capi-provisioning-example.yaml. O restante das informações no arquivo capi-provisioning-example.yaml é o mesmo que as informações apresentadas na seção de provisionamento (Seção 42.4, “Provisionamento de cluster downstream com provisionamento de rede direcionado (nó único)”).

Para esclarecer o processo, as alterações necessárias neste bloco (RKE2ControlPlane) para habilitar os recursos de telecomunicações são:

  • Os preRKE2Commands usados para executar os comandos antes do processo de instalação do RKE2. Neste caso, use o comando modprobe para habilitar os módulos do kernel vfio-pci e SR-IOV.

  • O arquivo do Ignition /var/lib/rancher/rke2/server/manifests/configmap-sriov-custom-auto.yaml que será usado para definir as interfaces, os drivers e o número de VFs que será criado e exposto às cargas de trabalho.

    • Os valores no mapa de configuração sriov-custom-auto-config são os únicos que precisam ser substituídos pelos valores reais.

      • ${RESOURCE_NAME1}: o nome do recurso usado para a primeira interface PF (por exemplo, sriov-resource-du1). Ele é adicionado ao prefixo rancher.io usado como o rótulo que as cargas de trabalho usarão (por exemplo, rancher.io/sriov-resource-du1).

      • ${SRIOV-NIC-NAME1}: o nome da primeira interface PF que será usada (por exemplo, eth0).

      • ${PF_NAME1}: o nome da primeira função física PF que será usada. Gere filtros mais complexos usando este comando (por exemplo, eth0#2-5).

      • ${DRIVER_NAME1}: o nome do driver que será usado para a primeira interface VF (por exemplo, vfio-pci).

      • ${NUM_VFS1}: o número de VFs que será criado para a primeira interface PF (por exemplo, 8).

  • O /var/sriov-auto-filler.sh usado como conversor entre o mapa de configuração de alto nível sriov-custom-auto-config e o sriovnetworknodepolicy, que contém as informações de hardware de baixo nível. Esse script foi criado para eliminar a complexidade do usuário em ter que saber com antecedência as informações do hardware. Não há necessidade de alterações no arquivo, mas ele deverá estar presente se precisarmos habilitar sr-iov e criar VFs.

  • Os argumentos do kernel que serão usados para habilitar os seguintes recursos:

Parâmetro

Valor

Descrição

isolcpus

domain,nohz,managed_irq,1-30,33-62

Isolar os núcleos 1-30 e 33-62.

skew_tick

1

Permite que o kernel distribua as interrupções do temporizador entre as CPUs isoladas.

nohz

on

Permite que o kernel execute o tick do temporizador em uma única CPU quando o sistema está ocioso.

nohz_full

1-30,33-62

O parâmetro de inicialização do kernel é a interface principal atual para configurar dynticks completos junto com o isolamento de CPU.

rcu_nocbs

1-30,33-62

Permite que o kernel execute os retornos de chamada RCU em uma única CPU quando o sistema está ocioso.

irqaffinity

0,31,32,63

Permite que o kernel execute as interrupções em uma única CPU quando o sistema está ocioso.

idle

poll

Minimiza a latência de sair do estado ocioso.

iommu

pt

Permite usar vfio para as interfaces dpdk.

intel_iommu

on

Permite usar vfio para VFs.

hugepagesz

1G

Permite definir o tamanho das páginas enormes como 1 G.

hugepages

40

O número de páginas enormes definido antes.

default_hugepagesz

1G

O valor padrão para habilitar o HugePages.

nowatchdog

 

Desabilita o watchdog.

nmi_watchdog

0

Desabilita o watchdog de NMI.

  • Os serviços systemd abaixo são usados para habilitar o seguinte:

    • rke2-preinstall.service para substituir automaticamente o BAREMETALHOST_UUID e o node-name durante o processo de provisionamento com as informações do Ironic.

    • cpu-partitioning.service para habilitar os núcleos de isolamento da CPU (por exemplo, 1-30,33-62).

    • performance-settings.service para habilitar o ajuste de desempenho da CPU.

    • sriov-custom-auto-vfs.service para instalar o gráfico Helm sriov. Aguarde a criação dos recursos personalizados e execute o /var/sriov-auto-filler.sh para substituir os valores no mapa de configuração sriov-custom-auto-config e criar o sriovnetworknodepolicy que as cargas de trabalho usarão.

  • A ${RKE2_VERSION} é a versão do RKE2 usada no lugar desse valor (por exemplo, v1.32.4+rke2r1).

Com todas essas alterações mencionadas, o bloco RKE2ControlPlane no capi-provisioning-example.yaml terá a seguinte aparência:

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3MachineTemplate
    name: single-node-cluster-controlplane
  replicas: 1
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  serverConfig:
    cni: calico
    cniMultusEnable: true
  preRKE2Commands:
    - modprobe vfio-pci enable_sriov=1 disable_idle_d3=1
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        storage:
          files:
            - path: /var/lib/rancher/rke2/server/manifests/configmap-sriov-custom-auto.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: v1
                  kind: ConfigMap
                  metadata:
                    name: sriov-custom-auto-config
                    namespace: kube-system
                  data:
                    config.json: |
                      [
                         {
                           "resourceName": "${RESOURCE_NAME1}",
                           "interface": "${SRIOV-NIC-NAME1}",
                           "pfname": "${PF_NAME1}",
                           "driver": "${DRIVER_NAME1}",
                           "numVFsToCreate": ${NUM_VFS1}
                         },
                         {
                           "resourceName": "${RESOURCE_NAME2}",
                           "interface": "${SRIOV-NIC-NAME2}",
                           "pfname": "${PF_NAME2}",
                           "driver": "${DRIVER_NAME2}",
                           "numVFsToCreate": ${NUM_VFS2}
                         }
                      ]
              mode: 0644
              user:
                name: root
              group:
                name: root
            - path: /var/lib/rancher/rke2/server/manifests/sriov-crd.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: sriov-crd
                    namespace: kube-system
                  spec:
                    chart: oci://registry.suse.com/edge/charts/sriov-crd
                    targetNamespace: sriov-network-operator
                    version: 303.0.2+up1.5.0
                    createNamespace: true
            - path: /var/lib/rancher/rke2/server/manifests/sriov-network-operator.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: sriov-network-operator
                    namespace: kube-system
                  spec:
                    chart: oci://registry.suse.com/edge/charts/sriov-network-operator
                    targetNamespace: sriov-network-operator
                    version: 303.0.2+up1.5.0
                    createNamespace: true
        kernel_arguments:
          should_exist:
            - intel_iommu=on
            - iommu=pt
            - idle=poll
            - mce=off
            - hugepagesz=1G hugepages=40
            - hugepagesz=2M hugepages=0
            - default_hugepagesz=1G
            - irqaffinity=${NON-ISOLATED_CPU_CORES}
            - isolcpus=domain,nohz,managed_irq,${ISOLATED_CPU_CORES}
            - nohz_full=${ISOLATED_CPU_CORES}
            - rcu_nocbs=${ISOLATED_CPU_CORES}
            - rcu_nocb_poll
            - nosoftlockup
            - nowatchdog
            - nohz=on
            - nmi_watchdog=0
            - skew_tick=1
            - quiet
        systemd:
          units:
            - name: rke2-preinstall.service
              enabled: true
              contents: |
                [Unit]
                Description=rke2-preinstall
                Wants=network-online.target
                Before=rke2-install.service
                ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                [Service]
                Type=oneshot
                User=root
                ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                ExecStart=/bin/sh -c "sed -i \"s/BAREMETALHOST_UUID/$(jq -r .uuid /mnt/openstack/latest/meta_data.json)/\" /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                ExecStartPost=/bin/sh -c "umount /mnt"
                [Install]
                WantedBy=multi-user.target
            - name: cpu-partitioning.service
              enabled: true
              contents: |
                [Unit]
                Description=cpu-partitioning
                Wants=network-online.target
                After=network.target network-online.target
                [Service]
                Type=oneshot
                User=root
                ExecStart=/bin/sh -c "echo isolated_cores=${ISOLATED_CPU_CORES} > /etc/tuned/cpu-partitioning-variables.conf"
                ExecStartPost=/bin/sh -c "tuned-adm profile cpu-partitioning"
                ExecStartPost=/bin/sh -c "systemctl enable tuned.service"
                [Install]
                WantedBy=multi-user.target
            - name: performance-settings.service
              enabled: true
              contents: |
                [Unit]
                Description=performance-settings
                Wants=network-online.target
                After=network.target network-online.target cpu-partitioning.service
                [Service]
                Type=oneshot
                User=root
                ExecStart=/bin/sh -c "/opt/performance-settings/performance-settings.sh"
                [Install]
                WantedBy=multi-user.target
            - name: sriov-custom-auto-vfs.service
              enabled: true
              contents: |
                [Unit]
                Description=SRIOV Custom Auto VF Creation
                Wants=network-online.target  rke2-server.target
                After=network.target network-online.target rke2-server.target
                [Service]
                User=root
                Type=forking
                TimeoutStartSec=900
                ExecStart=/bin/sh -c "while ! /var/lib/rancher/rke2/bin/kubectl --kubeconfig=/etc/rancher/rke2/rke2.yaml wait --for condition=ready nodes --all ; do sleep 2 ; done"
                ExecStartPost=/bin/sh -c "while [ $(/var/lib/rancher/rke2/bin/kubectl --kubeconfig=/etc/rancher/rke2/rke2.yaml get sriovnetworknodestates.sriovnetwork.openshift.io --ignore-not-found --no-headers -A | wc -l) -eq 0 ]; do sleep 1; done"
                ExecStartPost=/bin/sh -c "/opt/sriov/sriov-auto-filler.sh"
                RemainAfterExit=yes
                KillMode=process
                [Install]
                WantedBy=multi-user.target
    kubelet:
      extraArgs:
        - provider-id=metal3://BAREMETALHOST_UUID
    nodeName: "localhost.localdomain"

Após a criação do arquivo unindo os blocos anteriores, execute o seguinte comando no cluster de gerenciamento para iniciar o provisionamento do novo cluster downstream usando os recursos de telecomunicações:

$ kubectl apply -f capi-provisioning-example.yaml

42.8 Registro particular

É possível configurar um registro particular como espelho para as imagens que as cargas de trabalho usam.

Para isso, criamos o segredo com as informações sobre o registro particular que será usado pelo cluster downstream.

apiVersion: v1
kind: Secret
metadata:
  name: private-registry-cert
  namespace: default
data:
  tls.crt: ${TLS_CERTIFICATE}
  tls.key: ${TLS_KEY}
  ca.crt: ${CA_CERTIFICATE}
type: kubernetes.io/tls
---
apiVersion: v1
kind: Secret
metadata:
  name: private-registry-auth
  namespace: default
data:
  username: ${REGISTRY_USERNAME}
  password: ${REGISTRY_PASSWORD}

O tls.crt, tls.key e ca.crt são os certificados usados para autenticar o registro particular. O username e a password são as credenciais usadas para autenticar o registro particular.

Nota
Nota

O tls.crt, tls.key, ca.crt , username e password devem ser codificados no formato base64 antes de serem usados no segredo.

Com todas essas alterações mencionadas, o bloco RKE2ControlPlane no capi-provisioning-example.yaml terá a seguinte aparência:

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3MachineTemplate
    name: single-node-cluster-controlplane
  replicas: 1
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  privateRegistriesConfig:
    mirrors:
      "registry.example.com":
        endpoint:
          - "https://registry.example.com:5000"
    configs:
      "registry.example.com":
        authSecret:
          apiVersion: v1
          kind: Secret
          namespace: default
          name: private-registry-auth
        tls:
          tlsConfigSecret:
            apiVersion: v1
            kind: Secret
            namespace: default
            name: private-registry-cert
  serverConfig:
    cni: calico
    cniMultusEnable: true
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        systemd:
          units:
            - name: rke2-preinstall.service
              enabled: true
              contents: |
                [Unit]
                Description=rke2-preinstall
                Wants=network-online.target
                Before=rke2-install.service
                ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                [Service]
                Type=oneshot
                User=root
                ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                ExecStart=/bin/sh -c "sed -i \"s/BAREMETALHOST_UUID/$(jq -r .uuid /mnt/openstack/latest/meta_data.json)/\" /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                ExecStartPost=/bin/sh -c "umount /mnt"
                [Install]
                WantedBy=multi-user.target
    kubelet:
      extraArgs:
        - provider-id=metal3://BAREMETALHOST_UUID
    nodeName: "localhost.localdomain"

Em que registry.example.com é o nome de exemplo do registro particular usado pelo cluster downstream e deve ser substituído pelos valores reais.

42.9 Provisionamento de cluster downstream em cenários air-gapped

O fluxo de trabalho de provisionamento de rede direcionado permite automatizar o provisionamento de clusters downstream nos cenários air-gapped.

42.9.1 Requisitos para cenários air-gapped

  1. A imagem raw gerada pelo EIB deve incluir as imagens do contêiner específicas (imagens OCI de gráfico Helm e do contêiner) necessárias para executar o cluster downstream em um cenário air-gapped. Para obter mais informações, consulte esta seção (Seção 42.3, “Preparar uma imagem de cluster downstream para cenários air-gapped”).

  2. No caso de uso de SR-IOV ou qualquer outra carga de trabalho personalizada, as imagens necessárias para executar as cargas de trabalho devem ser pré-carregadas no registro particular, seguindo a seção sobre pré-carregamento no registro particular (Seção 42.3.2.7, “Pré-carregar seu registro particular com as imagens necessárias para cenários air-gapped e SR-IOV (opcional)”).

42.9.2 Registrar hosts bare metal em cenários air-gapped

O processo de registro de hosts bare metal no cluster de gerenciamento é o mesmo descrito na seção anterior (Seção 42.4, “Provisionamento de cluster downstream com provisionamento de rede direcionado (nó único)”).

42.9.3 Provisionar o cluster downstream em cenários air-gapped

Há algumas alterações importantes necessárias para provisionar o cluster downstream em cenários air-gapped:

  1. O bloco RKE2ControlPlane no arquivo capi-provisioning-example.yaml deve incluir a diretiva spec.agentConfig.airGapped: true.

  2. É necessário incluir a configuração do registro particular no bloco RKE2ControlPlane do arquivo capi-provisioning-airgap-example.yaml de acordo com a seção de registro particular (Seção 42.8, “Registro particular”).

  3. Se você usa SR-IOV ou qualquer outra configuração AdditionalUserData (script combustion) que requer a instalação de gráfico Helm, deve modificar o conteúdo para fazer referência ao registro particular, em vez de usar o registro público.

O exemplo a seguir mostra a configuração de SR-IOV no bloco AdditionalUserData do arquivo capi-provisioning-airgap-example.yaml com as modificações necessárias para fazer referência ao registro particular.

  • Referências de segredos do registro particular

  • Definição do gráfico Helm usando o registro particular em vez das imagens OCI públicas

# secret to include the private registry certificates
apiVersion: v1
kind: Secret
metadata:
  name: private-registry-cert
  namespace: default
data:
  tls.crt: ${TLS_BASE64_CERT}
  tls.key: ${TLS_BASE64_KEY}
  ca.crt: ${CA_BASE64_CERT}
type: kubernetes.io/tls
---
# secret to include the private registry auth credentials
apiVersion: v1
kind: Secret
metadata:
  name: private-registry-auth
  namespace: default
data:
  username: ${REGISTRY_USERNAME}
  password: ${REGISTRY_PASSWORD}
---
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3MachineTemplate
    name: single-node-cluster-controlplane
  replicas: 1
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  privateRegistriesConfig:       # Private registry configuration to add your own mirror and credentials
    mirrors:
      docker.io:
        endpoint:
          - "https://$(PRIVATE_REGISTRY_URL)"
    configs:
      "192.168.100.22:5000":
        authSecret:
          apiVersion: v1
          kind: Secret
          namespace: default
          name: private-registry-auth
        tls:
          tlsConfigSecret:
            apiVersion: v1
            kind: Secret
            namespace: default
            name: private-registry-cert
          insecureSkipVerify: false
  serverConfig:
    cni: calico
    cniMultusEnable: true
  preRKE2Commands:
    - modprobe vfio-pci enable_sriov=1 disable_idle_d3=1
  agentConfig:
    airGapped: true       # Airgap true to enable airgap mode
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        storage:
          files:
            - path: /var/lib/rancher/rke2/server/manifests/configmap-sriov-custom-auto.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: v1
                  kind: ConfigMap
                  metadata:
                    name: sriov-custom-auto-config
                    namespace: sriov-network-operator
                  data:
                    config.json: |
                      [
                         {
                           "resourceName": "${RESOURCE_NAME1}",
                           "interface": "${SRIOV-NIC-NAME1}",
                           "pfname": "${PF_NAME1}",
                           "driver": "${DRIVER_NAME1}",
                           "numVFsToCreate": ${NUM_VFS1}
                         },
                         {
                           "resourceName": "${RESOURCE_NAME2}",
                           "interface": "${SRIOV-NIC-NAME2}",
                           "pfname": "${PF_NAME2}",
                           "driver": "${DRIVER_NAME2}",
                           "numVFsToCreate": ${NUM_VFS2}
                         }
                      ]
              mode: 0644
              user:
                name: root
              group:
                name: root
            - path: /var/lib/rancher/rke2/server/manifests/sriov.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: v1
                  data:
                    .dockerconfigjson: ${REGISTRY_AUTH_DOCKERCONFIGJSON}
                  kind: Secret
                  metadata:
                    name: privregauth
                    namespace: kube-system
                  type: kubernetes.io/dockerconfigjson
                  ---
                  apiVersion: v1
                  kind: ConfigMap
                  metadata:
                    namespace: kube-system
                    name: example-repo-ca
                  data:
                    ca.crt: |-
                      -----BEGIN CERTIFICATE-----
                      ${CA_BASE64_CERT}
                      -----END CERTIFICATE-----
                  ---
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: sriov-crd
                    namespace: kube-system
                  spec:
                    chart: oci://${PRIVATE_REGISTRY_URL}/sriov-crd
                    dockerRegistrySecret:
                      name: privregauth
                    repoCAConfigMap:
                      name: example-repo-ca
                    createNamespace: true
                    set:
                      global.clusterCIDR: 192.168.0.0/18
                      global.clusterCIDRv4: 192.168.0.0/18
                      global.clusterDNS: 10.96.0.10
                      global.clusterDomain: cluster.local
                      global.rke2DataDir: /var/lib/rancher/rke2
                      global.serviceCIDR: 10.96.0.0/12
                    targetNamespace: sriov-network-operator
                    version: 303.0.2+up1.5.0
                  ---
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: sriov-network-operator
                    namespace: kube-system
                  spec:
                    chart: oci://${PRIVATE_REGISTRY_URL}/sriov-network-operator
                    dockerRegistrySecret:
                      name: privregauth
                    repoCAConfigMap:
                      name: example-repo-ca
                    createNamespace: true
                    set:
                      global.clusterCIDR: 192.168.0.0/18
                      global.clusterCIDRv4: 192.168.0.0/18
                      global.clusterDNS: 10.96.0.10
                      global.clusterDomain: cluster.local
                      global.rke2DataDir: /var/lib/rancher/rke2
                      global.serviceCIDR: 10.96.0.0/12
                    targetNamespace: sriov-network-operator
                    version: 303.0.2+up1.5.0
              mode: 0644
              user:
                name: root
              group:
                name: root
        kernel_arguments:
          should_exist:
            - intel_iommu=on
            - iommu=pt
            - idle=poll
            - mce=off
            - hugepagesz=1G hugepages=40
            - hugepagesz=2M hugepages=0
            - default_hugepagesz=1G
            - irqaffinity=${NON-ISOLATED_CPU_CORES}
            - isolcpus=domain,nohz,managed_irq,${ISOLATED_CPU_CORES}
            - nohz_full=${ISOLATED_CPU_CORES}
            - rcu_nocbs=${ISOLATED_CPU_CORES}
            - rcu_nocb_poll
            - nosoftlockup
            - nowatchdog
            - nohz=on
            - nmi_watchdog=0
            - skew_tick=1
            - quiet
        systemd:
          units:
            - name: rke2-preinstall.service
              enabled: true
              contents: |
                [Unit]
                Description=rke2-preinstall
                Wants=network-online.target
                Before=rke2-install.service
                ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                [Service]
                Type=oneshot
                User=root
                ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                ExecStart=/bin/sh -c "sed -i \"s/BAREMETALHOST_UUID/$(jq -r .uuid /mnt/openstack/latest/meta_data.json)/\" /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                ExecStartPost=/bin/sh -c "umount /mnt"
                [Install]
                WantedBy=multi-user.target
            - name: cpu-partitioning.service
              enabled: true
              contents: |
                [Unit]
                Description=cpu-partitioning
                Wants=network-online.target
                After=network.target network-online.target
                [Service]
                Type=oneshot
                User=root
                ExecStart=/bin/sh -c "echo isolated_cores=${ISOLATED_CPU_CORES} > /etc/tuned/cpu-partitioning-variables.conf"
                ExecStartPost=/bin/sh -c "tuned-adm profile cpu-partitioning"
                ExecStartPost=/bin/sh -c "systemctl enable tuned.service"
                [Install]
                WantedBy=multi-user.target
            - name: performance-settings.service
              enabled: true
              contents: |
                [Unit]
                Description=performance-settings
                Wants=network-online.target
                After=network.target network-online.target cpu-partitioning.service
                [Service]
                Type=oneshot
                User=root
                ExecStart=/bin/sh -c "/opt/performance-settings/performance-settings.sh"
                [Install]
                WantedBy=multi-user.target
            - name: sriov-custom-auto-vfs.service
              enabled: true
              contents: |
                [Unit]
                Description=SRIOV Custom Auto VF Creation
                Wants=network-online.target  rke2-server.target
                After=network.target network-online.target rke2-server.target
                [Service]
                User=root
                Type=forking
                TimeoutStartSec=1800
                ExecStart=/bin/sh -c "while ! /var/lib/rancher/rke2/bin/kubectl --kubeconfig=/etc/rancher/rke2/rke2.yaml wait --for condition=ready nodes --timeout=30m --all ; do sleep 10 ; done"
                ExecStartPost=/bin/sh -c "/opt/sriov/sriov-auto-filler.sh"
                RemainAfterExit=yes
                KillMode=process
                [Install]
                WantedBy=multi-user.target
    kubelet:
      extraArgs:
        - provider-id=metal3://BAREMETALHOST_UUID
    nodeName: "localhost.localdomain"
Documentation survey