4 Despliegues automatizados de BMC con Metal3 #
Metal3 es un proyecto de la CNCF que proporciona capacidades de gestión de infraestructura de equipo sin sistema operativo para Kubernetes.
Metal3 proporciona recursos nativos de Kubernetes para gestionar el ciclo de vida de los servidores de equipo sin sistema operativo que admiten la gestión mediante protocolos fuera de banda como Redfish.
También cuenta con un soporte maduro para Cluster API (CAPI), que permite la gestión de recursos de infraestructura a través de múltiples proveedores mediante APIs neutrales al proveedor y ampliamente adoptadas.
4.1 ¿Por qué utilizar este método? #
Este método es útil para escenarios en los que el hardware de destino admite la gestión fuera de banda y se desea un flujo de gestión de infraestructura totalmente automatizado.
Se configura un clúster de gestión para proporcionar APIs declarativas que permitan la gestión del inventario y del estado de los servidores de equipo sin sistema operativo del clúster descendente, incluida la inspección, limpieza y aprovisionamiento/desaprovisionamiento automatizados.
4.2 Arquitectura de alto nivel #
4.3 Requisitos previos #
Existen algunas restricciones específicas relacionadas con el hardware y la red del servidor del clúster descendente:
Clúster de gestión
Debe tener conectividad de red con la API de gestión/BMC del servidor de destino
Debe tener conectividad de red con la red del plano de control del servidor de destino
Para los clústeres de gestión de varios nodos, se requiere una dirección IP reservada adicional
Hosts que se van a controlar
Deben admitir la gestión fuera de banda a través de interfaces Redfish, iDRAC o iLO
Deben admitir el despliegue a través de medios virtuales (actualmente no se admite PXE)
Debe tener conectividad de red con el clúster de gestión para acceder a las API de aprovisionamiento de Metal3
Se requieren algunas herramientas; estas pueden instalarse en el clúster de gestión o en un host que pueda acceder a él.
Un entorno de ejecución de contenedor como Podman o Rancher Desktop
Una imagen sin procesar de SUSE Linux Micro 6.2 creada usando el Kiwi Builder (Chapter 64, Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi)
4.4 Distribución #
4.4.1 Configurar el clúster de gestión #
Los pasos básicos para instalar un clúster de gestión y utilizar Metal3 son:
Instalar un clúster de gestión RKE2
Instalar Rancher
Instalar un proveedor de almacenamiento (opcional)
Instalar las dependencias de Metal3
Instalar las dependencias del proveedor CAPI
Crear una imagen de SO SLEMicro para los hosts del clúster descendente
Registrar los CR de BareMetalHost para definir el inventario de equipo sin sistema operativo
Crear un clúster descendente definiendo recursos CAPI
Esta guía asume que ya existe un clúster RKE2 y que Rancher (incluido cert-manager) se ha instalado, por ejemplo, mediante Edge Image Builder (Chapter 12, Edge Image Builder).
Los pasos aquí descritos también pueden automatizarse por completo tal y como se describe en la Documentación del clúster de gestión (Part V, “Configuración del clúster de gestión”).
4.4.2 Instalación de las dependencias de Metal3 #
Si no se ha instalado ya como parte de la instalación de Rancher, cert-manager debe estar instalado y en ejecución.
Se requiere una IP adicional, la cual es gestionada por MetalLB para proporcionar un punto final consistente para los servicios de gestión de Metal3. Esta IP debe formar parte de la subred del plano de control y estar reservada para la configuración estática (no debe formar parte de ningún grupo DHCP).
Si el clúster de gestión es un nodo único, se puede evitar el requisito de una IP flotante adicional gestionada a través de MetalLB, véase Section 4.7.1, “Configuración de nodo único”.
Primero, instalamos MetalLB:
helm install \ metallb oci://registry.suse.com/edge/charts/metallb \ --namespace metallb-system \ --create-namespaceA continuación, definimos un
IPAddressPoolyL2Advertisementutilizando la IP reservada, definida comoSTATIC_IRONIC_IPa continuación: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 EOFAhora Metal3 puede instalarse:
helm install \ metal3 oci://registry.suse.com/edge/charts/metal3 \ --namespace metal3-system \ --create-namespace \ --set global.ironicIP="$STATIC_IRONIC_IP"El contenedor de inicialización puede tardar unos dos minutos en ejecutarse en este despliegue, así que aseguraos de que todos los pods estén en ejecución 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
No paséis a los siguientes pasos hasta que todos los pods en el espacio de nombres metal3-system estén en ejecución.
4.4.3 Instalación de las dependencias del proveedor de la API del clúster #
Las dependencias del proveedor de la API del clúster se gestionan a través del gráfico Helm de Rancher Turtles Providers:
helm install \
rancher-turtles oci://registry.suse.com/edge/charts/rancher-turtles-providers \
--namespace cattle-turtles-system \
--create-namespaceTras un tiempo, los pods del controlador deberían estar ejecutándose en los espacios de nombres cattle-capi-system, capm3-system, rke2-bootstrap-system y rke2-control-plane-system.
4.4.4 Preparar la imagen del clúster descendente #
Kiwi (Chapter 64, Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi) y Edge Image Builder (Chapter 12, Edge Image Builder) se utilizan para preparar una imagen base de SLEMicro modificada que se aprovisiona en los hosts del clúster descendente.
En esta guía, cubrimos la configuración mínima necesaria para desplegar el clúster descendente.
4.4.4.1 Configuración de la imagen #
Por favor, seguid Chapter 64, Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi primero para crear una imagen nueva como primer paso necesario para crear clústeres.
Al ejecutar Edge Image Builder, se monta un directorio desde el host, por lo que es necesario crear una estructura de directorios para almacenar los archivos de configuración utilizados para definir la imagen de destino.
downstream-cluster-config.yamles el archivo de definición de la imagen, véase Chapter 5, Clústeres independientes con Edge Image Builder para más detalles.Copiad la imagen base creada por Kiwi Builder al directorio
base-images.La carpeta
networkes opcional, véase Section 4.4.5.1.1, “Script adicional para la configuración de red estática” para más detalles.El directorio custom/scripts contiene scripts que se ejecutarán en el primer arranque; actualmente se requiere un script
01-fix-growfs.shpara redimensionar la partición root durante el despliegue.
├── 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 Archivo de definición de imagen del clúster descendente #
El archivo downstream-cluster-config.yaml es el archivo de configuración principal para la imagen del clúster descendente. A continuación se muestra un ejemplo mínimo para el despliegue mediante 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_CODEDonde $SCC_REGISTRATION_CODE es el código de registro copiado de SUSE Customer Center, y la lista de paquetes contiene jq, que es necesario.
$ROOT_PASSWORD es la contraseña cifrada para el usuario raíz, que puede ser útil para pruebas/depuración. Se puede generar con el comando openssl passwd -6 PASSWORD.
Para los entornos de producción, se recomienda utilizar las claves SSH que se pueden añadir al bloque de usuarios sustituyendo $USERKEY1 por las claves SSH reales.
Tened en cuenta que ignition.platform.id=openstack es obligatorio; sin este argumento, la configuración de SUSE Linux Micro mediante ignition fallará en el flujo automatizado de Metal3.
La sección time es opcional, pero se recomienda encarecidamente configurarla para evitar posibles problemas con los certificados y el desfase horario. Los valores proporcionados en este ejemplo son solo para fines ilustrativos. Ajustadlos para que se adapten a vuestros requisitos específicos.
4.4.4.1.2 Script Growfs #
Actualmente, se requiere un script personalizado (custom/scripts/01-fix-growfs.sh) para ampliar el sistema de archivos y que coincida con el tamaño del disco en el primer arranque tras el aprovisionamiento. El script 01-fix-growfs.sh incluye la información siguiente:
#!/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 /Añadid vuestros propios scripts personalizados para que se ejecuten durante el proceso de aprovisionamiento utilizando el mismo enfoque. Para obtener más información, consulte el Chapter 5, Clústeres independientes con Edge Image Builder.
4.4.4.2 Creación de imágenes #
Una vez preparada la estructura de directorios siguiendo las secciones anteriores, ejecutad el siguiente comando para compilar la imagen:
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.yamlEsto crea el archivo de imagen de salida llamado SLE-Micro-eib-output.raw, basado en la definición descrita anteriormente.
La imagen de salida debe estar disponible a través de un servidor web, ya sea el contenedor media-server habilitado mediante el gráfico de Metal3 (Note) o algún otro servidor accesible localmente. En los ejemplos siguientes, nos referimos a este servidor como imagecache.local:8080
Al desplegar imágenes EIB en clústeres en sentido descendente, también es necesario incluir la suma sha256 de la imagen en el objeto Metal3MachineTemplate.
Se puede generar de la siguiente manera:
sha256sum <image_file> > <image_file>.sha256
# On this example:
sha256sum SLE-Micro-eib-output.raw > SLE-Micro-eib-output.raw.sha2564.4.5 Adición del inventario de BareMetalHost #
El registro de servidores de equipo sin sistema operativo para el despliegue automatizado requiere la creación de dos recursos: un Secret que almacene las credenciales de acceso a BMC y un recurso Metal3 BareMetalHost que defina la conexión BMC y otros detalles:
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-credentialsTened en cuenta lo siguiente:
El nombre de usuario/contraseña del Secret debe estar codificado en base64. Tened en cuenta que esto no debe incluir saltos de línea finales (por ejemplo, utilizad
echo -n, ¡no soloecho!)La etiqueta
cluster-rolepuede establecerse ahora o más tarde durante la creación del clúster. En el ejemplo siguiente, esperamoscontrol-planeoworkerbootMACAddressdebe ser una MAC válida que coincida con la NIC del plano de control del hostLa dirección
bmces la conexión a la API de gestión de BMC; se admiten las siguientes:redfish-virtualmedia://<IP ADDRESS>/redfish/v1/Systems/<SYSTEM ID>: Medios virtuales Redfish, por ejemplo, SuperMicroidrac-virtualmedia://<IP ADDRESS>/redfish/v1/Systems/System.Embedded.1: Dell iDRAC
Consultad la documentación de la API de sentido ascendente para obtener más detalles sobre la API de BareMetalHost
4.4.5.1 Configuración de IP estáticas #
El ejemplo de BareMetalHost anterior asume que DHCP proporciona la configuración de red del plano de control, pero para escenarios donde se necesita una configuración manual, como las IP estáticas, es posible proporcionar una configuración adicional, como se describe a continuación.
4.4.5.1.1 Script adicional para la configuración de red estática #
Al crear la imagen base con Edge Image Builder, en la carpeta network, cree el siguiente archivo configure-network.sh.
Esto consume los datos de la unidad de configuración en el primer arranque y configura la red del host utilizando la herramienta 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 Secreto adicional con la configuración de red del host #
Se puede definir un secreto adicional que contenga datos en el formato nmstate admitido por NM Configurator (Chapter 13, Redes edge) para cada host.
El secreto se referencia entonces en el recurso BareMetalHost a través del campo spec 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 exampleEn algunas circunstancias, la dirección MAC puede omitirse. Consulte Section 13.5.8, “Configuraciones de nodo unificadas” para obtener más información.
4.4.5.2 Preparación de BareMetalHost #
Tras crear el recurso BareMetalHost y los secretos asociados como se ha descrito anteriormente, se activa un flujo de trabajo de preparación del host:
Se arranca una imagen de disco RAM mediante la conexión de medios virtuales al BMC del host de destino
El disco RAM inspecciona los detalles del hardware y prepara el host para el aprovisionamiento (por ejemplo, limpiando los discos de datos anteriores)
Al finalizar este proceso, los detalles del hardware en el campo
status.hardwarede BareMetalHost se actualizan y pueden verificarse
Este proceso puede tardar varios minutos, pero cuando finalice debería ver que el estado de BareMetalHost se convierte en available:
% kubectl get baremetalhost
NAME STATE CONSUMER ONLINE ERROR AGE
controlplane-0 available true 9m44s
worker-0 available true 9m44s4.4.6 Creación de clústeres de sentido descendente #
Ahora creamos recursos de Cluster API que definen el clúster de sentido descendente, y recursos Machine que provocarán que los recursos BareMetalHost se aprovisionen y, a continuación, se arranquen para formar un clúster RKE2.
4.4.7 Despliegue del plano de control #
Para desplegar el plano de control definimos un manifiesto yaml similar al que aparece a continuación, que contiene los siguientes recursos:
El recurso Cluster define el nombre del clúster, las redes y el tipo de proveedor de plano de control/infraestructura (en este caso RKE2/Metal3)
Metal3Cluster define el punto final del plano de control (IP del host para nodo único, punto final de LoadBalancer para nodos múltiples; este ejemplo asume un nodo único)
RKE2ControlPlane define la versión de RKE2 y cualquier configuración adicional necesaria durante el arranque del clúster
Metal3MachineTemplate define la imagen del SO que se aplicará a los recursos BareMetalHost, y hostSelector define qué BareMetalHosts consumir
Metal3DataTemplate define metadatos adicionales que se pasarán al BareMetalHost (tenga en cuenta que networkData no es compatible actualmente en la solución Edge)
Por simplicidad, este ejemplo asume un plano de control de nodo único donde el BareMetalHost está configurado con una IP de 192.168.125.200. Para ejemplos multinodo más avanzados, consulte Part VII, “Aprovisionamiento de red dirigido 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: machineAñadir la etiqueta cluster-api.cattle.io/rancher-auto-import: "true" a los objetos cluster.x-k8s.io importará el clúster a Rancher (creando un objeto clusters.management.cattle.io correspondiente).
Consulte la documentación de Cluster API para obtener más información.
Una vez adaptado a su entorno, puede aplicar el ejemplo mediante kubectl y, a continuación, supervisar el estado del clúster mediante 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 Ampliación de trabajador/cómputo #
De forma similar a la ampliación del plano de control, definimos un manifiesto YAML que contiene los siguientes recursos:
MachineDeployment define el número de réplicas (hosts) y el proveedor de inicio/infraestructura (en este caso, RKE2/Metal3).
RKE2ConfigTemplate describe la versión de RKE2 y la configuración de primer arranque para la inicialización del host agente.
Metal3MachineTemplate define la imagen del SO que se aplicará a los recursos BareMetalHost, y el selector de host define qué BareMetalHosts consumir
Metal3DataTemplate define metadatos adicionales que se pasarán al BareMetalHost (tenga en cuenta que
networkDatano es compatible actualmente).
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: machineUna vez que se haya copiado y adaptado el ejemplo anterior a su entorno, se puede aplicarlo mediante kubectl y, a continuación, se puede supervisar el estado del clúster con 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 Desaprovisionamiento del clúster #
El clúster descendente puede desaprovisionarse eliminando los recursos aplicados en los pasos de creación anteriores:
% kubectl delete -f rke2-agent.yaml
% kubectl delete -f rke2-control-plane.yamlEsto activa el desaprovisionamiento de los recursos BareMetalHost, lo que puede llevar varios minutos, tras lo cual deberían volver a estar en estado disponible:
% 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 conocidos #
El controlador de gestión de direcciones IP ascendente no es compatible actualmente, ya que aún no es compatible con nuestra elección de herramientas de configuración de red y cadena de herramientas de primer arranque en SLEMicro.
Relacionado con esto, los recursos IPAM y los campos networkData de Metal3DataTemplate no son compatibles actualmente.
Solo se admite actualmente el despliegue mediante redfish-virtualmedia.
4.6 Cambios previstos #
Habilitar la compatibilidad de los recursos IPAM y la configuración mediante campos networkData
4.7 Otros recursos #
La Documentación del clúster de gestión de SUSE Telco Cloud (Part V, “Configuración del clúster de gestión”) contiene ejemplos de un uso más avanzado de Metal3 para casos de uso de telecomunicaciones.
4.7.1 Configuración de nodo único #
Para entornos de prueba/PoC donde el clúster de gestión es un nodo único, es posible evitar el requisito de una IP flotante adicional gestionada a través de MetalLB.
En este modo, el punto final para las API del clúster de gestión es la IP del clúster de gestión, por lo tanto, debe reservarse al utilizar DHCP o configurarse de forma estática para garantizar que la IP del clúster de gestión no cambie, denominado <MANAGEMENT_CLUSTER_IP> a continuación.
Para habilitar este escenario, los valores del gráfico Metal3 necesarios son los siguientes:
global:
ironicIP: <MANAGEMENT_CLUSTER_IP>
metal3-ironic:
service:
type: NodePort4.7.2 Deshabilitación de TLS para la conexión de ISO de virtualmedia #
Algunos proveedores de servidores verifican la conexión SSL al conectar imágenes ISO de virtual-media al BMC, lo que puede causar un problema porque los certificados generados para el despliegue de Metal3 están autofirmados; para solucionar este problema, es posible deshabilitar TLS solo para la conexión de disco de virtualmedia con los valores del gráfico Metal3 de la siguiente manera:
global:
enable_vmedia_tls: falseUna solución alternativa es configurar los BMCs con el certificado de CA; en este caso, puede leer los certificados del clúster utilizando kubectl:
kubectl get secret -n metal3-system ironic-vmedia-cert -o yamlEl certificado se puede configurar entonces en la consola BMC del servidor, aunque el proceso para ello es específico del proveedor (y no es posible para todos los proveedores, en cuyo caso puede ser necesario el parámetro enable_vmedia_tls).
4.7.3 Configuración de storage #
Para entornos de prueba/PoC donde el clúster de gestión es un nodo único, no se requiere almacenamiento persistente, pero para casos de uso de producción se recomienda instalar SUSE Storage (Longhorn) en el clúster de gestión para que las imágenes relacionadas con Metal3 puedan persistir durante un reinicio/reprogramación de pod.
Para habilitar este almacenamiento persistente, los valores del gráfico Metal 3 necesarios son los siguientes:
metal3-ironic:
persistence:
ironic:
size: "5Gi"La documentación de SUSE Telco Cloud Management Cluster (Part V, “Configuración del clúster de gestión”) contiene más detalles sobre cómo configurar un clúster de gestión con almacenamiento persistente.
