4 Implantações automatizadas de BMC com Metal3 #
Metal3 é um projeto da CNCF que fornece recursos de gerenciamento de infraestrutura bare-metal para Kubernetes.
O Metal3 fornece recursos nativos do Kubernetes para gerenciar o ciclo de vida de servidores bare-metal que suportam gerenciamento via protocolos fora de banda, como Redfish.
Ele também possui suporte maduro para Cluster API (CAPI), que permite o gerenciamento de recursos de infraestrutura em vários provedores de infraestrutura por meio de APIs neutras de fornecedores amplamente adotadas.
4.1 Por que usar este método #
Este método é útil para cenários em que o hardware de destino suporta gerenciamento fora de banda e deseja-se um fluxo de gerenciamento de infraestrutura totalmente automatizado.
Um cluster de gerenciamento é configurado para fornecer APIs declarativas que permitem o gerenciamento de inventário e estado de servidores bare-metal de clusters downstream, incluindo inspeção, limpeza e provisionamento/desprovisionamento automatizados.
4.2 Arquitetura de alto nível #
4.3 Pré-requisitos #
Existem algumas restrições específicas relacionadas ao hardware e à rede do servidor do cluster downstream:
Cluster de gerenciamento
Deve ter conectividade de rede com a API de gerenciamento/BMC do servidor de destino
Deve ter conectividade de rede com a rede do plano de controle do servidor de destino
Para clusters de gerenciamento com vários nós, é necessário um endereço IP reservado adicional
Hosts a serem controlados
Deve oferecer suporte a gerenciamento fora de banda via interfaces Redfish, iDRAC ou iLO
Deve oferecer suporte a implantação via mídia virtual (PXE não é suportado atualmente)
Deve ter conectividade de rede com o cluster de gerenciamento para acesso às APIs de provisionamento do Metal3
Algumas ferramentas são necessárias; elas 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
Uma imagem raw do SUSE Linux Micro 6.2 criada usando o Kiwi Builder (Capítulo 64, Criando imagens atualizadas do SUSE Linux Micro com o Kiwi)
4.4 Implantação #
4.4.1 Configurar Cluster de gerenciamento #
As etapas básicas para instalar um cluster de gerenciamento e usar o 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 dependências do provedor CAPI
Criar uma imagem do SO SLEMicro para hosts de cluster downstream
Registrar CRs BareMetalHost para definir o inventário bare metal
Criar um cluster downstream definindo recursos CAPI
Este guia pressupõe que um cluster RKE2 e o Rancher (incluindo o cert-manager) existentes já foram instalados, por exemplo, usando o Edge Image Builder (Capítulo 12, Edge Image Builder).
As etapas aqui também podem ser totalmente automatizadas conforme descrito na Documentação do Cluster de gerenciamento (Parte V, “Configurando o cluster de gerenciamento”).
4.4.2 Instalando dependências do Metal3 #
Se não estiver instalado como parte da instalação do Rancher, o cert-manager deve estar instalado e em execução.
Um IP adicional é necessário, o qual é gerenciado pelo MetalLB para fornecer um endpoint consistente para os serviços de gerenciamento do Metal3. Este IP deve fazer parte da sub-rede do plano de controle e estar reservado para configuração estática (não fazer parte de nenhum pool DHCP).
Se o cluster de gerenciamento for um nó único, o requisito de um IP flutuante adicional gerenciado via MetalLB pode ser evitado, veja Seção 4.7.1, “Configuração de nó único”
Primeiro, instalamos o MetalLB:
helm install \ metallb oci://registry.suse.com/edge/charts/metallb \ --namespace metallb-system \ --create-namespaceEm seguida, definimos um
IPAddressPooleL2Advertisementusando o IP reservado, definido comoSTATIC_IRONIC_IPabaixo: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]} EOFcat <<-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 EOFAgora o Metal3 pode ser instalado:
helm install \ metal3 oci://registry.suse.com/edge/charts/metal3 \ --namespace metal3-system \ --create-namespace \ --set global.ironicIP="$STATIC_IRONIC_IP"Pode levar cerca de dois minutos para o contêiner init ser executado nesta implantação, portanto, certifique-se de que todos os pods estejam em execução antes de prosseguir:
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 prossiga para as etapas a seguir até que todos os pods no namespace metal3-system estejam em execução.
4.4.3 Instalando dependências do provedor de API de cluster #
As dependências do provedor de API de cluster são gerenciadas por meio do gráfico Helm Rancher Turtles Providers:
helm install \
rancher-turtles oci://registry.suse.com/edge/charts/rancher-turtles-providers \
--namespace cattle-turtles-system \
--create-namespaceApós algum tempo, os pods do controlador devem estar em execução nos namespaces cattle-capi-system, capm3-system, rke2-bootstrap-system e rke2-control-plane-system.
4.4.4 Preparar imagem do cluster downstream #
Kiwi (Capítulo 64, Criando imagens atualizadas do SUSE Linux Micro com o Kiwi) e Edge Image Builder (Capítulo 12, Edge Image Builder) são usados para preparar uma imagem base SLEMicro modificada que é provisionada nos hosts do cluster downstream.
Neste guia, abordamos a configuração mínima necessária para implantar o cluster downstream.
4.4.4.1 Configuração de imagens #
Siga Capítulo 64, Criando imagens atualizadas do SUSE Linux Micro com o Kiwi primeiro para criar uma imagem nova como a primeira etapa necessária para criar clusters.
Ao executar o Edge Image Builder, um diretório é montado a partir do 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 de imagem, consulte Capítulo 5, Clusters autônomos com o Edge Image Builder para obter mais detalhes.Copie a imagem base criada pelo Kiwi Builder para o diretório
base-images.A pasta
networké opcional, consulte Seção 4.4.5.1.1, “Script adicional para configuração de rede estática” para obter mais detalhes.O diretório custom/scripts contém scripts a serem executados na primeira inicialização; atualmente, um script
01-fix-growfs.shé necessário para redimensionar a partição raiz do SO na implantação
├── downstream-cluster-config.yaml
├── base-images/
│ └ SL-Micro.x86_64-6.2-Base-GM.raw
├── network/
| └ configure-network.sh
└── custom/
└ scripts/
└ 01-fix-growfs.sh4.4.4.1.1 Arquivo de definição de imagem do cluster downstream #
O arquivo downstream-cluster-config.yaml é o arquivo de configuração principal para a imagem do cluster downstream. A seguir, um exemplo mínimo para implantação via Metal3:
apiVersion: 1.3
image:
imageType: raw
arch: x86_64
baseImage: SL-Micro.x86_64-6.2-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
systemd:
disable:
- rebootmgr
- transactional-update.timer
- transactional-update-cleanup.timer
users:
- username: root
encryptedPassword: $ROOT_PASSWORD
sshKeys:
- $USERKEY1
createHomeDir: true
packages:
packageList:
- jq
sccRegistrationCode: $SCC_REGISTRATION_CODEOnde $SCC_REGISTRATION_CODE é o código de registro copiado do SUSE Customer Center, e a lista de pacotes contém jq, que é necessária.
$ROOT_PASSWORD é a senha criptografada para o usuário root, o que pode ser útil para testes/depuração. Ele pode ser gerado com o comando openssl passwd -6 PASSWORD.
Para os ambientes de produção, recomenda-se usar as chaves SSH que podem ser adicionadas ao bloco de usuários, substituindo $USERKEY1 pelas chaves SSH reais.
Observe que ignition.platform.id=openstack é obrigatório - sem este argumento, a configuração do SUSE Linux Micro via ignition falhará no fluxo automatizado Metal3.
A seção time é opcional, mas é altamente recomendável que seja configurada para evitar possíveis problemas com certificados e discrepância de relógio. Os valores fornecidos neste exemplo são apenas para fins ilustrativos. Por favor, ajuste-os para atender aos seus requisitos específicos.
4.4.4.1.2 Script Growfs #
Atualmente, um script personalizado (custom/scripts/01-fix-growfs.sh) é necessário para expandir o sistema de arquivos para corresponder ao 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 serem executados durante o processo de provisionamento usando a mesma abordagem. Para obter mais informações, consulte Capítulo 5, Clusters autônomos com o Edge Image Builder.
4.4.4.2 Criação de imagem #
Uma vez que a estrutura de diretórios esteja preparada seguindo 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.6/edge-image-builder:1.3.3.1 \
build --definition-file downstream-cluster-config.yamlIsso cria o arquivo de imagem de saída chamado SLE-Micro-eib-output.raw, com base na definição descrita acima.
A imagem de saída deve então ser disponibilizada via servidor web, seja o contêiner media-server habilitado via o Metal3 chart (Nota) ou algum outro servidor acessível localmente. Nos exemplos abaixo, nos referimos a este servidor como imagecache.local:8080
Ao implantar imagens EIB em clusters downstream, também é necessário incluir a soma sha256 da imagem no objeto Metal3MachineTemplate.
Ele pode ser gerado como:
sha256sum <image_file> > <image_file>.sha256
# On this example:
sha256sum SLE-Micro-eib-output.raw > SLE-Micro-eib-output.raw.sha2564.4.5 Adicionando inventário BareMetalHost #
O registro de servidores bare-metal para implantação automatizada requer a criação de dois recursos: um Secret armazenando credenciais de acesso BMC e um recurso Metal3 BareMetalHost definindo a conexã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:
architecture: x86_64
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-credentialsObserve o seguinte:
O nome de usuário/senha do Secret deve estar codificado em base64. Observe que isso não deve incluir nenhuma quebra de linha ao final (por exemplo, use
echo -n, não apenasecho!)O rótulo
cluster-rolepode ser definido agora ou posteriormente na criação do cluster. No exemplo abaixo, esperamoscontrol-planeouworkerbootMACAddressdeve ser um MAC válido que corresponda à NIC do plano de controle do hostO endereço
bmcé a conexão com a API de gerenciamento do BMC; os seguintes são suportados:redfish-virtualmedia://<IP ADDRESS>/redfish/v1/Systems/<SYSTEM ID>: Mídia virtual Redfish, por exemplo, SuperMicroidrac-virtualmedia://<IP ADDRESS>/redfish/v1/Systems/System.Embedded.1: Dell iDRAC
Consulte a documentação da API upstream para obter mais detalhes sobre a API BareMetalHost
4.4.5.1 Configurando IPs estáticos #
O exemplo de BareMetalHost acima pressupõe que o DHCP forneça a configuração de rede do plano de controle, mas para cenários onde a configuração manual é necessária, como IPs estáticos, é possível fornecer configuração adicional, conforme descrito abaixo.
4.4.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 seguinte arquivo configure-network.sh.
Isso consome 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
META_DATA_FILE="/mnt/openstack/latest/meta_data.json"
if [ ! -f "${META_DATA_FILE}" ]; then
umount /mnt
echo "No meta_data.json found, skipping hostname 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
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
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/generated4.4.5.1.2 Segredo adicional com configuração de rede do host #
Um segredo adicional contendo dados no formato nmstate suportado pelo NM Configurator (Capítulo 13, Rede de borda) pode ser definido para cada host.
O segredo é então referenciado no recurso BareMetalHost por meio do 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 exampleEm algumas circunstâncias, o endereço MAC pode ser omitido. Veja Seção 13.5.8, “Configurações de nó unificadas” para mais detalhes.
4.4.5.2 Preparação do BareMetalHost #
Após criar o recurso BareMetalHost e os segredos associados conforme descrito acima, um fluxo de trabalho de preparação do host é acionado:
Uma imagem de ramdisk é inicializada por anexo de virtualmedia ao BMC do host de destino
O ramdisk inspeciona os detalhes do hardware e prepara o host para o provisionamento (por exemplo, limpando discos de dados anteriores)
Ao concluir este processo, os detalhes do hardware no campo BareMetalHost
status.hardwaresão atualizados e podem ser verificados
Este processo pode levar vários minutos, mas quando concluído, você deverá ver o estado do BareMetalHost tornar-se available:
% kubectl get baremetalhost
NAME STATE CONSUMER ONLINE ERROR AGE
controlplane-0 available true 9m44s
worker-0 available true 9m44s4.4.6 Criando clusters downstream #
Agora criamos recursos do Cluster API que definem o cluster downstream, e recursos Machine que farão com que os recursos BareMetalHost sejam provisionados, e então inicializados para formar um cluster RKE2.
4.4.7 Implantação do plano de controle #
Para implantar o plano de controle, definimos um manifesto yaml semelhante ao abaixo, que contém os seguintes recursos:
O recurso Cluster define o nome do cluster, redes e o tipo de provedor de plano de controle/infraestrutura (neste caso, RKE2/Metal3)
O Metal3Cluster define o endpoint do plano de controle (IP do host para nó único, endpoint do LoadBalancer para multi-nó; este exemplo assume nó único)
O RKE2ControlPlane define a versão do RKE2 e qualquer configuração adicional necessária durante a inicialização do cluster
O Metal3MachineTemplate define a imagem do SO a ser aplicada aos recursos BareMetalHost, e o hostSelector define quais BareMetalHosts consumir
O Metal3DataTemplate define metadados adicionais a serem passados para o BareMetalHost (observe que o networkData atualmente não é suportado na solução Edge)
Para simplificar, este exemplo assume um plano de controle de nó único onde o BareMetalHost está configurado com um IP de 192.168.125.200. Para exemplos mais avançados de multi-nó, consulte Parte VII, “Provisionamento de rede direcionado totalmente automatizado”.
apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
name: sample-cluster
namespace: default
labels:
cluster-api.cattle.io/rancher-auto-import: "true"
spec:
clusterNetwork:
pods:
cidrBlocks:
- 192.168.0.0/18
services:
cidrBlocks:
- 10.96.0.0/12
controlPlaneRef:
apiGroup: controlplane.cluster.x-k8s.io
kind: RKE2ControlPlane
name: sample-cluster
infrastructureRef:
apiGroup: infrastructure.cluster.x-k8s.io
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/v1beta2
kind: RKE2ControlPlane
metadata:
name: sample-cluster
namespace: default
spec:
infrastructureRef:
apiGroup: infrastructure.cluster.x-k8s.io
kind: Metal3MachineTemplate
name: sample-cluster-controlplane
replicas: 1
version: v1.35.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"
ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
ExecStart=/bin/sh -c "echo \" - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
ExecStartPost=/bin/sh -c "umount /mnt"
[Install]
WantedBy=multi-user.target
# rke2-traefik-deployment.service unit to be removed once "traefik" being the default ingress controller (starting with RKE2 v1.36)
- name: rke2-traefik-deployment.service
enabled: true
contents: |
[Unit]
Description=rke2-traefik-deployment
Wants=rke2-preinstall.service
Before=rke2-install.service
ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
[Service]
Type=oneshot
User=root
ExecStart=/bin/sh -c "echo \"ingress-controller: traefik\" >> /etc/rancher/rke2/config.yaml"
[Install]
WantedBy=multi-user.target
storage:
directories:
- path: /var/lib/rancher/rke2/server/manifests
overwrite: true
files:
- path: /var/lib/rancher/rke2/server/manifests/rke2-traefik-config.yaml
overwrite: true
contents:
inline: |
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: rke2-traefik
namespace: kube-system
spec:
valuesContent: |-
ingressClass:
isDefaultClass: true
ports:
web:
hostPort: null # disallow hostPort
exposedPort: 80
websecure:
hostPort: null # disallow hostPort
exposedPort: 443
service:
enabled: true
type: LoadBalancer
spec:
externalTrafficPolicy: Local
allocateLoadBalancerNodePorts: false # k8s GA from 1.24; supported by MetalLB
mode: 0644
user:
name: root
group:
name: root
---
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: machineAdicionar o rótulo cluster-api.cattle.io/rancher-auto-import: "true" aos objetos cluster.x-k8s.io importará o cluster para o Rancher (criando um objeto clusters.management.cattle.io correspondente).
Consulte a documentação do Cluster API para obter mais informações.
Uma vez adaptado ao seu ambiente, você pode aplicar o exemplo via kubectl e então monitorar o status do cluster via 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 23m4.4.8 Implantação de Worker/Compute #
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 bootstrap/infraestrutura (neste caso, RKE2/Metal3)
RKE2ConfigTemplate descreve a versão do RKE2 e a configuração de primeira inicialização para o bootstrapping do host do agente
Metal3MachineTemplate define a imagem do SO a ser aplicada aos recursos BareMetalHost, e o seletor de host define quais BareMetalHosts consumir
Metal3DataTemplate define metadados adicionais a serem passados para o BareMetalHost (observe que
networkDatanão é suportado atualmente)
apiVersion: cluster.x-k8s.io/v1beta2
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:
apiGroup: bootstrap.cluster.x-k8s.io
kind: RKE2ConfigTemplate
name: sample-cluster-workers
clusterName: sample-cluster
infrastructureRef:
apiGroup: infrastructure.cluster.x-k8s.io
kind: Metal3MachineTemplate
name: sample-cluster-workers
deletion:
nodeDrainTimeoutSeconds: 0
version: v1.35.4+rke2r1
---
apiVersion: bootstrap.cluster.x-k8s.io/v1beta2
kind: RKE2ConfigTemplate
metadata:
name: sample-cluster-workers
namespace: default
spec:
template:
spec:
agentConfig:
format: ignition
version: v1.35.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"
ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
ExecStart=/bin/sh -c "echo \" - metal3.io/uuid=$(jq -r .uuid /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: machineQuando o exemplo acima tiver sido copiado e adaptado para atender ao seu ambiente, ele poderá ser aplicado via kubectl, então o status do cluster poderá ser monitorado com 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 23m4.4.9 Desprovisionamento de cluster #
O cluster downstream pode ser desprovisionado excluindo os recursos aplicados nas etapas de criação acima:
% kubectl delete -f rke2-agent.yaml
% kubectl delete -f rke2-control-plane.yamlIsso aciona o desprovisionamento dos recursos BareMetalHost, o que pode levar vários minutos, após os quais eles devem estar no estado disponível novamente:
% 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 15m4.5 Problemas conhecidos #
O controlador de Gerenciamento de Endereço IP upstream não é suportado atualmente, pois ainda não é compatível com nossa escolha de ferramentas de configuração de rede e cadeia de ferramentas de primeira inicialização no SLEMicro.
Relacionado a isso, os recursos de IPAM e os campos networkData do Metal3DataTemplate não são suportados atualmente.
Apenas a implantação via redfish-virtualmedia é suportada atualmente.
4.6 Mudanças planejadas #
Habilitar o suporte aos recursos de IPAM e configuração via campos networkData
4.7 Recursos adicionais #
A SUSE Telco Cloud Management Cluster Documentation (Parte V, “Configurando o cluster de gerenciamento”) contém exemplos de uso mais avançado do Metal3 para casos de uso em telecomunicações.
4.7.1 Configuração de nó único #
Para ambientes de teste/PoC onde o cluster de gerenciamento é um nó único, é possível evitar o requisito de um IP flutuante adicional gerenciado via MetalLB.
Neste 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 o IP do cluster de gerenciamento não mude - referido como <MANAGEMENT_CLUSTER_IP> abaixo.
Para habilitar este cenário, os valores do gráfico Metal3 necessários são os seguintes:
global:
ironicIP: <MANAGEMENT_CLUSTER_IP>
metal3-ironic:
service:
type: NodePort4.7.2 Desabilitando TLS para anexo de ISO de virtualmedia #
Alguns fornecedores de servidores verificam a conexão SSL ao anexar imagens ISO de virtual-media ao BMC, o que pode causar um problema porque os certificados gerados para a implantação do Metal3 são autoassinados; para contornar esse problema, é possível desabilitar o TLS apenas para o anexo de disco de virtualmedia com os valores do gráfico Metal3 da seguinte forma:
global:
enable_vmedia_tls: falseUma solução alternativa é configurar os BMCs com o certificado da CA - neste caso, você pode ler os certificados do cluster usando kubectl:
kubectl get secret -n metal3-system ironic-vmedia-cert -o yamlO certificado pode então ser configurado no console do BMC do servidor, embora o processo para isso seja específico do fornecedor (e não seja possível para todos os fornecedores, caso em que a flag enable_vmedia_tls pode ser necessária).
4.7.3 Configuração de armazenamento #
Para ambientes de teste/PoC onde o cluster de gerenciamento é um nó único, nenhum armazenamento persistente é necessário, mas para casos de uso de produção, recomenda-se instalar o SUSE Storage (Longhorn) no cluster de gerenciamento para que as imagens relacionadas ao Metal3 possam ser persistidas durante uma reinicialização/reagendamento de pod.
Para habilitar este armazenamento persistente, os valores do gráfico Metal3 necessários são os seguintes:
metal3-ironic:
persistence:
ironic:
size: "5Gi"A Documentação do SUSE Telco Cloud Management Cluster (Parte V, “Configurando o cluster de gerenciamento”) tem mais detalhes sobre como configurar um cluster de gerenciamento com armazenamento persistente.
