1 Implantações automatizadas de BMC com Metal3 #
Metal3 é um projeto da CNCF que oferece recursos de gerenciamento de infraestrutura bare metal para Kubernetes.
O Metal3 inclui recursos nativos do Kubernetes para gerenciar o ciclo de vida de servidores bare metal que suportam gerenciamento com protocolos fora da banda, como o Redfish.
Ele também conta com suporte a Cluster API (CAPI), que permite gerenciar os recursos da infraestrutura de vários provedores por meio de APIs amplamente adotadas e independentes de fornecedor.
1.1 Por que usar este método #
Este método é útil em cenários com hardware de destino que permite o gerenciamento fora da banda e quando se deseja um fluxo de gerenciamento de infraestrutura automatizado.
O cluster de gerenciamento é configurado para oferecer APIs declarativas que permitem o gerenciamento de inventário e de estado dos servidores bare metal do cluster downstream, incluindo inspeção automatizada, limpeza e provisionamento/desprovisionamento.
1.2 Arquitetura de alto nível #
1.3 Pré-requisitos #
Há algumas restrições específicas relacionadas ao hardware e à rede de servidor do cluster downstream:
Cluster de gerenciamento
É preciso ter conectividade de rede com a API de gerenciamento/BMC do servidor de destino
É preciso ter conectividade com a rede do plano de controle do servidor de destino
Para clusters de gerenciamento de vários nós, é necessário um endereço IP reservado adicional
Hosts para serem controlados
É preciso ter suporte a gerenciamento fora da banda pelas interfaces do Redfish, iDRAC ou iLO
É preciso ter suporte à implantação por mídia virtual (não há suporte a PXE no momento)
É preciso ter conectividade de rede com o cluster de gerenciamento para acessar as APIs de provisionamento do Metal3
Algumas ferramentas são necessárias e podem ser instaladas no cluster de gerenciamento ou em um host que possa acessá-lo.
Um tempo de execução do contêiner, como Podman ou Rancher Desktop
Faça download do arquivo de imagem de sistema operacional
SL-Micro.x86_64-6.1-Base-GM.raw
pelo SUSE Customer Center ou pela página de download da
SUSE.
1.3.1 Configurar o cluster de gerenciamento #
As etapas básicas de instalação de um cluster de gerenciamento e uso do Metal3 são:
Instalar um cluster de gerenciamento RKE2
Instalar o Rancher
Instalar um provedor de armazenamento (opcional)
Instalar as dependências do Metal3
Instalar as dependências da CAPI pelo Rancher Turtles
Criar uma imagem do sistema operacional SLEMicro para hosts do cluster downstream
Registrar CRs de BareMetalHost para definir o inventário de bare metal
Criar um cluster downstream definindo recursos da CAPI
Este guia considera que já existe um cluster RKE2 e que o Rancher (incluindo o cert-manager) foi instalado, por exemplo, usando o Edge Image Builder (Capítulo 11, Edge Image Builder).
Estas etapas também podem ser totalmente automatizadas conforme descrito na documentação do cluster de gerenciamento (Capítulo 40, Configurando o cluster de gerenciamento).
1.3.2 Instalando as dependências do Metal3 #
O cert-manager deve ser instalado e executado caso não tenha sido junto com a instalação do Rancher.
É necessário instalar um provedor de armazenamento persistente. O SUSE
Storage é recomendado, mas também é possível usar o
local-path-provisioner
em ambientes de
desenvolvimento/PoC. A instrução abaixo considera que StorageClass foi marcada
como padrão; do contrário, será necessária uma configuração adicional
para o gráfico do Metal3.
Um IP adicional é necessário, que pode ser gerenciado por MetalLB para fornecer um endpoint consistente aos serviços de gerenciamento do Metal3. Esse IP deve fazer parte da sub-rede do plano de controle e ser reservado para configuração estática (e não fazer parte de um pool DHCP).
Se o cluster de gerenciamento é um nó único, é possível evitar o requisito de IP flutuante adicional gerenciado por MetalLB. Consulte a Seção 1.6.1, “Configuração de nó único”.
Vamos instalar primeiro o MetalLB:
helm install \ metallb oci://registry.suse.com/edge/charts/metallb \ --namespace metallb-system \ --create-namespace
Na sequência, definimos um
IPAddressPool
eL2Advertisement
usando o IP reservado, especificado abaixo comoSTATIC_IRONIC_IP
:export STATIC_IRONIC_IP=<STATIC_IRONIC_IP> cat <<-EOF | kubectl apply -f - apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: ironic-ip-pool namespace: metallb-system spec: addresses: - ${STATIC_IRONIC_IP}/32 serviceAllocation: priority: 100 serviceSelectors: - matchExpressions: - {key: app.kubernetes.io/name, operator: In, values: [metal3-ironic]} EOF
cat <<-EOF | kubectl apply -f - apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: ironic-ip-pool-l2-adv namespace: metallb-system spec: ipAddressPools: - ironic-ip-pool EOF
Agora é possível instalar o Metal3:
helm install \ metal3 oci://registry.suse.com/edge/charts/metal3 \ --namespace metal3-system \ --create-namespace \ --set global.ironicIP="$STATIC_IRONIC_IP"
A execução do contêiner init pode levar cerca de dois minutos nesta implantação, portanto, garanta que todos os pods estejam em execução antes de continuar:
kubectl get pods -n metal3-system NAME READY STATUS RESTARTS AGE baremetal-operator-controller-manager-85756794b-fz98d 2/2 Running 0 15m metal3-metal3-ironic-677bc5c8cc-55shd 4/4 Running 0 15m metal3-metal3-mariadb-7c7d6fdbd8-64c7l 1/1 Running 0 15m
Não avance para as etapas seguintes até que todos os pods no namespace
metal3-system
estejam em execução.
1.3.3 Instalando as dependências de API do cluster #
As dependências de API do cluster são gerenciadas pelo gráfico Helm do Rancher Turtles:
cat > values.yaml <<EOF
rancherTurtles:
features:
embedded-capi:
disabled: true
rancher-webhook:
cleanup: true
EOF
helm install \
rancher-turtles oci://registry.suse.com/edge/charts/rancher-turtles \
--namespace rancher-turtles-system \
--create-namespace \
-f values.yaml
Após algum tempo, os pods do controlador deverão estar em execução nos
namespaces capi-system
, capm3-system
,
rke2-bootstrap-system
e
rke2-control-plane-system
.
1.3.4 Preparar a imagem do cluster downstream #
O Kiwi (Capítulo 28, Criando imagens atualizadas do SUSE Linux Micro com o Kiwi) e o Edge Image Builder (Capítulo 11, Edge Image Builder) são usados para preparar a imagem base do SLEMicro modificado que foi provisionado nos hosts do cluster downstream.
Neste guia, abordamos a configuração mínima necessária para implantar o cluster downstream.
1.3.4.1 Configuração da imagem #
Primeiro siga o Capítulo 28, Criando imagens atualizadas do SUSE Linux Micro com o Kiwi para gerar uma imagem nova como a primeira etapa necessária para criar clusters.
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.Quando o download da imagem base é feito, ela é compactada com
xz
, que deve ser descompactada comunxz
e copiada/movida para a pastabase-images
.A pasta
network
é opcional. Consulte a Seção 1.3.5.1.1, “Script adicional para configuração de rede estática” para obter mais detalhes.O diretório custom/scripts contém scripts que são executados na primeira inicialização. Atualmente, um script
01-fix-growfs.sh
é necessário para redimensionar a partição raiz do sistema operacional na implantação.
├── 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
1.3.4.1.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: SLE-Micro-eib-output.raw
operatingSystem:
time:
timezone: Europe/London
ntp:
forceWait: true
pools:
- 2.suse.pool.ntp.org
servers:
- 10.0.0.1
- 10.0.0.2
kernelArgs:
- ignition.platform.id=openstack
- net.ifnames=1
systemd:
disable:
- rebootmgr
- transactional-update.timer
- transactional-update-cleanup.timer
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 contém 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.
O net.ifnames=1
habilita a Nomenclatura
de interface de rede previsível.
Isso corresponde à configuração padrão do gráfico do
Metal3, mas a configuração deve corresponder ao
valor predictableNicNames
do gráfico.
Veja também que o ignition.platform.id=openstack
é
obrigatório. Sem esse argumento, a configuração do SUSE Linux Micro pelo
ignition vai falhar no fluxo automatizado do
Metal3.
A seção time
é opcional, mas sua configuração é altamente
recomendada para evitar possíveis problemas com certificados e divergência
de relógio. O valor usado neste exemplo é somente para fins
ilustrativos. Ajuste-o de acordo com seus requisitos específicos.
1.3.4.1.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 /
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.
1.3.4.2 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
Ele cria o arquivo de imagem de saída chamado
SLE-Micro-eib-output.raw
, com base na definição descrita
acima.
Depois disso, a imagem de saída deverá estar disponível em um servidor web,
ou o contêiner de servidor de mídia habilitado pelo gráfico do Metal3 (Nota) ou um outro servidor acessível
localmente. Nos exemplos a seguir, chamamos esse servidor de
imagecache.local:8080
.
Na implantação de imagens EIB em clusters downstream, é necessário também
incluir a soma sha256 da imagem no objeto
Metal3MachineTemplate
. É possível gerá-la com este
comando:
sha256sum <image_file> > <image_file>.sha256
# On this example:
sha256sum SLE-Micro-eib-output.raw > SLE-Micro-eib-output.raw.sha256
1.3.5 Adicionando o inventário de BareMetalHost #
Para registrar servidores bare metal para implantação automatizada, é necessário criar dois recursos: um segredo com as credenciais de acesso ao BMC e um recurso BareMetalHost do Metal3 com a definição da conexão com o BMC e outros detalhes:
apiVersion: v1
kind: Secret
metadata:
name: controlplane-0-credentials
type: Opaque
data:
username: YWRtaW4=
password: cGFzc3dvcmQ=
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
name: controlplane-0
labels:
cluster-role: control-plane
spec:
online: true
bootMACAddress: "00:f3:65:8a:a3:b0"
bmc:
address: redfish-virtualmedia://192.168.125.1:8000/redfish/v1/Systems/68bd0fb6-d124-4d17-a904-cdf33efe83ab
disableCertificateVerification: true
credentialsName: controlplane-0-credentials
Observe o seguinte:
O nome de usuário/senha do segredo deve ser codificado com base64. Observe que ele não deve incluir novas linhas à direita (por exemplo, usar
echo -n
, não apenasecho
!)É possível definir o rótulo
cluster-role
agora ou mais tarde, durante a criação do cluster. No exemplo abaixo, esperamoscontrol-plane
ouworker
bootMACAddress
deve ser um MAC válido correspondente à NIC de plano de controle do hostO endereço
bmc
é a conexão com a API de gerenciamento de BMC. As seguintes opções são suportadas:redfish-virtualmedia://<ENDEREÇO IP>/redfish/v1/Systems/<ID DO SISTEMA>
: mídia virtual Redfish, por exemplo, SuperMicroidrac-virtualmedia://<ENDEREÇO IP>/redfish/v1/Systems/System.Embedded.1
: iDRAC da Dell
Consulte os documentos da API upstream para obter mais detalhes sobre a API BareMetalHost
1.3.5.1 Configurando IPs estáticos #
O exemplo do BareMetalHost acima considera que o DHCP configura a rede do plano de controle, mas nos cenários em que a configuração manual é necessária, como no caso dos IPs estáticos, é possível definir uma configuração adicional, conforme descrito abaixo.
1.3.5.1.1 Script adicional para configuração de rede estática #
Ao criar a imagem base com o Edge Image Builder, na pasta
network
, crie o arquivo
configure-network.sh
a seguir.
Esse procedimento 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
1.3.5.1.2 Segredo adicional com a configuração de rede do host #
É possível definir um segredo adicional com os dados no formato nmstate suportado pela ferramenta NM Configurator (Capítulo 12, Rede de borda) para cada host.
Depois disso, o segredo será referenciado no recurso
BareMetalHost
pelo campo de especificação
preprovisioningNetworkDataName
.
apiVersion: v1
kind: Secret
metadata:
name: controlplane-0-networkdata
type: Opaque
stringData:
networkData: |
interfaces:
- name: enp1s0
type: ethernet
state: up
mac-address: "00:f3:65:8a:a3:b0"
ipv4:
address:
- ip: 192.168.125.200
prefix-length: 24
enabled: true
dhcp: false
dns-resolver:
config:
server:
- 192.168.125.1
routes:
config:
- destination: 0.0.0.0/0
next-hop-address: 192.168.125.1
next-hop-interface: enp1s0
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
name: controlplane-0
labels:
cluster-role: control-plane
spec:
preprovisioningNetworkDataName: controlplane-0-networkdata
# Remaining content as in previous example
Em algumas situações, é possível omitir o endereço MAC. Consulte a Seção 12.5.8, “Configurações unificadas de nós” para obter mais detalhes.
1.3.5.2 Preparação do BareMetalHost #
Depois de criar o recurso BareMetalHost e os segredos associados conforme descrito acima, será acionado um fluxo de trabalho de preparação do host:
Uma imagem de disco RAM será iniciada depois de conectar a mídia virtual ao BMC do host de destino
O disco RAM inspeciona os detalhes do hardware e prepara o host para provisionamento (por exemplo, limpando os discos de dados anteriores)
Ao término desse processo, os detalhes do hardware no campo
status.hardware
do BareMetalHost serão atualizados e poderão ser verificados
Esse processo pode levar bastante tempo, mas quando for concluído, você verá
que o estado do BareMetalHost deve mudar para available
:
% kubectl get baremetalhost
NAME STATE CONSUMER ONLINE ERROR AGE
controlplane-0 available true 9m44s
worker-0 available true 9m44s
1.3.6 Criando clusters downstream #
Agora criamos os recursos de Cluster API que definem o cluster downstream e os recursos de Machine que provisionam e, depois, iniciam os recursos do BareMetalHost para formar um cluster RKE2.
1.3.7 Implantação do plano de controle #
Para implantar o plano de controle, definimos um manifesto YAML semelhante ao mostrado abaixo, que contém os seguintes recursos:
O recurso Cluster define o nome do cluster, as redes e o tipo de provedor de plano de controle/infraestrutura (neste caso, RKE2/Metal3)
Metal3Cluster define o endpoint do plano de controle (IP do host para nó único, endpoint LoadBalancer para vários nós; neste exemplo, foi considerado o nó único)
RKE2ControlPlane define a versão RKE2 e a configuração adicional necessária durante a inicialização do cluster
Metal3MachineTemplate define a imagem do sistema operacional que será aplicada aos recursos do BareMetalHost, e hostSelector define quais BareMetalHosts serão consumidos
Metal3DataTemplate define o metaData adicional que será passado para o BareMetalHost (veja que o networkData não é suportado na solução Edge)
Para simplificar, este exemplo considera um plano de controle de nó único em
que o BareMetalHost está configurado com o IP
192.168.125.200
. Para ver exemplos mais avançados de
vários nós, consulte o Capítulo 42, Provisionamento de rede direcionado totalmente automatizado.
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
name: sample-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: sample-cluster
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3Cluster
name: sample-cluster
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3Cluster
metadata:
name: sample-cluster
namespace: default
spec:
controlPlaneEndpoint:
host: 192.168.125.200
port: 6443
noCloudProvider: true
---
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
name: sample-cluster
namespace: default
spec:
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3MachineTemplate
name: sample-cluster-controlplane
replicas: 1
version: v1.32.4+rke2r1
rolloutStrategy:
type: "RollingUpdate"
rollingUpdate:
maxSurge: 0
agentConfig:
format: ignition
kubelet:
extraArgs:
- provider-id=metal3://BAREMETALHOST_UUID
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
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3MachineTemplate
metadata:
name: sample-cluster-controlplane
namespace: default
spec:
template:
spec:
dataTemplate:
name: sample-cluster-controlplane-template
hostSelector:
matchLabels:
cluster-role: control-plane
image:
checksum: http://imagecache.local:8080/SLE-Micro-eib-output.raw.sha256
checksumType: sha256
format: raw
url: http://imagecache.local:8080/SLE-Micro-eib-output.raw
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3DataTemplate
metadata:
name: sample-cluster-controlplane-template
namespace: default
spec:
clusterName: sample-cluster
metaData:
objectNames:
- key: name
object: machine
- key: local-hostname
object: machine
- key: local_hostname
object: machine
Depois de adaptado ao seu ambiente, aplique o exemplo usando o
kubectl
e monitore o status do cluster por meio do
clusterctl
.
% kubectl apply -f rke2-control-plane.yaml
# Wait for the cluster to be provisioned
% clusterctl describe cluster sample-cluster
NAME READY SEVERITY REASON SINCE MESSAGE
Cluster/sample-cluster True 22m
├─ClusterInfrastructure - Metal3Cluster/sample-cluster True 27m
├─ControlPlane - RKE2ControlPlane/sample-cluster True 22m
│ └─Machine/sample-cluster-chflc True 23m
1.3.8 Implantação de worker/computação #
De maneira semelhante à implantação do plano de controle, definimos um manifesto YAML que contém os seguintes recursos:
MachineDeployment define o número de réplicas (hosts) e o provedor de inicialização/infraestrutura (neste caso, RKE2/Metal3)
RKE2ConfigTemplate descreve a versão RKE2 e a configuração da primeira inicialização para inicializar o host do agente
Metal3MachineTemplate define a imagem do sistema operacional que será aplicada aos recursos do BareMetalHost, e o seletor de host define quais BareMetalHosts serão consumidos
Metal3DataTemplate define os metadados adicionais que serão passados para o BareMetalHost (veja que o
networkData
não é suportado atualmente)
apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineDeployment
metadata:
labels:
cluster.x-k8s.io/cluster-name: sample-cluster
name: sample-cluster
namespace: default
spec:
clusterName: sample-cluster
replicas: 1
selector:
matchLabels:
cluster.x-k8s.io/cluster-name: sample-cluster
template:
metadata:
labels:
cluster.x-k8s.io/cluster-name: sample-cluster
spec:
bootstrap:
configRef:
apiVersion: bootstrap.cluster.x-k8s.io/v1alpha1
kind: RKE2ConfigTemplate
name: sample-cluster-workers
clusterName: sample-cluster
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3MachineTemplate
name: sample-cluster-workers
nodeDrainTimeout: 0s
version: v1.32.4+rke2r1
---
apiVersion: bootstrap.cluster.x-k8s.io/v1alpha1
kind: RKE2ConfigTemplate
metadata:
name: sample-cluster-workers
namespace: default
spec:
template:
spec:
agentConfig:
format: ignition
version: v1.32.4+rke2r1
kubelet:
extraArgs:
- provider-id=metal3://BAREMETALHOST_UUID
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
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3MachineTemplate
metadata:
name: sample-cluster-workers
namespace: default
spec:
template:
spec:
dataTemplate:
name: sample-cluster-workers-template
hostSelector:
matchLabels:
cluster-role: worker
image:
checksum: http://imagecache.local:8080/SLE-Micro-eib-output.raw.sha256
checksumType: sha256
format: raw
url: http://imagecache.local:8080/SLE-Micro-eib-output.raw
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3DataTemplate
metadata:
name: sample-cluster-workers-template
namespace: default
spec:
clusterName: sample-cluster
metaData:
objectNames:
- key: name
object: machine
- key: local-hostname
object: machine
- key: local_hostname
object: machine
Quando o exemplo acima for copiado e adaptado ao seu ambiente, ele poderá
ser aplicado usando o kubectl
e, depois, o status do
cluster poderá ser monitorado com o clusterctl
% kubectl apply -f rke2-agent.yaml
# Wait for the worker nodes to be provisioned
% clusterctl describe cluster sample-cluster
NAME READY SEVERITY REASON SINCE MESSAGE
Cluster/sample-cluster True 25m
├─ClusterInfrastructure - Metal3Cluster/sample-cluster True 30m
├─ControlPlane - RKE2ControlPlane/sample-cluster True 25m
│ └─Machine/sample-cluster-chflc True 27m
└─Workers
└─MachineDeployment/sample-cluster True 22m
└─Machine/sample-cluster-56df5b4499-zfljj True 23m
1.3.9 Desprovisionamento do cluster #
É possível desprovisionar o cluster downstream excluindo os recursos que foram aplicados nas etapas de criação acima:
% kubectl delete -f rke2-agent.yaml
% kubectl delete -f rke2-control-plane.yaml
Esse procedimento aciona o desprovisionamento dos recursos do BareMetalHost, o que pode levar bastante tempo. Depois disso, eles deverão voltar para o estado disponível:
% kubectl get bmh
NAME STATE CONSUMER ONLINE ERROR AGE
controlplane-0 deprovisioning sample-cluster-controlplane-vlrt6 false 10m
worker-0 deprovisioning sample-cluster-workers-785x5 false 10m
...
% kubectl get bmh
NAME STATE CONSUMER ONLINE ERROR AGE
controlplane-0 available false 15m
worker-0 available false 15m
1.4 Problemas conhecidos #
O controlador de gerenciamento de endereços IP upstream não é suportado no momento porque ainda não é compatível com a nossa seleção de ferramentas de configuração de rede e conjunto de ferramentas de primeira inicialização no SLEMicro.
De modo semelhante, os recursos IPAM e os campos networkData de Metal3DataTemplate não são suportados no momento.
Apenas há suporte para implantação por redfish-virtualmedia.
1.5 Alterações planejadas #
Habilitar suporte de recursos e configuração do IPAM pelos campos networkData
1.6 Recursos adicionais #
A documentação do SUSE Edge for Telco (Capítulo 37, SUSE Edge for Telco) tem exemplos de uso mais avançado do Metal3 para casos de uso de telecomunicações.
1.6.1 Configuração de nó único #
Para ambientes de teste/PoC em que o cluster de gerenciamento é um nó único, é possível evitar o requisito de IP flutuante adicional gerenciado por MetalLB.
Nesse modo, o endpoint para as APIs do cluster de gerenciamento é o IP do
cluster de gerenciamento, portanto, ele deve ser reservado ao usar DHCP ou
configurado estaticamente para garantir que não seja alterado. Mencionado
abaixo como <MANAGEMENT_CLUSTER_IP>
.
Para possibilitar esse cenário, os valores do gráfico do Metal3 necessários são estes:
global:
ironicIP: <MANAGEMENT_CLUSTER_IP>
metal3-ironic:
service:
type: NodePort
1.6.2 Desabilitando TLS para anexo de ISO de mídia virtual #
Alguns fornecedores de servidor verificam a conexão SSL ao anexar imagens ISO de mídia virtual ao BMC, o que pode causar um problema porque os certificados gerados para a implantação do Metal3 são autoassinados. Para solucionar esse problema, desabilite o TLS apenas para anexo de disco de mídia virtual com os valores do gráfico do Metal3 a seguir:
global:
enable_vmedia_tls: false
Uma solução alternativa é configurar os BMCs com o certificado de CA. Nesse
caso, você pode ler os certificados do cluster usando o
kubectl
:
kubectl get secret -n metal3-system ironic-vmedia-cert -o yaml
Depois disso, o certificado poderá ser configurado no console de BMC do
servidor, embora o processo para isso seja específico do fornecedor (e pode
não ser possível para todos os fornecedores e, consequentemente, exigir o
uso do sinalizador enable_vmedia_tls
).
1.6.3 Configuração do armazenamento #
Para ambientes de teste/PoC em que o cluster de gerenciamento é um nó único, não há necessidade de armazenamento persistente; mas em casos de uso de produção, a recomendação é instalar o SUSE Storage (Longhorn) no cluster de gerenciamento para que as imagens relacionadas ao Metal3 persistam durante a reinicialização/reprogramação de um pod.
Para habilitar o armazenamento persistente, os valores do gráfico do Metal3 necessários são estes:
metal3-ironic:
persistence:
ironic:
size: "5Gi"
A documentação para cluster de gerenciamento do SUSE Edge for Telco (Capítulo 40, Configurando o cluster de gerenciamento) tem mais detalhes sobre como configurar um cluster de gerenciamento com armazenamento persistente.