documentation.suse.com / Documentación de SUSE Edge
Documentation survey

Documentación de SUSE Edge

Fecha de publicación: 07/09/2025

Documentación de SUSE Edge 3.3.1

Le damos la bienvenida a la documentación de SUSE Edge. Aquí, encontrará una descripción general de la arquitectura, guías de inicio rápido, diseños validados, orientación sobre el uso de los componentes, integraciones de terceros y prácticas recomendadas para gestionar su infraestructura y sus cargas de trabajo de edge computing.

1 ¿Qué es SUSE Edge?

SUSE Edge es una solución integral, diseñada específicamente, estrechamente integrada y validada de forma exhaustiva para abordar los retos únicos que plantea el despliegue de infraestructura y aplicaciones nativas de la nube en el perímetro. Su objetivo principal es proporcionar una plataforma propia, pero altamente flexible, escalable y segura, que abarque desde la creación de imágenes de distribución inicial, el aprovisionamiento y la incorporación de nodos, el despliegue de aplicaciones, la observabilidad y las operaciones completas del ciclo de vida. La plataforma se basa por completo en el mejor software de código abierto, en consonancia con nuestros más de 30 años de historia proporcionando plataformas SUSE Linux seguras, estables y certificadas, y en nuestra experiencia en la gestión de Kubernetes altamente escalable y rica en funciones con nuestra cartera de productos Rancher. SUSE Edge se basa en estas capacidades para ofrecer funcionalidades que pueden aplicarse a numerosos segmentos de mercado, incluyendo el comercio minorista, la medicina, el transporte, la logística, las telecomunicaciones, la fabricación inteligente y el IoT industrial.

2 Filosofía de diseño

La solución se ha diseñado partiendo de la idea de que no existe una plataforma periférica única "válida para todo", debido a la gran variedad de requisitos y expectativas de los clientes. Los despliegues periféricos nos obligan a evolucionar para resolver continuamente problemas difíciles, como la escalabilidad masiva, la disponibilidad limitada de la red, las restricciones de espacio físico, las nuevas amenazas de seguridad y vectores de ataque, las variaciones en la arquitectura del hardware y los recursos del sistema, la necesidad de implantar e interactuar con infraestructuras y aplicaciones heredadas, y las soluciones de los clientes que tienen una vida útil prolongada. Dado que para muchos de estos retos es preciso pensar más allá de las fórmulas habituales, por ejemplo, en el despliegue de infraestructura y aplicaciones dentro de centros de datos o en la nube pública, tenemos que examinar el diseño con mucho más detalle y replantearnos muchas ideas que no hay que dar por hechas.

Por ejemplo, valoramos el minimalismo, la modularidad y la facilidad de uso. El minimalismo es importante para los entornos periféricos, ya que cuanto más complejo es un sistema, más probable es que tenga problemas. Cuando se analizan cientos de ubicaciones, y hasta cientos de miles, los sistemas complejos fallan de formas complejas. La modularidad de nuestra solución permite una mayor elección por parte del usuario, al tiempo que elimina la complejidad innecesaria en la plataforma. También debemos aportar facilidad de uso. Los seres humanos pueden cometer errores al repetir un proceso miles de veces, por lo que la plataforma debe garantizar que cualquier error potencial sea recuperable, eliminando la necesidad de visitas de técnicos in situ, pero también procurando que se consiga coherencia y estandarización.

3 Arquitectura general

La arquitectura general del sistema SUSE Edge se divide en dos categorías principales: clústeres de "gestión" y clústeres "descendentes". El clúster de gestión se encarga de la gestión remota de uno o varios clústeres descendentes, aunque se entiende que, en determinadas circunstancias, los clústeres descendentes deben funcionar sin gestión remota; por ejemplo, en situaciones en las que un sitio periférico no tenga conectividad externa y deba funcionar de forma aislada. En SUSE Edge, los componentes técnicos que se utilizan para el funcionamiento de los clústeres de gestión y descendentes son en gran medida comunes, aunque se pueden diferenciar tanto en las especificaciones del sistema como en las aplicaciones que residen en ellos; es decir, el clúster de gestión ejecutaría aplicaciones que permitan la gestión de sistemas y las operaciones del ciclo de vida, mientras que los clústeres descendentes cumplirían los requisitos para dar servicio a las aplicaciones de los usuarios.

3.1 Componentes usados en SUSE Edge

SUSE Edge está formado por componentes de SUSE y de Rancher, junto con funciones y componentes adicionales creados por el equipo de Edge para permitirnos abordar las limitaciones y complejidades que requiere la edge computing. En el diagrama simplificado siguiente se explican los componentes usados tanto en los clústeres de gestión como en los clústeres descendentes. Sin ser una lista exhaustiva, muestra la arquitectura general:

3.1.1 Clúster de gestión

clúster de gestión de suse edge
  • Gestión: esta es la parte centralizada de SUSE Edge que se usa para gestionar el aprovisionamiento y el ciclo de vida de los clústeres descendentes. El clúster de gestión suele incluir los componentes siguientes:

    • Gestión de varios clústeres con Rancher Prime (Capítulo 5, Rancher), que incluye un panel de control común para incorporar clústeres descendentes y para la gestión continua del ciclo de vida de la infraestructura y las aplicaciones, además de proporcionar un aislamiento completo de los inquilinos e integraciones de IDP (proveedores de identidad), un amplio mercado de integraciones y extensiones de terceros, y una API independiente del proveedor.

    • Gestión de sistemas Linux con SUSE Multi-Linux Manager, que permite la gestión automatizada de parches y configuraciones de Linux del sistema operativo Linux subyacente (*SUSE Linux Micro, Capítulo 9, SUSE Linux Micro) que se ejecuta en los clústeres descendentes. Tenga en cuenta que aunque este componente está en contenedores, actualmente debe ejecutarse en un sistema independiente del resto de los componentes de gestión, por lo que se etiqueta como "Gestión de Linux" en el diagrama anterior.

    • Un controlador dedicado de gestión del ciclo de vida (Capítulo 23, Upgrade Controller) que se encarga de la actualización de los componentes del clúster de gestión a una versión determinada de SUSE Edge.

    • Incorporación remota del sistema a Rancher Prime con Elemental (Capítulo 13, Elemental), lo que permite la vinculación posterior de los nodos periféricos conectados a los clústeres de Kubernetes deseados y el despliegue de aplicaciones, por ejemplo, a través de GitOps.

    • Compatibilidad opcional completa del ciclo de vida y la gestión física (bare metal) con los proveedores de infraestructura Metal3 (Capítulo 10, Metal3), MetalLB (Capítulo 19, MetalLB) y CAPI (Cluster API), lo que permite el aprovisionamiento completo de extremo a extremo de sistemas físicos con capacidades de gestión remota.

    • Un motor GitOps opcional llamado Fleet (Capítulo 8, Fleet) para gestionar el aprovisionamiento y el ciclo de vida de los clústeres descendentes y las aplicaciones que residen en ellos.

    • El clúster de gestión tiene SUSE Linux Micro (Capítulo 9, SUSE Linux Micro) como sistema operativo base y RKE2 (Capítulo 16, RKE2) como distribución de Kubernetes que aporta compatibilidad con las aplicaciones del clúster de gestión.

3.1.2 Clústeres descendentes

clúster descendente de suse edge
  • Descendentes: esta es la parte distribuida de SUSE Edge que se utiliza para ejecutar las cargas de trabajo del usuario en el perímetro; es decir, el software que se ejecuta en la propia ubicación perimetral y que, normalmente, se compone de los siguientes componentes:

    • Una selección de distribuciones de Kubernetes, con distribuciones seguras y ligeras como K3s (Capítulo 15, K3s) y RKE2 (Capítulo 16, RKE2) (RKE2 está reforzada, certificada y optimizada para su uso en el sector público y en industrias reguladas).

    • SUSE Security (Capítulo 18, SUSE Security) para habilitar funciones de seguridad como el análisis de vulnerabilidades de imágenes, la inspección profunda de paquetes y la protección en tiempo real contra amenazas y vulnerabilidades.

    • Software de almacenamiento en bloques con SUSE Storage (Capítulo 17, SUSE Storage) que permite un sistema de almacenamiento en bloques ligero, persistente, resistente y escalable.

    • Un sistema operativo Linux ligero, optimizado para contenedores y reforzado con SUSE Linux Micro (Capítulo 9, SUSE Linux Micro), que proporciona un sistema operativo inmutable y altamente resiliente para ejecutar contenedores y máquinas virtuales en el perímetro. SUSE Linux Micro está disponible para las arquitecturas AArch64 y AMD64/Intel 64, y también admite kernel en tiempo real para aplicaciones sensibles a la latencia (por ejemplo, para usos en telecomunicaciones).

    • Para los clústeres conectados (los que tienen conectividad con el clúster de gestión), se despliegan dos agentes: Rancher System Agent, para gestionar la conectividad con Rancher Prime, y venv-salt-minion, para recibir instrucciones de SUSE Multi-Linux Manager y aplicar las actualizaciones de software de Linux. Estos agentes no son necesarios para la gestión de clústeres desconectados.

3.2 Conectividad

arquitectura conectada de suse edge

La imagen anterior ofrece una descripción general de la arquitectura de los clústeres descendentes conectados y sus conexiones con el clúster de gestión. El clúster de gestión se puede desplegar en una amplia variedad de plataformas de infraestructura subyacentes, tanto en instalaciones locales como en la nube, dependiendo de la disponibilidad de red entre los clústeres descendentes y el clúster de gestión de destino. El único requisito para que funcione es que sea posible acceder a las API y las URL de redirección a través de la red que conecta los nodos del clúster descendente con la infraestructura de gestión.

Es importante entender que existen mecanismos distintos en los que se establece esta conectividad en relación con el mecanismo de despliegue del clúster descendente. Esto se explica con mucho más detalle en la siguiente sección. Como descripción general: existen tres mecanismos principales para que los clústeres descendentes conectados se establezcan como un clúster "gestionado":

  1. Los clústeres descendentes se despliegan inicialmente en modo "desconectado" (por ejemplo, mediante Edge Image Builder, Capítulo 11, Edge Image Builder) y, a continuación, se importan al clúster de gestión si la conectividad lo permite.

  2. Los clústeres descendentes se configuran para utilizar el mecanismo de incorporación integrado (por ejemplo, a través de Elemental (Capítulo 13, Elemental)) y se registran automáticamente en el clúster de gestión en el primer arranque, lo que permite la vinculación posterior de la configuración del clúster.

  3. Los clústeres descendentes se han aprovisionado con capacidades de gestión bare metal (CAPI + Metal3) y se importan automáticamente en el clúster de gestión después de que este se haya desplegado y configurado (a través del operador Rancher Turtles).

Nota
Nota

Se recomienda desplegar varios clústeres de gestión para adaptarse a la escala de los despliegues de gran tamaño, optimizar el ancho de banda y la latencia en entornos geográficamente dispersos, y minimizar las interrupciones en caso de una caída del servicio o una actualización del clúster de gestión. Encontrará los límites actuales de escalabilidad del clúster de gestión y los requisitos del sistema aquí.

4 Patrones de despliegue perimetrales comunes

Debido a la variedad de entornos operativos y requisitos de ciclo de vida existentes, hemos implantado compatibilidad para una serie de patrones de despliegue que se ajustan de manera general a los sectores del mercado y los casos de uso en los que funciona SUSE Edge. Hemos creado una guía de inicio rápido para cada uno de estos patrones a fin de que pueda familiarizarse con la plataforma SUSE Edge en función de sus necesidades. A continuación, se describen los tres patrones de despliegue que admitimos actualmente, con un enlace a la página de inicio rápido correspondiente.

4.1 Aprovisionamiento de red dirigida

En el aprovisionamiento de red dirigida se conocen los detalles del hardware en el que se desea realizar el despliegue y se tiene acceso directo a la interfaz de gestión fuera de banda para orquestar y automatizar todo el proceso de aprovisionamiento. En este caso, nuestros clientes esperan una solución que permita aprovisionar los sitios periféricos de forma totalmente automatizada desde una ubicación centralizada, lo que va mucho más allá de la simple creación de una imagen de arranque al minimizar las operaciones manuales en la ubicación periférica; basta con montar, alimentar y conectar las redes necesarias al hardware físico y el proceso de automatización enciende el equipo mediante la gestión fuera de banda (por ejemplo, a través de la API Redfish) y se encarga del aprovisionamiento, la incorporación y la implantación de la infraestructura sin intervención del usuario. La clave para que este modelo funcione es que los administradores conozcan los sistemas y que sepan qué hardware hay en cada ubicación y que el despliegue se gestionará de forma centralizada.

Esta solución es la más robusta, ya que interactúa directamente con la interfaz de gestión del hardware, trabaja con hardware conocido y tiene menos restricciones en cuanto a la disponibilidad de la red. En cuanto a la funcionalidad, esta solución utiliza ampliamente Cluster API y Metal3 para el aprovisionamiento automatizado, desde bare metal, pasando por el sistema operativo y Kubernetes hasta las aplicaciones en capas; y ofrece la posibilidad de vincularse al resto de las capacidades comunes de gestión del ciclo de vida de SUSE Edge tras el despliegue. La guía de inicio rápido para esta solución se puede encontrar en el Capítulo 1, Despliegues automatizados de BMC con Metal3.

4.2 Aprovisionamiento de red "phone home"

A veces, se trabaja en un entorno en el que el clúster de gestión central no puede gestionar el hardware directamente (por ejemplo, si la red remota está protegida por un cortafuegos o no hay una interfaz de gestión fuera de banda, algo habitual en el hardware de tipo "PC" que suele encontrarse en el perímetro). En este caso, proporcionamos herramientas para aprovisionar de forma remota los clústeres y sus cargas de trabajo sin necesidad de saber dónde se envía el hardware cuando se arranca. Este sistema es en el que la mayoría de la gente piensa al hablar de la edge computing: son los miles de sistemas algo desconocidos que se arrancan en ubicaciones periféricas y se comunican de forma segura con la central, validando quiénes son y recibiendo instrucciones sobre lo que deben hacer. Aquí se espera un aprovisionamiento y una gestión del ciclo de vida con muy poca intervención del usuario, aparte de la creación previa de imágenes del equipo en fábrica o de simplemente conectar una imagen de arranque, por ejemplo, a través de USB, y encender el sistema. Los principales retos en este modelo son cómo abordar la escala, la coherencia, la seguridad y el ciclo de vida de estos dispositivos en el mundo real.

Esta solución ofrece una gran flexibilidad y coherencia en la forma en que se aprovisionan e incorporan los sistemas, independientemente de su ubicación, tipo o especificaciones, o de cuándo se encienden por primera vez. SUSE Edge permite una flexibilidad y personalización totales del sistema a través de Edge Image Builder y aprovecha las capacidades de registro que ofrece Elemental para la incorporación de nodos y el aprovisionamiento de Kubernetes, junto con SUSE Multi-Linux Manager para la aplicación de parches al sistema operativo. La guía de inicio rápido de esta solución se puede encontrar en el Capítulo 2, Incorporación de hosts remotos con Elemental.

4.3 Aprovisionamiento basado en imágenes

Para los clientes que necesitan operar en entornos independientes, aislados o con limitaciones de red, SUSE Edge ofrece una solución que permite generar medios de instalación totalmente personalizados con todos los artefactos de despliegue necesarios para habilitar clústeres de Kubernetes de alta disponibilidad en el perímetro, tanto de un solo nodo como de múltiples nodos, incluyendo cualquier carga de trabajo o los componentes adicionales en capas que se requieran. Todo ello sin necesidad de conectividad de red con el mundo exterior y sin la intervención de una plataforma de gestión centralizada. La experiencia del usuario se asemeja mucho a la solución "phone home", en la que se proporcionan medios de instalación a los sistemas de destino, pero la solución se "arranca in situ". En este escenario, es posible conectar los clústeres resultantes a Rancher para su gestión continua (es decir, pasar de un modo de funcionamiento "desconectado" a "conectado" sin necesidad de realizar una reconfiguración o un redespliegue importantes), o bien seguir funcionando de forma aislada. Tenga en cuenta que, en ambos casos, se puede aplicar el mismo mecanismo unificado para automatizar las operaciones del ciclo de vida.

Además, esta solución se puede utilizar para crear rápidamente clústeres de gestión que puedan alojar la infraestructura centralizada que admite tanto el modelo de "aprovisionamiento de red dirigida" como el de "aprovisionamiento de red 'phone home'", ya que puede ser la forma más rápida y sencilla de aprovisionar todo tipo de infraestructura periférica. Esta solución utiliza en gran medida las capacidades de SUSE Edge Image Builder para crear medios de instalación totalmente personalizados y desatendidos. La guía de inicio rápido se puede encontrar en el Capítulo 3, Clústeres independientes con Edge Image Builder.

5 Validación de la pila SUSE Edge

Todas las versiones de SUSE Edge tienen componentes estrechamente integrados y minuciosamente validados que se lanzan unidos. Como parte de los esfuerzos de integración continua y validación de la pila, que no solo prueban la integración entre componentes, sino que también garantizan que el sistema funcione según lo esperado en escenarios de fallo forzado, el equipo de SUSE Edge publica todas las pruebas realizadas y sus resultados. Estos, junto con todos los parámetros de entrada, se pueden encontrar en ci.edge.suse.com.

6 Lista completa de componentes

Esta es la lista completa de componentes, junto con un enlace a una descripción general de cada uno de ellos y cómo se utilizan en SUSE Edge:

Parte I Guías de inicio rápido

Aquí están las guías de inicio rápido

  • 1 Despliegues automatizados de BMC con Metal3
  • Metal3 es un projecto de la CNCF que proporciona capacidades de gestión de infraestructura bare metal para Kubernetes.

  • 2 Incorporación de hosts remotos con Elemental
  • En esta sección se explica la solución de aprovisionamiento de red "phone home" (el comando que se usa, traducido como "llamar a casa") como parte de SUSE Edge. En ella se utiliza Elemental para ayudar con la incorporación de nodos. Elemental es una pila de software que permite el registro remoto de…

  • 3 Clústeres independientes con Edge Image Builder
  • Edge Image Builder (EIB) es una herramienta que agiliza el proceso de generación de imágenes de disco personalizadas y listas para arrancar (CRB) para equipos de arranque, incluso en entornos totalmente aislados. EIB se utiliza para crear imágenes de despliegue para su uso en las tres huellas de des…

  • 4 SUSE Multi-Linux Manager
  • SUSE Multi-Linux Manager está incluido en SUSE Edge y proporciona automatización y control con el fin de mantener el sistema operativo subyacente SUSE Linux Micro constantemente actualizado en todos los nodos de su despliegue periférico.

1 Despliegues automatizados de BMC con Metal3

Metal3 es un projecto de la CNCF que proporciona capacidades de gestión de infraestructura bare metal para Kubernetes.

Metal3 ofrece recursos nativos de Kubernetes para gestionar el ciclo de vida de los servidores bare metal que admiten la gestión a través de 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 de infraestructura mediante API ampliamente adoptadas y neutrales con respecto a los proveedores.

1.1 Por qué usar este método

Este método es útil para situaciones en las que el hardware de destino admite la gestión fuera de banda y se desea un flujo de gestión de la infraestructura totalmente automatizado.

Se configura un clúster de gestión para proporcionar API declarativas que permitan la gestión del inventario y el estado de los servidores bare metal del clúster descendente, incluida la inspección, limpieza y aprovisionamiento/desaprovisionamiento automatizados.

1.2 Arquitectura general

inicio rápido de la arquitectura de metal3

1.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 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 mediante interfaces Redfish, iDRAC o iLO

    • Deben admitir el despliegue mediante medios virtuales (actualmente no se admite PXE)

    • Deben tener conectividad de red con el clúster de gestión para acceder a las API de aprovisionamiento de Metal3

Se requieren algunas herramientas, que se pueden instalar en el clúster de gestión o en un host que pueda acceder a él.

El archivo de imagen de sistema operativo SL-Micro.x86_64-6.1-Base-GM.raw se debe descargar del Centro de servicios al cliente de SUSE o de la página de descargas de SUSE.

1.3.1 Configuración del clúster de gestión

Los pasos básicos para instalar un clúster de gestión y usar Metal3 son:

  1. Instalar un clúster de gestión RKE2

  2. Instalar Rancher

  3. Instalar un proveedor de almacenamiento (opcional)

  4. Instalar las dependencias de Metal3

  5. Instalar las dependencias de CAPI mediante Rancher Turtles

  6. Crear una imagen del sistema operativo SLEMicro para los hosts del clúster descendente

  7. Registrar los CR de BareMetalHost para definir el inventario de bare metal

  8. Crear un clúster descendente definiendo los recursos de CAPI

En esta guía se entiende que ya existe un clúster RKE2 y que se ha instalado Rancher (incluido cert-manager), por ejemplo, utilizando Edge Image Builder (Capítulo 11, Edge Image Builder).

Sugerencia
Sugerencia

Estos pasos también se pueden automatizar por completo, como se describe en la documentación sobre el clúster de gestión (Capítulo 40, Configuración del clúster de gestión).

1.3.2 Instalación de las dependencias de Metal3

Si aún no se ha hecho como parte de la instalación de Rancher, se debe instalar y ejecutar cert-manager.

Se debe instalar un proveedor de almacenamiento persistente. Se recomienda SUSE Storage, pero también se puede utilizar local-pathprovisioner para entornos de desarrollo/PoC. Las instrucciones siguientes dan por sentado que se ha marcado una StorageClass como predeterminada; de lo contrario, se requiere una configuración adicional para el chart de Metal3.

Se requiere una IP adicional, gestionada por MetalLB para proporcionar un punto final coherente 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).

Sugerencia
Sugerencia

Si el clúster de gestión es un solo nodo, no es necesario contar con una IP fleetnte adicional gestionada mediante MetalLB. Consulte la Sección 1.6.1, “Configuración de un solo nodo”.

  1. Primero, se instala MetalLB:

    helm install \
      metallb oci://registry.suse.com/edge/charts/metallb \
      --namespace metallb-system \
      --create-namespace
  2. Luego, se definen IPAddressPool y L2Advertisement con la IP reservada, definida como STATIC_IRONIC_IP a 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]}
    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
  3. Ya se puede instalar Metal3:

    helm install \
      metal3 oci://registry.suse.com/edge/charts/metal3 \
      --namespace metal3-system \
      --create-namespace \
      --set global.ironicIP="$STATIC_IRONIC_IP"
  4. El contenedor de inicio puede tardar unos dos minutos en ejecutarse en este despliegue, así que asegúrese de que todos los pods estén funcionando 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
Aviso
Aviso

No continúe con los siguientes pasos hasta que todos los pods del espacio de nombres metal3-system estén en ejecución.

1.3.3 Instalación de las dependencias de Cluster API

Las dependencias de Cluster API se gestionan mediante el chart de Helm de 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

Después de un tiempo, los pods del controlador deberían estar ejecutándose en los espacios de nombres capi-system, capm3-system, rke2-bootstrap-system y rke2-control-plane-system.

1.3.4 Preparación de la imagen del clúster descendente

Kiwi (Capítulo 28, Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi) y Edge Image Builder (Capítulo 11, Edge Image Builder) se usan para preparar una imagen base de SLEMicro modificada que se aprovisiona en los hosts de clústeres descendentes.

En esta guía, se trata la configuración mínima necesaria para desplegar el clúster descendente.

1.3.4.1 Configuración de la imagen

Nota
Nota

Como primer paso necesario para crear clústeres, cree una imagen nueva siguiendo las instrucciones del Capítulo 28, Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi.

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 usados para definir la imagen de destino.

├── 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 Archivo de definición de la imagen del clúster descendente

El archivo downstream-cluster-config.yaml es el principal archivo de configuración para la imagen del clúster descendente. A continuación, se muestra un ejemplo mínimo de despliegue mediante 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

Donde $SCC_REGISTRATION_CODE es el código de registro copiado del Centro de servicios al cliente de SUSE y la lista de paquetes contiene jq, que es obligatorio.

$ROOT_PASSWORD es la contraseña cifrada del usuario root, que puede ser útil para pruebas y depuración. Se puede generar con el comando openssl passwd -6 PASSWORD.

En entornos de producción, se recomienda usar las claves SSH que se pueden añadir al bloque de usuarios sustituyendo $USERKEY1 por las claves SSH reales.

Nota
Nota

net.ifnames=1 permite los nombres predecibles para las interfaces de red

Esto coincide con la configuración predeterminada para el chart de Metal3, pero el ajuste debe coincidir con el valor de predictableNicNames configurado en el chart.

Tenga en cuenta también que ignition.platform.id=openstack es obligatorio. Sin este argumento, la configuración de SUSE Linux Micro a través de 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 la desviación del reloj. Los valores proporcionados en este ejemplo son solo ilustrativos. Ajústelos según sus requisitos específicos.

1.3.4.1.2 Guion Growfs

Actualmente, se requiere un guion 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 después del aprovisionamiento. El guion 01-fix-growfs.sh contiene la siguiente información:

#!/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 /
Nota
Nota

Use el mismo método para añadir sus propios guiones personalizados que se ejecuten durante el proceso de aprovisionamiento. Para obtener más información, consulte el Capítulo 3, Clústeres independientes con Edge Image Builder.

1.3.4.2 Creación de la imagen

Cuando se haya preparado la estructura de directorios siguiendo las secciones anteriores, ejecute el siguiente comando para crear la imagen:

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

Esto crea el archivo de imagen de salida denominado SLE-Micro-eib-output.raw, basado en la definición descrita anteriormente.

La imagen resultante debe estar disponible a través de un servidor web, ya sea el contenedor del servidor multimedia habilitado mediante el chart de Metal3 (Nota) o algún otro servidor al que se pueda acceder localmente. En los ejemplos siguientes, nos referimos a este servidor como imagecache.local:8080.

Nota
Nota

Al desplegar imágenes de EIB en clústeres descendentes, 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.sha256

1.3.5 Adición del inventario de BareMetalHost

El registro de servidores bare metal para el despliegue automatizado requiere la creación de dos recursos: un secreto que almacena las credenciales de acceso a BMC y un recurso BareMetalHost de Metal3 que define la conexión de 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:
  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

Tenga en cuenta lo siguiente:

  • El nombre de usuario y la contraseña del secreto deben estar cifrados en base64. No deben incluir saltos de línea al final (por ejemplo, use echo -n, no solo echo)

  • La etiqueta cluster-role se puede establecer ahora o más adelante, durante la creación del clúster. En el ejemplo siguiente, se espera control-plane o worker

  • bootMACAddress debe ser una dirección MAC válida que coincida con la NIC de plano de control del host

  • La dirección bmc es la conexión a la API de gestión de BMC. Se admiten las siguientes:

    • redfish-virtualmedia://<DIRECCIÓN IP>/redfish/v1/Systems/<ID DEL SISTEMA>: medio virtual Redfish, por ejemplo, SuperMicro

    • idrac-virtualmedia://<DIRECCIÓN IP>/redfish/v1/Systems/System.Embedded.1: iDRAC de Dell

  • Consulte la documentación original de la API para obtener más información sobre la API de BareMetalHost

1.3.5.1 Configuración de IP estáticas

El ejemplo anterior de BareMetalHost presupone que DHCP proporciona la configuración de red del plano de control, pero para situaciones en las que se necesite una configuración manual, como en el caso de las IP estáticas, es posible proporcionar una configuración adicional, como se describe a continuación.

1.3.5.1.1 Guion adicional para la configuración de la red estática

Al crear la imagen base con Edge Image Builder, en la carpeta de network, cree el archivo configure-network.sh siguiente.

Esto consume datos de la unidad de configuración en el primer arranque y configura la red del host usando 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

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 Secreto adicional con configuración de red de host

Se puede definir un secreto adicional que contenga datos en el formato nmstate compatible con NM Configurator (Capítulo 12, Conexiones de red de Edge) para cada host.

A continuación, se hace referencia al secreto en el recurso BareMetalHost mediante el campo de especificación 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
Nota
Nota

En algunas circunstancias, la dirección MAC puede omitirse. Consulte la Sección 12.5.8, “Configuraciones unificadas de nodos” para obtener más detalles.

1.3.5.2 Preparación de BareMetalHost

Después de crear el recurso BareMetalHost y los secretos asociados como se ha descrito, se activa un flujo de trabajo de preparación del host:

  • Se arranca una imagen ramdisk mediante la conexión de un dispositivo virtual al BMC del host de destino

  • El ramdisk inspecciona los detalles del hardware y prepara el host para el aprovisionamiento (por ejemplo, limpiando los discos de datos anteriores)

  • Una vez completado este proceso, se actualizan los detalles del hardware en el campo status.hardware de BareMetalHost y se pueden verificar

Este proceso puede tardar varios minutos, pero una vez completado, debería ver que el estado de BareMetalHost pasa a ser available (disponible):

% kubectl get baremetalhost
NAME             STATE       CONSUMER   ONLINE   ERROR   AGE
controlplane-0   available              true             9m44s
worker-0         available              true             9m44s

1.3.6 Creación de clústeres descendentes

Ahora creamos recursos de Cluster API que definen el clúster descendente y recursos del equipo que provocarán que se aprovisionen los recursos de BareMetalHost y, a continuación, se arranquen para formar un clúster RKE2.

1.3.7 Despliegue del plano de control

Para desplegar el plano de control, se define un manifiesto YAML similar al que se muestra 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 un solo nodo, punto final LoadBalancer para varios nodos; en este ejemplo se supone que hay un solo nodo)

  • RKE2ControlPlane define la versión de RKE2 y cualquier configuración adicional necesaria durante el arranque del clúster

  • Metal3MachineTemplate define la imagen del sistema operativo que se aplicará a los recursos BareMetalHost, y hostSelector define qué recursos BareMetalHost se consumirán

  • Metal3DataTemplate define los metadatos adicionales que se pasarán a BareMetalHost (tenga en cuenta que networkData no es compatible actualmente con Edge)

Nota
Nota

Para simplificar, en este ejemplo se entiende que hay un plano de control de un solo nodo en el que BareMetalHost se ha configurado con la IP 192.168.125.200. Para ejemplos más avanzados de varios nodos, consulte el Capítulo 42, Aprovisionamiento de red dirigida 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

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                     23m

1.3.8 Despliegue de trabajadores/computación

De forma similar al despliegue del plano de control, se define un manifiesto YAML que contiene los siguientes recursos:

  • MachineDeployment define el número de réplicas (hosts) y el proveedor de arranque/infraestructura (en este caso, RKE2/Metal3)

  • RKE2ConfigTemplate describe la versión de RKE2 y la configuración de arranque inicial para el arranque del host del agente

  • Metal3MachineTemplate define la imagen del sistema operativo que se aplicará a los recursos BareMetalHost, y el selector de host define qué recursos BareMetalHost se consumirán

  • Metal3DataTemplate define los metadatos adicionales que se pasarán a BareMetalHost (tenga en cuenta que networkData no es compatible actualmente)

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

Una vez copiado y adaptado el ejemplo anterior a su entorno, se puede aplicar 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                     23m

1.3.9 Desaprovisionamiento del clúster

El clúster descendente se puede desaprovisionar eliminando los recursos aplicados en los pasos anteriores:

% kubectl delete -f rke2-agent.yaml
% kubectl delete -f rke2-control-plane.yaml

Esto activa el desaprovisionamiento de los recursos BareMetalHost, lo que puede tardar varios minutos, tras lo cual deberían volver a estar disponibles:

% 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 conocidos

  • El controlador de gestión de direcciones IP actualmente no se admite, ya que aún no es compatible con nuestras herramientas de configuración de red y la cadena de herramientas de primer arranque en SLEMicro.

  • Del mismo modo, los recursos IPAM y los campos networkData de Metal3DataTemplate no son compatibles actualmente.

  • Actualmente, solo se admite el despliegue mediante redfish-virtualmedia.

1.5 Cambios previstos

  • Habilitar la compatibilidad con los recursos y la configuración de IPAM a través de los campos networkData.

1.6 Recursos adicionales

La documentación de SUSE Edge for Telco (Capítulo 37, SUSE Edge for Telco) tiene ejemplos de uso más avanzados de Metal3 para casos de uso relacionados con las telecomunicaciones.

1.6.1 Configuración de un solo nodo

En entornos de prueba/PoC en los que el clúster de gestión es de un solo nodo, no se necesita una IP fleetnte 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 que debe reservarse cuando se utiliza DHCP o debe configurarse de forma estática para garantizar que la IP del clúster de gestión no cambie, lo que se denomina <MANAGEMENT_CLUSTER_IP> abajo.

Para habilitar este escenario, los valores necesarios del chart de Metal3 son los siguientes:

global:
  ironicIP: <MANAGEMENT_CLUSTER_IP>
metal3-ironic:
  service:
    type: NodePort

1.6.2 Inhabilitación de TLS para la conexión ISO de medios virtuales

Algunos proveedores de servidores verifican la conexión SSL al conectar imágenes ISO de medios virtuales al BMC, lo que puede causar un problema porque los certificados generados para el despliegue de Metal3 son autofirmados. Para solucionar este problema, es posible desactivar TLS solo para la conexión del disco de medios virtuales con los valores del chart de Metal3 de la siguiente manera:

global:
  enable_vmedia_tls: false

Una solución alternativa es configurar los BMC con el certificado de la CA; en este caso, puede leer los certificados del clúster utilizando kubectl:

kubectl get secret -n metal3-system ironic-vmedia-cert -o yaml

A continuación, el certificado se puede configurar en el panel de control del BMC del servidor, aunque ese proceso es específico de cada proveedor (y no es posible para todos los proveedores, en cuyo caso puede ser necesario el indicador enable_vmedia_tls).

1.6.3 Configuración de almacenamiento

Para entornos de prueba/PoC en los que el clúster de gestión es de un solo nodo, no se requiere almacenamiento persistente, pero para casos de uso en producción se recomienda instalar SUSE Storage (Longhorn) en el clúster de gestión para que las imágenes relacionadas con Metal3 puedan conservarse durante el reinicio/reprogramación de un pod.

Para habilitar este almacenamiento persistente, los valores necesarios del chart de Metal3 son los siguientes:

metal3-ironic:
  persistence:
    ironic:
      size: "5Gi"

La documentación sobre el clúster de gestión en SUSE Edge for Telco (Capítulo 40, 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.

2 Incorporación de hosts remotos con Elemental

En esta sección se explica la solución de aprovisionamiento de red "phone home" (el comando que se usa, traducido como "llamar a casa") como parte de SUSE Edge. En ella se utiliza Elemental para ayudar con la incorporación de nodos. Elemental es una pila de software que permite el registro remoto de hosts y la gestión centralizada y totalmente nativa en la nube del sistema operativo con Kubernetes. En la pila de SUSE Edge se utiliza la función de registro de Elemental para permitir la incorporación remota de hosts en Rancher, de modo que los hosts puedan integrarse en una plataforma de gestión centralizada y, desde allí, desplegar y gestionar clústeres de Kubernetes junto con componentes en capas, aplicaciones y su ciclo de vida, todo desde un lugar común.

Este enfoque puede ser útil en situaciones en las que los dispositivos que se desean controlar no se encuentren en la misma red que el clúster de gestión o no dispongan de un controlador de gestión fuera de banda integrado que permita un control más directo, y en los que se están arrancando muchos sistemas "desconocidos" diferentes en el perímetro y es necesario incorporarlos y gestionarlos de forma segura a gran escala. Este es un escenario común para usos en el comercio minorista, el IoT industrial u otros espacios en los que se tiene poco control sobre la red en la que se instalan los dispositivos.

2.1 Arquitectura general

guía de inicio rápido de la arquitectura de elemental

2.2 Recursos necesarios

A continuación se describen los requisitos mínimos del sistema y del entorno para la ejecución:

  • Un host para el clúster de gestión centralizada (el que aloja Rancher y Elemental):

    • Mínimo de 8 GB de RAM y 20 GB de espacio en disco para desarrollo o pruebas (consulte este documento para el uso en producción)

  • Un nodo de destino que se va a aprovisionar, es decir, el dispositivo periférico (se puede utilizar una máquina virtual para fines de demostración o pruebas)

    • Mínimo de 4 GB de RAM, CPU de 2 núcleos y 20 GB de disco

  • Un nombre de host resoluble para el clúster de gestión o una dirección IP estática para utilizar con un servicio como sslip.io

  • Un host para crear el medio de instalación a través de Edge Image Builder

    • Ejecutar SLES 15 SP6, openSUSE Leap 15.6 u otro sistema operativo compatible que admita Podman

    • Con Kubectl, Podman y Helm instalados

  • Una unidad flash USB desde la que arrancar (si se utiliza hardware físico)

  • Una copia descargada de la última imagen ISO de autoinstalación de SUSE Linux Micro 6.1, que se encuentra aquí

Nota
Nota

Los datos existentes en los equipos de destino se sobrescribirán como parte del proceso, por lo que debe asegurarse de realizar una copia de seguridad de todos los datos almacenados en dispositivos USB y discos conectados a los nodos de despliegue de destino.

En esta guía se utiliza un droplet de Digital Ocean para alojar el clúster ascendente y un NUC Intel como dispositivo descendente. Para crear el medio de instalación, se utiliza SUSE Linux Enterprise Server.

2.3 Creación del clúster de arranque

Para empezar, cree un clúster capaz de alojar Rancher y Elemental. Este clúster debe ser enrutable desde la red a la que están conectados los nodos descendentes.

2.3.1 Creación del clúster de Kubernetes

Si utiliza un hiperescalador (como Azure, AWS o Google Cloud), la forma más sencilla de configurar un clúster es utilizando sus herramientas integradas. Para que esta guía sea más concisa, no se detalla el proceso de cada una de estas opciones.

Si va a realizar la instalación en un servidor físico u otro servicio de alojamiento en el que también deba proporcionar la distribución de Kubernetes, le recomendamos que utilice RKE2.

2.3.2 Configuración de DNS

Antes de continuar, debe configurar el acceso a su clúster. Como ocurre con la configuración del propio clúster, la forma de configurar el servidor DNS variará en función del lugar donde esté alojado.

Sugerencia
Sugerencia

Si no desea ocuparse de la configuración de los registros DNS (por ejemplo, si se trata solo de un servidor de prueba efímero), puede utilizar un servicio como sslip.io en su lugar. Con este servicio, puede resolver cualquier dirección IP con <dirección>.sslip.io.

2.4 Instalar Rancher

Para instalar Rancher, necesitas acceder a la API de Kubernetes del clúster que acabas de crear. Esto varía en función de la distribución de Kubernetes que se utilice.

Para RKE2, el archivo kubeconfig se habrá escrito en /etc/rancher/rke2/rke2.yaml. Guarde este archivo como ~/.kube/config en su sistema local. Es posible que tenga que editar el archivo para incluir la dirección IP o el nombre de host externos correctos.

Instale Rancher fácilmente con los comandos que encontrará en la documentación de Rancher:

Instale cert-manager:

helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
 --namespace cert-manager \
 --create-namespace \
 --set crds.enabled=true

Después, instale Rancher:

helm repo add rancher-prime https://charts.rancher.com/server-charts/prime
helm repo update
helm install rancher rancher-prime/rancher \
  --namespace cattle-system \
  --create-namespace \
  --set hostname=<DNS or sslip from above> \
  --set replicas=1 \
  --set bootstrapPassword=<PASSWORD_FOR_RANCHER_ADMIN> \
  --version 2.11.2
Nota
Nota

Si se trata de un sistema de producción, use cert-manager para configurar un certificado real (como uno de Let’s Encrypt).

Busque el nombre de host que ha configurado e inicie sesión en Rancher con la contraseña que ha utilizado en bootstrapPassword. Se le guiará a través de un breve proceso de configuración.

2.5 Instalación de Elemental

Una vez instalado Rancher, ya puede instalar el operador de Elemental y las CRD necesarias. El chart de Helm para Elemental se publica como un artefacto OCI, por lo que la instalación es un poco más sencilla que la de otros charts. Se puede instalar desde la misma shell que se utilizó para instalar Rancher o en el navegador desde la shell de Rancher.

helm install --create-namespace -n cattle-elemental-system \
 elemental-operator-crds \
 oci://registry.suse.com/rancher/elemental-operator-crds-chart \
 --version 1.6.8

helm install -n cattle-elemental-system \
 elemental-operator \
 oci://registry.suse.com/rancher/elemental-operator-chart \
 --version 1.6.8

2.5.1 (Opcional) Instale la extensión de interfaz de usuario de Elemental

  1. Para usar la interfaz de usuario de Elemental, inicie sesión en su instancia de Rancher y haga clic en el menú de tres líneas de la parte superior izquierda:

    Instalación de la extensión 1 de Elemental
  2. En la pestaña "Available" (Disponible) de esta página, haga clic en "Install" (Instalar) en la tarjeta de Elemental:

    Instalación de la extensión 2 de Elemental
  3. Confirme que desea instalar la extensión:

    Instalación de la extensión 3 de Elemental
  4. Cuando se instale, se le pedirá que vuelva a cargar la página.

    Instalación de la extensión 4 de Elemental
  5. Tras el reinicio, podrá acceder a la extensión de Elemental a través de la aplicación global "OS Management" (Gestión del sistema operativo).

    Acceso a la extensión de Elemental

2.6 Configuración de Elemental

Por sencillez, se recomienda configurar la variable $ELEM con la vía completa donde desea que se encuentre el directorio de configuración:

export ELEM=$HOME/elemental
mkdir -p $ELEM

Para permitir que las máquinas se registren en Elemental, se necesita crear un objeto MachineRegistration en el espacio de nombres fleet-default.

Vamos a crear una versión básica de este objeto:

cat << EOF > $ELEM/registration.yaml
apiVersion: elemental.cattle.io/v1beta1
kind: MachineRegistration
metadata:
  name: ele-quickstart-nodes
  namespace: fleet-default
spec:
  machineName: "\${System Information/Manufacturer}-\${System Information/UUID}"
  machineInventoryLabels:
    manufacturer: "\${System Information/Manufacturer}"
    productName: "\${System Information/Product Name}"
EOF

kubectl apply -f $ELEM/registration.yaml
Nota
Nota

El comando cat escapa cada $ con una barra invertida (\) para que Bash no las utilice como plantilla. Elimine las barras invertidas si va a realizar una copia manualmente.

Una vez creado el objeto, busque y anote el punto final que se le asigna:

REGISURL=$(kubectl get machineregistration ele-quickstart-nodes -n fleet-default -o jsonpath='{.status.registrationURL}')

Alternativamente, puede hacerlo desde la interfaz de usuario.

Extensión de interfaz de usuario
  1. Desde la extensión de gestión del sistema operativo, haga clic en "Create Registration Endpoint" (Crear punto final de registro):

    Haga clic en "Create Registration" (Crear registro).
  2. Asigne un nombre a esta configuración.

    Adición del nombre
    Nota
    Nota

    Puede ignorar el campo "Cloud Configuration" (Configuración de la nube) porque estos datos se sobrescriben con los del paso siguiente con Edge Image Builder.

  3. A continuación, desplácese hacia abajo y haga clic en "Add Label" (Añadir etiqueta) para cada etiqueta que desee que aparezca en el recurso que se crea cuando se registra un equipo. Esto resulta útil para distinguir cada equipo.

    Adición de etiquetas
  4. Haga clic en "Create" (Crear) para guardar la configuración.

  5. Una vez creado el registro, debería ver la URL de registro en la lista y puede hacer clic en "Copy" (Copiar) para copiar la dirección:

    Copia de la URL
    Sugerencia
    Sugerencia

    Si ha salido de esa pantalla, puede hacer clic en "Registration Endpoints" (Puntos finales de registro) en el menú de la izquierda y, a continuación, hacer clic en el nombre del punto final que acaba de crear.

    Esta URL se usa en el paso siguiente.

2.7 Creación de la imagen

Aunque la versión actual de Elemental permite crear sus propios medios de instalación, en SUSE Edge 3.3.1 se hace con Kiwi y Edge Image Builder, por lo que el sistema resultante se crea con SUSE Linux Micro como sistema operativo base.

Sugerencia
Sugerencia

Para obtener más información sobre Kiwi, siga el proceso de creación de imágenes de Kiwi (Capítulo 28, Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi) para crear imágenes nuevas en primer lugar. En el caso de Edge Image Builder, consulte la guía de introducción a Edge Image Builder (Capítulo 3, Clústeres independientes con Edge Image Builder) y la documentación de los componentes (Capítulo 11, Edge Image Builder).

Desde un sistema Linux con Podman instalado, cree los directorios y coloque la imagen base que está creando Kiwi:

mkdir -p $ELEM/eib_quickstart/base-images
cp /path/to/{micro-base-image-iso} $ELEM/eib_quickstart/base-images/
mkdir -p $ELEM/eib_quickstart/elemental
curl $REGISURL -o $ELEM/eib_quickstart/elemental/elemental_config.yaml
cat << EOF > $ELEM/eib_quickstart/eib-config.yaml
apiVersion: 1.2
image:
    imageType: iso
    arch: x86_64
    baseImage: SL-Micro.x86_64-6.1-Base-SelfInstall-GM.install.iso
    outputImageName: elemental-image.iso
operatingSystem:
  time:
    timezone: Europe/London
    ntp:
      forceWait: true
      pools:
        - 2.suse.pool.ntp.org
      servers:
        - 10.0.0.1
        - 10.0.0.2
  isoConfiguration:
    installDevice: /dev/vda
  users:
    - username: root
      encryptedPassword: \$6\$jHugJNNd3HElGsUZ\$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
  packages:
    sccRegistrationCode: XXX
EOF
Nota
Nota
  • La sección time es opcional, pero se recomienda encarecidamente configurarla para evitar posibles problemas con los certificados y la desviación del reloj. Los valores proporcionados en este ejemplo son solo ilustrativos. Ajústelos según sus requisitos específicos.

  • La contraseña sin cifrar es eib.

  • Se necesita el código sccRegistrationCode para descargar e instalar los paquetes RPM necesarios de las fuentes oficiales (alternativamente, los RPM elemental-register y elemental-system-agent se pueden cargar de forma manual y local).

  • El comando cat escapa cada $ con una barra invertida (\) para que Bash no las utilice como plantilla. Elimine las barras invertidas si va a realizar una copia manualmente.

  • El dispositivo de instalación se borrará durante la instalación.

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

Si está arrancando un dispositivo físico, es necesario grabar la imagen en una unidad flash USB. Puede hacerlo con:

sudo dd if=/eib_quickstart/elemental-image.iso of=/dev/<PATH_TO_DISK_DEVICE> status=progress

2.8 Arranque de los nodos descendentes

Ahora que se ha creado el medio de instalación, se pueden arrancar los nodos descendentes con él.

Para cada sistema que desee controlar con Elemental, añada el medio de instalación y arranque el dispositivo. Tras la instalación, se reiniciará y se registrará automáticamente.

Si utiliza la extensión de la interfaz de usuario, debería ver su nodo aparecer en "Inventory of Machines" (Inventario de equipos).

Nota
Nota

No retire el medio de instalación hasta que haya visto el mensaje de inicio de sesión; durante el primer arranque, se sigue accediendo a los archivos desde la memoria USB.

2.9 Creación de clústeres descendentes

Para aprovisionar un clúster nuevo con Elemental, debe crear dos objetos.

  • Linux
  • Extensión de interfaz de usuario

El primero es MachineInventorySelectorTemplate. Este objeto permite especificar una asignación entre los clústeres y los equipos del inventario.

  1. Cree un selector que coincida con cualquier equipo del inventario con una etiqueta:

    cat << EOF > $ELEM/selector.yaml
    apiVersion: elemental.cattle.io/v1beta1
    kind: MachineInventorySelectorTemplate
    metadata:
      name: location-123-selector
      namespace: fleet-default
    spec:
      template:
        spec:
          selector:
            matchLabels:
              locationID: '123'
    EOF
  2. Aplique el recurso al clúster:

    kubectl apply -f $ELEM/selector.yaml
  3. Obtenga el nombre del equipo máquina y añada la etiqueta correspondiente:

    MACHINENAME=$(kubectl get MachineInventory -n fleet-default | awk 'NR>1 {print $1}')
    
    kubectl label MachineInventory -n fleet-default \
     $MACHINENAME locationID=123
  4. Cree un recurso de clúster K3s simple de un solo nodo y aplíquelo al clúster:

    cat << EOF > $ELEM/cluster.yaml
    apiVersion: provisioning.cattle.io/v1
    kind: Cluster
    metadata:
      name: location-123
      namespace: fleet-default
    spec:
      kubernetesVersion: v1.32.4+k3s1
      rkeConfig:
        machinePools:
          - name: pool1
            quantity: 1
            etcdRole: true
            controlPlaneRole: true
            workerRole: true
            machineConfigRef:
              kind: MachineInventorySelectorTemplate
              name: location-123-selector
              apiVersion: elemental.cattle.io/v1beta1
    EOF
    
    kubectl apply -f $ELEM/cluster.yaml

Después de crear estos objetos, debería ver cómo se inicia un nuevo clúster de Kubernetes que usa el nuevo nodo que acaba de instalar.

2.10 Restablecimiento del nodo (opcional)

SUSE Rancher Elemental permite realizar un "restablecimiento de nodo", que se puede activar opcionalmente cuando se elimina todo un clúster de Rancher o un solo nodo de un clúster, o cuando se elimina manualmente un nodo del inventario de equipos. Esto resulta útil cuando se desean restablecer y limpiar los recursos huérfanos y se quiere volver a incorporar automáticamente el nodo limpiado al inventario de equipos para que pueda reutilizarse. Esta función no está habilitada de forma predeterminada, por lo que no se limpiará cualquier sistema que se elimine (es decir, los datos no se eliminarán y los recursos del clúster de Kubernetes seguirán funcionando en los clústeres descendentes) y será necesaria una intervención manual para borrar los datos y volver a registrar el equipo en Rancher a través de Elemental.

Si desea que esta funcionalidad esté habilitada de forma predeterminada, debe asegurarse de que esté explícitamente habilitada en MachineRegistration añadiendo config.elemental.reset.enabled: true, por ejemplo:

config:
  elemental:
    registration:
      auth: tpm
    reset:
      enabled: true

A continuación, todos los sistemas registrados con este registro MachineRegistration recibirán automáticamente la anotación elemental.cattle.io/resettable: “true” en su configuración. Si desea hacerlo manualmente en nodos individuales, por ejemplo, porque tiene un MachineInventory que no tiene esa anotación o porque ya ha desplegado nodos, puede modificar MachineInventory y añadir la configuración resettable. Por ejemplo:

apiVersion: elemental.cattle.io/v1beta1
kind: MachineInventory
metadata:
  annotations:
    elemental.cattle.io/os.unmanaged: 'true'
    elemental.cattle.io/resettable: 'true'

En SUSE Edge 3.1, el operador de Elemental coloca un marcador en el sistema operativo que activará automáticamente el proceso de limpieza, detendrá todos los servicios de Kubernetes, eliminará todos los datos persistentes, desinstalará todos los servicios de Kubernetes, limpiará cualquier directorio restante de Kubernetes/Rancher y forzará un nuevo registro en Rancher a través de la configuración original de MachineRegistration de Elemental. Esto ocurre automáticamente, sin necesidad de intervención manual. El guion que se ejecuta se encuentra en /opt/edge/elemental_node_cleanup.sh y se activa a través de systemd.path al colocar el marcador, por lo que su ejecución es inmediata.

Aviso
Aviso

El uso de la función resettable presupone que el comportamiento deseado al eliminar un nodo/clúster de Rancher es borrar los datos y forzar un nuevo registro. En esta situación, la pérdida de datos está garantizada, por lo que solo debe utilizarla si está seguro de que desea que se realice un restablecimiento automático.

2.11 Pasos siguientes

Se recomienda estudiar los siguientes recursos después de utilizar esta guía:

3 Clústeres independientes con Edge Image Builder

Edge Image Builder (EIB) es una herramienta que agiliza el proceso de generación de imágenes de disco personalizadas y listas para arrancar (CRB) para equipos de arranque, incluso en entornos totalmente aislados. EIB se utiliza para crear imágenes de despliegue para su uso en las tres huellas de despliegue de SUSE Edge, ya que es lo suficientemente flexible como para ofrecer las personalizaciones más pequeñas, como añadir un usuario o configurar la zona horaria, a través de una imagen configurada de forma integral que establece, por ejemplo, configuraciones de red complejas, despliega clústeres de Kubernetes de varios nodos, despliega cargas de trabajo de clientes y se registra en la plataforma de gestión centralizada a través de Rancher/Elemental y SUSE Multi-Linux Manager. EIB se ejecuta como una imagen de contenedor, lo que lo hace increíblemente portátil entre plataformas y garantiza que todas las dependencias necesarias sean autónomas, con un impacto mínimo en los paquetes instalados del sistema que se utiliza para operar la herramienta.

Nota
Nota

En escenarios de varios nodos, EIB despliega automáticamente MetalLB y Endpoint Copier Operator para que los hosts aprovisionados con la misma imagen compilada se unan automáticamente a un clúster de Kubernetes.

Para obtener más información, lea la introducción de Edge Image Builder (Capítulo 11, Edge Image Builder).

Aviso
Aviso

Edge Image Builder 1.2.1 admite la personalización de imágenes de SUSE Linux Micro 6.1. En versiones anteriores, como SUSE Linux Enterprise Micro 5.5 o 6.0, no se admite.

3.1 Requisitos previos

Nota
Nota

Para fines no relacionados con la producción, se puede utilizar openSUSE Leap 15.6 u openSUSE Tumbleweed como equipo host de creación. Otros sistemas operativos pueden funcionar, siempre que se disponga de un entorno de ejecución de contenedores compatible.

3.1.1 Obtención de la imagen de EIB

La imagen del contenedor de EIB está disponible públicamente y se puede descargar desde el registro de SUSE Edge ejecutando el siguiente comando en el host de creación de imágenes:

podman pull registry.suse.com/edge/3.3/edge-image-builder:1.2.1

3.2 Creación del directorio de configuración de imágenes

Dado que EIB se ejecuta dentro de un contenedor, es necesario montar un directorio de configuración desde el host, lo que le permite especificar la configuración deseada. Así, durante el proceso de creación, EIB tiene acceso a cualquier archivo de entrada y artefactos de apoyo necesarios. Este directorio debe tener una estructura específica. Vamos a crearlo suponiendo que este directorio existirá en su directorio de inicio y se llamará "eib":

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

En el paso anterior creamos el directorio "base-images" donde se alojará la imagen de entrada de SUSE Linux Micro 6.1. Ahora, nos aseguraremos de que la imagen se copie en el directorio de configuración:

cp /path/to/SL-Micro.x86_64-6.1-Base-SelfInstall-GM.install.iso $CONFIG_DIR/base-images/slemicro.iso
Nota
Nota

Durante la ejecución de EIB, la imagen base original no se modifica; se crea una nueva versión personalizada con la configuración deseada en la raíz del directorio de configuración de EIB.

El directorio de configuración en este momento debería tener el siguiente aspecto:

└── base-images/
    └── slemicro.iso

3.3 Creación del archivo de definición de imagen

El archivo de definición describe la mayoría de las opciones configurables que admite Edge Image Builder. Encontrará un ejemplo completo de las opciones aquí. Le recomendamos que consulte la guía original sobre creación de imágenes para ver ejemplos más completos que los que se muestran a continuación. Comencemos con un archivo de definición muy básico para nuestra imagen del sistema operativo:

cat << EOF > $CONFIG_DIR/iso-definition.yaml
apiVersion: 1.2
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
EOF

Esta definición especifica que estamos generando una imagen de salida para un sistema basado en AMD64/Intel 64. Para modificaciones posteriores, se utilizará como base una imagen iso denominada slemicro.iso, que se espera que se encuentre en $CONFIG_DIR/base-images/slemicro.iso. También indica que, una vez que EIB haya terminado de modificarla, la imagen de salida se llamará eib-image.iso y, por defecto, se ubicará en $CONFIG_DIR.

Ahora, nuestra estructura de directorio debe tener este aspecto:

├── iso-definition.yaml
└── base-images/
    └── slemicro.iso

En las siguientes secciones veremos algunos ejemplos de operaciones comunes:

3.3.1 Configuración de usuarios del sistema operativo

EIB permite preconfigurar la información de inicio de sesión de los usuarios, como las contraseñas o las claves SSH, incluyendo la configuración de una contraseña raíz fija. Como parte de este ejemplo, vamos a fijar la contraseña raíz, y el primer paso es utilizar OpenSSL para crear una contraseña cifrada unidireccional:

openssl passwd -6 SecurePassword

Se obtendrá un resultado similar a:

$6$G392FCbxVgnLaFw1$Ujt00mdpJ3tDHxEg1snBU3GjujQf6f8kvopu7jiCBIhRbRvMmKUqwcmXAKggaSSKeUUOEtCP3ZUoZQY7zTXnC1

A continuación, podemos añadir una sección en el archivo de definición llamada operatingSystem con una matriz users en su interior. El archivo resultante debería tener el siguiente aspecto:

apiVersion: 1.2
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$G392FCbxVgnLaFw1$Ujt00mdpJ3tDHxEg1snBU3GjujQf6f8kvopu7jiCBIhRbRvMmKUqwcmXAKggaSSKeUUOEtCP3ZUoZQY7zTXnC1
Nota
Nota

También es posible añadir usuarios adicionales, crear los directorios de inicio, establecer identificadores de usuario, añadir autenticación mediante claves SSH y modificar la información de los grupos. Consulte la guía original sobre creación de imágenes para ver más ejemplos.

3.3.2 Configuración de la hora del sistema operativo

La sección time es opcional, pero se recomienda encarecidamente configurarla para evitar posibles problemas con los certificados y la desviación del reloj. EIB configurará chronyd y /etc/localtime en función de los parámetros aquí indicados.

operatingSystem:
  time:
    timezone: Europe/London
    ntp:
      forceWait: true
      pools:
        - 2.suse.pool.ntp.org
      servers:
        - 10.0.0.1
        - 10.0.0.2
  • timezone: especifica la zona horaria en el formato "Región/Localidad" (por ejemplo, "Europa/Madrid"). Para ver la lista completa, ejecute timedatectl list-timezones en un sistema Linux.

  • ntp: define los atributos relacionados con la configuración de NTP (usando chronyd).

  • forceWait: solicita que chronyd intente sincronizar las fuentes de tiempo antes de iniciar otros servicios, con un tiempo de espera de 180 segundos.

  • pools: especifica una lista de grupos que chronyd usará como fuentes de datos (utilizando iburst para mejorar el tiempo que tarda la sincronización inicial).

  • servers: especifica una lista de servidores que chronyd usará como fuentes de datos (utilizando iburst para mejorar el tiempo que tarda la sincronización inicial).

Nota
Nota

Los valores proporcionados en este ejemplo son solo ilustrativos. Ajústelos para que se adapten a sus necesidades específicas.

3.3.3 Adición de certificados

Los archivos de certificado con la extensión .pem o .crt almacenados en el directorio certificates se instalarán en el almacén de certificados del sistema del nodo:

.
├── definition.yaml
└── certificates
    ├── my-ca.pem
    └── my-ca.crt

Consulte la guía Securing Communication with TLS Certificate (Protección de las comunicaciones con un certificado TLS) para obtener más información.

3.3.4 Configuración de paquetes RPM

Una de las principales características de EIB es que proporciona un mecanismo para añadir paquetes de software adicionales a la imagen, de modo que, una vez completada la instalación, el sistema puede aprovechar los paquetes instalados de inmediato. EIB permite a los usuarios especificar lo siguiente:

  • Paquetes por su nombre dentro de una lista en la definición de imagen

  • Repositorios de red para buscar estos paquetes

  • Credenciales del Centro de servicios al cliente de SUSE (SCC) para buscar los paquetes mostrados en los repositorios oficiales de SUSE

  • Mediante un directorio $CONFIG_DIR/rpms, paquetes RPM personalizados y locales que no existen en los repositorios de red

  • Mediante el mismo directorio ($CONFIG_DIR/rpms/gpg-keys), claves GPG para habilitar la validación de paquetes de terceros

EIB ejecuta un proceso de resolución de paquetes en el momento de la creación de la imagen, tomando la imagen base como entrada, e intentará extraer e instalar todos los paquetes suministrados, ya sea especificados a través de la lista o proporcionados localmente. EIB descarga todos los paquetes, incluidas las dependencias, en un repositorio que existe dentro de la imagen de salida e indica al sistema que los instale durante el primer proceso de arranque. Realizar este proceso durante la creación de la imagen garantiza que los paquetes se instalarán correctamente durante el primer arranque en la plataforma deseada, por ejemplo, el nodo del perímetro. Esto también es útil en entornos en los que se desea integrar los paquetes adicionales en la imagen en lugar de descargarlos a través de la red durante el funcionamiento, por ejemplo, en entornos de red restringidos o aislados.

Como ejemplo de demostración simple, vamos a instalar el paquete RPM nvidia-container-toolkit que se encuentra en el repositorio NVIDIA de terceros:

  packages:
    packageList:
      - nvidia-container-toolkit
    additionalRepos:
      - url: https://nvidia.github.io/libnvidia-container/stable/rpm/x86_64

El archivo de definición resultante tiene el siguiente aspecto:

apiVersion: 1.2
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$G392FCbxVgnLaFw1$Ujt00mdpJ3tDHxEg1snBU3GjujQf6f8kvopu7jiCBIhRbRvMmKUqwcmXAKggaSSKeUUOEtCP3ZUoZQY7zTXnC1
  packages:
    packageList:
      - nvidia-container-toolkit
    additionalRepos:
      - url: https://nvidia.github.io/libnvidia-container/stable/rpm/x86_64

Este es un ejemplo sencillo. Si necesita uno más detallad, descargue la clave de firma del paquete NVIDIA antes de ejecutar la generación de la imagen:

$ mkdir -p $CONFIG_DIR/rpms/gpg-keys
$ curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey > $CONFIG_DIR/rpms/gpg-keys/nvidia.gpg
Aviso
Aviso

La adición de paquetes RPM adicionales mediante este método permite añadir componentes de terceros compatibles o paquetes proporcionados (y mantenidos) por el usuario. Este mecanismo no debe utilizarse para añadir paquetes que normalmente no serían compatibles con SUSE Linux Micro. Si se utiliza este mecanismo para añadir componentes de los repositorios de openSUSE (que no son compatibles), incluidos los de versiones más recientes o paquetes de servicio, es posible que se obtenga una configuración no compatible, especialmente si al resolver las dependencias se sustituyen partes fundamentales del sistema operativo, aunque el sistema resultante parezca funcionar según lo esperado. Si no está seguro, póngase en contacto con su representante de SUSE para que le ayude a determinar la compatibilidad de la configuración que desea.

Nota
Nota

Encontrará una guía más completa con ejemplos adicionales en la guía original sobre instalación de paquetes.

3.3.5 Configuración del clúster de Kubernetes y las cargas de trabajo de los usuarios

Otra característica de EIB es la posibilidad de utilizarlo para automatizar el despliegue de clústeres de Kubernetes de alta disponibilidad, tanto de un solo nodo como de varios nodos, que se "arrancan en el lugar" (es decir, que no requieren infraestructura de gestión centralizada para coordinarse). Este enfoque está pensado principalmente para despliegues en entornos aislados o con restricciones de red, pero también sirve como una forma de arrancar rápidamente clústeres independientes, incluso si se dispone de acceso completo y sin restricciones a la red.

Este método no solo permite el despliegue del sistema operativo personalizado, sino también la posibilidad de especificar la configuración de Kubernetes, cualquier componente adicional en capas a través de charts de Helm y cualquier carga de trabajo del usuario a través de los manifiestos de Kubernetes proporcionados. Sin embargo, el principio de diseño detrás del uso de este método es que asumimos por defecto que el usuario desea usar un entorno aislado y, por lo tanto, cualquier elemento especificado en la definición de la imagen se incorporará a la imagen y a las cargas de trabajo proporcionadas por el usuario. EIB se asegurará de que cualquier imagen descubierta que sea requerida por las definiciones proporcionadas se copie localmente y que el registro de imágenes integrado las proporcione al sistema desplegado resultante.

En el siguiente ejemplo, vamos a utilizar nuestra definición de imagen existente y especificaremos una configuración de Kubernetes (no se muestra una lista de los sistemas y sus funciones, por lo que entenderemos por defecto que se trata de un solo nodo). Se indicará a EIB que aprovisione un clúster RKE2 Kubernetes de un solo nodo. Para mostrar la automatización tanto del despliegue de las cargas de trabajo proporcionadas por el usuario (a través del manifiesto) como de los componentes en capas (a través de Helm), vamos a instalar KubeVirt a través del chart de Helm de SUSE Edge, así como NGINX a través de un manifiesto de Kubernetes. La configuración adicional que debemos añadir a la definición de imagen existente es la siguiente:

kubernetes:
  version: v1.32.4+rke2r1
  manifests:
    urls:
      - https://k8s.io/examples/application/nginx-app.yaml
  helm:
    charts:
      - name: kubevirt
        version: 303.0.0+up0.5.0
        repositoryName: suse-edge
    repositories:
      - name: suse-edge
        url: oci://registry.suse.com/edge/charts

El archivo de definición completo resultante debería tener ahora este aspecto:

apiVersion: 1.2
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$G392FCbxVgnLaFw1$Ujt00mdpJ3tDHxEg1snBU3GjujQf6f8kvopu7jiCBIhRbRvMmKUqwcmXAKggaSSKeUUOEtCP3ZUoZQY7zTXnC1
  packages:
    packageList:
      - nvidia-container-toolkit
    additionalRepos:
      - url: https://nvidia.github.io/libnvidia-container/stable/rpm/x86_64
kubernetes:
  version: v1.32.4+k3s1
  manifests:
    urls:
      - https://k8s.io/examples/application/nginx-app.yaml
  helm:
    charts:
      - name: kubevirt
        version: 303.0.0+up0.5.0
        repositoryName: suse-edge
    repositories:
      - name: suse-edge
        url: oci://registry.suse.com/edge/charts
Nota
Nota

Encontrará más ejemplos como despliegues de varios nodos, redes personalizadas y opciones/valores de chart de Helm en la documentación original.

3.3.6 Configuración de la red

En el último ejemplo de esta guía rápida, vamos a configurar la red que se activará cuando se aprovisione un sistema con la imagen generada por EIB. Es importante comprender que, a menos que se proporcione una configuración de red, el modelo predeterminado es que se utilizará DHCP en todas las interfaces detectadas en el momento del arranque. Sin embargo, no siempre se trata de la configuración deseable, especialmente si DHCP no está disponible y es necesario proporcionar configuraciones estáticas, o si es necesario configurar estructuras de red más complejas (por ejemplo, enlaces, LACP y VLAN) o si hay que anular ciertos parámetros (por ejemplo, nombres de host, servidores DNS y rutas).

EIB ofrece la posibilidad de proporcionar configuraciones por nodo (donde el sistema en cuestión se identifica de forma única por su dirección MAC) o de sustituir la existente y proporcionar una configuración idéntica a cada equipo, lo que resulta más útil cuando se desconocen las direcciones MAC del sistema. EIB utiliza una herramienta adicional llamada Network Manager Configurator, o nmc para abreviar, que es una herramienta creada por el equipo de SUSE Edge para permitir la aplicación de configuraciones de red personalizadas basadas en el esquema de red declarativo nmstate.io, y que en el momento del arranque identificará el nodo en el que se está iniciando y aplicará la configuración de red deseada antes de que se inicien los servicios.

Ahora aplicaremos una configuración de red estática para un sistema con una única interfaz describiendo el estado de red deseado en un archivo específico del nodo (basado en el nombre de host deseado) en el directorio network requerido:

mkdir $CONFIG_DIR/network

cat << EOF > $CONFIG_DIR/network/host1.local.yaml
routes:
  config:
  - destination: 0.0.0.0/0
    metric: 100
    next-hop-address: 192.168.122.1
    next-hop-interface: eth0
    table-id: 254
  - destination: 192.168.122.0/24
    metric: 100
    next-hop-address:
    next-hop-interface: eth0
    table-id: 254
dns-resolver:
  config:
    server:
    - 192.168.122.1
    - 8.8.8.8
interfaces:
- name: eth0
  type: ethernet
  state: up
  mac-address: 34:8A:B1:4B:16:E7
  ipv4:
    address:
    - ip: 192.168.122.50
      prefix-length: 24
    dhcp: false
    enabled: true
  ipv6:
    enabled: false
EOF
Aviso
Aviso

El ejemplo anterior está configurado para la subred predeterminada 192.168.122.0/24, suponiendo que la prueba se ejecuta en una máquina virtual. Adáptelo a su entorno, sin olvidar la dirección MAC. Dado que se puede utilizar la misma imagen para aprovisionar varios nodos, la configuración de red realizada por EIB (a través de nmc) depende de que pueda identificar de forma única el nodo por su dirección MAC y, por lo tanto, durante el arranque, nmc aplicará la configuración de red correcta a cada equipo. Esto significa que deberá conocer las direcciones MAC de los sistemas en los que desea realizar la instalación. Alternativamente, el comportamiento predeterminado es confiar en DHCP, pero puede utilizar el gancho configure-network.sh para aplicar una configuración común a todos los nodos. Consulte la guía sobre conexión de redes (Capítulo 12, Conexiones de red de Edge) para obtener más detalles.

La estructura de archivo resultante tendrá este aspecto:

├── iso-definition.yaml
├── base-images/
│   └── slemicro.iso
└── network/
    └── host1.local.yaml

La configuración de red que acabamos de crear se analizará y los archivos de conexión de NetworkManager necesarios se generarán automáticamente y se insertarán en la nueva imagen de instalación que creará EIB. Estos archivos se aplicarán durante el aprovisionamiento del host, lo que dará como resultado una configuración de red completa.

Nota
Nota

Consulte la sección sobre el componente de red de Edge (Capítulo 12, Conexiones de red de Edge) para obtener una explicación más completa de la configuración anterior y ejemplos de esta función.

3.4 Creación de la imagen

Ahora que tenemos una imagen base y una definición de imagen para que EIB la utilice, vamos a crear la imagen. Para ello, solo tenemos que usar Podman para llamar al contenedor EIB con el comando "build", especificando el archivo de definición:

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

El resultado del comando debe tener este aspecto:

Setting up Podman API listener...
Downloading file: dl-manifest-1.yaml 100% (498/498 B, 9.5 MB/s)
Pulling selected Helm charts... 100% (1/1, 43 it/min)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Resolving package dependencies...
Rpm .......................... [SUCCESS]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% (3/3, 10 it/min)
Embedded Artifact Registry ... [SUCCESS]
Keymap ....................... [SUCCESS]
Configuring Kubernetes component...
The Kubernetes CNI is not explicitly set, defaulting to 'cilium'.
Downloading file: rke2_installer.sh
Downloading file: rke2-images-core.linux-amd64.tar.zst 100% (657/657 MB, 48 MB/s)
Downloading file: rke2-images-cilium.linux-amd64.tar.zst 100% (368/368 MB, 48 MB/s)
Downloading file: rke2.linux-amd64.tar.gz 100% (35/35 MB, 50 MB/s)
Downloading file: sha256sum-amd64.txt 100% (4.3/4.3 kB, 6.2 MB/s)
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso

La imagen ISO creada se guarda en $CONFIG_DIR/eib-image.iso:

├── iso-definition.yaml
├── eib-image.iso
├── _build
│   └── cache/
│       └── ...
│   └── build-<timestamp>/
│       └── ...
├── base-images/
│   └── slemicro.iso
└── network/
    └── host1.local.yaml

Para cada imagen se crea una carpeta con marca de tiempo en $CONFIG_DIR/_build/ que incluye los registros del proceso de creación, los artefactos utilizados durante la creación y los directorios combustion y artefacts, que contienen todos los guiones y artefactos que se añaden a la imagen lista para arrancar.

El contenido de este directorio tendrá este aspecto:

├── build-<timestamp>/
│   │── combustion/
│   │   ├── 05-configure-network.sh
│   │   ├── 10-rpm-install.sh
│   │   ├── 12-keymap-setup.sh
│   │   ├── 13b-add-users.sh
│   │   ├── 20-k8s-install.sh
│   │   ├── 26-embedded-registry.sh
│   │   ├── 48-message.sh
│   │   ├── network/
│   │   │   ├── host1.local/
│   │   │   │   └── eth0.nmconnection
│   │   │   └── host_config.yaml
│   │   ├── nmc
│   │   └── script
│   │── artefacts/
│   │   │── registry/
│   │   │   ├── hauler
│   │   │   ├── nginx:<version>-registry.tar.zst
│   │   │   ├── rancher_kubectl:<version>-registry.tar.zst
│   │   │   └── registry.suse.com_suse_sles_15.6_virt-operator:<version>-registry.tar.zst
│   │   │── rpms/
│   │   │   └── rpm-repo
│   │   │       ├── addrepo0
│   │   │       │   ├── nvidia-container-toolkit-<version>.rpm
│   │   │       │   ├── nvidia-container-toolkit-base-<version>.rpm
│   │   │       │   ├── libnvidia-container1-<version>.rpm
│   │   │       │   └── libnvidia-container-tools-<version>.rpm
│   │   │       ├── repodata
│   │   │       │   ├── ...
│   │   │       └── zypper-success
│   │   └── kubernetes/
│   │       ├── rke2_installer.sh
│   │       ├── registries.yaml
│   │       ├── server.yaml
│   │       ├── images/
│   │       │   ├── rke2-images-cilium.linux-amd64.tar.zst
│   │       │   └── rke2-images-core.linux-amd64.tar.zst
│   │       ├── install/
│   │       │   ├── rke2.linux-amd64.tar.gz
│   │       │   └── sha256sum-amd64.txt
│   │       └── manifests/
│   │           ├── dl-manifest-1.yaml
│   │           └── kubevirt.yaml
│   ├── createrepo.log
│   ├── eib-build.log
│   ├── embedded-registry.log
│   ├── helm
│   │   └── kubevirt
│   │       └── kubevirt-0.4.0.tgz
│   ├── helm-pull.log
│   ├── helm-template.log
│   ├── iso-build.log
│   ├── iso-build.sh
│   ├── iso-extract
│   │   └── ...
│   ├── iso-extract.log
│   ├── iso-extract.sh
│   ├── modify-raw-image.sh
│   ├── network-config.log
│   ├── podman-image-build.log
│   ├── podman-system-service.log
│   ├── prepare-resolver-base-tarball-image.log
│   ├── prepare-resolver-base-tarball-image.sh
│   ├── raw-build.log
│   ├── raw-extract
│   │   └── ...
│   └── resolver-image-build
│       └──...
└── cache
    └── ...

Si la compilación falla, eib-build.log es el primer registro que contiene información. Desde allí, se le dirigirá al componente que falló para su depuración.

En este punto, debe tener una imagen lista para usar que:

  1. Desplegará SUSE Linux Micro 6.1

  2. Configurará la contraseña raíz

  3. Instalará el paquete nvidia-container-toolkit

  4. Configurará un registro de contenedor integrado para proporcionar contenido localmente

  5. Instalará RKE2 de un solo nodo

  6. Configurará la red estática

  7. Instalará KubeVirt

  8. Desplegará un manifiesto proporcionado por el usuario

3.5 Depuración del proceso de creación de imágenes

Si el proceso de creación de imágenes falla, consulte la guía original sobre depuración.

3.6 Prueba de la imagen recién creada

Para obtener instrucciones sobre cómo probar la imagen lista para arrancar recién creada, consulte la guía original sobre pruebas de imágenes.

4 SUSE Multi-Linux Manager

SUSE Multi-Linux Manager está incluido en SUSE Edge y proporciona automatización y control con el fin de mantener el sistema operativo subyacente SUSE Linux Micro constantemente actualizado en todos los nodos de su despliegue periférico.

Esta guía de inicio rápido tiene como objetivo familiarizarle con SUSE Multi-Linux Manager lo antes posible, con el fin de proporcionar actualizaciones del sistema operativo a sus nodos periféricos. No aborda temas como el dimensionamiento del almacenamiento, la creación y gestión de canales de software adicionales con fines de preparación, ni la gestión de usuarios, grupos de sistemas y organizaciones para despliegues de mayor envergadura. Para su uso en producción, le recomendamos encarecidamente que se familiarice con la completa documentación de SUSE Multi-Linux Manager.

Para preparar SUSE Edge a fin de que SUSE Multi-Linux Manager se use de forma eficaz, es necesario seguir los siguientes pasos:

  • Desplegar y configurar SUSE Multi-Linux Manager Server

  • Sincronizar los repositorios de paquetes de SUSE Linux Micro

  • Crear grupos de sistemas

  • Crear claves de activación

  • Usar Edge Image Builder para preparar el medio de instalación para el registro de SUSE Multi-Linux Manager

4.1 Despliegue de SUSE Multi-Linux Manager Server

Si ya tiene una instancia de la última versión de SUSE Multi-Linux Manager 5.0 en ejecución, puede omitir este paso.

Puede ejecutar SUSE Multi-Linux Manager Server en un servidor físico dedicado, como máquina virtual en su propio hardware, o en la nube. Se proporcionan imágenes de máquinas virtuales preconfiguradas para SUSE Multi-Linux Server para las nubes públicas compatibles.

En esta guía de inicio rápido se utiliza la imagen "qcow2" SUSE-Manager-Server.x86_64-5.0.2-Qcow-2024.12.qcow2 para AMD64/Intel 64. La puede encontrar en https://www.suse.com/download/suse-manager/ o en el Centro de servicios al cliente de SUSE. Esta imagen funciona como una máquina virtual en hipervisores como KVM. Compruebe siempre que dispone de la versión más reciente de la imagen y utilícela para las nuevas instalaciones.

También puede instalar SUSE Multi-Linux Manager Server en cualquier otra arquitectura de hardware compatible. En tal caso, elija la imagen que coincida con su arquitectura de hardware.

Una vez que haya descargado la imagen, cree una máquina virtual que cumpla, como mínimo, con las siguientes especificaciones de hardware:

  • 16 GB de RAM

  • 4 núcleos físicos o virtuales

  • Un dispositivo de bloque adicional con una capacidad mínima de 100 GB

Con la imagen qcow2, no es necesario instalar el sistema operativo. Puede conectar directamente la imagen como su partición raíz.

Debe configurar la red para que sus nodos periféricos puedan acceder posteriormente a SUSE Multi-Linux Manager Server con un nombre de host que contenga el nombre de dominio completo.

Cuando inicie SUSE Multi-Linux Manager por primera vez, deberá realizar algunas configuraciones iniciales:

  • Seleccionar la disposición del teclado

  • Aceptar el acuerdo de licencia

  • Seleccionar la zona horaria

  • Introducir la contraseña raíz del sistema operativo

Los pasos siguientes se deben realizar con permisos de usuario root:

Para el siguiente paso, necesitará dos códigos de registro, que encontrará en el Centro de servicios al cliente de SUSE:

  • Su código de registro para SLE Micro 5.5

  • Su código de registro para la extensión de SUSE Multi-Linux Manager

Registre SUSE Linux Micro:

transactional-update register -r <REGCODE> -e <your_email>

Registre SUSE Multi-Linux Manager:

transactional-update register -p SUSE-Manager-Server/5.0/x86_64 -r <REGCODE>

La cadena del producto depende de la arquitectura de su hardware. Por ejemplo, si utiliza SUSE Multi-Linux Manager en un sistema ARM de 64 bits, la cadena es "SUSE-Manager-Server/5.0/aarch64".

Rearranque.

Actualice el sistema:

transactional-update

A menos que no haya habido cambios, reinicie el sistema para aplicar las actualizaciones.

SUSE Multi-Linux Manager se proporciona a través de un contenedor gestionado por Podman. El comando mgradm se encarga de la instalación y la configuración.

Aviso
Aviso

Es muy importante que el nombre de host configurado en su instancia de SUSE Multi-Linux Manager Server tenga un nombre de dominio completo que los nodos periféricos que desea administrar puedan resolver correctamente en su red.

Antes de instalar y configurar el contenedor de SUSE Multi-Linux Manager Server, debe preparar el dispositivo de bloque adicional que ha añadido previamente. Para ello, debe conocer el nombre que la máquina virtual ha asignado al dispositivo. Por ejemplo, si el dispositivo de bloque es /dev/vdb, puede configurarlo para que se utilice con SUSE Multi-Linux Manager mediante el siguiente comando:

mgr-storage-server /dev/vdb

Despliegue SUSE Multi-Linux Manager:

mgradm install podman <FQDN>

Proporcione la contraseña para el certificado de CA. Esta contraseña debe ser diferente de sus contraseñas de inicio de sesión. Por lo general, no es necesario introducirla más adelante, pero debe anotarla.

Proporcione la contraseña para el usuario "admin". Se trata del usuario inicial para iniciar sesión en SUSE Multi-Linux Manager. Más adelante podrá crear usuarios adicionales con derechos completos o restringidos.

4.2 Configuración de SUSE Multi-Linux Manager

Una vez finalizado el despliegue, puede iniciar sesión en la interfaz de usuario web de SUSE Multi-Linux Manager utilizando el nombre de host que proporcionó anteriormente. El usuario inicial es "admin". Use la contraseña que proporcionó en el paso anterior.

Para el siguiente paso, necesitará las credenciales de su organización, que encontrará en la segunda subpestaña de la pestaña "Usuarios" de su organización en el Centro de servicios al cliente de SUSE. Con esas credenciales, SUSE Multi-Linux Manager puede sincronizar todos los productos a los que está suscrito.

Seleccione Admin › Setup Wizard (Admin > Asistente de configuración).

En la pestaña Organization Credentials (Credenciales de la organización) cree nuevas credenciales con sus datos de Username (Nombre de usuario) y Password (Contraseña) que encontró en el Centro de servicios al cliente de SUSE.

Diríjase a la pestaña siguiente, SUSE Products (Productos SUSE). Debe esperar hasta que finalice la primera sincronización de datos con el Centro de servicios al cliente de SUSE.

Cuando la lista se haya rellenado, utilice el filtro para mostrar solo "Micro 6". Marque la casilla de SUSE Linux Micro 6.1 para la arquitectura de hardware en la que se ejecutarán sus nodos periféricos (x86_64 o aarch64).

Haga clic en Add Products (Añadir productos). Esto añadirá el repositorio de paquetes principal ("canal") para SUSE Linux Micro y añadirá automáticamente el canal para las herramientas cliente de SUSE Manager como un subcanal.

Dependiendo de su conexión a Internet, la primera sincronización tardará un poco. Ya puede empezar con los siguientes pasos:

En Systems > System Groups (Sistemas > Grupos de sistemas), cree al menos un grupo al que sus sistemas se unirán automáticamente cuando se incorporen. Los grupos son una forma importante de categorizar los sistemas, ya que permiten aplicar configuraciones o acciones a un conjunto completo de sistemas a la vez. Conceptualmente, son similares a las etiquetas de Kubernetes.

Haga clic en + Create Group (Crear grupo).

Proporcione un nombre corto, por ejemplo, "Nodos periféricos", y una descripción detallada.

En Systems > Activation Keys (Sistemas > Claves de activación), cree al menos una clave de activación. Las claves de activación pueden considerarse como un perfil de configuración que se aplica automáticamente a los sistemas cuando se incorporan a SUSE Multi-Linux Manager. Si desea que determinados nodos periféricos se añadan a diferentes grupos o usen una configuración diferente, puede crear claves de activación independientes para ellos y utilizarlas posteriormente en Edge Image Builder para crear medios de instalación personalizados.

Un caso de uso avanzado típico de las claves de activación sería asignar los clústeres de prueba a los canales de software con las últimas actualizaciones y los clústeres de producción a los canales de software que solo reciben esas últimas actualizaciones una vez que se han probado en el clúster de prueba.

Haga clic en + Create Key (Crear clave).

Elija una descripción corta, por ejemplo, "Nodos periféricos". Proporcione un nombre único que identifique la clave, por ejemplo, "edge-x86_64" para sus nodos periféricos con arquitectura de hardware AMD64/Intel 64. Se añade automáticamente un prefijo numérico a la clave. Para la organización predeterminada, el número es siempre "1". Si crea organizaciones adicionales en SUSE Multi-Linux Manager y crea claves para ellas, ese número puede ser diferente.

Si no ha creado ningún canal de software duplicado, puede conservar la configuración del canal base como "SUSE Manager Default" (Predeterminada de SUSE Manager). De este modo, se asignará automáticamente el repositorio de actualizaciones de SUSE adecuado para sus nodos periféricos.

Como "Child Channel" (Canal secundario), seleccione el control deslizante "Include recommended" (Incluir recomendados) para la arquitectura de hardware para la que se utiliza su clave de activación. Esto añadirá el canal "SUSE-Manager-Tools-For-SL-Micro-6.1".

En la pestaña "Groups" (Grupos), añada el grupo que ha creado anteriormente. Todos los nodos que se incorporen utilizando esta clave de activación se añadirán automáticamente a ese grupo.

4.3 Creación de una imagen de instalación personalizada con Edge Image Builder

Para usar Edge Image Builder, solo necesita un entorno en el que pueda iniciar un contenedor basado en Linux con Podman.

Para una configuración mínima del laboratorio, es posible usar la misma máquina virtual en la que se ejecuta SUSE Multi-Linux Manager Server. Asegúrese de que dispone de suficiente espacio en disco en la máquina virtual. Esta configuración no es recomendable en entornos de producción. Consulte la Sección 3.1, “Requisitos previos” para conocer los sistemas operativos host con los que hemos probado Edge Image Builder.

Inicie sesión en su host de SUSE Multi-Linux Manager Server como usuario root.

Extraiga el contenedor de Edge Image Builder:

podman pull registry.suse.com/edge/3.3/edge-image-builder:1.2.1

Cree el directorio /opt/eib y un subdirectorio base-images:

mkdir -p /opt/eib/base-images

En esta guía de inicio rápido se usa la versión "autoinstalable" de la imagen de SUSE Linux Micro. Esa imagen se puede grabar posteriormente en una unidad USB física y utilizarse para la instalación en servidores físicos. Si su servidor tiene la opción de conexión remota de imágenes ISO de instalación a través de un BMC (Baseboard Management Controller), también puede utilizar ese método. Por último, esa imagen también se puede utilizar con la mayoría de las herramientas de virtualización.

Si desea precargar la imagen directamente en un nodo físico o iniciarla directamente desde una máquina virtual, también puede utilizar el tipo de imagen "raw".

Encontrará esas imágenes en el Centro de servicios al cliente de SUSE o en https://www.suse.com/download/sle-micro/.

Descargue o copie la imagen SL-Micro.x86_64-6.1-Default-SelfInstall-GM.install.iso en el directorio base-images y asígnele el nombre "slemicro.iso".

La creación de imágenes AArch64 en un host de creación basado en ARM es una tecnología en fase preliminar en SUSE Edge 3.3.1. Es muy probable que funcione, pero aún no es compatible. Si desea probarlo, debe ejecutar Podman en un equipo ARM de 64 bits y sustituir "x86_64" por "aarch64" en todos los ejemplos y fragmentos de código.

En /opt/eib, cree un archivo llamado iso-definition.yaml. Esta es tu definición de creación para Edge Image Builder.

En este sencillo ejemplo se instala SL Micro 6.1, se establece una contraseña raíz y el mapa de teclas, se inicia la interfaz gráfica Cockpit y se registra el nodo en SUSE Multi-Linux Manager:

apiVersion: 1.0
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
  - username: root
    createHomeDir: true
    encryptedPassword: $6$aaBTHyqDRUMY1HAp$pmBY7.qLtoVlCGj32XR/Ogei4cngc3f4OX7fwBD/gw7HWyuNBOKYbBWnJ4pvrYwH2WUtJLKMbinVtBhMDHQIY0
  keymap: de
  systemd:
    enable:
      - cockpit.socket
  packages:
    noGPGCheck: true
  suma:
    host: ${fully qualified hostname of your SUSE Multi-Linux Manager Server}
    activationKey: 1-edge-x86_64

Edge Image Builder también puede configurar la red, instalar automáticamente Kubernetes en el nodo e, incluso, desplegar aplicaciones a través de charts de Helm. Consulte el Capítulo 3, Clústeres independientes con Edge Image Builder para obtener ejemplos más completos.

Para baseImage, especifique el nombre real de la ISO en el directorio base-images que desea utilizar.

En este ejemplo, la contraseña raíz sería "root". Consulte la Sección 3.3.1, “Configuración de usuarios del sistema operativo” para crear hashes para la contraseña segura que desea utilizar.

Defina el mapa de teclas de la disposición de teclado actual que desee que tenga el sistema después de la instalación.

Nota
Nota

Utilizamos la opción noGPGCheck: true porque no vamos a proporcionar una clave GPG para comprobar los paquetes RPM. En la guía original sobre instalación de paquetes encontrará instrucciones completas para realizar una configuración más segura, que se recomienda en entornos de producción.

Como se ha mencionado en varias ocasiones, el host de SUSE Multi-Linux Manager requiere un nombre de host completo que pueda resolverse en la red en la que se iniciarán los nodos periféricos.

El valor de activationKey debe coincidir con la clave que ha creado en SUSE Multi-Linux Manager.

Para crear una imagen de instalación que registre automáticamente sus nodos periféricos en SUSE Multi-Linux Manager después de la instalación, también debe preparar dos artefactos:

  • El paquete minion de Salt que instala el agente de gestión para SUSE Multi-Linux Manager

  • El certificado de CA de su instancia de SUSE Multi-Linux Manager Server

4.3.1 Descarga del paquete venv-salt-minion

En /opt/eib, cree un subdirectorio rpms.

Descargue el paquete venv-salt-minion desde su instancia de SUSE Multi-Linux Manager Server en ese directorio. Puede obtenerlo a través de la interfaz de usuario web buscando el paquete en Software > Channel List (Software > Lista de canales) y descargándolo desde el canal SUSE-Manager-Tools​, o bien descargarlo desde el repositorio de arranque de SUSE Multi-Linux Manager con una herramienta como curl:

curl -O http://${HOSTNAME_OF_SUSE_MANAGER}/pub/repositories/slmicro/6/1/bootstrap/x86_64/venv-salt-minion-3006.0-3.1.x86_64.rpm

El nombre real del paquete puede variar si ya se ha lanzado una versión más reciente. Si hay varios paquetes entre los que elegir, elija siempre el más reciente.

4.4 Descarga del certificado de CA de SUSE Multi-Linux Manager

En /opt/eib, cree un subdirectorio certificates.

Descargue el certificado de CA de SUSE Multi-Linux Manager en ese directorio:

curl -O http://${HOSTNAME_OF_SUSE_MANAGER}/pub/RHN-ORG-TRUSTED-SSL-CERT
Aviso
Aviso

Debe cambiar el nombre del certificado a RHN-ORG-TRUSTED-SSL-CERT.crt. Edge Image Builder se asegurará de que el certificado se instale y se active en el nodo periférico durante la instalación.

Ahora puede ejecutar Edge Image Builder:

cd /opt/eib
podman run --rm -it --privileged -v /opt/eib:/eib \
registry.suse.com/edge/3.3/edge-image-builder:1.2.1 \
build --definition-file iso-definition.yaml

Si ha usado un nombre diferente para su archivo de definición YAML o desea utilizar una versión diferente de Edge Image Builder, deberá adaptar el comando en consecuencia.

Una vez finalizada la creación, encontrará la imagen ISO de instalación en el directorio /opt/eib con el nombre eib-image.iso.

Parte II Componentes

Lista de componentes de Edge

  • 5 Rancher
  • Consulte la documentación de Rancher en https://ranchermanager.docs.rancher.com/v2.11.

  • 6 Extensiones de panel de control de Rancher
  • Las extensiones permiten a los usuarios, desarrolladores, partners y clientes ampliar y mejorar la interfaz de usuario de Rancher. SUSE Edge proporciona extensiones para los paneles de control KubeVirt y Akri.

  • 7 Rancher Turtles
  • Consulte la documentación de Rancher Turtles en https://documentation.suse.com/cloudnative/cluster-api/

  • 8 Fleet
  • Fleet es un motor de gestión y despliegue de contenedores diseñado para ofrecer a los usuarios un mayor control sobre el clúster local y una supervisión constante a través de GitOps. Fleet no solo se centra en la escalabilidad, sino que también proporciona a los usuarios un alto grado de control y v…

  • 9 SUSE Linux Micro
  • Consulte la documentación oficial de SUSE Linux Micro

  • 10 Metal3
  • Metal3 es un proyecto de la CNCF que proporciona capacidades de gestión de infraestructura bare metal para Kubernetes.

  • 11 Edge Image Builder
  • Consulte el repositorio oficial.

  • 12 Conexiones de red de Edge
  • En esta sección se describe el enfoque de la configuración de redes en la solución SUSE Edge. Se explica cómo configurar NetworkManager en SUSE Linux Micro de forma declarativa y cómo se integran las herramientas relacionadas.

  • 13 Elemental
  • Elemental es una pila de software que permite la gestión centralizada y completa del sistema operativo nativo en la nube con Kubernetes. La pila Elemental consta de varios componentes que residen en Rancher o en los nodos periféricos. Los componentes principales son:

  • 14 Akri
  • Akri es un proyecto experimental de la CNCF cuyo objetivo es detectar dispositivos periféricos para presentarlos como recursos nativos de Kubernetes. También permite programar un pod o un trabajo para cada dispositivo detectado. Los dispositivos pueden ser locales o estar conectados en red, y pueden…

  • 15 K3s
  • K3s es una distribución de Kubernetes certificada y de alta disponibilidad, diseñada para cargas de trabajo de producción en ubicaciones remotas sin supervisión y con recursos limitados, o dentro de dispositivos IoT.

  • 16 RKE2
  • Consulte la documentación oficial de RKE2.

  • 17 SUSE Storage
  • SUSE Storage es un sistema de almacenamiento en bloques distribuido ligero, fiable y fácil de usar diseñado para Kubernetes. Se trata de un producto basado en Longhorn, un proyecto de código abierto desarrollado inicialmente por Rancher Labs y actualmente incubado bajo la CNCF.

  • 18 SUSE Security
  • SUSE Security es una solución de seguridad para Kubernetes que proporciona seguridad de red L7, seguridad en el entorno de ejecución, seguridad en la cadena de suministro y comprobaciones de cumplimiento en un paquete cohesionado.

  • 19 MetalLB
  • Consulte la documentación oficial de MetalLB.

  • 20 Endpoint Copier Operator
  • Endpoint Copier Operator es un operador de Kubernetes cuyo objetivo es crear una copia de un servicio y un punto final de Kubernetes y mantenerlos sincronizados.

  • 21 Edge Virtualization
  • En esta sección se describe cómo se puede utilizar Edge Virtualization para ejecutar máquinas virtuales en los nodos periféricos. Edge Virtualization se hadiseñado para casos de uso de virtualización ligeros, en los que se espera que se utilice un flujo de trabajo común para el despliegue y la gesti…

  • 22 System Upgrade Controller
  • Consulte la documentación de System Upgrade Controller.

  • 23 Upgrade Controller
  • Upgrade Controller es un controlador de Kubernetes capaz de realizar actualizaciones en los siguientes componentes de la plataforma SUSE Edge:

  • 24 SUSE Multi-Linux Manager
  • SUSE Multi-Linux Manager está incluido en SUSE Edge y proporciona automatización y control con el fin de mantener el sistema operativo subyacente SUSE Linux Micro constantemente actualizado en todos los nodos de su despliegue periférico.

5 Rancher

Consulte la documentación de Rancher en https://ranchermanager.docs.rancher.com/v2.11.

Rancher es una potente plataforma de gestión de Kubernetes de código abierto que optimiza el despliegue, las operaciones y la supervisión de clústeres de Kubernetes en múltiples entornos. Tanto si gestiona clústeres en sus instalaciones, en la nube o en el perímetro, Rancher le ofrece una plataforma unificada y centralizada para todas sus necesidades de Kubernetes.

5.1 Funciones clave de Rancher

  • Gestión de varios clústeres: la interfaz intuitiva de Rancher permite gestionar clústeres de Kubernetes desde cualquier lugar: nubes públicas, centros de datos privados y ubicaciones periféricas.

  • Seguridad y conformidad: Rancher aplica políticas de seguridad, control de acceso basado en roles (RBAC) y estándares de cumplimiento en todo su entorno de Kubernetes.

  • Operaciones simplificadas del clúster: Rancher automatiza el aprovisionamiento, las actualizaciones y la resolución de problemas de los clústeres, lo que simplifica las operaciones de Kubernetes para equipos de todos los tamaños.

  • Catálogo de aplicaciones centralizado: el catálogo de aplicaciones de Rancher ofrece una amplia gama de charts de Helm y operadores de Kubernetes, lo que facilita el despliegue y gestión de aplicaciones en contenedores.

  • Entrega continua: Rancher es compatible con GitOps y los procesos de CI/CD, lo que permite automatizar y optimizar los procesos de entrega de aplicaciones.

5.2 Uso de Rancher en SUSE Edge

Rancher proporciona varias funcionalidades básicas a la pila de SUSE Edge:

5.2.1 Gestión centralizada de Kubernetes

En despliegues periféricos típicos con numerosos clústeres distribuidos, Rancher actúa como un plano de control central para gestionar estos clústeres de Kubernetes. Ofrece una interfaz unificada para el aprovisionamiento, la actualización, la supervisión y la resolución de problemas, lo que simplifica las operaciones y garantiza la coherencia.

5.2.2 Despliegue simplificado de clústeres

Rancher optimiza la creación de clústeres de Kubernetes en el sistema operativo ligero SUSE Linux Micro, lo que facilita el despliegue de infraestructura periférica con sólidas capacidades de Kubernetes.

5.2.3 Despliegue y gestión de aplicaciones

El catálogo integrado de aplicaciones de Rancher puede simplificar el despliegue y la gestión de aplicaciones en contenedores en clústeres de SUSE Edge, lo que permite un despliegue fluido de las cargas de trabajo en el perímetro.

5.2.4 Seguridad y aplicación de directivas

Rancher proporciona herramientas de gobernanza basadas en directivas, control de acceso basado en roles (RBAC) e integración con proveedores de autenticación externos. Esto ayuda a mantener la seguridad y el cumplimiento normativo en los despliegues de SUSE Edge, aspectos fundamentales en entornos distribuidos.

5.3 Prácticas recomendadas

5.3.1 GitOps

Rancher incluye Fleet como un componente integrado para permitir la gestión de configuraciones de clústeres y despliegues de aplicaciones con código almacenado en git.

5.3.2 Observabilidad

Rancher incluye herramientas integradas de supervisión y registro, como Prometheus y Grafana, que proporcionan información detallada sobre el estado y el rendimiento del clúster.

5.4 Instalación con Edge Image Builder

SUSE Edge usa Capítulo 11, Edge Image Builder para personalizar las imágenes del sistema operativo base SUSE Linux Micro. Siga las instrucciones de la Sección 27.6, “Instalación de Rancher” para realizar una instalación en un entorno aislado de Rancher sobre clústeres de Kubernetes aprovisionados por EIB.

5.5 Recursos adicionales

6 Extensiones de panel de control de Rancher

Las extensiones permiten a los usuarios, desarrolladores, partners y clientes ampliar y mejorar la interfaz de usuario de Rancher. SUSE Edge proporciona extensiones para los paneles de control KubeVirt y Akri.

Consulte la documentación de Rancher para obtener información general sobre las extensiones de panel de control de Rancher.

6.1 Instalación

Todos los componentes de SUSE Edge 3.3.1, incluidas las extensiones de panel de control, se despliegan como artefactos OCI. Para instalar extensiones de SUSE Edge, puede usar la interfaz del usuario del panel de control de Rancher, Helm o Fleet:

6.1.1 Instalación con la interfaz de usuario del panel de control de Rancher

  1. Haga clic en Extensions (Extensiones) en la sección Configuration (Configuración) de la barra lateral de navegación.

  2. En la página Extensions (Extensiones), haga clic en el menú de tres puntos de la parte superior derecha y seleccione Manage Repositories (Gestionar repositorios).

    Cada extensión se despliega mediante su propio artefacto OCI. Están disponibles en el repositorio de charts de Helm de SUSE Edge.

  3. En la página Repositories (Repositorios), haga clic en Create (Crear).

  4. En el formulario, especifique el nombre y la URL del repositorio y haga clic en Create (Crear).

    URL del repositorio de charts de Helm de SUSE Edge: oci://registry.suse.com/edge/charts

    repositorio de oci para crear extensiones de panel de control
  5. Puede comprobar que el repositorio de extensiones se ha añadido a la lista y se encuentra en estado Active (Activo).

    lista de repositorios de extensiones de panel de control
  6. Vuelva a Extensions (Extensiones) en la sección Configuration (Configuración) de la barra lateral de navegación.

    En la pestaña Available (Disponibles), consulte las extensiones disponibles para instalar.

    extensiones de panel de control disponibles
  7. En la tarjeta de la extensión, haga clic en Install y confirme el proceso.

    Una vez instalada la extensión, la interfaz de usuario de Rancher solicita que se vuelva a cargar la página, tal y como se describe en la página Installing Extensions Rancher (Instalación de extensiones de Rancher) de la documentación.

6.1.2 Instalación con Helm

# KubeVirt extension
helm install kubevirt-dashboard-extension oci://registry.suse.com/edge/charts/kubevirt-dashboard-extension --version 303.0.2+up1.3.2 --namespace cattle-ui-plugin-system

# Akri extension
helm install akri-dashboard-extension oci://registry.suse.com/edge/charts/akri-dashboard-extension --version 303.0.2+up1.3.1 --namespace cattle-ui-plugin-system
Nota
Nota

Las extensiones se deben instalar en el espacio de nombres cattle-ui-plugin-system.

Nota
Nota

Después de instalar una extensión, es necesario volver a cargar la interfaz de usuario del panel de control de Rancher.

6.1.3 Instalación con Fleet

Para instalar extensiones de panel de control con Fleet, es necesario definir un recurso gitRepo que apunte a un repositorio Git con archivos de configuración fleet.yaml de bundle personalizados.

# KubeVirt extension fleet.yaml
defaultNamespace: cattle-ui-plugin-system
helm:
  releaseName: kubevirt-dashboard-extension
  chart: oci://registry.suse.com/edge/charts/kubevirt-dashboard-extension
  version: "303.0.2+up1.3.2"
# Akri extension fleet.yaml
defaultNamespace: cattle-ui-plugin-system
helm:
  releaseName: akri-dashboard-extension
  chart: oci://registry.suse.com/edge/charts/akri-dashboard-extension
  version: "303.0.2+up1.3.1"
Nota
Nota

La propiedad releaseName es obligatoria y debe coincidir con el nombre de la extensión para que esta se instale correctamente.

cat <<- EOF | kubectl apply -f -
apiVersion: fleet.cattle.io/v1alpha1
metadata:
  name: edge-dashboard-extensions
  namespace: fleet-local
spec:
  repo: https://github.com/suse-edge/fleet-examples.git
  branch: main
  paths:
  - fleets/kubevirt-dashboard-extension/
  - fleets/akri-dashboard-extension/
EOF

Para obtener más información, consulte el Capítulo 8, Fleet y el repositorio fleet-examples.

Después de que se hayan instalado las extensiones, aparecen en la sección Extensions (Extensiones) de la pestaña Installled (Instaladas). Dado que no se instalan a través de Apps/Marketplace, se marcan con la etiqueta Third-Party (De terceros).

extensiones de panel de control instaladas

6.2 Extensión de panel de control KubeVirt

La extensión KubeVirt proporciona funciones básicas de gestión de máquinas virtuales para la interfaz de usuario del panel de control de Rancher. Sus capacidades se describen en la Sección 21.7.2, “Uso de la extensión de panel de control KubeVirt de Rancher”.

6.3 Extensión de panel de control Akri

Akri es una interfaz de recursos de Kubernetes que permite exponer fácilmente dispositivos periféricos heterogéneos (como cámaras IP y dispositivos USB) como recursos en un clúster de Kubernetes, al tiempo que admite la exposición de recursos de hardware integrados, como GPU y FPGA. Akri detecta continuamente los nodos que tienen acceso a estos dispositivos y programa las cargas de trabajo en función de ellos.

La extensión de panel de control Akri permite utilizar la interfaz de usuario del panel de control de Rancher para gestionar y supervisar dispositivos periféricos y ejecutar cargas de trabajo una vez que se han detectado dichos dispositivos.

Las capacidades de la extensión se describen en más detalle en la Sección 14.5, “Extensión de panel de control Akri de Rancher”.

7 Rancher Turtles

Consulte la documentación de Rancher Turtles en https://documentation.suse.com/cloudnative/cluster-api/

Rancher Turtles es un operador de Kubernetes que proporciona integración entre Rancher Manager y Cluster API (CAPI) con el objetivo de ofrecer compatibilidad total con CAPI a Rancher.

7.1 Funciones principales de Rancher Turtles

  • Importar automáticamente clústeres CAPI a Rancher instalando el agente Rancher Cluster Agent en clústeres aprovisionados por CAPI.

  • Instalar y configurar las dependencias del controlador CAPI a través de CAPI Operator.

7.2 Uso de Rancher Turtles en SUSE Edge

La pila de SUSE Edge proporciona un chart wrapper de Helm que instala Rancher Turtles con una configuración específica que habilita lo siguiente:

  • Los componentes de controlador esenciales de CAPI

  • Los componentes de proveedor de plano de control y arranque de RKE2

  • Los componentes de proveedor de infraestructura de Metal3 (Capítulo 10, Metal3)

Solo se admiten los proveedores predeterminados instalados a través del chart wrapper. Los proveedores alternativos de plano de control, arranque e infraestructura no son compatibles actualmente como parte de la pila de SUSE Edge.

7.3 Instalación de Rancher Turtles

Rancher Turtles se puede instalar siguiendo las instrucciones de la guía de inicio rápido de Metal3 (Capítulo 1, Despliegues automatizados de BMC con Metal3) o la documentación del clúster de gestión (Capítulo 40, Configuración del clúster de gestión).

7.4 Recursos adicionales

8 Fleet

Fleet es un motor de gestión y despliegue de contenedores diseñado para ofrecer a los usuarios un mayor control sobre el clúster local y una supervisión constante a través de GitOps. Fleet no solo se centra en la escalabilidad, sino que también proporciona a los usuarios un alto grado de control y visibilidad para supervisar exactamente lo que hay instalado en el clúster.

Fleet puede gestionar despliegues desde Git de YAML sin procesar de Kubernetes, charts de Helm, Kustomize o cualquier combinación de los tres sistemas. Independientemente de la fuente, todos los recursos se convierten dinámicamente en charts de Helm, y Helm se utiliza como motor para desplegar todos los recursos en el clúster. Como resultado, los usuarios disfrutan de un alto grado de control, coherencia y auditabilidad de sus clústeres.

Para obtener información sobre cómo funciona Fleet, consulte Fleet Architecture (Arquitectura de Fleet).

8.1 Instalación de Fleet con Helm

Fleet viene integrado en Rancher, pero también se puede instalar como una aplicación independiente en cualquier clúster de Kubernetes utilizando Helm.

8.2 Uso de Fleet con Rancher

Rancher usa Fleet para desplegar aplicaciones en clústeres gestionados. La entrega continua con Fleet introduce GitOps a gran escala, un sistema diseñado para gestionar aplicaciones que se ejecutan en un gran número de clústeres.

Fleet funciona de forma óptima como parte integrante de Rancher. En los clústeres gestionados con Rancher se despliega automáticamente el agente de Fleet como parte del proceso de instalación/importación, y el clúster queda inmediatamente disponible para ser gestionado por Fleet.

8.3 Acceso a Fleet en la interfaz de usuario de Rancher

Fleet viene preinstalado en Rancher y se gestiona con la opción Continuous Delivery (Entrega continua) en la interfaz de usuario de Rancher.

panel de control de fleet

La sección Continuous Delivery (Entrega continua) incluye estos elementos:

8.3.1 Dashboard (Panel de control)

Se trata de una vista general de todos los repositorios GitOps en todos los espacios de trabajo. Solo se muestran los espacios de trabajo con repositorios.

8.3.2 Git repos (Repositorios Git)

Muestra una lista de repositorios GitOps del espacio de trabajo seleccionado. Seleccione el espacio de trabajo activo en la lista desplegable de la parte superior de la página.

8.3.3 Clusters (Clústeres)

Muestra una lista de clústeres gestionados. De forma predeterminada, todos los clústeres gestionados por Rancher se añaden al espacio de trabajo fleet-default. El espacio de trabajo fleet-local incluye el clúster local (de gestión). Desde aquí, es posible usar las acciones Pause (Pausar) o Force update (Forzar la actualización) en los clústeres o mover el clúster a otro espacio de trabajo. Editar el clúster permite actualizar las etiquetas y anotaciones utilizadas para agrupar los clústeres.

8.3.4 Cluster groups (Grupos de clústeres)

Esta sección permite agrupar de forma personalizada los clústeres dentro del espacio de trabajo mediante selectores.

8.3.5 Advanced (Avanzado)

Esta sección permite gestionar los espacios de trabajo y otros recursos relacionados con Fleet.

8.4 Ejemplo de instalación de KubeVirt con Rancher y Fleet usando el panel de control de Rancher

  1. Cree un repositorio Git que contenga el archivo fleet.yaml:

    defaultNamespace: kubevirt
    helm:
      chart: "oci://registry.suse.com/edge/charts/kubevirt"
      version: "303.0.0+up0.5.0"
      # kubevirt namespace is created by kubevirt as well, we need to take ownership of it
      takeOwnership: true
  2. En el panel de control de Rancher, diríjase a ☰ > Continuous Delivery > Git Repos (☰ > Entrega continua > Repositorios Git) y haga clic en Add Repository (Añadir repositorio).

  3. El asistente para la creación de repositorios le guía a través del proceso de creación del repositorio Git. Proporcione el nombre (Name) y la URL del repositorio (Repository URL) que haga referencia al repositorio Git creado en el paso anterior, y seleccione la rama o revisión adecuada. En el caso de un repositorio más complejo, especifique las rutas (Paths) para utilizar varios directorios en un solo repositorio.

    creación de repositorio 1 con fleet
  4. Haga clic en Next (Siguiente).

  5. En el paso siguiente, puede definir dónde se desplegarán las cargas de trabajo. Existen varias opciones básicas para seleccionar clústeres: puede no seleccionar ningún clúster, seleccionarlos todos o elegir directamente un clúster gestionado específico o un grupo de clústeres (si se ha definido). La opción Advanced (Avanzado) permite editar directamente los selectores a través del archivo YAML.

    creación de repositorio 2 con fleet
  6. Haga clic en Create (Crear). Se crea el repositorio. A partir de ahora, las cargas de trabajo se instalan y se mantienen sincronizadas en los clústeres que coinciden con la definición del repositorio.

8.5 Depuración y solución de problemas

La sección "Advanced" (Avanzado) ofrece una visión general de los recursos de Fleet de nivel inferior. Un bundle es un recurso interno que se utiliza para la coordinación de recursos de Git. Cuando se analiza un repositorio Git, se generan uno o varios Bundles.

Para encontrar Bundles relevantes para un repositorio específico, vaya a la página de detalles del repositorio Git y haga clic en la pestaña Bundles.

Bundles en repositorios fleet

El bundle se aplica a un recurso BundleDeployment que se crea para cada clúster. Para ver los detalles de BundleDeployment, haga clic en el botón Graph (Gráfico) situado en la parte superior derecha de la página de detalles del repositorio Git. Se carga un gráfico de Repo > Bundles > BundleDeployments (Repositorio > Bundles > BundleDeployments). Haga clic en BundleDeployment en el gráfico para ver sus detalles y haga clic en Id para ver el YAML de BundleDeployment.

gráfico de repositorios de fleet

Para consejos sobre la resolución de problemas de Fleet, consulte este documento.

8.6 Ejemplos de Fleet

El equipo de Edge mantiene un repositorio con ejemplos de instalación de proyectos de Edge con Fleet.

El proyecto de Fleet incluye un repositorio fleet-examples que cubre todos los posibles casos de uso para la estructura de repositorios de Git.

9 SUSE Linux Micro

Consulte la documentación oficial de SUSE Linux Micro

SUSE Linux Micro es un sistema operativo ligero y seguro para el perímetro. Combina los componentes reforzados para empresas de SUSE Linux Enterprise con las características que los desarrolladores desean en un sistema operativo moderno e inmutable. Como resultado, se obtiene una plataforma de infraestructura fiable con el mejor cumplimiento normativo de su clase y que, además, es fácil de usar.

9.1 ¿Cómo se usa SUSE Linux Micro en SUSE Edge?

Utilizamos SUSE Linux Micro como sistema operativo base para nuestra plataforma. Proporciona una base segura, estable y mínima sobre la que construir.

El uso de instantáneas del sistema de archivos (Btrfs) para permitir reversiones sencillas en caso de que algo salga mal con una actualización es único en SUSE Linux Micro. Esto permite actualizaciones remotas seguras para toda la plataforma, incluso sin acceso físico en caso de que surjan problemas.

9.2 Prácticas recomendadas

9.2.1 Medios de instalación

SUSE Edge usa Edge Image Builder (Capítulo 11, Edge Image Builder) para preconfigurar la imagen de autoinstalación de SUSE Linux Micro.

9.2.2 Administración local

SUSE Linux Micro incluye Cockpit para la gestión local del host a través de una aplicación web.

Este servicio está desactivado de forma predeterminada, pero se puede iniciar habilitando el servicio cockpit.socket de systemd.

9.3 Problemas conocidos

  • Por el momento, SUSE Linux Micro no dispone de ningún entorno de escritorio, pero se está desarrollando una solución en contenedores.

10 Metal3

Metal3 es un proyecto de la CNCF que proporciona capacidades de gestión de infraestructura bare metal para Kubernetes.

Metal3 ofrece recursos nativos de Kubernetes para gestionar el ciclo de vida de los servidores bare metal que admiten la gestión a través de 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 de infraestructura mediante API ampliamente adoptadas y neutrales con respecto a los proveedores.

10.1 ¿Cómo se usa Metal3 en SUSE Edge?

Este método es útil para situaciones en las que el hardware de destino admite la gestión fuera de banda y se desea un flujo de gestión de la infraestructura totalmente automatizado.

Este método proporciona API declarativas que permiten la gestión del inventario y el estado de los servidores bare metal, incluyendo la inspección, la limpieza y el aprovisionamiento/desaprovisionamiento automatizados.

10.2 Problemas conocidos

  • Actualmente, no se admite el controlador de gestión de direcciones IP original, ya que aún no es compatible con las herramientas de configuración de red que hemos elegido.

  • Del mismo modo, tampoco se admiten los recursos IPAM ni los campos networkData Metal3DataTemplate.

  • Actualmente, solo se admite el despliegue mediante redfish-virtualmedia.

11 Edge Image Builder

Consulte el repositorio oficial.

Edge Image Builder (EIB) es una herramienta que optimiza la generación de imágenes de disco personalizadas y listas para arrancar (CRB) para equipos de arranque. Estas imágenes permiten el despliegue integral de toda la pila de software de SUSE con una sola imagen.

Si bien EIB puede crear imágenes listas para arrancar para cualquier escenario de aprovisionamiento, resulta especialmente útil en despliegues en entornos aislados (air-gapped) con redes limitadas o completamente aisladas.

11.1 ¿Cómo se usa Edge Image Builder en SUSE Edge?

SUSE Edge utiliza EIB para la configuración simplificada y rápida de imágenes de SUSE Linux Micro personalizadas en distintas situaciones. Por ejemplo, para el arranque de máquinas virtuales y bare metal con lo siguiente:

  • Despliegues de K3s/RKE2 de Kubernetes (de un solo nodo y de varios nodos) en entornos totalmente aislados

  • Despliegues de chart de Helm y de manifiestos de Kubernetes en entornos totalmente aislados

  • Registro en Rancher mediante la API de Elemental

  • Metal3

  • Configuración de red personalizada (por ejemplo, IP estática, nombre de host, VLAN, vinculación, etc.)

  • Configuraciones personalizadas del sistema operativo (por ejemplo, usuarios, grupos, contraseñas, claves SSH, proxies, NTP, certificados SSL personalizados, etc.)

  • Instalación en entornos aislados de paquetes RPM a nivel de host y locales (incluida la resolución de dependencias)

  • Registro en SUSE Multi-Linux Manager para la gestión del sistema operativo

  • Imágenes de contenedor integradas

  • Argumentos de línea de comando del kernel

  • Unidades de systemd que se deben habilitar/inhabilitar en el arranque

  • Guiones y archivos personalizados para cualquier tarea manual

11.2 Inicio

Encontrará la documentación completa sobre el uso y las pruebas de Edge Image Builder aquí.

Asimismo, en el Capítulo 3, Clústeres independientes con Edge Image Builder se explica un escenario básico de despliegue.

Cuando se haya familiarizado con esta herramienta, encontrará más información útil en la página de consejos y trucos.

11.3 Problemas conocidos

  • EIB crea plantillas de charts de Helm y analiza todas las imágenes de la plantilla para aislar los charts de Helm. Si un chart de Helm no tiene todas sus imágenes dentro de la plantilla y, en su lugar, carga las imágenes de forma local, EIB no podrá aislar esas imágenes automáticamente. La solución es añadir manualmente cualquier imagen no detectada a la sección embeddedArtifactRegistry del archivo de definición.

12 Conexiones de red de Edge

En esta sección se describe el enfoque de la configuración de redes en la solución SUSE Edge. Se explica cómo configurar NetworkManager en SUSE Linux Micro de forma declarativa y cómo se integran las herramientas relacionadas.

12.1 Descripción general de NetworkManager

NetworkManager es una herramienta que gestiona la conexión de red principal y otras interfaces de conexión.

NetworkManager almacena las configuraciones de redes como archivos de conexión que contienen el estado deseado en el directorio /etc/NetworkManager/system-connections/.

Encontrará más información sobre NetworkManager en la documentación de SUSE Linux Micro.

12.2 Descripción general de nmstate

nmstate es una biblioteca de amplia adopción (que incluye una herramienta de interfaz de línea de comandos) que ofrece una API declarativa para configuraciones de red a través de un esquema predefinido.

Encontrará información sobre nmstate en la documentación original.

12.3 NetworkManager Configurator (nmc)

Para acceder a las opciones de personalización de redes disponibles en SUSE Edge se usa una herramienta de interfaz de línea de comandos llamada NetworkManager Configurator, o nmc para abreviar. Aprovecha la funcionalidad que ofrece la biblioteca nmstate y es capaz de configurar por si sola direcciones IP estáticas, servidores DNS, VLAN, vinculaciones, puentes, etc. Esta herramienta permite generar configuraciones de redes a partir de estados predefinidos deseados y aplicarlas de forma automatizada en muchos nodos diferentes.

Encontrará información sobre NetworkManager Configurator (nmc) en el repositorio original.

12.4 ¿Cómo se usa NetworkManager Configurator en SUSE Edge?

SUSE Edge usa nmc para personalizar las redes en los distintos modelos de aprovisionamiento:

12.5 Configuración con Edge Image Builder

Edge Image Builder (EIB) es una herramienta que permite configurar varios hosts con una sola imagen del sistema operativo. En esta sección, se muestra cómo se puede utilizar un enfoque declarativo para describir los estados de red deseados, cómo se convierten en las respectivas conexiones de NetworkManager y cómo se aplican durante el proceso de aprovisionamiento.

12.5.1 Requisitos previos

Si está siguiendo esta guía, se entiende que ya dispone de lo siguiente:

  • Un host físico (o máquina virtual) AMD64/Intel 64 que ejecute SLES 15 SP6 u openSUSE Leap 15.6

  • Un entorno de ejecución de contenedores disponible (por ejemplo, Podman)

  • Una copia de la imagen RAW de SUSE Linux Micro 6.1 que se encuentra aquí

12.5.2 Obtención de la imagen del contenedor de Edge Image Builder

La imagen del contenedor de EIB está disponible públicamente y se puede descargar desde el registro de SUSE Edge ejecutando:

podman pull registry.suse.com/edge/3.3/edge-image-builder:1.2.1

12.5.3 Creación del directorio de configuración de imágenes

Para empezar, se crea el directorio de configuración:

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

Ahora, hay que asegurarse de que la copia de la imagen base descargada se traslade al directorio de configuración:

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

EIB nunca modificará la imagen base introducida. Creará una nueva imagen con sus modificaciones.

El directorio de configuración en este momento debería tener el siguiente aspecto:

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

12.5.4 Creación del archivo de definición de imagen

El archivo de definición describe la mayoría de las opciones configurables que admite Edge Image Builder.

Comencemos con un archivo de definición muy básico para nuestra imagen del sistema operativo:

cat << EOF > $CONFIG_DIR/definition.yaml
apiVersion: 1.2
image:
  arch: x86_64
  imageType: raw
  baseImage: SL-Micro.x86_64-6.1-Base-GM.raw
  outputImageName: modified-image.raw
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
EOF

La sección image es obligatoria y especifica la imagen de entrada, su arquitectura y su tipo, así como el nombre que se le dará a la imagen de salida. La sección operatingSystem es opcional y contiene la configuración para habilitar el inicio de sesión en los sistemas aprovisionados con el nombre de usuario/contraseña root/eib.

Nota
Nota

Puede usar libremente su propia contraseña cifrada ejecutando openssl passwd -6 <contraseña>.

El directorio de configuración en este momento debería tener el siguiente aspecto:

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

12.5.5 Definición de las configuraciones de redes

Las configuraciones de redes deseadas no forman parte del archivo de definición de imagen que se acaba de crear. Se introducen ahora en el directorio network/ especial. Vamos a crearlo:

mkdir -p $CONFIG_DIR/network

Como se mencionó anteriormente, la herramienta NetworkManager Configurator (nmc) espera una entrada en forma de esquema predefinido. Encontrará cómo configurar una amplia variedad de opciones de red diferentes en la documentación de ejemplos de NMState original.

En esta guía se explica cómo configurar la red en tres nodos diferentes:

  • Un nodo que usa dos interfaces Ethernet

  • Un nodo que usa vinculación de interfaces de red

  • Un nodo que usa un puente de redes

Aviso
Aviso

No se recomienda utilizar configuraciones de redes completamente diferentes en entornos de producción, especialmente si se configuran clústeres de Kubernetes. Las configuraciones de redes deben ser, por lo general, homogéneas entre los nodos o, al menos, entre las funciones dentro de un clúster determinado. Esta guía incluye varias opciones diferentes solo a modo de referencia.

Nota
Nota

En el ejemplo siguiente se entiende que se usa una red libvirt predeterminada con un rango de direcciones IP 192.168.122.1/24. Ajústelo según las necesidades concretas de su entorno.

Vamos a crear los estados deseados para el primer nodo, al que llamaremos node1.suse.com:

cat << EOF > $CONFIG_DIR/network/node1.suse.com.yaml
routes:
  config:
    - destination: 0.0.0.0/0
      metric: 100
      next-hop-address: 192.168.122.1
      next-hop-interface: eth0
      table-id: 254
    - destination: 192.168.122.0/24
      metric: 100
      next-hop-address:
      next-hop-interface: eth0
      table-id: 254
dns-resolver:
  config:
    server:
      - 192.168.122.1
      - 8.8.8.8
interfaces:
  - name: eth0
    type: ethernet
    state: up
    mac-address: 34:8A:B1:4B:16:E1
    ipv4:
      address:
        - ip: 192.168.122.50
          prefix-length: 24
      dhcp: false
      enabled: true
    ipv6:
      enabled: false
  - name: eth3
    type: ethernet
    state: down
    mac-address: 34:8A:B1:4B:16:E2
    ipv4:
      address:
        - ip: 192.168.122.55
          prefix-length: 24
      dhcp: false
      enabled: true
    ipv6:
      enabled: false
EOF

En este ejemplo, definimos el estado deseado de dos interfaces Ethernet (eth0 y eth3), sus direcciones IP solicitadas, el enrutamiento y la resolución DNS.

Aviso
Aviso

Debe asegurarse de que las direcciones MAC de todas las interfaces Ethernet estén incluidas en la lista. Estas direcciones se utilizan durante el proceso de aprovisionamiento como identificadores de los nodos y sirven para determinar qué configuraciones deben aplicarse. De esta manera, podemos configurar varios nodos utilizando una sola imagen ISO o RAW.

El siguiente es el segundo nodo, al que llamaremos node2.suse.com y que utilizará vinculación de interfaces de red:

cat << EOF > $CONFIG_DIR/network/node2.suse.com.yaml
routes:
  config:
    - destination: 0.0.0.0/0
      metric: 100
      next-hop-address: 192.168.122.1
      next-hop-interface: bond99
      table-id: 254
    - destination: 192.168.122.0/24
      metric: 100
      next-hop-address:
      next-hop-interface: bond99
      table-id: 254
dns-resolver:
  config:
    server:
      - 192.168.122.1
      - 8.8.8.8
interfaces:
  - name: bond99
    type: bond
    state: up
    ipv4:
      address:
        - ip: 192.168.122.60
          prefix-length: 24
      enabled: true
    link-aggregation:
      mode: balance-rr
      options:
        miimon: '140'
      port:
        - eth0
        - eth1
  - name: eth0
    type: ethernet
    state: up
    mac-address: 34:8A:B1:4B:16:E3
    ipv4:
      enabled: false
    ipv6:
      enabled: false
  - name: eth1
    type: ethernet
    state: up
    mac-address: 34:8A:B1:4B:16:E4
    ipv4:
      enabled: false
    ipv6:
      enabled: false
EOF

En este ejemplo definimos un estado deseado de dos interfaces Ethernet (eth0 y eth1) que no permiten el direccionamiento IP, así como una vinculación con una directiva round-robin y su dirección respectiva que se utilizará para reenviar el tráfico de red.

Por último, crearemos el tercer y último archivo de estado deseado, que usará un puente de red y al que llamaremos node3.suse.com:

cat << EOF > $CONFIG_DIR/network/node3.suse.com.yaml
routes:
  config:
    - destination: 0.0.0.0/0
      metric: 100
      next-hop-address: 192.168.122.1
      next-hop-interface: linux-br0
      table-id: 254
    - destination: 192.168.122.0/24
      metric: 100
      next-hop-address:
      next-hop-interface: linux-br0
      table-id: 254
dns-resolver:
  config:
    server:
      - 192.168.122.1
      - 8.8.8.8
interfaces:
  - name: eth0
    type: ethernet
    state: up
    mac-address: 34:8A:B1:4B:16:E5
    ipv4:
      enabled: false
    ipv6:
      enabled: false
  - name: linux-br0
    type: linux-bridge
    state: up
    ipv4:
      address:
        - ip: 192.168.122.70
          prefix-length: 24
      dhcp: false
      enabled: true
    bridge:
      options:
        group-forward-mask: 0
        mac-ageing-time: 300
        multicast-snooping: true
        stp:
          enabled: true
          forward-delay: 15
          hello-time: 2
          max-age: 20
          priority: 32768
      port:
        - name: eth0
          stp-hairpin-mode: false
          stp-path-cost: 100
          stp-priority: 32
EOF

El directorio de configuración en este momento debería tener el siguiente aspecto:

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

Los nombres de los archivos del directorio network/ son intencionados. Corresponden a los nombres de host que se establecerán durante el proceso de aprovisionamiento.

12.5.6 Creación de la imagen del sistema operativo

Ahora que todas las configuraciones necesarias están listas, podemos crear la imagen ejecutando:

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

El resultado debe ser parecido a esto:

Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Systemd ...................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Embedded Artifact Registry ... [SKIPPED]
Keymap ....................... [SUCCESS]
Kubernetes ................... [SKIPPED]
Certificates ................. [SKIPPED]
Building RAW image...
Kernel Params ................ [SKIPPED]
Image build complete!

El fragmento anterior nos indica que el componente Network se ha configurado correctamente y que podemos continuar con el aprovisionamiento de nuestros nodos periféricos.

Nota
Nota

Es posible inspeccionar un archivo de registro (network-config.log) y los respectivos archivos de conexión de NetworkManager en el directorio _build resultante, dentro de un directorio con marca de hora de la ejecución de la imagen.

12.5.7 Aprovisionamiento de los nodos periféricos

Vamos a copiar la imagen RAW resultante:

mkdir edge-nodes && cd edge-nodes
for i in {1..4}; do cp $CONFIG_DIR/modified-image.raw node$i.raw; done

Notará que hemos copiado la imagen creada cuatro veces, pero solo especificamos las configuraciones de redes para tres nodos. Esto se debe a que también queremos mostrar lo que sucederá si aprovisionamos un nodo que no coincide con ninguna de las configuraciones deseadas.

Nota
Nota

En esta guía se usará virtualización para los ejemplos de aprovisionamiento de nodos. Asegúrese de que estén habilitadas las extensiones necesarias en el BIOS (consulte este documento para obtener más detalles).

Utilizaremos virt-install para crear máquinas virtuales utilizando los discos sin procesar copiados. Cada máquina virtual utilizará 10 GB de RAM y 6 CPU virtuales.

12.5.7.1 Aprovisionamiento del primer nodo

Vamos a crear la máquina virtual:

virt-install --name node1 --ram 10000 --vcpus 6 --disk path=node1.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default,mac=34:8A:B1:4B:16:E1 --network default,mac=34:8A:B1:4B:16:E2 --virt-type kvm --import
Nota
Nota

Es importante que creemos las interfaces de red con las mismas direcciones MAC que las del estado deseado que hemos descrito anteriormente.

Una vez completada la operación, veremos algo similar a lo siguiente:

Starting install...
Creating domain...

Running text console command: virsh --connect qemu:///system console node1
Connected to domain 'node1'
Escape character is ^] (Ctrl + ])


Welcome to SUSE Linux Micro 6.0 (x86_64) - Kernel 6.4.0-18-default (tty1).

SSH host key: SHA256:XN/R5Tw43reG+QsOw480LxCnhkc/1uqMdwlI6KUBY70 (RSA)
SSH host key: SHA256:/96yGrPGKlhn04f1rb9cXv/2WJt4TtrIN5yEcN66r3s (DSA)
SSH host key: SHA256:Dy/YjBQ7LwjZGaaVcMhTWZNSOstxXBsPsvgJTJq5t00 (ECDSA)
SSH host key: SHA256:TNGqY1LRddpxD/jn/8dkT/9YmVl9hiwulqmayP+wOWQ (ED25519)
eth0: 192.168.122.50
eth1:


Configured with the Edge Image Builder
Activate the web console with: systemctl enable --now cockpit.socket

node1 login:

Ahora podemos iniciar sesión con el par de credenciales root:eib. Si lo preferimos, también podemos conectarnos por SSH al host, en lugar de a la consola virsh que se presenta aquí.

Cuando haya iniciado sesión, confirmaremos que todos los ajustes estén correctos.

Verifique que el nombre de host esté configurado correctamente:

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

Verifique que la configuración de enrutamiento sea correcta:

node1:~ # ip r
default via 192.168.122.1 dev eth0 proto static metric 100
192.168.122.0/24 dev eth0 proto static scope link metric 100
192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.50 metric 100

Verifique que la conexión a Internet esté disponible:

node1:~ # ping google.com
PING google.com (142.250.72.78) 56(84) bytes of data.
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=1 ttl=56 time=13.2 ms
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=2 ttl=56 time=13.4 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 13.248/13.304/13.361/0.056 ms

Verifique que haya exactamente dos interfaces Ethernet configuradas y que solo una de ellas esté activa:

node1:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e1 brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
    inet 192.168.122.50/24 brd 192.168.122.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e2 brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    altname ens3

node1:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME  UUID                                  TYPE      DEVICE  FILENAME
eth0  dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0    /etc/NetworkManager/system-connections/eth0.nmconnection
eth1  7e211aea-3d14-59cf-a4fa-be91dac5dbba  ethernet  --      /etc/NetworkManager/system-connections/eth1.nmconnection

Notará que la segunda interfaz es eth1 en lugar de la predefinida en nuestro estado de red deseado, eth3. Esto se debe a que NetworkManager Configurator (nmc) es capaz de detectar que el sistema operativo ha asignado un nombre diferente a la tarjeta de red con la dirección MAC 34:8a:b1:4b:16:e2 y ajusta su configuración en consecuencia.

Verifique que, efectivamente, esto sea así inspeccionando la fase de Combustion del aprovisionamiento:

node1:~ # journalctl -u combustion | grep nmc
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Identified host: node1.suse.com
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Set hostname: node1.suse.com
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Processing interface 'eth0'...
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Processing interface 'eth3'...
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Using interface name 'eth1' instead of the preconfigured 'eth3'
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc] Successfully applied config

Ahora, aprovisionaremos el resto de los nodos, pero solo mostraremos las diferencias en la configuración final. No dude en aplicar cualquiera de las comprobaciones anteriores, o todas ellas, a todos los nodos que vaya a aprovisionar.

12.5.7.2 Aprovisionamiento del segundo nodo

Vamos a crear la máquina virtual:

virt-install --name node2 --ram 10000 --vcpus 6 --disk path=node2.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default,mac=34:8A:B1:4B:16:E3 --network default,mac=34:8A:B1:4B:16:E4 --virt-type kvm --import

Cuando la máquina virtual esté activa y en funcionamiento, se puede confirmar que este nodo está utilizando interfaces vinculadas:

node2:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond99 state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e3 brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
3: eth1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond99 state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e3 brd ff:ff:ff:ff:ff:ff permaddr 34:8a:b1:4b:16:e4
    altname enp0s3
    altname ens3
4: bond99: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e3 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.60/24 brd 192.168.122.255 scope global noprefixroute bond99
       valid_lft forever preferred_lft forever

Confirme que el enrutamiento utiliza la vinculación de interfaces:

node2:~ # ip r
default via 192.168.122.1 dev bond99 proto static metric 100
192.168.122.0/24 dev bond99 proto static scope link metric 100
192.168.122.0/24 dev bond99 proto kernel scope link src 192.168.122.60 metric 300

Asegúrese de que los archivos de conexión estática se utilicen correctamente:

node2:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME    UUID                                  TYPE      DEVICE  FILENAME
bond99  4a920503-4862-5505-80fd-4738d07f44c6  bond      bond99  /etc/NetworkManager/system-connections/bond99.nmconnection
eth0    dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0    /etc/NetworkManager/system-connections/eth0.nmconnection
eth1    0523c0a1-5f5e-5603-bcf2-68155d5d322e  ethernet  eth1    /etc/NetworkManager/system-connections/eth1.nmconnection

12.5.7.3 Aprovisionamiento del tercer nodo

Vamos a crear la máquina virtual:

virt-install --name node3 --ram 10000 --vcpus 6 --disk path=node3.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default,mac=34:8A:B1:4B:16:E5 --virt-type kvm --import

Cuando la máquina virtual está activa y en funcionamiento, se puede confirmar que este nodo está utilizando un puente de red:

node3:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master linux-br0 state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e5 brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
3: linux-br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.70/24 brd 192.168.122.255 scope global noprefixroute linux-br0
       valid_lft forever preferred_lft forever

Confirme que el enrutamiento utiliza el puente:

node3:~ # ip r
default via 192.168.122.1 dev linux-br0 proto static metric 100
192.168.122.0/24 dev linux-br0 proto static scope link metric 100
192.168.122.0/24 dev linux-br0 proto kernel scope link src 192.168.122.70 metric 425

Asegúrese de que los archivos de conexión estática se utilicen correctamente:

node3:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME       UUID                                  TYPE      DEVICE     FILENAME
linux-br0  1f8f1469-ed20-5f2c-bacb-a6767bee9bc0  bridge    linux-br0  /etc/NetworkManager/system-connections/linux-br0.nmconnection
eth0       dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0       /etc/NetworkManager/system-connections/eth0.nmconnection

12.5.7.4 Aprovisionamiento del cuarto nodo

Por último, se aprovisionará un nodo que no coincida con ninguna de las configuraciones predefinidas por una dirección MAC. En estos casos, utilizaremos DHCP de forma predeterminada para configurar las interfaces de red.

Vamos a crear la máquina virtual:

virt-install --name node4 --ram 10000 --vcpus 6 --disk path=node4.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default --virt-type kvm --import

Cuando la máquina virtual esté activa y en funcionamiento, podemos confirmar que este nodo utiliza una dirección IP aleatoria para su interfaz de red:

localhost:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:56:63:71 brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
    inet 192.168.122.86/24 brd 192.168.122.255 scope global dynamic noprefixroute eth0
       valid_lft 3542sec preferred_lft 3542sec
    inet6 fe80::5054:ff:fe56:6371/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

Verifique que nmc no ha podido aplicar configuraciones estáticas para este nodo:

localhost:~ # journalctl -u combustion | grep nmc
Apr 23 12:15:45 localhost.localdomain combustion[1357]: [2024-04-23T12:15:45Z ERROR nmc] Applying config failed: None of the preconfigured hosts match local NICs

Verifique que la interfaz Ethernet se haya configurado mediante DHCP:

localhost:~ # journalctl | grep eth0
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7801] manager: (eth0): new Ethernet device (/org/freedesktop/NetworkManager/Devices/2)
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7802] device (eth0): state change: unmanaged -> unavailable (reason 'managed', sys-iface-state: 'external')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7929] device (eth0): carrier: link connected
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7931] device (eth0): state change: unavailable -> disconnected (reason 'carrier-changed', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7944] device (eth0): Activation: starting connection 'Wired Connection' (300ed658-08d4-4281-9f8c-d1b8882d29b9)
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7945] device (eth0): state change: disconnected -> prepare (reason 'none', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7947] device (eth0): state change: prepare -> config (reason 'none', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7953] device (eth0): state change: config -> ip-config (reason 'none', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7964] dhcp4 (eth0): activation: beginning transaction (timeout in 90 seconds)
Apr 23 12:15:33 localhost.localdomain NetworkManager[704]: <info>  [1713874533.1272] dhcp4 (eth0): state changed new lease, address=192.168.122.86

localhost:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME              UUID                                  TYPE      DEVICE  FILENAME
Wired Connection  300ed658-08d4-4281-9f8c-d1b8882d29b9  ethernet  eth0    /var/run/NetworkManager/system-connections/default_connection.nmconnection

12.5.8 Configuraciones unificadas de nodos

Hay ocasiones en las que no es posible basarse en direcciones MAC conocidas. En esos casos, podemos optar por la denominada configuración unificada, que permite especificar los ajustes en un archivo _all.yaml que luego se aplicará a todos los nodos aprovisionados.

Crearemos y aprovisionaremos un nodo periférico con una estructura de configuración diferente. Siga todos los pasos desde la Sección 12.5.3, “Creación del directorio de configuración de imágenes” hasta la Sección 12.5.5, “Definición de las configuraciones de redes”.

En este ejemplo, definimos un estado deseado de dos interfaces Ethernet (eth0 y eth1): una utiliza DHCP y a la otra se le asigna una dirección IP estática.

mkdir -p $CONFIG_DIR/network

cat <<- EOF > $CONFIG_DIR/network/_all.yaml
interfaces:
- name: eth0
  type: ethernet
  state: up
  ipv4:
    dhcp: true
    enabled: true
  ipv6:
    enabled: false
- name: eth1
  type: ethernet
  state: up
  ipv4:
    address:
    - ip: 10.0.0.1
      prefix-length: 24
    enabled: true
    dhcp: false
  ipv6:
    enabled: false
EOF

Vamos a crear la imagen:

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

Cuando la imagen se haya creado correctamente, crearemos una máquina virtual con dicha imagen:

virt-install --name node1 --ram 10000 --vcpus 6 --disk path=$CONFIG_DIR/modified-image.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default --network default --virt-type kvm --import

El proceso de aprovisionamiento puede tardar unos minutos. Una vez finalizado, inicie sesión en el sistema con las credenciales proporcionadas.

Verifique que la configuración de enrutamiento sea correcta:

localhost:~ # ip r
default via 192.168.122.1 dev eth0 proto dhcp src 192.168.122.100 metric 100
10.0.0.0/24 dev eth1 proto kernel scope link src 10.0.0.1 metric 101
192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.100 metric 100

Verifique que la conexión a Internet esté disponible:

localhost:~ # ping google.com
PING google.com (142.250.72.46) 56(84) bytes of data.
64 bytes from den16s08-in-f14.1e100.net (142.250.72.46): icmp_seq=1 ttl=56 time=14.3 ms
64 bytes from den16s08-in-f14.1e100.net (142.250.72.46): icmp_seq=2 ttl=56 time=14.2 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 14.196/14.260/14.324/0.064 ms

Verifique que las interfaces Ethernet estén configuradas y activas:

localhost:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:26:44:7a brd ff:ff:ff:ff:ff:ff
    altname enp1s0
    inet 192.168.122.100/24 brd 192.168.122.255 scope global dynamic noprefixroute eth0
       valid_lft 3505sec preferred_lft 3505sec
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:ec:57:9e brd ff:ff:ff:ff:ff:ff
    altname enp7s0
    inet 10.0.0.1/24 brd 10.0.0.255 scope global noprefixroute eth1
       valid_lft forever preferred_lft forever

localhost:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME  UUID                                  TYPE      DEVICE  FILENAME
eth0  dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0    /etc/NetworkManager/system-connections/eth0.nmconnection
eth1  0523c0a1-5f5e-5603-bcf2-68155d5d322e  ethernet  eth1    /etc/NetworkManager/system-connections/eth1.nmconnection

localhost:~ # cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
id=eth0
interface-name=eth0
type=802-3-ethernet
uuid=dfd202f5-562f-5f07-8f2a-a7717756fb70

[ipv4]
dhcp-client-id=mac
dhcp-send-hostname=true
dhcp-timeout=2147483647
ignore-auto-dns=false
ignore-auto-routes=false
method=auto
never-default=false

[ipv6]
addr-gen-mode=0
dhcp-timeout=2147483647
method=disabled

localhost:~ # cat /etc/NetworkManager/system-connections/eth1.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
id=eth1
interface-name=eth1
type=802-3-ethernet
uuid=0523c0a1-5f5e-5603-bcf2-68155d5d322e

[ipv4]
address0=10.0.0.1/24
dhcp-timeout=2147483647
method=manual

[ipv6]
addr-gen-mode=0
dhcp-timeout=2147483647
method=disabled

12.5.9 Configuraciones de red personalizadas

Ya hemos tratado la configuración de red predeterminada para Edge Image Builder, que se basa en NetworkManager Configurator. Sin embargo, también existe la opción de modificarla mediante un guion personalizado. Aunque esta opción es muy flexible y tampoco depende de la dirección MAC, su limitación radica en el hecho de que su uso resulta mucho menos práctico cuando se arrancan varios nodos con una sola imagen.

Nota
Nota

Se recomienda utilizar la configuración de red predeterminada mediante archivos que describen los estados de red deseados en el directorio /network. Utilice guiones personalizados únicamente cuando ese comportamiento no sea aplicable a su caso de uso.

Crearemos y aprovisionaremos un nodo periférico con una estructura de configuración diferente. Siga todos los pasos desde la Sección 12.5.3, “Creación del directorio de configuración de imágenes” hasta la Sección 12.5.5, “Definición de las configuraciones de redes”.

En este ejemplo, crearemos un guion personalizado que aplica una configuración estática para la interfaz eth0 en todos los nodos aprovisionados, además de eliminar e inhabilitar las conexiones con cable que haya creado automáticamente NetworkManager. Esto resulta útil en situaciones en las que se desea garantizar que todos los nodos del clúster tengan una configuración de red idéntica, por lo que no es necesario preocuparse por la dirección MAC de cada nodo antes de crear la imagen.

Para empezar, se almacena el archivo de conexión en el directorio /custom/files:

mkdir -p $CONFIG_DIR/custom/files

cat << EOF > $CONFIG_DIR/custom/files/eth0.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
autoconnect-retries=1
id=eth0
interface-name=eth0
type=802-3-ethernet
uuid=dfd202f5-562f-5f07-8f2a-a7717756fb70
wait-device-timeout=60000

[ipv4]
dhcp-timeout=2147483647
method=auto

[ipv6]
addr-gen-mode=eui64
dhcp-timeout=2147483647
method=disabled
EOF

Ahora que ya hemos creado la configuración estática, también crearemos nuestro guion de red personalizado:

mkdir -p $CONFIG_DIR/network

cat << EOF > $CONFIG_DIR/network/configure-network.sh
#!/bin/bash
set -eux

# Remove and disable wired connections
mkdir -p /etc/NetworkManager/conf.d/
printf "[main]\nno-auto-default=*\n" > /etc/NetworkManager/conf.d/no-auto-default.conf
rm -f /var/run/NetworkManager/system-connections/* || true

# Copy pre-configured network configuration files into NetworkManager
mkdir -p /etc/NetworkManager/system-connections/
cp eth0.nmconnection /etc/NetworkManager/system-connections/
chmod 600 /etc/NetworkManager/system-connections/*.nmconnection
EOF

chmod a+x $CONFIG_DIR/network/configure-network.sh
Nota
Nota

El binario de nmc seguirá estando incluido por defecto, por lo que también se puede utilizar en el guion configure-network.sh si es necesario.

Aviso
Aviso

El guion personalizado siempre debe proporcionarse en /network/configure-network.sh en el directorio de configuración. Si está presente, se ignorarán todos los demás archivos. NO es posible configurar una red utilizando simultáneamente configuraciones estáticas en formato YAML y un guion personalizado.

El directorio de configuración en este momento debería tener el siguiente aspecto:

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

Vamos a crear la imagen:

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

Cuando la imagen se haya creado correctamente, crearemos una máquina virtual con dicha imagen:

virt-install --name node1 --ram 10000 --vcpus 6 --disk path=$CONFIG_DIR/modified-image.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default --virt-type kvm --import

El proceso de aprovisionamiento puede tardar unos minutos. Una vez finalizado, inicie sesión en el sistema con las credenciales proporcionadas.

Verifique que la configuración de enrutamiento sea correcta:

localhost:~ # ip r
default via 192.168.122.1 dev eth0 proto dhcp src 192.168.122.185 metric 100
192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.185 metric 100

Verifique que la conexión a Internet esté disponible:

localhost:~ # ping google.com
PING google.com (142.250.72.78) 56(84) bytes of data.
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=1 ttl=56 time=13.6 ms
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=2 ttl=56 time=13.6 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 13.592/13.599/13.606/0.007 ms

Verifique que se ha configurado de forma estática una interfaz Ethernet utilizando nuestro archivo de conexión y que esta interfaz esté activa:

localhost:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:31:d0:1b brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
    inet 192.168.122.185/24 brd 192.168.122.255 scope global dynamic noprefixroute eth0

localhost:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME  UUID                                  TYPE      DEVICE  FILENAME
eth0  dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0    /etc/NetworkManager/system-connections/eth0.nmconnection

localhost:~ # cat  /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
autoconnect-retries=1
id=eth0
interface-name=eth0
type=802-3-ethernet
uuid=dfd202f5-562f-5f07-8f2a-a7717756fb70
wait-device-timeout=60000

[ipv4]
dhcp-timeout=2147483647
method=auto

[ipv6]
addr-gen-mode=eui64
dhcp-timeout=2147483647
method=disabled

13 Elemental

Elemental es una pila de software que permite la gestión centralizada y completa del sistema operativo nativo en la nube con Kubernetes. La pila Elemental consta de varios componentes que residen en Rancher o en los nodos periféricos. Los componentes principales son:

  • elemental-operator: el operador central que reside en Rancher y gestiona las solicitudes de registro de los clientes.

  • elemental-register: el cliente que se ejecuta en los nodos periféricos y permite el registro a través de elemental-operator.

  • elemental-system-agent: un agente que reside en los nodos periféricos. Toma su configuración de elemental-register y recibe un plan para configurar el agente rancher-system-agent.

  • rancher-system-agent: cuando el nodo periférico se ha registrado por completo, toma el control de elemental-system-agent y espera nuevos planes de Rancher Manager (por ejemplo, para la instalación de Kubernetes).

Consulte la documentación original de Elemental para obtener información completa sobre Elemental y su relación con Rancher.

13.1 ¿Cómo se usa Elemental en SUSE Edge?

Partes de Elemental se usan para gestionar dispositivos remotos en caso de que no sea posible hacerlo con Metal3 (por ejemplo, si no hay BMC o si el dispositivo está tras una puerta de enlace NAT). Esto permite a los operadores arrancar sus dispositivos en un laboratorio antes de saber cuándo o dónde se enviarán. En concreto, se aprovechan los componentes elemental-register y elemental-system-agent para permitir la incorporación de hosts de SUSE Linux Micro en Rancher para casos de uso de aprovisionamiento de red "phone home". Si se usa Edge Image Builder (EIB) para crear imágenes de despliegue, es posible realizar el registro automático a través de Rancher vía Elemental especificando la configuración de registro en el directorio de configuración de EIB.

Nota
Nota

En SUSE Edge 3.3.1 no se aprovechan las funciones de gestión del sistema operativo de Elemental, por lo que no es posible gestionar los parches del sistema operativo a través de Rancher. En lugar de utilizar las herramientas de Elemental para crear imágenes de despliegue, SUSE Edge usa Edge Image Builder, que hace uso de la configuración de registro.

13.2 Prácticas recomendadas

13.2.1 Medios de instalación

La forma recomendada por SUSE Edge para crear imágenes de despliegue que puedan aprovechar Elemental para el registro en Rancher en el método de aprovisionamiento de red "phone home" es seguir las instrucciones descritas en la guía de inicio rápido de incorporación de hosts remotos con Elemental (Capítulo 2, Incorporación de hosts remotos con Elemental).

13.2.2 Etiquetas

Elemental realiza un seguimiento de su inventario con la CRD MachineInventory y ofrece una forma de seleccionar el inventario (por ejemplo, para seleccionar equipos en los que desplegar clústeres de Kubernetes) basada en etiquetas. Esto permite a los usuarios predefinir la mayor parte (si no la totalidad) de sus necesidades de infraestructura antes incluso de adquirir el hardware. Además, dado que los nodos pueden añadir o eliminar etiquetas en sus objetos de inventario respectivos (volviendo a ejecutar elemental-register con el indicador adicional --label "FOO=BAR"), es posible escribir guiones que detecten y comuniquen a Rancher dónde se ha iniciado un nodo.

13.3 Problemas conocidos

  • La interfaz de usuario de Elemental no puede actualmente crear medios de instalación ni actualizar sistemas operativos que no sean "Elemental Teal". Esto debería solucionarse en futuras versiones.

14 Akri

Akri es un proyecto experimental de la CNCF cuyo objetivo es detectar dispositivos periféricos para presentarlos como recursos nativos de Kubernetes. También permite programar un pod o un trabajo para cada dispositivo detectado. Los dispositivos pueden ser locales o estar conectados en red, y pueden utilizar una amplia variedad de protocolos.

La documentación original de Akri está en: https://docs.akri.sh

14.1 ¿Cómo se usa Akri en SUSE Edge?

Aviso
Aviso

Akri es actualmente una tecnología en fase preliminar en la pila de SUSE Edge.

Akri está disponible como parte de la pila de Edge siempre que sea necesario detectar y programar cargas de trabajo en dispositivos periféricos.

14.2 Instalación de Akri

Akri está disponible como un chart de Helm dentro del repositorio de Helm de Edge. La forma recomendada de configurar Akri es utilizando el chart de Helm proporcionado para desplegar los diferentes componentes (agente, controlador, gestores de descubrimiento) y, a continuación, utilizar su mecanismo de despliegue preferido para desplegar las CRD de configuración de Akri.

14.3 Configuración de Akri

Akri se configura mediante un objeto akri.sh/Configuration. En él, se recopila toda la información sobre cómo detectar los dispositivos, así como indicaciones de qué hacer cuando se detecta uno compatible.

A continuación se muestra un ejemplo de la configuración con todos los campos explicados:

apiVersion: akri.sh/v0
kind: Configuration
metadata:
  name: sample-configuration
spec:

Esta parte describe la configuración del controlador de detección. Debe especificar su nombre (los controladores disponibles como parte del chart de Akri son udev, opcua y onvif). discoveryDetails es específico de cada controlador; consulte la documentación del controlador para saber cómo configurarlo.

  discoveryHandler:
    name: debugEcho
    discoveryDetails: |+
      descriptions:
        - "foo"
        - "bar"

Esta sección define la carga de trabajo que se desplegará para cada dispositivo detectado. El ejemplo muestra una versión mínima de una configuración de pod en brokerPodSpec. Aquí se pueden utilizar todos los campos habituales de la especificación de un pod. También muestra la sintaxis específica de Akri para solicitar el dispositivo en la sección resources.

Como alternativa, puede utilizar un trabajo en lugar de un pod, utilizando la clave brokerJobSpec y proporcionándole la parte específica de un trabajo.

  brokerSpec:
    brokerPodSpec:
      containers:
      - name: broker-container
        image: rancher/hello-world
        resources:
          requests:
            "{{PLACEHOLDER}}" : "1"
          limits:
            "{{PLACEHOLDER}}" : "1"

Estas dos secciones muestran cómo configurar Akri para desplegar un servicio por agente (instanceService) o apuntando a todos los agentes (configurationService). Contienen todos los elementos relacionados con un servicio habitual.

  instanceServiceSpec:
    type: ClusterIp
    ports:
    - name: http
      port: 80
      protocol: tcp
      targetPort: 80
  configurationServiceSpec:
    type: ClusterIp
    ports:
    - name: https
      port: 443
      protocol: tcp
      targetPort: 443

El campo brokerProperties es un almacén de claves/valores que se expondrán como variables de entorno adicionales a cualquier pod que solicite un dispositivo detectado.

La capacidad es el número permitido de usuarios simultáneos de un dispositivo detectado.

  brokerProperties:
    key: value
  capacity: 1

14.4 Escritura y despliegue de controladores de detección adicionales

En caso de que el protocolo utilizado por su dispositivo no esté cubierto por un controlador de detección existente, puede escribir su propio protocolo utilizando la guía de desarrollo de controladores.

14.5 Extensión de panel de control Akri de Rancher

La extensión de panel de control Akri permite utilizar la interfaz de usuario del panel de control de Rancher para gestionar y supervisar dispositivos periféricos y ejecutar cargas de trabajo una vez que se han detectado dichos dispositivos.

Consulte el Capítulo 6, Extensiones de panel de control de Rancher para obtener instrucciones sobre la instalación.

Una vez instalada la extensión, puede dirigirse a cualquier clúster gestionado compatible con Akri utilizando el explorador de clústeres. En el grupo de navegación Akri, puede ver las secciones Configurations (Configuraciones) e Instances (Instancias).

configuraciones de extensión de akri

La lista de configuraciones proporciona información sobre Configuration Discovery Handler (gestor de detección de configuraciones) y el número de instancias. Al hacer clic en el nombre, se abre una página con los detalles de la configuración.

detalle de configuración de la extensión de akri

También puede editar o crear una nueva configuración. La extensión le permite seleccionar el controlador de detección, configurar el pod o el trabajo del agente, personalizar las configuraciones y los servicios de instancia, y establecer la capacidad de configuración.

edición de configuración de extensión de akri

Los dispositivos descubiertos se muestran en la lista Instances (Instancias).

lista de instancias de extensión de akri

Al hacer clic en un nombre de Instance (Instancia), se abre una página de detalles donde se muestran las cargas de trabajo y el servicio de la instancia.

detalle de instancia de extensión de akri

15 K3s

K3s es una distribución de Kubernetes certificada y de alta disponibilidad, diseñada para cargas de trabajo de producción en ubicaciones remotas sin supervisión y con recursos limitados, o dentro de dispositivos IoT.

Se presenta como un único archivo binario de pequeño tamaño, por lo que su instalación y actualización es rápida y sencilla.

15.1 ¿Cómo se usa K3s en SUSE Edge?

K3s se puede utilizar como la distribución de Kubernetes que respalda la pila de SUSE Edge. Está diseñado para instalarse en un sistema operativo SUSE Linux Micro.

El uso de K3s como distribución de Kubernetes de la pila de SUSE Edge solo se recomienda cuando resulta imposible usar etcd como backend. Si es posible usar etcd como backend, es mejor utilizar RKE2 (Capítulo 16, RKE2).

15.2 Prácticas recomendadas

15.2.1 Instalación

La forma recomendada de instalar K3s como parte de la pila de SUSE Edge es utilizando Edge Image Builder (EIB). Consulte la documentación (Capítulo 11, Edge Image Builder) para obtener más detalles sobre cómo configurar EIB para desplegar K3s.

Admite automáticamente tanto la configuración de HA (alta disponibilidad) como la configuración de Elemental.

15.2.2 Fleet para flujo de trabajo de GitOps

La pila de SUSE Edge utiliza Fleet como su herramienta GitOps preferida. Para obtener más información sobre la instalación y el uso, consulte la sección Fleet (Capítulo 8, Fleet) de esta documentación.

15.2.3 Gestión del almacenamiento

K3s incluye almacenamiento de ruta local preconfigurado, lo cual resulta útil para los clústeres de un solo nodo. En el caso de los clústeres de varios nodos, se recomienda utilizar SUSE Storage (Capítulo 17, SUSE Storage).

15.2.4 Equilibrio de carga y HA

Si ha instalado K3s utilizando EIB, esta parte ya se trata en la documentación de EIB, en la sección sobre HA.

De lo contrario, deberá instalar y configurar MetalLB siguiendo las instrucciones correspondientes de la documentación (Capítulo 25, MetalLB en K3s (con el modo de capa 2)).

16 RKE2

Consulte la documentación oficial de RKE2.

RKE2 es una distribución de Kubernetes totalmente compatible que se centra en la seguridad y el cumplimiento normativo:

  • Proporcionando valores predeterminados y opciones de configuración que permiten a los clústeres superar la prueba CIS Kubernetes Benchmark v1.6 o v1.23 con una intervención mínima por parte del operador

  • Habilitando la conformidad con FIPS 140-2

  • Escaneando regularmente los componentes en busca de CVE mediante trivy en el proceso de creación de RKE2

RKE2 lanza los componentes del plano de control como pods estáticos, gestionados por kubelet. El entorno de ejecución del contenedor integrado es containerd.

Nota: RKE2 también se conoce como RKE Government cuando se emplea en otro caso de uso y en el sector al que se dirige.

16.1 RKE2 frente a K3s

K3s es una distribución de Kubernetes totalmente compatible y ligera, centrada en Edge, IoT y ARM, optimizada para que su uso sea sencillo y para entornos con recursos limitados.

RKE2 combina lo mejor de la versión 1.x de RKE (en adelante, RKE1) y de K3s.

De K3s, hereda la facilidad de uso, la simplicidad de funcionamiento y el modelo de despliegue.

De RKE1, hereda una estrecha alineación con la versión original de Kubernetes. En algunos aspectos, K3s se ha desviado de la versión original de Kubernetes con el fin de optimizar los despliegues periféricos; pero RKE1 y RKE2 pueden mantenerse estrechamente alineados con dicha versión original.

16.2 ¿Cómo se usa RK2 en SUSE Edge?

RKE2 es una pieza fundamental de la pila de SUSE Edge. Se sitúa sobre SUSE Linux Micro (Capítulo 9, SUSE Linux Micro) y proporciona una interfaz de Kubernetes estándar necesaria para desplegar cargas de trabajo de Edge.

16.3 Prácticas recomendadas

16.3.1 Instalación

La forma recomendada de instalar RKE2 como parte de la pila de SUSE Edge es utilizando Edge Image Builder (EIB). Consulte la documentación de EIB (Capítulo 11, Edge Image Builder) para obtener más detalles sobre cómo hacerlo.

EIB es lo suficientemente flexible como para admitir cualquier parámetro requerido por RKE2, como especificar la versión de RKE2, la configuración de servidores o la configuración de los agentes, cubriendo todos los casos de uso de Edge.

También se usa e instala para otros casos de uso relacionados con Metal3. En ellos, la versión de RK2 de proveedor de Cluster API despliega automáticamente RKE2 en los clústeres que se aprovisionan con Metal3 utilizando la pila de Edge.

En esos casos, la configuración de RKE2 debe aplicarse en las diferentes CRD involucradas. Un ejemplo de cómo proporcionar una CNI diferente utilizando la CRD RKE2ControlPlane sería el siguiente:

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  serverConfig:
    cni: calico
    cniMultusEnable: true
...

Para obtener más información sobre los casos de uso de Metal3, consulte el Capítulo 10, Metal3.

16.3.2 High Availability

Para los despliegues de HA (High Availability, alta disponibilidad), EIB despliega y configura automáticamente MetalLB (Capítulo 19, MetalLB) y el operador Endpoint Copier Operator (Capítulo 20, Endpoint Copier Operator) para exponer externamente el punto final de la API de RKE2.

16.3.3 Redes

La pila de SUSE Edge admite Cilium y Calico, siendo Cilium su CNI por defecto. El metacomplemento Multus también se puede usar si los pods requieren varias interfaces de red. RKE2 por sí mismo admite una gama más amplia de opciones de CNI.

16.3.4 Almacenamiento

RKE2 no proporciona ninguna clase ni operador de almacenamiento persistente. Para clústeres que abarquen varios nodos, se recomienda utilizar SUSE Storage (Capítulo 17, SUSE Storage).

SUSE Storage es un sistema de almacenamiento en bloques distribuido ligero, fiable y fácil de usar diseñado para Kubernetes. Se trata de un producto basado en Longhorn, un proyecto de código abierto desarrollado inicialmente por Rancher Labs y actualmente incubado bajo la CNCF.

17.1 Requisitos previos

Si está siguiendo esta guía, se da por hecho que ya dispone de lo siguiente:

  • Al menos un host con SUSE Linux Micro 6.1 instalado; puede ser físico o virtual

  • Un clúster de Kubernetes instalado; ya sea K3s o RKE2

  • Helm

17.2 Instalación manual de SUSE Storage

17.2.1 Instalación de Open-iSCSI

Un requisito fundamental para desplegar y utilizar SUSE Storage es instalar el paquete open-iscsi y que el daemon iscsid se ejecute en todos los nodos de Kubernetes. Esto es obligatorio, ya que Longhorn depende de que iscsiadm esté en el host para proporcionar volúmenes persistentes a Kubernetes.

Vamos a instalarlo:

transactional-update pkg install open-iscsi

Es importante tener en cuenta que, una vez completada la operación, el paquete solo se instala en una nueva instantánea, ya que SUSE Linux Micro es un sistema operativo inmutable. Para cargarlo y que el daemon iscsid comience a ejecutarse, hay que volver a arrancar en esa nueva instantánea que acabamos de crear. Ejecute el comando reboot cuando esté listo:

reboot
Sugerencia
Sugerencia

Para obtener ayuda adicional sobre cómo instalar open-iscsi, consulte la documentación oficial de Longhorn.

17.2.2 Instalación de SUSE Storage

Hay varias formas de instalar SUSE Storage en los clústeres de Kubernetes. Esta guía explica la instalación con Helm, pero si desea usar otro método, puede seguir la documentación oficial.

  1. Añada el repositorio de charts de Helm de Rancher:

    helm repo add rancher-charts https://charts.rancher.io/
  2. Obtenga los charts más recientes del repositorio:

    helm repo update
  3. Instale SUSE Storage en el espacio de nombres longhorn-system:

    helm install longhorn-crd rancher-charts/longhorn-crd --namespace longhorn-system --create-namespace --version 106.2.0+up1.8.1
    helm install longhorn rancher-charts/longhorn --namespace longhorn-system --version 106.2.0+up1.8.1
  4. Confirme que el despliegue se ha realizado correctamente:

    kubectl -n longhorn-system get pods
    localhost:~ # kubectl -n longhorn-system get pod
    NAMESPACE         NAME                                                READY   STATUS      RESTARTS        AGE
    longhorn-system   longhorn-ui-5fc9fb76db-z5dc9                        1/1     Running     0               90s
    longhorn-system   longhorn-ui-5fc9fb76db-dcb65                        1/1     Running     0               90s
    longhorn-system   longhorn-manager-wts2v                              1/1     Running     1 (77s ago)     90s
    longhorn-system   longhorn-driver-deployer-5d4f79ddd-fxgcs            1/1     Running     0               90s
    longhorn-system   instance-manager-a9bf65a7808a1acd6616bcd4c03d925b   1/1     Running     0               70s
    longhorn-system   engine-image-ei-acb7590c-htqmp                      1/1     Running     0               70s
    longhorn-system   csi-attacher-5c4bfdcf59-j8xww                       1/1     Running     0               50s
    longhorn-system   csi-provisioner-667796df57-l69vh                    1/1     Running     0               50s
    longhorn-system   csi-attacher-5c4bfdcf59-xgd5z                       1/1     Running     0               50s
    longhorn-system   csi-provisioner-667796df57-dqkfr                    1/1     Running     0               50s
    longhorn-system   csi-attacher-5c4bfdcf59-wckt8                       1/1     Running     0               50s
    longhorn-system   csi-resizer-694f8f5f64-7n2kq                        1/1     Running     0               50s
    longhorn-system   csi-snapshotter-959b69d4b-rp4gk                     1/1     Running     0               50s
    longhorn-system   csi-resizer-694f8f5f64-r6ljc                        1/1     Running     0               50s
    longhorn-system   csi-resizer-694f8f5f64-k7429                        1/1     Running     0               50s
    longhorn-system   csi-snapshotter-959b69d4b-5k8pg                     1/1     Running     0               50s
    longhorn-system   csi-provisioner-667796df57-n5w9s                    1/1     Running     0               50s
    longhorn-system   csi-snapshotter-959b69d4b-x7b7t                     1/1     Running     0               50s
    longhorn-system   longhorn-csi-plugin-bsc8c                           3/3     Running     0               50s

17.3 Creación de volúmenes de SUSE Storage

SUSE Storage utiliza recursos de Kubernetes denominados StorageClass para aprovisionar automáticamente objetos PersistentVolume para los pods. Piense en StorageClass como una forma que tienen los administradores de describir las clases o los perfiles de almacenamiento que ofrecen.

Vamos a crear un recurso StorageClass con algunas opciones predeterminadas:

kubectl apply -f - <<EOF
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: longhorn-example
provisioner: driver.longhorn.io
allowVolumeExpansion: true
parameters:
  numberOfReplicas: "3"
  staleReplicaTimeout: "2880" # 48 hours in minutes
  fromBackup: ""
  fsType: "ext4"
EOF

Ahora que ya tenemos nuestro StorageClass, necesitamos una solicitud PersistentVolumeClaim que haga referencia a él. Una PersistentVolumeClaim (PVC) es una solicitud de almacenamiento por parte de un usuario. Las PVC consumen recursos PersistentVolume. Las solicitudes pueden pedir tamaños y modos de acceso específicos (por ejemplo, se pueden montar una vez en modo lectura/escritura o varias veces en modo solo lectura).

Vamos a crear una PersistentVolumeClaim:

kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: longhorn-volv-pvc
  namespace: longhorn-system
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: longhorn-example
  resources:
    requests:
      storage: 2Gi
EOF

Tras crear la PersistentVolumeClaim, podemos adjuntarla a un pod. Cuando se despliega el pod, Kubernetes crea el volumen de Longhorn y lo vincula al ood si hay almacenamiento disponible.

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: volume-test
  namespace: longhorn-system
spec:
  containers:
  - name: volume-test
    image: nginx:stable-alpine
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: volv
      mountPath: /data
    ports:
    - containerPort: 80
  volumes:
  - name: volv
    persistentVolumeClaim:
      claimName: longhorn-volv-pvc
EOF
Sugerencia
Sugerencia

El concepto de almacenamiento en Kubernetes es un tema complejo, pero importante. Hemos mencionado brevemente algunos de los recursos más comunes de Kubernetes, sin embargo, le sugerimos que se familiarice con la terminología específica en la documentación de Longhorn.

En este ejemplo, el resultado debería ser similar a esto:

localhost:~ # kubectl get storageclass
NAME                 PROVISIONER          RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
longhorn (default)   driver.longhorn.io   Delete          Immediate           true                   12m
longhorn-example     driver.longhorn.io   Delete          Immediate           true                   24s

localhost:~ # kubectl get pvc -n longhorn-system
NAME                STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS       AGE
longhorn-volv-pvc   Bound    pvc-f663a92e-ac32-49ae-b8e5-8a6cc29a7d1e   2Gi        RWO            longhorn-example   54s

localhost:~ # kubectl get pods -n longhorn-system
NAME                                                READY   STATUS    RESTARTS      AGE
csi-attacher-5c4bfdcf59-qmjtz                       1/1     Running   0             14m
csi-attacher-5c4bfdcf59-s7n65                       1/1     Running   0             14m
csi-attacher-5c4bfdcf59-w9xgs                       1/1     Running   0             14m
csi-provisioner-667796df57-fmz2d                    1/1     Running   0             14m
csi-provisioner-667796df57-p7rjr                    1/1     Running   0             14m
csi-provisioner-667796df57-w9fdq                    1/1     Running   0             14m
csi-resizer-694f8f5f64-2rb8v                        1/1     Running   0             14m
csi-resizer-694f8f5f64-z9v9x                        1/1     Running   0             14m
csi-resizer-694f8f5f64-zlncz                        1/1     Running   0             14m
csi-snapshotter-959b69d4b-5dpvj                     1/1     Running   0             14m
csi-snapshotter-959b69d4b-lwwkv                     1/1     Running   0             14m
csi-snapshotter-959b69d4b-tzhwc                     1/1     Running   0             14m
engine-image-ei-5cefaf2b-hvdv5                      1/1     Running   0             14m
instance-manager-0ee452a2e9583753e35ad00602250c5b   1/1     Running   0             14m
longhorn-csi-plugin-gd2jx                           3/3     Running   0             14m
longhorn-driver-deployer-9f4fc86-j6h2b              1/1     Running   0             15m
longhorn-manager-z4lnl                              1/1     Running   0             15m
longhorn-ui-5f4b7bbf69-bln7h                        1/1     Running   3 (14m ago)   15m
longhorn-ui-5f4b7bbf69-lh97n                        1/1     Running   3 (14m ago)   15m
volume-test                                         1/1     Running   0             26s

17.4 Acceso a la interfaz del usuario

Si ha instalado Longhorn con kubectl o Helm, debe configurar un controlador Ingress para permitir el tráfico externo hacia el clúster. La autenticación no está habilitada de forma predeterminada. Si se ha usado la aplicación de catálogo de Rancher, Rancher habrá creado automáticamente un controlador Ingress con control de acceso (el proxy de rancher).

  1. Obtenga la dirección IP del servicio externo de Longhorn:

    kubectl -n longhorn-system get svc
  2. Cuando haya recuperado la dirección IP de longhorn-frontend, puede acceder a la interfaz de usuario en su navegador y empezar a usarla.

17.5 Instalación con Edge Image Builder

SUSE Edge utiliza Capítulo 11, Edge Image Builder para personalizar las imágenes del sistema operativo SUSE Linux Micro base. Vamos a mostrar cómo hacerlo para aprovisionar un clúster RKE2 con Longhorn sobre él.

Vamos a crear el archivo de definición:

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

cat << EOF > $CONFIG_DIR/iso-definition.yaml
apiVersion: 1.2
image:
  imageType: iso
  baseImage: SL-Micro.x86_64-6.1-Base-SelfInstall-GM.install.iso
  arch: x86_64
  outputImageName: eib-image.iso
kubernetes:
  version: v1.32.4+rke2r1
  helm:
    charts:
      - name: longhorn
        version: 106.2.0+up1.8.1
        repositoryName: longhorn
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
      - name: longhorn-crd
        version: 106.2.0+up1.8.1
        repositoryName: longhorn
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
    repositories:
      - name: longhorn
        url: https://charts.rancher.io
operatingSystem:
  packages:
    sccRegistrationCode: <reg-code>
    packageList:
      - open-iscsi
  users:
  - username: root
    encryptedPassword: \$6\$jHugJNNd3HElGsUZ\$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
EOF
Nota
Nota

Es posible personalizar cualquiera de los valores del chart de Helm mediante un archivo independiente proporcionado en helm.charts[].valuesFile. Consulte la documentación original para obtener más detalles.

Vamos a crear la imagen:

podman run --rm --privileged -it -v $CONFIG_DIR:/eib registry.suse.com/edge/3.3/edge-image-builder:1.2.1 build --definition-file $CONFIG_DIR/iso-definition.yaml

Una vez creada la imagen, puede usarla para instalar su sistema operativo en un host físico o virtual. Tras completar el aprovisionamiento, podrá iniciar sesión en el sistema utilizando el par de credenciales root:eib.

Asegúrese de que Longhorn se haya desplegado correctamente:

localhost:~ # /var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml -n longhorn-system get pods
NAME                                                READY   STATUS    RESTARTS        AGE
csi-attacher-5c4bfdcf59-qmjtz                       1/1     Running   0               103s
csi-attacher-5c4bfdcf59-s7n65                       1/1     Running   0               103s
csi-attacher-5c4bfdcf59-w9xgs                       1/1     Running   0               103s
csi-provisioner-667796df57-fmz2d                    1/1     Running   0               103s
csi-provisioner-667796df57-p7rjr                    1/1     Running   0               103s
csi-provisioner-667796df57-w9fdq                    1/1     Running   0               103s
csi-resizer-694f8f5f64-2rb8v                        1/1     Running   0               103s
csi-resizer-694f8f5f64-z9v9x                        1/1     Running   0               103s
csi-resizer-694f8f5f64-zlncz                        1/1     Running   0               103s
csi-snapshotter-959b69d4b-5dpvj                     1/1     Running   0               103s
csi-snapshotter-959b69d4b-lwwkv                     1/1     Running   0               103s
csi-snapshotter-959b69d4b-tzhwc                     1/1     Running   0               103s
engine-image-ei-5cefaf2b-hvdv5                      1/1     Running   0               109s
instance-manager-0ee452a2e9583753e35ad00602250c5b   1/1     Running   0               109s
longhorn-csi-plugin-gd2jx                           3/3     Running   0               103s
longhorn-driver-deployer-9f4fc86-j6h2b              1/1     Running   0               2m28s
longhorn-manager-z4lnl                              1/1     Running   0               2m28s
longhorn-ui-5f4b7bbf69-bln7h                        1/1     Running   3 (2m7s ago)    2m28s
longhorn-ui-5f4b7bbf69-lh97n                        1/1     Running   3 (2m10s ago)   2m28s
Nota
Nota

Esta instalación no funciona en entornos completamente aislados. Para esos casos, consulte la Sección 27.8, “Instalación de SUSE Storage”.

SUSE Security es una solución de seguridad para Kubernetes que proporciona seguridad de red L7, seguridad en el entorno de ejecución, seguridad en la cadena de suministro y comprobaciones de cumplimiento en un paquete cohesionado.

SUSE Security es un producto que se despliega como una plataforma de múltiples contenedores, que se comunican entre sí a través de varios puertos e interfaces. En segundo plano, utiliza NeuVector como componente de seguridad de contenedores subyacente. La plataforma SUSE Security está formada por siguientes contenedores:

  • Manager (Administrador). Un contenedor sin estado que presenta el panel de control basado en web. Normalmente, solo se necesita uno y puede ejecutarse en cualquier lugar. Si el administrador falla, ninguna de las operaciones del controlador o del ejecutor se ven afectadas. Sin embargo, el administrador almacena en la memoria caché ciertas notificaciones (eventos) y datos de conexiones recientes, por lo que su visualización sí se vería afectada.

  • Controller (Controlador). El "plano de control" de SUSE Security debe desplegarse en una configuración HA (de alta disponibilidad), de modo que la configuración no se pierda en caso de fallo de un nodo. Los controladores se pueden ejecutar en cualquier lugar, aunque se suele optar por colocarlos en nodos de "gestión", maestros o de infraestructura debido a su importancia crítica.

  • Enforcer (Aplicador). Este contenedor se despliega como conjunto de daemons, por lo que hay un aplicador en cada nodo que se vaya a proteger. Normalmente, se despliega en todos los nodos de trabajador, pero es posible programar que también se despliegue en los nodos maestros y de infraestructura. Nota: si el aplicador no está en un nodo del clúster y las conexiones provienen de un pod en ese nodo, SUSE Security las etiqueta como cargas de trabajo "no gestionadas".

  • Scanner (Escáner). Realiza el análisis de vulnerabilidades utilizando la base de datos de CVE integrada, según las instrucciones del controlador. Se pueden desplegar varios escáneres para aumentar la capacidad de análisis. Los escáneres pueden ejecutarse en cualquier lugar, pero es habitual que sea en los nodos donde se ejecutan los controladores. Tenga en cuenta las consideraciones sobre el tamaño de los nodos del escáner expuestas a continuación. También es posible invocar un escáner de forma independiente para el análisis de la fase de creación, por ejemplo, dentro de un canal que activa un análisis, recupera los resultados y detiene el escáner. El escáner contiene la base de datos de CVE más reciente, por lo que debe actualizarse a diario.

  • Updater (Actualizador). El actualizador activa una actualización del escáner mediante una tarea programada de Kubernetes cuando se desea actualizar la base de datos de CVE. Asegúrese de adaptarlo a su entorno.

Encontrará documentación más detallada sobre la incorporación de SUSE Security y las prácticas recomendadas aquí.

18.1 ¿Cómo se usa SUSE Security en SUSE Edge?

SUSE Edge proporciona una configuración más ágil de SUSE Security como punto de partida para despliegues periféricos.

18.2 Notas importantes

  • El contenedor Scanner debe tener suficiente memoria para cargar la imagen que se va a escanear en la memoria y ampliarla. Para escanear imágenes de más de 1 GB, aumente la memoria del escáner hasta un poco más del tamaño máximo previsto de la imagen.

  • En el modo de protección, se espera un gran número de conexiones de red. El contenedor Enforcer requiere CPU y memoria cuando se encuentra en ese modo (bloqueo de firewall en línea) para conservar e inspeccionar las conexiones y la posible carga útil (DLP). Aumentar la memoria y dedicar un núcleo de CPU a Enforcer puede garantizar una capacidad de filtrado de paquetes adecuada.

18.3 Instalación con Edge Image Builder

SUSE Edge utiliza Capítulo 11, Edge Image Builder para personalizar las imágenes del sistema operativo SUSE Linux Micro base. Siga las instrucciones de la Sección 27.7, “Instalación de SUSE Security” para realizar una instalación en entornos aislados de SUSE Security sobre clústeres de Kubernetes aprovisionados por EIB.

19 MetalLB

Consulte la documentación oficial de MetalLB.

MetalLB es una implementación de equilibrador de carga para clústeres de Kubernetes en bare metal que utiliza protocolos de enrutamiento estándar.

En entornos bare metal, configurar equilibradores de carga de red es notablemente más complejo que en entornos en la nube. A diferencia de las sencillas llamadas a la API de las configuraciones en la nube, en bare metal se requieren dispositivos de red dedicados o una combinación de equilibradores de carga y configuraciones de IP virtual (VIP) para gestionar la alta disponibilidad (HA) o abordar el posible punto único de fallo (SPOF) inherente a que haya un equilibrador de carga de un solo nodo. Estas configuraciones no se automatizan fácilmente, lo que plantea retos en los despliegues de Kubernetes, donde los componentes se escalan dinámicamente.

MetalLB aborda estos retos aprovechando el modelo de Kubernetes para crear servicios de tipo LoadBalancer como si estuvieran operando en un entorno de nube, incluso en configuraciones bare metal.

Hay dos enfoques distintos, mediante el modo L2 (que usa tricks ARP) o mediante BGP. A rasgos generales, el modo L2 no necesita ningún equipo de red especial, pero BGP suele ser mejor. El uso de un enfoque u otro dependerá de los casos de uso.

19.1 ¿Cómo se usa MetalLB en SUSE Edge?

SUSE Edge usa MetalLB principalmente de dos formas:

  • Como solución de equilibrador de carga: MetalLB sirve como solución de equilibrio de carga para equipos bare metal.

  • En configuraciones K3s/RKE2 de HA: MetalLB permite equilibrar la carga de la API de Kubernetes utilizando una dirección IP virtual.

Nota
Nota

Para poder exponer la API, se utiliza el operador Endpoint Copier Operator (Capítulo 20, Endpoint Copier Operator) para mantener sincronizados los puntos finales de la API de K8s desde el servicio kubernetes con un servicio LoadBalancer kubernetes-vip.

19.2 Prácticas recomendadas

La instalación de MetalLB en el modo L2 se describe en el Capítulo 25, MetalLB en K3s (con el modo de capa 2).

Hay disponible una guía sobre cómo instalar MetalLB delante del kube-api-server para lograr una topología de alta disponibilidad en el Capítulo 26, MetalLB delante del servidor de Kubernetes API.

19.3 Problemas conocidos

  • K3s incluye su propia solución de equilibrio de carga llamada Klipper. Para utilizar MetalLB, es necesario inhabilitar Klipper. Para hacerlo, inicie el servidor K3s con la opción --disable servicelb, tal y como se describe en la documentación de K3s.

20 Endpoint Copier Operator

Endpoint Copier Operator es un operador de Kubernetes cuyo objetivo es crear una copia de un servicio y un punto final de Kubernetes y mantenerlos sincronizados.

20.1 ¿Cómo se usa Endpoint Copier Operator en SUSE Edge?

En SUSE Edge, Endpoint Copier Operator desempeña un papel crucial para conseguir una configuración de alta disponibilidad (HA) para clústeres K3s/RKE2. Esto se logra creando un servicio kubernetes-vip de tipo LoadBalancer, lo que garantiza que su punto final se sincronice constantemente con el punto final de Kubernetes. MetalLB (Capítulo 19, MetalLB) se utiliza para gestionar el servicio kubernetes-vip, ya que la dirección IP expuesta se utiliza desde otros nodos para unirse al clúster.

20.2 Prácticas recomendadas

La documentación completa para utilizar Endpoint Copier Operator se encuentra aquí.

También puede consultar nuestra guía (Capítulo 25, MetalLB en K3s (con el modo de capa 2)) sobre cómo lograr una configuración HA de K3s/RKE2 utilizando Endpoint Copier Operator y MetalLB.

20.3 Problemas conocidos

Actualmente, Endpoint Copier Operator solo puede trabajar con un servicio/punto final. Se prevé realizar mejoras en el futuro para admitir múltiples servicios/puntos finales.

21 Edge Virtualization

En esta sección se describe cómo se puede utilizar Edge Virtualization para ejecutar máquinas virtuales en los nodos periféricos. Edge Virtualization se hadiseñado para casos de uso de virtualización ligeros, en los que se espera que se utilice un flujo de trabajo común para el despliegue y la gestión tanto de aplicaciones virtualizadas como en contenedores.

SUSE Edge Virtualization admite dos métodos para ejecutar máquinas virtuales:

  1. Despliegue manual de las máquinas virtuales mediante libvirt+qemu-kvm a nivel del host (sin intervención de Kubernetes)

  2. Despliegue del operador KubeVirt para la gestión basada en Kubernetes de máquinas virtuales

Ambas opciones son válidas, pero solo la segunda se trata a continuación. Si desea utilizar los mecanismos de virtualización estándares listos para usar que proporciona SUSE Linux Micro, encontrará una guía completa en este documento. Aunque está escrita principalmente para SUSE Linux Enterprise Server, los conceptos son prácticamente idénticos.

Esta guía explica inicialmente cómo desplegar los componentes de virtualización adicionales en un sistema que ya ha sido predesplegado, pero incluye una sección que describe cómo integrar esta configuración en el despliegue inicial a través de Edge Image Builder. Si no desea repasar los conceptos básicos y configurarlo todo manualmente, pase directamente a esa sección.

21.1 Descripción general de KubeVirt

KubeVirt permite gestionar máquinas virtuales con Kubernetes junto con el resto de sus cargas de trabajo en contenedores. Para ello, ejecuta la parte del espacio de usuario de la pila de virtualización de Linux en un contenedor. Esto minimiza los requisitos del sistema host, lo que facilita la configuración y la gestión.

Encontrará los detalles sobre la arquitectura de KubeVirt en la documentación original.

21.2 Requisitos previos

Si está siguiendo esta guía, se da por hecho que ya dispone de lo siguiente:

  • Al menos un host físico con SUSE Linux Micro 6.1 instalado y con las extensiones de virtualización habilitadas en el BIOS (consulte este documento para obtener más detalles).

  • Un clúster Kubernetes de K3s/RKE2 ya desplegado en todos sus nodos y con una kubeconfig adecuada que permita el acceso de superusuario al clúster.

  • Acceso al usuario root: estas instrucciones dan por sentado que usted es el usuario root y que no está derivando sus privilegios mediante sudo.

  • Debe tener Helm disponible localmente con una conexión de red adecuada para poder enviar configuraciones a su clúster de Kubernetes y descargar las imágenes necesarias.

21.3 Instalación manual de Edge Virtualization

Esta guía no explica el despliegue de Kubernetes, pero da por sentado que ha instalado la versión de K3s o RKE2 adecuada para SUSE Edge y que tiene su kubeconfig configurada adecuadamente para que los comandos estándar kubectl se puedan ejecutar como superusuario. También se presupone que su nodo forma un clúster de un solo nodo, aunque no se esperan diferencias significativas para los despliegues de varios nodos.

SUSE Edge Virtualization se despliega mediante tres charts de Helm distintos, en concreto:

  • KubeVirt: los componentes básicos de virtualización, es decir, las CRD de Kubernetes, los operadores y otros componentes necesarios para que Kubernetes pueda desplegar y gestionar máquinas virtuales.

  • Extensión de panel de control KubeVirt: una extensión opcional de la interfaz de usuario de Rancher que permite la gestión básica de máquinas virtuales; por ejemplo, iniciar/detener máquinas virtuales, así como acceder al panel de control.

  • Containerized Data Importer (CDI): un componente adicional que permite la integración del almacenamiento persistente para KubeVirt, proporcionando capacidades para que las máquinas virtuales puedan usar sistemas secundarios de almacenamiento existentes de Kubernetes para los datos, pero también permitiendo a los usuarios importar o clonar volúmenes de datos para máquinas virtuales.

Cada uno de estos charts de Helm tiene versiones distintas según la versión de SUSE Edge que esté utilizando actualmente. Para usarlos en entornos de producción o con asistencia, utilice los artefactos que se pueden encontrar en el registro de SUSE.

En primer lugar, asegúrese de que puede acceder correctamente a kubectl:

$ kubectl get nodes

Esto debería mostrar algo similar a lo siguiente:

NAME                   STATUS   ROLES                       AGE     VERSION
node1.edge.rdo.wales   Ready    control-plane,etcd,master   4h20m   v1.30.5+rke2r1
node2.edge.rdo.wales   Ready    control-plane,etcd,master   4h15m   v1.30.5+rke2r1
node3.edge.rdo.wales   Ready    control-plane,etcd,master   4h15m   v1.30.5+rke2r1

Ahora, puede instalar los charts de Helm de KubeVirt y Containerized Data Importer (CDI):

$ helm install kubevirt oci://registry.suse.com/edge/charts/kubevirt --namespace kubevirt-system --create-namespace
$ helm install cdi oci://registry.suse.com/edge/charts/cdi --namespace cdi-system --create-namespace

En unos minutos, debería tener todos los componentes de KubeVirt y CDI desplegados. Puede comprobar que todos los recursos se han desplegado en los espacios de nombres kubevirt-system y cdi-system.

Verifique los recursos de KubeVirt:

$ kubectl get all -n kubevirt-system

Esto debería mostrar algo similar a lo siguiente:

NAME                                   READY   STATUS    RESTARTS      AGE
pod/virt-operator-5fbcf48d58-p7xpm     1/1     Running   0             2m24s
pod/virt-operator-5fbcf48d58-wnf6s     1/1     Running   0             2m24s
pod/virt-handler-t594x                 1/1     Running   0             93s
pod/virt-controller-5f84c69884-cwjvd   1/1     Running   1 (64s ago)   93s
pod/virt-controller-5f84c69884-xxw6q   1/1     Running   1 (64s ago)   93s
pod/virt-api-7dfc54cf95-v8kcl          1/1     Running   1 (59s ago)   118s

NAME                                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/kubevirt-prometheus-metrics   ClusterIP   None            <none>        443/TCP   2m1s
service/virt-api                      ClusterIP   10.43.56.140    <none>        443/TCP   2m1s
service/kubevirt-operator-webhook     ClusterIP   10.43.201.121   <none>        443/TCP   2m1s
service/virt-exportproxy              ClusterIP   10.43.83.23     <none>        443/TCP   2m1s

NAME                          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/virt-handler   1         1         1       1            1           kubernetes.io/os=linux   93s

NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/virt-operator     2/2     2            2           2m24s
deployment.apps/virt-controller   2/2     2            2           93s
deployment.apps/virt-api          1/1     1            1           118s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/virt-operator-5fbcf48d58     2         2         2       2m24s
replicaset.apps/virt-controller-5f84c69884   2         2         2       93s
replicaset.apps/virt-api-7dfc54cf95          1         1         1       118s

NAME                            AGE     PHASE
kubevirt.kubevirt.io/kubevirt   2m24s   Deployed

Verifique los recursos de CDI:

$ kubectl get all -n cdi-system

Esto debería mostrar algo similar a lo siguiente:

NAME                                   READY   STATUS    RESTARTS   AGE
pod/cdi-operator-55c74f4b86-692xb      1/1     Running   0          2m24s
pod/cdi-apiserver-db465b888-62lvr      1/1     Running   0          2m21s
pod/cdi-deployment-56c7d74995-mgkfn    1/1     Running   0          2m21s
pod/cdi-uploadproxy-7d7b94b968-6kxc2   1/1     Running   0          2m22s

NAME                             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/cdi-uploadproxy          ClusterIP   10.43.117.7    <none>        443/TCP    2m22s
service/cdi-api                  ClusterIP   10.43.20.101   <none>        443/TCP    2m22s
service/cdi-prometheus-metrics   ClusterIP   10.43.39.153   <none>        8080/TCP   2m21s

NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/cdi-operator      1/1     1            1           2m24s
deployment.apps/cdi-apiserver     1/1     1            1           2m22s
deployment.apps/cdi-deployment    1/1     1            1           2m21s
deployment.apps/cdi-uploadproxy   1/1     1            1           2m22s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/cdi-operator-55c74f4b86      1         1         1       2m24s
replicaset.apps/cdi-apiserver-db465b888      1         1         1       2m21s
replicaset.apps/cdi-deployment-56c7d74995    1         1         1       2m21s
replicaset.apps/cdi-uploadproxy-7d7b94b968   1         1         1       2m22s

Para verificar que las definiciones de recursos personalizados (CRD) de VirtualMachine están desplegadas, puede usar:

$ kubectl explain virtualmachine

Esto debería dar como resultado la definición del objeto VirtualMachine, que debería tener este aspecto:

GROUP:      kubevirt.io
KIND:       VirtualMachine
VERSION:    v1

DESCRIPTION:
    VirtualMachine handles the VirtualMachines that are not running or are in a
    stopped state The VirtualMachine contains the template to create the
    VirtualMachineInstance. It also mirrors the running state of the created
    VirtualMachineInstance in its status.
(snip)

21.4 Despliegue de máquinas virtuales

Ahora que KubeVirt y CDI se han desplegado, vamos a definir una máquina virtual sencilla basada en openSUSE Tumbleweed. La configuración de esta máquina virtual es muy sencilla: usa una "conexión de red de pod" idéntica a la de cualquier otro pod. También emplea almacenamiento no persistente, lo que garantiza que el almacenamiento sea efímero, al igual que en cualquier contenedor que no tenga un PVC.

$ kubectl apply -f - <<EOF
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: tumbleweed
  namespace: default
spec:
  runStrategy: Always
  template:
    spec:
      domain:
        devices: {}
        machine:
          type: q35
        memory:
          guest: 2Gi
        resources: {}
      volumes:
      - containerDisk:
          image: registry.opensuse.org/home/roxenham/tumbleweed-container-disk/containerfile/cloud-image:latest
        name: tumbleweed-containerdisk-0
      - cloudInitNoCloud:
          userDataBase64: I2Nsb3VkLWNvbmZpZwpkaXNhYmxlX3Jvb3Q6IGZhbHNlCnNzaF9wd2F1dGg6IFRydWUKdXNlcnM6CiAgLSBkZWZhdWx0CiAgLSBuYW1lOiBzdXNlCiAgICBncm91cHM6IHN1ZG8KICAgIHNoZWxsOiAvYmluL2Jhc2gKICAgIHN1ZG86ICBBTEw9KEFMTCkgTk9QQVNTV0Q6QUxMCiAgICBsb2NrX3Bhc3N3ZDogRmFsc2UKICAgIHBsYWluX3RleHRfcGFzc3dkOiAnc3VzZScK
        name: cloudinitdisk
EOF

El resultado debe ser que se ha creado una VirtualMachine:

virtualmachine.kubevirt.io/tumbleweed created

Esta definición de VirtualMachine es mínima y especifica muy poco sobre la configuración. Solo indica que se trata de una máquina de tipo q35 con 2 GB de memoria que usa una imagen de disco basada en un containerDisk efímero (es decir, una imagen de disco que se almacena en una imagen de contenedor desde un repositorio de imágenes remoto), y especifica un disco cloudInit con cifrado base64, que solo utilizamos para la creación de usuarios y la obligación de usar contraseña en el momento del arranque (utilice base64 -d para descifrarlo).

Nota
Nota

Esta imagen de máquina virtual sirve solo para realizar pruebas. La imagen no cuenta con asistencia oficial y solo se ofrece como ejemplo para fines de documentación.

Esta máquina tarda unos minutos en arrancar, ya que necesita descargar la imagen de disco de openSUSE Tumbleweed, pero una vez que lo haya hecho, podrá ver más detalles sobre ella:

$ kubectl get vmi

Esto debería dar como resultado el nodo en el que se inició la máquina virtual y la dirección IP de la máquina virtual. Recuerde que, dado que utiliza conexión de red de pod, la dirección IP indicada será igual que la de cualquier otro pod y, por lo tanto, enrutable:

NAME         AGE     PHASE     IP           NODENAME               READY
tumbleweed   4m24s   Running   10.42.2.98   node3.edge.rdo.wales   True

Al ejecutar estos comandos en los propios nodos del clúster de Kubernetes, con una CNI que enruta el tráfico directamente a los pods (por ejemplo, Cilium), debería poder conectarse directamente por ssh a la máquina. Sustituya la siguiente dirección IP por la que se le haya asignado a su máquina virtual:

$ ssh suse@10.42.2.98
(password is "suse")

Cuando se encuentre en esta máquina virtual, puede practicar un poco, pero recuerde que tiene recursos limitados y solo cuenta con 1 GB de espacio en disco. Cuando termine, pulse Ctrl+D o exit para desconectarse de la sesión SSH.

El proceso de la máquina virtual sigue estando envuelto en un pod estándar de Kubernetes. La CRD VirtualMachine es una representación de la máquina virtual deseada, pero el proceso en el que se inicia realmente la máquina virtual es a través del pod virt-launcher, un pod estándar de Kubernetes, igual que cualquier otra aplicación. Por cada máquina virtual iniciada, se puede ver que hay un pod virt-launcher:

$ kubectl get pods

Esto debería mostrar el único pod virt-launcher para la máquina Tumbleweed que hemos definido:

NAME                             READY   STATUS    RESTARTS   AGE
virt-launcher-tumbleweed-8gcn4   3/3     Running   0          10m

Si echamos un vistazo a este pod virt-launcher, veremos que está ejecutando los procesos libvirt y qemu-kvm. Podemos entrar en el propio pod y echar un vistazo, pero tenga en cuenta que es necesario adaptar el siguiente comando al nombre de su pod:

$ kubectl exec -it virt-launcher-tumbleweed-8gcn4 -- bash

Una vez en el pod, pruebe a ejecutar comandos virsh y observe los procesos. Comprobará que se está ejecutando el binario qemu-system-x86_64, junto con ciertos procesos para supervisar la máquina virtual. También verá la ubicación de la imagen de disco y cómo está conectada la red (como un dispositivo tap):

qemu@tumbleweed:/> ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ssl    0:00 /usr/bin/virt-launcher-monitor --qemu-timeout 269s --name tumbleweed --uid b9655c11-38f7-4fa8-8f5d-bfe987dab42c --namespace default --kubevirt-share-dir /var/run/kubevirt --ephemeral-disk-dir /var/run/kubevirt-ephemeral-disks --container-disk-dir /var/run/kube
   12 ?        Sl     0:01 /usr/bin/virt-launcher --qemu-timeout 269s --name tumbleweed --uid b9655c11-38f7-4fa8-8f5d-bfe987dab42c --namespace default --kubevirt-share-dir /var/run/kubevirt --ephemeral-disk-dir /var/run/kubevirt-ephemeral-disks --container-disk-dir /var/run/kubevirt/con
   24 ?        Sl     0:00 /usr/sbin/virtlogd -f /etc/libvirt/virtlogd.conf
   25 ?        Sl     0:01 /usr/sbin/virtqemud -f /var/run/libvirt/virtqemud.conf
   83 ?        Sl     0:31 /usr/bin/qemu-system-x86_64 -name guest=default_tumbleweed,debug-threads=on -S -object {"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/run/kubevirt-private/libvirt/qemu/lib/domain-1-default_tumbleweed/master-key.aes"} -machine pc-q35-7.1,usb
  286 pts/0    Ss     0:00 bash
  320 pts/0    R+     0:00 ps ax

qemu@tumbleweed:/> virsh list --all
 Id   Name                 State
------------------------------------
 1    default_tumbleweed   running

qemu@tumbleweed:/> virsh domblklist 1
 Target   Source
---------------------------------------------------------------------------------------------
 sda      /var/run/kubevirt-ephemeral-disks/disk-data/tumbleweed-containerdisk-0/disk.qcow2
 sdb      /var/run/kubevirt-ephemeral-disks/cloud-init-data/default/tumbleweed/noCloud.iso

qemu@tumbleweed:/> virsh domiflist 1
 Interface   Type       Source   Model                     MAC
------------------------------------------------------------------------------
 tap0        ethernet   -        virtio-non-transitional   e6:e9:1a:05:c0:92

qemu@tumbleweed:/> exit
exit

Por último, eliminemos esta máquina virtual:

$ kubectl delete vm/tumbleweed
virtualmachine.kubevirt.io "tumbleweed" deleted

21.5 Uso de virtctl

Además de la estándar de Kubernetes (kubectl), KubeVirt incluye una interfaz de línea de comandos adicional que permite interactuar con el clúster de una forma que obvia ciertas diferencias entre los entornos de virtualización y los usos para los que se diseñó Kubernetes. Por ejemplo, la herramienta virtctl permite gestionar el ciclo de vida de las máquinas virtuales (iniciar, detener, reiniciar, etc.), proporciona acceso a los paneles de control virtuales, permite cargar imágenes de máquinas virtuales e interactuar con construcciones de Kubernetes como servicios, sin utilizar directamente la API o las CRD.

Vamos a descargar la última versión estable de la herramienta virtctl:

$ export VERSION=v1.4.0
$ wget https://github.com/kubevirt/kubevirt/releases/download/$VERSION/virtctl-$VERSION-linux-amd64

Si utiliza una arquitectura diferente o una máquina que no sea Linux, encontrará otras versiones aquí. Debe hacer que este archivo sea ejecutable antes de continuar, y puede ser útil moverlo a una ubicación dentro de $PATH:

$ mv virtctl-$VERSION-linux-amd64 /usr/local/bin/virtctl
$ chmod a+x /usr/local/bin/virtctl

A continuación, puede utilizar la herramienta de línea de comandos virtctl para crear máquinas virtuales. Vamos a replicar nuestra máquina virtual anterior, teniendo en cuenta que estamos canalizando la salida directamente a kubectl apply:

$ virtctl create vm --name virtctl-example --memory=1Gi \
    --volume-containerdisk=src:registry.opensuse.org/home/roxenham/tumbleweed-container-disk/containerfile/cloud-image:latest \
    --cloud-init-user-data "I2Nsb3VkLWNvbmZpZwpkaXNhYmxlX3Jvb3Q6IGZhbHNlCnNzaF9wd2F1dGg6IFRydWUKdXNlcnM6CiAgLSBkZWZhdWx0CiAgLSBuYW1lOiBzdXNlCiAgICBncm91cHM6IHN1ZG8KICAgIHNoZWxsOiAvYmluL2Jhc2gKICAgIHN1ZG86ICBBTEw9KEFMTCkgTk9QQVNTV0Q6QUxMCiAgICBsb2NrX3Bhc3N3ZDogRmFsc2UKICAgIHBsYWluX3RleHRfcGFzc3dkOiAnc3VzZScK" | kubectl apply -f -

Esto debería mostrar la máquina virtual en ejecución (esta vez debería iniciarse mucho más rápido, ya que la imagen del contenedor estará almacenada en caché):

$ kubectl get vmi
NAME              AGE   PHASE     IP           NODENAME               READY
virtctl-example   52s   Running   10.42.2.29   node3.edge.rdo.wales   True

Ahora, podemos usar virtctl para conectarnos directamente a la máquina virtual:

$ virtctl ssh suse@virtctl-example
(password is "suse" - Ctrl-D to exit)

Se pueden utilizar muchos otros comandos con virtctl. Por ejemplo, virtctl console permite acceder al panel de control serie si la red no funciona, y puede utilizar virtctl guestosinfo para obtener información completa sobre el sistema operativo, siempre que el invitado tenga instalado y en ejecución qemu-guest-agent.

Por último, hagamos una pausa y reiniciemos la máquina virtual:

$ virtctl pause vm virtctl-example
VMI virtctl-example was scheduled to pause

Verá que el objeto VirtualMachine aparece como Paused (En pausa) y el objeto VirtualMachineInstance aparece como Running (En ejecución), pero como READY=False:

$ kubectl get vm
NAME              AGE     STATUS   READY
virtctl-example   8m14s   Paused   False

$ kubectl get vmi
NAME              AGE     PHASE     IP           NODENAME               READY
virtctl-example   8m15s   Running   10.42.2.29   node3.edge.rdo.wales   False

También comprobará que ya no puede conectarse a la máquina virtual:

$ virtctl ssh suse@virtctl-example
can't access VMI virtctl-example: Operation cannot be fulfilled on virtualmachineinstance.kubevirt.io "virtctl-example": VMI is paused

Reiniciemos la máquina virtual y volvamos a intentarlo:

$ virtctl unpause vm virtctl-example
VMI virtctl-example was scheduled to unpause

Ahora deberíamos poder restablecer la conexión:

$ virtctl ssh suse@virtctl-example
suse@vmi/virtctl-example.default's password:
suse@virtctl-example:~> exit
logout

Por último, eliminemos la máquina virtual:

$ kubectl delete vm/virtctl-example
virtualmachine.kubevirt.io "virtctl-example" deleted

21.6 Conexión de redes sencilla con Ingress

En esta sección, se explica cómo exponer máquinas virtuales como servicios estándar de Kubernetes y cómo hacerlas disponibles mediante el servicio Ingress de Kubernetes; por ejemplo, NGINX con RKE2 o Traefik con K3s. En este documento se entiende que estos componentes ya están configurados adecuadamente y que dispone de un puntero DNS adecuado (por ejemplo, un comodín) que dirija a los nodos de su servidor de Kubernetes o a su IP virtual de Ingress para que Ingress se resuelva adecuadamente.

Nota
Nota

En SUSE Edge 3.1 y versiones posteriores, si utiliza K3s en una configuración de nodos con varios servidores, es posible que haya tenido que configurar una IP virtual basada en MetalLB para Ingress. Esto no es necesario para RKE2.

En el entorno de ejemplo, se despliega otra máquina virtual Tumbleweed de openSUSE, se usa cloud-init para instalar NGINX como servidor Web sencillo en el momento del arranque y se configura un mensaje sencillo, que se envía para verificar que funciona según lo esperado cuando se realiza una llamada. Para ver cómo se hace, use el comando base64 -d en la sección cloud-init del siguiente ejemplo.

Vamos a crear esta máquina virtual:

$ kubectl apply -f - <<EOF
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: ingress-example
  namespace: default
spec:
  runStrategy: Always
  template:
    metadata:
      labels:
        app: nginx
    spec:
      domain:
        devices: {}
        machine:
          type: q35
        memory:
          guest: 2Gi
        resources: {}
      volumes:
      - containerDisk:
          image: registry.opensuse.org/home/roxenham/tumbleweed-container-disk/containerfile/cloud-image:latest
        name: tumbleweed-containerdisk-0
      - cloudInitNoCloud:
          userDataBase64: I2Nsb3VkLWNvbmZpZwpkaXNhYmxlX3Jvb3Q6IGZhbHNlCnNzaF9wd2F1dGg6IFRydWUKdXNlcnM6CiAgLSBkZWZhdWx0CiAgLSBuYW1lOiBzdXNlCiAgICBncm91cHM6IHN1ZG8KICAgIHNoZWxsOiAvYmluL2Jhc2gKICAgIHN1ZG86ICBBTEw9KEFMTCkgTk9QQVNTV0Q6QUxMCiAgICBsb2NrX3Bhc3N3ZDogRmFsc2UKICAgIHBsYWluX3RleHRfcGFzc3dkOiAnc3VzZScKcnVuY21kOgogIC0genlwcGVyIGluIC15IG5naW54CiAgLSBzeXN0ZW1jdGwgZW5hYmxlIC0tbm93IG5naW54CiAgLSBlY2hvICJJdCB3b3JrcyEiID4gL3Nydi93d3cvaHRkb2NzL2luZGV4Lmh0bQo=
        name: cloudinitdisk
EOF

Cuando esta máquina virtual se haya iniciado correctamente, se podrá usar el comando virtctl para exponer la instancia VirtualMachineInstance con el puerto externo 8080 y el puerto de destino 80 (en el que NGINX escucha por defecto). Aquí, utilizamos el comando virtctl, ya que entiende la asignación entre el objeto de máquina virtual y el pod. Esto crea un nuevo servicio:

$ virtctl expose vmi ingress-example --port=8080 --target-port=80 --name=ingress-example
Service ingress-example successfully exposed for vmi ingress-example

A continuación, se crea automáticamente el servicio adecuado:

$ kubectl get svc/ingress-example
NAME              TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                         AGE
ingress-example   ClusterIP      10.43.217.19    <none>            8080/TCP                        9s

Ahora, si utiliza kubectl create ingress, puede crear un objeto Ingress que apunte a este servicio. Adapte la URL (conocida como "host" en el objeto ingress) aquí para que coincida con su configuración de DNS y asegúrese de que apunta al puerto 8080:

$ kubectl create ingress ingress-example --rule=ingress-example.suse.local/=ingress-example:8080

Con el servidor DNS configurado correctamente, debería poder ejecutar el comando curl en la URL de inmediato:

$ curl ingress-example.suse.local
It works!

Para limpiar, eliminaremos esta máquina virtual y sus recursos de servicio y de Ingress:

$ kubectl delete vm/ingress-example svc/ingress-example ingress/ingress-example
virtualmachine.kubevirt.io "ingress-example" deleted
service "ingress-example" deleted
ingress.networking.k8s.io "ingress-example" deleted

21.7 Uso de la extensión de interfaz de usuario de Rancher

SUSE Edge Virtualization proporciona una extensión de interfaz de usuario para Rancher Manager, lo que permite la gestión básica de máquinas virtuales mediante la interfaz de usuario del panel de control de Rancher.

21.7.1 Instalación

Consulte la sección sobre extensiones de panel de control de Rancher (Capítulo 6, Extensiones de panel de control de Rancher) para obtener instrucciones de instalación.

21.7.2 Uso de la extensión de panel de control KubeVirt de Rancher

La extensión introduce una nueva sección KubeVirt en Cluster Explorer. Esta sección se añade a cualquier clúster gestionado que tenga instalado KubeVirt.

La extensión permite interactuar directamente con los recursos de la máquina virtual de KubeVirt para gestionar el ciclo de vida de las máquinas virtuales.

21.7.2.1 Creación de una máquina virtual

  1. En el panel de navegación izquierdo, diríjase a Cluster Explorer (Explorador de clústeres) haciendo clic en el clúster gestionado habilitado para KubeVirt.

  2. Diríjase a la página KubeVirt > Virtual Machines (KubeVirt > Máquinas virtuales) y haga clic en Create from YAML (Crear desde YAML) en la parte superior derecha de la pantalla.

  3. Rellene o pegue una definición de máquina virtual y pulse Create (Crear). Use la definición de máquina virtual de la sección Despliegue de máquinas virtuales como referencia.

página de máquinas virtuales

21.7.2.2 Acciones de la máquina virtual

Puede utilizar el menú de acciones al que se accede desde la lista desplegable situada a la derecha de cada máquina virtual para iniciar, detener, pausar o hacer un reinicio suave. También puede usar las acciones de grupo de la parte superior de la lista seleccionando las máquinas virtuales en las que desea realizar la acción.

Estas acciones pueden afectar a la estrategia de ejecución de la máquina virtual. Consulte la tabla en la documentación de KubeVirt para obtener más detalles.

21.7.2.3 Acceso al panel de control de la máquina virtual

La lista "Virtual Machines" (Máquinas virtuales) proporciona una lista desplegable Console (Panel de control) que permite conectarse a la máquina mediante VNC o un panel de control serie. Esta acción solo está disponible para máquinas en ejecución.

En algunos casos, para poder acceder al panel de control en una máquina virtual recién iniciada se debe esperar un poco.

interfaz del panel de control de vnc

21.8 Instalación con Edge Image Builder

SUSE Edge usa Capítulo 11, Edge Image Builder para personalizar las imágenes del sistema operativo SUSE Linux Micro base. Siga las instrucciones de la Sección 27.9, “Instalación de KubeVirt y CDI” para realizar una instalación en un entorno aislado tanto de KubeVirt como de CDI sobre clústeres de Kubernetes aprovisionados por EIB.

22 System Upgrade Controller

Consulte la documentación de System Upgrade Controller.

System Upgrade Controller (SUC) proporciona un controlador de actualización de uso general y nativo de Kubernetes (para nodos). Introduce una nueva CRD, llamada "plan", para definir todas sus políticas y requisitos de actualización. Un plan es una intención pendiente de mutar nodos en su clúster.

22.1 ¿Cómo se usa System Upgrade Controller en SUSE Edge?

SUSE Edge usa SUC para facilitar diversas operaciones de "día 2" relacionadas con las actualizaciones de la versión del sistema operativo y Kubernetes en los clústeres de gestión y descendentes.

Las operaciones de "día 2" se definen mediante planes de SUC. Según esos planes, SUC despliega las cargas de trabajo en cada nodo para ejecutar la operación correspondiente de "día 2".

SUC también se utiliza en Capítulo 23, Upgrade Controller. Para obtener más información sobre las diferencias clave entre SUC y Upgrade Controller, consulte la Sección 23.2, “Diferencias entre Upgrade Controller y System Upgrade Controller”.

22.2 Instalación de System Upgrade Controller

Importante
Importante

A partir de la versión 2.10.0 de Rancher, System Upgrade Controller se instala automáticamente.

Siga los pasos siguientes solo si su entorno no está gestionado por Rancher, o si su versión de Rancher es anterior a la 2.10.0.

Se recomienda instalar SUC mediante Fleet (Capítulo 8, Fleet), situado en el repositorio suse-edge/fleet-examples.

Nota
Nota

Los recursos ofrecidos por el repositorio suse-edge/fleet-examples deben utilizarse siempre desde una versión válida de fleet-examples. Para determinar qué versión debe utilizar, consulte las Notas de la versión (Sección 52.1, “Resumen”).

Si no puede utilizar Fleet para la instalación de SUC, puede instalarlo mediante el repositorio de charts de Helm de Rancher o incorporar el chart de Helm de Rancher en su propio flujo de trabajo de GitOps de terceros.

En esta sección se trata lo siguiente:

22.2.1 Instalación de System Upgrade Controller con Fleet

Hay dos posibles recursos que se pueden usar para desplegar SUC mediante Fleet:

22.2.1.1 Instalación de System Upgrade Controller - GitRepo

Nota
Nota

Este proceso también se puede realizar a través de la interfaz de usuario de Rancher, si está disponible. Para obtener más información, consulte Accessing Fleet in the Rancher UI (Acceso a Fleet en la interfaz de Rancher).

En el clúster de gestión:

  1. Determine en qué clústeres desea desplegar SUC. Para ello, despliegue un recurso GitRepo de SUC en el espacio de trabajo correcto de Fleet de su clúster de gestión. De forma predeterminada, Fleet tiene dos espacios de trabajo:

    • fleet-local: para recursos que deben desplegarse en el clúster de gestión.

    • fleet-default: para recursos que deben desplegarse en clústeres descendentes.

      Para obtener más información sobre los espacios de trabajo de Fleet, consulte la documentación original.

  2. Despliegue el recurso GitRepo:

    • Para desplegar SUC en el clúster de gestión:

      kubectl apply -n fleet-local -f - <<EOF
      apiVersion: fleet.cattle.io/v1alpha1
      kind: GitRepo
      metadata:
        name: system-upgrade-controller
      spec:
        revision: release-3.3.0
        paths:
        - fleets/day2/system-upgrade-controller
        repo: https://github.com/suse-edge/fleet-examples.git
      EOF
    • Para desplegar SUC en los clústeres descendentes:

      Nota
      Nota

      Antes de desplegar el recurso que se indica a continuación, debe proporcionar una configuración válida para targets, de modo que Fleet sepa en qué clústeres descendentes debe desplegar su recurso. Para obtener más información sobre cómo realizar la asignación a clústeres descendentes, consulte Mapping to Downstream Clusters (Asignación a clústeres descendentes).

      kubectl apply -n fleet-default -f - <<EOF
      apiVersion: fleet.cattle.io/v1alpha1
      kind: GitRepo
      metadata:
        name: system-upgrade-controller
      spec:
        revision: release-3.3.0
        paths:
        - fleets/day2/system-upgrade-controller
        repo: https://github.com/suse-edge/fleet-examples.git
        targets:
        - clusterSelector: CHANGEME
        # Example matching all clusters:
        # targets:
        # - clusterSelector: {}
      EOF
  3. Compruebe que el recurso GitRepo se ha desplegado:

    # Namespace will vary based on where you want to deploy SUC
    kubectl get gitrepo system-upgrade-controller -n <fleet-local/fleet-default>
    
    NAME                        REPO                                              COMMIT          BUNDLEDEPLOYMENTS-READY   STATUS
    system-upgrade-controller   https://github.com/suse-edge/fleet-examples.git   release-3.3.0   1/1
  4. Compruebe que System Upgrade Controller se ha desplegado:

    kubectl get deployment system-upgrade-controller -n cattle-system
    NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
    system-upgrade-controller   1/1     1            1           2m20s

22.2.1.2 Instalación de System Upgrade Controller - Bundle

Esta sección muestra cómo crear y desplegar un recurso Bundle a partir de una configuración estándar de Fleet utilizando fleet-cli.

  1. En un equipo con acceso de red, descargue fleet-cli:

    Nota
    Nota

    Asegúrese de que la versión de fleet-cli que descargue coincida con la versión de Fleet que se ha desplegado en su clúster.

    • Para usuarios de Mac, hay una versión propia de fleet-cli.

    • Para usuarios de Linux y Windows, los binarios son recursos distintos para cada versión de Fleet.

      • Linux AMD:

        curl -L -o fleet-cli https://github.com/rancher/fleet/releases/download/v0.12.2/fleet-linux-amd64
      • Linux ARM:

        curl -L -o fleet-cli https://github.com/rancher/fleet/releases/download/v0.12.2/fleet-linux-arm64
  2. Permita que fleet-cli se pueda ejecutar:

    chmod +x fleet-cli
  3. Clone la versión de suse-edge/fleet-examples que desee usar:

    git clone -b release-3.3.0 https://github.com/suse-edge/fleet-examples.git
  4. Diríjase a la instancia de Fleet de SUC, situada en el repositorio fleet-examples:

    cd fleet-examples/fleets/day2/system-upgrade-controller
  5. Determine en qué clústeres desea desplegar SUC. Para ello, despliegue el Bundle de SUC en el espacio de trabajo correcto de Fleet dentro de su clúster de gestión. De forma predeterminada, Fleet tiene dos espacios de trabajo:

    • fleet-local: para recursos que deben desplegarse en el clúster de gestión.

    • fleet-default: para recursos que deben desplegarse en clústeres descendentes.

      Para obtener más información sobre los espacios de trabajo de Fleet, consulte la documentación original.

  6. Si tiene intención de desplegar SUC solo en clústeres descendentes, cree un archivo targets.yaml que coincida con los clústeres específicos:

    cat > targets.yaml <<EOF
    targets:
    - clusterSelector: CHANGEME
    EOF

    Para obtener información sobre cómo realizar la asignación a clústeres descendentes, consulte Mapping to Downstream Clusters (Asignación a clústeres descendentes).

  7. Cree el Bundle:

    Nota
    Nota

    Asegúrese de que no ha descargado fleet-cli en el directorio fleet-examples/fleets/day2/system-upgrade-controller, ya que, si fuera así, se empaquetaría con el Bundle, lo cual no es recomendable.

    • Para desplegar SUC en su clúster de gestión, ejecute:

      fleet-cli apply --compress -n fleet-local -o - system-upgrade-controller . > system-upgrade-controller-bundle.yaml
    • Para desplegar SUC en sus clústeres descendentes, ejecute:

      fleet-cli apply --compress --targets-file=targets.yaml -n fleet-default -o - system-upgrade-controller . > system-upgrade-controller-bundle.yaml

      Para obtener más información sobre este proceso, consulte la sección Convert a Helm Chart into a Bundle (Conversión de un chart de Helm en un Bundle).

      Para obtener más información sobre el comando fleet-cli apply, consulte fleet apply.

  8. Transfiera el Bundle system-upgrade-controller-bundle.yaml al equipo del clúster de gestión:

    scp system-upgrade-controller-bundle.yaml <machine-address>:<filesystem-path>
  9. En el clúster de gestión, despliegue el Bundle system-upgrade-controller-bundle.yaml:

    kubectl apply -f system-upgrade-controller-bundle.yaml
  10. En el clúster de gestión, compruebe que el Bundle está desplegado:

    # Namespace will vary based on where you want to deploy SUC
    kubectl get bundle system-upgrade-controller -n <fleet-local/fleet-default>
    
    NAME                        BUNDLEDEPLOYMENTS-READY   STATUS
    system-upgrade-controller   1/1
  11. Según el espacio de trabajo de Fleet en el que haya desplegado su Bundle, diríjase al clúster y compruebe que SUC se ha desplegado:

    Nota
    Nota

    SUC siempre se despliega en el espacio de nombres cattle-system.

    kubectl get deployment system-upgrade-controller -n cattle-system
    NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
    system-upgrade-controller   1/1     1            1           111s

22.2.2 Instalación de System Upgrade Controller con Helm

  1. Añada el repositorio de charts de Rancher:

    helm repo add rancher-charts https://charts.rancher.io/
  2. Despliegue el chart de SUC:

    helm install system-upgrade-controller rancher-charts/system-upgrade-controller --version 106.0.0 --set global.cattle.psp.enabled=false -n cattle-system --create-namespace

    Esto instalará la versión 0.15.2 de SUC, que es la que necesita la plataforma Edge 3.3.1.

  3. Compruebe que SUC se ha desplegado:

    kubectl get deployment system-upgrade-controller -n cattle-system
    NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
    system-upgrade-controller   1/1     1            1           37s

22.3 Supervisión de planes de System Upgrade Controller

Los planes de SUC se pueden consultar de las siguientes maneras:

Importante
Importante

Los pods desplegados para los planes de SUC se mantienen activos 15 minutos tras una ejecución correcta. Después, son eliminados por el trabajo correspondiente que los creó. Para tener acceso a los registros del pod después de este periodo de tiempo, debe habilitar el registro para su clúster. Para obtener información sobre cómo hacerlo en Rancher, consulte Rancher Integration with Logging Services (Integración de Rancher con servicios de registro).

22.3.1 Supervisión de planes de System Upgrade Controller - Interfaz de usuario de Rancher

Para comprobar los registros del pod para el plan de SUC específico:

  1. En la esquina superior izquierda, ☰ → <nombre-de-su-clúster>.

  2. Seleccione Workloads → Pods (Cargas de trabajo > Pods).

  3. Seleccione el menú desplegable Only User Namespaces (Solo espacios de nombres de usuario) y añada el espacio de nombres cattle-system.

  4. En la barra de filtro Pod, escriba el nombre de su pod del plan de SUC. El nombre tendrá el siguiente formato: apply-<nombre_plan>-on-<nombre_nodo>.

    Nota
    Nota

    Puede haber pods con los estados Completed (Completado) y Unknown (Desconocido) para un plan de SUC específico. Esto está previsto debido a la naturaleza de algunas de las actualizaciones.

  5. Seleccione el pod cuyos registros desea revisar y vaya a ⋮ → View Logs (⋮ > Ver registros).

22.3.2 Supervisión de planes de System Upgrade Controller - Manual

Nota
Nota

Los pasos siguientes dan por supuesto que kubectl se ha configurado para conectarse al clúster en el que se han desplegado los planes de SUC.

  1. Muestre los planes de SUC desplegados:

    kubectl get plans -n cattle-system
  2. Obtenga el pod para el plan de SUC:

    kubectl get pods -l upgrade.cattle.io/plan=<plan_name> -n cattle-system
    Nota
    Nota

    Puede haber pods con los estados Completed (Completado) y Unknown (Desconocido) para un plan de SUC específico. Esto está previsto debido a la naturaleza de algunas de las actualizaciones.

  3. Obtenga los registros del pod:

    kubectl logs <pod_name> -n cattle-system

23 Upgrade Controller

Upgrade Controller es un controlador de Kubernetes capaz de realizar actualizaciones en los siguientes componentes de la plataforma SUSE Edge:

  • Sistema operativo (SUSE Linux Micro)

  • Kubernetes (K3s y RKE2)

  • Componentes adicionales (Rancher, Elemental, SUSE Security, etc.)

Upgrade Controller optimiza el proceso de actualización de esto componentes encapsulando sus complejidades en un único recurso orientado al usuario que sirve como activador de la actualización. Los usuarios solo tienen que configurar este recurso y Upgrade Controller se encarga del resto.

Nota
Nota

Upgrade Controller actualmente solo admite actualizaciones de la plataforma SUSE Edge para clústeres de gestión que no estén en entornos aislados. Consulte la Sección 23.7, “Limitaciones conocidas” para obtener más información.

23.1 ¿Cómo se usa Upgrade Controller en SUSE Edge?

Upgrade Controller es esencial para automatizar las operaciones de "día 2" (que antes eran manuales) necesarias para actualizar los clústeres de gestión desde una versión de SUSE Edge a la siguiente.

Para lograr esta automatización, Upgrade Controller usa herramientas como System Upgrade Controller (Capítulo 22, System Upgrade Controller) y Helm Controller.

Para obtener más detalles sobre cómo funciona Upgrade Controller, consulte la Sección 23.4, “¿Cómo funciona Upgrade Controller?”.

Para ver las limitaciones de Upgrade Controller, consulte la Sección 23.7, “Limitaciones conocidas”.

Para ver las diferencias entre Upgrade Controller y System Upgrade Controller, consulte la Sección 23.2, “Diferencias entre Upgrade Controller y System Upgrade Controller”.

23.2 Diferencias entre Upgrade Controller y System Upgrade Controller

System Upgrade Controller (SUC) (Capítulo 22, System Upgrade Controller) es una herramienta de uso general que propaga instrucciones de actualización a nodos específicos de Kubernetes.

Aunque admite algunas operaciones de "día 2" para la plataforma SUSE Edge, no las cubre todas. Además, incluso en el caso de las operaciones admitidas, los usuarios tienen que configurar, mantener y desplegar manualmente múltiples planes de SUC, un proceso propenso a errores que puede dar lugar a problemas inesperados.

Esto llevó a la necesidad de una herramienta que automatizara y resumiera la complejidad de gestionar diversas operaciones de "día 2" para la plataforma SUSE Edge. Así, se desarrolló Upgrade Controller, que simplifica el proceso de actualización al introducir un único recurso orientado al usuario que se encarga de la actualización. Los usuarios solo tienen que gestionar este recurso y Upgrade Controller se encarga del resto.

23.3 Instalación de Upgrade Controller

23.3.1 Requisitos previos

23.3.2 Pasos

  1. Instale el chart de Helm de Upgrade Controller en el clúster de gestión:

    helm install upgrade-controller oci://registry.suse.com/edge/charts/upgrade-controller --version 303.0.1+up0.1.1 --create-namespace --namespace upgrade-controller-system
  2. Compruebe que Upgrade Controller se ha desplegado:

    kubectl get deployment -n upgrade-controller-system
  3. Compruebe el pod de Upgrade Controller:

    kubectl get pods -n upgrade-controller-system
  4. Compruebe los registros del pod de Upgrade Controller:

    kubectl logs <pod_name> -n upgrade-controller-system

23.4 ¿Cómo funciona Upgrade Controller?

Para actualizar la versión de Edge, Upgrade Controller introduce dos nuevos recursos personalizados de Kubernetes:

  • UpgradePlan (Sección 23.5.1, “UpgradePlan”): creado por el usuario; contiene configuraciones relacionadas con la actualización de una versión de Edge.

  • ReleaseManifest (Sección 23.5.2, “ReleaseManifest”): creado por Upgrade Controller; contiene las versiones de los componentes específicas de una versión concreta de Edge. Este archivo no debe ser editado por los usuarios.

Upgrade Controller crea un recurso ReleaseManifest que contiene los datos de los componentes de la versión de Edge especificada por el usuario en la propiedad releaseVersion del recurso UpgradePlan.

Con los datos de los componentes de ReleaseManifest, Upgrade Controller actualiza los componentes de la versión de Edge en el orden siguiente:

Nota
Nota

Durante el proceso de actualización, Upgrade Controller envía continuamente información sobre la actualización al recurso UpgradePlan creado. Para obtener más información sobre cómo realizar un seguimiento del proceso de actualización, consulte la sección correspondiente (Sección 23.6, “Seguimiento del proceso de actualización”).

23.4.1 Actualización del sistema operativo

Para actualizar el sistema operativo, Upgrade Controller crea planes de SUC (Capítulo 22, System Upgrade Controller) que siguen este formato de nombre:

  • Para los planes de SUC relacionados con actualizaciones del SO del nodo de plano de control: control-plane-<nombre-so>-<versión-so>-<sufijo>.

  • Para los planes de SUC relacionados con actualizaciones del SO del nodo de trabajador: workers-<nombre-so>-<versión-so>-<sufijo>.

Basándose en estos planes, SUC crea cargas de trabajo en cada nodo del clúster que realizan la actualización real del sistema operativo.

Dependiendo del recurso ReleaseManifest, la actualización del sistema operativo puede incluir:

  • Solo actualizaciones de paquetes: para casos en los que la versión del sistema operativo no cambie entre las versiones de Edge.

  • Migración completa del sistema operativo: para casos en los que la versión del sistema operativo cambie entre versiones de Edge.

La actualización se ejecuta nodo a nodo, comenzando por los nodos de plano de control. Solo cuando finalice la actualización del nodo de plano de control, se empezarán a actualizar los nodos de trabajador.

Nota
Nota

Upgrade Controller configura los planes de SUC del sistema operativo para realizar un drenaje de los nodos del clúster si este tiene más de un nodo del tipo especificado.

En los clústeres en los que hay más de un nodo de plano de control y hay un único nodo de trabajador, el drenaje se realizará solo para los nodos de plano de control, y viceversa.

Para obtener información sobre cómo inhabilitar el drenaje de nodos, consulte la sección sobre UpgradePlan (Sección 23.5.1, “UpgradePlan”).

23.4.2 Actualización de Kubernetes

Para actualizar la distribución de Kubernetes de un clúster, Upgrade Controller crea planes de SUC (Capítulo 22, System Upgrade Controller) con el siguiente formato de nombre:

  • Para planes de SUC relacionados con actualizaciones de Kubernetes en nodos de plano de control: control-plane-<versión-k8s>-<sufijo>.

  • Para planes de SUC relacionados con actualizaciones de Kubernetes en nodos de trabajador: workers-<versión-k8s>-<sufijo>.

Basándose en estos planes, SUC crea cargas de trabajo en cada nodo del clúster que realizan la actualización real de Kubernetes.

La actualización de Kubernetes se realizará nodo a nodo, comenzando por los nodos de plano de control. Solo cuando finalice la actualización de los nodos de plano de control se empezarán a actualizar los nodos de trabajador.

Nota
Nota

Upgrade Controller configura los planes de SUC de Kubernetes para realizar un drenaje de los nodos del clúster si este tiene más de un nodo del tipo especificado.

En los clústeres en los que hay más de un nodo de plano de control y hay un único nodo de trabajador, el drenaje se realizará solo para los nodos de plano de control, y viceversa.

Para obtener información sobre cómo inhabilitar el drenaje de nodos, consulte la Sección 23.5.1, “UpgradePlan”.

23.4.3 Actualización de componentes adicionales

Actualmente, todos los componentes adicionales se instalan mediante charts de Helm. Para obtener una lista completa de los componentes de una versión específica, consulte las Notas de la versión (Sección 52.1, “Resumen”).

Para los charts de Helm desplegados a través de EIB (Capítulo 11, Edge Image Builder), Upgrade Controller actualiza la CR de HelmChart existente de cada componente.

Para los charts de Helm desplegados fuera de EIB, Upgrade Controller crea un recurso HelmChart para cada componente.

Tras la creación/actualización del recurso HelmChart, Upgrade Controller se basa en helm-controller para detectar este cambio y proceder con la actualización real del componente.

Los charts se actualizan secuencialmente según su orden en ReleaseManifest. También se pueden pasar valores adicionales a través de UpgradePlan. Si la versión de un chart permanece sin cambios en la nueva versión de SUSE Edge, no se actualizará. Para obtener más información al respecto, consulte la Sección 23.5.1, “UpgradePlan”.

23.5 Extensiones de la API de Kubernetes

Extensiones a la API de Kubernetes introducidas por Upgrade Controller.

23.5.1 UpgradePlan

Upgrade Controller introduce un nuevo recurso personalizado de Kubernetes llamado UpgradePlan.

UpgradePlan sirve como mecanismo de instrucción para Upgrade Controller y admite las siguientes configuraciones:

  • releaseVersion: versión de Edge a la que se va a actualizar el clúster. La versión debe seguir el sistema semántico de versiones y debe obtenerse de las Notas de la versión (Sección 52.1, “Resumen”).

  • disableDrain: (opcional) indica a Upgrade Controller si debe inhabilitar el drenaje de nodos. Resulta útil cuando se tienen cargas de trabajo con presupuestos de interrupción.

    • Ejemplo de inhabilitación del drenaje del nodo de plano de control:

      spec:
        disableDrain:
          controlPlane: true
    • Ejemplo de inhabilitación del drenaje del nodo de plano de control y del nodo de trabajador:

      spec:
        disableDrain:
          controlPlane: true
          worker: true
  • helm: (opcional) especifica valores adicionales para los componentes instalados a través de Helm.

    Aviso
    Aviso

    Se recomienda utilizar este campo únicamente para valores que sean críticos para las actualizaciones. Las actualizaciones estándares de valores de chart deben realizarse después de que los charts correspondientes se hayan actualizado a la siguiente versión.

    • Ejemplo:

      spec:
        helm:
        - chart: foo
          values:
            bar: baz

23.5.2 ReleaseManifest

Upgrade Controller introduce un nuevo recurso personalizado de Kubernetes llamado ReleaseManifest.

El recurso ReleaseManifest lo crea Upgrade Controller y contiene datos de componentes para una versión específica de Edge. Esto significa que cada actualización de la versión de Edge estará representada por un recurso ReleaseManifest diferente.

Aviso
Aviso

El recurso ReleaseManifest siempre debe crearlo Upgrade Controller.

No es recomendable crear o editar manualmente los recursos ReleaseManifest. Si un usuario decide hacerlo, será bajo su propia responsabilidad.

Estos son algunos de los componentes que incluye ReleaseManifest:

  • Datos del sistema operativo: versión, arquitecturas compatibles, datos adicionales sobre actualizaciones, etc.

  • Datos de distribución de Kubernetes: versiones admitidas de RKE2/K3s

  • Datos de componentes adicionales: datos del chart de Helm de SUSE (ubicación, versión, nombre, etc.)

Para ver un ejemplo de recurso ReleaseManifest, consulte la documentación original. Tenga en cuenta que se trata solo de un ejemplo, no de un recurso ReleaseManifest válido.

23.6 Seguimiento del proceso de actualización

Esta sección sirve como medio para realizar un seguimiento y depurar el proceso de actualización que inicia Upgrade Controller después de que el usuario haya creado un recurso UpgradePlan.

23.6.1 General

La información general sobre el estado del proceso de actualización se puede consultar en las condiciones de estado del recurso UpgradePlan.

El estado del recurso UpgradePlan se puede consultar de la siguiente manera:

kubectl get upgradeplan <upgradeplan_name> -n upgrade-controller-system -o yaml

Ejemplo de UpgradePlan en ejecución:

apiVersion: lifecycle.suse.com/v1alpha1
kind: UpgradePlan
metadata:
  name: upgrade-plan-mgmt
  namespace: upgrade-controller-system
spec:
  releaseVersion: 3.3.1
status:
  conditions:
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: Control plane nodes are being upgraded
    reason: InProgress
    status: "False"
    type: OSUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: Kubernetes upgrade is not yet started
    reason: Pending
    status: Unknown
    type: KubernetesUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: Rancher upgrade is not yet started
    reason: Pending
    status: Unknown
    type: RancherUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: Longhorn upgrade is not yet started
    reason: Pending
    status: Unknown
    type: LonghornUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: MetalLB upgrade is not yet started
    reason: Pending
    status: Unknown
    type: MetalLBUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: CDI upgrade is not yet started
    reason: Pending
    status: Unknown
    type: CDIUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: KubeVirt upgrade is not yet started
    reason: Pending
    status: Unknown
    type: KubeVirtUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: NeuVector upgrade is not yet started
    reason: Pending
    status: Unknown
    type: NeuVectorUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: EndpointCopierOperator upgrade is not yet started
    reason: Pending
    status: Unknown
    type: EndpointCopierOperatorUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: Elemental upgrade is not yet started
    reason: Pending
    status: Unknown
    type: ElementalUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: SRIOV upgrade is not yet started
    reason: Pending
    status: Unknown
    type: SRIOVUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: Akri upgrade is not yet started
    reason: Pending
    status: Unknown
    type: AkriUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: Metal3 upgrade is not yet started
    reason: Pending
    status: Unknown
    type: Metal3Upgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: RancherTurtles upgrade is not yet started
    reason: Pending
    status: Unknown
    type: RancherTurtlesUpgraded
  observedGeneration: 1
  sucNameSuffix: 90315a2b6d

Aquí puede ver todos los componentes para los que Upgrade Controller intentará programar una actualización. Cada condición sigue el siguiente formato:

  • lastTransitionTime: la hora a la que esta condición del componente pasó de un estado a otro por última vez.

  • message: mensaje que indica el estado actual de actualización de la condición específica del componente.

  • reason: el estado actual de actualización de la condición específica del componente. Los valores posibles para reasons son:

    • Succeeded: la actualización del componente específico se ha realizado correctamente.

    • Failed: la actualización del componente específico ha fallado.

    • InProgress: la actualización del componente específico está en curso.

    • Pending: la actualización del componente específico aún no se ha programado.

    • Skipped: el componente específico no se encuentra en el clúster, por lo que se omitirá su actualización.

    • Error: se ha producido un error transitorio en un componente específico.

  • status: el estado de type (tipo) de la condición actual. Puede ser True (Verdadero), False (Falso) o Unknown (Desconocido).

  • type: indicador del componente actualmente actualizado.

Upgrade Controller crea planes de SUC para las condiciones de componentes de tipo OSUpgraded y KubernetesUpgraded. Para realizar un seguimiento más detallado de los planes de SUC creados para estos componentes, consulte la Sección 22.3, “Supervisión de planes de System Upgrade Controller”.

Es posible seguir realizando un seguimiento de todos los demás tipos de condiciones de los componentes mediante la visualización de los recursos creados para ellos por helm-controller. Para obtener más información, consulte la Sección 23.6.2, “Helm Controller”.

Un recurso UpgradePlan programado por Upgrade Controller se puede marcar como successful (correcto) si cumple estas condiciones:

  1. No hay condiciones de componentes con el estado Pending o InProgress.

  2. La propiedad lastSuccessfulReleaseVersion apunta a la versión de releaseVersion especificada en la configuración de UpgradePlan. Upgrade Controller añade esta propiedad al estado de UpgradePlan después de que el proceso de actualización se ha completado correctamente.

Ejemplo de UpgradePlan correcto:

apiVersion: lifecycle.suse.com/v1alpha1
kind: UpgradePlan
metadata:
  name: upgrade-plan-mgmt
  namespace: upgrade-controller-system
spec:
  releaseVersion: 3.3.1
status:
  conditions:
  - lastTransitionTime: "2024-10-01T06:26:48Z"
    message: All cluster nodes are upgraded
    reason: Succeeded
    status: "True"
    type: OSUpgraded
  - lastTransitionTime: "2024-10-01T06:26:59Z"
    message: All cluster nodes are upgraded
    reason: Succeeded
    status: "True"
    type: KubernetesUpgraded
  - lastTransitionTime: "2024-10-01T06:27:13Z"
    message: Chart rancher upgrade succeeded
    reason: Succeeded
    status: "True"
    type: RancherUpgraded
  - lastTransitionTime: "2024-10-01T06:27:13Z"
    message: Chart longhorn is not installed
    reason: Skipped
    status: "False"
    type: LonghornUpgraded
  - lastTransitionTime: "2024-10-01T06:27:13Z"
    message: Specified version of chart metallb is already installed
    reason: Skipped
    status: "False"
    type: MetalLBUpgraded
  - lastTransitionTime: "2024-10-01T06:27:13Z"
    message: Chart cdi is not installed
    reason: Skipped
    status: "False"
    type: CDIUpgraded
  - lastTransitionTime: "2024-10-01T06:27:13Z"
    message: Chart kubevirt is not installed
    reason: Skipped
    status: "False"
    type: KubeVirtUpgraded
  - lastTransitionTime: "2024-10-01T06:27:13Z"
    message: Chart neuvector-crd is not installed
    reason: Skipped
    status: "False"
    type: NeuVectorUpgraded
  - lastTransitionTime: "2024-10-01T06:27:14Z"
    message: Specified version of chart endpoint-copier-operator is already installed
    reason: Skipped
    status: "False"
    type: EndpointCopierOperatorUpgraded
  - lastTransitionTime: "2024-10-01T06:27:14Z"
    message: Chart elemental-operator upgrade succeeded
    reason: Succeeded
    status: "True"
    type: ElementalUpgraded
  - lastTransitionTime: "2024-10-01T06:27:15Z"
    message: Chart sriov-crd is not installed
    reason: Skipped
    status: "False"
    type: SRIOVUpgraded
  - lastTransitionTime: "2024-10-01T06:27:16Z"
    message: Chart akri is not installed
    reason: Skipped
    status: "False"
    type: AkriUpgraded
  - lastTransitionTime: "2024-10-01T06:27:19Z"
    message: Chart metal3 is not installed
    reason: Skipped
    status: "False"
    type: Metal3Upgraded
  - lastTransitionTime: "2024-10-01T06:27:27Z"
    message: Chart rancher-turtles is not installed
    reason: Skipped
    status: "False"
    type: RancherTurtlesUpgraded
  lastSuccessfulReleaseVersion: 3.3.1
  observedGeneration: 1
  sucNameSuffix: 90315a2b6d

23.6.2 Helm Controller

Esta sección explica cómo realizar un seguimiento de los recursos creados por helm-controller.

Nota
Nota

En los pasos siguientes se da por supuesto que kubectl se ha configurado para conectarse al clúster en el que se ha desplegado Upgrade Controller.

  1. Localice el recurso HelmChart para el componente específico:

    kubectl get helmcharts -n kube-system
  2. Use el nombre del recurso HelmChart para localizar el pod de actualización que creó helm-controller:

    kubectl get pods -l helmcharts.helm.cattle.io/chart=<helmchart_name> -n kube-system
    
    # Example for Rancher
    kubectl get pods -l helmcharts.helm.cattle.io/chart=rancher -n kube-system
    NAME                         READY   STATUS      RESTARTS   AGE
    helm-install-rancher-tv9wn   0/1     Completed   0          16m
  3. Consulte los registros del pod específico del componente:

    kubectl logs <pod_name> -n kube-system

23.7 Limitaciones conocidas

  • Las actualizaciones de clústeres descendentes aún no se gestionan mediante Upgrade Controller. Para obtener información sobre cómo actualizar clústeres descendentes, consulte el Capítulo 36, Clústeres descendentes.

  • Upgrade Controller espera que cualquier chart de Helm de SUSE Edge adicional que se despliegue a través de EIB (Capítulo 11, Edge Image Builder) tenga su CR de HelmChart desplegada en el espacio de nombres kube-system. Para ello, configure la propiedad installationNamespace en su archivo de definición de EIB. Para obtener más información, consulte la documentación original.

  • Actualmente, Upgrade Controller no tiene forma de determinar la versión actual de Edge que se está ejecutando en el clúster de gestión. Asegúrese de proporcionar una versión de Edge superior a la versión actual que se está ejecutando en el clúster.

  • Actualmente, Upgrade Controller solo admite actualizaciones en entornos no aislados. Aún no es posible realizar actualizaciones en entornos aislados.

24 SUSE Multi-Linux Manager

SUSE Multi-Linux Manager está incluido en SUSE Edge y proporciona automatización y control con el fin de mantener el sistema operativo subyacente SUSE Linux Micro constantemente actualizado en todos los nodos de su despliegue periférico.

Para obtener más información, consulte el Capítulo 4, SUSE Multi-Linux Manager y la documentación de SUSE Multi-Linux Manager.

Parte III Guías prácticas

Guías y prácticas recomendadas

  • 25 MetalLB en K3s (con el modo de capa 2)
  • MetalLB es una implementación de equilibrador de carga para clústeres de Kubernetes en bare metal que utiliza protocolos de enrutamiento estándar.

  • 26 MetalLB delante del servidor de Kubernetes API
  • Esta guía explica cómo usar un servicio MetalLB para exponer la API de RKE2/K3s externamente en un clúster de HA con tres nodos de plano de control. Para lograrlo, se crearán manualmente un servicio de Kubernetes de tipo LoadBalancer y puntos finales. Los puntos finales mantienen las IP de todos los…

  • 27 Despliegues en entornos aislados con Edge Image Builder
  • Esta guía explica cómo desplegar varios componentes de SUSE Edge en entornos completamente aislados en SUSE Linux Micro 6.1 utilizando Edge Image Builder(EIB) (Capítulo 11, Edge Image Builder). De este modo, podrá arrancar en una imagen personalizada lista para arrancar (CRB) creada por EIB y desple…

  • 28 Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi
  • En esta sección se explica cómo generar imágenes actualizadas de SUSE Linux Micro para utilizarlas con Edge Image Builder, con Cluster API (CAPI) + Metal3, o para escribir la imagen de disco directamente en un dispositivo de bloques. Este proceso resulta útil en situaciones en las que es necesario i…

  • 29 Uso de ClusterClass para desplegar clústeres descendentes
  • El aprovisionamiento de clústeres de Kubernetes es una tarea compleja que requiere una gran experiencia a la hora de configurar los componentes del clúster. A medida que las configuraciones se vuelven más complejas, o que las exigencias de los diferentes proveedores introducen numerosas definiciones…

25 MetalLB en K3s (con el modo de capa 2)

MetalLB es una implementación de equilibrador de carga para clústeres de Kubernetes en bare metal que utiliza protocolos de enrutamiento estándar.

En esta guía se explica cómo desplegar MetalLB en el modo de capa 2 (L2).

25.1 Por qué usar este método

MetalLB es una opción conveniente para el equilibrio de carga en clústeres bare metal de Kubernetes por varias razones:

  1. Integración nativa con Kubernetes: MetalLB se integra a la perfección con Kubernetes, lo que facilita el despliegue y la gestión mediante las herramientas y prácticas habituales de Kubernetes.

  2. Compatibilidad bare metal: a diferencia de los equilibradores de carga basados en la nube, MetalLB se ha diseñado específicamente para despliegues locales en las que los sistemas de equilibrio de carga tradicionales podrían no estar disponibles o no ser viables.

  3. Compatibilidad con múltiples protocolos: MetalLB admite el modo de capa 2 y BGP (Border Gateway Protocol, protocolo de gateway de frontera), lo que proporciona flexibilidad para diferentes arquitecturas y requisitos de red.

  4. Alta disponibilidad: dado que distribuye el equilibrio de carga entre varios nodos, MetalLB garantiza una alta disponibilidad y fiabilidad para sus servicios.

  5. Escalabilidad: MetalLB puede manejar despliegues a gran escala, y se va adaptando con su clúster de Kubernetes para satisfacer la demanda creciente.

En el modo de capa 2 (L2), un nodo asume la responsabilidad de anunciar un servicio a la red local. Desde la perspectiva de la red, simplemente parece que esa máquina tiene varias direcciones IP asignadas a su interfaz de red.

La mayor ventaja del modo de capa 2 es su universalidad: funciona en cualquier red Ethernet sin necesidad de hardware especial, ni siquiera de routers sofisticados.

25.2 MetalLB en K3s (con L2)

En este inicio rápido, se utilizará el modo L2. Esto significa que no se necesita equipo de red especial, solo tres IP libres dentro del rango de red.

25.3 Requisitos previos

  • Un clúster K3s donde se vaya a desplegar MetalLB.

Aviso
Aviso

K3S incluye su propio equilibrador de carga de servicios llamado Klipper. Debe inhabilitarlo para ejecutar MetalLB. Para inhabilitar Klipper, hay que instalar K3s mediante el indicador --disable=servicelb.

  • Helm

  • Tres direcciones IP libres dentro del rango de red. En este ejemplo 192.168.122.10-192.168.122.12

Importante
Importante

Debe asegurarse de que esas direcciones IP no están asignadas. En un entorno DHCP esas direcciones no deben formar parte del pool DHCP para evitar dobles asignaciones.

25.4 Despliegue

Utilizaremos el chart de Helm de MetalLB publicado como parte de la solución SUSE Edge:

helm install \
  metallb oci://registry.suse.com/edge/charts/metallb \
  --namespace metallb-system \
  --create-namespace

while ! kubectl wait --for condition=ready -n metallb-system $(kubectl get\
 pods -n metallb-system -l app.kubernetes.io/component=controller -o name)\
 --timeout=10s; do
 sleep 2
done

25.5 Configuración

En este punto, la instalación ya está completa. Ahora hay que configurarla con nuestros valores de ejemplo:

cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: ip-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.122.10/32
  - 192.168.122.11/32
  - 192.168.122.12/32
EOF
cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: ip-pool-l2-adv
  namespace: metallb-system
spec:
  ipAddressPools:
  - ip-pool
EOF

Ahora, está lista para usarse. Es posible personalizar muchas cosas en el modo L2, por ejemplo:

Y mucho más para BGP.

25.5.1 Traefik y MetalLB

Traefik se despliega por defecto con K3s (se puede inhabilitar con --disable=traefik) y se expone por defecto como LoadBalancer (para usarse con Klipper). Sin embargo, como hay que inhabilitar Klipper, el servicio Traefik para Ingress sigue siendo de tipo LoadBalancer. Por lo tanto, en el momento de desplegar MetalLB, la primera IP se asignará automáticamente para Traefik Ingress.

# Before deploying MetalLB
kubectl get svc -n kube-system traefik
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
traefik   LoadBalancer   10.43.44.113   <pending>     80:31093/TCP,443:32095/TCP   28s
# After deploying MetalLB
kubectl get svc -n kube-system traefik
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)                      AGE
traefik   LoadBalancer   10.43.44.113   192.168.122.10   80:31093/TCP,443:32095/TCP   3m10s

Esto se aplicará más tarde en el proceso (Sección 25.6.1, “Ingress con MetalLB”).

25.6 Uso

Vamos a crear un despliegue de ejemplo:

cat <<- EOF | kubectl apply -f -
---
apiVersion: v1
kind: Namespace
metadata:
  name: hello-kubernetes
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: hello-kubernetes
  namespace: hello-kubernetes
  labels:
    app.kubernetes.io/name: hello-kubernetes
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes
  namespace: hello-kubernetes
  labels:
    app.kubernetes.io/name: hello-kubernetes
spec:
  replicas: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: hello-kubernetes
  template:
    metadata:
      labels:
        app.kubernetes.io/name: hello-kubernetes
    spec:
      serviceAccountName: hello-kubernetes
      containers:
        - name: hello-kubernetes
          image: "paulbouwer/hello-kubernetes:1.10"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          env:
          - name: HANDLER_PATH_PREFIX
            value: ""
          - name: RENDER_PATH_PREFIX
            value: ""
          - name: KUBERNETES_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: KUBERNETES_POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: KUBERNETES_NODE_NAME
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
          - name: CONTAINER_IMAGE
            value: "paulbouwer/hello-kubernetes:1.10"
EOF

Y, por último, el servicio:

cat <<- EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: hello-kubernetes
  namespace: hello-kubernetes
  labels:
    app.kubernetes.io/name: hello-kubernetes
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: hello-kubernetes
EOF

Veámoslo en acción:

kubectl get svc -n hello-kubernetes
NAME               TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
hello-kubernetes   LoadBalancer   10.43.127.75   192.168.122.11   80:31461/TCP   8s

curl http://192.168.122.11
<!DOCTYPE html>
<html>
<head>
    <title>Hello Kubernetes!</title>
    <link rel="stylesheet" type="text/css" href="/css/main.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300" >
</head>
<body>

  <div class="main">
    <img src="/images/kubernetes.png"/>
    <div class="content">
      <div id="message">
  Hello world!
</div>
<div id="info">
  <table>
    <tr>
      <th>namespace:</th>
      <td>hello-kubernetes</td>
    </tr>
    <tr>
      <th>pod:</th>
      <td>hello-kubernetes-7c8575c848-2c6ps</td>
    </tr>
    <tr>
      <th>node:</th>
      <td>allinone (Linux 5.14.21-150400.24.46-default)</td>
    </tr>
  </table>
</div>
<div id="footer">
  paulbouwer/hello-kubernetes:1.10 (linux/amd64)
</div>
    </div>
  </div>

</body>
</html>

25.6.1 Ingress con MetalLB

Como Traefik ya sirve como controlador de Ingress, podemos exponer todo el tráfico HTTP/HTTPS a través de un objeto Ingress como:

IP=$(kubectl get svc -n kube-system traefik -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
cat <<- EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-kubernetes-ingress
  namespace: hello-kubernetes
spec:
  rules:
  - host: hellok3s.${IP}.sslip.io
    http:
      paths:
        - path: "/"
          pathType: Prefix
          backend:
            service:
              name: hello-kubernetes
              port:
                name: http
EOF

Y, a continuación:

curl http://hellok3s.${IP}.sslip.io
<!DOCTYPE html>
<html>
<head>
    <title>Hello Kubernetes!</title>
    <link rel="stylesheet" type="text/css" href="/css/main.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300" >
</head>
<body>

  <div class="main">
    <img src="/images/kubernetes.png"/>
    <div class="content">
      <div id="message">
  Hello world!
</div>
<div id="info">
  <table>
    <tr>
      <th>namespace:</th>
      <td>hello-kubernetes</td>
    </tr>
    <tr>
      <th>pod:</th>
      <td>hello-kubernetes-7c8575c848-fvqm2</td>
    </tr>
    <tr>
      <th>node:</th>
      <td>allinone (Linux 5.14.21-150400.24.46-default)</td>
    </tr>
  </table>
</div>
<div id="footer">
  paulbouwer/hello-kubernetes:1.10 (linux/amd64)
</div>
    </div>
  </div>

</body>
</html>

Verifique que MetalLB funciona correctamente:

% arping hellok3s.${IP}.sslip.io

ARPING 192.168.64.210
60 bytes from 92:12:36:00:d3:58 (192.168.64.210): index=0 time=1.169 msec
60 bytes from 92:12:36:00:d3:58 (192.168.64.210): index=1 time=2.992 msec
60 bytes from 92:12:36:00:d3:58 (192.168.64.210): index=2 time=2.884 msec

En el ejemplo anterior, el flujo de tráfico es el siguiente:

  1. hellok3s.${IP}.sslip.io se resuelve en la IP real.

  2. Después, el tráfico se gestiona con el pod metallb-speaker.

  3. metallb-speaker redirige el tráfico al controlador traefik.

  4. Por último, Traefik reenvía la petición al servicio hello-kubernetes.

26 MetalLB delante del servidor de Kubernetes API

Esta guía explica cómo usar un servicio MetalLB para exponer la API de RKE2/K3s externamente en un clúster de HA con tres nodos de plano de control. Para lograrlo, se crearán manualmente un servicio de Kubernetes de tipo LoadBalancer y puntos finales. Los puntos finales mantienen las IP de todos los nodos de plano de control disponibles en el clúster. Para que el punto final esté continuamente sincronizado con los eventos que ocurren en el clúster (añadir/eliminar un nodo o que un nodo se desconecte), se desplegará el Endpoint Copier Operator (Capítulo 20, Endpoint Copier Operator). Este operador supervisa los eventos que ocurren en el punto final kubernetes por defecto y actualiza el que se gestiona automáticamente para mantenerlos sincronizados. Dado que el servicio gestionado es de tipo LoadBalancer, MetalLB le asigna una IP externa (ExternalIP estática. Esta ExternalIP se utilizará para comunicarse con el servidor de API.

26.1 Requisitos previos

  • Tres hosts para desplegar RKE2/K3s encima.

    • Asegúrese de que los hosts tienen nombres distintos.

    • Para realizar pruebas, pueden ser máquinas virtuales.

  • Al menos 2 IP disponibles en la red (una para Traefik/Nginx y otra para el servicio gestionado).

  • Helm

26.2 Instalación de RKE2/K3s

Nota
Nota

Si no desea utilizar un clúster nuevo, omita este paso y continúe con el siguiente.

En primer lugar, se debe reservar una IP libre en la red que se utilizará posteriormente para ExternalIP en el servicio gestionado.

Use SSH para el primer host e instale la distribución deseada en modo de clúster.

Para RKE2:

# Export the free IP mentioned above
export VIP_SERVICE_IP=<ip>

curl -sfL https://get.rke2.io | INSTALL_RKE2_EXEC="server \
 --write-kubeconfig-mode=644 --tls-san=${VIP_SERVICE_IP} \
 --tls-san=https://${VIP_SERVICE_IP}.sslip.io" sh -

systemctl enable rke2-server.service
systemctl start rke2-server.service

# Fetch the cluster token:
RKE2_TOKEN=$(tr -d '\n' < /var/lib/rancher/rke2/server/node-token)

Para K3s:

# Export the free IP mentioned above
export VIP_SERVICE_IP=<ip>
export INSTALL_K3S_SKIP_START=false

curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --cluster-init \
 --disable=servicelb --write-kubeconfig-mode=644 --tls-san=${VIP_SERVICE_IP} \
 --tls-san=https://${VIP_SERVICE_IP}.sslip.io" K3S_TOKEN=foobar sh -
Nota
Nota

Asegúrese de que se proporciona el indicador --disable=servicelb en el comando k3s server.

Importante
Importante

A partir de ahora, los comandos deben ejecutarse en el equipo local.

Para acceder al servidor de API desde el exterior, se utilizará la IP de la máquina virtual RKE2/K3s.

# Replace <node-ip> with the actual IP of the machine
export NODE_IP=<node-ip>
export KUBE_DISTRIBUTION=<k3s/rke2>

scp ${NODE_IP}:/etc/rancher/${KUBE_DISTRIBUTION}/${KUBE_DISTRIBUTION}.yaml ~/.kube/config && sed \
 -i '' "s/127.0.0.1/${NODE_IP}/g" ~/.kube/config && chmod 600 ~/.kube/config

26.3 Configuración de un clúster existente

Nota
Nota

Este paso solo es válido si pretende utilizar un clúster RKE2/K3s existente.

Para usar un clúster existente, deben modificarse los indicadores tls-san. Además, el equilibrador de carga servicelb debe inhabilitarse para K3s.

Para cambiar los indicadores de los servidores RKE2 o K3s, es necesario modificar el archivo /etc/systemd/system/rke2.service o el archivo /etc/systemd/system/k3s.service en todas las máquinas virtuales del clúster, en función de la distribución.

Los indicadores deben insertarse en ExecStart. Por ejemplo:

Para RKE2:

# Replace the <vip-service-ip> with the actual ip
ExecStart=/usr/local/bin/rke2 \
    server \
        '--write-kubeconfig-mode=644' \
        '--tls-san=<vip-service-ip>' \
        '--tls-san=https://<vip-service-ip>.sslip.io' \

Para K3s:

# Replace the <vip-service-ip> with the actual ip
ExecStart=/usr/local/bin/k3s \
    server \
        '--cluster-init' \
        '--write-kubeconfig-mode=644' \
        '--disable=servicelb' \
        '--tls-san=<vip-service-ip>' \
        '--tls-san=https://<vip-service-ip>.sslip.io' \

A continuación, se deben ejecutar los siguientes comandos para cargar las nuevas configuraciones:

systemctl daemon-reload
systemctl restart ${KUBE_DISTRIBUTION}

26.4 Instalación de MetalLB

Para desplegar MetalLB, se puede usar la guía de MetalLB en K3s (Capítulo 25, MetalLB en K3s (con el modo de capa 2)).

NOTA: asegúrese de que las direcciones IP del IPAddressPool ip-pool no se solapan con las direcciones IP previamente seleccionadas para el servicio LoadBalancer.

Cree un IpAddressPool independiente que se utilizará solo para el servicio gestionado.

# Export the VIP_SERVICE_IP on the local machine
# Replace with the actual IP
export VIP_SERVICE_IP=<ip>

cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: kubernetes-vip-ip-pool
  namespace: metallb-system
spec:
  addresses:
  - ${VIP_SERVICE_IP}/32
  serviceAllocation:
    priority: 100
    namespaces:
      - default
EOF
cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: ip-pool-l2-adv
  namespace: metallb-system
spec:
  ipAddressPools:
  - ip-pool
  - kubernetes-vip-ip-pool
EOF

26.5 Instalación de Endpoint Copier Operator

helm install \
endpoint-copier-operator oci://registry.suse.com/edge/charts/endpoint-copier-operator \
--namespace endpoint-copier-operator \
--create-namespace

El comando de arriba desplegará el operador endpoint-copier-operator con dos réplicas. Una será la líder y la otra asumirá el papel de líder si fuera necesario.

Ahora se debe desplegar el servicio kubernetes-vip, que el operador reconciliará, y se creará un punto final con los puertos y la IP configurados.

Para RKE2:

cat <<-EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: kubernetes-vip
  namespace: default
spec:
  ports:
  - name: rke2-api
    port: 9345
    protocol: TCP
    targetPort: 9345
  - name: k8s-api
    port: 6443
    protocol: TCP
    targetPort: 6443
  type: LoadBalancer
EOF

Para K3s:

cat <<-EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: kubernetes-vip
  namespace: default
spec:
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: https
    port: 6443
    protocol: TCP
    targetPort: 6443
  sessionAffinity: None
  type: LoadBalancer
EOF

Verifique que el servicio kubernetes-vip tenga la dirección IP correcta:

kubectl get service kubernetes-vip -n default \
 -o=jsonpath='{.status.loadBalancer.ingress[0].ip}'

Asegúrese de que los recursos de punto final kubernetes-vip y kubernetes del espacio de nombres default dirijan a las mismas IP.

kubectl get endpoints kubernetes kubernetes-vip

Si todo está correcto, lo último que queda por hacer es usar VIP_SERVICE_IP en nuestro Kubeconfig.

sed -i '' "s/${NODE_IP}/${VIP_SERVICE_IP}/g" ~/.kube/config

A partir de ahora, todo kubectl pasará por el servicio kubernetes-vip.

26.6 Adición de nodos de plano de control

Para supervisar todo el proceso, se pueden abrir dos pestañas de terminal más.

Primer terminal:

watch kubectl get nodes

Segundo terminal:

watch kubectl get endpoints

Ahora, ejecute los comandos siguientes en el segundo y el tercer nodo.

Para RKE2:

# Export the VIP_SERVICE_IP in the VM
# Replace with the actual IP
export VIP_SERVICE_IP=<ip>

curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="server" sh -
systemctl enable rke2-server.service


mkdir -p /etc/rancher/rke2/
cat <<EOF > /etc/rancher/rke2/config.yaml
server: https://${VIP_SERVICE_IP}:9345
token: ${RKE2_TOKEN}
EOF

systemctl start rke2-server.service

Para K3s:

# Export the VIP_SERVICE_IP in the VM
# Replace with the actual IP
export VIP_SERVICE_IP=<ip>
export INSTALL_K3S_SKIP_START=false

curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server \
 --server https://${VIP_SERVICE_IP}:6443 --disable=servicelb \
 --write-kubeconfig-mode=644" K3S_TOKEN=foobar sh -

27 Despliegues en entornos aislados con Edge Image Builder

27.1 Introducción

Esta guía explica cómo desplegar varios componentes de SUSE Edge en entornos completamente aislados en SUSE Linux Micro 6.1 utilizando Edge Image Builder(EIB) (Capítulo 11, Edge Image Builder). De este modo, podrá arrancar en una imagen personalizada lista para arrancar (CRB) creada por EIB y desplegar los componentes especificados en un clúster RKE2 o K3s sin conexión a Internet ni pasos manuales. Esta configuración es muy conveniente para los clientes que desean preparar de antemano todos los artefactos necesarios para el despliegue en su imagen del sistema operativo para que estén disponible de inmediato en el arranque.

Muestra una instalación en un entorno aislado de:

Aviso
Aviso

EIB analizará y descargará previamente todas las imágenes a las que se haga referencia en los charts de Helm y los manifiestos de Kubernetes proporcionados. Sin embargo, es posible que algunos de ellos intenten extraer imágenes de contenedores y crear recursos de Kubernetes basados en estas imágenes en el entorno de ejecución. Si se dieran estos casos, para configurar un entorno completamente aislado, habrá que especificar manualmente las imágenes necesarias en el archivo de definición.

27.2 Requisitos previos

Si sigue esta guía, se entiende que ya está familiarizado con EIB (Capítulo 11, Edge Image Builder). Si no es así, siga la guía de inicio rápido (Capítulo 3, Clústeres independientes con Edge Image Builder) para comprender mejor los conceptos que se muestran en la práctica de abajo.

27.3 Configuración de red de Libvirt

Nota
Nota

Como ejemplo de un despliegue en entorno aislado, en esta guía se usa una red libvirt aislada simulada, por lo que la configuración que se muestra se adapta en consecuencia. Para sus despliegues, puede que tenga que modificar la configuración de host1.local.yaml que se introducirá en el siguiente paso.

Si desea utilizar la misma configuración de red de libvirt, siga adelante. Si no, salte a la Sección 27.4, “Configuración del directorio base”.

Vamos a crear una configuración de red aislada con un rango de direcciones IP 192.168.100.2/24 para DHCP:

cat << EOF > isolatednetwork.xml
<network>
  <name>isolatednetwork</name>
  <bridge name='virbr1' stp='on' delay='0'/>
  <ip address='192.168.100.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.100.2' end='192.168.100.254'/>
    </dhcp>
  </ip>
</network>
EOF

Ahora, solo queda crear la red y ponerla en marcha:

virsh net-define isolatednetwork.xml
virsh net-start isolatednetwork

27.4 Configuración del directorio base

La configuración del directorio base es la misma para todos los componentes, así que la configuraremos aquí.

Primero, creamos los subdirectorios necesarios:

export CONFIG_DIR=$HOME/config
mkdir -p $CONFIG_DIR/base-images
mkdir -p $CONFIG_DIR/network
mkdir -p $CONFIG_DIR/kubernetes/helm/values

Asegúrese de añadir la imagen base que tenga previsto utilizar en el directorio base-images. Esta guía se centra en la imagen ISO de autoinstalación que se encuentra aquí.

Copiemos la imagen descargada:

cp SL-Micro.x86_64-6.1-Base-SelfInstall-GM.install.iso $CONFIG_DIR/base-images/slemicro.iso
Nota
Nota

EIB nunca modifica la entrada de la imagen base.

Vamos a crear un archivo que contenga la configuración de red deseada:

cat << EOF > $CONFIG_DIR/network/host1.local.yaml
routes:
  config:
  - destination: 0.0.0.0/0
    metric: 100
    next-hop-address: 192.168.100.1
    next-hop-interface: eth0
    table-id: 254
  - destination: 192.168.100.0/24
    metric: 100
    next-hop-address:
    next-hop-interface: eth0
    table-id: 254
dns-resolver:
  config:
    server:
    - 192.168.100.1
    - 8.8.8.8
interfaces:
- name: eth0
  type: ethernet
  state: up
  mac-address: 34:8A:B1:4B:16:E7
  ipv4:
    address:
    - ip: 192.168.100.50
      prefix-length: 24
    dhcp: false
    enabled: true
  ipv6:
    enabled: false
EOF

Esta configuración garantiza la presencia de los siguientes elementos en los sistemas aprovisionados (utilizando la dirección MAC especificada):

  • una interfaz Ethernet con una dirección IP estática

  • enrutamiento

  • DNS

  • nombre de host (host1.local)

La estructura de archivos resultante debería tener el siguiente aspecto:

├── kubernetes/
│   └── helm/
│       └── values/
├── base-images/
│   └── slemicro.iso
└── network/
    └── host1.local.yaml

27.5 Archivo de definición base

Edge Image Builder usa archivos de definición para modificar las imágenes de SUSE Linux Micro. Estos archivos contienen la mayoría de las opciones configurables. Muchas de estas opciones se repetirán en las diferentes secciones de los componentes, por lo que las mostraremos y explicaremos aquí.

Sugerencia
Sugerencia

La lista completa de opciones de personalización del archivo de definición se encuentra en la documentación original.

Veamos los campos que estarán presentes en todos los archivos de definición:

apiVersion: 1.2
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
  version: v1.32.4+rke2r1
embeddedArtifactRegistry:
  images:
    - ...

La sección image es obligatoria y especifica la imagen de entrada, su arquitectura y su tipo, y cómo se llamará la imagen de salida.

La sección operatingSystem es opcional y contiene la configuración para permitir el inicio de sesión en los sistemas aprovisionados con el nombre de usuario/contraseña root/eib.

La sección kubernetes es opcional y define el tipo y la versión de Kubernetes. Vamos a usar la distribución RKE2. Utilice kubernetes.version: v1.32.4+k3s1 si desea K3s en su lugar. A menos que se configure explícitamente a través del campo kubernetes.nodes, todos los clústeres que arranquemos en esta guía serán de un solo nodo.

La sección embeddedArtifactRegistry incluirá todas las imágenes a las que solo se hace referencia y solo se extraen en el tiempo de ejecución del componente específico.

27.6 Instalación de Rancher

Nota
Nota

El despliegue de Rancher (Capítulo 5, Rancher) de este ejemplo es muy reducido para que sea más fácil de explicar. En sus despliegues reales, pueden ser necesarios artefactos adicionales, dependiendo de su configuración.

Los recursos de la versión Rancher 2.11.2 contienen un archivo rancher-images.txt que muestra todas las imágenes necesarias para una instalación en entornos aislados.

Hay más de 600 imágenes de contenedor en total, lo que significa que la imagen lista para arrancar resultante tendría aproximadamente 30 GB. Para nuestra instalación de Rancher, reduciremos la lista a la configuración de trabajo más pequeña posible. A partir de ahí, es posible añadir cualquier imagen que necesite en sus despliegues.

Crearemos el archivo de definición e incluiremos la lista de imágenes desglosada:

apiVersion: 1.2
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
  version: v1.32.4+rke2r1
  manifests:
    urls:
    - https://github.com/cert-manager/cert-manager/releases/download/v1.15.3/cert-manager.crds.yaml
  helm:
    charts:
      - name: rancher
        version: 2.11.2
        repositoryName: rancher-prime
        valuesFile: rancher-values.yaml
        targetNamespace: cattle-system
        createNamespace: true
        installationNamespace: kube-system
      - name: cert-manager
        installationNamespace: kube-system
        createNamespace: true
        repositoryName: jetstack
        targetNamespace: cert-manager
        version: 1.15.3
    repositories:
      - name: jetstack
        url: https://charts.jetstack.io
      - name: rancher-prime
        url: https://charts.rancher.com/server-charts/prime
embeddedArtifactRegistry:
  images:
    - name: registry.rancher.com/rancher/backup-restore-operator:v7.0.1
    - name: registry.rancher.com/rancher/calico-cni:v3.29.0-rancher1
    - name: registry.rancher.com/rancher/cis-operator:v1.4.0
    - name: registry.rancher.com/rancher/flannel-cni:v1.4.1-rancher1
    - name: registry.rancher.com/rancher/fleet-agent:v0.12.2
    - name: registry.rancher.com/rancher/fleet:v0.12.2
    - name: registry.rancher.com/rancher/hardened-addon-resizer:1.8.22-build20250110
    - name: registry.rancher.com/rancher/hardened-calico:v3.29.2-build20250306
    - name: registry.rancher.com/rancher/hardened-cluster-autoscaler:v1.9.0-build20241126
    - name: registry.rancher.com/rancher/hardened-cni-plugins:v1.6.2-build20250306
    - name: registry.rancher.com/rancher/hardened-coredns:v1.12.0-build20241126
    - name: registry.rancher.com/rancher/hardened-dns-node-cache:1.24.0-build20241211
    - name: registry.rancher.com/rancher/hardened-etcd:v3.5.19-k3s1-build20250306
    - name: registry.rancher.com/rancher/hardened-flannel:v0.26.5-build20250306
    - name: registry.rancher.com/rancher/hardened-k8s-metrics-server:v0.7.2-build20250110
    - name: registry.rancher.com/rancher/hardened-kubernetes:v1.32.3-rke2r1-build20250312
    - name: registry.rancher.com/rancher/hardened-multus-cni:v4.1.4-build20250108
    - name: registry.rancher.com/rancher/hardened-whereabouts:v0.8.0-build20250131
    - name: registry.rancher.com/rancher/k3s-upgrade:v1.32.3-k3s1
    - name: registry.rancher.com/rancher/klipper-helm:v0.9.4-build20250113
    - name: registry.rancher.com/rancher/klipper-lb:v0.4.13
    - name: registry.rancher.com/rancher/kube-api-auth:v0.2.4
    - name: registry.rancher.com/rancher/kubectl:v1.32.2
    - name: registry.rancher.com/rancher/kuberlr-kubectl:v4.0.2
    - name: registry.rancher.com/rancher/local-path-provisioner:v0.0.31
    - name: registry.rancher.com/rancher/machine:v0.15.0-rancher125
    - name: registry.rancher.com/rancher/mirrored-cluster-api-controller:v1.9.5
    - name: registry.rancher.com/rancher/nginx-ingress-controller:v1.12.1-hardened1
    - name: registry.rancher.com/rancher/prom-prometheus:v2.55.1
    - name: registry.rancher.com/rancher/prometheus-federator:v3.0.1
    - name: registry.rancher.com/rancher/pushprox-client:v0.1.4-rancher2-client
    - name: registry.rancher.com/rancher/pushprox-proxy:v0.1.4-rancher2-proxy
    - name: registry.rancher.com/rancher/rancher-agent:v2.11.1
    - name: registry.rancher.com/rancher/rancher-csp-adapter:v6.0.0
    - name: registry.rancher.com/rancher/rancher-webhook:v0.7.1
    - name: registry.rancher.com/rancher/rancher:v2.11.1
    - name: registry.rancher.com/rancher/remotedialer-proxy:v0.4.4
    - name: registry.rancher.com/rancher/rke-tools:v0.1.111
    - name: registry.rancher.com/rancher/rke2-cloud-provider:v1.32.0-rc3.0.20241220224140-68fbd1a6b543-build20250101
    - name: registry.rancher.com/rancher/rke2-runtime:v1.32.3-rke2r1
    - name: registry.rancher.com/rancher/rke2-upgrade:v1.32.3-rke2r1
    - name: registry.rancher.com/rancher/security-scan:v0.6.0
    - name: registry.rancher.com/rancher/shell:v0.4.0
    - name: registry.rancher.com/rancher/system-agent-installer-k3s:v1.32.3-k3s1
    - name: registry.rancher.com/rancher/system-agent-installer-rke2:v1.32.3-rke2r1
    - name: registry.rancher.com/rancher/system-agent:v0.3.12-suc
    - name: registry.rancher.com/rancher/system-upgrade-controller:v0.15.2
    - name: registry.rancher.com/rancher/ui-plugin-catalog:4.0.1
    - name: registry.rancher.com/rancher/kubectl:v1.20.2
    - name: registry.rancher.com/rancher/shell:v0.1.24
    - name: registry.rancher.com/rancher/mirrored-ingress-nginx-kube-webhook-certgen:v1.5.0
    - name: registry.rancher.com/rancher/mirrored-ingress-nginx-kube-webhook-certgen:v1.5.2

En comparación con la lista completa de más de 600 imágenes, esta versión reducida solo tiene unas 60, por lo que la nueva imagen lista para arrancar solo ocupa unos 7 GB.

También necesitamos crear un archivo de valores de Helm para Rancher:

cat << EOF > $CONFIG_DIR/kubernetes/helm/values/rancher-values.yaml
hostname: 192.168.100.50.sslip.io
replicas: 1
bootstrapPassword: "adminadminadmin"
systemDefaultRegistry: registry.rancher.com
useBundledSystemChart: true
EOF
Aviso
Aviso

Establece en systemDefaultRegistry el valor registry.rancher.com permite a Rancher buscar automáticamente imágenes en el registro de artefactos integrados iniciado dentro de la imagen lista para arrancar en el arranque. Si se omite este campo, quizás no se encuentren las imágenes de contenedor en el nodo.

Vamos a crear la imagen:

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

El resultado debe ser parecido a esto:

Downloading file: dl-manifest-1.yaml 100% |██████████████████████████████████████████████████████████████████████████████| (583/583 kB, 12 MB/s)
Pulling selected Helm charts... 100% |███████████████████████████████████████████████████████████████████████████████████████████| (2/2, 3 it/s)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |███████████████████████████████████████████████████████████████████████████| (56/56, 8 it/min)
Embedded Artifact Registry ... [SUCCESS]
Keymap ....................... [SUCCESS]
Configuring Kubernetes component...
The Kubernetes CNI is not explicitly set, defaulting to 'cilium'.
Downloading file: rke2_installer.sh
Downloading file: rke2-images-core.linux-amd64.tar.zst 100% |███████████████████████████████████████████████████████████| (644/644 MB, 29 MB/s)
Downloading file: rke2-images-cilium.linux-amd64.tar.zst 100% |█████████████████████████████████████████████████████████| (400/400 MB, 29 MB/s)
Downloading file: rke2.linux-amd64.tar.gz 100% |███████████████████████████████████████████████████████████████████████████| (36/36 MB, 30 MB/s)
Downloading file: sha256sum-amd64.txt 100% |█████████████████████████████████████████████████████████████████████████████| (4.3/4.3 kB, 29 MB/s)
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso

Una vez que se aprovisiona un nodo que usa la imagen creada, es posible verificar la instalación de Rancher:

/var/lib/rancher/rke2/bin/kubectl get all -n cattle-system --kubeconfig /etc/rancher/rke2/rke2.yaml

El resultado debería ser similar a lo siguiente, donde se muestra que todo se ha desplegado correctamente:

NAME                                            READY   STATUS      RESTARTS   AGE
pod/helm-operation-6l6ld                        0/2     Completed   0          107s
pod/helm-operation-8tk2v                        0/2     Completed   0          2m2s
pod/helm-operation-blnrr                        0/2     Completed   0          2m49s
pod/helm-operation-hdcmt                        0/2     Completed   0          3m19s
pod/helm-operation-m74c7                        0/2     Completed   0          97s
pod/helm-operation-qzzr4                        0/2     Completed   0          2m30s
pod/helm-operation-s9jh5                        0/2     Completed   0          3m
pod/helm-operation-tq7ts                        0/2     Completed   0          2m41s
pod/rancher-99d599967-ftjkk                     1/1     Running     0          4m15s
pod/rancher-webhook-79798674c5-6w28t            1/1     Running     0          2m27s
pod/system-upgrade-controller-56696956b-trq5c   1/1     Running     0          104s

NAME                      TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/rancher           ClusterIP   10.43.255.80   <none>        80/TCP,443/TCP   4m15s
service/rancher-webhook   ClusterIP   10.43.7.238    <none>        443/TCP          2m27s

NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/rancher                     1/1     1            1           4m15s
deployment.apps/rancher-webhook             1/1     1            1           2m27s
deployment.apps/system-upgrade-controller   1/1     1            1           104s

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/rancher-99d599967                     1         1         1       4m15s
replicaset.apps/rancher-webhook-79798674c5            1         1         1       2m27s
replicaset.apps/system-upgrade-controller-56696956b   1         1         1       104s

Cuando vamos a https://192.168.100.50.sslip.io e iniciamos sesión con la contraseña adminadminadmin que establecimos anteriormente, accedemos al panel de control de Rancher:

rancher en entorno aislado

27.7 Instalación de SUSE Security

A diferencia de la instalación de Rancher, la instalación de SUSE Security no requiere ningún tratamiento especial en EIB. EIB instalará en un entorno aislado automáticamente todas las imágenes requeridas por su componente subyacente NeuVector.

Vamos a crear el archivo de definición:

apiVersion: 1.2
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
  version: v1.32.4+rke2r1
  helm:
    charts:
      - name: neuvector-crd
        version: 106.0.1+up2.8.6
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector-values.yaml
      - name: neuvector
        version: 106.0.1+up2.8.6
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector-values.yaml
    repositories:
      - name: rancher-charts
        url: https://charts.rancher.io/

También crearemos un archivo de valores de Helm para NeuVector:

cat << EOF > $CONFIG_DIR/kubernetes/helm/values/neuvector-values.yaml
controller:
  replicas: 1
manager:
  enabled: false
cve:
  scanner:
    enabled: false
    replicas: 1
k3s:
  enabled: true
crdwebhook:
  enabled: false
EOF

Vamos a crear la imagen:

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

El resultado debe ser parecido a esto:

Pulling selected Helm charts... 100% |███████████████████████████████████████████████████████████████████████████████████████████| (2/2, 4 it/s)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |██████████████████████████████████████████████████████████████████████████████| (5/5, 13 it/min)
Embedded Artifact Registry ... [SUCCESS]
Keymap ....................... [SUCCESS]
Configuring Kubernetes component...
The Kubernetes CNI is not explicitly set, defaulting to 'cilium'.
Downloading file: rke2_installer.sh
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso

Después de que se haya aprovisionado un nodo con la imagen creada, podemos verificar la instalación de SUSE Security:

/var/lib/rancher/rke2/bin/kubectl get all -n neuvector --kubeconfig /etc/rancher/rke2/rke2.yaml

El resultado debería ser similar a lo siguiente, donde se muestra que todo se ha desplegado correctamente:

NAME                                            READY   STATUS      RESTARTS   AGE
pod/neuvector-cert-upgrader-job-bxbnz           0/1     Completed   0          3m39s
pod/neuvector-controller-pod-7d854bfdc7-nhxjf   1/1     Running     0          3m44s
pod/neuvector-enforcer-pod-ct8jm                1/1     Running     0          3m44s

NAME                                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                         AGE
service/neuvector-svc-admission-webhook   ClusterIP   10.43.234.241   <none>        443/TCP                         3m44s
service/neuvector-svc-controller          ClusterIP   None            <none>        18300/TCP,18301/TCP,18301/UDP   3m44s
service/neuvector-svc-crd-webhook         ClusterIP   10.43.50.190    <none>        443/TCP                         3m44s

NAME                                    DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/neuvector-enforcer-pod   1         1         1       1            1           <none>          3m44s

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/neuvector-controller-pod   1/1     1            1           3m44s

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/neuvector-controller-pod-7d854bfdc7   1         1         1       3m44s

NAME                                        SCHEDULE    TIMEZONE   SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/neuvector-cert-upgrader-pod   0 0 1 1 *   <none>     True      0        <none>          3m44s
cronjob.batch/neuvector-updater-pod         0 0 * * *   <none>     False     0        <none>          3m44s

NAME                                    STATUS     COMPLETIONS   DURATION   AGE
job.batch/neuvector-cert-upgrader-job   Complete   1/1           7s         3m39s

27.8 Instalación de SUSE Storage

La documentación oficial de Longhorn contiene un archivo longhorn-images.txt que muestra todas las imágenes necesarias para una instalación en entornos aislados. Vamos a incluir sus homólogos duplicados del registro de contenedores de Rancher en nuestro archivo de definición. Vamos a crear el archivo:

apiVersion: 1.2
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
  packages:
    sccRegistrationCode: [reg-code]
    packageList:
      - open-iscsi
kubernetes:
  version: v1.32.4+rke2r1
  helm:
    charts:
      - name: longhorn
        repositoryName: longhorn
        targetNamespace: longhorn-system
        createNamespace: true
        version: 106.2.0+up1.8.1
      - name: longhorn-crd
        repositoryName: longhorn
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
        version: 106.2.0+up1.8.1
    repositories:
      - name: longhorn
        url: https://charts.rancher.io
embeddedArtifactRegistry:
  images:
    - name: registry.suse.com/rancher/mirrored-longhornio-csi-attacher:v4.8.1
    - name: registry.suse.com/rancher/mirrored-longhornio-csi-provisioner:v5.2.0
    - name: registry.suse.com/rancher/mirrored-longhornio-csi-resizer:v1.13.2
    - name: registry.suse.com/rancher/mirrored-longhornio-csi-snapshotter:v8.2.0
    - name: registry.suse.com/rancher/mirrored-longhornio-csi-node-driver-registrar:v2.13.0
    - name: registry.suse.com/rancher/mirrored-longhornio-livenessprobe:v2.15.0
    - name: registry.suse.com/rancher/mirrored-longhornio-backing-image-manager:v1.8.1
    - name: registry.suse.com/rancher/mirrored-longhornio-longhorn-engine:v1.8.1
    - name: registry.suse.com/rancher/mirrored-longhornio-longhorn-instance-manager:v1.8.1
    - name: registry.suse.com/rancher/mirrored-longhornio-longhorn-manager:v1.8.1
    - name: registry.suse.com/rancher/mirrored-longhornio-longhorn-share-manager:v1.8.1
    - name: registry.suse.com/rancher/mirrored-longhornio-longhorn-ui:v1.8.1
    - name: registry.suse.com/rancher/mirrored-longhornio-support-bundle-kit:v0.0.52
    - name: registry.suse.com/rancher/mirrored-longhornio-longhorn-cli:v1.8.1
Nota
Nota

Observará que el archivo de definición muestra el paquete open-iscsi. Este paquete es obligatorio, ya que Longhorn se basa en un daemon iscsiadm que se ejecuta en los diferentes nodos para proporcionar volúmenes persistentes a Kubernetes.

Vamos a crear la imagen:

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

El resultado debe ser parecido a esto:

Setting up Podman API listener...
Pulling selected Helm charts... 100% |██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| (2/2, 3 it/s)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Resolving package dependencies...
Rpm .......................... [SUCCESS]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |███████████████████████████████████████████████████████████████████████████████████████████████████████████| (15/15, 20956 it/s)
Embedded Artifact Registry ... [SUCCESS]
Keymap ....................... [SUCCESS]
Configuring Kubernetes component...
The Kubernetes CNI is not explicitly set, defaulting to 'cilium'.
Downloading file: rke2_installer.sh
Downloading file: rke2-images-core.linux-amd64.tar.zst 100% (782/782 MB, 108 MB/s)
Downloading file: rke2-images-cilium.linux-amd64.tar.zst 100% (367/367 MB, 104 MB/s)
Downloading file: rke2.linux-amd64.tar.gz 100% (34/34 MB, 108 MB/s)
Downloading file: sha256sum-amd64.txt 100% (3.9/3.9 kB, 7.5 MB/s)
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso

Una vez aprovisionado un nodo con la imagen creada, podemos verificar la instalación de Longhorn:

/var/lib/rancher/rke2/bin/kubectl get all -n longhorn-system --kubeconfig /etc/rancher/rke2/rke2.yaml

El resultado debería ser similar a lo siguiente, donde se muestra que todo se ha desplegado correctamente:

NAME                                                    READY   STATUS    RESTARTS   AGE
pod/csi-attacher-787fd9c6c8-sf42d                       1/1     Running   0          2m28s
pod/csi-attacher-787fd9c6c8-tb82p                       1/1     Running   0          2m28s
pod/csi-attacher-787fd9c6c8-zhc6s                       1/1     Running   0          2m28s
pod/csi-provisioner-74486b95c6-b2v9s                    1/1     Running   0          2m28s
pod/csi-provisioner-74486b95c6-hwllt                    1/1     Running   0          2m28s
pod/csi-provisioner-74486b95c6-mlrpk                    1/1     Running   0          2m28s
pod/csi-resizer-859d4557fd-t54zk                        1/1     Running   0          2m28s
pod/csi-resizer-859d4557fd-vdt5d                        1/1     Running   0          2m28s
pod/csi-resizer-859d4557fd-x9kh4                        1/1     Running   0          2m28s
pod/csi-snapshotter-6f69c6c8cc-r62gr                    1/1     Running   0          2m28s
pod/csi-snapshotter-6f69c6c8cc-vrwjn                    1/1     Running   0          2m28s
pod/csi-snapshotter-6f69c6c8cc-z65nb                    1/1     Running   0          2m28s
pod/engine-image-ei-4623b511-9vhkb                      1/1     Running   0          3m13s
pod/instance-manager-6f95fd57d4a4cd0459e469d75a300552   1/1     Running   0          2m43s
pod/longhorn-csi-plugin-gx98x                           3/3     Running   0          2m28s
pod/longhorn-driver-deployer-55f9c88499-fbm6q           1/1     Running   0          3m28s
pod/longhorn-manager-dpdp7                              2/2     Running   0          3m28s
pod/longhorn-ui-59c85fcf94-gg5hq                        1/1     Running   0          3m28s
pod/longhorn-ui-59c85fcf94-s49jc                        1/1     Running   0          3m28s

NAME                                  TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/longhorn-admission-webhook    ClusterIP   10.43.77.89    <none>        9502/TCP   3m28s
service/longhorn-backend              ClusterIP   10.43.56.17    <none>        9500/TCP   3m28s
service/longhorn-conversion-webhook   ClusterIP   10.43.54.73    <none>        9501/TCP   3m28s
service/longhorn-frontend             ClusterIP   10.43.22.82    <none>        80/TCP     3m28s
service/longhorn-recovery-backend     ClusterIP   10.43.45.143   <none>        9503/TCP   3m28s

NAME                                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/engine-image-ei-4623b511   1         1         1       1            1           <none>          3m13s
daemonset.apps/longhorn-csi-plugin        1         1         1       1            1           <none>          2m28s
daemonset.apps/longhorn-manager           1         1         1       1            1           <none>          3m28s

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/csi-attacher               3/3     3            3           2m28s
deployment.apps/csi-provisioner            3/3     3            3           2m28s
deployment.apps/csi-resizer                3/3     3            3           2m28s
deployment.apps/csi-snapshotter            3/3     3            3           2m28s
deployment.apps/longhorn-driver-deployer   1/1     1            1           3m28s
deployment.apps/longhorn-ui                2/2     2            2           3m28s

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/csi-attacher-787fd9c6c8               3         3         3       2m28s
replicaset.apps/csi-provisioner-74486b95c6            3         3         3       2m28s
replicaset.apps/csi-resizer-859d4557fd                3         3         3       2m28s
replicaset.apps/csi-snapshotter-6f69c6c8cc            3         3         3       2m28s
replicaset.apps/longhorn-driver-deployer-55f9c88499   1         1         1       3m28s
replicaset.apps/longhorn-ui-59c85fcf94                2         2         2       3m28s

27.9 Instalación de KubeVirt y CDI

Los charts de Helm tanto para KubeVirt como para CDI solo instalan sus operadores respectivos. Depende de los operadores desplegar el resto de sistemas, lo que significa que tendremos que incluir todas las imágenes de contenedor necesarias en nuestro archivo de definición. Vamos a crearlo:

apiVersion: 1.2
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
  version: v1.32.4+rke2r1
  helm:
    charts:
      - name: kubevirt
        repositoryName: suse-edge
        version: 303.0.0+up0.5.0
        targetNamespace: kubevirt-system
        createNamespace: true
        installationNamespace: kube-system
      - name: cdi
        repositoryName: suse-edge
        version: 303.0.0+up0.5.0
        targetNamespace: cdi-system
        createNamespace: true
        installationNamespace: kube-system
    repositories:
      - name: suse-edge
        url: oci://registry.suse.com/edge/charts
embeddedArtifactRegistry:
  images:
    - name: registry.suse.com/suse/sles/15.6/cdi-uploadproxy:1.60.1-150600.3.9.1
    - name: registry.suse.com/suse/sles/15.6/cdi-uploadserver:1.60.1-150600.3.9.1
    - name: registry.suse.com/suse/sles/15.6/cdi-apiserver:1.60.1-150600.3.9.1
    - name: registry.suse.com/suse/sles/15.6/cdi-controller:1.60.1-150600.3.9.1
    - name: registry.suse.com/suse/sles/15.6/cdi-importer:1.60.1-150600.3.9.1
    - name: registry.suse.com/suse/sles/15.6/cdi-cloner:1.60.1-150600.3.9.1
    - name: registry.suse.com/suse/sles/15.6/virt-api:1.3.1-150600.5.9.1
    - name: registry.suse.com/suse/sles/15.6/virt-controller:1.3.1-150600.5.9.1
    - name: registry.suse.com/suse/sles/15.6/virt-launcher:1.3.1-150600.5.9.1
    - name: registry.suse.com/suse/sles/15.6/virt-handler:1.3.1-150600.5.9.1
    - name: registry.suse.com/suse/sles/15.6/virt-exportproxy:1.3.1-150600.5.9.1
    - name: registry.suse.com/suse/sles/15.6/virt-exportserver:1.3.1-150600.5.9.1

Vamos a crear la imagen:

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

El resultado debe ser parecido a esto:

Pulling selected Helm charts... 100% |███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| (2/2, 48 it/min)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |██████████████████████████████████████████████████████████████████████████████████████████████████████████| (15/15, 4 it/min)
Embedded Artifact Registry ... [SUCCESS]
Keymap ....................... [SUCCESS]
Configuring Kubernetes component...
The Kubernetes CNI is not explicitly set, defaulting to 'cilium'.
Downloading file: rke2_installer.sh
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso

Una vez aprovisionado un nodo con la imagen construida, podemos verificar la instalación tanto de KubeVirt como de CDI.

Verifique KubeVirt:

/var/lib/rancher/rke2/bin/kubectl get all -n kubevirt-system --kubeconfig /etc/rancher/rke2/rke2.yaml

El resultado debería ser similar a lo siguiente, donde se muestra que todo se ha desplegado correctamente:

NAME                                  READY   STATUS    RESTARTS   AGE
pod/virt-api-59cb997648-mmt67         1/1     Running   0          2m34s
pod/virt-controller-69786b785-7cc96   1/1     Running   0          2m8s
pod/virt-controller-69786b785-wq2dz   1/1     Running   0          2m8s
pod/virt-handler-2l4dm                1/1     Running   0          2m8s
pod/virt-operator-7c444cff46-nps4l    1/1     Running   0          3m1s
pod/virt-operator-7c444cff46-r25xq    1/1     Running   0          3m1s

NAME                                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/kubevirt-operator-webhook     ClusterIP   10.43.167.109   <none>        443/TCP   2m36s
service/kubevirt-prometheus-metrics   ClusterIP   None            <none>        443/TCP   2m36s
service/virt-api                      ClusterIP   10.43.18.202    <none>        443/TCP   2m36s
service/virt-exportproxy              ClusterIP   10.43.142.188   <none>        443/TCP   2m36s

NAME                          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/virt-handler   1         1         1       1            1           kubernetes.io/os=linux   2m8s

NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/virt-api          1/1     1            1           2m34s
deployment.apps/virt-controller   2/2     2            2           2m8s
deployment.apps/virt-operator     2/2     2            2           3m1s

NAME                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/virt-api-59cb997648         1         1         1       2m34s
replicaset.apps/virt-controller-69786b785   2         2         2       2m8s
replicaset.apps/virt-operator-7c444cff46    2         2         2       3m1s

NAME                            AGE    PHASE
kubevirt.kubevirt.io/kubevirt   3m1s   Deployed

Verifique CDI:

/var/lib/rancher/rke2/bin/kubectl get all -n cdi-system --kubeconfig /etc/rancher/rke2/rke2.yaml

El resultado debería ser similar a lo siguiente, donde se muestra que todo se ha desplegado correctamente:

NAME                                   READY   STATUS    RESTARTS   AGE
pod/cdi-apiserver-5598c9bf47-pqfxw     1/1     Running   0          3m44s
pod/cdi-deployment-7cbc5db7f8-g46z7    1/1     Running   0          3m44s
pod/cdi-operator-777c865745-2qcnj      1/1     Running   0          3m48s
pod/cdi-uploadproxy-646f4cd7f7-fzkv7   1/1     Running   0          3m44s

NAME                             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/cdi-api                  ClusterIP   10.43.2.224    <none>        443/TCP    3m44s
service/cdi-prometheus-metrics   ClusterIP   10.43.237.13   <none>        8080/TCP   3m44s
service/cdi-uploadproxy          ClusterIP   10.43.114.91   <none>        443/TCP    3m44s

NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/cdi-apiserver     1/1     1            1           3m44s
deployment.apps/cdi-deployment    1/1     1            1           3m44s
deployment.apps/cdi-operator      1/1     1            1           3m48s
deployment.apps/cdi-uploadproxy   1/1     1            1           3m44s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/cdi-apiserver-5598c9bf47     1         1         1       3m44s
replicaset.apps/cdi-deployment-7cbc5db7f8    1         1         1       3m44s
replicaset.apps/cdi-operator-777c865745      1         1         1       3m48s
replicaset.apps/cdi-uploadproxy-646f4cd7f7   1         1         1       3m44s

27.10 Solución de problemas

Si tiene algún problema al crear las imágenes o desea probar y depurar el proceso, consulte la documentación original.

28 Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi

En esta sección se explica cómo generar imágenes actualizadas de SUSE Linux Micro para utilizarlas con Edge Image Builder, con Cluster API (CAPI) + Metal3, o para escribir la imagen de disco directamente en un dispositivo de bloques. Este proceso resulta útil en situaciones en las que es necesario incluir los parches más recientes en las imágenes de arranque iniciales del sistema inicial (para minimizar la transferencia de parches tras la instalación), o para situaciones en las que se usa CAPI, donde se prefiere reinstalar el sistema operativo con una imagen nueva en lugar de actualizar los hosts in situ.

Este proceso hace uso de Kiwi para crear la imagen. SUSE Edge incluye una versión en contenedor que simplifica todo el proceso con una utilidad de ayuda integrada que permite especificar el perfil de destino necesario. El perfil define el tipo de imagen de destino que se requiere. A continuación se muestran los tipos más comunes:

  • "Base": una imagen de disco de SUSE Linux Micro con un conjunto de paquetes reducido (incluye Podman).

  • "Base-SelfInstall": una imagen de autoinstalación basada en la imagen "Base" anterior.

  • "Base-RT": igual que "Base", pero usa un kernel en tiempo real (rt).

  • "Base-RT-SelfInstall": una imagen de autoinstalación basada en la imagen "Base-RT" anterior.

  • "Default": una imagen de disco de SUSE Linux Micro basada en la imagen "Base" anterior, pero con algunas herramientas más, como la pila de virtualización, Cockpit y salt-minion.

  • "Default-SelfInstall": una imagen de autoinstalación basada en la imagen "Default" anterior.

Consulte la documentación de SUSE Linux Micro 6.1 para obtener más detalles.

Este proceso funciona tanto para arquitecturas AMD64/Intel 64 como AArch64, aunque no todos los perfiles de imagen están disponibles para ambas arquitecturas. Por ejemplo, en SUSE Edge 3.3, donde se utiliza SUSE Linux Micro 6.1, no hay disponible actualmente ningún perfil con un kernel en tiempo real (es decir, "Base-RT" o "Base-RT-SelfInstall") para AArch64.

Nota
Nota

Es preciso usar un host de creación con la misma arquitectura de las imágenes que se están creando. En otras palabras, para crear una imagen AArch64, hay que utilizar un host de creación AArch64; y lo mismo ocurre para AMD64/Intel 64. Actualmente, no se admiten las creaciones cruzadas.

28.1 Requisitos previos

El creador de imágenes Kiwi requiere lo siguiente:

  • Un host ("sistema de creación") SUSE Linux Micro 6.1 con la misma arquitectura que la imagen que se va a crear.

  • El sistema de creación debe haberse registrado vía SUSEConnect (el registro se utiliza para extraer los paquetes más recientes de los repositorios de SUSE).

  • Una conexión a Internet que pueda usarse para extraer los paquetes necesarios. Si se conecta a través de proxy y el host de creación debe estar preconfigurado.

  • SELinux debe estar inhabilitado en el host de creación (ya que el etiquetado de SELinux tiene lugar en el contenedor y puede entrar en conflicto con la directiva del host).

  • Al menos 10 GB de espacio libre en disco para alojar la imagen de contenedor, la raíz de creación y las imágenes de salida resultantes.

28.2 Inicio

Debido a ciertas limitaciones, actualmente es necesario inhabilitar SELinux. Conéctese al host de creación de imágenes de SUSE Linux Micro 6.1 y asegúrese de que SELinux está inhabilitado:

# setenforce 0

Cree un directorio de salida que se compartirá con el contenedor de creación de Kiwi para guardar las imágenes resultantes:

# mkdir ~/output

Obtenga la imagen más reciente de Kiwi Builder del registro de SUSE:

# podman pull registry.suse.com/edge/3.3/kiwi-builder:10.2.12.0
(...)

28.3 Creación de la imagen por defecto

Este es el comportamiento por defecto del contenedor de imágenes de Kiwi si no se proporcionan argumentos durante la ejecución de la imagen del contenedor. El comando siguiente ejecuta Podman con dos directorios asignados al contenedor:

  • El directorio del repositorio de paquetes /etc/zypp/repos.d de SUSE Linux Micro del host subyacente.

  • El directorio de salida ~/output creado arriba.

El contenedor de imágenes de Kiwi requiere que se ejecute el guion de ayuda build-image como:

# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output \
    -it registry.suse.com/edge/3.3/kiwi-builder:10.2.12.0 build-image
(...)
Nota
Nota

Es de esperar que, si ejecuta este guion por primera vez, falle poco después de comenzar con el error "ERROR: Early loop device test failed, please retry the container run." (La prueba del dispositivo de bucle temprano ha fallado. Vuelva a intentar la ejecución del contenedor). Esto es un síntoma de que se están creando dispositivos de bucle en el sistema host subyacente que no son inmediatamente visibles dentro de la imagen del contenedor. Solo tiene que ejecutar de nuevo el comando y el guion continuará sin más problemas.

Al cabo de unos minutos, las imágenes se encuentran en el directorio de salida local:

(...)
INFO: Image build successful, generated images are available in the 'output' directory.

# ls -1 output/
SLE-Micro.x86_64-6.1.changes
SLE-Micro.x86_64-6.1.packages
SLE-Micro.x86_64-6.1.raw
SLE-Micro.x86_64-6.1.verified
build
kiwi.result
kiwi.result.json

28.4 Creación de imágenes con otros perfiles

Para crear perfiles de imagen distintos, se utiliza la opción de comando "-p" en el guion de ayuda de la imagen del contenedor de Kiwi. Por ejemplo, para crear la imagen ISO "Default-SelfInstall":

# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output \
    -it registry.suse.com/edge/3.3/kiwi-builder:10.2.12.0 build-image -p Default-SelfInstall
(...)
Nota
Nota

Para evitar la pérdida de datos, Kiwi negará a ejecutarse si hay imágenes en el directorio output. Es necesario eliminar el contenido del directorio de salida antes de proceder con rm -f output/*.

Como alternativa, puede crear una imagen ISO de autoinstalación con el kernel en tiempo real ("kernel-rt"):

# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output \
    -it registry.suse.com/edge/3.3/kiwi-builder:10.2.12.0 build-image -p Base-RT-SelfInstall
(...)

28.5 Creación de imágenes con sectores de gran tamaño

Hay hardware que requiere una imagen con un tamaño de sectores grandes; por ejemplo, de 4096 bytes en lugar de los 512 bytes estándar. El creador en contenedor de Kiwi permite generar imágenes con bloques grandes especificando el parámetro "-b". Por ejemplo, para crear una imagen "Default-SelfInstall" con sectores grandes:

# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output \
    -it registry.suse.com/edge/3.3/kiwi-builder:10.2.12.0 build-image -p Default-SelfInstall -b
(...)

28.6 Uso de un archivo de definición de imagen de Kiwi personalizado

En ciertos casos de uso avanzados, es posible usar un archivo de definición de imagen de Kiwi personalizado (SL-Micro.kiwi) junto con los guiones de postcreación necesarios. Para ello, habrá que anular las definiciones predeterminadas preempaquetadas por el equipo de SUSE Edge.

Cree un directorio nuevo y asígnelo a la imagen de contenedor donde busca el guion de ayuda (/micro-sdk/defs):

# mkdir ~/mydefs/
# cp /path/to/SL-Micro.kiwi ~/mydefs/
# cp /path/to/config.sh ~/mydefs/
# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output -v ~/mydefs/:/micro-sdk/defs/ \
    -it registry.suse.com/edge/3.3/kiwi-builder:10.2.12.0 build-image
(...)
Aviso
Aviso

Esto solo es necesario para casos de uso avanzados y puede causar problemas de compatibilidad. Póngase en contacto con su representante de SUSE para obtener más ayuda.

Para obtener los archivos de definición de imagen de Kiwi por defecto incluidos en el contenedor, se pueden utilizar los siguientes comandos:

$ podman create --name kiwi-builder registry.suse.com/edge/3.3/kiwi-builder:10.2.12.0
$ podman cp kiwi-builder:/micro-sdk/defs/SL-Micro.kiwi .
$ podman cp kiwi-builder:/micro-sdk/defs/SL-Micro.kiwi.4096 .
$ podman rm kiwi-builder
$ ls ./SL-Micro.*
(...)

29 Uso de ClusterClass para desplegar clústeres descendentes

29.1 Introducción

El aprovisionamiento de clústeres de Kubernetes es una tarea compleja que requiere una gran experiencia a la hora de configurar los componentes del clúster. A medida que las configuraciones se vuelven más complejas, o que las exigencias de los diferentes proveedores introducen numerosas definiciones de recursos específicas para cada uno, la creación de clústeres puede resultar abrumadora. Afortunadamente, la API de clústeres de Kubernetes (Cluster API, CAPI) ofrece un enfoque elegante y claro aún más reforzado gracias a ClusterClass. Esta función introduce un modelo basado en plantillas que permite definir una clase de clúster reutilizable que encapsula la complejidad y promueve la coherencia.

29.2 ¿Qué es ClusterClass?

El proyecto CAPI introdujo la función ClusterClass como un cambio de paradigma en la gestión del ciclo de vida de los clústeres de Kubernetes mediante la adopción de una metodología basada en plantillas para la instanciación de clústeres. En lugar de definir los recursos de forma independiente para cada clúster, los usuarios definen una ClusterClass, que sirve como un modelo completo y reutilizable. Esta representación abstracta encapsula el estado y la configuración deseados de un clúster de Kubernetes, lo que permite la creación rápida y coherente de múltiples clústeres que se ajustan a las especificaciones definidas. Esta abstracción reduce la carga de configuración, lo que da como resultado manifiestos de despliegue más manejables. Esto significa que los componentes centrales de un clúster de carga de trabajo se definen a nivel de clase, lo que permite a los usuarios utilizar estas plantillas como variantes de clústeres de Kubernetes que se pueden reutilizar una o varias veces para el aprovisionamiento de clústeres. La implementación de ClusterClass ofrece varias ventajas clave que abordan los retos inherentes a la gestión tradicional de CAPI a gran escala:

  • Reducción sustancial de la complejidad y la redundancia de YAML

  • Procesos de mantenimiento y actualización optimizados

  • Mejora en la coherencia y la estandarización entre despliegues

  • Mejora en la escalabilidad y las capacidades de automatización

  • Gestión declarativa y control de versiones robusto

clusterclass

29.3 Ejemplo de archivo de aprovisionamiento de CAPI actual

El despliegue de un clúster de Kubernetes que aproveche Cluster API (CAPI) y el proveedor RKE2 requiere la definición de varios recursos personalizados. Estos recursos definen el estado deseado del clúster y su infraestructura subyacente, lo que permite a CAPI orquestar el ciclo de vida del aprovisionamiento y gestión. El fragmento de código siguiente ilustra los tipos de recursos que deben configurarse:

  • Cluster: este recurso encapsula configuraciones generales, incluida la topología de red que regirá la comunicación entre nodos y la detección de servicios. Además, establece los vínculos esenciales con la especificación del plano de control y el recurso del proveedor de infraestructura designado, informando así a CAPI sobre la arquitectura de clúster deseada y la infraestructura subyacente sobre la que se aprovisionará.

  • Metal3Cluster: este recurso define los atributos a nivel de infraestructura exclusivos de Metal3; por ejemplo, el punto final externo a través del cual se podrá acceder al servidor de API de Kubernetes.

  • RKE2ControlPlane: este recurso define las características y el comportamiento de los nodos de plano de control del clúster. Dentro de esta especificación, se configuran parámetros como el número deseado de réplicas del plano de control (fundamental para garantizar una alta disponibilidad y tolerancia a fallos), la versión específica de la distribución de Kubernetes (alineada con la versión elegida de RKE2) y la estrategia para distribuir actualizaciones en los componentes de plano de control. Además, este recurso dicta la interfaz de red de contenedores (CNI) que se empleará dentro del clúster y facilita la inyección de configuraciones específicas del agente, a menudo aprovechando Ignition para el aprovisionamiento automatizado y sin interrupciones de los agentes RKE2 en los nodos de plano de control.

  • Metal3MachineTemplate: este recurso actúa como un modelo para la creación de las instancias de computación individuales que formarán los nodos de trabajador del clúster de Kubernetes, definiendo la imagen que se utilizará.

  • Metal3DataTemplate: como complemento de Metal3MachineTemplate, el recurso Metal3DataTemplate permite especificar metadatos adicionales para los equipos recién aprovisionados.

---
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  name: emea-spa-cluster-3
  namespace: emea-spa
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: emea-spa-cluster-3
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3Cluster
    name: emea-spa-cluster-3
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3Cluster
metadata:
  name: emea-spa-cluster-3
  namespace: emea-spa
spec:
  controlPlaneEndpoint:
    host: 192.168.122.203
    port: 6443
  noCloudProvider: true
---
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
  name: emea-spa-cluster-3
  namespace: emea-spa
spec:
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3MachineTemplate
    name: emea-spa-cluster-3
  replicas: 1
  version: v1.32.4+rke2r1
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 1
  registrationMethod: "control-plane-endpoint"
  registrationAddress: 192.168.122.203
  serverConfig:
    cni: cilium
    cniMultusEnable: true
    tlsSan:
      - 192.168.122.203
      - https://192.168.122.203.sslip.io
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        storage:
          files:
            - 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:
                      - 192.168.122.203/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
        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"
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3MachineTemplate
metadata:
  name: emea-spa-cluster-3
  namespace: emea-spa
spec:
  nodeReuse: True
  template:
    spec:
      automatedCleaningMode: metadata
      dataTemplate:
        name: emea-spa-cluster-3
      hostSelector:
        matchLabels:
          cluster-role: control-plane
          deploy-region: emea-spa
          node: group-3
      image:
        checksum: http://fileserver.local:8080/eibimage-downstream-cluster.raw.sha256
        checksumType: sha256
        format: raw
        url: http://fileserver.local:8080/eibimage-downstream-cluster.raw
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3DataTemplate
metadata:
  name: emea-spa-cluster-3
  namespace: emea-spa
spec:
  clusterName: emea-spa-cluster-3
  metaData:
    objectNames:
      - key: name
        object: machine
      - key: local-hostname
        object: machine
      - key: local_hostname
        object: machine

29.4 Transformación del archivo de aprovisionamiento de CAPI en ClusterClass

29.4.1 Definición de ClusterClass

El siguiente código define un recurso ClusterClass, una plantilla declarativa para desplegar de forma coherente un tipo específico de clúster de Kubernetes. Esta especificación incluye configuraciones comunes de infraestructura y plano de control, lo que permite un aprovisionamiento eficiente y una gestión uniforme del ciclo de vida en toda una flota de clústeres. En el siguiente ejemplo de ClusterClass, algunas variables se sustituirán durante el proceso de instanciación del clúster por los valores reales. En el ejemplo se utilizan las siguientes variables:

  • controlPlaneMachineTemplate: este es el nombre que define la referencia de la plantilla del equipo de plano de control que se va a utilizar.

  • controlPlaneEndpointHost: este es el nombre de host o la dirección IP del punto final del plano de control.

  • tlsSan: este es el nombre alternativo del sujeto TLS para el punto final del plano de control.

El archivo de definición de ClusterClass se basa en los tres recursos siguientes:

  • ClusterClass: este recurso encapsula toda la definición de ClusterClass, incluyendo el plano de control y las plantillas de infraestructura. Además, incluye la lista de variables que se sustituirán durante el proceso de instanciación.

  • RKE2ControlPlaneTemplate: este recurso define la plantilla del plano de control y especifica la configuración deseada para los nodos de plano de control. Incluye parámetros como el número de réplicas, la versión de Kubernetes y la CNI que se va a utilizar. Además, algunos parámetros se sustituirán por los valores correctos durante el proceso de instanciación.

  • Metal3ClusterTemplate: este recurso define la plantilla de infraestructura y especifica la configuración deseada para la infraestructura subyacente. Incluye parámetros como el punto final del plano de control y el indicador noCloudProvider. Además, algunos parámetros se sustituirán por los valores correctos durante el proceso de instanciación.

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlaneTemplate
metadata:
  name: example-controlplane-type2
  namespace: emea-spa
spec:
  template:
    spec:
      infrastructureRef:
        apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
        kind: Metal3MachineTemplate
        name: example-controlplane    # This will be replaced by the patch applied in each cluster instances
        namespace: emea-spa
      replicas: 1
      version: v1.32.4+rke2r1
      rolloutStrategy:
        type: "RollingUpdate"
        rollingUpdate:
          maxSurge: 1
      registrationMethod: "control-plane-endpoint"
      registrationAddress: "default"  # This will be replaced by the patch applied in each cluster instances
      serverConfig:
        cni: cilium
        cniMultusEnable: true
        tlsSan:
          - "default"  # This will be replaced by the patch applied in each cluster instances
      agentConfig:
        format: ignition
        additionalUserData:
          config: |
            default
        kubelet:
          extraArgs:
            - provider-id=metal3://BAREMETALHOST_UUID
        nodeName: "localhost.localdomain"
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3ClusterTemplate
metadata:
  name: example-cluster-template-type2
  namespace: emea-spa
spec:
  template:
    spec:
      controlPlaneEndpoint:
        host: "default"  # This will be replaced by the patch applied in each cluster instances
        port: 6443
      noCloudProvider: true
---
apiVersion: cluster.x-k8s.io/v1beta1
kind: ClusterClass
metadata:
  name: example-clusterclass-type2
  namespace: emea-spa
spec:
  variables:
    - name: controlPlaneMachineTemplate
      required: true
      schema:
        openAPIV3Schema:
          type: string
    - name: controlPlaneEndpointHost
      required: true
      schema:
        openAPIV3Schema:
          type: string
    - name: tlsSan
      required: true
      schema:
        openAPIV3Schema:
          type: array
          items:
            type: string
  infrastructure:
    ref:
      kind: Metal3ClusterTemplate
      apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
      name: example-cluster-template-type2
  controlPlane:
    ref:
      kind: RKE2ControlPlaneTemplate
      apiVersion: controlplane.cluster.x-k8s.io/v1beta1
      name: example-controlplane-type2
  patches:
    - name: setControlPlaneMachineTemplate
      definitions:
        - selector:
            apiVersion: controlplane.cluster.x-k8s.io/v1beta1
            kind: RKE2ControlPlaneTemplate
            matchResources:
              controlPlane: true
          jsonPatches:
            - op: replace
              path: "/spec/template/spec/infrastructureRef/name"
              valueFrom:
                variable: controlPlaneMachineTemplate
    - name: setControlPlaneEndpoint
      definitions:
        - selector:
            apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
            kind: Metal3ClusterTemplate
            matchResources:
              infrastructureCluster: true  # Added to select InfraCluster
          jsonPatches:
            - op: replace
              path: "/spec/template/spec/controlPlaneEndpoint/host"
              valueFrom:
                variable: controlPlaneEndpointHost
    - name: setRegistrationAddress
      definitions:
        - selector:
            apiVersion: controlplane.cluster.x-k8s.io/v1beta1
            kind: RKE2ControlPlaneTemplate
            matchResources:
              controlPlane: true  # Added to select ControlPlane
          jsonPatches:
            - op: replace
              path: "/spec/template/spec/registrationAddress"
              valueFrom:
                variable: controlPlaneEndpointHost
    - name: setTlsSan
      definitions:
        - selector:
            apiVersion: controlplane.cluster.x-k8s.io/v1beta1
            kind: RKE2ControlPlaneTemplate
            matchResources:
              controlPlane: true  # Added to select ControlPlane
          jsonPatches:
            - op: replace
              path: "/spec/template/spec/serverConfig/tlsSan"
              valueFrom:
                variable: tlsSan
    - name: updateAdditionalUserData
      definitions:
        - selector:
            apiVersion: controlplane.cluster.x-k8s.io/v1beta1
            kind: RKE2ControlPlaneTemplate
            matchResources:
              controlPlane: true
          jsonPatches:
            - op: replace
              path: "/spec/template/spec/agentConfig/additionalUserData"
              valueFrom:
                template: |
                  config: |
                    variant: fcos
                    version: 1.4.0
                    storage:
                      files:
                        - 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:
                                  - {{ .controlPlaneEndpointHost }}/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
                    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

29.4.2 Definición de la instancia del clúster

En el contexto de ClusterClass, una instancia de clúster es una instancia concreta y en ejecución de un clúster creado a partir de una ClusterClass definida. Representa un despliegue concreto con sus configuraciones, recursos y estado operativo únicos, que se derivan directamente del modelo especificado en la ClusterClass. Esto incluye el conjunto específico de equipos, configuraciones de red y componentes de Kubernetes asociados que se están ejecutando activamente. Comprender la instancia del clúster es fundamental para gestionar su ciclo de vida, realizar actualizaciones, ejecutar operaciones de escalado y supervisar un clúster desplegado concreto que se ha aprovisionado utilizando el marco ClusterClass.

Para definir una instancia de clúster, debemos definir los siguientes recursos:

  • Cluster

  • Metal3MachineTemplate

  • Metal3DataTemplate

Las variables definidas previamente en la plantilla (archivo de definición de ClusterClass) se sustituirán por los valores finales para esta instanciación del clúster:

apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  name: emea-spa-cluster-3
  namespace: emea-spa
spec:
  topology:
    class: example-clusterclass-type2  # Correct way to reference ClusterClass
    version: v1.32.4+rke2r1
    controlPlane:
      replicas: 1
    variables:                         # Variables to be replaced for this cluster instance
      - name: controlPlaneMachineTemplate
        value: emea-spa-cluster-3-machinetemplate
      - name: controlPlaneEndpointHost
        value: 192.168.122.203
      - name: tlsSan
        value:
          - 192.168.122.203
          - https://192.168.122.203.sslip.io
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3MachineTemplate
metadata:
  name: emea-spa-cluster-3-machinetemplate
  namespace: emea-spa
spec:
  nodeReuse: True
  template:
    spec:
      automatedCleaningMode: metadata
      dataTemplate:
        name: emea-spa-cluster-3
      hostSelector:
        matchLabels:
          cluster-role: control-plane
          deploy-region: emea-spa
          cluster-type: type2
      image:
        checksum: http://fileserver.local:8080/eibimage-downstream-cluster.raw.sha256
        checksumType: sha256
        format: raw
        url: http://fileserver.local:8080/eibimage-downstream-cluster.raw
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3DataTemplate
metadata:
  name: emea-spa-cluster-3
  namespace: emea-spa
spec:
  clusterName: emea-spa-cluster-3
  metaData:
    objectNames:
      - key: name
        object: machine
      - key: local-hostname
        object: machine

Este enfoque permite un proceso más ágil, ya que es posible desplegar un clúster con solo 3 recursos una vez que se ha definido ClusterClass.

Parte IV Consejos y trucos

Consejos y trucos para componentes de Edge

  • 30 Edge Image Builder
  • Si se encuentra en un entorno que no sea Linux y sigue estas instrucciones para crear una imagen, es probable que esté ejecutando Podman a través de una máquina virtual. De forma predeterminada, esta máquina virtual estará configurada para tener asignada una pequeña cantidad de recursos del sistema,…

  • 31 Elemental
  • Cuando se utiliza RKE2 o K3s, es necesario exponer los servicios (Rancher en este contexto) desde el clúster de gestión, ya que no están expuestos de forma predeterminada. En RKE2, hay un controlador Ingress NGINX, y en k3s utiliza Traefik. El flujo de trabajo actual sugiere utilizar MetalLB para an…

30 Edge Image Builder

30.1 Comunes

  • Si se encuentra en un entorno que no sea Linux y sigue estas instrucciones para crear una imagen, es probable que esté ejecutando Podman a través de una máquina virtual. De forma predeterminada, esta máquina virtual estará configurada para tener asignada una pequeña cantidad de recursos del sistema, lo que puede provocar inestabilidad en Edge Image Builder durante operaciones que consumen muchos recursos, como el proceso de resolución de RPM. Deberá ajustar los recursos de la máquina de Podman, ya sea utilizando Podman Desktop (icono de configuración → icono de edición de máquina de Podman) o directamente mediante el comando podman-machine-set.

  • En este momento, Edge Image Builder no puede crear imágenes en una configuración de arquitectura cruzada, es decir, debe ejecutarlo en:

    • Sistemas AArch64 (como Apple Silicon) para crear imágenes aarch64 de SL Micro

    • Sistemas AMD64/Intel 64 para crear imágenes x86_64 de SL Micro

30.2 Kubernetes

  • Para crear clústeres de Kubernetes de varios nodos, es necesario ajustar la sección kubernetes del archivo de definición para:

    • Mostrar todos los nodos de servidor y agente de kubernetes.nodes

    • Establecer una dirección IP virtual que se utilizaría para que todos los nodos no inicializadores se unan al clúster en kubernetes.network.apiVIP

    • Opcionalmente, configurar un host de API para especificar una dirección de dominio de acceso al clúster en kubernetes.network.apiHost. Para obtener más información sobre esta configuración, consulte la sección sobre Kubernetes de la documentación.

  • Edge Image Builder se basa en los nombres de host de los diferentes nodos para determinar su tipo de Kubernetes (server o agent). Aunque esta configuración se gestiona en el archivo de definición, para la configuración general de red de las máquinas podemos utilizar la configuración DHCP, tal y como se describe en el Capítulo 12, Conexiones de red de Edge.

31 Elemental

31.1 Comunes

31.1.1 Exposición del servicio Rancher

Cuando se utiliza RKE2 o K3s, es necesario exponer los servicios (Rancher en este contexto) desde el clúster de gestión, ya que no están expuestos de forma predeterminada. En RKE2, hay un controlador Ingress NGINX, y en k3s utiliza Traefik. El flujo de trabajo actual sugiere utilizar MetalLB para anunciar un servicio (con el modo L2 o con BGP) y el controlador de Ingress correspondiente para crear un objeto Ingress a través de HelmChartConfig, ya que la creación de un nuevo objeto Ingress anularía la configuración existente.

  1. Instale Rancher Prime (mediante Helm) y configure los valores necesarios.

    hostname: rancher-192.168.64.101.sslip.io
    replicas: 1
    bootstrapPassword: Admin
    global.cattle.psp.enabled: "false"
    Sugerencia
    Sugerencia

    Siga las instrucciones para la instalación de Rancher de la documentación para obtener más detalles.

  2. Cree un servicio LoadBalancer para exponer Rancher.

    kubectl apply -f - <<EOF
    apiVersion: helm.cattle.io/v1
    kind: HelmChartConfig
    metadata:
      name: rke2-ingress-nginx
      namespace: kube-system
    spec:
      valuesContent: |-
        controller:
          config:
            use-forwarded-headers: "true"
            enable-real-ip: "true"
          publishService:
            enabled: true
          service:
            enabled: true
            type: LoadBalancer
            externalTrafficPolicy: Local
    EOF
  3. Cree un pool de direcciones IP para el servicio utilizando la dirección IP que hemos configurado anteriormente en los valores de Helm.

    kubectl apply -f - <<EOF
    apiVersion: metallb.io/v1beta1
    kind: IPAddressPool
    metadata:
      name: ingress-ippool
      namespace: metallb-system
    spec:
      addresses:
      - 192.168.64.101/32
      serviceAllocation:
        priority: 100
        serviceSelectors:
        - matchExpressions:
          - {key: app.kubernetes.io/name, operator: In, values: [rke2-ingress-nginx]}
    EOF
  4. Crear un anuncio L2 para el pool de direcciones IP.

    kubectl apply -f - <<EOF
    apiVersion: metallb.io/v1beta1
    kind: L2Advertisement
    metadata:
      name: ingress-l2-adv
      namespace: metallb-system
    spec:
      ipAddressPools:
      - ingress-ippool
    EOF
  5. Asegúrese de que Elemental se ha instalado correctamente.

    1. Instale el operador de Elemental y la interfaz del usuario de Elemental en los nodos de gestión.

    2. Añada la configuración de Elemental en el nodo descendente junto con un código de registro, ya que eso hará que Edge Image Builder incluya la opción de registro remoto para el equipo.

Sugerencia
Sugerencia

Consulte la Sección 2.5, “Instalación de Elemental” y la Sección 2.6, “Configuración de Elemental” para obtener información adicional y ejemplos.

31.2 Específicos del hardware

31.2.1 Trusted Platform Module

Es necesario gestionar correctamente la configuración del módulo de plataforma segura Trusted Platform Module (TPM). Si no se hace, se producirán errores como este:

Nov 25 18:17:06 eled elemental-register[4038]: Error: registering machine: cannot generate authentication token: opening tpm for getting attestation data: TPM device not available

Esto se puede mitigar con uno de estos enfoques:

  • Habilite TPM en la configuración de la máquina virtual

Ejemplo con UTM en MacOS

TPM
  • Emule TPM utilizando un valor negativo para la semilla de TPM en el recurso MachineRegistration.

apiVersion: elemental.cattle.io/v1beta1
kind: MachineRegistration
metadata:
  name: ...
  namespace: ...
spec:
    ...
    elemental:
      ...
      registration:
        emulate-tpm: true
        emulated-tpm-seed: -1
  • Inhabilite TPM en el recurso MachineRegistration.

apiVersion: elemental.cattle.io/v1beta1
kind: MachineRegistration
metadata:
  name: ...
  namespace: ...
spec:
    ...
    elemental:
      ...
      registration:
        emulate-tpm: false

Parte V Integración de productos de otros fabricantes

Integración de herramientas de terceros

  • 32 NATS
  • NATS es una tecnología de conectividad diseñada para un mundo cada vez más hiperconectado. Se trata de una tecnología única que permite a las aplicaciones comunicarse de forma segura a través de cualquier combinación de proveedores de la nube, instalaciones locales, dispositivos periféricos, Web y m…

  • 33 GPU NVIDIA en SUSE Linux Micro
  • Esta guía muestra cómo implementar compatibilidad con GPU NVIDIA a nivel de host mediante controladores de código abierto creados previamente en SUSE Linux Micro 6.1. Estos controladores están integrados en el sistema operativo, en lugar de cargarse de forma dinámica mediante el operador GPU Operato…

32 NATS

NATS es una tecnología de conectividad diseñada para un mundo cada vez más hiperconectado. Se trata de una tecnología única que permite a las aplicaciones comunicarse de forma segura a través de cualquier combinación de proveedores de la nube, instalaciones locales, dispositivos periféricos, Web y móviles. NATS consta de una familia de productos de código abierto estrechamente integrados, pero que pueden desplegarse de forma independiente y sencilla. NATS se utiliza en miles de empresas de todo el mundo y abarca casos de uso que incluyen microservicios, edge computing, dispositivos móviles e IoT. También se puede utilizar para ampliar o sustituir la mensajería tradicional.

32.1 Arquitectura

NATS es una infraestructura que permite el intercambio de datos entre aplicaciones en forma de mensajes.

32.1.1 Aplicaciones cliente de NATS

Las bibliotecas cliente NATS permiten que las aplicaciones publiquen, se suscriban, soliciten y respondan entre diferentes instancias. Estas aplicaciones se denominan generalmente aplicaciones cliente.

32.1.2 Infraestructura de servicios NATS

Los servicios NATS son proporcionados por uno o varios procesos de servidor NATS configurados para interconectarse entre sí y ofrecer una infraestructura. Esta infraestructura puede escalarse desde un único proceso de servidor NATS que se ejecuta en un dispositivo final hasta un superclúster global público compuesto por muchos clústeres que abarca todos los principales proveedores de nube y todas las regiones del mundo.

32.1.3 Diseño de mensajería sencillo

Con NATS, las aplicaciones pueden comunicarse fácilmente enviando y recibiendo mensajes. Estos mensajes se dirigen e identifican mediante cadenas de asunto y no dependen de la ubicación de la red. Los datos se cifran y se estructuran como mensajes, y son enviados por un editor. El mensaje es recibido, descifrado y procesado por uno o varios suscriptores.

32.1.4 NATS JetStream

NATS cuenta con un sistema de persistencia distribuida integrado llamado JetStream. JetStream se creó para resolver los problemas de transmisión identificados de la tecnología actual: complejidad, fragilidad y falta de escalabilidad. JetStream también resuelve el problema del acoplamiento entre el editor y el suscriptor (los suscriptores deben estar activos y en funcionamiento para recibir el mensaje cuando se publica). Para obtener más información sobre NATS JetStream, consulte este documento.

32.2 Instalación

32.2.1 Instalación de NATS sobre K3s

NATS está diseñado para múltiples arquitecturas, por lo que se puede instalar fácilmente en K3s (Capítulo 15, K3s).

Vamos a crear un archivo de valores para sobrescribir los valores predeterminados de NATS.

cat > values.yaml <<EOF
cluster:
  # Enable the HA setup of the NATS
  enabled: true
  replicas: 3

nats:
  jetstream:
    # Enable JetStream
    enabled: true

    memStorage:
      enabled: true
      size: 2Gi

    fileStorage:
      enabled: true
      size: 1Gi
      storageDirectory: /data/
EOF

Ahora, se instala NATS mediante Helm:

helm repo add nats https://nats-io.github.io/k8s/helm/charts/
helm install nats nats/nats --namespace nats --values values.yaml \
 --create-namespace

Con el archivo values.yaml anterior, los componentes siguientes estarán en el espacio de nombres nats:

  1. Una versión de alta disponibilidad de NATS Statefulset que incluye tres contenedores: el servidor de NATS, el recargador de configuración y sidecars de métricas.

  2. Un contenedor de caja de NATS, que incluye un conjunto de utilidades NATS que se pueden utilizar para verificar la configuración.

  3. JetStream también aprovecha su interfaz final de clave-valor incluida con PVC vinculados a los pods.

32.2.1.1 Prueba de la configuración

kubectl exec -n nats -it deployment/nats-box -- /bin/sh -l
  1. Cree una suscripción de prueba:

    nats sub test &
  2. Envíe un mensaje de prueba:

    nats pub test hi

32.2.1.2 Limpieza

helm -n nats uninstall nats
rm values.yaml

32.2.2 NATS como interfaz final para K3s

Uno de los componentes que aprovecha K3s es KINE, que es un shim que permite sustituir etcd por interfaces finales de almacenamiento alternativas destinadas originalmente a bases de datos relacionales. Dado que JetStream proporciona una API de clave-valor, esto hace posible utilizar NATS como interfaz final para el clúster K3s.

Ya existe una solicitud para simplificar la integración de NATS en K3s, pero los cambios aún no se han incluido en las versiones de K3s.

Por eso, el binario de K3s debe crearse manualmente.

32.2.2.1 Creación de K3s

git clone --depth 1 https://github.com/k3s-io/k3s.git && cd k3s

El siguiente comando añade nats en las etiquetas de creación para habilitar la integración de NATS en K3s:

sed -i '' 's/TAGS="ctrd/TAGS="nats ctrd/g' scripts/build
make local

Sustituya <node-ip> con la IP real del nodo donde se iniciará K3s:

export NODE_IP=<node-ip>
sudo scp dist/artifacts/k3s-arm64 ${NODE_IP}:/usr/local/bin/k3s
Nota
Nota

Para crear K3s localmente se necesita el complemento buildx Docker CLI. Se puede instalar manualmente si $ make local falla.

32.2.2.2 Instalación de la interfaz de línea de comandos de NATS

TMPDIR=$(mktemp -d)
nats_version="nats-0.0.35-linux-arm64"
curl -o "${TMPDIR}/nats.zip" -sfL https://github.com/nats-io/natscli/releases/download/v0.0.35/${nats_version}.zip
unzip "${TMPDIR}/nats.zip" -d "${TMPDIR}"

sudo scp ${TMPDIR}/${nats_version}/nats ${NODE_IP}:/usr/local/bin/nats
rm -rf ${TMPDIR}

32.2.2.3 Ejecución de NATS como interfaz final de K3s

Vamos a usar ssh en el nodo y a ejecutar K3s con el indicador --datastore-endpoint apuntando a nats.

Nota
Nota

El siguiente comando inicia K3s como un proceso en primer plano, por lo que es posible consultar fácilmente en el registro si hay algún problema. Para no bloquear el terminal actual, se puede añadir el indicador & antes del comando para iniciarlo como un proceso en segundo plano.

k3s server  --datastore-endpoint=nats://
Nota
Nota

Para hacer permanente el servidor K3s con la interfaz final de NATS en su máquina virtual slemicro, puede ejecutar el siguiente guion, que crea un servicio systemd con la configuración necesaria.

export INSTALL_K3S_SKIP_START=false
export INSTALL_K3S_SKIP_DOWNLOAD=true

curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server \
 --datastore-endpoint=nats://"  sh -

32.2.2.4 Solución de problemas

Los siguientes comandos se pueden ejecutar en el nodo para verificar que todo lo relacionado con la transmisión funciona correctamente:

nats str report -a
nats str view -a

33 GPU NVIDIA en SUSE Linux Micro

33.1 Introducción

Esta guía muestra cómo implementar compatibilidad con GPU NVIDIA a nivel de host mediante controladores de código abierto creados previamente en SUSE Linux Micro 6.1. Estos controladores están integrados en el sistema operativo, en lugar de cargarse de forma dinámica mediante el operador GPU Operator de NVIDIA. Esta configuración es muy recomendable para los clientes que desean integrar previamente todos los artefactos necesarios para el despliegue en la imagen y en cuando sea necesario seleccionar dinámicamente la versión del controlador; es decir, que el usuario pueda seleccionar la versión del controlador a través de Kubernetes. Al principio de esta guía se explica cómo desplegar los componentes adicionales en un sistema que ya ha sido desplegado previamente, y continúa con una sección donde se describe cómo integrar esta configuración en el despliegue inicial mediante Edge Image Builder. Si no desea repasar los conceptos básicos y configurarlo todo manualmente, pase directamente a esa sección.

Es importante destacar que la asistencia para estos controladores la proporcionan tanto SUSE como NVIDIA en estrecha colaboración, y que el controlador ha sido creado y lo proporciona SUSE como parte de los repositorios de paquetes. Sin embargo, si tiene alguna duda o pregunta sobre la combinación en la que utiliza los controladores, solicite ayuda adicional a sus gestores de cuentas de SUSE o NVIDIA. Si tiene previsto utilizar NVIDIA AI Enterprise (NVAIE), asegúrese de que está utilizando una GPU certificada para NVAIE, lo que puede requerir el uso de controladores de NVIDIA. Si no está seguro, consulte con su representante de NVIDIA.

Esta guía no incluye más información sobre la integración del operador GPU de NVIDIA. Aunque no trata sobre la integración del operador de GPU de NVIDIA para Kubernetes, puede seguir la mayoría de los pasos de esta guía para configurar el sistema operativo subyacente y, simplemente, habilitar el operador de GPU para que utilice los controladores preinstalados mediante el indicador driver.enabled=false en el chart de Helm del operador de GPU NVIDIA, donde bastará con seleccionar los controladores instalados en el host. Encontrará instrucciones más completas de NVIDIA en este documento.

33.2 Requisitos previos

Si está siguiendo esta guía, se da por hecho que ya dispone de lo siguiente:

  • Al menos un host con SUSE Linux Micro 6.1 instalado; puede ser físico o virtual.

  • Sus hosts están vinculados a una suscripción obligatoria para poder acceder al paquete. Hay una versión de evaluación disponible aquí.

  • Una GPU NVIDIA compatible instalada (o transferida completamente a la máquina virtual en la que se ejecute SUSE Linux Micro).

  • Acceso al usuario root: estas instrucciones dan por sentado que usted es el usuario root y que no está derivando sus privilegios mediante sudo.

33.3 Instalación manual

En esta sección, va a instalar los controladores de NVIDIA directamente en el sistema operativo SUSE Linux Micro, ya que el controlador de código abierto de NVIDIA ahora forma parte de los repositorios de paquetes principales de SUSE Linux Micro. De esta forma, basta con instalar los paquetes RPM necesarios. No es necesario compilar ni descargar paquetes ejecutables. A continuación, le guiaremos a través del despliegue de la generación "G06" del controlador, que admite las GPU más recientes (consulte este documento para obtener más información). Debe seleccionar la generación adecuada del controlador de GPU de NVIDIA de su sistema. Para las GPU modernas, el controlador "G06" es la opción más habitual.

Antes de comenzar, tenga en cuenta que, además del controlador de código abierto de NVIDIA que SUSE incluye en SUSE Linux Micro, es posible que necesite componentes adicionales de NVIDIA para su configuración. Por ejemplo, bibliotecas OpenGL, kits de herramientas CUDA, utilidades de línea de comandos como nvidia-smi y componentes de integración de contenedores como nvidia-container-toolkit. SUSE no suministra muchos de estos componentes, ya sea porque son software propiedad de NVIDIA o porque no tiene sentido que los suministremos nosotros en lugar de NVIDIA. Por lo tanto, como parte de las instrucciones, configuraremos repositorios adicionales que nos den acceso a dichos componentes y veremos algunos ejemplos de uso de estas herramientas, de modo que el sistema resultante será totalmente funcional. Es importante distinguir entre los repositorios de SUSE y los de NVIDIA, ya que en ocasiones puede haber una discrepancia entre las versiones de los paquetes que NVIDIA pone a disposición y las que SUSE ha creado. Esto suele ocurrir cuando SUSE lanza una nueva versión del controlador de código abierto y pasan un par de días antes de que los paquetes equivalentes estén disponibles en los repositorios de NVIDIA.

Le recomendamos que se asegure de que la versión del controlador que selecciona sea compatible con su GPU y cumpla con los requisitos de CUDA que pueda tener. Compruebe lo siguiente:

Sugerencia
Sugerencia

Para localizar las versiones del controlador de código abierto de NVIDIA, ejecute zypper se -s nvidia-open-driver en el equipo de destino o busque "nvidia-open-driver" en el Centro de servicios al cliente de SUSE en SUSE Linux Micro 6.1 para AMD64/Intel 64.

Centro de servicios al cliente de SUSE

Cuando haya confirmado que hay una versión equivalente disponible en los repositorios de NVIDIA, podrá instalar los paquetes en el sistema operativo host. Para ello, debemos abrir una sesión transactional-update, que crea una nueva instantánea de lectura/escritura del sistema operativo subyacente para que podamos realizar cambios en la plataforma inmutable (para obtener más instrucciones sobre transactional-update, consulte este documento):

transactional-update shell

Cuando acceda a la shell transactional-update, añada un repositorio de paquetes adicional de NVIDIA. Esto nos permite incorporar utilidades adicionales, por ejemplo, nvidia-smi:

zypper ar https://download.nvidia.com/suse/sle15sp6/ nvidia-suse-main
zypper --gpg-auto-import-keys refresh

A continuación, puede instalar el controlador y nvidia-compute-utils para obtener utilidades adicionales. Si no necesita las utilidades, puede omitirlas, pero para fines de prueba, vale la pena instalarlas en esta etapa:

zypper install -y --auto-agree-with-licenses nvidia-open-driver-G06-signed-kmp nvidia-compute-utils-G06
Nota
Nota

Si la instalación falla, podría deberse a una incompatibilidad entre la versión del controlador seleccionada y la que NVIDIA incluye en sus repositorios. Consulte la sección anterior para verificar que las versiones coincidan. Pruebe a instalar una versión diferente del controlador. Por ejemplo, si los repositorios de NVIDIA tienen una versión anterior, puede especificar nvidia-open-driver-G06-signed-kmp=550.54.14 en su comando de instalación para especificar una versión que coincida.

A continuación, si no utiliza una GPU compatible (recuerde que la lista está aquí), puede comprobar si el controlador funciona habilitando la compatibilidad a nivel de módulo, pero los resultados pueden variar. Omita este paso si utiliza una GPU compatible:

sed -i '/NVreg_OpenRmEnableUnsupportedGpus/s/^#//g' /etc/modprobe.d/50-nvidia-default.conf

Ahora que ha instalado estos paquetes, es el momento de salir de la sesión transactional-update:

exit
Nota
Nota

Asegúrese de haber salido de la sesión transactional-update antes de continuar.

Después de instalar los controladores, reinicie. Dado que SUSE Linux Micro es un sistema operativo inmutable, es necesario reiniciar en la nueva instantánea que ha creado en el paso anterior. Los controladores solo se instalan en esta nueva instantánea, por lo que no es posible cargarlos sin reiniciar en ella, lo cual se realiza automáticamente. Ejecute el comando de reinicio cuando esté listo:

reboot

Una vez que el sistema se haya reiniciado correctamente, vuelva a iniciar sesión y use la herramienta nvidia-smi para comprobar que el controlador se ha cargado correctamente y que puede acceder y mostrar sus GPU:

nvidia-smi

El resultado de este comando debería mostrar algo similar a lo siguiente, teniendo en cuenta que en este ejemplo tenemos dos GPU:

+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 545.29.06              Driver Version: 545.29.06    CUDA Version: 12.3     |
|-----------------------------------------+----------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |         Memory-Usage | GPU-Util  Compute M. |
|                                         |                      |               MIG M. |
|=========================================+======================+======================|
|   0  NVIDIA A100-PCIE-40GB          Off | 00000000:17:00.0 Off |                    0 |
| N/A   29C    P0              35W / 250W |      4MiB / 40960MiB |      0%      Default |
|                                         |                      |             Disabled |
+-----------------------------------------+----------------------+----------------------+
|   1  NVIDIA A100-PCIE-40GB          Off | 00000000:CA:00.0 Off |                    0 |
| N/A   30C    P0              33W / 250W |      4MiB / 40960MiB |      0%      Default |
|                                         |                      |             Disabled |
+-----------------------------------------+----------------------+----------------------+

+---------------------------------------------------------------------------------------+
| Processes:                                                                            |
|  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
|        ID   ID                                                             Usage      |
|=======================================================================================|
|  No running processes found                                                           |
+---------------------------------------------------------------------------------------+

Con esto concluye el proceso de instalación y verificación de los controladores NVIDIA en su sistema SUSE Linux Micro.

33.4 Validación adicional de la instalación manual

En esta fase, lo único que hemos podido verificar es que, a nivel del host, se puede acceder al dispositivo NVIDIA y que los controladores se cargan correctamente. Sin embargo, si queremos asegurarnos de que funcionan, una prueba sencilla sería validar que la GPU puede recibir instrucciones de una aplicación del espacio de usuarios, idealmente a través de un contenedor y mediante la biblioteca CUDA, ya que eso es lo que normalmente utilizaría una carga de trabajo real. Para ello, podemos realizar una modificación adicional en el sistema operativo del host instalando nvidia-container-toolkit (NVIDIA Container Toolkit). En primer lugar, abra otra shell transactional-update, teniendo en cuenta que podríamos haberlo hecho en una sola transacción en el paso anterior. Veremos cómo hacerlo de forma totalmente automatizada en una sección posterior:

transactional-update shell

A continuación, instale el paquete nvidia-container-toolkit desde el repositorio de NVIDIA Container Toolkit:

  • El archivo nvidia-container-toolkit.repo que aparece a continuación contiene un repositorio estable (nvidia-container-toolkit) y otro experimental (nvidia-container-toolkit-experimental). Se recomienda utilizar el repositorio estable para uso en producción. El repositorio experimental está inhabilitado de forma predeterminada.

zypper ar https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo
zypper --gpg-auto-import-keys install -y nvidia-container-toolkit

Cuando esté listo, puede salir de la shell transactional-update:

exit

... y reiniciar el equipo en la nueva instantánea:

reboot
Nota
Nota

Como antes, debe asegurarse de que ha salido de transactional-shell y ha reiniciado el equipo para que los cambios surtan efecto.

Una vez reiniciada el equipo, compruebe que el sistema puede mostrar correctamente los dispositivos que usan NVIDIA Container Toolkit. El resultado debe ser detallado, con mensajes INFO y WARN, pero sin mensajes ERROR:

nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml

Esto garantiza que cualquier contenedor iniciado en el equipo pueda emplear los dispositivos GPU NVIDIA que se hayan detectado. Cuando esté listo, ejecute un contenedor basado en Podman. Ejecutarlo con Podman es una buena forma de validar el acceso al dispositivo NVIDIA desde dentro de un contenedor, lo que debería dar confianza para hacer lo mismo con Kubernetes en una fase posterior. Otorgue a Podman acceso a los dispositivos NVIDIA etiquetados que se gestionaron con el comando anterior, basándose en SLE BCI y ejecute el comando Bash:

podman run --rm --device nvidia.com/gpu=all --security-opt=label=disable -it registry.suse.com/bci/bci-base:latest bash

Ahora ejecutará comandos desde un contenedor de Podman temporal. No tiene acceso a su sistema subyacente y es efímero, por lo que cualquier acción que realicemos aquí no será permanente y no debería poder dañar nada en el host subyacente. Como ahora estamos en un contenedor, podemos instalar las bibliotecas CUDA necesarias, comprobando de nuevo la versión correcta de CUDA para su controlador aquí, aunque el resultado anterior de nvidia-smi debería mostrar la versión de CUDA necesaria. En el ejemplo siguiente, vamos a instalar CUDA 12.3 y a extraer muchos ejemplos, demostraciones y kits de desarrollo para que pueda validar completamente la GPU:

zypper ar https://developer.download.nvidia.com/compute/cuda/repos/sles15/x86_64/ cuda-suse
zypper in -y cuda-libraries-devel-12-3 cuda-minimal-build-12-3 cuda-demo-suite-12-3

Cuando se haya instalado correctamente, no salga del contenedor. Ejecutaremos el ejemplo de CUDA deviceQuery, que valida de forma exhaustiva el acceso a la GPU a través de CUDA, y desde el propio contenedor:

/usr/local/cuda-12/extras/demo_suite/deviceQuery

Si todo va bien, debería ver un resultado similar al siguiente. Fíjese en el mensaje Result = PASS al final del comando y en que, en el resultado, el sistema identifica correctamente dos GPU, mientras que es posible que su entorno solo tenga una:

/usr/local/cuda-12/extras/demo_suite/deviceQuery Starting...

 CUDA Device Query (Runtime API) version (CUDART static linking)

Detected 2 CUDA Capable device(s)

Device 0: "NVIDIA A100-PCIE-40GB"
  CUDA Driver Version / Runtime Version          12.2 / 12.1
  CUDA Capability Major/Minor version number:    8.0
  Total amount of global memory:                 40339 MBytes (42298834944 bytes)
  (108) Multiprocessors, ( 64) CUDA Cores/MP:     6912 CUDA Cores
  GPU Max Clock rate:                            1410 MHz (1.41 GHz)
  Memory Clock rate:                             1215 Mhz
  Memory Bus Width:                              5120-bit
  L2 Cache Size:                                 41943040 bytes
  Maximum Texture Dimension Size (x,y,z)         1D=(131072), 2D=(131072, 65536), 3D=(16384, 16384, 16384)
  Maximum Layered 1D Texture Size, (num) layers  1D=(32768), 2048 layers
  Maximum Layered 2D Texture Size, (num) layers  2D=(32768, 32768), 2048 layers
  Total amount of constant memory:               65536 bytes
  Total amount of shared memory per block:       49152 bytes
  Total number of registers available per block: 65536
  Warp size:                                     32
  Maximum number of threads per multiprocessor:  2048
  Maximum number of threads per block:           1024
  Max dimension size of a thread block (x,y,z): (1024, 1024, 64)
  Max dimension size of a grid size    (x,y,z): (2147483647, 65535, 65535)
  Maximum memory pitch:                          2147483647 bytes
  Texture alignment:                             512 bytes
  Concurrent copy and kernel execution:          Yes with 3 copy engine(s)
  Run time limit on kernels:                     No
  Integrated GPU sharing Host Memory:            No
  Support host page-locked memory mapping:       Yes
  Alignment requirement for Surfaces:            Yes
  Device has ECC support:                        Enabled
  Device supports Unified Addressing (UVA):      Yes
  Device supports Compute Preemption:            Yes
  Supports Cooperative Kernel Launch:            Yes
  Supports MultiDevice Co-op Kernel Launch:      Yes
  Device PCI Domain ID / Bus ID / location ID:   0 / 23 / 0
  Compute Mode:
     < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >

Device 1: <snip to reduce output for multiple devices>
     < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >
> Peer access from NVIDIA A100-PCIE-40GB (GPU0) -> NVIDIA A100-PCIE-40GB (GPU1) : Yes
> Peer access from NVIDIA A100-PCIE-40GB (GPU1) -> NVIDIA A100-PCIE-40GB (GPU0) : Yes

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 12.3, CUDA Runtime Version = 12.3, NumDevs = 2, Device0 = NVIDIA A100-PCIE-40GB, Device1 = NVIDIA A100-PCIE-40GB
Result = PASS

Desde aquí, puede continuar ejecutando cualquier otra carga de trabajo CUDA. Utilice compiladores y cualquier otro aspecto del ecosistema CUDA para realizar más pruebas. Cuando haya terminado, puede salir del contenedor, pero tenga en cuenta que todo lo que haya instalado en él es efímero (por lo que se perderá) y no ha afectado al sistema operativo subyacente:

exit

33.5 Implementación con Kubernetes

Ahora que hemos probado la instalación y el uso del controlador de código abierto de NVIDIA en SUSE Linux Micro, veamos cómo configurar Kubernetes en el mismo equipo. Esta guía no le guiará a través del despliegue de Kubernetes, pero se entiende que ha instalado K3s o RKE2 y que su kubeconfig se ha configurado en consecuencia, de modo que puede ejecutar como superusuario los comandos estándares de kubectl. Se sobrentiende que su nodo forma un clúster de un solo nodo, aunque los pasos básicos deberían ser similares para clústeres de varios nodos. En primer lugar, asegúrese de que su acceso a kubectl funciona:

kubectl get nodes

Esto debería mostrar algo similar a lo siguiente:

NAME       STATUS   ROLES                       AGE   VERSION
node0001   Ready    control-plane,etcd,master   13d   v1.32.4+rke2r1

Debería ver que su instalación de k3s/rke2 ha detectado NVIDIA Container Toolkit en el host y ha configurado automáticamente la integración del entorno de ejecución de NVIDIA en containerd (la interfaz de entorno de ejecución de contenedores que utiliza k3s/rke2). Confírmelo comprobando el archivo config.toml de containerd:

tail -n8 /var/lib/rancher/rke2/agent/etc/containerd/config.toml

El resultado debe ser similar a lo siguiente. La ubicación equivalente de K3s es /var/lib/rancher/k3s/agent/etc/containerd/config.toml:

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes."nvidia"]
  runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes."nvidia".options]
  BinaryName = "/usr/bin/nvidia-container-runtime"
Nota
Nota

Si estas entradas no están presentes, es posible que la detección haya fallado. Podría deberse a que el equipo o los servicios de Kubernetes no se han reiniciado. Si es necesario, añádalos manualmente como se indica anteriormente.

A continuación, debemos configurar RuntimeClass de NVIDIA como entorno de ejecución adicional al predeterminado de Kubernetes, lo que garantiza que cualquier solicitud de pods que haga el usuario y que necesite acceder a la GPU pueda utilizar NVIDIA Container Toolkit para hacerlo, a través de nvidia-container-runtime, tal y como se configura en containerd:

kubectl apply -f - <<EOF
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: nvidia
handler: nvidia
EOF

El siguiente paso es configurar el complemento de dispositivos de NVIDIA. Este complemento configura Kubernetes para aprovechar las GPU NVIDIA como recursos que se pueden utilizar dentro del clúster, en combinación con NVIDIA Container Toolkit. Esta herramienta detecta inicialmente todas las capacidades del host subyacente, incluidas las GPU, los controladores y otras (como GL) y, luego, permite solicitar recursos de GPU y consumirlos como parte de sus aplicaciones.

Primero, debe añadir y actualizar el repositorio de Helm para el complemento de dispositivos de NVIDIA:

helm repo add nvdp https://nvidia.github.io/k8s-device-plugin
helm repo update

Ahora puede instalar el complemento de dispositivos de NVIDIA:

helm upgrade -i nvdp nvdp/nvidia-device-plugin --namespace nvidia-device-plugin --create-namespace --version 0.14.5 --set runtimeClassName=nvidia

Después de unos minutos, verá un nuevo pod en ejecución que completará la detección en los nodos disponibles y los etiquetará con el número de GPU que se han detectado:

kubectl get pods -n nvidia-device-plugin
NAME                              READY   STATUS    RESTARTS      AGE
nvdp-nvidia-device-plugin-jp697   1/1     Running   2 (12h ago)   6d3h

kubectl get node node0001 -o json | jq .status.capacity
{
  "cpu": "128",
  "ephemeral-storage": "466889732Ki",
  "hugepages-1Gi": "0",
  "hugepages-2Mi": "0",
  "memory": "32545636Ki",
  "nvidia.com/gpu": "1",                      <----
  "pods": "110"
}

Ahora ya está listo para crear un pod de NVIDIA que intentará utilizar esta GPU. Probemos con el contenedor CUDA Benchmark:

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: nbody-gpu-benchmark
  namespace: default
spec:
  restartPolicy: OnFailure
  runtimeClassName: nvidia
  containers:
  - name: cuda-container
    image: nvcr.io/nvidia/k8s/cuda-sample:nbody
    args: ["nbody", "-gpu", "-benchmark"]
    resources:
      limits:
        nvidia.com/gpu: 1
    env:
    - name: NVIDIA_VISIBLE_DEVICES
      value: all
    - name: NVIDIA_DRIVER_CAPABILITIES
      value: all
EOF

Si todo ha ido bien, puede consultar los registros y ver la información del benchmark:

kubectl logs nbody-gpu-benchmark
Run "nbody -benchmark [-numbodies=<numBodies>]" to measure performance.
	-fullscreen       (run n-body simulation in fullscreen mode)
	-fp64             (use double precision floating point values for simulation)
	-hostmem          (stores simulation data in host memory)
	-benchmark        (run benchmark to measure performance)
	-numbodies=<N>    (number of bodies (>= 1) to run in simulation)
	-device=<d>       (where d=0,1,2.... for the CUDA device to use)
	-numdevices=<i>   (where i=(number of CUDA devices > 0) to use for simulation)
	-compare          (compares simulation results running once on the default GPU and once on the CPU)
	-cpu              (run n-body simulation on the CPU)
	-tipsy=<file.bin> (load a tipsy model file for simulation)

NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.

> Windowed mode
> Simulation data stored in video memory
> Single precision floating point simulation
> 1 Devices used for simulation
GPU Device 0: "Turing" with compute capability 7.5

> Compute 7.5 CUDA device: [Tesla T4]
40960 bodies, total time for 10 iterations: 101.677 ms
= 165.005 billion interactions per second
= 3300.103 single-precision GFLOP/s at 20 flops per interaction

Por último, si sus aplicaciones requieren OpenGL, puede instalar las bibliotecas de OpenGL de NVIDIA necesarias en el nivel del host. El complemento de dispositivos de NVIDIA y NVIDIA Container Toolkit las pondrán a disposición de los contenedores. Para ello, instale el paquete de la siguiente manera:

transactional-update pkg install nvidia-gl-G06
Nota
Nota

Debe rearrancar el sistema para que este paquete esté disponible para sus aplicaciones. El complemento de dispositivos de NVIDIA debería volver a detectarlo automáticamente mediante NVIDIA Container Toolkit.

33.6 Unificación mediante Edge Image Builder

Ya ha demostrado la plena funcionalidad de sus aplicaciones y GPU en SUSE Linux Micro y ahora desea utilizar Capítulo 11, Edge Image Builder para unificarlo todo en una imagen de disco ISO o RAW desplegable/consumible. Esta guía no explica cómo usar Edge Image Builder, pero proporciona las configuraciones necesarias para crear dicha imagen. A continuación encontrará un ejemplo de definición de imagen, junto con los archivos de configuración de Kubernetes necesarios, para garantizar que todos los componentes requeridos se desplieguen. Esta es la estructura de directorio de Edge Image Builder para el ejemplo que se muestra a continuación:

.
├── base-images
│   └── SL-Micro.x86_64-6.1-Base-SelfInstall-GM.install.iso
├── eib-config-iso.yaml
├── kubernetes
│   ├── config
│   │   └── server.yaml
│   ├── helm
│   │   └── values
│   │       └── nvidia-device-plugin.yaml
│   └── manifests
│       └── nvidia-runtime-class.yaml
└── rpms
    └── gpg-keys
        └── nvidia-container-toolkit.key

Exploremos esos archivos. En primer lugar, hay una definición de imagen de muestra para un clúster de un solo nodo que ejecuta K3s y que despliega las utilidades y los paquetes OpenGL (eib-config-iso.yaml):

apiVersion: 1.2
image:
  arch: x86_64
  imageType: iso
  baseImage: SL-Micro.x86_64-6.1-Base-SelfInstall-GM.install.iso
  outputImageName: deployimage.iso
operatingSystem:
  time:
    timezone: Europe/London
    ntp:
      pools:
        - 2.suse.pool.ntp.org
  isoConfiguration:
    installDevice: /dev/sda
  users:
    - username: root
      encryptedPassword: $6$XcQN1xkuQKjWEtQG$WbhV80rbveDLJDz1c93K5Ga9JDjt3mF.ZUnhYtsS7uE52FR8mmT8Cnii/JPeFk9jzQO6eapESYZesZHO9EslD1
  packages:
    packageList:
      - nvidia-open-driver-G06-signed-kmp-default
      - nvidia-compute-utils-G06
      - nvidia-gl-G06
      - nvidia-container-toolkit
    additionalRepos:
      - url: https://download.nvidia.com/suse/sle15sp6/
      - url: https://nvidia.github.io/libnvidia-container/stable/rpm/x86_64
    sccRegistrationCode: [snip]
kubernetes:
  version: v1.32.4+k3s1
  helm:
    charts:
      - name: nvidia-device-plugin
        version: v0.14.5
        installationNamespace: kube-system
        targetNamespace: nvidia-device-plugin
        createNamespace: true
        valuesFile: nvidia-device-plugin.yaml
        repositoryName: nvidia
    repositories:
      - name: nvidia
        url: https://nvidia.github.io/k8s-device-plugin
Nota
Nota

Esto es solo un ejemplo. Deberá personalizarlo según sus necesidades y expectativas. Además, si utiliza SUSE Linux Micro, debe proporcionar su propio código sccRegistrationCode para resolver las dependencias del paquete y conseguir los controladores de NVIDIA.

Además, debemos añadir componentes adicionales para que Kubernetes los cargue durante el arranque. El directorio de EIB necesita primero un directorio kubernetes, con subdirectorios para la configuración, los valores del chart de Helm y cualquier manifiesto adicional que sea necesario:

mkdir -p kubernetes/config kubernetes/helm/values kubernetes/manifests

Ahora vamos a configurar Kubernetes (opcional) eligiendo una CNI (por defecto es Cilium si no se selecciona ninguna) y habilitando SELinux:

cat << EOF > kubernetes/config/server.yaml
cni: cilium
selinux: true
EOF

Ahora, asegúrese de que se haya creado RuntimeClass de NVIDIA en el clúster de Kubernetes:

cat << EOF > kubernetes/manifests/nvidia-runtime-class.yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: nvidia
handler: nvidia
EOF

Usamos la versión integrada de Helm Controller para desplegar el complemento de dispositivos de NVIDIA a través del propio Kubernetes. Proporcionemos la clase de tiempo de ejecución en el archivo de valores para el chart:

cat << EOF > kubernetes/helm/values/nvidia-device-plugin.yaml
runtimeClassName: nvidia
EOF

Antes de continuar, debemos obtener la clave pública del RPM de NVIDIA Container Toolkit:

mkdir -p rpms/gpg-keys
curl -o rpms/gpg-keys/nvidia-container-toolkit.key https://nvidia.github.io/libnvidia-container/gpgkey

Todos los artefactos necesarios, incluidos el binario de Kubernetes, las imágenes de contenedores, los charts de Helm (y cualquier imagen referenciada), se aislarán automáticamente, lo que significa que, en el momento del despliegue, los sistemas no deberían requerir conexión a Internet de forma predeterminada. Ahora solo tiene que obtener la imagen ISO de SUSE Linux Micro de la página de descargas de SUSE (y colocarla en el directorio base-images). Puede generar la imagen ISO con Edge Image Builder. Para completar el ejemplo, este es el comando que se utilizó para crear la imagen:

podman run --rm --privileged -it -v /path/to/eib-files/:/eib \
registry.suse.com/edge/3.3/edge-image-builder:1.2.1 \
build --definition-file eib-config-iso.yaml

Para obtener más información, consulte la documentación de Edge Image Builder.

33.7 Resolución de problemas

33.7.1 nvidia-smi no encuentra la GPU

Utilice dmesg para comprobar los mensajes del kernel. Si se indica que no es posible asignar NvKMSKapDevice, aplique la solución alternativa para las GPU no compatibles:

sed -i '/NVreg_OpenRmEnableUnsupportedGpus/s/^#//g' /etc/modprobe.d/50-nvidia-default.conf

NOTA: para que los cambios surtan efecto, si cambia la configuración del módulo del kernel en el paso anterior, deberá volver a cargar el módulo del kernel o rearrancar el sistema.

Parte VI Operaciones de día 2

En esta sección se explica cómo los administradores pueden gestionar diferentes tareas operativas de "día dos" tanto en los clústeres de gestión como en los descendentes.

34 Migración a Edge 3.3

En esta sección se explica cómo migrar los clústeres de gestión y descendentes de Edge 3.2 a Edge 3.3.0.

Importante
Importante

Realice siempre las migraciones de clústeres desde la última versión z-stream de Edge 3.2.

Migre siempre a la versión Edge 3.3.0. Para actualizaciones posteriores a la migración, consulte las secciones sobre los clústeres de gestión (Capítulo 35, Clúster de gestión) y los clústeres descendentes (Capítulo 36, Clústeres descendentes).

34.1 Clúster de gestión

En esta sección se tratan los temas siguientes:

Sección 34.1.1, “Requisitos previos”: pasos previos que deben completarse antes de iniciar la migración.

Sección 34.1.2, “Upgrade Controller”: cómo migrar un clúster de gestión con Capítulo 23, Upgrade Controller.

Sección 34.1.3, “Fleet”: cómo migrar un clúster de gestión con Capítulo 8, Fleet.

34.1.1 Requisitos previos

34.1.1.1 Actualización de las CRD del operador bare metal

Nota
Nota

Solo se aplica a clústeres que requieren una actualización del chart de Capítulo 10, Metal3.

El chart de Helm de Metal3 incluye las CRD de Bare Metal Operator (BMO) obtenidas del directorio CRD de Helm.

Sin embargo, este enfoque tiene ciertas limitaciones, en particular la imposibilidad de actualizar las CRD de este directorio utilizando Helm. Para obtener más información, consulte la documentación de Helm.

Como resultado, antes de actualizar Metal3 a una versión compatible de Edge 3.3.0, los usuarios deben actualizar manualmente las CRD de BMO subyacentes.

En un equipo con Helm instalado y kubectl configurado que apunte al clúster de gestión:

  1. Aplique manualmente las CRD de BMO:

    helm show crds oci://registry.suse.com/edge/charts/metal3 --version 303.0.7+up0.11.5 | kubectl apply -f -

34.1.2 Upgrade Controller

Importante
Importante

Upgrade Controller actualmente solo admite migraciones de versiones de Edge para clústeres de gestión en entornos que no sean aislados.

En esta sección se tratan los siguientes temas:

Sección 34.1.2.1, “Requisitos previos”: requisitos previos específicos de Upgrade Controller.

Sección 34.1.2.2, “Pasos de la migración”: pasos para migrar un clúster de gestión a una versión nueva de Edge mediante Upgrade Controller.

34.1.2.1 Requisitos previos

34.1.2.1.1 Upgrade Controller de Edge 3.3

Antes de usar Upgrade Controller, debe asegurarse de que está ejecutando una versión que sea compatible con la migración a la versión de Edge deseada.

Para ello:

  1. Si ya ha desplegado Upgrade Controller desde una versión anterior de Edge, actualice su chart:

    helm upgrade upgrade-controller -n upgrade-controller-system oci://registry.suse.com/edge/charts/upgrade-controller --version 303.0.1+up0.1.1
  2. Si no ha desplegado Upgrade Controller, siga la Sección 23.3, “Instalación de Upgrade Controller”.

34.1.2.2 Pasos de la migración

Migrar un clúster de gestión con Upgrade Controller es básicamente igual a ejecutar una actualización.

La única diferencia es que su recurso UpgradePlan debe especificar la versión 3.3.0:

apiVersion: lifecycle.suse.com/v1alpha1
kind: UpgradePlan
metadata:
  name: upgrade-plan-mgmt
  # Change to the namespace of your Upgrade Controller
  namespace: CHANGE_ME
spec:
  releaseVersion: 3.3.0

Para obtener información sobre cómo usar el recurso UpgradePlan mencionado para realizar una migración, consulte el proceso de actualización de Upgrade Controller (Sección 35.1, “Upgrade Controller”).

34.1.3 Fleet

Nota
Nota

Siempre que sea posible, use las instrucciones de la Sección 34.1.2, “Upgrade Controller” para la migración.

Consulte esta sección solo para los casos no cubiertos por la migración con Upgrade Controller.

Migrar un clúster de gestión con Fleet es básicamente igual a ejecutar una actualización.

Estas son las diferencias principales:

  1. Fleet se debe usar desde la versión release-3.3.0 del repositorio suse-edge/fleet-examples.

  2. Los charts cuya actualización esté programada, deben actualizarse a versiones compatibles con la versión Edge 3.3.0. Para ver una lista de los componentes de Edge 3.3.0, consulte la Sección 52.4, “Versión 3.3.0”.

Importante
Importante

Para garantizar que la migración a Edge 3.3.0 se realice correctamente, es importante que los usuarios cumplan con los puntos descritos anteriormente.

Teniendo en cuenta los puntos anteriores, los usuarios pueden seguir la documentación de Fleet (Sección 35.2, “Fleet”) sobre el clúster de gestión, que incluye todos los pasos necesarios para realizar la migración.

34.2 Clústeres descendentes

Sección 34.2.1, “Fleet”: cómo migrar un clúster descendente con Capítulo 8, Fleet.

34.2.1 Fleet

Migrar un clúster descendente con Fleet es básicamente igual a ejecutar una actualización.

Estas son las diferencias principales:

  1. Fleet se debe usar desde la versión release-3.3.0 del repositorio suse-edge/fleet-examples.

  2. Los charts cuya actualización esté programada, deben actualizarse a versiones compatibles con la versión Edge 3.3.0. Para ver una lista de los componentes de Edge 3.3.0, consulte la Sección 52.4, “Versión 3.3.0”.

Importante
Importante

Para garantizar que la migración a Edge 3.3.0 se realice correctamente, es importante que los usuarios cumplan con los puntos descritos anteriormente.

Teniendo en cuenta los puntos anteriores, los usuarios pueden seguir la documentación de Fleet (Sección 36.1, “Fleet”) sobre los clústeres descendentes para obtener una guía completa sobre los pasos necesarios para realizar la migración.

35 Clúster de gestión

Actualmente, hay dos formas de realizar operaciones de "día 2" en su clúster de gestión:

35.1 Upgrade Controller

Importante
Importante

Upgrade Controller actualmente solo admite operaciones de día 2 para clústeres en entornos no aislados.

En esta sección se explica cómo realizar las distintas operaciones de día 2 relacionadas con la actualización del clúster de gestión de una versión de la plataforma Edge a otra.

Las operaciones de día 2 se automatizan con Upgrade Controller (Capítulo 23, Upgrade Controller) e incluyen:

35.1.1 Requisitos previos

Antes de actualizar su clúster de gestión, deben cumplirse los siguientes requisitos previos:

  1. Nodos registrados en el SCC: asegúrese de que los sistemas operativos de los nodos del clúster estén registrados con una clave de suscripción que admita la versión del sistema operativo especificada en la versión de Edge (Sección 52.1, “Resumen”) a la que desea actualizar.

  2. Upgrade Controller: asegúrese de que Upgrade Controller se haya desplegado en su clúster de gestión. Para conocer los pasos de instalación, consulte la Sección 23.3, “Instalación de Upgrade Controller”.

35.1.2 Actualización

  1. Determine la versión de Edge (Sección 52.1, “Resumen”) a la que desea actualizar el clúster de gestión.

  2. En el clúster de gestión, despliegue un recurso UpgradePlan que especifique la versión deseada. UpgradePlan debe desplegarse en el espacio de nombres de Upgrade Controller.

    kubectl apply -n <upgrade_controller_namespace> -f - <<EOF
    apiVersion: lifecycle.suse.com/v1alpha1
    kind: UpgradePlan
    metadata:
      name: upgrade-plan-mgmt
    spec:
      # Version retrieved from release notes
      releaseVersion: 3.X.Y
    EOF
    Nota
    Nota

    Puede haber casos en los que desee realizar configuraciones adicionales sobre el recurso UpgradePlan. Para conocer todas las configuraciones posibles, consulte la Sección 23.5.1, “UpgradePlan”.

  3. El despliegue de UpgradePlan en el espacio de nombres de Upgrade Controller iniciará el proceso de actualización.

    Nota
    Nota

    Para obtener más información sobre el proceso de actualización real, consulte la Sección 23.4, “¿Cómo funciona Upgrade Controller?”.

    Para obtener más información sobre cómo hacer un seguimiento del proceso de actualización, consulte la Sección 23.6, “Seguimiento del proceso de actualización”.

35.2 Fleet

Esta sección ofrece información sobre cómo realizar operaciones de "día 2" utilizando el componente Fleet (Capítulo 8, Fleet).

En esta sección se tratan los siguientes temas:

  1. Sección 35.2.1, “Componentes”: los componentes predeterminados usados para todas las operaciones de "día 2".

  2. Sección 35.2.2, “Determinación de su caso de uso”: proporciona una descripción general de los recursos personalizados de Fleet que se usarán y su idoneidad para diferentes casos de uso de operaciones de "día 2".

  3. Sección 35.2.3, “Flujo de trabajo de día 2”: proporciona una guía del flujo de trabajo para ejecutar operaciones de "día 2" con Fleet.

  4. Sección 35.2.4, “Actualización del sistema operativo”: describe cómo realizar actualizaciones del sistema operativo con Fleet.

  5. Sección 35.2.5, “Actualización de la versión de Kubernetes”: describe cómo realizar actualizaciones de la versión de Kubernetes con Fleet.

  6. Sección 35.2.6, “Actualización de charts de Helm”: describe cómo realizar actualizaciones de charts de Helm con Fleet.

35.2.1 Componentes

A continuación, encontrará una descripción de los componentes predeterminados que deben configurarse en su clúster de gestión para poder realizar correctamente las operaciones de "día 2" con Fleet.

35.2.1.1 Rancher

(Opcional) Es el responsable de gestionar los clústeres descendentes y de desplegar System Upgrade Controller en su clúster de gestión.

Para obtener más información, consulte el Capítulo 5, Rancher.

35.2.1.2 System Upgrade Controller (SUC)

System Upgrade Controller es responsable de ejecutar tareas en nodos específicos según los datos de configuración proporcionados mediante un recurso personalizado, denominado plan.

SUC se utiliza activamente para actualizar el sistema operativo y la distribución de Kubernetes.

Para obtener más información sobre el componente SUC y cómo encaja en la pila de Edge, consulte el Capítulo 22, System Upgrade Controller.

35.2.2 Determinación de su caso de uso

Fleet usa dos tipos de recursos personalizados para permitir la gestión de los recursos de Kubernetes y Helm.

A continuación, encontrará información sobre la finalidad de estos recursos y los casos de uso para los que son más adecuados en el contexto de las operaciones de "día 2".

35.2.2.1 GitRepo

Un GitRepo es un recurso de Fleet (Capítulo 8, Fleet) que representa un repositorio Git desde el que Fleet puede crear Bundles. Cada Bundle se crea en función de las rutas de configuración definidas dentro del recurso GitRepo. Para obtener más información, consulte la documentación de GitRepo.

En el contexto de las operaciones de "día 2", los recursos GitRepo se suelen usar para desplegar SUC o planes de SUC en entornos no aislados que emplean un enfoque de GitOps de Fleet.

Como alternativa, los recursos GitRepo también se pueden utilizar para desplegar SUC o planes de SUC en entornos aislados, siempre que se refleje la configuración del repositorio a través de un servidor Git local.

35.2.2.2 Bundle

Los Bundles contienen recursos sin procesar de Kubernetes que se desplegarán en el clúster de destino. Por lo general, se crean a partir de un recurso GitRepo, pero hay casos en los que se pueden desplegar manualmente. Para obtener más información, consulte la documentación de Bundle.

En el contexto de las operaciones de "día 2", los recursos Bundle se suelen usar para desplegar SUC o planes de SUC en entornos aislados que no utilizan algún tipo de procedimiento GitOps local (por ejemplo, un servidor Git local).

Alternativamente, si su caso de uso no permite un flujo de trabajo GitOps (por ejemplo, porque use un repositorio Git), también se pueden utilizar recursos Bundle para desplegar SUC o planes de SUC en entornos no aislados.

35.2.3 Flujo de trabajo de día 2

A continuación, se describe el flujo de trabajo de "día 2" que se debe seguir al actualizar un clúster de gestión a una versión específica de Edge.

35.2.4 Actualización del sistema operativo

En esta sección se describe cómo realizar una actualización del sistema operativo utilizando Capítulo 8, Fleet y Capítulo 22, System Upgrade Controller.

En esta sección se tratan los siguientes temas:

  1. Sección 35.2.4.1, “Componentes”: componentes adicionales usados por el proceso de actualización.

  2. Sección 35.2.4.2, “Descripción general”: descripción general del proceso de actualización.

  3. Sección 35.2.4.3, “Requisitos”: requisitos del proceso de actualización.

  4. Sección 35.2.4.4, “Actualización del sistema operativo - Despliegue del plan de SUC”: información sobre cómo desplegar planes de SUC, responsables de iniciar el proceso de actualización.

35.2.4.1 Componentes

Esta sección trata sobre los componentes personalizados que el proceso de actualización del sistema operativo usa en lugar de los componentes predeterminados de "día 2" (Sección 35.2.1, “Componentes”).

35.2.4.1.1 systemd.service

La actualización del sistema operativo en un nodo específico se gestiona mediante un servicio systemd.service.

En función del tipo de actualización que requiera el sistema operativo de una versión de Edge a otra, se creará un servicio diferente:

  • Para las versiones de Edge que requieren la misma versión del sistema operativo (por ejemplo, la 6.0), se creará el servicio os-pkg-update.service. Use transactional-update para realizar una actualización normal del paquete.

  • Para las versiones de Edge que requieran una migración de la versión del sistema operativo (por ejemplo, de la 6.0 a la 6.1), se creará el servicio os-migration.service. Use transactional-update para realizar:

    1. Una actualización normal del paquete que garantice que todos los paquetes estén actualizados para mitigar cualquier fallo en la migración relacionado con versiones antiguas del paquete.

    2. Una migración del sistema operativo mediante el comando zypper migration.

Los servicios mencionados anteriormente se envían a cada nodo a través de un plan de SUC, que debe estar ubicado en el clúster de gestión que necesita una actualización del sistema operativo.

35.2.4.2 Descripción general

La actualización del sistema operativo para los nodos del clúster de gestión se realiza con Fleet y System Upgrade Controller (SUC).

Fleet se usa para desplegar y gestionar planes de SUC en el clúster deseado.

Nota
Nota

Los planes de SUC son recursos personalizados que describen los pasos que debe seguir SUC para ejecutar una tarea específica en un conjunto de nodos. Para ver un ejemplo de cómo es un plan de SUC, consulte el repositorio original.

Los planes de SUC de sistema operativo se envían a cada clúster desplegando un recurso GitRepo o Bundle a un espacio de trabajo de Fleet específico. Fleet recupera el GitRepo/Bundle desplegado y despliega su contenido (los planes de SUC de sistema operativo) en los clústeres deseados.

Nota
Nota

Los recursos GitRepo/Bundle siempre se despliegan en el clúster de gestión. Que se use un recurso GitRepo o Bundle depende del caso de uso. Consulte la Sección 35.2.2, “Determinación de su caso de uso” para obtener más información.

Los planes de SUC de sistema operativo describen el siguiente flujo de trabajo:

  1. Use siempre el comando cordon en los nodos antes de las actualizaciones del sistema operativo.

  2. Actualice siempre los nodos control-plane antes que los nodos worker.

  3. Actualice siempre el clúster en un único nodo cada vez.

Una vez desplegados los planes de SUC de sistema operativo, el flujo de trabajo es el siguiente:

  1. SUC reconcilia los planes de SUC de sistema operativo desplegados y crea un trabajo de Kubernetes en cada nodo.

  2. El trabajo de Kubernetes crea un servicio systemd.service (Sección 35.2.4.1.1, “systemd.service”) para la actualización de paquetes o para la migración del sistema operativo.

  3. El servicio systemd.service creado activa el proceso de actualización del sistema operativo en el nodo específico.

    Importante
    Importante

    Cuando finaliza el proceso de actualización del sistema operativo, el nodo correspondiente se rearranca para aplicar las actualizaciones en el sistema.

A continuación, encontrará un diagrama de la descripción anterior:

actualización de sistema operativo de gestión de día 2 con fleet

35.2.4.3 Requisitos

Generales:

  1. Equipo registrado en el Centro de servicios al cliente de SUSE. Todos los nodos del clúster de gestión deben estar registrados en https://scc.suse.com/. Esto es necesario para que el servicio systemd.service respectivo pueda conectarse correctamente al repositorio de RPM deseado.

    Importante
    Importante

    Para las versiones de Edge que requieren una migración de la versión del sistema operativo (por ejemplo, de la 6.0 a la 6.1), asegúrese de que su clave del Centro de servicios al cliente de SUSE admita la migración a la nueva versión.

  2. Asegúrese de que las tolerancias del plan de SUC coincidan con las tolerancias de los nodos. Si los nodos de su clúster de Kubernetes tienen intolerancias (taints) personalizadas, asegúrese de añadir tolerancias (tolerations) para ellas en los planes de SUC. De forma predeterminada, los planes de SUC solo tienen tolerancias para los nodos de plano de control. Las tolerancias predeterminadas son:

    • CriticalAddonsOnly=true:NoExecute

    • node-role.kubernetes.io/control-plane:NoSchedule

    • node-role.kubernetes.io/etcd:NoExecute

      Nota
      Nota

      Cualquier tolerancia adicional debe añadirse en la sección .spec.tolerations de cada plan. Los planes de SUC relacionados con la actualización del sistema operativo se pueden encontrar en el repositorio suse-edge/fleet-examples en fleets/day2/system-upgrade-controller-plans/os-upgrade. Asegúrese de usar planes que tengan una etiqueta de versión de repositorio válida.

      Esto es un ejemplo de definición de tolerancias personalizadas para el plan de SUC de plano de control:

      apiVersion: upgrade.cattle.io/v1
      kind: Plan
      metadata:
        name: os-upgrade-control-plane
      spec:
        ...
        tolerations:
        # default tolerations
        - key: "CriticalAddonsOnly"
          operator: "Equal"
          value: "true"
          effect: "NoExecute"
        - key: "node-role.kubernetes.io/control-plane"
          operator: "Equal"
          effect: "NoSchedule"
        - key: "node-role.kubernetes.io/etcd"
          operator: "Equal"
          effect: "NoExecute"
        # custom toleration
        - key: "foo"
          operator: "Equal"
          value: "bar"
          effect: "NoSchedule"
      ...

En entornos aislados:

  1. Duplique los repositorios RPM de SUSE. Los repositorios RPM del sistema operativo deben duplicarse y guardarse de forma local para que el servicio systemd.service pueda acceder a ellos. Para ello, utilice RMT o SUMA.

35.2.4.4 Actualización del sistema operativo - Despliegue del plan de SUC

Importante
Importante

En entornos que se hayan actualizado previamente mediante este procedimiento, los usuarios deben asegurarse de que se haya completado uno de los pasos siguientes:

  • Elimine cualquier plan de SUC desplegado anteriormente relacionado con versiones anteriores de Edge del clúster de gestión. Puede hacerlo eliminando el clúster deseado de la configuración de destino del GitRepo/Bundle o eliminando por completo el recurso GitRepo/Bundle.

  • Reutilice el recurso GitRepo/Bundle existente. Puede hacerlo haciendo que la revisión del recurso apunte a una nueva etiqueta que contenga los recursos de Fleet correctos para la versión deseada de suse-edge/fleet-examples.

Esto se hace con el fin de evitar conflictos entre los planes de SUC para versiones anteriores de Edge.

Si los usuarios intentan actualizar mientras hay planes de SUC en el clúster de gestión, verán el siguiente error de Fleet:

Not installed: Unable to continue with install: Plan <plan_name> in namespace <plan_namespace> exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error..

Como se menciona en la Sección 35.2.4.2, “Descripción general”, las actualizaciones del sistema operativo se realizan incluyendo planes de SUC en el clúster deseado de las siguientes formas:

Para determinar qué recurso se debe usar, consulte la Sección 35.2.2, “Determinación de su caso de uso”.

Si desea desplegar los planes de SUC de sistema operativo desde una herramienta GitOps de terceros, consulte la Sección 35.2.4.4.3, “Despliegue del plan de SUC - Flujo de trabajo de GitOps de terceros”.

35.2.4.4.1 Despliegue del plan de SUC - Recurso GitRepo

Es posible desplegar un recurso GitRepo, que incluye los planes de SUC de sistema operativo, de estas formas:

  1. Mediante la interfaz de usuario de Rancher: Sección 35.2.4.4.1.1, “Creación de GitRepo - Interfaz de usuario de Rancher” (si Rancher está disponible).

  2. Desplegando manualmente (Sección 35.2.4.4.1.2, “Creación de GitRepo - Manual”) el recurso en el clúster de gestión.

Una vez desplegado, para supervisar el proceso de actualización del sistema operativo de los nodos de su clúster de destino, consulte la Sección 22.3, “Supervisión de planes de System Upgrade Controller”.

35.2.4.4.1.1 Creación de GitRepo - Interfaz de usuario de Rancher

Para crear un recurso GitRepo con la interfaz de usuario de Rancher, siga la documentación oficial.

El equipo de Edge mantiene una flota (fleet) lista para usar. Dependiendo de su entorno, se puede utilizar directamente o como plantilla.

Importante
Importante

Use siempre esta flota desde una etiqueta de versión de Edge válida.

Para los casos prácticos en los que no es necesario incluir cambios personalizados en los planes de SUC que incluye la flota, los usuarios pueden usar directamente la flota os-upgrade desde el repositorio suse-edge/fleet-examples.

Si fuera necesario realizar cambios personalizados (por ejemplo, para añadir tolerancias personalizadas), los usuarios deben usar la flota os-upgrade desde un repositorio independiente, lo que les permitirá añadir los cambios a los planes de SUC según sea necesario.

Hay un ejemplo de cómo se puede configurar un recurso GitRepo para utilizar la flota del repositorio suse-edge/fleet-examples aquí.

35.2.4.4.1.2 Creación de GitRepo - Manual
  1. Extraiga el recurso GitRepo:

    curl -o os-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.3.0/gitrepos/day2/os-upgrade-gitrepo.yaml
  2. Edite la configuración de GitRepo:

    • Elimine la sección spec.targets: solo se necesita para clústeres descendentes.

      # Example using sed
      sed -i.bak '/^  targets:/,$d' os-upgrade-gitrepo.yaml && rm -f os-upgrade-gitrepo.yaml.bak
      
      # Example using yq (v4+)
      yq eval 'del(.spec.targets)' -i os-upgrade-gitrepo.yaml
    • Dirija el espacio de nombres de GitRepo al espacio de nombres fleet-local. Esto se hace para desplegar el recurso en el clúster de gestión.

      # Example using sed
      sed -i.bak 's/namespace: fleet-default/namespace: fleet-local/' os-upgrade-gitrepo.yaml && rm -f os-upgrade-gitrepo.yaml.bak
      
      # Example using yq (v4+)
      yq eval '.metadata.namespace = "fleet-local"' -i os-upgrade-gitrepo.yaml
  3. Aplique el recurso GitRepo a su clúster de gestión:

    kubectl apply -f os-upgrade-gitrepo.yaml
  4. Compruebe que el recurso GitRepo creado se encuentra en el espacio de nombres fleet-local:

    kubectl get gitrepo os-upgrade -n fleet-local
    
    # Example output
    NAME            REPO                                              COMMIT         BUNDLEDEPLOYMENTS-READY   STATUS
    os-upgrade      https://github.com/suse-edge/fleet-examples.git   release-3.3.0  0/0
35.2.4.4.2 Despliegue del plan de SUC - Recurso Bundle

Es posible desplegar un recurso Bundle, que incluye los planes de SUC de sistema operativo válidos, de estas formas:

  1. Mediante la interfaz de usuario de Rancher: Sección 35.2.4.4.2.1, “Creación de Bundle - Interfaz de usuario de Rancher” (si Rancher está disponible).

  2. Desplegando manualmente (Sección 35.2.4.4.2.2, “Creación del Bundle - Manual”) el recurso en el clúster de gestión.

Una vez desplegado, para supervisar el proceso de actualización del sistema operativo de los nodos de su clúster de destino, consulte la Sección 22.3, “Supervisión de planes de System Upgrade Controller”.

35.2.4.4.2.1 Creación de Bundle - Interfaz de usuario de Rancher

El equipo de Edge mantiene un bundle listo para usar que puede emplear en los pasos que se indican a continuación.

Importante
Importante

Use siempre este bundle desde una etiqueta de versión válida de Edge.

Para crear un bundle con la interfaz de usuario de Rancher:

  1. En la esquina superior izquierda, haga clic en ☰ → Continuous Delivery (☰ → Entrega continua).

  2. Diríjase a Advanced > Bundles (Avanzado > Bundles).

  3. Seleccione Create from YAML (Crear desde YAML).

  4. Desde aquí, puede crear el Bundle de las siguientes maneras:

    Nota
    Nota

    Puede haber casos en los que sea necesario incluir cambios personalizados en los planes de SUC que incluye el Bundle (por ejemplo, para añadir tolerancias personalizadas). Asegúrese de incluir esos cambios en el Bundle que se generará con los pasos siguientes.

    1. Copiando manualmente el contenido del Bundle desde suse-edge/fleet-examples a la página Create from YAML (Crear desde YAML).

    2. Clonando el repositorio suse-edge/fleet-examples desde la etiqueta de versión deseada y seleccionando la opciónRead from File (Leer desde archivo) en la página Create from YAML (Crear desde YAML). Desde ahí, diríjase a la ubicación del Bundle (bundles/day2/system-upgrade-controller-plans/os-upgrade) y seleccione el archivo del Bundle. Esto rellenará automáticamente la página Create from YAML (Crear desde YAML) con el contenido del Bundle.

  5. Edite el Bundle en la interfaz de usuario de Rancher:

    • Cambie el espacio de nombres del bundle para que dirija al espacio de nombres fleet-local.

      # Example
      kind: Bundle
      apiVersion: fleet.cattle.io/v1alpha1
      metadata:
        name: os-upgrade
        namespace: fleet-local
      ...
    • Cambie los clústeres de destino para que el bundle apunte a su clúster de gestión local:

      spec:
        targets:
        - clusterName: local
      Nota
      Nota

      Hay casos prácticos en los que el clúster local podría tener un nombre diferente.

      Para recuperar el nombre del clúster local, ejecute el siguiente comando:

      kubectl get clusters.fleet.cattle.io -n fleet-local
  6. Seleccione Create (Crear).

35.2.4.4.2.2 Creación del Bundle - Manual
  1. Extraiga el recurso Bundle:

    curl -o os-upgrade-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.3.0/bundles/day2/system-upgrade-controller-plans/os-upgrade/os-upgrade-bundle.yaml
  2. Edite la configuración del Bundle:

    • Cambie los clústeres de destino para que el bundle apunte a su clúster de gestión local:

      spec:
        targets:
        - clusterName: local
      Nota
      Nota

      Hay casos prácticos en los que el clúster local podría tener un nombre diferente.

      Para recuperar el nombre del clúster local, ejecute el siguiente comando:

      kubectl get clusters.fleet.cattle.io -n fleet-local
    • Cambie el espacio de nombres del bundle para que dirija al espacio de nombres fleet-local.

      # Example
      kind: Bundle
      apiVersion: fleet.cattle.io/v1alpha1
      metadata:
        name: os-upgrade
        namespace: fleet-local
      ...
  3. Aplique el recurso Bundle al clúster de gestión:

    kubectl apply -f os-upgrade-bundle.yaml
  4. Compruebe que el recurso Bundle se ha creado en el espacio de nombres fleet-local:

    kubectl get bundles -n fleet-local
35.2.4.4.3 Despliegue del plan de SUC - Flujo de trabajo de GitOps de terceros

Puede haber casos prácticos en los que los usuarios deseen incorporar los planes de SUC de sistema operativo a su propio flujo de trabajo de GitOps de terceros (por ejemplo, Flux).

Para obtener los recursos de actualización del sistema operativo que necesita, determine primero la etiqueta de versión de Edge del repositorio suse-edge/fleet-examples que desea utilizar.

Después, los recursos se encuentran en fleets/day2/system-upgrade-controller-plans/os-upgrade, donde:

  • plan-control-plane.yaml es un recurso de plan de SUC para los nodos de plano de control.

  • plan-worker.yaml es un recurso de plan de SUC para los nodos de trabajador.

  • secret.yaml es un secreto que contiene el guion upgrade.sh, que se encarga de crear el servicio systemd.service (Sección 35.2.4.1.1, “systemd.service”).

  • config-map.yaml es un mapa de configuración que contiene las configuraciones que utiliza el guion upgrade.sh.

Importante
Importante

Estos recursos de plan son interpretados por System Upgrade Controller y se deben desplegar en cada clúster descendente que desee actualizar. Para obtener información sobre el despliegue de SUC, consulte la Sección 22.2, “Instalación de System Upgrade Controller”.

Para comprender mejor cómo usar su flujo de trabajo de GitOps para desplegar los planes de SUC para actualizar el sistema operativo, puede resultar útil echar un vistazo a la descripción general (Sección 35.2.4.2, “Descripción general”).

35.2.5 Actualización de la versión de Kubernetes

En esta sección se describe cómo realizar una actualización de Kubernetes utilizando Capítulo 8, Fleet y Capítulo 22, System Upgrade Controller.

En esta sección se tratan los siguientes temas:

  1. Sección 35.2.5.1, “Componentes”: componentes adicionales usados por el proceso de actualización.

  2. Sección 35.2.5.2, “Descripción general”: descripción general del proceso de actualización.

  3. Sección 35.2.5.3, “Requisitos”: requisitos del proceso de actualización.

  4. Sección 35.2.5.4, “Actualización de K8s - Despliegue del plan de SUC”: información sobre cómo desplegar planes de SUC, responsables de iniciar el proceso de actualización.

35.2.5.1 Componentes

Esta sección trata sobre los componentes personalizados que el proceso de actualización de K8s usa en lugar de los componentes predeterminados de "día 2" (Sección 35.2.1, “Componentes”).

35.2.5.1.1 rke2-upgrade

Es la imagen de contenedor responsable de actualizar la versión de RKE2 de un nodo específico.

Se incluye a través de un pod creado por SUC basado en un plan de SUC. El plan debe estar ubicado en cada clúster que necesite una actualización de RKE2.

Para obtener más información sobre cómo la imagen rke2-upgrade realiza la actualización, consulte la documentación original.

35.2.5.1.2 k3s-upgrade

Es la imagen de contenedor responsable de actualizar la versión de K3s de un nodo específico.

Se incluye a través de un pod creado por SUC basado en un plan de SUC. El plan debe estar ubicado en cada clúster que necesite una actualización de K3s.

Para obtener más información sobre cómo realiza la imagen k3s-upgrade la actualización, consulte la documentación original.

35.2.5.2 Descripción general

La actualización de la distribución de Kubernetes para los nodos del clúster de gestión se realiza con Fleet y System Upgrade Controller (SUC).

Fleet se usa para desplegar y gestionar planes de SUC en el clúster deseado.

Nota
Nota

Los planes de SUC son recursos personalizados que describen los pasos que debe seguir SUC para ejecutar una tarea específica en un conjunto de nodos. Para ver un ejemplo de un plan de SUC, consulte el repositorio original.

Los planes de SUC de K8s se incluyen en cada clúster desplegando un recurso GitRepo o Bundle en un espacio de trabajo específico de Fleet. Fleet recupera el GitRepo/Bundle desplegado y despliega su contenido (los planes de SUC de K8s) en los clústeres deseados.

Nota
Nota

Los recursos GitRepo/Bundle siempre se despliegan en el clúster de gestión. Que se use un recurso GitRepo o Bundle depende del caso de uso. Consulte la Sección 35.2.2, “Determinación de su caso de uso” para obtener más información.

Los planes de SUC de K8s describen el siguiente flujo de trabajo:

  1. Use siempre el comando cordon en los nodos antes de las actualizaciones de K8s.

  2. Actualice siempre los nodos control-plane antes que los nodos worker.

  3. Actualice siempre los nodos de control-plane (plano de control) de uno en uno y los nodos worker (trabajador) de dos en dos.

Una vez desplegados los planes de SUC de K8s, el flujo de trabajo es el siguiente:

  1. SUC reconcilia los planes de SUC de K8s desplegados y crea un trabajo de Kubernetes en cada nodo.

  2. Dependiendo de la distribución de Kubernetes, el trabajo creará un pod que ejecutará la imagen de contenedor rke2-upgrade (Sección 35.2.5.1.1, “rke2-upgrade”) o k3s-upgrade (Sección 35.2.5.1.2, “k3s-upgrade”).

  3. El pod creado seguirá el siguiente flujo de trabajo:

    1. Sustituye el binario rke2/k3s existente en el nodo por el de la imagen rke2-upgrade/k3s-upgrade.

    2. Detiene el proceso rke2/k3s en ejecución.

  4. Al detener el proceso rke2/k3s, se activa un reinicio y se lanza un nuevo proceso que ejecuta el binario actualizado, lo que da como resultado una versión actualizada de la distribución de Kubernetes.

A continuación, encontrará un diagrama de la descripción anterior:

actualización de k8s de gestión de día2 con fleet

35.2.5.3 Requisitos

  1. Haga una copia de seguridad de su distribución de Kubernetes:

    1. Para los clústeres RKE2, consulte RKE2 Backup and Restore (Copia de seguridad y restauración de RKE2).

    2. Para los clústeres K3s, consulte K3s Backup and Restore (Copia de seguridad y restauración de K3s).

  2. Asegúrese de que las tolerancias del plan de SUC coincidan con las tolerancias de los nodos. Si los nodos del clúster de Kubernetes tienen intolerancias (taints) personalizadas, asegúrese de añadir tolerancias (tolerations) para ellas en los planes de SUC. Por defecto, los planes de SUC solo tienen tolerancias para los nodos de plano de control. Las tolerancias predeterminadas son:

    • CriticalAddonsOnly=true:NoExecute

    • node-role.kubernetes.io/control-plane:NoSchedule

    • node-role.kubernetes.io/etcd:NoExecute

      Nota
      Nota

      Cualquier tolerancia adicional debe añadirse en la sección .spec.tolerations de cada plan. Los planes de SUC relacionados con la actualización de la versión de Kubernetes se encuentran en el repositorio suse-edge/fleet-examples en:

      • Para RKE2: fleets/day2/system-upgrade-controller-plans/rke2-upgrade

      • Para K3s: fleets/day2/system-upgrade-controller-plans/k3s-upgrade

      Asegúrese de usar los planes de una etiqueta de versión del repositorio válida.

      Este es un ejemplo de definición de tolerancias personalizadas para el plan de SUC de plano de control de RKE2:

      apiVersion: upgrade.cattle.io/v1
      kind: Plan
      metadata:
        name: rke2-upgrade-control-plane
      spec:
        ...
        tolerations:
        # default tolerations
        - key: "CriticalAddonsOnly"
          operator: "Equal"
          value: "true"
          effect: "NoExecute"
        - key: "node-role.kubernetes.io/control-plane"
          operator: "Equal"
          effect: "NoSchedule"
        - key: "node-role.kubernetes.io/etcd"
          operator: "Equal"
          effect: "NoExecute"
        # custom toleration
        - key: "foo"
          operator: "Equal"
          value: "bar"
          effect: "NoSchedule"
      ...

35.2.5.4 Actualización de K8s - Despliegue del plan de SUC

Importante
Importante

En entornos que se hayan actualizado previamente mediante este procedimiento, los usuarios deben asegurarse de que se haya completado uno de los pasos siguientes:

  • Elimine cualquier plan de SUC desplegado anteriormente relacionado con versiones anteriores de Edge del clúster de gestión. Puede hacerlo eliminando el clúster deseado de la configuración de destino del GitRepo/Bundle o eliminando por completo el recurso GitRepo/Bundle.

  • Reutilice el recurso GitRepo/Bundle existente. Puede hacerlo haciendo que la revisión del recurso apunte a una nueva etiqueta que contenga los recursos de Fleet correctos para la versión deseada de suse-edge/fleet-examples.

Esto se hace con el fin de evitar conflictos entre los planes de SUC para versiones anteriores de Edge.

Si los usuarios intentan actualizar mientras hay planes de SUC en el clúster de gestión, verán el siguiente error de Fleet:

Not installed: Unable to continue with install: Plan <plan_name> in namespace <plan_namespace> exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error..

Como se menciona en la Sección 35.2.5.2, “Descripción general”, las actualizaciones de Kubernetes se realizan incluyendo planes de SUC en el clúster deseado de las siguientes formas:

Para determinar qué recurso se debe usar, consulte la Sección 35.2.2, “Determinación de su caso de uso”.

Si desea desplegar los planes de SUC de K8s desde una herramienta GitOps de terceros, consulte la Sección 35.2.5.4.3, “Despliegue del plan de SUC - Flujo de trabajo de GitOps de terceros”.

35.2.5.4.1 Despliegue del plan de SUC - Recurso GitRepo

Es posible desplegar un recurso GitRepo, que incluye los planes de SUC de K8s necesarios, de las siguientes formas:

  1. Mediante la interfaz de usuario de Rancher: Sección 35.2.5.4.1.1, “Creación de GitRepo - Interfaz de usuario de Rancher” (si Rancher está disponible).

  2. Desplegando manualmente (Sección 35.2.5.4.1.2, “Creación de GitRepo - Manual”) el recurso en el clúster de gestión.

Una vez desplegado, para supervisar el proceso de actualización de Kubernetes de los nodos del clúster de destino, consulte la Sección 22.3, “Supervisión de planes de System Upgrade Controller”.

35.2.5.4.1.1 Creación de GitRepo - Interfaz de usuario de Rancher

Para crear un recurso GitRepo con la interfaz de usuario de Rancher, siga la documentación oficial.

El equipo de Edge mantiene flotas listas para usar para las distribuciones de Kubernetes rke2 y k3s. Según su entorno, estas flotas se pueden usar directamente o como plantilla.

Importante
Importante

Utilice siempre estas flotas desde una etiqueta de versión de Edge válida.

Cuando no sea necesario incluir cambios personalizados en los planes de SUC que incluyen estas flotas, los usuarios pueden consultar directamente las flotas en el repositorio suse-edge/fleet-examples.

Si fuera necesario realizar cambios personalizados (por ejemplo, para añadir tolerancias personalizadas), los usuarios deben consultar las flotas desde un repositorio independiente, lo que les permitirá añadir los cambios a los planes de SUC según sea necesario.

Ejemplos de configuración para un recurso GitRepo utilizando las flotas del repositorio suse-edge/fleet-examples:

35.2.5.4.1.2 Creación de GitRepo - Manual
  1. Extraiga el recurso GitRepo:

    • Para clústeres RKE2:

      curl -o rke2-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.3.0/gitrepos/day2/rke2-upgrade-gitrepo.yaml
    • Para clústeres K3s:

      curl -o k3s-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.3.0/gitrepos/day2/k3s-upgrade-gitrepo.yaml
  2. Edite la configuración de GitRepo:

    • Elimine la sección spec.targets: solo se necesita para clústeres descendentes.

      • Para RKE2:

        # Example using sed
        sed -i.bak '/^  targets:/,$d' rke2-upgrade-gitrepo.yaml && rm -f rke2-upgrade-gitrepo.yaml.bak
        
        # Example using yq (v4+)
        yq eval 'del(.spec.targets)' -i rke2-upgrade-gitrepo.yaml
      • Para K3s:

        # Example using sed
        sed -i.bak '/^  targets:/,$d' k3s-upgrade-gitrepo.yaml && rm -f k3s-upgrade-gitrepo.yaml.bak
        
        # Example using yq (v4+)
        yq eval 'del(.spec.targets)' -i k3s-upgrade-gitrepo.yaml
    • Dirija el espacio de nombres de GitRepo al espacio de nombres fleet-local. Esto se hace para desplegar el recurso en el clúster de gestión.

      • Para RKE2:

        # Example using sed
        sed -i.bak 's/namespace: fleet-default/namespace: fleet-local/' rke2-upgrade-gitrepo.yaml && rm -f rke2-upgrade-gitrepo.yaml.bak
        
        # Example using yq (v4+)
        yq eval '.metadata.namespace = "fleet-local"' -i rke2-upgrade-gitrepo.yaml
      • Para K3s:

        # Example using sed
        sed -i.bak 's/namespace: fleet-default/namespace: fleet-local/' k3s-upgrade-gitrepo.yaml && rm -f k3s-upgrade-gitrepo.yaml.bak
        
        # Example using yq (v4+)
        yq eval '.metadata.namespace = "fleet-local"' -i k3s-upgrade-gitrepo.yaml
  3. Aplique los recursos GitRepo a su clúster de gestión:

    # RKE2
    kubectl apply -f rke2-upgrade-gitrepo.yaml
    
    # K3s
    kubectl apply -f k3s-upgrade-gitrepo.yaml
  4. Compruebe que el recurso GitRepo creado se encuentra en el espacio de nombres fleet-local:

    # RKE2
    kubectl get gitrepo rke2-upgrade -n fleet-local
    
    # K3s
    kubectl get gitrepo k3s-upgrade -n fleet-local
    
    # Example output
    NAME           REPO                                              COMMIT          BUNDLEDEPLOYMENTS-READY   STATUS
    k3s-upgrade    https://github.com/suse-edge/fleet-examples.git   fleet-local   0/0
    rke2-upgrade   https://github.com/suse-edge/fleet-examples.git   fleet-local   0/0
35.2.5.4.2 Despliegue del plan de SUC - Recurso Bundle

Es posible desplegar un recurso Bundle, que incluye los planes de SUC de actualización de Kubernetes necesarios, de una de estas formas:

  1. Mediante la interfaz de usuario de Rancher: Sección 35.2.5.4.2.1, “Creación de Bundle - Interfaz de usuario de Rancher” (si Rancher está disponible).

  2. Desplegando manualmente (Sección 35.2.5.4.2.2, “Creación del Bundle - Manual”) el recurso en el clúster de gestión.

Una vez desplegado, para supervisar el proceso de actualización de Kubernetes de los nodos del clúster de destino, consulte la Sección 22.3, “Supervisión de planes de System Upgrade Controller”.

35.2.5.4.2.1 Creación de Bundle - Interfaz de usuario de Rancher

El equipo de Edge mantiene bundles listos para usar para las distribuciones de Kubernetes rke2 y k3s. Dependiendo de su entorno, estos bundles se pueden utilizar directamente o como plantilla.

Importante
Importante

Use siempre este bundle desde una etiqueta de versión válida de Edge.

Para crear un bundle con la interfaz de usuario de Rancher:

  1. En la esquina superior izquierda, haga clic en ☰ → Continuous Delivery (☰ → Entrega continua).

  2. Diríjase a Advanced > Bundles (Avanzado > Bundles).

  3. Seleccione Create from YAML (Crear desde YAML).

  4. Desde aquí, puede crear el Bundle de las siguientes maneras:

    Nota
    Nota

    Puede haber casos en los que sea necesario incluir cambios personalizados en los planes de SUC que incluye el Bundle (por ejemplo, para añadir tolerancias personalizadas). Asegúrese de incluir esos cambios en el Bundle que se generará con los pasos siguientes.

    1. Copie manualmente el contenido del Bundle para RKE2 o K3s desde suse-edge/fleet-examples en la página Create from YAML (Crear desde YAML).

    2. Clone el repositorio suse-edge/fleet-examples desde la etiqueta de versión deseada y seleccione la opción Read from File (Leer desde archivo) en la página Create from YAML (Crear desde YAML). Desde ahí, diríjase al Bundle que necesita (bundles/day2/system-upgrade-controller-plans/rke2-upgrade/plan-bundle.yaml para RKE2 y bundles/day2/system-upgrade-controller-plans/k3s-upgrade/plan-bundle.yaml para K3s). La página Create from YAML (Crear desde YAML) se rellenará automáticamente con el contenido del paquete.

  5. Edite el Bundle en la interfaz de usuario de Rancher:

    • Cambie el espacio de nombres del bundle para que dirija al espacio de nombres fleet-local.

      # Example
      kind: Bundle
      apiVersion: fleet.cattle.io/v1alpha1
      metadata:
        name: rke2-upgrade
        namespace: fleet-local
      ...
    • Cambie los clústeres de destino para que el bundle apunte a su clúster de gestión local:

      spec:
        targets:
        - clusterName: local
      Nota
      Nota

      Hay casos prácticos en los que el clúster local podría tener un nombre diferente.

      Para recuperar el nombre del clúster local, ejecute el siguiente comando:

      kubectl get clusters.fleet.cattle.io -n fleet-local
  6. Seleccione Create (Crear).

35.2.5.4.2.2 Creación del Bundle - Manual
  1. Extraiga los recursos Bundle:

    • Para clústeres RKE2:

      curl -o rke2-plan-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.3.0/bundles/day2/system-upgrade-controller-plans/rke2-upgrade/plan-bundle.yaml
    • Para clústeres K3s:

      curl -o k3s-plan-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.3.0/bundles/day2/system-upgrade-controller-plans/k3s-upgrade/plan-bundle.yaml
  2. Edite la configuración del Bundle:

    • Cambie los clústeres de destino para que el bundle apunte a su clúster de gestión local:

      spec:
        targets:
        - clusterName: local
      Nota
      Nota

      Hay casos prácticos en los que el clúster local podría tener un nombre diferente.

      Para recuperar el nombre del clúster local, ejecute el siguiente comando:

      kubectl get clusters.fleet.cattle.io -n fleet-local
    • Cambie el espacio de nombres del bundle para que dirija al espacio de nombres fleet-local.

      # Example
      kind: Bundle
      apiVersion: fleet.cattle.io/v1alpha1
      metadata:
        name: rke2-upgrade
        namespace: fleet-local
      ...
  3. Aplique los recursos Bundle al clúster de gestión:

    # For RKE2
    kubectl apply -f rke2-plan-bundle.yaml
    
    # For K3s
    kubectl apply -f k3s-plan-bundle.yaml
  4. Compruebe que el recurso Bundle se ha creado en el espacio de nombres fleet-local:

    # For RKE2
    kubectl get bundles rke2-upgrade -n fleet-local
    
    # For K3s
    kubectl get bundles k3s-upgrade -n fleet-local
    
    # Example output
    NAME           BUNDLEDEPLOYMENTS-READY   STATUS
    k3s-upgrade    0/0
    rke2-upgrade   0/0
35.2.5.4.3 Despliegue del plan de SUC - Flujo de trabajo de GitOps de terceros

Puede haber casos prácticos en los que los usuarios deseen incorporar los planes de SUC de actualización de Kubernetes a su propio flujo de trabajo de GitOps de terceros (por ejemplo, Flux).

Para obtener los recursos de actualización de K8s que necesita, primero determine la etiqueta de versión de Edge del repositorio suse-edge/fleet-examples que desea utilizar.

Después, los recursos se encuentran en:

  • Para actualizar un clúster RKE2:

    • Para nodos control-plane: fleets/day2/system-upgrade-controller-plans/rke2-upgrade/plan-control-plane.yaml

    • Para nodos worker: fleets/day2/system-upgrade-controller-plans/rke2-upgrade/plan-worker.yaml

  • Para actualizar un clúster K3s:

    • Para nodos control-plane: fleets/day2/system-upgrade-controller-plans/k3s-upgrade/plan-control-plane.yaml

    • Para nodos worker: fleets/day2/system-upgrade-controller-plans/k3s-upgrade/plan-worker.yaml

Importante
Importante

Estos recursos de plan son interpretados por System Upgrade Controller y se deben desplegar en cada clúster descendente que desee actualizar. Para obtener información sobre el despliegue de SUC, consulte la Sección 22.2, “Instalación de System Upgrade Controller”.

Para comprender mejor cómo usar su flujo de trabajo de GitOps para desplegar los planes de SUC para actualizar la versión de Kubernetes, puede resultar útil echar un vistazo a la descripción general (Sección 35.2.5.2, “Descripción general”) del procedimiento de actualización mediante Fleet.

35.2.6 Actualización de charts de Helm

Esta sección cubre lo siguiente:

  1. Sección 35.2.6.1, “Preparación para entornos aislados”: contiene información sobre cómo incluir charts e imágenes OCI relacionados con Edge en su registro privado.

  2. Sección 35.2.6.2, “Procedimiento de actualización”: contiene información sobre diferentes casos de actualización de charts de Helm y su procedimiento de actualización.

35.2.6.1 Preparación para entornos aislados

35.2.6.1.1 Asegúrese de tener acceso a los recursos de Fleect del chart de Helm

Dependiendo de lo que admita su entorno, puede elegir una de estas opciones:

  1. Aloje los recursos de Fleet de su chart en un servidor Git local al que pueda acceder su clúster de gestión.

  2. Use la interfaz de línea de comandos de Fleet para convertir un chart de Helm en un Bundle que podrá utilizar directamente sin necesidad de alojarlo en ningún sitio. Puede descargar la interfaz de línea de comandos de la página de la versión. Para los usuarios de Mac, hay una versión propia de fleet-cli.

35.2.6.1.2 Busque los recursos necesarios para su versión de Edge
  1. Vaya a la página de la versión de "día 2", busque la versión de Edge a la que desea actualizar su chart y haga clic en Assets (Recursos).

  2. En la sección Assets (Recursos), descargue los archivos siguientes:

    Archivo de versión

    Descripción

    edge-save-images.sh

    Extrae las imágenes especificadas en el archivo edge-release-images.txt y las empaqueta en un archivo ".tar.gz".

    edge-save-oci-artefacts.sh

    Extrae las imágenes del chart OCI relacionadas con la versión específica de Edge y las empaqueta en un archivo ".tar.gz".

    edge-load-images.sh

    Carga imágenes desde un archivo ".tar.gz", las vuelve a etiquetar y las envía a un registro privado.

    edge-load-oci-artefacts.sh

    Toma un directorio que contiene paquetes de charts OCI ".tgz" de Edge y los carga en un registro privado.

    edge-release-helm-oci-artefacts.txt

    Contiene una lista de imágenes de charts OCI relacionadas con una versión específica de Edge.

    edge-release-images.txt

    Contiene una lista de imágenes relacionadas con una versión específica de Edge.

35.2.6.1.3 Cree el archivo de imágenes de la versión de Edge

En un equipo con acceso a Internet:

  1. Permita que edge-save-images.sh se pueda ejecutar:

    chmod +x edge-save-images.sh
  2. Genere el archivo de imagen:

    ./edge-save-images.sh --source-registry registry.suse.com
  3. Esto creará un archivo listo para cargar llamado edge-images.tar.gz.

    Nota
    Nota

    Si se especifica la opción -i|--images, el nombre del archivo puede ser diferente.

  4. Copie este archivo a su equipo aislado:

    scp edge-images.tar.gz <user>@<machine_ip>:/path
35.2.6.1.4 Cree el archivo de imágenes del chart OCI de Edge

En un equipo con acceso a Internet:

  1. Permita que edge-save-oci-artefacts.sh se pueda ejecutar:

    chmod +x edge-save-oci-artefacts.sh
  2. Genere el archivo de imagen del chart OCI:

    ./edge-save-oci-artefacts.sh --source-registry registry.suse.com
  3. Esto creará un archivo denominado oci-artefacts.tar.gz.

    Nota
    Nota

    Si se especifica la opción -a|--archive, el nombre del archivo puede ser distinto.

  4. Copie este archivo a su equipo aislado:

    scp oci-artefacts.tar.gz <user>@<machine_ip>:/path
35.2.6.1.5 Cargue las imágenes de la versión de Edge en su equipo aislado

En su equipo aislado:

  1. Inicie sesión en su registro privado (si es necesario):

    podman login <REGISTRY.YOURDOMAIN.COM:PORT>
  2. Permita que edge-load-images.sh se pueda ejecutar:

    chmod +x edge-load-images.sh
  3. Ejecute el guion pasando el archivo edge-images.tar.gz copiado anteriormente:

    ./edge-load-images.sh --source-registry registry.suse.com --registry <REGISTRY.YOURDOMAIN.COM:PORT> --images edge-images.tar.gz
    Nota
    Nota

    Esto cargará todas las imágenes desde edge-images.tar.gz, las volverá a etiquetar y las enviará al registro especificado en la opción --registry.

35.2.6.1.6 Cargue las imágenes del chart OCI de Edge en su equipo aislado

En su equipo aislado:

  1. Inicie sesión en su registro privado (si es necesario):

    podman login <REGISTRY.YOURDOMAIN.COM:PORT>
  2. Permita que edge-load-oci-artefacts.sh se pueda ejecutar:

    chmod +x edge-load-oci-artefacts.sh
  3. Desempaquete el archivo oci-artefacts.tar.gz copiado:

    tar -xvf oci-artefacts.tar.gz
  4. Esto generará un directorio con el formato de nombre edge-release-oci-tgz-<fecha>.

  5. Pase este directorio al guion edge-load-oci-artefacts.sh para cargar las imágenes del chart OCI de Edge a su registro privado:

    Nota
    Nota

    Este guion presupone que la interfaz de línea de comandos de Helm ya está preinstalada en su entorno. Para obtener instrucciones sobre la instalación de Helm, consulte Installing Helm (Instalación de Helm).

    ./edge-load-oci-artefacts.sh --archive-directory edge-release-oci-tgz-<date> --registry <REGISTRY.YOURDOMAIN.COM:PORT> --source-registry registry.suse.com
35.2.6.1.7 Configure el registro privado en su distribución de Kubernetes

Para RKE2, consulte Private Registry Configuration (Configuración del registro privado)

Para K3s, consulte Private Registry Configuration (Configuración del registro privado)

35.2.6.2 Procedimiento de actualización

Esta sección se centra en los siguientes casos prácticos del procedimiento de actualización de Helm:

Importante
Importante

Los charts de Helm desplegados manualmente no se pueden actualizar de forma fiable. Recomendamos volver a desplegar el chart de Helm utilizando el método Sección 35.2.6.2.1, “Tengo un nuevo clúster y me gustaría desplegar y gestionar un chart de Helm de Edge”.

35.2.6.2.1 Tengo un nuevo clúster y me gustaría desplegar y gestionar un chart de Helm de Edge

En esta sección se trata lo siguiente:

35.2.6.2.1.1 Prepare los recursos de Fleet para su chart
  1. Adquiera los recursos de Fleet del chart desde la etiqueta de versión de Edge que desee usar.

  2. Diríjase a la flota del chart de Helm (fleets/day2/chart-templates/<chart>).

  3. Si tiene intención de utilizar un flujo de trabajo de GitOps, copie el directorio Fleet del chart en el repositorio Git desde donde realizará la operación de GitOps.

  4. Opcionalmente, si el chart de Helm requiere que se configuren sus valores, edite la configuración de .helm.values dentro del archivo fleet.yaml del directorio copiado.

  5. Opcionalmente, puede haber casos en los que sea necesario añadir recursos adicionales a la flota de su chart para que se adapte mejor a su entorno. Para obtener información sobre cómo mejorar su directorio de Fleet, consulte Git Repository Contents (Contenido del repositorio Git).

Nota
Nota

En algunos casos, el tiempo de espera predeterminado que Fleet usa para las operaciones de Helm puede ser insuficiente, lo que da lugar al siguiente error:

failed pre-install: context deadline exceeded

Si fuera el caso, añada la propiedad timeoutSeconds en la configuración de helm de su archivo fleet.yaml.

Esto es un ejemplo del aspecto que tendría el chart de Helm de longhorn:

  • Estructura del repositorio Git del usuario:

    <user_repository_root>
    ├── longhorn
    │   └── fleet.yaml
    └── longhorn-crd
        └── fleet.yaml
  • Contenido de fleet.yaml con datos de Longhorn del usuario:

    defaultNamespace: longhorn-system
    
    helm:
      # timeoutSeconds: 10
      releaseName: "longhorn"
      chart: "longhorn"
      repo: "https://charts.rancher.io/"
      version: "106.2.0+up1.8.1"
      takeOwnership: true
      # custom chart value overrides
      values:
        # Example for user provided custom values content
        defaultSettings:
          deletingConfirmationFlag: true
    
    # https://fleet.rancher.io/bundle-diffs
    diff:
      comparePatches:
      - apiVersion: apiextensions.k8s.io/v1
        kind: CustomResourceDefinition
        name: engineimages.longhorn.io
        operations:
        - {"op":"remove", "path":"/status/conditions"}
        - {"op":"remove", "path":"/status/storedVersions"}
        - {"op":"remove", "path":"/status/acceptedNames"}
      - apiVersion: apiextensions.k8s.io/v1
        kind: CustomResourceDefinition
        name: nodes.longhorn.io
        operations:
        - {"op":"remove", "path":"/status/conditions"}
        - {"op":"remove", "path":"/status/storedVersions"}
        - {"op":"remove", "path":"/status/acceptedNames"}
      - apiVersion: apiextensions.k8s.io/v1
        kind: CustomResourceDefinition
        name: volumes.longhorn.io
        operations:
        - {"op":"remove", "path":"/status/conditions"}
        - {"op":"remove", "path":"/status/storedVersions"}
        - {"op":"remove", "path":"/status/acceptedNames"}
    Nota
    Nota

    Estos son solo valores de ejemplo que se utilizan para mostrar configuraciones personalizadas en el chart de longhorn. NO deben considerarse directrices de despliegue para el chart de longhorn.

35.2.6.2.1.2 Despliegue la flota en su chart

Puede desplegar la flota de su chart usando GitRepo (Sección 35.2.6.2.1.2.1, “GitRepo”) o Bundle (Sección 35.2.6.2.1.2.2, “Bundle”).

Nota
Nota

Al desplegar su flota, si recibe un mensaje con la indicación Modified (Modificado), asegúrese de añadir la entrada comparePatches correspondiente a la sección diff del Fleet. Para obtener más información, consulte Generating Diffs to Ignore Modified GitRepos (Generación de diffs para ignorar recursos GitRepo modificados).

35.2.6.2.1.2.1 GitRepo

El recurso GitRepo de Fleet incluye información sobre cómo acceder a los recursos de Fleet de su chart y a qué clústeres deben aplicarse esos recursos.

El recurso GitRepo se puede desplegar mediante la interfaz de usuario de Rancher o, manualmente, desplegando el recurso en el clúster de gestión.

Recurso GitRepo de Longhorn de ejemplo para el despliegue manual:

apiVersion: fleet.cattle.io/v1alpha1
kind: GitRepo
metadata:
  name: longhorn-git-repo
  namespace: fleet-local
spec:
  # If using a tag
  # revision: user_repository_tag
  #
  # If using a branch
  # branch: user_repository_branch
  paths:
  # As seen in the 'Prepare your Fleet resources' example
  - longhorn
  - longhorn-crd
  repo: user_repository_url
35.2.6.2.1.2.2 Bundle

Los recursos Bundle contienen los recursos sin procesar de Kubernetes que debe desplegar Fleet. Normalmente, se recomienda utilizar el enfoque de GitRepo, pero en entornos aislados o que no admitan un servidor Git local, los Bundles pueden ayudarle a propagar su chart de Helm de Fleet a los clústeres de destino.

Es posible desplegar un Bundle mediante la interfaz de usuario de Rancher seleccionando Continuous Delivery → Advanced → Bundles → Create from YAML (Entrega continua → Avanzado → Bundles → Crear desde YAML)) o desplegando manualmente el recurso Bundle en el espacio de nombres de Fleet correcto. Para obtener información sobre los espacios de nombres de Fleet, consulte la documentación original.

Es posible crear Bundles para los charts de Helm de Edge convirtiendo un chart de Helm en un Bundle de Fleet.

A continuación, hay un ejemplo de cómo crear un recurso Bundle a partir de plantillas de flota de un chart de Helm de longhorn y longhorn-crd y cómo desplegar manualmente este Bundle en su clúster de gestión.

Nota
Nota

Para ilustrar el flujo de trabajo, el siguiente ejemplo usa la estructura de directorio suse-edge/fleet-examples.

  1. Diríjase a la plantilla de flota de chart de longhorn:

    cd fleets/day2/chart-templates/longhorn/longhorn
  2. Cree un archivo targets.yaml que indicará a Fleet en qué clústeres debe desplegar el chart de Helm:

    cat > targets.yaml <<EOF
    targets:
    # Match your local (management) cluster
    - clusterName: local
    EOF
    Nota
    Nota

    Hay casos prácticos en los que el clúster local podría tener un nombre diferente.

    Para recuperar el nombre del clúster local, ejecute el siguiente comando:

    kubectl get clusters.fleet.cattle.io -n fleet-local
  3. Convierta la flota de chart de Helm de Longhorn en un recurso Bundle mediante fleet-cli.

    Nota
    Nota

    Puede obtener la interfaz de línea de comandos de Fleet (fleet-linux-amd64) de la página Assets (Recursos) de su versión.

    Para usuarios de Mac, hay una versión propia de fleet-cli.

    fleet apply --compress --targets-file=targets.yaml -n fleet-local -o - longhorn-bundle > longhorn-bundle.yaml
  4. Diríjase a la plantilla de flota de chart longhorn-crd:

    cd fleets/day2/chart-templates/longhorn/longhorn-crd
  5. Cree un archivo targets.yaml que indicará a Fleet en qué clústeres debe desplegar el chart de Helm:

    cat > targets.yaml <<EOF
    targets:
    # Match your local (management) cluster
    - clusterName: local
    EOF
  6. Convierta la flota de chart de Helm de la CRD de Longhorn en un recurso Bundle mediante fleet-cli.

    fleet apply --compress --targets-file=targets.yaml -n fleet-local -o - longhorn-crd-bundle > longhorn-crd-bundle.yaml
  7. Despliegue los archivos longhorn-bundle.yaml y longhorn-crd-bundle.yaml en su clúster de gestión:

    kubectl apply -f longhorn-crd-bundle.yaml
    kubectl apply -f longhorn-bundle.yaml

Siga estos pasos para asegurarse de que SUSE Storage se despliega en todos los clústeres de gestión especificados.

35.2.6.2.1.3 Gestione el chart de Helm desplegado

Cuando se complete el despliegue con Fleet, para actualizaciones de charts de Helm, consulte la Sección 35.2.6.2.2, “Quiero actualizar un chart de Helm gestionado por Fleet”.

35.2.6.2.2 Quiero actualizar un chart de Helm gestionado por Fleet
  1. Determine la versión a la que debe actualizar su chart para que sea compatible con la versión deseada de Edge. Puede consultar la versión del chart de Helm para cada versión de Edge en las notas de la versión (Sección 52.1, “Resumen”).

  2. En su repositorio Git supervisado por Fleet, edite el archivo fleet.yaml del chart de Helm con la versión y el repositorio correctos del chart, tal y como se indica en las notas de la versión (Sección 52.1, “Resumen”).

  3. Después de confirmar y enviar los cambios al repositorio, se activará una actualización del chart de Helm deseado.

35.2.6.2.3 Quiero actualizar un chart de Helm desplegado mediante EIB

Capítulo 11, Edge Image Builder despliega charts de Helm creando un recurso HelmChart y usando el helm-controller introducido por la función de integración de Helm RKE2/K3s.

Para garantizar que un chart de Helm desplegado mediante EIB se actualice correctamente, los usuarios deben realizar una actualización de los recursos HelmChart correspondientes.

A continuación, encontrará más información:

35.2.6.2.3.1 Descripción general

Los charts de Helm que se despliegan mediante EIB se actualizan usando una flota llamada eib-charts-upgrader.

Esta flota procesa los datos proporcionados por el usuario para actualizar un conjunto específico de recursos HelmChart.

Al actualizar estos recursos se activa helm-controller, que actualiza los charts de Helm asociados con los recursos HelmChart modificados.

Solo se espera de los usuarios que:

  1. Extraigan localmente los archivos de cada chart de Helm que deba actualizarse.

  2. Pasen estos archivos al guion generate-chart-upgrade-data.sh generate-chart-upgrade-data.sh, que incluirá los datos de estos archivos en la flota eib-charts-upgrader.

  3. Desplieguen la flota eib-charts-upgrader a su clúster de gestión. Esto se hace con un recurso GitRepo o Bundle.

Una vez desplegado, eib-charts-upgrader, con la ayuda de Fleet, incluirá sus recursos en el clúster de gestión deseado.

Estos recursos incluyen:

  1. Un conjunto de secretos que guardan los datos del chart de Helm proporcionados por el usuario.

  2. Un trabajo de Kubernetes que desplegará un pod que montará los secretos mencionados anteriormente y, basándose en ellos, parcheará los recursos HelmChart correspondientes.

Como se mencionó anteriormente, esto activará helm-controller, que llevará a cabo la actualización real del chart de Helm.

A continuación, encontrará un diagrama de la descripción anterior:

actualización eib del helm de gestión de día 2 de fleet
35.2.6.2.3.2 Pasos para la actualización
  1. Clone el repositorio suse-edge/fleet-examples de la etiqueta de versión correcta.

  2. Cree un directorio en el que almacenarán los archivos de los charts de Helm extraídos.

    mkdir archives
  3. En el directorio recién creado, extraiga los archivos de los charts de Helm que desea actualizar:

    cd archives
    helm pull [chart URL | repo/chartname]
    
    # Alternatively if you want to pull a specific version:
    # helm pull [chart URL | repo/chartname] --version 0.0.0
  4. En la página Assets (Recursos) de la etiqueta de versión deseada, descargue el guion generate-chart-upgrade-data.sh.

  5. Ejecute el guion generate-chart-upgrade-data.sh:

    chmod +x ./generate-chart-upgrade-data.sh
    
    ./generate-chart-upgrade-data.sh --archive-dir /foo/bar/archives/ --fleet-path /foo/bar/fleet-examples/fleets/day2/eib-charts-upgrader

    Para cada archivo de chart del directorio --archive-dir, el guion genera un archivo Kubernetes Secret YAML que contiene los datos de actualización de chart y lo guardar en el directorio base/secrets de la flota especificada por --fleet-path.

    El guion generate-chart-upgrade-data.sh también aplica modificaciones adicionales a la flota para garantizar que la carga de trabajo desplegada por la flota utilice correctamente los archivos Kubernetes Secret YAML generados.

    Importante
    Importante

    Los usuarios no deben cambiar nada de lo que genera el guion generate-chart-upgrade-data.sh.

Los pasos siguientes dependen del entorno en el que se esté ejecutando:

  1. En un entorno que admita GitOps (por ejemplo, que no esté aislado, o que esté aislado pero permita la asistencia de un servidor Git local):

    1. Copie la flota fleets/day2/eib-charts-upgrader en el repositorio que usará para GitOps.

      Nota
      Nota

      Asegúrese de que la flota incluye los cambios realizados por el guion generate-chart-upgrade-data.sh.

    2. Configure un recurso GitRepo que se usará para incluir todos los recursos de la flota eib-charts-upgrader.

      1. Para la configuración y el despliegue de GitRepo mediante la interfaz de usuario de Rancher, consulte Accessing Fleet in the Rancher UI (Acceso a Fleet en la interfaz de usuario de Rancher).

      2. Para la configuración y el despliegue manuales de GitRepo, consulte Creating a Deployment (Creación de un despliegue).

  2. En un entorno que no admita GitOps (por ejemplo, un entorno aislado que no permita el uso de un servidor Git local):

    1. Descargue el binario de fleet-cli de la página de versión de rancher/fleet (fleet-linux-amd64 para Linux). Los usuarios de Mac pueden usar una versión propia: fleet-cli.

    2. Diríjase a la flota eib-charts-upgrader:

      cd /foo/bar/fleet-examples/fleets/day2/eib-charts-upgrader
    3. Cree un archivo targets.yaml que indicará a Fleet dónde debe desplegar los recursos:

      cat > targets.yaml <<EOF
      targets:
      # To map the local(management) cluster
      - clusterName: local
      EOF
      Nota
      Nota

      Hay casos prácticos en los que el clúster local podría tener un nombre diferente.

      Para recuperar el nombre del clúster local, ejecute el siguiente comando:

      kubectl get clusters.fleet.cattle.io -n fleet-local
    4. Utilice fleet-cli para convertir la flota en un recurso Bundle:

      fleet apply --compress --targets-file=targets.yaml -n fleet-local -o - eib-charts-upgrade > bundle.yaml

      Esto creará un Bundle (bundle.yaml) que contendrá todos los recursos de plantilla de la flota eib-charts-upgrader.

      Para obtener más información sobre el comando fleet apply, consulte fleet apply.

      Para obtener más información sobre cómo convertir flotas en Bundles, consulte Convert a Helm Chart into a Bundle (Conversión de un chart de Helm en un Bundle).

    5. Despliegue el Bundle. Puede hacerlo de dos formas:

      1. Mediante la interfaz de usuario de Rancher: seleccione Continuous Delivery → Advanced → Bundles → Create from YAML (Entrega continua → Avanzado → Bundles → Crear desde YAML) y pegue el contenido de bundle.yaml o haga clic en la opción Read from File (Leer desde archivo) y pase el archivo.

      2. Manualmente: despliegue el archivo bundle.yaml manualmente dentro de su clúster de gestión.

Al ejecutar estos pasos, se desplegará correctamente el recurso GitRepo/Bundle. Fleet recogerá el recurso y su contenido se desplegará en los clústeres de destino que el usuario haya especificado en los pasos anteriores. Para obtener una descripción general del proceso, consulte la Sección 35.2.6.2.3.1, “Descripción general”.

Para obtener información sobre cómo realizar un seguimiento del proceso de actualización, consulte la Sección 35.2.6.2.3.3, “Ejemplo”.

Importante
Importante

Cuando haya verificado que el chart se ha actualizado correctamente, elimine el recurso Bundle/GitRepo.

Esto eliminará los recursos de actualización que ya no son necesarios del clúster de gestión, lo que garantizará que no se produzcan conflictos entre versiones en el futuro.

35.2.6.2.3.3 Ejemplo
Nota
Nota

El siguiente ejemplo muestra cómo actualizar un chart de Helm desplegado mediante EIB de una versión a otra en un clúster de gestión. Tenga en cuenta que las versiones utilizadas en este ejemplo no son recomendaciones. Para obtener recomendaciones de versiones específicas para una versión de Edge, consulte las notas de la versión (Sección 52.1, “Resumen”).

Caso práctico:

  • Se ejecuta un clúster de gestión en una versión anterior de Longhorn.

  • El clúster se ha desplegado mediante EIB, utilizando el siguiente fragmento de definición de imagen:

    kubernetes:
      helm:
        charts:
        - name: longhorn-crd
          repositoryName: rancher-charts
          targetNamespace: longhorn-system
          createNamespace: true
          version: 104.2.0+up1.7.1
          installationNamespace: kube-system
        - name: longhorn
          repositoryName: rancher-charts
          targetNamespace: longhorn-system
          createNamespace: true
          version: 104.2.0+up1.7.1
          installationNamespace: kube-system
        repositories:
        - name: rancher-charts
          url: https://charts.rancher.io/
    ...
  • SUSE Storage debe actualizarse a una versión compatible con la versión Edge 3.3.1. Esto significa que debe actualizarse a 106.2.0+up1.8.1.

  • Se entiende que el clúster de gestión está aislado, sin asistencia para un servidor Git local y con una configuración de Rancher operativa.

Siga los pasos de actualización (Sección 35.2.6.2.3.2, “Pasos para la actualización”):

  1. Clone el repositorio suse-edge/fleet-example desde la etiqueta release-3.3.0.

    git clone -b release-3.3.0 https://github.com/suse-edge/fleet-examples.git
  2. Cree un directorio donde se almacenará el archivo de actualización de Longhorn.

    mkdir archives
  3. Extraiga la versión del archivo de chart de Longhorn deseada:

    # First add the Rancher Helm chart repository
    helm repo add rancher-charts https://charts.rancher.io/
    
    # Pull the Longhorn 1.8.1 CRD archive
    helm pull rancher-charts/longhorn-crd --version 106.2.0+up1.8.1
    
    # Pull the Longhorn 1.8.1 chart archive
    helm pull rancher-charts/longhorn --version 106.2.0+up1.8.1
  4. Fuera del directorio archives, descargue el guion generate-chart-upgrade-data.sh de la etiqueta de la versión suse-edge/fleet-examples.

  5. La configuración del directorio debería ser similar a:

    .
    ├── archives
    |   ├── longhorn-106.2.0+up1.8.1.tgz
    │   └── longhorn-crd-106.2.0+up1.8.1.tgz
    ├── fleet-examples
    ...
    │   ├── fleets
    │   │   ├── day2
    |   |   |   ├── ...
    │   │   │   ├── eib-charts-upgrader
    │   │   │   │   ├── base
    │   │   │   │   │   ├── job.yaml
    │   │   │   │   │   ├── kustomization.yaml
    │   │   │   │   │   ├── patches
    │   │   │   │   │   │   └── job-patch.yaml
    │   │   │   │   │   ├── rbac
    │   │   │   │   │   │   ├── cluster-role-binding.yaml
    │   │   │   │   │   │   ├── cluster-role.yaml
    │   │   │   │   │   │   ├── kustomization.yaml
    │   │   │   │   │   │   └── sa.yaml
    │   │   │   │   │   └── secrets
    │   │   │   │   │       ├── eib-charts-upgrader-script.yaml
    │   │   │   │   │       └── kustomization.yaml
    │   │   │   │   ├── fleet.yaml
    │   │   │   │   └── kustomization.yaml
    │   │   │   └── ...
    │   └── ...
    └── generate-chart-upgrade-data.sh
  6. Ejecute el guion generate-chart-upgrade-data.sh:

    # First make the script executable
    chmod +x ./generate-chart-upgrade-data.sh
    
    # Then execute the script
    ./generate-chart-upgrade-data.sh --archive-dir ./archives --fleet-path ./fleet-examples/fleets/day2/eib-charts-upgrader

    La estructura del directorio tras la ejecución del guion debería ser similar a esto:

    .
    ├── archives
    |   ├── longhorn-106.2.0+up1.8.1.tgz
    │   └── longhorn-crd-106.2.0+up1.8.1.tgz
    ├── fleet-examples
    ...
    │   ├── fleets
    │   │   ├── day2
    │   │   │   ├── ...
    │   │   │   ├── eib-charts-upgrader
    │   │   │   │   ├── base
    │   │   │   │   │   ├── job.yaml
    │   │   │   │   │   ├── kustomization.yaml
    │   │   │   │   │   ├── patches
    │   │   │   │   │   │   └── job-patch.yaml
    │   │   │   │   │   ├── rbac
    │   │   │   │   │   │   ├── cluster-role-binding.yaml
    │   │   │   │   │   │   ├── cluster-role.yaml
    │   │   │   │   │   │   ├── kustomization.yaml
    │   │   │   │   │   │   └── sa.yaml
    │   │   │   │   │   └── secrets
    │   │   │   │   │       ├── eib-charts-upgrader-script.yaml
    │   │   │   │   │       ├── kustomization.yaml
    │   │   │   │   │       ├── longhorn-VERSION.yaml - secret created by the generate-chart-upgrade-data.sh script
    │   │   │   │   │       └── longhorn-crd-VERSION.yaml - secret created by the generate-chart-upgrade-data.sh script
    │   │   │   │   ├── fleet.yaml
    │   │   │   │   └── kustomization.yaml
    │   │   │   └── ...
    │   └── ...
    └── generate-chart-upgrade-data.sh

    Los archivos modificados en Git deberían tener este aspecto:

    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
    	modified:   fleets/day2/eib-charts-upgrader/base/patches/job-patch.yaml
    	modified:   fleets/day2/eib-charts-upgrader/base/secrets/kustomization.yaml
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    	fleets/day2/eib-charts-upgrader/base/secrets/longhorn-VERSION.yaml
    	fleets/day2/eib-charts-upgrader/base/secrets/longhorn-crd-VERSION.yaml
  7. Cree un Bundle para la flota eib-charts-upgrader:

    1. En primer lugar, diríjase a la flota:

      cd ./fleet-examples/fleets/day2/eib-charts-upgrader
    2. A continuación, cree un archivo targets.yaml:

      cat > targets.yaml <<EOF
      targets:
      - clusterName: local
      EOF
    3. Después, use el binario de fleet-cli para convertir la flota en un Bundle:

      fleet apply --compress --targets-file=targets.yaml -n fleet-local -o - eib-charts-upgrade > bundle.yaml
  8. Despliegue el Bundle mediante la interfaz de usuario de Rancher:

    ejemplo 1 de actualización del chart de helm de día 2
    Figura 35.1: Despliegue del Bundle mediante la interfaz de Rancher

    Ahora, seleccione Read from File (Leer desde archivo) y busque el archivo bundle.yaml en su sistema.

    El Bundle se rellenará automáticamente en la interfaz de usuario de Rancher.

    Seleccione Create (Crear).

  9. Cuando haya finalizado el despliegue correctamente, el Bundle deberá tener un aspecto similar al siguiente:

    ejemplo 2 de actualización de chart del helm de día 2
    Figura 35.2: Bundle desplegado correctamente

Cuando haya finalizado el despliegue del Bundle correctamente, para supervisar el proceso de actualización:

  1. Verifique los registros del pod de actualización:

    ejemplo 3 de actualización de chart de helm de día 2 gestión
  2. Ahora, verifique los registros del pod creado para la actualización por helm-controller:

    1. El nombre del pod tendrá este formato: helm-install-longhorn-<sufijo aleatorio>

    2. El pod estará en el espacio de nombres donde se desplegó el recurso HelmChart. En nuestro caso, kube-system.

      ejemplo 4 de actualización de chart de helm de día 2 gestión
      Figura 35.3: Registros de chart de Longhorn actualizado correctamente
  3. Compruebe que la versión de HelmChart se ha actualizado. Para ello, diríjase a la sección HelmCharts de Rancher seleccionando More Resources → HelmCharts (Más recursos → HelmCharts). Seleccione el espacio de nombres donde se desplegó el chart; en este ejemplo, sería kube-system.

  4. Por último, compruebe que los pods de Longhorn se estén ejecutando.

Después de realizar las validaciones anteriores, se puede entender con seguridad que el chart de Helm de Longhorn se ha actualizado a la versión 106.2.0+up1.8.1.

35.2.6.2.3.4 Actualización del chart de Helm con una herramienta GitOps de terceros

Puede darse el caso de que los usuarios deseen utilizar este procedimiento de actualización con un flujo de trabajo de GitOps que no sea Fleet (por ejemplo, Flux).

Para generar los recursos necesarios para el procedimiento de actualización, puede usar el guion generate-chart-upgrade-data.sh para rellenar la flota eib-charts-upgrader con los datos proporcionados por el usuario. Para obtener más información sobre cómo hacerlo, consulte la Sección 35.2.6.2.3.2, “Pasos para la actualización”.

Cuando haya completado la configuración, puede utilizar kustomize para generar una solución totalmente funcional que puede desplegar en su clúster:

cd /foo/bar/fleets/day2/eib-charts-upgrader

kustomize build .

Si desea incluir la solución en su flujo de trabajo de GitOps, puede eliminar el archivo fleet.yaml y usar lo que queda como una configuración válida de Kustomize. No olvide ejecutar primero el guion generate-chart-upgrade-data.sh, para poder rellenar la configuración de Kustomize con los datos de los charts de Helm a los que desea actualizar.

Para comprender cómo se pretende usar este flujo de trabajo, puede resultar útil consultar la Sección 35.2.6.2.3.1, “Descripción general” y la Sección 35.2.6.2.3.2, “Pasos para la actualización”.

36 Clústeres descendentes

Importante
Importante

Los pasos siguientes no se aplican a clústeres descendentes gestionados por SUSE Edge for Telco (Capítulo 37, SUSE Edge for Telco). Para obtener información sobre cómo actualizar estos clústeres, consulte la Sección 43.2, “Actualización de clústeres descendentes”.

Esta sección describe las formas posibles de realizar operaciones de "día 2" para diferentes partes de su clúster descendente.

36.1 Fleet

Esta sección ofrece información sobre cómo realizar operaciones de "día 2" utilizando el componente Fleet (Capítulo 8, Fleet).

En esta sección se tratan los siguientes temas:

  1. Sección 36.1.1, “Componentes”: los componentes predeterminados usados para todas las operaciones de "día 2".

  2. Sección 36.1.2, “Determinación de su caso de uso”: proporciona una descripción general de los recursos personalizados de Fleet que se usarán y su idoneidad para diferentes casos de uso de operaciones de "día 2".

  3. Sección 36.1.3, “Flujo de trabajo de día 2”: proporciona una guía del flujo de trabajo para ejecutar operaciones de "día 2" con Fleet.

  4. Sección 36.1.4, “Actualización del sistema operativo”: describe cómo realizar actualizaciones del sistema operativo con Fleet.

  5. Sección 36.1.5, “Actualización de la versión de Kubernetes”: describe cómo realizar actualizaciones de la versión de Kubernetes con Fleet.

  6. Sección 36.1.6, “Actualización de charts de Helm”: describe cómo realizar actualizaciones de charts de Helm con Fleet.

36.1.1 Componentes

A continuación, encontrará una descripción de los componentes predeterminados que deben configurarse en el clúster descendente para poder realizar correctamente operaciones de "día 2" con Fleet.

36.1.1.1 System Upgrade Controller (SUC)

Nota
Nota

Debe desplegarse en cada clúster descendente.

System Upgrade Controller es responsable de ejecutar tareas en nodos específicos según los datos de configuración proporcionados mediante un recurso personalizado, denominado plan.

SUC se utiliza activamente para actualizar el sistema operativo y la distribución de Kubernetes.

Para obtener más información sobre el componente SUC y cómo encaja en la pila de Edge, consulte el Capítulo 22, System Upgrade Controller.

Para obtener información sobre cómo desplegar SUC, determine primero su caso práctico Sección 36.1.2, “Determinación de su caso de uso”) y, a continuación, consulte las secciones Instalación de System Upgrade Controller - GitRepo (Sección 22.2.1.1, “Instalación de System Upgrade Controller - GitRepo”) o Instalación de System Upgrade Controller - Bundle (Sección 22.2.1.2, “Instalación de System Upgrade Controller - Bundle”).

36.1.2 Determinación de su caso de uso

Fleet usa dos tipos de recursos personalizados para permitir la gestión de los recursos de Kubernetes y Helm.

A continuación, encontrará información sobre la finalidad de estos recursos y los casos de uso para los que son más adecuados en el contexto de las operaciones de "día 2".

36.1.2.1 GitRepo

Un GitRepo es un recurso de Fleet (Capítulo 8, Fleet) que representa un repositorio Git desde el que Fleet puede crear Bundles. Cada Bundle se crea en función de las rutas de configuración definidas dentro del recurso GitRepo. Para obtener más información, consulte la documentación de GitRepo.

En el contexto de las operaciones de "día 2", los recursos GitRepo se suelen usar para desplegar SUC o planes de SUC en entornos no aislados que emplean un enfoque de GitOps de Fleet.

Como alternativa, los recursos GitRepo también se pueden utilizar para desplegar SUC o planes de SUC en entornos aislados, siempre que se refleje la configuración del repositorio a través de un servidor Git local.

36.1.2.2 Bundle

Los Bundles contienen recursos sin procesar de Kubernetes que se desplegarán en el clúster de destino. Por lo general, se crean a partir de un recurso GitRepo, pero hay casos en los que se pueden desplegar manualmente. Para obtener más información, consulte la documentación de Bundle.

En el contexto de las operaciones de "día 2", los recursos Bundle se suelen usar para desplegar SUC o planes de SUC en entornos aislados que no utilizan algún tipo de procedimiento GitOps local (por ejemplo, un servidor Git local).

Alternativamente, si su caso de uso no permite un flujo de trabajo GitOps (por ejemplo, porque use un repositorio Git), también se pueden utilizar recursos Bundle para desplegar SUC o planes de SUC en entornos no aislados.

36.1.3 Flujo de trabajo de día 2

A continuación, se describe el flujo de trabajo de "día 2" que se debe seguir al actualizar un clúster descendente a una versión específica de Edge.

36.1.4 Actualización del sistema operativo

En esta sección se describe cómo realizar una actualización del sistema operativo utilizando Capítulo 8, Fleet y Capítulo 22, System Upgrade Controller.

En esta sección se tratan los siguientes temas:

  1. Sección 36.1.4.1, “Componentes”: componentes adicionales usados por el proceso de actualización.

  2. Sección 36.1.4.2, “Descripción general”: descripción general del proceso de actualización.

  3. Sección 36.1.4.3, “Requisitos”: requisitos del proceso de actualización.

  4. Sección 36.1.4.4, “Actualización del sistema operativo - Despliegue del plan de SUC”: información sobre cómo desplegar planes de SUC, responsables de iniciar el proceso de actualización.

36.1.4.1 Componentes

Esta sección trata sobre los componentes personalizados que el proceso de actualización del sistema operativo usa en lugar de los componentes predeterminados de "día 2" (Sección 36.1.1, “Componentes”).

36.1.4.1.1 systemd.service

La actualización del sistema operativo en un nodo específico se gestiona mediante un servicio systemd.service.

En función del tipo de actualización que requiera el sistema operativo de una versión de Edge a otra, se creará un servicio diferente:

  • Para las versiones de Edge que requieren la misma versión del sistema operativo (por ejemplo, la 6.0), se creará el servicio os-pkg-update.service. Use transactional-update para realizar una actualización normal del paquete.

  • Para las versiones de Edge que requieran una migración de la versión del sistema operativo (por ejemplo, de la 6.0 a la 6.1), se creará el servicio os-migration.service. Use transactional-update para realizar:

    1. Una actualización normal del paquete que garantice que todos los paquetes estén actualizados para mitigar cualquier fallo en la migración relacionado con versiones antiguas del paquete.

    2. Una migración del sistema operativo mediante el comando zypper migration.

Los servicios mencionados se incluyen a cada nodo mediante un plan de SUC que debe estar ubicado en el clúster descendente que necesita una actualización del sistema operativo.

36.1.4.2 Descripción general

La actualización del sistema operativo para los nodos del clúster descendente se realiza con Fleet y System Upgrade Controller (SUC).

Fleet se usa para desplegar y gestionar planes de SUC en el clúster deseado.

Nota
Nota

Los planes de SUC son recursos personalizados que describen los pasos que debe seguir SUC para ejecutar una tarea específica en un conjunto de nodos. Para ver un ejemplo de cómo es un plan de SUC, consulte el repositorio original.

Los planes de SUC de sistema operativo se envían a cada clúster desplegando un recurso GitRepo o Bundle a un espacio de trabajo de Fleet específico. Fleet recupera el GitRepo/Bundle desplegado y despliega su contenido (los planes de SUC de sistema operativo) en los clústeres deseados.

Nota
Nota

Los recursos GitRepo/Bundle siempre se despliegan en el clúster de gestión. Que se use un recurso GitRepo o Bundle depende del caso de uso. Consulte la Sección 36.1.2, “Determinación de su caso de uso” para obtener más información.

Los planes de SUC de sistema operativo describen el siguiente flujo de trabajo:

  1. Use siempre el comando cordon en los nodos antes de las actualizaciones del sistema operativo.

  2. Actualice siempre los nodos control-plane antes que los nodos worker.

  3. Actualice siempre el clúster en un único nodo cada vez.

Una vez desplegados los planes de SUC de sistema operativo, el flujo de trabajo es el siguiente:

  1. SUC reconcilia los planes de SUC de sistema operativo desplegados y crea un trabajo de Kubernetes en cada nodo.

  2. El trabajo de Kubernetes crea un servicio systemd.service (Sección 36.1.4.1.1, “systemd.service”) para la actualización de paquetes o para la migración del sistema operativo.

  3. El servicio systemd.service creado activa el proceso de actualización del sistema operativo en el nodo específico.

    Importante
    Importante

    Cuando finaliza el proceso de actualización del sistema operativo, el nodo correspondiente se rearranca para aplicar las actualizaciones en el sistema.

A continuación, encontrará un diagrama de la descripción anterior:

actualización del sistema operativo descendente día 2 fleet

36.1.4.3 Requisitos

Generales:

  1. Equipo registrado en el Centro de servicios al cliente de SUSE: todos los nodos del clúster descendentes deben estar registrados en https://scc.suse.com/. Es necesario para que el servicio systemd.service respectivo pueda conectarse correctamente al repositorio RPM deseado.

    Importante
    Importante

    Para las versiones de Edge que requieren una migración de la versión del sistema operativo (por ejemplo, de la 6.0 a la 6.1), asegúrese de que su clave del Centro de servicios al cliente de SUSE admita la migración a la nueva versión.

  2. Asegúrese de que las tolerancias del plan de SUC coincidan con las tolerancias de los nodos. Si los nodos de su clúster de Kubernetes tienen intolerancias (taints) personalizadas, asegúrese de añadir tolerancias (tolerations) para ellas en los planes de SUC. De forma predeterminada, los planes de SUC solo tienen tolerancias para los nodos de plano de control. Las tolerancias predeterminadas son:

    • CriticalAddonsOnly=true:NoExecute

    • node-role.kubernetes.io/control-plane:NoSchedule

    • node-role.kubernetes.io/etcd:NoExecute

      Nota
      Nota

      Cualquier tolerancia adicional debe añadirse en la sección .spec.tolerations de cada plan. Los planes de SUC relacionados con la actualización del sistema operativo se pueden encontrar en el repositorio suse-edge/fleet-examples en fleets/day2/system-upgrade-controller-plans/os-upgrade. Asegúrese de usar planes que tengan una etiqueta de versión de repositorio válida.

      Esto es un ejemplo de definición de tolerancias personalizadas para el plan de SUC de plano de control:

      apiVersion: upgrade.cattle.io/v1
      kind: Plan
      metadata:
        name: os-upgrade-control-plane
      spec:
        ...
        tolerations:
        # default tolerations
        - key: "CriticalAddonsOnly"
          operator: "Equal"
          value: "true"
          effect: "NoExecute"
        - key: "node-role.kubernetes.io/control-plane"
          operator: "Equal"
          effect: "NoSchedule"
        - key: "node-role.kubernetes.io/etcd"
          operator: "Equal"
          effect: "NoExecute"
        # custom toleration
        - key: "foo"
          operator: "Equal"
          value: "bar"
          effect: "NoSchedule"
      ...

En entornos aislados:

  1. Duplique los repositorios RPM de SUSE. Los repositorios RPM del sistema operativo deben duplicarse y guardarse de forma local para que el servicio systemd.service pueda acceder a ellos. Para ello, utilice RMT o SUMA.

36.1.4.4 Actualización del sistema operativo - Despliegue del plan de SUC

Importante
Importante

En entornos que se hayan actualizado previamente mediante este procedimiento, los usuarios deben asegurarse de que se haya completado uno de los pasos siguientes:

  • Elimine cualquier plan de SUC desplegado anteriormente relacionado con versiones anteriores de Edge del clúster descendente. Esto se puede hacer eliminando el clúster deseado de la configuración de destino de GitRepo/Bundle existente o eliminando por completo el recurso GitRepo/Bundle.

  • Reutilice el recurso GitRepo/Bundle existente. Puede hacerlo haciendo que la revisión del recurso apunte a una nueva etiqueta que contenga los recursos de Fleet correctos para la versión deseada de suse-edge/fleet-examples.

Esto se hace con el fin de evitar conflictos entre los planes de SUC para versiones anteriores de Edge.

Si los usuarios intentan actualizar, mientras haya planes de SUC existentes en el clúster descendente, verán el siguiente error de Fleet:

Not installed: Unable to continue with install: Plan <plan_name> in namespace <plan_namespace> exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error..

Como se menciona en la Sección 36.1.4.2, “Descripción general”, las actualizaciones del sistema operativo se realizan incluyendo planes de SUC en el clúster deseado de las siguientes formas:

Para determinar qué recurso se debe usar, consulte la Sección 36.1.2, “Determinación de su caso de uso”.

Si desea desplegar los planes de SUC de sistema operativo desde una herramienta GitOps de terceros, consulte la Sección 36.1.4.4.3, “Despliegue del plan de SUC - Flujo de trabajo de GitOps de terceros”.

36.1.4.4.1 Despliegue del plan de SUC - Recurso GitRepo

Es posible desplegar un recurso GitRepo, que incluye los planes de SUC de sistema operativo, de estas formas:

  1. Mediante la interfaz de usuario de Rancher: Sección 36.1.4.4.1.1, “Creación de GitRepo - Interfaz de usuario de Rancher” (si Rancher está disponible).

  2. Desplegando manualmente (Sección 36.1.4.4.1.2, “Creación de GitRepo - Manual”) el recurso en el clúster de gestión.

Una vez desplegado, para supervisar el proceso de actualización del sistema operativo de los nodos de su clúster de destino, consulte la Sección 22.3, “Supervisión de planes de System Upgrade Controller”.

36.1.4.4.1.1 Creación de GitRepo - Interfaz de usuario de Rancher

Para crear un recurso GitRepo con la interfaz de usuario de Rancher, siga la documentación oficial.

El equipo de Edge mantiene una flota (fleet) lista para usar. Dependiendo de su entorno, se puede utilizar directamente o como plantilla.

Importante
Importante

Use siempre esta flota desde una etiqueta de versión de Edge válida.

Para los casos prácticos en los que no es necesario incluir cambios personalizados en los planes de SUC que incluye la flota, los usuarios pueden usar directamente la flota os-upgrade desde el repositorio suse-edge/fleet-examples.

Si fuera necesario realizar cambios personalizados (por ejemplo, para añadir tolerancias personalizadas), los usuarios deben usar la flota os-upgrade desde un repositorio independiente, lo que les permitirá añadir los cambios a los planes de SUC según sea necesario.

Hay un ejemplo de cómo se puede configurar un recurso GitRepo para utilizar la flota del repositorio suse-edge/fleet-examples aquí.

36.1.4.4.1.2 Creación de GitRepo - Manual
  1. Extraiga el recurso GitRepo:

    curl -o os-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.3.0/gitrepos/day2/os-upgrade-gitrepo.yaml
  2. Edite la configuración de GitRepo. En spec.targets, especifique la lista de destinos que desee. De forma predeterminada, los recursos GitRepo de suse-edge/fleet-examples NO están asignados a ningún clúster descendente.

    • Para que coincidan todos los clústeres, cambie el destino predeterminado de GitRepo a:

      spec:
        targets:
        - clusterSelector: {}
    • Como alternativa, si desea una selección de clústeres más detallada, consulte Mapping to Downstream Clusters (Asignación a clústeres descendentes).

  3. Aplique el recurso GitRepo a su clúster de gestión:

    kubectl apply -f os-upgrade-gitrepo.yaml
  4. Consulte el recurso GitRepo creado en el espacio de nombres fleet-default:

    kubectl get gitrepo os-upgrade -n fleet-default
    
    # Example output
    NAME            REPO                                              COMMIT         BUNDLEDEPLOYMENTS-READY   STATUS
    os-upgrade      https://github.com/suse-edge/fleet-examples.git   release-3.3.0  0/0
36.1.4.4.2 Despliegue del plan de SUC - Recurso Bundle

Es posible desplegar un recurso Bundle, que incluye los planes de SUC de sistema operativo válidos, de estas formas:

  1. Mediante la interfaz de usuario de Rancher: Sección 36.1.4.4.2.1, “Creación de Bundle - Interfaz de usuario de Rancher” (si Rancher está disponible).

  2. Desplegando manualmente (Sección 36.1.4.4.2.2, “Creación del Bundle - Manual”) el recurso en el clúster de gestión.

Una vez desplegado, para supervisar el proceso de actualización del sistema operativo de los nodos de su clúster de destino, consulte la Sección 22.3, “Supervisión de planes de System Upgrade Controller”.

36.1.4.4.2.1 Creación de Bundle - Interfaz de usuario de Rancher

El equipo de Edge mantiene un bundle listo para usar que puede emplear en los pasos que se indican a continuación.

Importante
Importante

Use siempre este bundle desde una etiqueta de versión válida de Edge.

Para crear un bundle con la interfaz de usuario de Rancher:

  1. En la esquina superior izquierda, haga clic en ☰ → Continuous Delivery (☰ → Entrega continua).

  2. Diríjase a Advanced > Bundles (Avanzado > Bundles).

  3. Seleccione Create from YAML (Crear desde YAML).

  4. Desde aquí, puede crear el Bundle de las siguientes maneras:

    Nota
    Nota

    Puede haber casos en los que sea necesario incluir cambios personalizados en los planes de SUC que incluye el Bundle (por ejemplo, para añadir tolerancias personalizadas). Asegúrese de incluir esos cambios en el Bundle que se generará con los pasos siguientes.

    1. Copiando manualmente el contenido del Bundle desde suse-edge/fleet-examples a la página Create from YAML (Crear desde YAML).

    2. Clonando el repositorio suse-edge/fleet-examples desde la etiqueta de versión deseada y seleccionando la opciónRead from File (Leer desde archivo) en la página Create from YAML (Crear desde YAML). Desde ahí, diríjase a la ubicación del Bundle (bundles/day2/system-upgrade-controller-plans/os-upgrade) y seleccione el archivo del Bundle. Esto rellenará automáticamente la página Create from YAML (Crear desde YAML) con el contenido del Bundle.

  5. Cambie los clústeres de destino para el Bundle:

    • Para que coincidan todos los clústeres descendentes, cambie el valor .spec.targets predeterminado del Bundle a:

      spec:
        targets:
        - clusterSelector: {}
    • Para obtener asignaciones de clústeres descendentes más detalladas, consulte Mapping to Downstream Clusters (Asignación a clústeres descendentes).

  6. Seleccione Create (Crear).

36.1.4.4.2.2 Creación del Bundle - Manual
  1. Extraiga el recurso Bundle:

    curl -o os-upgrade-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.3.0/bundles/day2/system-upgrade-controller-plans/os-upgrade/os-upgrade-bundle.yaml
  2. Edite las configuraciones de destino del Bundle. En spec.targets, proporcione la lista de objetivos que desee. De forma predeterminada, los recursos Bundle de suse-edge/fleet-examples NO están asignados a ningún clúster descendente.

    • Para que coincidan con todos los clústeres descendentes, cambie el valor de destino predeterminado del Bundle a:

      spec:
        targets:
        - clusterSelector: {}
    • Como alternativa, si desea una selección de clústeres más detallada, consulte Mapping to Downstream Clusters (Asignación a clústeres descendentes).

  3. Aplique el recurso Bundle al clúster de gestión:

    kubectl apply -f os-upgrade-bundle.yaml
  4. Consulte el recurso Bundle creado en el espacio de nombres fleet-default:

    kubectl get bundles -n fleet-default
36.1.4.4.3 Despliegue del plan de SUC - Flujo de trabajo de GitOps de terceros

Puede haber casos prácticos en los que los usuarios deseen incorporar los planes de SUC de sistema operativo a su propio flujo de trabajo de GitOps de terceros (por ejemplo, Flux).

Para obtener los recursos de actualización del sistema operativo que necesita, determine primero la etiqueta de versión de Edge del repositorio suse-edge/fleet-examples que desea utilizar.

Después, los recursos se encuentran en fleets/day2/system-upgrade-controller-plans/os-upgrade, donde:

  • plan-control-plane.yaml es un recurso de plan de SUC para los nodos de plano de control.

  • plan-worker.yaml es un recurso de plan de SUC para los nodos de trabajador.

  • secret.yaml es un secreto que contiene el guion upgrade.sh, que se encarga de crear el servicio systemd.service (Sección 36.1.4.1.1, “systemd.service”).

  • config-map.yaml es un mapa de configuración que contiene las configuraciones que utiliza el guion upgrade.sh.

Importante
Importante

Estos recursos de plan son interpretados por System Upgrade Controller y se deben desplegar en cada clúster descendente que desee actualizar. Para obtener información sobre el despliegue de SUC, consulte la Sección 22.2, “Instalación de System Upgrade Controller”.

Para comprender mejor cómo usar su flujo de trabajo de GitOps para desplegar los planes de SUC para actualizar el sistema operativo, puede resultar útil echar un vistazo a la descripción general (Sección 36.1.4.2, “Descripción general”).

36.1.5 Actualización de la versión de Kubernetes

Importante
Importante

Esta sección trata sobre las actualizaciones de Kubernetes para clústeres descendentes que NO se hayan creado mediante una instancia de Rancher (Capítulo 5, Rancher). Para obtener información sobre cómo actualizar la versión de Kubernetes de los clústeres creados con Rancher, consulte Upgrading and Rolling Back Kubernetes (Actualización y reversión de Kubernetes).

En esta sección se describe cómo realizar una actualización de Kubernetes utilizando Capítulo 8, Fleet y Capítulo 22, System Upgrade Controller.

En esta sección se tratan los siguientes temas:

  1. Sección 36.1.5.1, “Componentes”: componentes adicionales usados por el proceso de actualización.

  2. Sección 36.1.5.2, “Descripción general”: descripción general del proceso de actualización.

  3. Sección 36.1.5.3, “Requisitos”: requisitos del proceso de actualización.

  4. Sección 36.1.5.4, “Actualización de K8s - Despliegue del plan de SUC”: información sobre cómo desplegar planes de SUC, responsables de iniciar el proceso de actualización.

36.1.5.1 Componentes

Esta sección trata sobre los componentes personalizados que el proceso de actualización de K8s usa en lugar de los componentes predeterminados de "día 2" (Sección 36.1.1, “Componentes”).

36.1.5.1.1 rke2-upgrade

Es la imagen de contenedor responsable de actualizar la versión de RKE2 de un nodo específico.

Se incluye a través de un pod creado por SUC basado en un plan de SUC. El plan debe estar ubicado en cada clúster que necesite una actualización de RKE2.

Para obtener más información sobre cómo la imagen rke2-upgrade realiza la actualización, consulte la documentación original.

36.1.5.1.2 k3s-upgrade

Es la imagen de contenedor responsable de actualizar la versión de K3s de un nodo específico.

Se incluye a través de un pod creado por SUC basado en un plan de SUC. El plan debe estar ubicado en cada clúster que necesite una actualización de K3s.

Para obtener más información sobre cómo realiza la imagen k3s-upgrade la actualización, consulte la documentación original.

36.1.5.2 Descripción general

La actualización de la distribución de Kubernetes para los nodos del clúster descendentes se realiza con Fleet y System Upgrade Controller (SUC).

Fleet se usa para desplegar y gestionar planes de SUC en el clúster deseado.

Nota
Nota

Los planes de SUC son recursos personalizados que describen los pasos que debe seguir SUC para ejecutar una tarea específica en un conjunto de nodos. Para ver un ejemplo de un plan de SUC, consulte el repositorio original.

Los planes de SUC de K8s se incluyen en cada clúster desplegando un recurso GitRepo o Bundle en un espacio de trabajo específico de Fleet. Fleet recupera el GitRepo/Bundle desplegado y despliega su contenido (los planes de SUC de K8s) en los clústeres deseados.

Nota
Nota

Los recursos GitRepo/Bundle siempre se despliegan en el clúster de gestión. Que se use un recurso GitRepo o Bundle depende del caso de uso. Consulte la Sección 36.1.2, “Determinación de su caso de uso” para obtener más información.

Los planes de SUC de K8s describen el siguiente flujo de trabajo:

  1. Use siempre el comando cordon en los nodos antes de las actualizaciones de K8s.

  2. Actualice siempre los nodos control-plane antes que los nodos worker.

  3. Actualice siempre los nodos de control-plane (plano de control) de uno en uno y los nodos worker (trabajador) de dos en dos.

Una vez desplegados los planes de SUC de K8s, el flujo de trabajo es el siguiente:

  1. SUC reconcilia los planes de SUC de K8s desplegados y crea un trabajo de Kubernetes en cada nodo.

  2. Dependiendo de la distribución de Kubernetes, el trabajo creará un pod que ejecutará la imagen de contenedor rke2-upgrade (Sección 36.1.5.1.1, “rke2-upgrade”) o k3s-upgrade (Sección 36.1.5.1.2, “k3s-upgrade”).

  3. El pod creado seguirá el siguiente flujo de trabajo:

    1. Sustituye el binario rke2/k3s existente en el nodo por el de la imagen rke2-upgrade/k3s-upgrade.

    2. Detiene el proceso rke2/k3s en ejecución.

  4. Al detener el proceso rke2/k3s, se activa un reinicio y se lanza un nuevo proceso que ejecuta el binario actualizado, lo que da como resultado una versión actualizada de la distribución de Kubernetes.

A continuación, encontrará un diagrama de la descripción anterior:

actualización k8s descendente de día 2 con fleet

36.1.5.3 Requisitos

  1. Haga una copia de seguridad de su distribución de Kubernetes:

    1. Para los clústeres RKE2, consulte RKE2 Backup and Restore (Copia de seguridad y restauración de RKE2).

    2. Para los clústeres K3s, consulte K3s Backup and Restore (Copia de seguridad y restauración de K3s).

  2. Asegúrese de que las tolerancias del plan de SUC coincidan con las tolerancias de los nodos. Si los nodos del clúster de Kubernetes tienen intolerancias (taints) personalizadas, asegúrese de añadir tolerancias (tolerations) para ellas en los planes de SUC. Por defecto, los planes de SUC solo tienen tolerancias para los nodos de plano de control. Las tolerancias predeterminadas son:

    • CriticalAddonsOnly=true:NoExecute

    • node-role.kubernetes.io/control-plane:NoSchedule

    • node-role.kubernetes.io/etcd:NoExecute

      Nota
      Nota

      Cualquier tolerancia adicional debe añadirse en la sección .spec.tolerations de cada plan. Los planes de SUC relacionados con la actualización de la versión de Kubernetes se encuentran en el repositorio suse-edge/fleet-examples en:

      • Para RKE2: fleets/day2/system-upgrade-controller-plans/rke2-upgrade

      • Para K3s: fleets/day2/system-upgrade-controller-plans/k3s-upgrade

      Asegúrese de usar los planes de una etiqueta de versión del repositorio válida.

      Este es un ejemplo de definición de tolerancias personalizadas para el plan de SUC de plano de control de RKE2:

      apiVersion: upgrade.cattle.io/v1
      kind: Plan
      metadata:
        name: rke2-upgrade-control-plane
      spec:
        ...
        tolerations:
        # default tolerations
        - key: "CriticalAddonsOnly"
          operator: "Equal"
          value: "true"
          effect: "NoExecute"
        - key: "node-role.kubernetes.io/control-plane"
          operator: "Equal"
          effect: "NoSchedule"
        - key: "node-role.kubernetes.io/etcd"
          operator: "Equal"
          effect: "NoExecute"
        # custom toleration
        - key: "foo"
          operator: "Equal"
          value: "bar"
          effect: "NoSchedule"
      ...

36.1.5.4 Actualización de K8s - Despliegue del plan de SUC

Importante
Importante

En entornos que se hayan actualizado previamente mediante este procedimiento, los usuarios deben asegurarse de que se haya completado uno de los pasos siguientes:

  • Elimine cualquier plan de SUC desplegado anteriormente relacionado con versiones anteriores de Edge del clúster descendente. Esto se puede hacer eliminando el clúster deseado de la configuración de destino de GitRepo/Bundle existente o eliminando por completo el recurso GitRepo/Bundle.

  • Reutilice el recurso GitRepo/Bundle existente. Puede hacerlo haciendo que la revisión del recurso apunte a una nueva etiqueta que contenga los recursos de Fleet correctos para la versión deseada de suse-edge/fleet-examples.

Esto se hace con el fin de evitar conflictos entre los planes de SUC para versiones anteriores de Edge.

Si los usuarios intentan actualizar, mientras haya planes de SUC existentes en el clúster descendente, verán el siguiente error de Fleet:

Not installed: Unable to continue with install: Plan <plan_name> in namespace <plan_namespace> exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error..

Como se menciona en la Sección 36.1.5.2, “Descripción general”, las actualizaciones de Kubernetes se realizan incluyendo planes de SUC en el clúster deseado de las siguientes formas:

Para determinar qué recurso se debe usar, consulte la Sección 36.1.2, “Determinación de su caso de uso”.

Si desea desplegar los planes de SUC de K8s desde una herramienta GitOps de terceros, consulte la Sección 36.1.5.4.3, “Despliegue del plan de SUC - Flujo de trabajo de GitOps de terceros”.

36.1.5.4.1 Despliegue del plan de SUC - Recurso GitRepo

Es posible desplegar un recurso GitRepo, que incluye los planes de SUC de K8s necesarios, de las siguientes formas:

  1. Mediante la interfaz de usuario de Rancher: Sección 36.1.5.4.1.1, “Creación de GitRepo - Interfaz de usuario de Rancher” (si Rancher está disponible).

  2. Desplegando manualmente (Sección 36.1.5.4.1.2, “Creación de GitRepo - Manual”) el recurso en el clúster de gestión.

Una vez desplegado, para supervisar el proceso de actualización de Kubernetes de los nodos del clúster de destino, consulte la Sección 22.3, “Supervisión de planes de System Upgrade Controller”.

36.1.5.4.1.1 Creación de GitRepo - Interfaz de usuario de Rancher

Para crear un recurso GitRepo con la interfaz de usuario de Rancher, siga la documentación oficial.

El equipo de Edge mantiene flotas listas para usar para las distribuciones de Kubernetes rke2 y k3s. Según su entorno, estas flotas se pueden usar directamente o como plantilla.

Importante
Importante

Utilice siempre estas flotas desde una etiqueta de versión de Edge válida.

Cuando no sea necesario incluir cambios personalizados en los planes de SUC que incluyen estas flotas, los usuarios pueden consultar directamente las flotas en el repositorio suse-edge/fleet-examples.

Si fuera necesario realizar cambios personalizados (por ejemplo, para añadir tolerancias personalizadas), los usuarios deben consultar las flotas desde un repositorio independiente, lo que les permitirá añadir los cambios a los planes de SUC según sea necesario.

Ejemplos de configuración para un recurso GitRepo utilizando las flotas del repositorio suse-edge/fleet-examples:

36.1.5.4.1.2 Creación de GitRepo - Manual
  1. Extraiga el recurso GitRepo:

    • Para clústeres RKE2:

      curl -o rke2-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.3.0/gitrepos/day2/rke2-upgrade-gitrepo.yaml
    • Para clústeres K3s:

      curl -o k3s-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.3.0/gitrepos/day2/k3s-upgrade-gitrepo.yaml
  2. Edite la configuración de GitRepo. En spec.targets, especifique la lista de destinos que desee. De forma predeterminada, los recursos GitRepo de suse-edge/fleet-examples NO están asignados a ningún clúster descendente.

    • Para que coincidan todos los clústeres, cambie el destino predeterminado de GitRepo a:

      spec:
        targets:
        - clusterSelector: {}
    • Como alternativa, si desea una selección de clústeres más detallada, consulte Mapping to Downstream Clusters (Asignación a clústeres descendentes).

  3. Aplique los recursos GitRepo a su clúster de gestión:

    # RKE2
    kubectl apply -f rke2-upgrade-gitrepo.yaml
    
    # K3s
    kubectl apply -f k3s-upgrade-gitrepo.yaml
  4. Consulte el recurso GitRepo creado en el espacio de nombres fleet-default:

    # RKE2
    kubectl get gitrepo rke2-upgrade -n fleet-default
    
    # K3s
    kubectl get gitrepo k3s-upgrade -n fleet-default
    
    # Example output
    NAME           REPO                                              COMMIT          BUNDLEDEPLOYMENTS-READY   STATUS
    k3s-upgrade    https://github.com/suse-edge/fleet-examples.git   fleet-default   0/0
    rke2-upgrade   https://github.com/suse-edge/fleet-examples.git   fleet-default   0/0
36.1.5.4.2 Despliegue del plan de SUC - Recurso Bundle

Es posible desplegar un recurso Bundle, que incluye los planes de SUC de actualización de Kubernetes necesarios, de una de estas formas:

  1. Mediante la interfaz de usuario de Rancher: Sección 36.1.5.4.2.1, “Creación de Bundle - Interfaz de usuario de Rancher” (si Rancher está disponible).

  2. Desplegando manualmente (Sección 36.1.5.4.2.2, “Creación del Bundle - Manual”) el recurso en el clúster de gestión.

Una vez desplegado, para supervisar el proceso de actualización de Kubernetes de los nodos del clúster de destino, consulte la Sección 22.3, “Supervisión de planes de System Upgrade Controller”.

36.1.5.4.2.1 Creación de Bundle - Interfaz de usuario de Rancher

El equipo de Edge mantiene bundles listos para usar para las distribuciones de Kubernetes rke2 y k3s. Dependiendo de su entorno, estos bundles se pueden utilizar directamente o como plantilla.

Importante
Importante

Use siempre este bundle desde una etiqueta de versión válida de Edge.

Para crear un bundle con la interfaz de usuario de Rancher:

  1. En la esquina superior izquierda, haga clic en ☰ → Continuous Delivery (☰ → Entrega continua).

  2. Diríjase a Advanced > Bundles (Avanzado > Bundles).

  3. Seleccione Create from YAML (Crear desde YAML).

  4. Desde aquí, puede crear el Bundle de las siguientes maneras:

    Nota
    Nota

    Puede haber casos en los que sea necesario incluir cambios personalizados en los planes de SUC que incluye el Bundle (por ejemplo, para añadir tolerancias personalizadas). Asegúrese de incluir esos cambios en el Bundle que se generará con los pasos siguientes.

    1. Copie manualmente el contenido del Bundle para RKE2 o K3s desde suse-edge/fleet-examples en la página Create from YAML (Crear desde YAML).

    2. Clone el repositorio suse-edge/fleet-examples desde la etiqueta de versión deseada y seleccione la opción Read from File (Leer desde archivo) en la página Create from YAML (Crear desde YAML). Desde ahí, diríjase al Bundle que necesita (bundles/day2/system-upgrade-controller-plans/rke2-upgrade/plan-bundle.yaml para RKE2 y bundles/day2/system-upgrade-controller-plans/k3s-upgrade/plan-bundle.yaml para K3s). La página Create from YAML (Crear desde YAML) se rellenará automáticamente con el contenido del paquete.

  5. Cambie los clústeres de destino para el Bundle:

    • Para que coincidan todos los clústeres descendentes, cambie el valor .spec.targets predeterminado del Bundle a:

      spec:
        targets:
        - clusterSelector: {}
    • Para obtener asignaciones de clústeres descendentes más detalladas, consulte Mapping to Downstream Clusters (Asignación a clústeres descendentes).

  6. Seleccione Create (Crear).

36.1.5.4.2.2 Creación del Bundle - Manual
  1. Extraiga los recursos Bundle:

    • Para clústeres RKE2:

      curl -o rke2-plan-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.3.0/bundles/day2/system-upgrade-controller-plans/rke2-upgrade/plan-bundle.yaml
    • Para clústeres K3s:

      curl -o k3s-plan-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.3.0/bundles/day2/system-upgrade-controller-plans/k3s-upgrade/plan-bundle.yaml
  2. Edite las configuraciones de destino del Bundle. En spec.targets, proporcione la lista de objetivos que desee. De forma predeterminada, los recursos Bundle de suse-edge/fleet-examples NO están asignados a ningún clúster descendente.

    • Para que coincidan con todos los clústeres descendentes, cambie el valor de destino predeterminado del Bundle a:

      spec:
        targets:
        - clusterSelector: {}
    • Como alternativa, si desea una selección de clústeres más detallada, consulte Mapping to Downstream Clusters (Asignación a clústeres descendentes).

  3. Aplique los recursos Bundle al clúster de gestión:

    # For RKE2
    kubectl apply -f rke2-plan-bundle.yaml
    
    # For K3s
    kubectl apply -f k3s-plan-bundle.yaml
  4. Consulte el recurso Bundle creado en el espacio de nombres fleet-default:

    # For RKE2
    kubectl get bundles rke2-upgrade -n fleet-default
    
    # For K3s
    kubectl get bundles k3s-upgrade -n fleet-default
    
    # Example output
    NAME           BUNDLEDEPLOYMENTS-READY   STATUS
    k3s-upgrade    0/0
    rke2-upgrade   0/0
36.1.5.4.3 Despliegue del plan de SUC - Flujo de trabajo de GitOps de terceros

Puede haber casos prácticos en los que los usuarios deseen incorporar los planes de SUC de actualización de Kubernetes a su propio flujo de trabajo de GitOps de terceros (por ejemplo, Flux).

Para obtener los recursos de actualización de K8s que necesita, primero determine la etiqueta de versión de Edge del repositorio suse-edge/fleet-examples que desea utilizar.

Después, los recursos se encuentran en:

  • Para actualizar un clúster RKE2:

    • Para nodos control-plane: fleets/day2/system-upgrade-controller-plans/rke2-upgrade/plan-control-plane.yaml

    • Para nodos worker: fleets/day2/system-upgrade-controller-plans/rke2-upgrade/plan-worker.yaml

  • Para actualizar un clúster K3s:

    • Para nodos control-plane: fleets/day2/system-upgrade-controller-plans/k3s-upgrade/plan-control-plane.yaml

    • Para nodos worker: fleets/day2/system-upgrade-controller-plans/k3s-upgrade/plan-worker.yaml

Importante
Importante

Estos recursos de plan son interpretados por System Upgrade Controller y se deben desplegar en cada clúster descendente que desee actualizar. Para obtener información sobre el despliegue de SUC, consulte la Sección 22.2, “Instalación de System Upgrade Controller”.

Para comprender mejor cómo usar su flujo de trabajo de GitOps para desplegar los planes de SUC para actualizar la versión de Kubernetes, puede resultar útil echar un vistazo a la descripción general (Sección 36.1.5.2, “Descripción general”) del procedimiento de actualización utilizando Fleet.

36.1.6 Actualización de charts de Helm

Esta sección cubre lo siguiente:

  1. Sección 36.1.6.1, “Preparación para entornos aislados”: contiene información sobre cómo incluir charts e imágenes OCI relacionados con Edge en su registro privado.

  2. Sección 36.1.6.2, “Procedimiento de actualización”: contiene información sobre diferentes casos de actualización de charts de Helm y su procedimiento de actualización.

36.1.6.1 Preparación para entornos aislados

36.1.6.1.1 Asegúrese de tener acceso a los recursos de Fleect del chart de Helm

Dependiendo de lo que admita su entorno, puede elegir una de estas opciones:

  1. Aloje los recursos de Fleet de su chart en un servidor Git local al que pueda acceder su clúster de gestión.

  2. Use la interfaz de línea de comandos de Fleet para convertir un chart de Helm en un Bundle que podrá utilizar directamente sin necesidad de alojarlo en ningún sitio. Puede descargar la interfaz de línea de comandos de la página de la versión. Para los usuarios de Mac, hay una versión propia de fleet-cli.

36.1.6.1.2 Busque los recursos necesarios para su versión de Edge
  1. Vaya a la página de la versión de "día 2", busque la versión de Edge a la que desea actualizar su chart y haga clic en Assets (Recursos).

  2. En la sección Assets (Recursos), descargue los archivos siguientes:

    Archivo de versión

    Descripción

    edge-save-images.sh

    Extrae las imágenes especificadas en el archivo edge-release-images.txt y las empaqueta en un archivo ".tar.gz".

    edge-save-oci-artefacts.sh

    Extrae las imágenes del chart OCI relacionadas con la versión específica de Edge y las empaqueta en un archivo ".tar.gz".

    edge-load-images.sh

    Carga imágenes desde un archivo ".tar.gz", las vuelve a etiquetar y las envía a un registro privado.

    edge-load-oci-artefacts.sh

    Toma un directorio que contiene paquetes de charts OCI ".tgz" de Edge y los carga en un registro privado.

    edge-release-helm-oci-artefacts.txt

    Contiene una lista de imágenes de charts OCI relacionadas con una versión específica de Edge.

    edge-release-images.txt

    Contiene una lista de imágenes relacionadas con una versión específica de Edge.

36.1.6.1.3 Cree el archivo de imágenes de la versión de Edge

En un equipo con acceso a Internet:

  1. Permita que edge-save-images.sh se pueda ejecutar:

    chmod +x edge-save-images.sh
  2. Genere el archivo de imagen:

    ./edge-save-images.sh --source-registry registry.suse.com
  3. Esto creará un archivo listo para cargar llamado edge-images.tar.gz.

    Nota
    Nota

    Si se especifica la opción -i|--images, el nombre del archivo puede ser diferente.

  4. Copie este archivo a su equipo aislado:

    scp edge-images.tar.gz <user>@<machine_ip>:/path
36.1.6.1.4 Cree el archivo de imágenes del chart OCI de Edge

En un equipo con acceso a Internet:

  1. Permita que edge-save-oci-artefacts.sh se pueda ejecutar:

    chmod +x edge-save-oci-artefacts.sh
  2. Genere el archivo de imagen del chart OCI:

    ./edge-save-oci-artefacts.sh --source-registry registry.suse.com
  3. Esto creará un archivo denominado oci-artefacts.tar.gz.

    Nota
    Nota

    Si se especifica la opción -a|--archive, el nombre del archivo puede ser distinto.

  4. Copie este archivo a su equipo aislado:

    scp oci-artefacts.tar.gz <user>@<machine_ip>:/path
36.1.6.1.5 Cargue las imágenes de la versión de Edge en su equipo aislado

En su equipo aislado:

  1. Inicie sesión en su registro privado (si es necesario):

    podman login <REGISTRY.YOURDOMAIN.COM:PORT>
  2. Permita que edge-load-images.sh se pueda ejecutar:

    chmod +x edge-load-images.sh
  3. Ejecute el guion pasando el archivo edge-images.tar.gz copiado anteriormente:

    ./edge-load-images.sh --source-registry registry.suse.com --registry <REGISTRY.YOURDOMAIN.COM:PORT> --images edge-images.tar.gz
    Nota
    Nota

    Esto cargará todas las imágenes desde edge-images.tar.gz, las volverá a etiquetar y las enviará al registro especificado en la opción --registry.

36.1.6.1.6 Cargue las imágenes del chart OCI de Edge en su equipo aislado

En su equipo aislado:

  1. Inicie sesión en su registro privado (si es necesario):

    podman login <REGISTRY.YOURDOMAIN.COM:PORT>
  2. Permita que edge-load-oci-artefacts.sh se pueda ejecutar:

    chmod +x edge-load-oci-artefacts.sh
  3. Desempaquete el archivo oci-artefacts.tar.gz copiado:

    tar -xvf oci-artefacts.tar.gz
  4. Esto generará un directorio con el formato de nombre edge-release-oci-tgz-<fecha>.

  5. Pase este directorio al guion edge-load-oci-artefacts.sh para cargar las imágenes del chart OCI de Edge a su registro privado:

    Nota
    Nota

    Este guion presupone que la interfaz de línea de comandos de Helm ya está preinstalada en su entorno. Para obtener instrucciones sobre la instalación de Helm, consulte Installing Helm (Instalación de Helm).

    ./edge-load-oci-artefacts.sh --archive-directory edge-release-oci-tgz-<date> --registry <REGISTRY.YOURDOMAIN.COM:PORT> --source-registry registry.suse.com
36.1.6.1.7 Configure el registro privado en su distribución de Kubernetes

Para RKE2, consulte Private Registry Configuration (Configuración del registro privado)

Para K3s, consulte Private Registry Configuration (Configuración del registro privado)

36.1.6.2 Procedimiento de actualización

Esta sección se centra en los siguientes casos prácticos del procedimiento de actualización de Helm:

Importante
Importante

Los charts de Helm desplegados manualmente no se pueden actualizar de forma fiable. Recomendamos volver a desplegar el chart de Helm utilizando el método Sección 36.1.6.2.1, “Tengo un nuevo clúster y me gustaría desplegar y gestionar un chart de Helm de Edge”.

36.1.6.2.1 Tengo un nuevo clúster y me gustaría desplegar y gestionar un chart de Helm de Edge

En esta sección se trata lo siguiente:

36.1.6.2.1.1 Prepare los recursos de Fleet para su chart
  1. Adquiera los recursos de Fleet del chart desde la etiqueta de versión de Edge que desee usar.

  2. Diríjase a la flota del chart de Helm (fleets/day2/chart-templates/<chart>).

  3. Si tiene intención de utilizar un flujo de trabajo de GitOps, copie el directorio Fleet del chart en el repositorio Git desde donde realizará la operación de GitOps.

  4. Opcionalmente, si el chart de Helm requiere que se configuren sus valores, edite la configuración de .helm.values dentro del archivo fleet.yaml del directorio copiado.

  5. Opcionalmente, puede haber casos en los que sea necesario añadir recursos adicionales a la flota de su chart para que se adapte mejor a su entorno. Para obtener información sobre cómo mejorar su directorio de Fleet, consulte Git Repository Contents (Contenido del repositorio Git).

Nota
Nota

En algunos casos, el tiempo de espera predeterminado que Fleet usa para las operaciones de Helm puede ser insuficiente, lo que da lugar al siguiente error:

failed pre-install: context deadline exceeded

Si fuera el caso, añada la propiedad timeoutSeconds en la configuración de helm de su archivo fleet.yaml.

Esto es un ejemplo del aspecto que tendría el chart de Helm de longhorn:

  • Estructura del repositorio Git del usuario:

    <user_repository_root>
    ├── longhorn
    │   └── fleet.yaml
    └── longhorn-crd
        └── fleet.yaml
  • Contenido de fleet.yaml con datos de Longhorn del usuario:

    defaultNamespace: longhorn-system
    
    helm:
      # timeoutSeconds: 10
      releaseName: "longhorn"
      chart: "longhorn"
      repo: "https://charts.rancher.io/"
      version: "106.2.0+up1.8.1"
      takeOwnership: true
      # custom chart value overrides
      values:
        # Example for user provided custom values content
        defaultSettings:
          deletingConfirmationFlag: true
    
    # https://fleet.rancher.io/bundle-diffs
    diff:
      comparePatches:
      - apiVersion: apiextensions.k8s.io/v1
        kind: CustomResourceDefinition
        name: engineimages.longhorn.io
        operations:
        - {"op":"remove", "path":"/status/conditions"}
        - {"op":"remove", "path":"/status/storedVersions"}
        - {"op":"remove", "path":"/status/acceptedNames"}
      - apiVersion: apiextensions.k8s.io/v1
        kind: CustomResourceDefinition
        name: nodes.longhorn.io
        operations:
        - {"op":"remove", "path":"/status/conditions"}
        - {"op":"remove", "path":"/status/storedVersions"}
        - {"op":"remove", "path":"/status/acceptedNames"}
      - apiVersion: apiextensions.k8s.io/v1
        kind: CustomResourceDefinition
        name: volumes.longhorn.io
        operations:
        - {"op":"remove", "path":"/status/conditions"}
        - {"op":"remove", "path":"/status/storedVersions"}
        - {"op":"remove", "path":"/status/acceptedNames"}
    Nota
    Nota

    Estos son solo valores de ejemplo que se utilizan para mostrar configuraciones personalizadas en el chart de longhorn. NO deben considerarse directrices de despliegue para el chart de longhorn.

36.1.6.2.1.2 Despliegue la flota en su chart

Puede desplegar la flota de su chart usando GitRepo (Sección 36.1.6.2.1.2.1, “GitRepo”) o Bundle (Sección 36.1.6.2.1.2.2, “Bundle”).

Nota
Nota

Al desplegar su flota, si recibe un mensaje con la indicación Modified (Modificado), asegúrese de añadir la entrada comparePatches correspondiente a la sección diff del Fleet. Para obtener más información, consulte Generating Diffs to Ignore Modified GitRepos (Generación de diffs para ignorar recursos GitRepo modificados).

36.1.6.2.1.2.1 GitRepo

El recurso GitRepo de Fleet incluye información sobre cómo acceder a los recursos de Fleet de su chart y a qué clústeres deben aplicarse esos recursos.

El recurso GitRepo se puede desplegar mediante la interfaz de usuario de Rancher o, manualmente, desplegando el recurso en el clúster de gestión.

Recurso GitRepo de Longhorn de ejemplo para el despliegue manual:

apiVersion: fleet.cattle.io/v1alpha1
kind: GitRepo
metadata:
  name: longhorn-git-repo
  namespace: fleet-default
spec:
  # If using a tag
  # revision: user_repository_tag
  #
  # If using a branch
  # branch: user_repository_branch
  paths:
  # As seen in the 'Prepare your Fleet resources' example
  - longhorn
  - longhorn-crd
  repo: user_repository_url
  targets:
  # Match all clusters
  - clusterSelector: {}
36.1.6.2.1.2.2 Bundle

Los recursos Bundle contienen los recursos sin procesar de Kubernetes que debe desplegar Fleet. Normalmente, se recomienda utilizar el enfoque de GitRepo, pero en entornos aislados o que no admitan un servidor Git local, los Bundles pueden ayudarle a propagar su chart de Helm de Fleet a los clústeres de destino.

Es posible desplegar un Bundle mediante la interfaz de usuario de Rancher seleccionando Continuous Delivery → Advanced → Bundles → Create from YAML (Entrega continua → Avanzado → Bundles → Crear desde YAML)) o desplegando manualmente el recurso Bundle en el espacio de nombres de Fleet correcto. Para obtener información sobre los espacios de nombres de Fleet, consulte la documentación original.

Es posible crear Bundles para los charts de Helm de Edge convirtiendo un chart de Helm en un Bundle de Fleet.

A continuación, hay un ejemplo de cómo crear un recurso Bundle a partir de plantillas de flota de un chart de Helm de longhorn y longhorn-crd y cómo desplegar manualmente este Bundle en su clúster de gestión.

Nota
Nota

Para ilustrar el flujo de trabajo, el siguiente ejemplo usa la estructura de directorio suse-edge/fleet-examples.

  1. Diríjase a la plantilla de flota de chart de longhorn:

    cd fleets/day2/chart-templates/longhorn/longhorn
  2. Cree un archivo targets.yaml que indicará a Fleet en qué clústeres debe desplegar el chart de Helm:

    cat > targets.yaml <<EOF
    targets:
    # Matches all downstream clusters
    - clusterSelector: {}
    EOF

    Para una selección más detallada de clústeres descendentes, consulte Mapping to Downstream Clusters (Asignación a clústeres descendentes).

  3. Convierta la flota de chart de Helm de Longhorn en un recurso Bundle mediante fleet-cli.

    Nota
    Nota

    Puede obtener la interfaz de línea de comandos de Fleet (fleet-linux-amd64) de la página Assets (Recursos) de su versión.

    Para usuarios de Mac, hay una versión propia de fleet-cli.

    fleet apply --compress --targets-file=targets.yaml -n fleet-default -o - longhorn-bundle > longhorn-bundle.yaml
  4. Diríjase a la plantilla de flota de chart longhorn-crd:

    cd fleets/day2/chart-templates/longhorn/longhorn-crd
  5. Cree un archivo targets.yaml que indicará a Fleet en qué clústeres debe desplegar el chart de Helm:

    cat > targets.yaml <<EOF
    targets:
    # Matches all downstream clusters
    - clusterSelector: {}
    EOF
  6. Convierta la flota de chart de Helm de la CRD de Longhorn en un recurso Bundle mediante fleet-cli.

    fleet apply --compress --targets-file=targets.yaml -n fleet-default -o - longhorn-crd-bundle > longhorn-crd-bundle.yaml
  7. Despliegue los archivos longhorn-bundle.yaml y longhorn-crd-bundle.yaml en su clúster de gestión:

    kubectl apply -f longhorn-crd-bundle.yaml
    kubectl apply -f longhorn-bundle.yaml

Seguir estos pasos garantizará que SUSE Storage se despliegue en todos los clústeres descendentes especificados.

36.1.6.2.1.3 Gestione el chart de Helm desplegado

Cuando se complete el despliegue con Fleet, para actualizaciones de charts de Helm, consulte la Sección 36.1.6.2.2, “Quiero actualizar un chart de Helm gestionado por Fleet”.

36.1.6.2.2 Quiero actualizar un chart de Helm gestionado por Fleet
  1. Determine la versión a la que debe actualizar su chart para que sea compatible con la versión deseada de Edge. Puede consultar la versión del chart de Helm para cada versión de Edge en las notas de la versión (Sección 52.1, “Resumen”).

  2. En su repositorio Git supervisado por Fleet, edite el archivo fleet.yaml del chart de Helm con la versión y el repositorio correctos del chart, tal y como se indica en las notas de la versión (Sección 52.1, “Resumen”).

  3. Después de confirmar y enviar los cambios al repositorio, se activará una actualización del chart de Helm deseado.

36.1.6.2.3 Quiero actualizar un chart de Helm desplegado mediante EIB

Capítulo 11, Edge Image Builder despliega charts de Helm creando un recurso HelmChart y usando el helm-controller introducido por la función de integración de Helm RKE2/K3s.

Para garantizar que un chart de Helm desplegado mediante EIB se actualice correctamente, los usuarios deben realizar una actualización de los recursos HelmChart correspondientes.

A continuación, encontrará más información:

36.1.6.2.3.1 Descripción general

Los charts de Helm que se despliegan mediante EIB se actualizan usando una flota llamada eib-charts-upgrader.

Esta flota procesa los datos proporcionados por el usuario para actualizar un conjunto específico de recursos HelmChart.

Al actualizar estos recursos se activa helm-controller, que actualiza los charts de Helm asociados con los recursos HelmChart modificados.

Solo se espera de los usuarios que:

  1. Extraigan localmente los archivos de cada chart de Helm que deba actualizarse.

  2. Pasen estos archivos al guion generate-chart-upgrade-data.sh generate-chart-upgrade-data.sh, que incluirá los datos de estos archivos en la flota eib-charts-upgrader.

  3. Desplieguen la flota eib-charts-upgrader a su clúster de gestión. Esto se hace con un recurso GitRepo o Bundle.

Una vez desplegado, eib-charts-upgrader, con ayuda de Fleet, incluirá sus recursos en el clúster descendente deseado.

Estos recursos incluyen:

  1. Un conjunto de secretos que guardan los datos del chart de Helm proporcionados por el usuario.

  2. Un trabajo de Kubernetes que desplegará un pod que montará los secretos mencionados anteriormente y, basándose en ellos, parcheará los recursos HelmChart correspondientes.

Como se mencionó anteriormente, esto activará helm-controller, que llevará a cabo la actualización real del chart de Helm.

A continuación, encontrará un diagrama de la descripción anterior:

actualización eib de helm descendente de día 2 con fleet
36.1.6.2.3.2 Pasos para la actualización
  1. Clone el repositorio suse-edge/fleet-examples de la etiqueta de versión correcta.

  2. Cree un directorio en el que almacenarán los archivos de los charts de Helm extraídos.

    mkdir archives
  3. En el directorio recién creado, extraiga los archivos de los charts de Helm que desea actualizar:

    cd archives
    helm pull [chart URL | repo/chartname]
    
    # Alternatively if you want to pull a specific version:
    # helm pull [chart URL | repo/chartname] --version 0.0.0
  4. En la página Assets (Recursos) de la etiqueta de versión deseada, descargue el guion generate-chart-upgrade-data.sh.

  5. Ejecute el guion generate-chart-upgrade-data.sh:

    chmod +x ./generate-chart-upgrade-data.sh
    
    ./generate-chart-upgrade-data.sh --archive-dir /foo/bar/archives/ --fleet-path /foo/bar/fleet-examples/fleets/day2/eib-charts-upgrader

    Para cada archivo de chart del directorio --archive-dir, el guion genera un archivo Kubernetes Secret YAML que contiene los datos de actualización de chart y lo guardar en el directorio base/secrets de la flota especificada por --fleet-path.

    El guion generate-chart-upgrade-data.sh también aplica modificaciones adicionales a la flota para garantizar que la carga de trabajo desplegada por la flota utilice correctamente los archivos Kubernetes Secret YAML generados.

    Importante
    Importante

    Los usuarios no deben cambiar nada de lo que genera el guion generate-chart-upgrade-data.sh.

Los pasos siguientes dependen del entorno en el que se esté ejecutando:

  1. En un entorno que admita GitOps (por ejemplo, que no esté aislado, o que esté aislado pero permita la asistencia de un servidor Git local):

    1. Copie la flota fleets/day2/eib-charts-upgrader en el repositorio que usará para GitOps.

      Nota
      Nota

      Asegúrese de que la flota incluye los cambios realizados por el guion generate-chart-upgrade-data.sh.

    2. Configure un recurso GitRepo que se usará para incluir todos los recursos de la flota eib-charts-upgrader.

      1. Para la configuración y el despliegue de GitRepo mediante la interfaz de usuario de Rancher, consulte Accessing Fleet in the Rancher UI (Acceso a Fleet en la interfaz de usuario de Rancher).

      2. Para la configuración y el despliegue manuales de GitRepo, consulte Creating a Deployment (Creación de un despliegue).

  2. En un entorno que no admita GitOps (por ejemplo, un entorno aislado que no permita el uso de un servidor Git local):

    1. Descargue el binario de fleet-cli de la página de versión de rancher/fleet (fleet-linux-amd64 para Linux). Los usuarios de Mac pueden usar una versión propia: fleet-cli.

    2. Diríjase a la flota eib-charts-upgrader:

      cd /foo/bar/fleet-examples/fleets/day2/eib-charts-upgrader
    3. Cree un archivo targets.yaml que indicará a Fleet dónde debe desplegar los recursos:

      cat > targets.yaml <<EOF
      targets:
      # To match all downstream clusters
      - clusterSelector: {}
      EOF

      Para obtener información sobre cómo asignar clústeres de destino, consulte la documentación original.

    4. Utilice fleet-cli para convertir la flota en un recurso Bundle:

      fleet apply --compress --targets-file=targets.yaml -n fleet-default -o - eib-charts-upgrade > bundle.yaml

      Esto creará un Bundle (bundle.yaml) que contendrá todos los recursos de plantilla de la flota eib-charts-upgrader.

      Para obtener más información sobre el comando fleet apply, consulte fleet apply.

      Para obtener más información sobre cómo convertir flotas en Bundles, consulte Convert a Helm Chart into a Bundle (Conversión de un chart de Helm en un Bundle).

    5. Despliegue el Bundle. Puede hacerlo de dos formas:

      1. Mediante la interfaz de usuario de Rancher: seleccione Continuous Delivery → Advanced → Bundles → Create from YAML (Entrega continua → Avanzado → Bundles → Crear desde YAML) y pegue el contenido de bundle.yaml o haga clic en la opción Read from File (Leer desde archivo) y pase el archivo.

      2. Manualmente: despliegue el archivo bundle.yaml manualmente dentro de su clúster de gestión.

Al ejecutar estos pasos, se desplegará correctamente el recurso GitRepo/Bundle. Fleet recogerá el recurso y su contenido se desplegará en los clústeres de destino que el usuario haya especificado en los pasos anteriores. Para obtener una descripción general del proceso, consulte la Sección 36.1.6.2.3.1, “Descripción general”.

Para obtener información sobre cómo realizar un seguimiento del proceso de actualización, consulte la Sección 36.1.6.2.3.3, “Ejemplo”.

Importante
Importante

Cuando haya verificado que el chart se ha actualizado correctamente, elimine el recurso Bundle/GitRepo.

Esto eliminará los recursos de actualización que ya no son necesarios de su clúster descendente, lo que garantizará que no se produzcan conflictos entre versiones en el futuro.

36.1.6.2.3.3 Ejemplo
Nota
Nota

El siguiente ejemplo muestra cómo actualizar un chart de Helm desplegado con EIB de una versión a otra en un clúster descendente. Tenga en cuenta que las versiones utilizadas en este ejemplo no son recomendaciones. Para obtener recomendaciones de versiones específicas para una versión de Edge, consulte las notas de la versión (Sección 52.1, “Resumen”).

Caso práctico:

  • Un clúster denominado doc-example ejecuta una versión anterior de Longhorn.

  • El clúster se ha desplegado mediante EIB, utilizando el siguiente fragmento de definición de imagen:

    kubernetes:
      helm:
        charts:
        - name: longhorn-crd
          repositoryName: rancher-charts
          targetNamespace: longhorn-system
          createNamespace: true
          version: 104.2.0+up1.7.1
          installationNamespace: kube-system
        - name: longhorn
          repositoryName: rancher-charts
          targetNamespace: longhorn-system
          createNamespace: true
          version: 104.2.0+up1.7.1
          installationNamespace: kube-system
        repositories:
        - name: rancher-charts
          url: https://charts.rancher.io/
    ...
  • SUSE Storage debe actualizarse a una versión compatible con la versión Edge 3.3.1. Esto significa que debe actualizarse a 106.2.0+up1.8.1.

  • Se sobrentiende que el clúster de gestión encargado de gestionar doc-example está aislado, sin asistencia para un servidor Git local y con una configuración de Rancher operativa.

Siga los pasos de actualización (Sección 36.1.6.2.3.2, “Pasos para la actualización”):

  1. Clone el repositorio suse-edge/fleet-example desde la etiqueta release-3.3.0.

    git clone -b release-3.3.0 https://github.com/suse-edge/fleet-examples.git
  2. Cree un directorio donde se almacenará el archivo de actualización de Longhorn.

    mkdir archives
  3. Extraiga la versión del archivo de chart de Longhorn deseada:

    # First add the Rancher Helm chart repository
    helm repo add rancher-charts https://charts.rancher.io/
    
    # Pull the Longhorn 1.8.1 CRD archive
    helm pull rancher-charts/longhorn-crd --version 106.2.0+up1.8.1
    
    # Pull the Longhorn 1.8.1 chart archive
    helm pull rancher-charts/longhorn --version 106.2.0+up1.8.1
  4. Fuera del directorio archives, descargue el guion generate-chart-upgrade-data.sh de la etiqueta de la versión suse-edge/fleet-examples.

  5. La configuración del directorio debería ser similar a:

    .
    ├── archives
    |   ├── longhorn-106.2.0+up1.8.1.tgz
    │   └── longhorn-crd-106.2.0+up1.8.1.tgz
    ├── fleet-examples
    ...
    │   ├── fleets
    │   │   ├── day2
    |   |   |   ├── ...
    │   │   │   ├── eib-charts-upgrader
    │   │   │   │   ├── base
    │   │   │   │   │   ├── job.yaml
    │   │   │   │   │   ├── kustomization.yaml
    │   │   │   │   │   ├── patches
    │   │   │   │   │   │   └── job-patch.yaml
    │   │   │   │   │   ├── rbac
    │   │   │   │   │   │   ├── cluster-role-binding.yaml
    │   │   │   │   │   │   ├── cluster-role.yaml
    │   │   │   │   │   │   ├── kustomization.yaml
    │   │   │   │   │   │   └── sa.yaml
    │   │   │   │   │   └── secrets
    │   │   │   │   │       ├── eib-charts-upgrader-script.yaml
    │   │   │   │   │       └── kustomization.yaml
    │   │   │   │   ├── fleet.yaml
    │   │   │   │   └── kustomization.yaml
    │   │   │   └── ...
    │   └── ...
    └── generate-chart-upgrade-data.sh
  6. Ejecute el guion generate-chart-upgrade-data.sh:

    # First make the script executable
    chmod +x ./generate-chart-upgrade-data.sh
    
    # Then execute the script
    ./generate-chart-upgrade-data.sh --archive-dir ./archives --fleet-path ./fleet-examples/fleets/day2/eib-charts-upgrader

    La estructura del directorio tras la ejecución del guion debería ser similar a esto:

    .
    ├── archives
    |   ├── longhorn-106.2.0+up1.8.1.tgz
    │   └── longhorn-crd-106.2.0+up1.8.1.tgz
    ├── fleet-examples
    ...
    │   ├── fleets
    │   │   ├── day2
    │   │   │   ├── ...
    │   │   │   ├── eib-charts-upgrader
    │   │   │   │   ├── base
    │   │   │   │   │   ├── job.yaml
    │   │   │   │   │   ├── kustomization.yaml
    │   │   │   │   │   ├── patches
    │   │   │   │   │   │   └── job-patch.yaml
    │   │   │   │   │   ├── rbac
    │   │   │   │   │   │   ├── cluster-role-binding.yaml
    │   │   │   │   │   │   ├── cluster-role.yaml
    │   │   │   │   │   │   ├── kustomization.yaml
    │   │   │   │   │   │   └── sa.yaml
    │   │   │   │   │   └── secrets
    │   │   │   │   │       ├── eib-charts-upgrader-script.yaml
    │   │   │   │   │       ├── kustomization.yaml
    │   │   │   │   │       ├── longhorn-VERSION.yaml - secret created by the generate-chart-upgrade-data.sh script
    │   │   │   │   │       └── longhorn-crd-VERSION.yaml - secret created by the generate-chart-upgrade-data.sh script
    │   │   │   │   ├── fleet.yaml
    │   │   │   │   └── kustomization.yaml
    │   │   │   └── ...
    │   └── ...
    └── generate-chart-upgrade-data.sh

    Los archivos modificados en Git deberían tener este aspecto:

    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
    	modified:   fleets/day2/eib-charts-upgrader/base/patches/job-patch.yaml
    	modified:   fleets/day2/eib-charts-upgrader/base/secrets/kustomization.yaml
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    	fleets/day2/eib-charts-upgrader/base/secrets/longhorn-VERSION.yaml
    	fleets/day2/eib-charts-upgrader/base/secrets/longhorn-crd-VERSION.yaml
  7. Cree un Bundle para la flota eib-charts-upgrader:

    1. En primer lugar, diríjase a la flota:

      cd ./fleet-examples/fleets/day2/eib-charts-upgrader
    2. A continuación, cree un archivo targets.yaml:

      cat > targets.yaml <<EOF
      targets:
      - clusterName: doc-example
      EOF
    3. Después, use el binario de fleet-cli para convertir la flota en un Bundle:

      fleet apply --compress --targets-file=targets.yaml -n fleet-default -o - eib-charts-upgrade > bundle.yaml
    4. Ahora, transfiera bundle.yaml a su equipo del clúster de gestión.

  8. Despliegue el Bundle mediante la interfaz de usuario de Rancher:

    ejemplo 1 de actualización del chart de helm de día 2
    Figura 36.1: Despliegue del Bundle mediante la interfaz de Rancher

    Ahora, seleccione Read from File (Leer desde archivo) y busque el archivo bundle.yaml en su sistema.

    El Bundle se rellenará automáticamente en la interfaz de usuario de Rancher.

    Seleccione Create (Crear).

  9. Cuando haya finalizado el despliegue correctamente, el Bundle deberá tener un aspecto similar al siguiente:

    ejemplo 2 de actualización de chart del helm de día 2
    Figura 36.2: Bundle desplegado correctamente

Cuando haya finalizado el despliegue del Bundle correctamente, para supervisar el proceso de actualización:

  1. Verifique los registros del pod de actualización:

    ejemplo 3 de actualización de chart de helm de día dos descendente
  2. Ahora, verifique los registros del pod creado para la actualización por helm-controller:

    1. El nombre del pod tendrá este formato: helm-install-longhorn-<sufijo aleatorio>

    2. El pod estará en el espacio de nombres donde se desplegó el recurso HelmChart. En nuestro caso, kube-system.

      ejemplo 4 de actualización de chart de helm de día dos descendente
      Figura 36.3: Registros de chart de Longhorn actualizado correctamente
  3. Compruebe que la versión de HelmChart se ha actualizado. Para ello, diríjase a la sección HelmCharts de Rancher seleccionando More Resources → HelmCharts (Más recursos → HelmCharts). Seleccione el espacio de nombres donde se desplegó el chart; en este ejemplo, sería kube-system.

  4. Por último, compruebe que los pods de Longhorn se estén ejecutando.

Después de realizar las validaciones anteriores, se puede entender con seguridad que el chart de Helm de Longhorn se ha actualizado a la versión 106.2.0+up1.8.1.

36.1.6.2.3.4 Actualización del chart de Helm con una herramienta GitOps de terceros

Puede darse el caso de que los usuarios deseen utilizar este procedimiento de actualización con un flujo de trabajo de GitOps que no sea Fleet (por ejemplo, Flux).

Para generar los recursos necesarios para el procedimiento de actualización, puede usar el guion generate-chart-upgrade-data.sh para rellenar la flota eib-charts-upgrader con los datos proporcionados por el usuario. Para obtener más información sobre cómo hacerlo, consulte la Sección 36.1.6.2.3.2, “Pasos para la actualización”.

Cuando haya completado la configuración, puede utilizar kustomize para generar una solución totalmente funcional que puede desplegar en su clúster:

cd /foo/bar/fleets/day2/eib-charts-upgrader

kustomize build .

Si desea incluir la solución en su flujo de trabajo de GitOps, puede eliminar el archivo fleet.yaml y usar lo que queda como una configuración válida de Kustomize. No olvide ejecutar primero el guion generate-chart-upgrade-data.sh, para poder rellenar la configuración de Kustomize con los datos de los charts de Helm a los que desea actualizar.

Para comprender cómo se pretende usar este flujo de trabajo, puede resultar útil consultar la Sección 36.1.6.2.3.1, “Descripción general” y la Sección 36.1.6.2.3.2, “Pasos para la actualización”.

Parte VII Documentación del producto

Aquí encontrará la documentación de SUSE Edge for Telco

  • 37 SUSE Edge for Telco
  • SUSE Edge for Telco (antes conocido como Adaptive Telco Infrastructure Platform/ATIP) es una plataforma de edge computing optimizada para las telecomunicaciones que permite a las empresas de ese sector innovar y acelerar la modernización de sus redes.

  • 38 Concepto y arquitectura
  • SUSE Edge for Telco es una plataforma diseñada para alojar aplicaciones de telecomunicaciones modernas y nativas de la nube a gran escala, desde el núcleo hasta la periferia.

  • 39 Requisitos y supuestos
  • Estos son los requisitos de hardware de SUSE Edge for Telco:

  • 40 Configuración del clúster de gestión
  • El clúster de gestión es la parte de SUSE Edge for Telco que se utiliza para gestionar el aprovisionamiento y el ciclo de vida de las pilas de entorno de ejecución. Desde un punto de vista técnico, el clúster de gestión contiene los siguientes componentes:

  • 41 Configuración de funciones de telecomunicaciones
  • Esta sección documenta y explica la configuración de las funciones específicas para telecomunicaciones en clústeres desplegados mediante SUSE Edge for Telco.

  • 42 Aprovisionamiento de red dirigida totalmente automatizado
  • El aprovisionamiento de red dirigida es una función que permite automatizar el aprovisionamiento de clústeres descendentes. Esta función resulta útil cuando hay muchos clústeres descendentes que aprovisionar y se desea automatizar el proceso.

  • 43 Acciones del ciclo de vida
  • Esta sección describe las acciones de gestión del ciclo de vida de los clústeres desplegados con SUSE Edge for Telco.

37 SUSE Edge for Telco

SUSE Edge for Telco (antes conocido como Adaptive Telco Infrastructure Platform/ATIP) es una plataforma de edge computing optimizada para las telecomunicaciones que permite a las empresas de ese sector innovar y acelerar la modernización de sus redes.

SUSE Edge for Telco es una pila completa de nube para telecomunicaciones diseñada para alojar CNF (construcciones de nube) como 5G Packet Core y Cloud RAN.

  • Automatiza la distribución sin intervención y la gestión del ciclo de vida de configuraciones complejas de pilas periféricas dirigidas a las telecomunicaciones.

  • Garantiza continuamente la calidad del hardware para telecomunicaciones, utilizando configuraciones y cargas de trabajo específicas para el sector.

  • Sus componentes están específicamente diseñados para usarse en edge computing, lo que ocupan menos espacio y ofrecen un mayor rendimiento por vatio.

  • Mantiene una estrategia de plataforma flexible con API independientes del proveedor y 100 % de código abierto.

38 Concepto y arquitectura

SUSE Edge for Telco es una plataforma diseñada para alojar aplicaciones de telecomunicaciones modernas y nativas de la nube a gran escala, desde el núcleo hasta la periferia.

Esta página explica la arquitectura y los componentes usados en SUSE Edge for Telco.

38.1 Arquitectura de SUSE Edge for Telco

El siguiente diagrama muestra la arquitectura general de SUSE Edge for Telco:

arquitectura de producto atip 1

38.2 Componentes

Hay dos bloques diferentes: la pila de gestión y la pila de entorno de ejecución:

  • Pila de gestión: es la parte de SUSE Edge for Telco que se emplea para gestionar el aprovisionamiento y el ciclo de vida de las pilas de entornos de ejecución. Incluye los siguientes componentes:

    • Gestión de múltiples clústeres en entornos de nube pública y privada con Rancher (Capítulo 5, Rancher)

    • Asistencia bare metal con proveedores de infraestructura Metal3 (Capítulo 10, Metal3), MetalLB (Capítulo 19, MetalLB) y CAPI (Cluster API)

    • Aislamiento completo de inquilinos e integraciones IDP (proveedor de identidad)

    • Gran mercado de integraciones y extensiones de terceros

    • API independiente del proveedor y un rico ecosistema de proveedores

    • Control de las actualizaciones transaccionales de SUSE Linux Micro

    • Motor GitOps para gestionar el ciclo de vida de los clústeres mediante repositorios Git con Fleet (Capítulo 8, Fleet)

  • Pila de entorno de ejecución: es la parte de SUSE Edge for Telco que se emplea para ejecutar las cargas de trabajo.

    • Kubernetes con distribuciones seguras y ligeras como K3s (Capítulo 15, K3s) y RKE2 (Capítulo 16, RKE2) (RKE2 está reforzado, certificado y optimizado para su uso gubernamental y en sectores regulados).

    • SUSE Security (Capítulo 18, SUSE Security) para habilitar funciones de seguridad como el análisis de vulnerabilidades de imágenes, la inspección profunda de paquetes y el control automático del tráfico dentro del clúster.

    • Almacenamiento en bloques con SUSE Storage (Capítulo 17, SUSE Storage) para permitir una forma sencilla y fácil de utilizar una solución de almacenamiento nativa en la nube.

    • Sistema operativo optimizado con SUSE Linux Micro (Capítulo 9, SUSE Linux Micro) para habilitar un sistema operativo seguro, ligero e inmutable (sistema de archivos transaccional) para ejecutar contenedores. SUSE Linux Micro está disponible en arquitecturas AArch64 y AMD64/Intel 64, y también es compatible con un kernel en tiempo real para casos prácticos de telecomunicaciones y periféricos.

38.3 Ejemplo de flujos de despliegue

A continuación se muestran ejemplos generales de flujos de trabajo para comprender la relación entre los componentes de gestión y los componentes de entorno de ejecución.

El aprovisionamiento de red dirigida es el flujo de trabajo que permite el despliegue de un nuevo clúster descendente con todos los componentes preconfigurados y listos para ejecutar cargas de trabajo sin intervención manual.

38.3.1 Ejemplo 1: despliegue de un nuevo clúster de gestión con todos los componentes instalados

Use Edge Image Builder (Capítulo 11, Edge Image Builder) para crear una imagen ISO nueva con la pila de gestión incluida. A continuación, puede utilizar esta imagen ISO para instalar un clúster de gestión nuevo en máquinas virtuales o en hardware físico.

arquitectura de producto atip 2
Nota
Nota

Para obtener más información sobre cómo desplegar un nuevo clúster de gestión, consulte el capítulo sobre el clúster de gestión de SUSE Edge for Telco (Capítulo 40, Configuración del clúster de gestión).

Nota
Nota

Para obtener más información sobre cómo usar Edge Image Builder, consulte el capítulo sobre Edge Image Builder (Capítulo 3, Clústeres independientes con Edge Image Builder).

38.3.2 Ejemplo 2: despliegue de un clúster descendente de un solo nodo con perfiles de telecomunicaciones para permitir la ejecución de cargas de trabajo de telecomunicaciones

Cuando tengamos el clúster de gestión instalado y en funcionamiento, podremos utilizarlo para desplegar un clúster descendente de un solo nodo con todas las capacidades de telecomunicaciones habilitadas y configuradas mediante el flujo de trabajo de aprovisionamiento de red dirigida.

El siguiente diagrama muestra el flujo de trabajo general para desplegarlo:

arquitectura de producto atip 3
Nota
Nota

Para obtener más información sobre cómo desplegar un clúster descendente, consulte el capítulo sobre aprovisionamiento automatizado de SUSE Edge for Telco (Capítulo 42, Aprovisionamiento de red dirigida totalmente automatizado).

Nota
Nota

Para obtener más información sobre las funciones de telecomunicaciones, consulte el capítulo sobre funciones de telecomunicaciones de SUSE Edge for Telco (Capítulo 41, Configuración de funciones de telecomunicaciones).

38.3.3 Ejemplo 3: despliegue de un clúster descendente de alta disponibilidad con MetalLB como equilibrador de carga

Cuando tengamos el clúster de gestión instalado y en funcionamiento, podremos utilizarlo para desplegar un clúster descendente de alta disponibilidad con MetalLB como equilibrador de carga mediante el flujo de trabajo de aprovisionamiento de red dirigida.

El siguiente diagrama muestra el flujo de trabajo general para desplegarlo:

arquitectura de producto atip 4
Nota
Nota

Para obtener más información sobre cómo desplegar un clúster descendente, consulte el capítulo sobre aprovisionamiento automatizado de SUSE Edge for Telco (Capítulo 42, Aprovisionamiento de red dirigida totalmente automatizado).

Nota
Nota

Para obtener más información sobre MetalLB, consulte el Capítulo 19, MetalLB.

39 Requisitos y supuestos

39.1 Hardware

Estos son los requisitos de hardware de SUSE Edge for Telco:

  • Clúster de gestión: el clúster de gestión tiene componentes como SUSE Linux Micro, RKE2, SUSE Rancher Prime y Metal3, y se utiliza para gestionar varios clústeres descendentes. Dependiendo del número de clústeres descendentes que se vayan a gestionar, los requisitos de hardware para el servidor pueden variar.

    • Los requisitos mínimos para el servidor (MV o bare metal) son:

      • RAM: 8 GB como mínimo (se recomiendan al menos 16 GB)

      • CPU: 2 como mínimo (se recomiendan al menos 4 CPU)

  • Clústeres descendentes: los clústeres descendentes son los clústeres desplegados para ejecutar cargas de trabajo de telecomunicaciones. Hay requisitos específicos para habilitar ciertas capacidades de telecomunicaciones como SR-IOV, Optimización del rendimiento de la CPU, etc.

    • SR-IOV: para adjuntar funciones virtuales (VF) en modo de encaminamiento a varias CNF/VNF, la tarjeta de interfaz de red debe admitir SR-IOV y VT-d/AMD-Vi debe estar habilitado en el BIOS.

    • Procesadores CPU: para ejecutar cargas de trabajo específicas de telecomunicaciones, el modelo de procesador CPU debe adaptarse para permitir la mayoría de las funciones disponibles en esta tabla de referencia (Capítulo 41, Configuración de funciones de telecomunicaciones).

    • Requisitos de firmware para la instalación con medios virtuales:

Hardware del servidor

Modelo de BMC

Gestión

Hardware Dell

15.ª generación

iDRAC9

Hardware Supermicro

01.00.25

Supermicro SMC - Redfish

Hardware HPE

1.50

iLO6

39.2 Red

Como referencia para la arquitectura de red, el siguiente diagrama muestra una arquitectura de red típica para un entorno de telecomunicaciones:

requisitos de producto atip 1

La arquitectura de red se basa en los siguientes componentes:

  • Red de gestión: esta red se usa para la gestión de los nodos del clúster descendentes. Se utiliza para la gestión fuera de banda. Por lo general, esta red también está conectada a un conmutador de gestión independiente, pero puede conectarse al mismo conmutador de servicio mediante VLAN para aislar el tráfico.

  • Red de plano de control: esta red se usa para la comunicación entre los nodos del clúster descendente y los servicios que se ejecutan en ellos. Esta red también se utiliza para la comunicación entre los nodos y los servicios externos, como los servidores DHCP o DNS. En algunos casos, para entornos conectados, el conmutador/enrutador puede gestionar el tráfico a través de Internet.

  • Otras redes: en algunos casos, los nodos podrían conectarse a otras redes con fines específicos.

Nota
Nota

Para utilizar el flujo de trabajo de aprovisionamiento de red dirigida, el clúster de gestión debe tener conectividad de red con el controlador de gestión de la placa base (BMC) del servidor del clúster descendente, de modo que se puedan automatizar la preparación y el aprovisionamiento del host.

39.3 Servicios (DHCP, DNS, etc.)

Algunos servicios externos como DHCP, DNS, etc. podrían ser necesarios dependiendo del tipo de entorno en el que se desplieguen:

  • Entorno conectado: en este caso, los nodos estarán conectados a Internet (a través de protocolos de enrutamiento L3) y el cliente proporcionará los servicios externos.

  • Entorno desconectado/aislado: en este caso, los nodos no tendrán conectividad IP a Internet y se necesitarán servicios adicionales para duplicar localmente el contenido requerido por el flujo de trabajo de aprovisionamiento de red dirigida.

  • Servidor de archivos: se utiliza para almacenar las imágenes del sistema operativo que se aprovisionarán en los nodos del clúster descendente durante el flujo de trabajo de aprovisionamiento de red dirigida. El chart de Helm de Metal3 puede desplegar un servidor multimedia para almacenar las imágenes del sistema operativo, consulte la siguiente sección (Nota), pero también es posible utilizar un servidor Web local existente.

39.4 Inhabilitación de servicios systemd

Para las cargas de trabajo de telecomunicaciones, es importante inhabilitar o configurar adecuadamente algunos de los servicios que se ejecutan en los nodos para evitar cualquier impacto en el rendimiento de la carga de trabajo que se ejecuta en los nodos (latencia).

  • rebootmgr es un servicio que permite configurar una estrategia de rearranque cuando el sistema tenga actualizaciones pendientes. Para las cargas de trabajo de telecomunicaciones, es muy importante inhabilitar o configurar correctamente el servicio rebootmgr para evitar el rearranque de los nodos en caso de actualizaciones programadas por el sistema, con el fin de evitar cualquier impacto en los servicios que se ejecutan en los nodos.

Nota
Nota

Para obtener más información sobre rebootmgr, consulte el repositorio GitHub de rebootmgr.

Verifique la estrategia que se está utilizando ejecutando:

cat /etc/rebootmgr.conf
[rebootmgr]
window-start=03:30
window-duration=1h30m
strategy=best-effort
lock-group=default

Puede inhabilitarla ejecutando:

sed -i 's/strategy=best-effort/strategy=off/g' /etc/rebootmgr.conf

O con el comando rebootmgrctl:

rebootmgrctl strategy off
Nota
Nota

Esta configuración para establecer la estrategia de rebootmgr se puede automatizar mediante el flujo de trabajo de aprovisionamiento de red dirigida. Para obtener más información, consulte el capítulo correspondiente (Capítulo 42, Aprovisionamiento de red dirigida totalmente automatizado).

  • transactional-update es un servicio que permite actualizaciones automáticas controladas por el sistema. Para las cargas de trabajo de telecomunicaciones, es importante inhabilitar las actualizaciones automáticas para evitar cualquier impacto en los servicios que se ejecutan en los nodos.

Para inhabilitar las actualizaciones automáticas, puede ejecutar:

systemctl --now disable transactional-update.timer
systemctl --now disable transactional-update-cleanup.timer
  • fstrim es un servicio que permite recortar los sistemas de archivos automáticamente cada semana. Para las cargas de trabajo de telecomunicaciones, es importante inhabilitar el recorte automático para evitar cualquier impacto en los servicios que se ejecutan en los nodos.

Para inhabilitar el recorte automático, puede ejecutar:

systemctl --now disable fstrim.timer

40 Configuración del clúster de gestión

40.1 Introducción

El clúster de gestión es la parte de SUSE Edge for Telco que se utiliza para gestionar el aprovisionamiento y el ciclo de vida de las pilas de entorno de ejecución. Desde un punto de vista técnico, el clúster de gestión contiene los siguientes componentes:

  • SUSE Linux Micro como sistema operativo. Dependiendo del caso práctico, será posible personalizar algunas configuraciones como la red, el almacenamiento, los usuarios y los argumentos del kernel.

  • RKE2 como clúster de Kubernetes. Dependiendo del caso práctico, se puede configurar para utilizar complementos de CNI específicos, como Multus, Cilium, Calico, etc.

  • Rancher como plataforma de gestión del ciclo de vida de los clústeres.

  • Metal3 como componente para gestionar el ciclo de vida de los nodos bare metal.

  • CAPI como componente para gestionar el ciclo de vida de los clústeres de Kubernetes (clústeres descendentes). El proveedor CAPI de RKE2 se utiliza para gestionar el ciclo de vida de los clústeres RKE2.

Con todos los componentes mencionados, el clúster de gestión puede gestionar el ciclo de vida de los clústeres descendentes usando un enfoque declarativo para gestionar la infraestructura y las aplicaciones.

Nota
Nota

Para obtener más información sobre SUSE Linux Micro, consulte: SUSE Linux Micro (Capítulo 9, SUSE Linux Micro)

Para obtener más información sobre RKE2, consulte: RKE2 (Capítulo 16, RKE2)

Para obtener más información sobre Rancher, consulte: Rancher (Capítulo 5, Rancher)

Para obtener más información sobre Metal3, consulte: Metal3 (Capítulo 10, Metal3)

40.2 Pasos para configurar el clúster de gestión

Los siguientes pasos son necesarios para configurar el clúster de gestión (usando un único nodo):

clúster gestión de producto atip 1

Estos son los pasos principales para configurar el clúster de gestión usando un enfoque declarativo:

  1. Preparación de imágenes para entornos conectados (Sección 40.3, “Preparación de la imagen para entornos conectados”). El primer paso es preparar los manifiestos y los archivos con todas las configuraciones necesarias para su uso en entornos conectados.

    • Estructura de directorios para entornos conectados (Sección 40.3.1, “Estructura del directorio”). Este paso crea una estructura de directorios que Edge Image Builder utilizará para almacenar los archivos de configuración y la propia imagen.

    • Archivo de definición del clúster de gestión (Sección 40.3.2, “Archivo de definición del clúster de gestión”). El archivo mgmt-cluster.yaml es el archivo de definición principal del clúster de gestión. Contiene la siguiente información sobre la imagen que se va a crear:

      • Información de la imagen: la información relacionada con la imagen que se creará utilizando la imagen base.

      • Sistema operativo: las configuraciones del sistema operativo que se utilizarán en la imagen.

      • Kubernetes: los charts de Helm y los repositorios, la versión de Kubernetes, la configuración de red y los nodos que se utilizarán en el clúster.

    • Carpeta personalizada (Sección 40.3.3, “Carpeta custom”). La carpeta custom contiene los archivos de configuración y los guiones que utilizará Edge Image Builder para desplegar un clúster de gestión totalmente funcional.

      • Archivos: contiene los archivos de configuración que utilizará el clúster de gestión.

      • Guiones: contiene los guiones que utilizará el clúster de gestión.

    • Carpeta de Kubernetes (Sección 40.3.4, “Carpeta kubernetes”). La carpeta kubernetes contiene los archivos de configuración que utilizará el clúster de gestión.

      • Manifiestos: contiene los manifiestos que utilizará el clúster de gestión.

      • Helm: contiene los archivos de valores de Helm que utilizará el clúster de gestión.

      • Config: contiene los archivos de configuración que utilizará el clúster de gestión.

    • Carpeta de red (Sección 40.3.5, “Carpeta network”). La carpeta network contiene los archivos de configuración de red que utilizarán los nodos del clúster de gestión.

  2. Preparación de imágenes para entornos aislados (Sección 40.4, “Preparación de la imagen para entornos aislados”). El paso consiste en mostrar las diferencias para preparar los manifiestos y los archivos que se utilizarán en un entorno aislado.

  3. Creación de la imagen (Sección 40.5, “Creación de la imagen”). Este paso abarca la creación de la imagen mediante la herramienta Edge Image Builder (tanto para escenarios conectados como en entornos aislados). Compruebe los requisitos previos (Capítulo 11, Edge Image Builder) para ejecutar la herramienta Edge Image Builder en su sistema.

  4. Aprovisionamiento del clúster de gestión (Sección 40.6, “Aprovisionamiento del clúster de gestión”). Este paso abarca el aprovisionamiento del clúster de gestión que usa la imagen creada en el paso anterior (tanto para entornos conectados como aislados). Este paso se puede realizar con un ordenador portátil, un servidor, una máquina virtual o cualquier otro sistema AMD64/Intel 64 con un puerto USB.

Nota
Nota

Para obtener más información, consulte la sección sobre Edge Image Builder (Capítulo 11, Edge Image Builder) y la guía de inicio rápido de Edge Image Builder (Capítulo 3, Clústeres independientes con Edge Image Builder).

40.3 Preparación de la imagen para entornos conectados

Edge Image Builder se utiliza para crear la imagen del clúster de gestión. En este documento se describe la configuración mínima necesaria para configurar el clúster de gestión.

Edge Image Builder se ejecuta dentro de un contenedor, por lo que se requiere un entorno de ejecución de contenedores como Podman o Rancher Desktop. En esta guía, se entiende que Podman está disponible.

Además, como requisito previo para desplegar un clúster de gestión de alta disponibilidad, es necesario reservar tres direcciones IP en la red:

  • apiVIP para la dirección IP virtual de API (utilizada para acceder al servidor API de Kubernetes).

  • ingressVIP para la dirección IP virtual de Ingress (utilizada, por ejemplo, por la interfaz de usuario de Rancher).

  • metal3VIP para la dirección IP virtual de Metal3.

40.3.1 Estructura del directorio

Al ejecutar EIB, se monta un directorio desde el host, por lo que lo primero que hay que hacer es crear una estructura de directorios que EIB utilizará para almacenar los archivos de configuración y la propia imagen. Este directorio tiene la siguiente estructura:

eib
├── mgmt-cluster.yaml
├── network
│ └── mgmt-cluster-node1.yaml
├── kubernetes
│ ├── manifests
│ │ ├── rke2-ingress-config.yaml
│ │ ├── neuvector-namespace.yaml
│ │ ├── ingress-l2-adv.yaml
│ │ └── ingress-ippool.yaml
│ ├── helm
│ │ └── values
│ │     ├── rancher.yaml
│ │     ├── neuvector.yaml
│ │     ├── metal3.yaml
│ │     └── certmanager.yaml
│ └── config
│     └── server.yaml
├── custom
│ ├── scripts
│ │ ├── 99-register.sh
│ │ ├── 99-mgmt-setup.sh
│ │ └── 99-alias.sh
│ └── files
│     ├── rancher.sh
│     ├── mgmt-stack-setup.service
│     ├── metal3.sh
│     └── basic-setup.sh
└── base-images
Nota
Nota

La imagen SL-Micro.x86_64-6.1-Base-SelfInstall-GM.install.iso debe descargarse desde el Centro de servicios al cliente de SUSE o desde la página de descargas de SUSE, y debe estar ubicada en la carpeta base-images.

Debe comprobar la suma de comprobación SHA256 de la imagen para asegurarse de que no ha sido manipulada. La suma de comprobación se encuentra en la misma ubicación en la que se descargó la imagen.

Un ejemplo de estructura del directorios se puede encontrar en el repositorio GitHub de SUSE Edge, en la carpeta "telco-examples".

40.3.2 Archivo de definición del clúster de gestión

El archivo de definición principal del clúster de gestión es mgmt-cluster.yaml. Contiene la siguiente información:

apiVersion: 1.2
image:
  imageType: iso
  arch: x86_64
  baseImage: SL-Micro.x86_64-6.1-Base-SelfInstall-GM.install.iso
  outputImageName: eib-mgmt-cluster-image.iso
operatingSystem:
  isoConfiguration:
    installDevice: /dev/sda
  users:
  - username: root
    encryptedPassword: $ROOT_PASSWORD
  packages:
    packageList:
    - git
    - jq
    sccRegistrationCode: $SCC_REGISTRATION_CODE
kubernetes:
  version: v1.32.4+rke2r1
  helm:
    charts:
      - name: cert-manager
        repositoryName: jetstack
        version: 1.15.3
        targetNamespace: cert-manager
        valuesFile: certmanager.yaml
        createNamespace: true
        installationNamespace: kube-system
      - name: longhorn-crd
        version: 106.2.0+up1.8.1
        repositoryName: rancher-charts
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
      - name: longhorn
        version: 106.2.0+up1.8.1
        repositoryName: rancher-charts
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
      - name: metal3
        version: 303.0.7+up0.11.5
        repositoryName: suse-edge-charts
        targetNamespace: metal3-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: metal3.yaml
      - name: rancher-turtles
        version: 303.0.4+up0.20.0
        repositoryName: suse-edge-charts
        targetNamespace: rancher-turtles-system
        createNamespace: true
        installationNamespace: kube-system
      - name: neuvector-crd
        version: 106.0.1+up2.8.6
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: neuvector
        version: 106.0.1+up2.8.6
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: rancher
        version: 2.11.2
        repositoryName: rancher-prime
        targetNamespace: cattle-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: rancher.yaml
    repositories:
      - name: jetstack
        url: https://charts.jetstack.io
      - name: rancher-charts
        url: https://charts.rancher.io/
      - name: suse-edge-charts
        url: oci://registry.suse.com/edge/charts
      - name: rancher-prime
        url: https://charts.rancher.com/server-charts/prime
  network:
    apiHost: $API_HOST
    apiVIP: $API_VIP
  nodes:
    - hostname: mgmt-cluster-node1
      initializer: true
      type: server
#   - hostname: mgmt-cluster-node2
#     type: server
#   - hostname: mgmt-cluster-node3
#     type: server

Para explicar los campos y valores del archivo de definición mgmt-cluster.yaml, lo hemos dividido en las siguientes secciones.

  • Sección de imagen (archivo de definición):

image:
  imageType: iso
  arch: x86_64
  baseImage: SL-Micro.x86_64-6.1-Base-SelfInstall-GM.install.iso
  outputImageName: eib-mgmt-cluster-image.iso

Donde baseImage es la imagen original que descargó del Centro de servicios al cliente de SUSE o de la página de descargas de SUSE. outputImageName es el nombre de la nueva imagen que se utilizará para aprovisionar el clúster de gestión.

  • Sección de sistema operativo (archivo de definición):

operatingSystem:
  isoConfiguration:
    installDevice: /dev/sda
  users:
  - username: root
    encryptedPassword: $ROOT_PASSWORD
  packages:
    packageList:
    - jq
    sccRegistrationCode: $SCC_REGISTRATION_CODE

Donde installDevice es el dispositivo que se utilizará para instalar el sistema operativo, username y encryptedPassword son las credenciales que se utilizarán para acceder al sistema, packageList es la lista de paquetes que se instalarán (jq es necesario internamente durante el proceso de instalación), y sccRegistrationCode es el código de registro utilizado para obtener los paquetes y las dependencias en el momento de la creación, que se pueden obtener en el Centro de servicios al cliente de SUSE. La contraseña cifrada se puede generar utilizando el comando openssl de la siguiente manera:

openssl passwd -6 MyPassword!123

El resultado es algo similar a esto:

$6$UrXB1sAGs46DOiSq$HSwi9GFJLCorm0J53nF2Sq8YEoyINhHcObHzX2R8h13mswUIsMwzx4eUzn/rRx0QPV4JIb0eWCoNrxGiKH4R31
  • Sección de Kubernetes (archivo de definición):

kubernetes:
  version: v1.32.4+rke2r1
  helm:
    charts:
      - name: cert-manager
        repositoryName: jetstack
        version: 1.15.3
        targetNamespace: cert-manager
        valuesFile: certmanager.yaml
        createNamespace: true
        installationNamespace: kube-system
      - name: longhorn-crd
        version: 106.2.0+up1.8.1
        repositoryName: rancher-charts
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
      - name: longhorn
        version: 106.2.0+up1.8.1
        repositoryName: rancher-charts
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
      - name: metal3
        version: 303.0.7+up0.11.5
        repositoryName: suse-edge-charts
        targetNamespace: metal3-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: metal3.yaml
      - name: rancher-turtles
        version: 303.0.4+up0.20.0
        repositoryName: suse-edge-charts
        targetNamespace: rancher-turtles-system
        createNamespace: true
        installationNamespace: kube-system
      - name: neuvector-crd
        version: 106.0.1+up2.8.6
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: neuvector
        version: 106.0.1+up2.8.6
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: rancher
        version: 2.11.2
        repositoryName: rancher-prime
        targetNamespace: cattle-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: rancher.yaml
    repositories:
      - name: jetstack
        url: https://charts.jetstack.io
      - name: rancher-charts
        url: https://charts.rancher.io/
      - name: suse-edge-charts
        url: oci://registry.suse.com/edge/charts
      - name: rancher-prime
        url: https://charts.rancher.com/server-charts/prime
    network:
      apiHost: $API_HOST
      apiVIP: $API_VIP
    nodes:
    - hostname: mgmt-cluster-node1
      initializer: true
      type: server
#   - hostname: mgmt-cluster-node2
#     type: server
#   - hostname: mgmt-cluster-node3
#     type: server

La sección helm contiene la lista de charts de Helm que se instalarán, los repositorios que se utilizarán y la configuración de la versión de todos ellos.

La sección network contiene la configuración de la red, como apiHost y apiVIP, que utilizará el componente RKE2. apiVIP debe ser una dirección IP que no se use en la red y no debe formar parte del pool DHCP (en caso de que se utilice DHCP). Además, si se usa apiVIP en un clúster de varios nodos, se hace para acceder al servidor de API de Kubernetes. apiHost es la resolución de nombres para apiVIP que utilizará el componente RKE2.

La sección nodes contiene la lista de nodos que se utilizarán en el clúster. En este ejemplo, se utiliza un clúster de un solo nodo, pero se puede ampliar a un clúster de varios nodos añadiendo más nodos a la lista (descomentando las líneas).

Nota
Nota
  • Los nombres de los nodos deben ser únicos en el clúster.

  • Si lo desea, puede usar el campo initializer para especificar el host de arranque. Si no lo hace, será el primer nodo de la lista.

  • Si se requiere una configuración de red, los nombres de los nodos deben ser los mismos que los nombres de host definidos en la carpeta network (Sección 40.3.5, “Carpeta network”).

40.3.3 Carpeta custom

La carpeta custom contiene las siguientes subcarpetas:

...
├── custom
│ ├── scripts
│ │ ├── 99-register.sh
│ │ ├── 99-mgmt-setup.sh
│ │ └── 99-alias.sh
│ └── files
│     ├── rancher.sh
│     ├── mgmt-stack-setup.service
│     ├── metal3.sh
│     └── basic-setup.sh
...
  • La carpeta custom/files contiene los archivos de configuración que utilizará el clúster de gestión.

  • La carpeta custom/scripts contiene los guiones que utilizará el clúster de gestión.

La carpeta custom/files contiene los siguientes archivos:

  • basic-setup.sh: contiene los parámetros de configuración para Metal3, Rancher y MetalLB. Solo debe modificar este archivo si desea cambiar los espacios de nombres que se van a utilizar.

    #!/bin/bash
    # Pre-requisites. Cluster already running
    export KUBECTL="/var/lib/rancher/rke2/bin/kubectl"
    export KUBECONFIG="/etc/rancher/rke2/rke2.yaml"
    
    ##################
    # METAL3 DETAILS #
    ##################
    export METAL3_CHART_TARGETNAMESPACE="metal3-system"
    
    ###########
    # METALLB #
    ###########
    export METALLBNAMESPACE="metallb-system"
    
    ###########
    # RANCHER #
    ###########
    export RANCHER_CHART_TARGETNAMESPACE="cattle-system"
    export RANCHER_FINALPASSWORD="adminadminadmin"
    
    die(){
      echo ${1} 1>&2
      exit ${2}
    }
  • metal3.sh: contiene la configuración del componente Metal3 que se va a utilizar (no es necesario modificarlo). En futuras versiones, este guion se sustituirá por Rancher Turtles para facilitar su uso.

    #!/bin/bash
    set -euo pipefail
    
    BASEDIR="$(dirname "$0")"
    source ${BASEDIR}/basic-setup.sh
    
    METAL3LOCKNAMESPACE="default"
    METAL3LOCKCMNAME="metal3-lock"
    
    trap 'catch $? $LINENO' EXIT
    
    catch() {
      if [ "$1" != "0" ]; then
        echo "Error $1 occurred on $2"
        ${KUBECTL} delete configmap ${METAL3LOCKCMNAME} -n ${METAL3LOCKNAMESPACE}
      fi
    }
    
    # Get or create the lock to run all those steps just in a single node
    # As the first node is created WAY before the others, this should be enough
    # TODO: Investigate if leases is better
    if [ $(${KUBECTL} get cm -n ${METAL3LOCKNAMESPACE} ${METAL3LOCKCMNAME} -o name | wc -l) -lt 1 ]; then
      ${KUBECTL} create configmap ${METAL3LOCKCMNAME} -n ${METAL3LOCKNAMESPACE} --from-literal foo=bar
    else
      exit 0
    fi
    
    # Wait for metal3
    while ! ${KUBECTL} wait --for condition=ready -n ${METAL3_CHART_TARGETNAMESPACE} $(${KUBECTL} get pods -n ${METAL3_CHART_TARGETNAMESPACE} -l app.kubernetes.io/name=metal3-ironic -o name) --timeout=10s; do sleep 2 ; done
    
    # Get the ironic IP
    IRONICIP=$(${KUBECTL} get cm -n ${METAL3_CHART_TARGETNAMESPACE} ironic-bmo -o jsonpath='{.data.IRONIC_IP}')
    
    # If LoadBalancer, use metallb, else it is NodePort
    if [ $(${KUBECTL} get svc -n ${METAL3_CHART_TARGETNAMESPACE} metal3-metal3-ironic -o jsonpath='{.spec.type}') == "LoadBalancer" ]; then
      # Wait for metallb
      while ! ${KUBECTL} wait --for condition=ready -n ${METALLBNAMESPACE} $(${KUBECTL} get pods -n ${METALLBNAMESPACE} -l app.kubernetes.io/component=controller -o name) --timeout=10s; do sleep 2 ; done
    
      # Do not create the ippool if already created
      ${KUBECTL} get ipaddresspool -n ${METALLBNAMESPACE} ironic-ip-pool -o name || cat <<-EOF | ${KUBECTL} apply -f -
      apiVersion: metallb.io/v1beta1
      kind: IPAddressPool
      metadata:
        name: ironic-ip-pool
        namespace: ${METALLBNAMESPACE}
      spec:
        addresses:
        - ${IRONICIP}/32
        serviceAllocation:
          priority: 100
          serviceSelectors:
          - matchExpressions:
            - {key: app.kubernetes.io/name, operator: In, values: [metal3-ironic]}
    	EOF
    
      # Same for L2 Advs
      ${KUBECTL} get L2Advertisement -n ${METALLBNAMESPACE} ironic-ip-pool-l2-adv -o name || cat <<-EOF | ${KUBECTL} apply -f -
      apiVersion: metallb.io/v1beta1
      kind: L2Advertisement
      metadata:
        name: ironic-ip-pool-l2-adv
        namespace: ${METALLBNAMESPACE}
      spec:
        ipAddressPools:
        - ironic-ip-pool
    	EOF
    fi
    
    # If rancher is deployed
    if [ $(${KUBECTL} get pods -n ${RANCHER_CHART_TARGETNAMESPACE} -l app=rancher -o name | wc -l) -ge 1 ]; then
      cat <<-EOF | ${KUBECTL} apply -f -
    	apiVersion: management.cattle.io/v3
    	kind: Feature
    	metadata:
    	  name: embedded-cluster-api
    	spec:
    	  value: false
    	EOF
    
      # Disable Rancher webhooks for CAPI
      ${KUBECTL} delete --ignore-not-found=true mutatingwebhookconfiguration.admissionregistration.k8s.io mutating-webhook-configuration
      ${KUBECTL} delete --ignore-not-found=true validatingwebhookconfigurations.admissionregistration.k8s.io validating-webhook-configuration
      ${KUBECTL} wait --for=delete namespace/cattle-provisioning-capi-system --timeout=300s
    fi
    
    # Clean up the lock cm
    
    ${KUBECTL} delete configmap ${METAL3LOCKCMNAME} -n ${METAL3LOCKNAMESPACE}
    • rancher.sh: contiene la configuración del componente Rancher que se va a utilizar (no es necesario modificarlo).

      #!/bin/bash
      set -euo pipefail
      
      BASEDIR="$(dirname "$0")"
      source ${BASEDIR}/basic-setup.sh
      
      RANCHERLOCKNAMESPACE="default"
      RANCHERLOCKCMNAME="rancher-lock"
      
      if [ -z "${RANCHER_FINALPASSWORD}" ]; then
        # If there is no final password, then finish the setup right away
        exit 0
      fi
      
      trap 'catch $? $LINENO' EXIT
      
      catch() {
        if [ "$1" != "0" ]; then
          echo "Error $1 occurred on $2"
          ${KUBECTL} delete configmap ${RANCHERLOCKCMNAME} -n ${RANCHERLOCKNAMESPACE}
        fi
      }
      
      # Get or create the lock to run all those steps just in a single node
      # As the first node is created WAY before the others, this should be enough
      # TODO: Investigate if leases is better
      if [ $(${KUBECTL} get cm -n ${RANCHERLOCKNAMESPACE} ${RANCHERLOCKCMNAME} -o name | wc -l) -lt 1 ]; then
        ${KUBECTL} create configmap ${RANCHERLOCKCMNAME} -n ${RANCHERLOCKNAMESPACE} --from-literal foo=bar
      else
        exit 0
      fi
      
      # Wait for rancher to be deployed
      while ! ${KUBECTL} wait --for condition=ready -n ${RANCHER_CHART_TARGETNAMESPACE} $(${KUBECTL} get pods -n ${RANCHER_CHART_TARGETNAMESPACE} -l app=rancher -o name) --timeout=10s; do sleep 2 ; done
      until ${KUBECTL} get ingress -n ${RANCHER_CHART_TARGETNAMESPACE} rancher > /dev/null 2>&1; do sleep 10; done
      
      RANCHERBOOTSTRAPPASSWORD=$(${KUBECTL} get secret -n ${RANCHER_CHART_TARGETNAMESPACE} bootstrap-secret -o jsonpath='{.data.bootstrapPassword}' | base64 -d)
      RANCHERHOSTNAME=$(${KUBECTL} get ingress -n ${RANCHER_CHART_TARGETNAMESPACE} rancher -o jsonpath='{.spec.rules[0].host}')
      
      # Skip the whole process if things have been set already
      if [ -z $(${KUBECTL} get settings.management.cattle.io first-login -ojsonpath='{.value}') ]; then
        # Add the protocol
        RANCHERHOSTNAME="https://${RANCHERHOSTNAME}"
        TOKEN=""
        while [ -z "${TOKEN}" ]; do
          # Get token
          sleep 2
          TOKEN=$(curl -sk -X POST ${RANCHERHOSTNAME}/v3-public/localProviders/local?action=login -H 'content-type: application/json' -d "{\"username\":\"admin\",\"password\":\"${RANCHERBOOTSTRAPPASSWORD}\"}" | jq -r .token)
        done
      
        # Set password
        curl -sk ${RANCHERHOSTNAME}/v3/users?action=changepassword -H 'content-type: application/json' -H "Authorization: Bearer $TOKEN" -d "{\"currentPassword\":\"${RANCHERBOOTSTRAPPASSWORD}\",\"newPassword\":\"${RANCHER_FINALPASSWORD}\"}"
      
        # Create a temporary API token (ttl=60 minutes)
        APITOKEN=$(curl -sk ${RANCHERHOSTNAME}/v3/token -H 'content-type: application/json' -H "Authorization: Bearer ${TOKEN}" -d '{"type":"token","description":"automation","ttl":3600000}' | jq -r .token)
      
        curl -sk ${RANCHERHOSTNAME}/v3/settings/server-url -H 'content-type: application/json' -H "Authorization: Bearer ${APITOKEN}" -X PUT -d "{\"name\":\"server-url\",\"value\":\"${RANCHERHOSTNAME}\"}"
        curl -sk ${RANCHERHOSTNAME}/v3/settings/telemetry-opt -X PUT -H 'content-type: application/json' -H 'accept: application/json' -H "Authorization: Bearer ${APITOKEN}" -d '{"value":"out"}'
      fi
      
      # Clean up the lock cm
      ${KUBECTL} delete configmap ${RANCHERLOCKCMNAME} -n ${RANCHERLOCKNAMESPACE}
    • mgmt-stack-setup.service: contiene la configuración para crear el servicio systemd que ejecutará los guiones durante el primer arranque (no es necesario modificarlo).

      [Unit]
      Description=Setup Management stack components
      Wants=network-online.target
      # It requires rke2 or k3s running, but it will not fail if those services are not present
      After=network.target network-online.target rke2-server.service k3s.service
      # At least, the basic-setup.sh one needs to be present
      ConditionPathExists=/opt/mgmt/bin/basic-setup.sh
      
      [Service]
      User=root
      Type=forking
      # Metal3 can take A LOT to download the IPA image
      TimeoutStartSec=1800
      
      ExecStartPre=/bin/sh -c "echo 'Setting up Management components...'"
      # Scripts are executed in StartPre because Start can only run a single one
      ExecStartPre=/opt/mgmt/bin/rancher.sh
      ExecStartPre=/opt/mgmt/bin/metal3.sh
      ExecStart=/bin/sh -c "echo 'Finished setting up Management components'"
      RemainAfterExit=yes
      KillMode=process
      # Disable & delete everything
      ExecStartPost=rm -f /opt/mgmt/bin/rancher.sh
      ExecStartPost=rm -f /opt/mgmt/bin/metal3.sh
      ExecStartPost=rm -f /opt/mgmt/bin/basic-setup.sh
      ExecStartPost=/bin/sh -c "systemctl disable mgmt-stack-setup.service"
      ExecStartPost=rm -f /etc/systemd/system/mgmt-stack-setup.service
      
      [Install]
      WantedBy=multi-user.target

La carpeta custom/scripts contiene los siguientes archivos:

  • Guion 99-alias.sh: contiene el alias que usará el clúster de gestión para cargar el archivo kubeconfig en el primer arranque (no es necesario modificarlo).

    #!/bin/bash
    echo "alias k=kubectl" >> /etc/profile.local
    echo "alias kubectl=/var/lib/rancher/rke2/bin/kubectl" >> /etc/profile.local
    echo "export KUBECONFIG=/etc/rancher/rke2/rke2.yaml" >> /etc/profile.local
  • Guion 99-mgmt-setup.sh: contiene la configuración para copiar los guiones durante el primer arranque (no es necesario modificarlo).

    #!/bin/bash
    
    # Copy the scripts from combustion to the final location
    mkdir -p /opt/mgmt/bin/
    for script in basic-setup.sh rancher.sh metal3.sh; do
    	cp ${script} /opt/mgmt/bin/
    done
    
    # Copy the systemd unit file and enable it at boot
    cp mgmt-stack-setup.service /etc/systemd/system/mgmt-stack-setup.service
    systemctl enable mgmt-stack-setup.service
  • Guion 99-register.sh: contiene la configuración para registrar el sistema usando el código de registro del Centro de servicios al cliente de SUSE. Los elementos ${SCC_ACCOUNT_EMAIL} y ${SCC_REGISTRATION_CODE} deben configurarse correctamente para registrar el sistema con su cuenta.

    #!/bin/bash
    set -euo pipefail
    
    # Registration https://www.suse.com/support/kb/doc/?id=000018564
    if ! which SUSEConnect > /dev/null 2>&1; then
    	zypper --non-interactive install suseconnect-ng
    fi
    SUSEConnect --email "${SCC_ACCOUNT_EMAIL}" --url "https://scc.suse.com" --regcode "${SCC_REGISTRATION_CODE}"

40.3.4 Carpeta kubernetes

La carpeta kubernetes contiene las siguientes subcarpetas:

...
├── kubernetes
│ ├── manifests
│ │ ├── rke2-ingress-config.yaml
│ │ ├── neuvector-namespace.yaml
│ │ ├── ingress-l2-adv.yaml
│ │ └── ingress-ippool.yaml
│ ├── helm
│ │ └── values
│ │     ├── rancher.yaml
│ │     ├── neuvector.yaml
│ │     ├── metal3.yaml
│ │     └── certmanager.yaml
│ └── config
│     └── server.yaml
...

La carpeta kubernetes/config contiene los siguientes archivos:

  • server.yaml: de forma predeterminada, el complemento de CNI instalado por defecto es Cilium, por lo que no es necesario crear esta carpeta ni este archivo. En caso de que necesite personalizar el complemento de CNI, puede usar el archivo server.yaml que se encuentra en la carpeta kubernetes/config. Contiene la siguiente información:

    cni:
    - multus
    - cilium
Nota
Nota

Se trata de un archivo opcional para definir ciertas personalizaciones de Kubernetes, como los complementos de CNI que se utilizarán o muchas opciones que puede consultar en la documentación oficial.

La carpeta kubernetes/manifests contiene los siguientes archivos:

  • rke2-ingress-config.yaml: contiene la configuración para crear el servicio Ingress para el clúster de gestión (no es necesario modificarlo).

    apiVersion: helm.cattle.io/v1
    kind: HelmChartConfig
    metadata:
      name: rke2-ingress-nginx
      namespace: kube-system
    spec:
      valuesContent: |-
        controller:
          config:
            use-forwarded-headers: "true"
            enable-real-ip: "true"
          publishService:
            enabled: true
          service:
            enabled: true
            type: LoadBalancer
            externalTrafficPolicy: Local
  • neuvector-namespace.yaml: contiene la configuración para crear el espacio de nombres NeuVector (no es necesario modificarlo).

    apiVersion: v1
    kind: Namespace
    metadata:
      labels:
        pod-security.kubernetes.io/enforce: privileged
      name: neuvector
  • ingress-l2-adv.yaml: contiene la configuración para crear el L2Advertisement para el componente MetalLB (no es necesario modificarlo).

    apiVersion: metallb.io/v1beta1
    kind: L2Advertisement
    metadata:
      name: ingress-l2-adv
      namespace: metallb-system
    spec:
      ipAddressPools:
        - ingress-ippool
  • ingress-ippool.yaml: contiene la configuración para crear el IPAddressPool para el componente rke2-ingress-nginx. ${INGRESS_VIP} debe configurarse correctamente para definir la dirección IP reservada para usarse por el componente rke2-ingress-nginx.

    apiVersion: metallb.io/v1beta1
    kind: IPAddressPool
    metadata:
      name: ingress-ippool
      namespace: metallb-system
    spec:
      addresses:
        - ${INGRESS_VIP}/32
      serviceAllocation:
        priority: 100
        serviceSelectors:
          - matchExpressions:
              - {key: app.kubernetes.io/name, operator: In, values: [rke2-ingress-nginx]}

La carpeta kubernetes/helm/values contiene los siguientes archivos:

  • rancher.yaml: contiene la configuración para crear el componente Rancher. ${INGRESS_VIP} debe configurarse correctamente para definir la dirección IP que utilizará el componente Rancher. La URL para acceder al componente Rancher será https://rancher-${INGRESS_VIP}.sslip.io.

    hostname: rancher-${INGRESS_VIP}.sslip.io
    bootstrapPassword: "foobar"
    replicas: 1
    global.cattle.psp.enabled: "false"
  • neuvector.yaml: contiene la configuración para crear el componente NeuVector (no es necesario modificarlo).

    controller:
      replicas: 1
      ranchersso:
        enabled: true
    manager:
      enabled: false
    cve:
      scanner:
        enabled: false
        replicas: 1
    k3s:
      enabled: true
    crdwebhook:
      enabled: false
  • metal3.yaml: contiene la configuración para crear el componente Metal3. ${METAL3_VIP} debe configurarse correctamente para definir la dirección IP que utilizará el componente Metal3.

    global:
      ironicIP: ${METAL3_VIP}
      enable_vmedia_tls: false
      additionalTrustedCAs: false
    metal3-ironic:
      global:
        predictableNicNames: "true"
      persistence:
        ironic:
          size: "5Gi"

    Si desea desplegar clústeres descendentes arm64 utilizando este clúster de gestión x86_64, debe añadir la línea deployArchitecture: arm64 siguiente a la sección global del archivo metal3.yaml:

    global:
      ironicIP: ${METAL3_VIP}
      enable_vmedia_tls: false
      additionalTrustedCAs: false
      deployArchitecture: arm64
    metal3-ironic:
      global:
        predictableNicNames: "true"
      persistence:
        ironic:
          size: "5Gi"
Nota
Nota

En la versión actual, existe una limitación con respecto al uso de deployArchitecture: arm64. En concreto, si habilita el despliegue de clústeres arm64 descendentes mediante esta directiva, el clúster de gestión solo podrá desplegar posteriormente esta arquitectura. Para desplegar clústeres en ambas arquitecturas (x86_64 y arm64), deberá aprovisionar dos clústeres de gestión independientes. Esta limitación se eliminará en una versión futura.

Nota
Nota

El servidor de medios es una función opcional incluida en Metal3 (inhabilitada de forma predeterminada). Para utilizar esta función de Metal3, es necesario configurarla en el manifiesto anterior. Para utilizar el servidor de medios de Metal3, especifique la siguiente variable:

  • Defina enable_metal3_media_server como true para habilitar la función de servidor de medios en la sección global.

  • Incluya la siguiente configuración sobre el servidor de medios, donde ${MEDIA_VOLUME_PATH} es la ruta al volumen de medios en el medio (por ejemplo, /home/metal3/bmh-image-cache).

    metal3-media:
      mediaVolume:
        hostPath: ${MEDIA_VOLUME_PATH}

Se puede utilizar un servidor de medios externo para almacenar las imágenes y, en caso de que desee usarlo con TLS, deberá modificar las siguientes configuraciones:

  • Defina true en additionalTrustedCAs en el archivo metal3.yaml anterior para habilitar las CA de confianza adicionales del servidor de medios externo.

  • Incluya la siguiente configuración de secreto en la carpeta kubernetes/manifests/metal3-cacert-secret.yaml para almacenar el certificado de CA del servidor de medios externo.

    apiVersion: v1
    kind: Namespace
    metadata:
      name: metal3-system
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: tls-ca-additional
      namespace: metal3-system
    type: Opaque
    data:
      ca-additional.crt: {{ additional_ca_cert | b64encode }}

additional_ca_cert es el certificado de CA cifrado en base64 del servidor de medios externo. Puede usar el siguiente comando para cifrar el certificado y generar el secreto manualmente:

kubectl -n meta3-system create secret generic tls-ca-additional --from-file=ca-additional.crt=./ca-additional.crt
  • certmanager.yaml: contiene la configuración para crear el componente Cert-Manager (no es necesario modificarlo).

    installCRDs: "true"

40.3.5 Carpeta network

La carpeta network contiene tantos archivos como nodos haya en el clúster de gestión. En nuestro caso, solo tenemos un nodo, por lo que solo tenemos un archivo llamado mgmt-cluster-node1.yaml. El nombre del archivo debe coincidir con el nombre de host definido en el archivo de definición mgmt-cluster.yaml en la sección network/node descrita anteriormente.

Si necesita personalizar la configuración de red, por ejemplo, para utilizar una dirección IP estática específica (si no se usa DHCP), puede utilizar el archivo mgmt-cluster-node1.yaml que se encuentra en la carpeta network. Contiene la siguiente información:

  • ${MGMT_GATEWAY}: la dirección IP del gateway.

  • ${MGMT_DNS}: la dirección IP del servidor DNS.

  • ${MGMT_MAC}: la dirección MAC de la interfaz de red.

  • ${MGMT_NODE_IP}: la dirección IP del clúster de gestión.

routes:
  config:
  - destination: 0.0.0.0/0
    metric: 100
    next-hop-address: ${MGMT_GATEWAY}
    next-hop-interface: eth0
    table-id: 254
dns-resolver:
  config:
    server:
    - ${MGMT_DNS}
    - 8.8.8.8
interfaces:
- name: eth0
  type: ethernet
  state: up
  mac-address: ${MGMT_MAC}
  ipv4:
    address:
    - ip: ${MGMT_NODE_IP}
      prefix-length: 24
    dhcp: false
    enabled: true
  ipv6:
    enabled: false

Si desea utilizar DHCP para obtener la dirección IP, puede usar la siguiente configuración (la dirección MAC debe configurarse correctamente utilizando la variable ${MGMT_MAC}):

## This is an example of a dhcp network configuration for a management cluster
interfaces:
- name: eth0
  type: ethernet
  state: up
  mac-address: ${MGMT_MAC}
  ipv4:
    dhcp: true
    enabled: true
  ipv6:
    enabled: false
Nota
Nota
  • Dependiendo del número de nodos del clúster de gestión, puede crear más archivos como mgmt-cluster-node2.yaml, mgmt-cluster-node3.yaml, etc. para configurar el resto de los nodos.

  • La sección routes se utiliza para definir la tabla de enrutamiento del clúster de gestión.

40.4 Preparación de la imagen para entornos aislados

En esta sección se describe cómo preparar la imagen para entornos aislados. Muestra solo las diferencias con respecto a las secciones anteriores. Para preparar la imagen para entornos aislados, es necesario realizar los siguientes cambios con respecto a la sección sobre la preparación de imagen en entornos conectados (Sección 40.3, “Preparación de la imagen para entornos conectados”):

  • El archivo mgmt-cluster.yaml debe modificarse para incluir la sección embeddedArtifactRegistry con el campo images definido con todas las imágenes de contenedor que se incluirán en la imagen de salida de EIB.

  • El archivo mgmt-cluster.yaml debe modificarse para incluir el chart de Helm rancher-turtles-airgap-resources.

  • El guion custom/scripts/99-register.sh debe eliminarse si se utiliza un entorno aislado.

40.4.1 Modificaciones del archivo de definición

El archivo mgmt-cluster.yaml debe modificarse para incluir la sección embeddedArtifactRegistry. En ella, el campo images debe contener la lista de todas las imágenes de contenedor que se incluirán en la imagen de salida.

Nota
Nota

A continuación, se muestra un ejemplo del archivo mgmt-cluster.yaml con la sección embeddedArtifactRegistry incluida. Asegúrese de que las imágenes indicadas contengan las versiones de los componentes que necesita.

También se debe añadir el chart de Helm rancher-turtles-airgap-resources, que crea los recursos descritos en la documentación de Rancher Turtles para entornos aislados. Esto también requiere un archivo de valores turtles.yaml para que el chart de rancher-turtles especifique la configuración necesaria.

apiVersion: 1.2
image:
  imageType: iso
  arch: x86_64
  baseImage: SL-Micro.x86_64-6.1-Base-SelfInstall-GM.install.iso
  outputImageName: eib-mgmt-cluster-image.iso
operatingSystem:
  isoConfiguration:
    installDevice: /dev/sda
  users:
  - username: root
    encryptedPassword: $ROOT_PASSWORD
  packages:
    packageList:
    - jq
    sccRegistrationCode: $SCC_REGISTRATION_CODE
kubernetes:
  version: v1.32.4+rke2r1
  helm:
    charts:
      - name: cert-manager
        repositoryName: jetstack
        version: 1.15.3
        targetNamespace: cert-manager
        valuesFile: certmanager.yaml
        createNamespace: true
        installationNamespace: kube-system
      - name: longhorn-crd
        version: 106.2.0+up1.8.1
        repositoryName: rancher-charts
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
      - name: longhorn
        version: 106.2.0+up1.8.1
        repositoryName: rancher-charts
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
      - name: metal3
        version: 303.0.7+up0.11.5
        repositoryName: suse-edge-charts
        targetNamespace: metal3-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: metal3.yaml
      - name: rancher-turtles
        version: 303.0.4+up0.20.0
        repositoryName: suse-edge-charts
        targetNamespace: rancher-turtles-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: turtles.yaml
      - name: rancher-turtles-airgap-resources
        version: 303.0.4+up0.20.0
        repositoryName: suse-edge-charts
        targetNamespace: rancher-turtles-system
        createNamespace: true
        installationNamespace: kube-system
      - name: neuvector-crd
        version: 106.0.1+up2.8.6
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: neuvector
        version: 106.0.1+up2.8.6
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: rancher
        version: 2.11.2
        repositoryName: rancher-prime
        targetNamespace: cattle-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: rancher.yaml
    repositories:
      - name: jetstack
        url: https://charts.jetstack.io
      - name: rancher-charts
        url: https://charts.rancher.io/
      - name: suse-edge-charts
        url: oci://registry.suse.com/edge/charts
      - name: rancher-prime
        url: https://charts.rancher.com/server-charts/prime
    network:
      apiHost: $API_HOST
      apiVIP: $API_VIP
    nodes:
    - hostname: mgmt-cluster-node1
      initializer: true
      type: server
#   - hostname: mgmt-cluster-node2
#     type: server
#   - hostname: mgmt-cluster-node3
#     type: server
#       type: server
embeddedArtifactRegistry:
  images:
    - name: registry.suse.com/rancher/hardened-cluster-autoscaler:v1.9.0-build20241203
    - name: registry.suse.com/rancher/hardened-cni-plugins:v1.6.2-build20250306
    - name: registry.suse.com/rancher/hardened-coredns:v1.12.1-build20250401
    - name: registry.suse.com/rancher/hardened-k8s-metrics-server:v0.7.2-build20250110
    - name: registry.suse.com/rancher/hardened-multus-cni:v4.2.0-build20250326
    - name: registry.suse.com/rancher/klipper-helm:v0.9.5-build20250306
    - name: registry.suse.com/rancher/mirrored-cilium-cilium:v1.17.3
    - name: registry.suse.com/rancher/mirrored-cilium-operator-generic:v1.17.3
    - name: registry.suse.com/rancher/mirrored-longhornio-csi-attacher:v4.8.1
    - name: registry.suse.com/rancher/mirrored-longhornio-csi-node-driver-registrar:v2.13.0
    - name: registry.suse.com/rancher/mirrored-longhornio-csi-provisioner:v5.2.0
    - name: registry.suse.com/rancher/mirrored-longhornio-csi-resizer:v1.13.2
    - name: registry.suse.com/rancher/mirrored-longhornio-csi-snapshotter:v8.2.0
    - name: registry.suse.com/rancher/mirrored-longhornio-livenessprobe:v2.15.0
    - name: registry.suse.com/rancher/mirrored-longhornio-longhorn-engine:v1.8.1
    - name: registry.suse.com/rancher/mirrored-longhornio-longhorn-instance-manager:v1.8.1
    - name: registry.suse.com/rancher/mirrored-longhornio-longhorn-manager:v1.8.1
    - name: registry.suse.com/rancher/mirrored-longhornio-longhorn-share-manager:v1.8.1
    - name: registry.suse.com/rancher/mirrored-longhornio-longhorn-ui:v1.8.1
    - name: registry.suse.com/rancher/mirrored-sig-storage-snapshot-controller:v8.2.0
    - name: registry.suse.com/rancher/neuvector-compliance-config:1.0.5
    - name: registry.suse.com/rancher/neuvector-controller:5.4.4
    - name: registry.suse.com/rancher/neuvector-enforcer:5.4.4
    - name: registry.suse.com/rancher/nginx-ingress-controller:v1.12.1-hardened3
    - name: registry.rancher.com/rancher/cluster-api-addon-provider-fleet:v0.10.0
    - name: registry.rancher.com/rancher/cluster-api-operator:v0.17.0
    - name: registry.rancher.com/rancher/fleet-agent:v0.12.3
    - name: registry.rancher.com/rancher/fleet:v0.12.3
    - name: registry.rancher.com/rancher/hardened-node-feature-discovery:v0.15.7-build20250425
    - name: registry.rancher.com/rancher/rancher-webhook:v0.7.2
    - name: registry.rancher.com/rancher/rancher/turtles:v0.20.0
    - name: registry.rancher.com/rancher/rancher:v2.11.2
    - name: registry.rancher.com/rancher/shell:v0.4.1
    - name: registry.rancher.com/rancher/system-upgrade-controller:v0.15.2
    - name: registry.suse.com/rancher/cluster-api-controller:v1.9.5
    - name: registry.suse.com/rancher/cluster-api-provider-metal3:v1.9.3
    - name: registry.suse.com/rancher/cluster-api-provider-rke2-bootstrap:v0.16.1
    - name: registry.suse.com/rancher/cluster-api-provider-rke2-controlplane:v0.16.1
    - name: registry.suse.com/rancher/hardened-sriov-network-operator:v1.5.0-build20250425
    - name: registry.suse.com/rancher/ip-address-manager:v1.9.4
    - name: registry.rancher.com/rancher/kubectl:v1.32.2

40.4.2 Modificaciones de la carpeta custom

  • El guion custom/scripts/99-register.sh debe eliminarse si se utiliza un entorno aislado. Como se puede ver en la estructura del directorio, el guion 99-register.sh no está incluido en la carpeta custom/scripts.

40.4.3 Modificaciones de la carpeta de valores de Helm

  • El archivo turtles.yaml contiene la configuración necesaria para especificar el funcionamiento con aislamiento para Rancher Turtles. Tenga en cuenta que esto depende de la instalación del chart de rancher-turtles-airgap-resources.

    cluster-api-operator:
      cluster-api:
        core:
          fetchConfig:
            selector: "{\"matchLabels\": {\"provider-components\": \"core\"}}"
        rke2:
          bootstrap:
            fetchConfig:
              selector: "{\"matchLabels\": {\"provider-components\": \"rke2-bootstrap\"}}"
          controlPlane:
            fetchConfig:
              selector: "{\"matchLabels\": {\"provider-components\": \"rke2-control-plane\"}}"
        metal3:
          infrastructure:
            fetchConfig:
              selector: "{\"matchLabels\": {\"provider-components\": \"metal3\"}}"

40.5 Creación de la imagen

Una vez preparada la estructura de directorios siguiendo las secciones anteriores (tanto para escenarios conectados como aislados), ejecute el comando siguiente para crear la imagen:

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

Esto crea el archivo de imagen ISO de salida que, en nuestro caso, según la definición de imagen descrita anteriormente, es eib-mgmt-cluster-image.iso.

40.6 Aprovisionamiento del clúster de gestión

La imagen anterior contiene todos los componentes explicados anteriormente y se puede utilizar para aprovisionar el clúster de gestión mediante una máquina virtual o un servidor bare metal (usando la función de medios virtuales).

41 Configuración de funciones de telecomunicaciones

Esta sección documenta y explica la configuración de las funciones específicas para telecomunicaciones en clústeres desplegados mediante SUSE Edge for Telco.

Se utiliza el método de despliegue de aprovisionamiento de red dirigida, descrito en la sección sobre aprovisionamiento automatizado (Capítulo 42, Aprovisionamiento de red dirigida totalmente automatizado).

En esta sección se tratan los siguientes temas:

41.1 Imagen del kernel en tiempo real

Usar una imagen de kernel en tiempo real no es necesariamente mejor que usar un kernel estándar. Se trata de un kernel diferente, optimizado para un caso práctico concreto. El kernel en tiempo real está optimizado para reducir la latencia a costa del rendimiento. No se recomienda el uso del kernel en tiempo real para fines generales, pero en nuestro caso, es el kernel recomendado para cargas de trabajo de telecomunicaciones, donde la latencia es un factor clave.

Hay cuatro funciones principales:

  • Ejecución determinista:

    Se consigue una mayor previsibilidad: se garantiza que los procesos empresariales críticos se completan a tiempo, siempre, y ofrece un servicio de alta calidad, incluso con cargas elevadas del sistema. Al proteger los recursos clave del sistema para los procesos de alta prioridad, se garantiza una mayor previsibilidad para las aplicaciones en las que el tiempo es importante.

  • Baja fluctuación:

    La baja fluctuación basada en la tecnología altamente determinista ayuda a mantener las aplicaciones sincronizadas con el mundo real. Esto ayuda a los servicios que necesitan cálculos continuos y repetidos.

  • Herencia de prioridad:

    La herencia de prioridad hace referencia a la capacidad de un proceso de subir de prioridad si existe un proceso de mayor prioridad que requiere que el de menor prioridad finalice antes para poder completar su tarea. SUSE Linux Enterprise Real Time resuelve estos problemas de inversión de prioridad para los procesos críticos.

  • Interrupciones de subprocesos:

    En un sistema operativo de uso general, no se pueden interrumpir los procesos que se ejecutan en modo de interrupción. Con SUSE Linux Enterprise Real Time, estas interrupciones se encapsulan en subprocesos del kernel, que son interrumpibles. De esta forma, los procesos de mayor prioridad definidos por el usuario pueden interrumpir tanto interrupciones duras como suaves.

    En nuestro caso, si ha instalado una imagen en tiempo real como SUSE Linux Micro RT, el kernel en tiempo real ya está instalado. Puede descargar la imagen del kernel en tiempo real del Centro de servicios al cliente de SUSE.

    Nota
    Nota

    Para obtener más información sobre el kernel en tiempo real, visite SUSE Real Time.

41.2 Argumentos del kernel para baja latencia y alto rendimiento

Es importante configurar los argumentos del kernel para que el kernel en tiempo real funcione correctamente y ofrezca el mejor rendimiento y una baja latencia para ejecutar cargas de trabajo de telecomunicaciones. Hay algunos conceptos importantes que hay que tener en cuenta al configurar los argumentos del kernel para este caso práctico:

  • Elimine kthread_cpus cuando use el kernel en tiempo real de SUSE. Este parámetro controla en qué CPU se crean los subprocesos del kernel. También controla qué CPU están permitidas para el PID 1 y para cargar módulos del kernel (el ayudante del espacio de usuario kmod). Este parámetro no se reconoce y no tiene ningún efecto.

  • Use isolcpus, nohz_full, rcu_nocbs e irqaffinity para aislar los núcleos de CPU. Para obtener una lista completa de las técnicas de fijación de CPU, consulte el capítulo sobre fijación de CPU mediante Tuned y argumentos del kernel (Sección 41.3, “Fijación de CPU mediante Tuned y argumentos del kernel”).

  • Añade los indicadores domain,nohz,managed_irq al argumento del kernel isolcpus. Si no se añade ningún indicador, isolcpus equivale a especificar solo el indicador domain. Esto aísla las CPU especificadas de la programación, incluidas las tareas del kernel. El indicador nohz detiene la marca del programador en las CPU especificadas (si solo se puede ejecutar una tarea en una CPU), y el indicador managed_irq evita el enrutamiento de interrupciones externas gestionadas (dispositivos) en las CPU especificadas. Tenga en cuenta que las líneas IRQ de los dispositivos NVMe están totalmente gestionadas por el kernel y, como consecuencia, se enrutarán a los núcleos no aislados (de mantenimiento). Por ejemplo, la línea de comandos que se proporciona al final de esta sección dará como resultado que solo se asignen cuatro colas (más una cola de administración/control) en el sistema:

    for I in $(grep nvme0 /proc/interrupts | cut -d ':' -f1); do cat /proc/irq/${I}/effective_affinity_list; done | column
    39      0       19      20      39

    Este comportamiento evita cualquier interrupción causada por la E/S del disco en cualquier aplicación sensible al tiempo que se ejecute en los núcleos aislados, pero puede requerir atención y un diseño cuidadoso para las cargas de trabajo centradas en el almacenamiento.

  • Ajuste las marcas (ticks, interrupciones periódicas del temporizador del kernel):

    • skew_tick=1: a veces, las marcas pueden ocurrir simultáneamente. En lugar de que todas las CPU reciban su marca de temporizador exactamente al mismo tiempo, skew_tick=1 hace que se produzcan en momentos ligeramente distintos. Esto ayuda a reducir la fluctuación del sistema, lo que se traduce en tiempos de respuesta a las interrupciones más consistentes y más bajos (un requisito esencial para las aplicaciones sensibles a la latencia).

    • nohz=on: detiene la marca del temporizador periódico en las CPU inactivas.

    • nohz_full=<núcleos-cpu>: detiene la marca del temporizador periódico en las CPU especificadas que están dedicadas a aplicaciones en tiempo real.

  • Inhabilite la gestión de excepciones de comprobación de máquina (MCE) especificando mce=off. Las MCE son errores de hardware detectados por el procesador y desactivarlas puede evitar que los registros sean excesivamente grandes.

  • Añada nowatchdog para inhabilitar el watchdog de bloqueo suave, que se implementa como un temporizador que se ejecuta en el contexto de interrupción dura del temporizador. Cuando caduca (es decir, cuando se detecta un bloqueo suave), muestra una advertencia (en el contexto de interrupción dura) y ejecuta cualquier objetivo de latencia. Incluso si no caduca nunca, pasa a la lista de temporizadores, lo que aumenta ligeramente la sobrecarga de cada interrupción del temporizador. Esta opción también inhabilita el watchdog de NMI, por lo que las NMI no pueden interferir.

  • nmi_watchdog=0 inhabilita el watchdog de NMI (interrupción no enmascarable). Se puede omitir si se usa nowatchdog.

  • RCU (Read-Copy-Update, leer-copiar-actualizar) es un mecanismo del kernel que permite el acceso simultáneo y sin bloqueos de muchos lectores a datos compartidos. Una retrollamada RCU, una función que se activa tras un "periodo de gracia", garantiza que todos los lectores anteriores hayan terminado, de modo que los datos antiguos puedan recuperarse de forma segura. Ajustamos RCU, especialmente para cargas de trabajo sensibles, con el fin de descargar estas retrollamadas de CPU dedicadas (fijadas), evitando que las operaciones del kernel interfieran con tareas críticas y sensibles al tiempo.

    • Especifique las CPU fijadas en rcu_nocbs para que las retrollamadas de RCU no se ejecuten en ellas. Esto ayuda a reducir la fluctuación y la latencia de las cargas de trabajo en tiempo real.

    • rcu_nocb_poll hace que las CPU sin retrollamada realicen sondeos periódicos para comprobar si es necesario gestionar la retrollamada. Esto puede reducir la sobrecarga de interrupciones.

    • rcupdate.rcu_cpu_stall_suppress=1 suprime las advertencias de bloqueo de la CPU por RCU, que en ocasiones pueden ser falsos positivos en sistemas en tiempo real con mucha carga.

    • rcupdate.rcu_expedited=1 acelera el período de gracia para las operaciones RCU, lo que hace que las secciones críticas de lectura sean más receptivas.

    • rcupdate.rcu_normal_after_boot=1, cuando se usa con rcu_expedited, permite que RCU vuelva al funcionamiento normal (no acelerado) después del arranque del sistema.

    • rcupdate.rcu_task_stall_timeout=0 inhabilita el detector de bloqueo de tareas RCU, lo que evita posibles advertencias o interrupciones del sistema provocadas por tareas RCU de larga duración.

    • rcutree.kthread_prio=99 establece la prioridad del subproceso del kernel de retrollamadas de RCU al máximo posible (99), lo que garantiza que se programen y gestionen las retrollamadas de RCU con rapidez cuando sea necesario.

  • Añada ignition.platform.id=openstack para Metal3 y Cluster API a fin de aprovisionar/desaprovisionar correctamente el clúster. Esto lo utiliza el agente Python de Metal3, que tiene su origen en Openstack Ironic.

  • Elimine intel_pstate=passive. Esta opción configura intel_pstate para que funcione con reguladores cpufreq genéricos; pero, para que esto funcione, inhabilita los estados P gestionados por hardware (HWP) como efecto secundario. Para reducir la latencia del hardware, no se recomienda utilizar esta opción para cargas de trabajo en tiempo real.

  • Reemplace intel_idle.max_cstate=0 processor.max_cstate=1 por idle=poll. Para evitar las transiciones de estado C, se usa la opción idle=poll para inhabilitar las transiciones de estado C y mantener la CPU en el estado C más alto. La opción intel_idle.max_cstate=0 inhabilita intel_idle, por lo que se usa acpi_idle, y acpi_idle.max_cstate=1 establece el estado C máximo para acpi_idle. En arquitecturas AMD64/Intel 64, el primer estado C de ACPI es siempre POLL, pero usa una función poll_idle(), que puede introducir una pequeña latencia al leer el reloj periódicamente y reiniciar el bucle principal en do_idle() después de un tiempo de espera (esto también implica borrar y establecer el indicador de tarea TIF_POLL). Por el contrario, idle=poll se ejecuta en un bucle cerrado, esperando activamente a que se reprogramen las tareas. Esto minimiza la latencia al salir del estado de inactividad, pero a costa de mantener la CPU funcionando a toda velocidad en el subproceso inactivo.

  • Desactive C1E en BIOS. Es importante desactivar el estado C1E en el BIOS para evitar que la CPU entre en el estado C1E cuando está inactiva. El estado C1E es un estado de bajo consumo que puede introducir latencia cuando la CPU está inactiva.

El resto de esta documentación trata sobre parámetros adicionales, incluyendo las páginas enormes e IOMMU.

Se proporciona un ejemplo de argumentos del kernel para un servidor Intel de 32 núcleos, que incluye los ajustes mencionados anteriormente:

$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=77b713de-5cc7-4d4c-8fc6-f5eca0a43cf9 skew_tick=1 rd.timeout=60 rd.retry=45 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack intel_iommu=on iommu=pt irqaffinity=0,31,32,63 isolcpus=domain,nohz,managed_irq,1-30,33-62 nohz_full=1-30,33-62 nohz=on mce=off net.ifnames=0 nosoftlockup nowatchdog nmi_watchdog=0 quiet rcu_nocb_poll rcu_nocbs=1-30,33-62 rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll

Aquí hay otro ejemplo de configuración para un servidor AMD de 64 núcleos. Entre los 128 procesadores lógicos (0-127), los primeros 8 núcleos (0-7) se destinan a tareas de mantenimiento, mientras que los 120 núcleos restantes (8-127) se fijan para las aplicaciones:

$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=575291cf-74e8-42cf-8f2c-408a20dc00b8 skew_tick=1 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack amd_iommu=on iommu=pt irqaffinity=0-7 isolcpus=domain,nohz,managed_irq,8-127 nohz_full=8-127 rcu_nocbs=8-127 mce=off nohz=on net.ifnames=0 nowatchdog nmi_watchdog=0 nosoftlockup quiet rcu_nocb_poll rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll

41.3 Fijación de CPU mediante Tuned y argumentos del kernel

tuned es una herramienta de ajuste del sistema que supervisa las condiciones del sistema para optimizar el rendimiento usando varios perfiles predefinidos. Una característica clave es su capacidad para aislar los núcleos de la CPU para cargas de trabajo específicas, como aplicaciones en tiempo real. Esto evita que el sistema operativo utilice esos núcleos y aumente potencialmente la latencia.

Para habilitar y configurar esta función, lo primero es crear un perfil para los núcleos de CPU que se deseen aislar. En este ejemplo, dedicamos 60 de los 64 núcleos (1-30,33-62) a la aplicación y los 4 núcleos restantes para tareas de mantenimiento. Tenga en cuenta que el diseño de las CPU aisladas depende en gran medida de las aplicaciones en tiempo real.

$ echo "export tuned_params" >> /etc/grub.d/00_tuned

$ echo "isolated_cores=1-30,33-62" >> /etc/tuned/cpu-partitioning-variables.conf

$ tuned-adm profile cpu-partitioning
Tuned (re)started, changes applied.

A continuación, debemos modificar la opción GRUB para aislar los núcleos de CPU y otros parámetros importantes para el uso de las CPU. Es importante personalizar las opciones siguientes con las especificaciones reales de su hardware:

ParámetroValorDescripción

isolcpus

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

Aísla los núcleos 1-30 y 33-62. domain indica que estas CPU forman parte del dominio de aislamiento. nohz habilita el funcionamiento sin marcas en estas CPU aisladas cuando están inactivas para reducir las interrupciones. managed_irq aísla las CPU fijadas para que no sean objeto de IRQ. Esto contempla irqaffinity=0-7, que ya dirige la mayoría de las IRQ a los núcleos de mantenimiento.

skew_tick

1

Esta opción permite al kernel distribuir las interrupciones del temporizador entre las CPU aisladas.

nohz

on

Si está habilitada, la interrupción periódica del temporizador del kernel (la "marca") se detendrá en cualquier núcleo de CPU que esté inactivo. Esto beneficia principalmente a las CPU de mantenimiento (0,31,32,63). De este modo se ahorra energía y se reducen los despertares innecesarios en esos núcleos de uso general.

nohz_full

1-30,33-62

En el caso de los núcleos aislados, esto detiene la marca incluso si la CPU está ejecutando una sola tarea activa. Es decir, hace que la CPU funcione en modo totalmente sin marcas (o "dyntick"). El kernel solo proporcionará interrupciones del temporizador cuando sean realmente necesarias.

rcu_nocbs

1-30,33-62

Esta opción descarga el procesamiento de retrollamada de RCU de los núcleos de CPU especificados.

rcu_nocb_poll

 

Cuando esta opción está definida, las CPU sin retrollamada de RCU realizarán sondeos periódicos para comprobar si es necesario gestionar las retrollamadas, en lugar de que se activen explícitamente por otras CPU. Esto puede reducir la sobrecarga de interrupciones.

irqaffinity

0,31,32,63

Esta opción permite al kernel ejecutar las interrupciones en los núcleos de mantenimiento.

idle

poll

Esto minimiza la latencia al salir del estado inactivo, pero a costa de mantener la CPU funcionando a toda velocidad en el subproceso inactivo.

nmi_watchdog

0

Esta opción inhabilita únicamente el watchdog de NMI. Se puede omitir si se ha definido nowatchdog.

nowatchdog

 

Esta opción inhabilita el watchdog de bloqueo suave, que se implementa como un temporizador que se ejecuta en el contexto de interrupción dura del temporizador.

Los siguientes comandos modifican la configuración de GRUB y aplican los cambios mencionados anteriormente para que estén presentes en el próximo arranque:

Edite el archivo /etc/default/grub con los parámetros anteriores. El archivo tendrá este aspecto:

GRUB_CMDLINE_LINUX="BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=77b713de-5cc7-4d4c-8fc6-f5eca0a43cf9 skew_tick=1 rd.timeout=60 rd.retry=45 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack intel_iommu=on iommu=pt irqaffinity=0,31,32,63 isolcpus=domain,nohz,managed_irq,1-30,33-62 nohz_full=1-30,33-62 nohz=on mce=off net.ifnames=0 nosoftlockup nowatchdog nmi_watchdog=0 quiet rcu_nocb_poll rcu_nocbs=1-30,33-62 rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll"

Actualice la configuración de GRUB:

$ transactional-update grub.cfg
$ reboot

Para comprobar que los parámetros se han aplicado después del rearranque, puede utilizar el siguiente comando para comprobar la línea de comandos del kernel:

$ cat /proc/cmdline

Puede usar otro guion para ajustar la configuración de la CPU, que básicamente realiza los siguientes pasos:

  • Definir el regulador de la CPU como performance.

  • Desactivar la migración del temporizador a las CPU aisladas.

  • Migrar los subprocesos kdaemon a las CPU de mantenimiento.

  • Definir la latencia de las CPU aisladas en el valor más bajo posible.

  • Retrasar las actualizaciones de vmstat a 300 segundos.

El guion está disponible en el repositorio de ejemplos de SUSE Edge for Telco.

41.4 Configuración de la CNI

41.4.1 Cilium

Cilium es el complemento de CNI predeterminado para SUSE Edge for Telco. Para habilitar Cilium en el clúster RKE2 como complemento predeterminado hay que configurar lo siguiente en el archivo /etc/rancher/rke2/config.yaml:

cni:
- cilium

Esto también se puede especificar con argumentos de línea de comandos, es decir, con --cni=cilium en la línea del servidor del archivo /etc/systemd/system/rke2-server.

Para usar el operador de red SR-IOV descrito en la siguiente sección (Sección 41.5, “SR-IOV”), use Multus con otro complemento de CNI, como Cilium o Calico, como complemento secundario.

cni:
- multus
- cilium
Nota
Nota

Para obtener más información sobre los complementos de CNI, visite Network Options (Opciones de red).

41.5 SR-IOV

SR-IOV permite que un dispositivo, como un adaptador de red, divida el acceso a sus recursos entre varias funciones de hardware PCIe. Hay diferentes formas de desplegar SR-IOV, y aquí mostramos dos:

  • Opción 1: usar los complementos de dispositivo de CNI SR-IOV y un mapa de configuración para configurarlo correctamente.

  • Opción 2 (recomendada): usar el chart de Helm de SR-IOV en Rancher Prime para facilitar este despliegue.

Opción 1: Instalación de complementos de dispositivo de CNI SR-IOV y un mapa de configuración para configurarlo correctamente

  • Prepare el mapa de configuración para el complemento de dispositivo

Obtenga la información para rellenar el mapa de configuración desde el comando lspci:

$ lspci | grep -i acc
8a:00.0 Processing accelerators: Intel Corporation Device 0d5c

$ lspci | grep -i net
19:00.0 Ethernet controller: Broadcom Inc. and subsidiaries BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (rev 11)
19:00.1 Ethernet controller: Broadcom Inc. and subsidiaries BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (rev 11)
19:00.2 Ethernet controller: Broadcom Inc. and subsidiaries BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (rev 11)
19:00.3 Ethernet controller: Broadcom Inc. and subsidiaries BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (rev 11)
51:00.0 Ethernet controller: Intel Corporation Ethernet Controller E810-C for QSFP (rev 02)
51:00.1 Ethernet controller: Intel Corporation Ethernet Controller E810-C for QSFP (rev 02)
51:01.0 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:01.1 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:01.2 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:01.3 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:11.0 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:11.1 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:11.2 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:11.3 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)

El mapa de configuración es un archivo JSON que describe los dispositivos utilizando filtros para detectarlos, y crea grupos para las interfaces. Lo importante es comprender qué son los filtros y los grupos. Los filtros se usan para detectar los dispositivos y los grupos, para crear las interfaces.

Es posible establecer filtros como:

  • vendorID: 8086 (Intel)

  • deviceID: 0d5c (tarjeta Accelerator)

  • driver: vfio-pci (controlador)

  • pfNames: p2p1 (nombre de interfaz física)

También es posible definir filtros con una sintaxis de interfaz más compleja, por ejemplo:

  • pfNames: ["eth1#1,2,3,4,5,6"] o [eth1#1-6] (nombre de interfaz física)

Para los grupos, es posible crear un grupo para la tarjeta FEC y otro para la tarjeta Intel, o incluso crear un prefijo en función de nuestro caso de uso:

  • resourceName: pci_sriov_net_bh_dpdk

  • resourcePrefix: Rancher.io

Hay muchas combinaciones posibles para descubrir y crear el grupo de recursos necesario para asignar funciones virtuales a los pods.

Nota
Nota

Para obtener más información sobre los filtros y los grupos, consulte sr-iov network device plug-in (Complemento de dispositivo de red sr-iov).

Después de configurar los filtros y los grupos que coincidan con las interfaces del hardware y el caso de uso, el mapa de configuración siguiente muestra un ejemplo útil:

apiVersion: v1
kind: ConfigMap
metadata:
  name: sriovdp-config
  namespace: kube-system
data:
  config.json: |
    {
        "resourceList": [
            {
                "resourceName": "intel_fec_5g",
                "devicetype": "accelerator",
                "selectors": {
                    "vendors": ["8086"],
                    "devices": ["0d5d"]
                }
            },
            {
                "resourceName": "intel_sriov_odu",
                "selectors": {
                    "vendors": ["8086"],
                    "devices": ["1889"],
                    "drivers": ["vfio-pci"],
                    "pfNames": ["p2p1"]
                }
            },
            {
                "resourceName": "intel_sriov_oru",
                "selectors": {
                    "vendors": ["8086"],
                    "devices": ["1889"],
                    "drivers": ["vfio-pci"],
                    "pfNames": ["p2p2"]
                }
            }
        ]
    }
  • Prepare el archivo daemonset para desplegar el complemento de dispositivo.

El complemento de dispositivo admite varias arquitecturas (arm, amd o ppc64le), por lo que se puede usar el mismo archivo para diferentes arquitecturas, desplegando un daemonset para cada arquitectura.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: sriov-device-plugin
  namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-sriov-device-plugin-amd64
  namespace: kube-system
  labels:
    tier: node
    app: sriovdp
spec:
  selector:
    matchLabels:
      name: sriov-device-plugin
  template:
    metadata:
      labels:
        name: sriov-device-plugin
        tier: node
        app: sriovdp
    spec:
      hostNetwork: true
      nodeSelector:
        kubernetes.io/arch: amd64
      tolerations:
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      serviceAccountName: sriov-device-plugin
      containers:
      - name: kube-sriovdp
        image: rancher/hardened-sriov-network-device-plugin:v3.7.0-build20240816
        imagePullPolicy: IfNotPresent
        args:
        - --log-dir=sriovdp
        - --log-level=10
        securityContext:
          privileged: true
        resources:
          requests:
            cpu: "250m"
            memory: "40Mi"
          limits:
            cpu: 1
            memory: "200Mi"
        volumeMounts:
        - name: devicesock
          mountPath: /var/lib/kubelet/
          readOnly: false
        - name: log
          mountPath: /var/log
        - name: config-volume
          mountPath: /etc/pcidp
        - name: device-info
          mountPath: /var/run/k8s.cni.cncf.io/devinfo/dp
      volumes:
        - name: devicesock
          hostPath:
            path: /var/lib/kubelet/
        - name: log
          hostPath:
            path: /var/log
        - name: device-info
          hostPath:
            path: /var/run/k8s.cni.cncf.io/devinfo/dp
            type: DirectoryOrCreate
        - name: config-volume
          configMap:
            name: sriovdp-config
            items:
            - key: config.json
              path: config.json
  • Después de aplicar el mapa de configuración y el daemonset, se desplegará el complemento de dispositivo y se detectarán las interfaces, que estarán disponibles para los pods.

    $ kubectl get pods -n kube-system | grep sriov
    kube-system  kube-sriov-device-plugin-amd64-twjfl  1/1  Running  0  2m
  • Compruebe qué interfaces se han detectado y están disponibles en los nodos para los pods:

    $ kubectl get $(kubectl get nodes -oname) -o jsonpath='{.status.allocatable}' | jq
    {
      "cpu": "64",
      "ephemeral-storage": "256196109726",
      "hugepages-1Gi": "40Gi",
      "hugepages-2Mi": "0",
      "intel.com/intel_fec_5g": "1",
      "intel.com/intel_sriov_odu": "4",
      "intel.com/intel_sriov_oru": "4",
      "memory": "221396384Ki",
      "pods": "110"
    }
  • La tarjeta FEC es intel.com/intel_fec_5g y su valor es 1.

  • La función virtual VF es intel.com/intel_sriov_odu o intel.com/intel_sriov_oru si la despliega con un complemento de dispositivo y el mapa de configuración sin charts de Helm.

Importante
Importante

Si no hay interfaces, no tiene mucho sentido continuar, ya que la interfaz no estará disponible para los pods. Revise primero el mapa de configuración y los filtros para resolver el problema.

Opción 2 (recomendada): instalación con Rancher mediante el chart de Helm para la CNI SR-IOV y los complementos de dispositivo

  • Consiga Helm si no está presente:

$ curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
  • Instale SR-IOV.

helm install sriov-crd oci://registry.suse.com/edge/charts/sriov-crd -n sriov-network-operator
helm install sriov-network-operator oci://registry.suse.com/edge/charts/sriov-network-operator -n sriov-network-operator
  • Compruebe los crd y los pods de los recursos desplegados:

$ kubectl get crd
$ kubectl -n sriov-network-operator get pods
  • Compruebe la etiqueta de los nodos.

Con todos los recursos en ejecución, la etiqueta aparece automáticamente en su nodo:

$ kubectl get nodes -oyaml | grep feature.node.kubernetes.io/network-sriov.capable

feature.node.kubernetes.io/network-sriov.capable: "true"
  • Revise el daemonset para comprobar si las entradas sriov-network-config-daemon y sriov-rancher-nfd-worker nuevas están activas y listas:

$ kubectl get daemonset -A
NAMESPACE             NAME                            DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR                                           AGE
calico-system            calico-node                     1         1         1       1            1           kubernetes.io/os=linux                                  15h
sriov-network-operator   sriov-network-config-daemon     1         1         1       1            1           feature.node.kubernetes.io/network-sriov.capable=true   45m
sriov-network-operator   sriov-rancher-nfd-worker        1         1         1       1            1           <none>                                                  45m
kube-system              rke2-ingress-nginx-controller   1         1         1       1            1           kubernetes.io/os=linux                                  15h
kube-system              rke2-multus-ds                  1         1         1       1            1           kubernetes.io/arch=amd64,kubernetes.io/os=linux         15h

En unos minutos (la actualización puede tardar hasta 10 minutos), los nodos se detectan y se configuran capacidad de SR-IOV:

$ kubectl get sriovnetworknodestates.sriovnetwork.openshift.io -A
NAMESPACE             NAME     AGE
sriov-network-operator   xr11-2   83s
  • Compruebe las interfaces detectadas.

Las interfaces detectadas deben ser la dirección PCI del dispositivo de red. Compruebe esta información con el comando lspci en el host.

$ kubectl get sriovnetworknodestates.sriovnetwork.openshift.io -n kube-system -oyaml
apiVersion: v1
items:
- apiVersion: sriovnetwork.openshift.io/v1
  kind: SriovNetworkNodeState
  metadata:
    creationTimestamp: "2023-06-07T09:52:37Z"
    generation: 1
    name: xr11-2
    namespace: sriov-network-operator
    ownerReferences:
    - apiVersion: sriovnetwork.openshift.io/v1
      blockOwnerDeletion: true
      controller: true
      kind: SriovNetworkNodePolicy
      name: default
      uid: 80b72499-e26b-4072-a75c-f9a6218ec357
    resourceVersion: "356603"
    uid: e1f1654b-92b3-44d9-9f87-2571792cc1ad
  spec:
    dpConfigVersion: "356507"
  status:
    interfaces:
    - deviceID: "1592"
      driver: ice
      eSwitchMode: legacy
      linkType: ETH
      mac: 40:a6:b7:9b:35:f0
      mtu: 1500
      name: p2p1
      pciAddress: "0000:51:00.0"
      totalvfs: 128
      vendor: "8086"
    - deviceID: "1592"
      driver: ice
      eSwitchMode: legacy
      linkType: ETH
      mac: 40:a6:b7:9b:35:f1
      mtu: 1500
      name: p2p2
      pciAddress: "0000:51:00.1"
      totalvfs: 128
      vendor: "8086"
    syncStatus: Succeeded
kind: List
metadata:
  resourceVersion: ""
Nota
Nota

Si su interfaz no se detecta, asegúrese de que esté presente en el siguiente mapa de configuración:

$ kubectl get cm supported-nic-ids -oyaml -n sriov-network-operator

Si su dispositivo no aparece, edite el mapa de configuración y añada los valores correctos que se deban detectar (puede que sea necesario reiniciar el daemonset sriov-network-config-daemon).

  • Cree la directiva NetworkNodePolicy para configurar las funciones virtuales.

Se crearán algunas funciones virtuales (numVfs) desde el dispositivo (rootDevices) y se configurarán con el controlador deviceType y el MTU:

Nota
Nota

El campo resourceName no debe contener caracteres especiales y debe ser único en todo el clúster. En el ejemplo se usa deviceType: vfio-pci porque dpdk se usará junto a sr-iov. Si no utiliza dpdk, el valor de deviceType debe ser deviceType: netdevice (valor predeterminado).

apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: policy-dpdk
  namespace: sriov-network-operator
spec:
  nodeSelector:
    feature.node.kubernetes.io/network-sriov.capable: "true"
  resourceName: intelnicsDpdk
  deviceType: vfio-pci
  numVfs: 8
  mtu: 1500
  nicSelector:
    deviceID: "1592"
    vendor: "8086"
    rootDevices:
    - 0000:51:00.0
  • Valide las configuraciones:

$ kubectl get $(kubectl get nodes -oname) -o jsonpath='{.status.allocatable}' | jq
{
  "cpu": "64",
  "ephemeral-storage": "256196109726",
  "hugepages-1Gi": "60Gi",
  "hugepages-2Mi": "0",
  "intel.com/intel_fec_5g": "1",
  "memory": "200424836Ki",
  "pods": "110",
  "rancher.io/intelnicsDpdk": "8"
}
  • Cree la red sr-iov (opcional, si se necesita una red diferente):

apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetwork
metadata:
  name: network-dpdk
  namespace: sriov-network-operator
spec:
  ipam: |
    {
      "type": "host-local",
      "subnet": "192.168.0.0/24",
      "rangeStart": "192.168.0.20",
      "rangeEnd": "192.168.0.60",
      "routes": [{
        "dst": "0.0.0.0/0"
      }],
      "gateway": "192.168.0.1"
    }
  vlan: 500
  resourceName: intelnicsDpdk
  • Compruebe la red creada:

$ kubectl get network-attachment-definitions.k8s.cni.cncf.io -A -oyaml

apiVersion: v1
items:
- apiVersion: k8s.cni.cncf.io/v1
  kind: NetworkAttachmentDefinition
  metadata:
    annotations:
      k8s.v1.cni.cncf.io/resourceName: rancher.io/intelnicsDpdk
    creationTimestamp: "2023-06-08T11:22:27Z"
    generation: 1
    name: network-dpdk
    namespace: sriov-network-operator
    resourceVersion: "13124"
    uid: df7c89f5-177c-4f30-ae72-7aef3294fb15
  spec:
    config: '{ "cniVersion":"0.4.0", "name":"network-dpdk","type":"sriov","vlan":500,"vlanQoS":0,"ipam":{"type":"host-local","subnet":"192.168.0.0/24","rangeStart":"192.168.0.10","rangeEnd":"192.168.0.60","routes":[{"dst":"0.0.0.0/0"}],"gateway":"192.168.0.1"}
      }'
kind: List
metadata:
  resourceVersion: ""

41.6 DPDK

DPDK (Data Plane Development Kit, kit de desarrollo del plano de datos) es un conjunto de bibliotecas y controladores para el procesamiento rápido de paquetes. Se utiliza para acelerar las cargas de trabajo de procesamiento de paquetes que se ejecutan en una amplia variedad de arquitecturas de CPU. DPDK incluye bibliotecas de plano de datos y controladores de controlador de interfaz de red (NIC) optimizados para lo siguiente:

  1. Un gestor de colas implementa colas sin bloqueo.

  2. Un gestor de búferes preasigna búferes de tamaño fijo.

  3. Un gestor de memoria asigna pools de objetos en la memoria y usa un anillo para almacenar los objetos libres; esto garantiza que los objetos se distribuyan de forma equitativa en todos los canales DRAM.

  4. Los controladores en modo de sondeo (Poll mode drivers, PMD) están diseñados para funcionar sin notificaciones asíncronas, lo que reduce la sobrecarga.

  5. Un marco de paquetes como un conjunto de bibliotecas que sirven de ayuda para desarrollar el procesamiento de paquetes.

Los siguientes pasos muestran cómo habilitar DPDK y cómo crear funciones virtuales a partir de las NIC que se utilizarán en las interfaces de DPDK:

  • Instale el paquete de DPDK:

$ transactional-update pkg install dpdk dpdk-tools libdpdk-23
$ reboot
  • Parámetros del kernel:

Para usar DPDK, emplee algunos controladores para habilitar ciertos parámetros en el kernel:

ParámetroValorDescripción

iommu

pt

Esta opción permite el uso del controlador vfio para las interfaces de DPDK.

intel_iommu o amd_iommu

on

Esta opción permite el uso de vfio para las funciones virtuales.

Para habilitar los parámetros, añádalos al archivo /etc/default/grub:

GRUB_CMDLINE_LINUX="BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=77b713de-5cc7-4d4c-8fc6-f5eca0a43cf9 skew_tick=1 rd.timeout=60 rd.retry=45 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack intel_iommu=on iommu=pt irqaffinity=0,31,32,63 isolcpus=domain,nohz,managed_irq,1-30,33-62 nohz_full=1-30,33-62 nohz=on mce=off net.ifnames=0 nosoftlockup nowatchdog nmi_watchdog=0 quiet rcu_nocb_poll rcu_nocbs=1-30,33-62 rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll"

Actualice la configuración de GRUB y rearranque el sistema para aplicar los cambios:

$ transactional-update grub.cfg
$ reboot
  • Cargue el módulo del kernel vfio-pci y habilite SR-IOV en las tarjetas NIC:

$ modprobe vfio-pci enable_sriov=1 disable_idle_d3=1
  • Cree algunas funciones virtuales (VF) a partir de las tarjetas NIC.

Para crear funciones virtuales, por ejemplo, para dos NIC distintas, se requieren los siguientes comandos:

$ echo 4 > /sys/bus/pci/devices/0000:51:00.0/sriov_numvfs
$ echo 4 > /sys/bus/pci/devices/0000:51:00.1/sriov_numvfs
  • Vincule las nuevas funciones virtuales con el controlador vfio-pci:

$ dpdk-devbind.py -b vfio-pci 0000:51:01.0 0000:51:01.1 0000:51:01.2 0000:51:01.3 \
                              0000:51:11.0 0000:51:11.1 0000:51:11.2 0000:51:11.3
  • Compruebe que la configuración se haya aplicado correctamente:

$ dpdk-devbind.py -s

Network devices using DPDK-compatible driver
============================================
0000:51:01.0 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:01.1 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:01.2 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:01.3 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:01.0 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:11.1 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:21.2 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:31.3 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio

Network devices using kernel driver
===================================
0000:19:00.0 'BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet 1751' if=em1 drv=bnxt_en unused=igb_uio,vfio-pci *Active*
0000:19:00.1 'BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet 1751' if=em2 drv=bnxt_en unused=igb_uio,vfio-pci
0000:19:00.2 'BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet 1751' if=em3 drv=bnxt_en unused=igb_uio,vfio-pci
0000:19:00.3 'BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet 1751' if=em4 drv=bnxt_en unused=igb_uio,vfio-pci
0000:51:00.0 'Ethernet Controller E810-C for QSFP 1592' if=eth13 drv=ice unused=igb_uio,vfio-pci
0000:51:00.1 'Ethernet Controller E810-C for QSFP 1592' if=rename8 drv=ice unused=igb_uio,vfio-pci

41.7 Aceleración vRAN (Intel ACC100/ACC200)

A medida que los proveedores de servicios de comunicaciones pasan de las redes 4G a las 5G, muchos están adoptando arquitecturas de redes de acceso por radio virtualizadas (vRAN) para obtener una mayor capacidad de canal y facilitar el despliegue de servicios y aplicaciones basados en la periferia. Las soluciones vRAN son perfectas para ofrecer servicios de baja latencia con la flexibilidad de aumentar o disminuir la capacidad en función del volumen de tráfico en tiempo real y la demanda de la red.

Una de las cargas de trabajo de 4G y 5G que más recursos informáticos consume es la FEC de la capa 1 (L1) de la RAN, que resuelve los errores de transmisión de datos en canales de comunicación poco fiables o con ruido. La tecnología FEC detecta y corrige un número limitado de errores en los datos 4G o 5G, lo que elimina la necesidad de retransmisión. Dado que la transacción de aceleración de FEC no contiene información sobre el estado de las celdas, se puede virtualizar fácilmente, de forma que se puede aprovechar la agrupación y facilitar la migración de celdas.

  • Parámetros del kernel

Para habilitar la aceleración vRAN, es preciso habilitar los siguientes parámetros del kernel (si aún no están presentes):

ParámetroValorDescripción

iommu

pt

Esta opción permite el uso de vfio para las interfaces DPDK.

intel_iommu o amd_iommu

on

Esta opción permite el uso de vfio para las funciones virtuales.

Modifique el archivo GRUB /etc/default/grub para añadirlos a la línea de comandos del kernel:

GRUB_CMDLINE_LINUX="BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=77b713de-5cc7-4d4c-8fc6-f5eca0a43cf9 skew_tick=1 rd.timeout=60 rd.retry=45 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack intel_iommu=on iommu=pt irqaffinity=0,31,32,63 isolcpus=domain,nohz,managed_irq,1-30,33-62 nohz_full=1-30,33-62 nohz=on mce=off net.ifnames=0 nosoftlockup nowatchdog nmi_watchdog=0 quiet rcu_nocb_poll rcu_nocbs=1-30,33-62 rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll"

Actualice la configuración de GRUB y rearranque el sistema para aplicar los cambios:

$ transactional-update grub.cfg
$ reboot

Para verificar que los parámetros se han aplicado después del rearranque, compruebe la línea de comandos:

$ cat /proc/cmdline
  • Cargue los módulos del kernel vfio-pci para habilitar la aceleración vRAN:

$ modprobe vfio-pci enable_sriov=1 disable_idle_d3=1
  • Obtenga información de la interfaz Acc100:

$ lspci | grep -i acc
8a:00.0 Processing accelerators: Intel Corporation Device 0d5c
  • Vincule la interfaz física (PF) con el controlador vfio-pci:

$ dpdk-devbind.py -b vfio-pci 0000:8a:00.0
  • Cree las funciones virtuales (VF) a partir de la interfaz física (PF).

Cree dos VF desde la PF y vincúlelas con vfio-pci así:

$ echo 2 > /sys/bus/pci/devices/0000:8a:00.0/sriov_numvfs
$ dpdk-devbind.py -b vfio-pci 0000:8b:00.0
  • Configure acc100 con el archivo de configuración propuesto:

$ pf_bb_config ACC100 -c /opt/pf-bb-config/acc100_config_vf_5g.cfg
Tue Jun  6 10:49:20 2023:INFO:Queue Groups: 2 5GUL, 2 5GDL, 2 4GUL, 2 4GDL
Tue Jun  6 10:49:20 2023:INFO:Configuration in VF mode
Tue Jun  6 10:49:21 2023:INFO: ROM version MM 99AD92
Tue Jun  6 10:49:21 2023:WARN:* Note: Not on DDR PRQ version  1302020 != 10092020
Tue Jun  6 10:49:21 2023:INFO:PF ACC100 configuration complete
Tue Jun  6 10:49:21 2023:INFO:ACC100 PF [0000:8a:00.0] configuration complete!
  • Compruebe las nuevas funciones virtuales creadas desde la interfaz física FEC:

$ dpdk-devbind.py -s
Baseband devices using DPDK-compatible driver
=============================================
0000:8a:00.0 'Device 0d5c' drv=vfio-pci unused=
0000:8b:00.0 'Device 0d5d' drv=vfio-pci unused=

Other Baseband devices
======================
0000:8b:00.1 'Device 0d5d' unused=

41.8 Páginas enormes

Cuando un proceso utiliza RAM, la CPU lo marca como utilizado por ese proceso. Por motivos de eficiencia, la CPU asigna RAM en bloques de 4K bytes, que es el valor predeterminado en muchas plataformas. Esos bloques se denominan páginas. Las páginas se pueden intercambiar en el disco, etc.

Dado que el espacio de direcciones del proceso es virtual, la CPU y el sistema operativo deben recordar qué páginas pertenecen a cada proceso y dónde se almacena cada página. Cuanto más páginas haya, más tiempo llevará la búsqueda de asignación de memoria. Cuando un proceso usa 1 GB de memoria, eso supone 262 144 entradas que buscar (1 GB / 4 K). Si una entrada de la tabla de páginas consume 8 bytes, eso supone 2 MB (262 144 * 8) que buscar.

La mayoría de las arquitecturas actuales de CPU admiten páginas más grandes que las predeterminadas, lo que reduce el número de entradas que la CPU/SO debe buscar.

  • Parámetros del kernel

Para habilitar estas páginas enormes (huge pages), debemos añadir los siguientes parámetros del kernel. En este ejemplo, configuramos 40 páginas de 1 GB, aunque el tamaño de la página enorme y el número exacto de ellas deben adaptarse a los requisitos de memoria de su aplicación:

ParámetroValorDescripción

hugepagesz

1G

Esta opción permite establecer el tamaño de las páginas enormes en 1 G

hugepages

40

Este es el número de páginas enormes definidas anteriormente

default_hugepagesz

1G

Este es el valor predeterminado para obtener las páginas enormes

Modifique el archivo GRUB /etc/default/grub para añadir estos parámetros en GRUB_CMDLINE_LINUX:

default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0

Actualice la configuración de GRUB y rearranque el sistema para aplicar los cambios:

$ transactional-update grub.cfg
$ reboot

Para comprobar que los parámetros se han aplicado después del rearranque, puede consultar la línea de comandos:

$ cat /proc/cmdline
  • Uso de páginas enormes

Para usar las páginas enormes, debe montarlas:

$ mkdir -p /hugepages
$ mount -t hugetlbfs nodev /hugepages

Despliegue una carga de trabajo de Kubernetes creando los recursos y los volúmenes:

...
 resources:
   requests:
     memory: "24Gi"
     hugepages-1Gi: 16Gi
     intel.com/intel_sriov_oru: '4'
   limits:
     memory: "24Gi"
     hugepages-1Gi: 16Gi
     intel.com/intel_sriov_oru: '4'
...
...
volumeMounts:
  - name: hugepage
    mountPath: /hugepages
...
volumes:
  - name: hugepage
    emptyDir:
      medium: HugePages
...

41.9 Fijación de CPU en Kubernetes

41.9.1 Requisito previo

Debe tener la CPU ajustada al perfil de rendimiento descrito en esta sección (Sección 41.3, “Fijación de CPU mediante Tuned y argumentos del kernel”).

41.9.2 Configuración de Kubernetes para la fijación de CPU

Configure los argumentos de kubelet para implementar la gestión de la CPU en el clúster RKE2. Añada el siguiente bloque de configuración, como se muestra en el ejemplo siguiente, al archivo /etc/rancher/rke2/config.yaml. Asegúrese de especificar los núcleos de CPU de mantenimiento en los argumentos kubelet-reserved y system-reserved:

kubelet-arg:
- "cpu-manager-policy=static"
- "cpu-manager-policy-options=full-pcpus-only=true"
- "cpu-manager-reconcile-period=0s"
- "kubelet-reserved=cpu=0,31,32,63"
- "system-reserved=cpu=0,31,32,63"

41.9.3 Aprovechamiento de CPU fijadas para cargas de trabajo

Hay tres formas de utilizar esa función utilizando la directiva estática definida en kubelet, dependiendo de las solicitudes y los límites que defina en su carga de trabajo:

  1. Clase de calidad de servicio BestEffort: si no se define ninguna solicitud o límite para la CPU, el pod se programa en la primera CPU disponible en el sistema.

    Este es un ejemplo de uso de la clase de calidad de servicio BestEffort:

    spec:
      containers:
      - name: nginx
        image: nginx
  2. Clase de calidad de servicio Burstable: si se define una solicitud para la CPU que no se ajusta a los límites establecidos, o si no hay ninguna solicitud de CPU.

    Ejemplos de uso de la clase de calidad de servicio Burstable:

    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          limits:
            memory: "200Mi"
          requests:
            memory: "100Mi"

    o

    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          limits:
            memory: "200Mi"
            cpu: "2"
          requests:
            memory: "100Mi"
            cpu: "1"
  3. Clase de calidad de servicio Guaranteed: si define una solicitud de CPU que es igual a los límites.

    Ejemplo de uso de la clase de calidad de servicio Guaranteed:

    spec:
      containers:
        - name: nginx
          image: nginx
          resources:
            limits:
              memory: "200Mi"
              cpu: "2"
            requests:
              memory: "200Mi"
              cpu: "2"

41.10 Programación compatible con NUMA

El acceso a la memoria no uniforme o arquitectura de memoria no uniforme (NUMA) es un diseño de memoria física utilizado en la arquitectura SMP (multiprocesadores) en la que el tiempo de acceso a la memoria depende de la ubicación de la memoria con respecto al procesador. En NUMA, un procesador puede acceder a su propia memoria local más rápido que a la memoria no local; es decir, la memoria local de otro procesador o la memoria compartida entre procesadores.

41.10.1 Identificación de nodos NUMA

Para identificar los nodos NUMA, utilice el siguiente comando en su sistema:

$ lscpu | grep NUMA
NUMA node(s):                       1
NUMA node0 CPU(s):                  0-63
Nota
Nota

En este ejemplo, solo tenemos un nodo NUMA que muestra 64 CPU.

NUMA debe estar habilitado en el BIOS. Si dmesg no tiene registros de la inicialización de NUMA durante el arranque, es posible que los mensajes relacionados con NUMA del búfer del anillo del kernel se hayan sobrescrito.

41.11 MetalLB

MetalLB es una implementación de equilibrador de carga para clústeres bare metal de Kubernetes que utiliza protocolos de enrutamiento estándar como L2 y BGP como protocolos de anuncios. Se trata de un equilibrador de carga de red que se puede utilizar para exponer servicios de un clúster de Kubernetes al mundo exterior que necesite utilizar el tipo de servicios de Kubernetes LoadBalancer con bare metal.

Para habilitar MetalLB en el clúster RKE2, se deben seguir estos pasos:

  • Instale MetalLB con este comando:

$ kubectl apply <<EOF -f
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
---
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
EOF
  • Cree la configuración IpAddressPool y L2advertisement:

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: kubernetes-vip-ip-pool
  namespace: metallb-system
spec:
  addresses:
    - 10.168.200.98/32
  serviceAllocation:
    priority: 100
    namespaces:
      - default
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: ip-pool-l2-adv
  namespace: metallb-system
spec:
  ipAddressPools:
    - kubernetes-vip-ip-pool
  • Cree el servicio de punto final para exponer la IP virtual:

apiVersion: v1
kind: Service
metadata:
  name: kubernetes-vip
  namespace: default
spec:
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: rke2-api
    port: 9345
    protocol: TCP
    targetPort: 9345
  - name: k8s-api
    port: 6443
    protocol: TCP
    targetPort: 6443
  sessionAffinity: None
  type: LoadBalancer
  • Compruebe que se ha creado la IP virtual y que los pods de MetalLB se están ejecutando:

$ kubectl get svc -n default
$ kubectl get pods -n default

41.12 Configuración del registro privado

Es posible configurar Containerd para que se conecte a registros privados y los use para extraer imágenes privadas en cada nodo.

Durante el inicio, RKE2 comprueba si existe un archivo registries.yaml en /etc/rancher/rke2/ y ordena a containerd que use cualquier registro definido en el archivo. Si desea utilizar un registro privado, cree este archivo como usuario root en cada nodo que vaya a utilizar el registro.

Para añadir el registro privado, cree el archivo /etc/rancher/rke2/registries.yaml con el siguiente contenido:

mirrors:
  docker.io:
    endpoint:
      - "https://registry.example.com:5000"
configs:
  "registry.example.com:5000":
    auth:
      username: xxxxxx # this is the registry username
      password: xxxxxx # this is the registry password
    tls:
      cert_file:            # path to the cert file used to authenticate to the registry
      key_file:             # path to the key file for the certificate used to authenticate to the registry
      ca_file:              # path to the ca file used to verify the registry's certificate
      insecure_skip_verify: # may be set to true to skip verifying the registry's certificate

o sin autenticación:

mirrors:
  docker.io:
    endpoint:
      - "https://registry.example.com:5000"
configs:
  "registry.example.com:5000":
    tls:
      cert_file:            # path to the cert file used to authenticate to the registry
      key_file:             # path to the key file for the certificate used to authenticate to the registry
      ca_file:              # path to the ca file used to verify the registry's certificate
      insecure_skip_verify: # may be set to true to skip verifying the registry's certificate

Para que los cambios en el registro surtan efecto, debe configurar este archivo antes de iniciar RKE2 en el nodo, o bien reiniciar RKE2 en cada nodo configurado.

Nota
Nota

Para obtener más información, consulte containerd registry configuration rke2 (Configuración del registro containerd en RKE2).

41.13 Protocolo de tiempo de precisión (PTP)

El protocolo de tiempo de precisión (PTP) es un protocolo de red desarrollado por el IEEE (Instituto de Ingenieros Eléctricos y Electrónicos) para permitir la sincronización del tiempo en submicrosegundos en una red informática. Desde su creación y durante las últimas dos décadas, el PTP se ha utilizado en muchos sectores. Recientemente, se ha observado un aumento de su adopción en las redes de telecomunicaciones como elemento fundamental para las redes 5G. Aunque se trata de un protocolo relativamente sencillo, su configuración puede variar significativamente en función de la aplicación. Por ese motivo, se han definido y estandarizado múltiples perfiles.

En esta sección solo se tratan los perfiles específicos de telecomunicaciones. Por lo tanto, se dará por sentado que la NIC cuenta con capacidad de marcación de tiempo y con un reloj de hardware PTP (PHC). Hoy en día, todos los adaptadores de red para telecomunicaciones incluyen compatibilidad con PTP en el hardware, pero puede verificarlo con el siguiente comando:

# ethtool -T p1p1
Time stamping parameters for p1p1:
Capabilities:
        hardware-transmit
        software-transmit
        hardware-receive
        software-receive
        software-system-clock
        hardware-raw-clock
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
        off
        on
Hardware Receive Filter Modes:
        none
        all

Sustituya p1p1 por el nombre de la interfaz que se utilizará para PTP.

Las siguientes secciones explican cómo instalar y configurar PTP en SUSE Edge específicamente, pero se espera que el usuario esté familiarizado con los conceptos básicos de PTP. Para obtener una breve descripción general de PTP y la implementación incluida en SUSE Edge for Telco, consulte https://documentation.suse.com/sles/html/SLES-all/cha-tuning-ptp.html.

41.13.1 Instalación de los componentes de software de PTP

En SUSE Edge for Telco, la implementación de PTP la proporciona el paquete linuxptp, que incluye dos componentes:

  • ptp4l: un daemon que controla el PHC en la NIC y ejecuta el protocolo PTP

  • phc2sys: un daemon que mantiene el reloj del sistema sincronizado con el PHC sincronizado por PTP en la NIC

Ambos daemons son necesarios para que la sincronización del sistema funcione correctamente y deben estar configurados adecuadamente según su configuración. Esto se explica en la Sección 41.13.2, “Configuración de PTP para despliegues de telecomunicaciones”.

La mejor manera, y la más fácil, de integrar PTP en su clúster descendente es añadir el paquete linuxptp en packageList en el archivo de definición de Edge Image Builder (EIB). De esta forma, el software del plano de control de PTP se instalará automáticamente durante el aprovisionamiento del clúster. Consulte la documentación de EIB (Sección 3.3.4, “Configuración de paquetes RPM”) para obtener más información sobre la instalación de paquetes.

Esto es un ejemplo de manifiesto de EIB con linuxptp:

apiVersion: 1.0
image:
  imageType: RAW
  arch: x86_64
  baseImage: {micro-base-rt-image-raw}
  outputImageName: eibimage-slmicrort-telco.raw
operatingSystem:
  time:
    timezone: America/New_York
  kernelArgs:
    - ignition.platform.id=openstack
    - net.ifnames=1
  systemd:
    disable:
      - rebootmgr
      - transactional-update.timer
      - transactional-update-cleanup.timer
      - fstrim
      - time-sync.target
    enable:
      - ptp4l
      - phc2sys
  users:
    - username: root
      encryptedPassword: ${ROOT_PASSWORD}
  packages:
    packageList:
      - jq
      - dpdk
      - dpdk-tools
      - libdpdk-23
      - pf-bb-config
      - open-iscsi
      - tuned
      - cpupower
      - linuxptp
    sccRegistrationCode: ${SCC_REGISTRATION_CODE}
Nota
Nota

El paquete linuxptp incluido en SUSE Edge for Telco no habilita ptp4l ni phc2sys de forma predeterminada. Si sus archivos de configuración específicos del sistema se despliegan en el momento del aprovisionamiento (consulte la Sección 41.13.3, “Integración de Cluster API”), deben habilitarse. Para ello, añádalos a la sección systemd del manifiesto, como en el ejemplo anterior.

Siga el proceso habitual para crear la imagen que se describe en la documentación de EIB (Sección 3.4, “Creación de la imagen”) y utilícela para desplegar su clúster. Si no tiene experiencia con EIB, comience por el Capítulo 11, Edge Image Builder.

41.13.2 Configuración de PTP para despliegues de telecomunicaciones

Muchas aplicaciones de telecomunicaciones requieren una sincronización estricta de fase y tiempo con poca desviación. Por eso, se definieron dos perfiles orientados a las telecomunicaciones: el ITU-T G.8275.1 y el ITU-T G.8275.2. Ambos tienen una alta tasa de mensajes de sincronización y otras características distintivas, como el uso de un algoritmo de reloj maestro óptimo (BMCA) alternativo. Este comportamiento exige ajustes específicos en el archivo de configuración utilizado por ptp4l, que se proporcionan en las siguientes secciones como referencia.

Nota
Nota
  • Ambas secciones solo cubren el caso de un reloj normal con una configuración de recepción de hora.

  • Los perfiles de este tipo deben utilizarse en una infraestructura PTP bien planificada.

  • Es posible que su red PTP específica requiera ajustes de configuración adicionales. Asegúrese de revisar y adaptar los ejemplos proporcionados si es necesario.

41.13.2.1 Perfil ITU-T G.8275.1 de PTP

El perfil G.8275.1 tiene las siguientes especificaciones:

  • Se ejecuta directamente en Ethernet y requiere soporte de red completo (los nodos/conmutadores adyacentes deben ser compatibles con PTP).

  • La configuración predeterminada del dominio es 24.

  • La comparación de conjuntos de datos se basa en el algoritmo G.8275.x y sus valores localPriority después de priority2.

Copie el siguiente contenido en un archivo llamado /etc/ptp4l-G.8275.1.conf:

# Telecom G.8275.1 example configuration
[global]
domainNumber                    24
priority2			255
dataset_comparison              G.8275.x
G.8275.portDS.localPriority     128
G.8275.defaultDS.localPriority  128
maxStepsRemoved                 255
logAnnounceInterval             -3
logSyncInterval                 -4
logMinDelayReqInterval          -4
announceReceiptTimeout		3
serverOnly                      0
ptp_dst_mac                     01:80:C2:00:00:0E
network_transport               L2

Una vez creado el archivo, debe hacerse referencia a él en /etc/sysconfig/ptp4l para que el daemon se inicie correctamente. Puede hacerlo cambiando la línea OPTIONS= por:

OPTIONS="-f /etc/ptp4l-G.8275.1.conf -i $IFNAME --message_tag ptp-8275.1"

En concreto:

  • -f requiere el nombre del archivo de configuración que se va a utilizar; en este caso, /etc/ptp4l-G.8275.1.conf.

  • -i requiere el nombre de la interfaz que se va a utilizar. Sustituya $IFNAME por el nombre real de la interfaz.

  • --message_tag permite identificar mejor la salida de ptp4l en los registros del sistema y es opcional.

Una vez completados los pasos anteriores, se debe (re)iniciar el daemon ptp4l:

# systemctl restart ptp4l

Compruebe el estado de sincronización observando los registros con:

# journalctl -e -u ptp4l

41.13.2.2 Perfil ITU-T G.8275.2 de PTP

El perfil G.8275.2 tiene las siguientes especificaciones:

  • Funciona con IP y no requiere soporte de red completo (los nodos/conmutadores adyacentes pueden no ser compatibles con PTP).

  • La configuración predeterminada del dominio es 44.

  • La comparación de conjuntos de datos se basa en el algoritmo G.8275.x y sus valores localPriority después de priority2.

Copie el siguiente contenido en un archivo llamado /etc/ptp4l-G.8275.2.conf:

# Telecom G.8275.2 example configuration
[global]
domainNumber                    44
priority2			255
dataset_comparison              G.8275.x
G.8275.portDS.localPriority     128
G.8275.defaultDS.localPriority  128
maxStepsRemoved                 255
logAnnounceInterval             0
serverOnly                      0
hybrid_e2e                      1
inhibit_multicast_service       1
unicast_listen                  1
unicast_req_duration            60
logSyncInterval                 -5
logMinDelayReqInterval          -4
announceReceiptTimeout		2
#
# Customize the following for slave operation:
#
[unicast_master_table]
table_id                        1
logQueryInterval                2
UDPv4                           $PEER_IP_ADDRESS
[$IFNAME]
unicast_master_table            1

Asegúrese de sustituir los siguientes marcadores de posición:

  • $PEER_IP_ADDRESS: la dirección IP del siguiente nodo PTP con el que se va a comunicar, como el reloj maestro o el reloj fronterizo que proporcionará la sincronización.

  • $IFNAME: indica a ptp4l qué interfaz debe utilizar para PTP.

Una vez creado el archivo, debe referenciarse en /etc/sysconfig/ptp4l junto con el nombre de la interfaz que se utilizará para PTP para que el daemon se inicie correctamente. Puede hacerlo cambiando la línea OPTIONS= por:

OPTIONS="-f /etc/ptp4l-G.8275.2.conf --message_tag ptp-8275.2"

En concreto:

  • -f requiere el nombre del archivo de configuración que se va a utilizar. En este caso, es /etc/ptp4l-G.8275.2.conf.

  • --message_tag permite identificar mejor la salida de ptp4l en los registros del sistema y es opcional.

Una vez completados los pasos anteriores, se debe (re)iniciar el daemon ptp4l:

# systemctl restart ptp4l

Compruebe el estado de sincronización observando los registros con:

# journalctl -e -u ptp4l

41.13.2.3 Configuración de phc2sys

Aunque no es obligatorio, se recomienda completar totalmente la configuración de ptp4l antes de pasar a phc2sys. phc2sys no requiere un archivo de configuración y sus parámetros de ejecución se pueden controlar únicamente a través de la variable OPTIONS= presente en /etc/sysconfig/ptp4l, de forma similar a ptp4l:

OPTIONS="-s $IFNAME -w"

Donde $IFNAME es el nombre de la interfaz ya configurada en ptp4l que se utilizará como fuente para el reloj del sistema. Esto se utiliza para identificar la fuente de PHC.

41.13.3 Integración de Cluster API

Cada vez que se despliega un clúster mediante un clúster de gestión y un aprovisionamiento de red dirigido, tanto el archivo de configuración como las dos variables de configuración de /etc/sysconfig se pueden desplegar en el host en el momento del aprovisionamiento. A continuación, se muestra un extracto de una definición de clúster, centrado en un objeto RKE2ControlPlane modificado que despliega el mismo archivo de configuración G.8275.1 en todos los hosts:

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
  registrationMethod: "control-plane-endpoint"
  serverConfig:
    cni: canal
  agentConfig:
    format: ignition
    cisProfile: cis
    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:
            - path: /etc/ptp4l-G.8275.1.conf
              overwrite: true
              contents:
                inline: |
                  # Telecom G.8275.1 example configuration
                  [global]
                  domainNumber                    24
                  priority2                       255
                  dataset_comparison              G.8275.x
                  G.8275.portDS.localPriority     128
                  G.8275.defaultDS.localPriority  128
                  maxStepsRemoved                 255
                  logAnnounceInterval             -3
                  logSyncInterval                 -4
                  logMinDelayReqInterval          -4
                  announceReceiptTimeout          3
                  serverOnly                      0
                  ptp_dst_mac                     01:80:C2:00:00:0E
                  network_transport               L2
              mode: 0644
              user:
                name: root
              group:
                name: root
            - path: /etc/sysconfig/ptp4l
              overwrite: true
              contents:
                inline: |
                  ## Path:           Network/LinuxPTP
                  ## Description:    Precision Time Protocol (PTP): ptp4l settings
                  ## Type:           string
                  ## Default:        "-i eth0 -f /etc/ptp4l.conf"
                  ## ServiceRestart: ptp4l
                  #
                  # Arguments when starting ptp4l(8).
                  #
                  OPTIONS="-f /etc/ptp4l-G.8275.1.conf -i $IFNAME --message_tag ptp-8275.1"
              mode: 0644
              user:
                name: root
              group:
                name: root
            - path: /etc/sysconfig/phc2sys
              overwrite: true
              contents:
                inline: |
                  ## Path:           Network/LinuxPTP
                  ## Description:    Precision Time Protocol (PTP): phc2sys settings
                  ## Type:           string
                  ## Default:        "-s eth0 -w"
                  ## ServiceRestart: phc2sys
                  #
                  # Arguments when starting phc2sys(8).
                  #
                  OPTIONS="-s $IFNAME -w"
              mode: 0644
              user:
                name: root
              group:
                name: root
    kubelet:
      extraArgs:
        - provider-id=metal3://BAREMETALHOST_UUID
    nodeName: "localhost.localdomain"

Además de otras variables, la definición anterior debe completarse con el nombre de la interfaz y con los demás objetos de Cluster API, como se describe en el Capítulo 42, Aprovisionamiento de red dirigida totalmente automatizado.

Nota
Nota
  • Este enfoque solo resulta útil si el hardware del clúster es uniforme y se necesita la misma configuración en todos los hosts, incluido el nombre de la interfaz.

  • Existen enfoques alternativos que se tratarán en futuras versiones.

En este punto, los hosts deberían tener una pila PTP operativa y en ejecución, y comenzarán a negociar su función PTP.

42 Aprovisionamiento de red dirigida totalmente automatizado

42.1 Introducción

El aprovisionamiento de red dirigida es una función que permite automatizar el aprovisionamiento de clústeres descendentes. Esta función resulta útil cuando hay muchos clústeres descendentes que aprovisionar y se desea automatizar el proceso.

Un clúster de gestión (Capítulo 40, Configuración del clúster de gestión) automatiza el despliegue de los siguientes componentes:

  • SUSE Linux Micro RT como sistema operativo. Dependiendo del caso de uso, se pueden personalizar ajustes como las redes, el almacenamiento, los usuarios y los argumentos del kernel.

  • RKE2 como clúster de Kubernetes. El complemento de CNI predeterminado es Cilium. Dependiendo del caso práctico, se pueden usar determinados complementos de CNI, como Cilium+Multus.

  • SUSE Storage

  • SUSE Security

  • MetalLB se puede usar como equilibrador de carga para clústeres de varios nodos de alta disponibilidad.

Nota
Nota

Para obtener más información sobre SUSE Linux Micro, consulte el Capítulo 9, SUSE Linux Micro. Para obtener más información sobre RKE2, consulte el Capítulo 16, RKE2. Para obtener más información sobre SUSE Storage, consulte el Capítulo 17, SUSE Storage. Para obtener más información sobre SUSE Security, consulte el Capítulo 18, SUSE Security.

Las siguientes secciones describen los diferentes flujos de trabajo de aprovisionamiento de red dirigida y algunas características adicionales que se pueden añadir al proceso de aprovisionamiento:

Nota
Nota

Las siguientes secciones muestran cómo preparar los diferentes escenarios para el flujo de trabajo de aprovisionamiento de red dirigida utilizando SUSE Edge for Telco. Para ver ejemplos de las diferentes opciones de configuración para el despliegue (incluidos entornos aislados, redes con DHCP y sin DHCP, registros de contenedores privados, etc.), consulte el repositorio de SUSE Edge for Telco.

42.2 Preparación de la imagen del clúster descendente para entornos conectados

Edge Image Builder (Capítulo 11, Edge Image Builder) se utiliza para preparar una imagen base de SLEMicro modificada que se aprovisiona en los hosts del clúster descendente.

Gran parte de la configuración se puede realizar con Edge Image Builder, pero en esta guía cubrimos las configuraciones mínimas necesarias para configurar el clúster descendente.

42.2.1 Requisitos previos para entornos conectados

  • Se requiere un entorno de ejecución de contenedores como Podman o Rancher Desktop para ejecutar Edge Image Builder.

  • La imagen base se creará con las instrucciones del Capítulo 28, Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi y el perfil Base-SelfInstall (o Base-RT-SelfInstall para el kernel en tiempo real). El proceso es el mismo para ambas arquitecturas (x86-64 y aarch64).

  • Para desplegar clústeres descendentes aarch64, antes del despliegue del clúster de gestión debe definir el parámetro deployArchitecture: arm64 en el archivo metal3.yaml, lo que se explica en la documentación del clúster de gestión (???). Esto es necesario para garantizar que se utiliza la arquitectura correcta para el clúster descendente.

Nota
Nota

Es necesario utilizar un host de creación con la misma arquitectura que las imágenes que se están creando. En otras palabras, para crear una imagen aarch64, es necesario utilizar un host de creación aarch64, y lo mismo ocurre para x86-64 (actualmente, no se admiten creaciones con arquitecturas cruzadas).

42.2.2 Configuración de la imagen para entornos conectados

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 usados para definir la imagen de destino.

  • downstream-cluster-config.yaml es el archivo de definición de la imagen. Consulte el Capítulo 3, Clústeres independientes con Edge Image Builder para obtener más detalles.

  • La carpeta de imágenes base contendrá la imagen raw generada al seguir las instrucciones del Capítulo 28, Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi con el perfil Base-SelfInstall (o Base-RT-SelfInstall para el kernel en tiempo real) y deberá copiarse/moverse a la carpeta base-images.

  • La carpeta network es opcional. Para obtener más información, consulte la Sección 42.2.2.6, “Guion adicional para la configuración avanzada de red”.

  • El directorio custom/scripts contiene guiones que se deben ejecutar en el primer arranque:

    1. El guion 01-fix-growfs.sh es necesario para cambiar el tamaño de la partición raíz del sistema operativo durante el despliegue.

    2. El guion 02-performance.sh es opcional y se puede usar para configurar el sistema con el fin de optimizar su rendimiento.

    3. El guion 03-sriov.sh es opcional y se puede usar para configurar el sistema para SR-IOV.

  • El directorio custom/files contiene los archivos performance-settings.sh y sriov-auto-filler.sh que se copiarán en la imagen durante el proceso de creación de la imagen.

├── 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 Archivo de definición de la imagen del clúster descendente

El archivo downstream-cluster-config.yaml es el principal archivo de configuración para la imagen del clúster descendente. A continuación, se muestra un ejemplo mínimo de despliegue mediante 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

Donde $SCC_REGISTRATION_CODE es el código de registro copiado del Centro de servicios al cliente de SUSE, y la lista de paquetes contiene jq, que es necesario.

$ROOT_PASSWORD es la contraseña cifrada del usuario root, que puede ser útil para pruebas y depuración. Se puede generar con el comando openssl passwd -6 PASSWORD.

En entornos de producción, se recomienda usar las claves SSH que se pueden añadir al bloque de usuarios sustituyendo $USERKEY1 por las claves SSH reales.

Nota
Nota

arch: x86_64 es la arquitectura de la imagen. Para la arquitectura arm64, utilice arch: aarch64.

net.ifnames=1 permite los nombres predecibles para las interfaces de red

Esto coincide con la configuración predeterminada para el chart de metal3, pero el ajuste debe coincidir con el valor de predictableNicNames configurado en el chart.

Tenga en cuenta también que ignition.platform.id=openstack es obligatorio. Sin este argumento, la configuración de SLEMicro mediante Ignition fallará en el flujo automatizado de Metal3.

42.2.2.2 Guion Growfs

Actualmente, se requiere un guion 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 después del aprovisionamiento. El guion 01-fix-growfs.sh contiene la siguiente información:

#!/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 Guion performance

El siguiente guion opcional (custom/scripts/02-performance.sh) se puede usar para configurar el sistema a fin de optimizar su rendimiento:

#!/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/

El contenido de custom/files/performance-settings. sh es un guion que se puede usar para configurar el sistema con el fin de optimizar su rendimiento, y se puede descargar desde el siguiente enlace.

42.2.2.4 Guion SR-IOV

El siguiente guion opcional (custom/scripts/03-sriov.sh) se puede usar para configurar el 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

El contenido de custom/files/ sriov-auto-filler.sh es un guion que se puede usar para configurar el sistema para SR-IOV, y se puede descargar desde el siguiente enlace.

Nota
Nota

Use el mismo método para añadir sus propios guiones personalizados que se ejecuten durante el proceso de aprovisionamiento. Para obtener más información, consulte el Capítulo 3, Clústeres independientes con Edge Image Builder.

42.2.2.5 Configuración adicional para cargas de trabajo de telecomunicaciones

Para habilitar funciones de telecomunicaciones como dpdk, sr-iov o FEC, es posible que se requieran paquetes adicionales, como se muestra en el siguiente ejemplo.

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

Donde $SCC_REGISTRATION_CODE es el código de registro copiado del Centro de servicios al cliente de SUSE, y la lista de paquetes contiene los paquetes mínimos que se utilizarán para los perfiles de telecomunicaciones.

Nota
Nota

arch: x86_64 es la arquitectura de la imagen. Para la arquitectura arm64, utilice arch: aarch64.

42.2.2.6 Guion adicional para la configuración avanzada de red

Si necesita configurar direcciones IP estáticas o escenarios de red más avanzados, como se describe en la Sección 42.6, “Configuración de red avanzada”, se requiere la siguiente configuración adicional.

En la carpeta network, cree el siguiente archivo configure-network.sh. Este archivo consume los datos de la unidad de configuración durante 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

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 Creación de la imagen

Cuando se haya preparado la estructura de directorios siguiendo las secciones anteriores, ejecute el siguiente comando para crear la imagen:

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

Esto crea el archivo de imagen ISO de salida denominado eibimage-output-telco.raw, basado en la definición descrita anteriormente.

La imagen resultante debe estar disponible a través de un servidor Web, ya sea el contenedor del servidor de medios habilitado en los pasos descritos en la sección sobre el clúster de gestión (Nota) o algún otro servidor al que se pueda acceder localmente. En los ejemplos siguientes, nos referimos a este servidor como imagecache.local:8080.

42.3 Preparación de la imagen del clúster descendente para entornos aislados

Edge Image Builder (Capítulo 11, Edge Image Builder) se utiliza para preparar una imagen base de SLEMicro modificada que se aprovisiona en los hosts del clúster descendente.

Gran parte de la configuración se puede realizar con Edge Image Builder, pero en esta guía tratamos las configuraciones mínimas necesarias para configurar el clúster descendente en entornos aislados.

42.3.1 Requisitos previos para entornos aislados

  • Se requiere un entorno de ejecución de contenedores como Podman o Rancher Desktop para ejecutar Edge Image Builder.

  • La imagen base se creará con las instrucciones del Capítulo 28, Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi y el perfil Base-SelfInstall (o Base-RT-SelfInstall para el kernel en tiempo real). El proceso es el mismo para ambas arquitecturas (x86-64 y aarch64).

  • Para desplegar clústeres descendentes aarch64, antes del despliegue del clúster de gestión debe definir el parámetro deployArchitecture: arm64 en el archivo metal3.yaml, lo que se explica en la documentación del clúster de gestión (???). Esto es necesario para garantizar que se utiliza la arquitectura correcta para el clúster descendente.

  • Si desea utilizar SR-IOV o cualquier otra carga de trabajo que requiera una imagen de contenedor, debe desplegar y configurar previamente un registro privado local (con o sin TLS y/o autenticación). Este registro se utilizará para almacenar las imágenes y las imágenes OCI del chart de Helm.

Nota
Nota

Es necesario utilizar un host de creación con la misma arquitectura que las imágenes que se están creando. En otras palabras, para crear una imagen aarch64, es necesario utilizar un host de creación aarch64, y lo mismo ocurre para x86-64 (actualmente, no se admiten creaciones con arquitecturas cruzadas).

42.3.2 Configuración de la imagen para entornos aislados

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 usados para definir la imagen de destino.

  • downstream-cluster-airgap-config.yaml es el archivo de definición de la imagen. Para obtener más información, consulte el Capítulo 3, Clústeres independientes con Edge Image Builder.

  • La carpeta de imágenes base contendrá la imagen raw generada al seguir las instrucciones del Capítulo 28, Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi con el perfil Base-SelfInstall (o Base-RT-SelfInstall para el kernel en tiempo real) y deberá copiarse/moverse a la carpeta base-images.

  • La carpeta network es opcional. Para obtener más información, consulte la Sección 42.2.2.6, “Guion adicional para la configuración avanzada de red”.

  • El directorio custom/scripts contiene guiones que se deben ejecutar en el primer arranque:

    1. El guion 01-fix-growfs.sh es necesario para cambiar el tamaño de la partición raíz del sistema operativo durante el despliegue.

    2. El guion 02-airgap.sh es necesario para copiar las imágenes en el lugar correcto durante el proceso de creación de imágenes para entornos aislados.

    3. El guion 03-performance.sh es opcional y se puede usar para configurar el sistema con el fin de optimizar su rendimiento.

    4. El guion 04-sriov.sh es opcional y se puede usar para configurar el sistema para SR-IOV.

  • El directorio custom/files contiene las imágenes rke2 y cni que se copiarán en la imagen durante el proceso de creación de la imagen. Además, se pueden incluir los archivos opcionales performance-settings.sh y 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 Archivo de definición de la imagen del clúster descendente

El archivo downstream-cluster-airgap-config.yaml es el archivo de configuración principal para la imagen del clúster descendente y su contenido se ha descrito en la sección anterior (Sección 42.2.2.5, “Configuración adicional para cargas de trabajo de telecomunicaciones”).

42.3.2.2 Guion Growfs

Actualmente, se requiere un guion 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 después del aprovisionamiento. El guion 01-fix-growfs.sh contiene la siguiente información:

#!/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 Guion air-gap

El siguiente guion (custom/scripts/02-airgap.sh) es necesario para copiar las imágenes en el lugar correcto durante el proceso de creación de la imagen:

#!/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 Guion performance

El siguiente guion opcional (custom/scripts/03-performance.sh) se puede usar para configurar el sistema con el fin de optimizar su rendimiento:

#!/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/

El contenido de custom/files/performance-settings. sh es un guion que se puede usar para configurar el sistema con el fin de optimizar su rendimiento, y se puede descargar desde el siguiente enlace.

42.3.2.5 Guion SR-IOV

El siguiente guion opcional (custom/scripts/04-sriov.sh) se puede usar para configurar el 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

El contenido de custom/files/ sriov-auto-filler.sh es un guion que se puede usar para configurar el sistema para SR-IOV, y se puede descargar desde el siguiente enlace.

42.3.2.6 Archivos personalizados para entornos aislados

El directorio custom/files contiene las imágenes rke2 y cni que se copiarán en la imagen durante el proceso de creación de la imagen. Para generar fácilmente las imágenes, prepárelas localmente utilizando el siguiente guion y la lista de imágenes que encontrará aquí para generar los artefactos que deben incluirse en custom/files. Además, puede descargar el guion rke2-install más reciente desde aquí.

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

Después de descargar las imágenes, la estructura de directorios debería tener este aspecto:

└── 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 Carga previa del registro privado con las imágenes necesarias para situaciones de entornos aislados y SR-IOV (opcional)

Si desea utilizar SR-IOV en un entorno aislado o en cualquier otra imagen de carga de trabajo, debe cargar previamente su registro privado local con las imágenes siguiendo estos pasos:

  • Descargar, extraer y enviar las imágenes OCI del chart de Helm al registro privado

  • Descargar, extraer y enviar el resto de imágenes necesarias al registro privado

Los guiones siguientes se pueden usar para descargar, extraer y enviar las imágenes al registro privado. Mostraremos un ejemplo para precargar las imágenes de SR-IOV, pero también puede usar el mismo método para cargar previamente cualquier otra imagen personalizada:

  1. Realice la carga previa con imágenes OCI del chart de Helm para SR-IOV:

    1. Debe crear una lista con las imágenes OCI del chart de Helm necesarias:

      $ 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. Genere un archivo tarball local utilizando el siguiente guion y la lista creada anteriormente:

      $ ./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. Suba el archivo tarball a su registro privado (por ejemplo, myregistry:5000) usando el guion siguiente para cargar previamente su registro con las imágenes OCI del chart de Helm descargadas en el paso anterior:

      $ tar zxvf edge-release-oci-tgz-20240705.tgz
      $ ./edge-load-oci-artefacts.sh -ad edge-release-oci-tgz-20240705 -r myregistry:5000
  2. Realice la carga previa del resto de las imágenes necesarias para SR-IOV:

    1. En este caso, debemos incluir las imágenes de contenedor sr-iov para cargas de trabajo de telecomunicaciones (por ejemplo, como referencia, puede obtenerlas de los valores del chart de 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. Con el guion siguiente y la lista creada anteriormente, debe generar localmente el archivo tarball con las imágenes necesarias:

      $ ./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. Suba el archivo tarball a su registro privado (por ejemplo, myregistry:5000) usando el guion siguiente para precargar su registro privado con las imágenes descargadas en el paso 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 Creación de la imagen para entornos aislados

Cuando se haya preparado la estructura de directorios siguiendo las secciones anteriores, ejecute el siguiente comando para crear la imagen:

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

Esto crea el archivo de imagen ISO de salida denominado eibimage-output-telco.raw, basado en la definición descrita anteriormente.

La imagen resultante debe estar disponible a través de un servidor Web, ya sea el contenedor del servidor de medios habilitado siguiendo los pasos de la sección sobre el clúster de gestión (Nota) o algún otro servidor al que se pueda acceder localmente. En los ejemplos siguientes, nos referimos a este servidor como imagecache.local:8080.

42.4 Aprovisionamiento de clústeres descendentes con aprovisionamiento de red dirigida (nodo único)

En esta sección se describe el flujo de trabajo usado para automatizar el aprovisionamiento de un clúster descendente de un solo nodo con el método de aprovisionamiento de red dirigida. Se trata de la forma más sencilla de automatizar el aprovisionamiento de un clúster descendente.

Requisitos

Flujo de trabajo

El diagrama siguiente muestra el flujo de trabajo usado para automatizar el aprovisionamiento de un clúster descendente de un solo nodo con el método de aprovisionamiento de red dirigida:

atip automatizado de un solo nodo 1

Hay dos pasos diferentes para automatizar el aprovisionamiento de un clúster descendente de un solo nodo con el método de aprovisionamiento de red dirigida:

  1. Inscribir el host bare metal para que esté disponible para el proceso de aprovisionamiento.

  2. Proporcionar el host bare metal para instalar y configurar el sistema operativo y el clúster de Kubernetes.

Inscripción del host bare metal

El primer paso es inscribir el nuevo host bare metal en el clúster de gestión para que esté disponible para su aprovisionamiento. Para ello, se debe crear el archivo bmh-example.yaml en el clúster de gestión, con el fin de especificar las credenciales de BMC que se van a utilizar y el objeto BaremetalHost que se va a inscribir:

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

Donde:

  • ${BMC_USERNAME}: es el nombre de usuario del BMC del nuevo host bare metal.

  • ${BMC_PASSWORD}: es la contraseña para el BMC del nuevo host bare metal.

  • ${BMC_MAC}: es la dirección MAC del nuevo host bare metal que se va a utilizar.

  • ${BMC_ADDRESS}: es la URL del host bare metal de BMC (por ejemplo, redfish-virtualmedia://192.168.200.75/redfish/v1/Systems/1/). Para obtener más información sobre las opciones disponibles en función de su proveedor de hardware, consulte el siguiente enlace.

Nota
Nota

Si no se ha especificado ninguna configuración de red para el host, ya sea en el momento de la creación de la imagen o en la definición BareMetalHost, se utilizará un mecanismo de configuración automática (DHCP, DHCPv6 o SLAAC). Para obtener más detalles o configuraciones complejas, consulte la Sección 42.6, “Configuración de red avanzada”.

Una vez creado el archivo, se debe ejecutar el siguiente comando en el clúster de gestión para comenzar a inscribir el nuevo host bare metal en el clúster de gestión:

$ kubectl apply -f bmh-example.yaml

El nuevo objeto host bare metal se inscribirá y cambiará su estado de "registering" (en registro) a "inspecting" (en inspección) y "available" (disponible). Los cambios se pueden comprobar con el siguiente comando:

$ kubectl get bmh
Nota
Nota

El objeto BaremetalHost permanece en estado registering (en registro) hasta que se validan las credenciales de BMC. Una vez validadas las credenciales, el objeto BaremetalHost cambia su estado a inspecting (en inspección), y este paso puede tardar algún tiempo dependiendo del hardware (hasta 20 minutos). Durante la fase de inspección, se recupera la información del hardware y se actualiza el objeto de Kubernetes. Compruebe la información con el siguiente comando: kubectl get bmh -o yaml.

Paso de aprovisionamiento

Una vez que el host bare metal está inscrito y disponible, el paso siguiente es aprovisionar el host bare metal para instalar y configurar el sistema operativo y el clúster de Kubernetes. Para ello, se debe crear el archivo capi-provisioning-example.yaml en el clúster de gestión con la siguiente información (el archivo capi-provisioning-example.yaml se puede generar uniendo los bloques siguientes).

Nota
Nota

Solo los valores entre $\{…​\} deben sustituirse por los valores reales.

El siguiente bloque es la definición del clúster, donde se puede configurar la red utilizando los bloques pods y services. Además, contiene las referencias al plano de control y a los objetos de infraestructura (utilizando el proveedor de Metal3) que se van a utilizar.

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 un despliegue con pods y servicios de doble pila, se puede utilizar la siguiente definición en su lugar:

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

Los despliegues de IPv6 y doble pila se encuentran en fase de tecnología en fase preliminar y no son compatibles oficialmente.

El objeto Metal3Cluster especifica el punto final del plano de control (en sustitución de ${DOWNSTREAM_CONTROL_PLANE_IP}) que se va a configurar y el objeto noCloudProvider, ya que se utiliza un nodo 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

El objeto RKE2ControlPlane especifica la configuración de plano de control que se va a utilizar y el objeto Metal3MachineTemplate especifica la imagen de plano de control que se va a utilizar. Además, contiene la información sobre el número de réplicas que se utilizarán (en este caso, una) y el complemento de CNI que se usará (en este caso, Cilium). El bloque agentConfig contiene el formato de Ignition que se va a usar y el objeto additionalUserData que se va a usar para configurar el nodo RKE2 con información como un servicio systemd denominado rke2-preinstall.service para sustituir automáticamente BAREMETALHOST_UUID y node-name durante el proceso de aprovisionamiento utilizando la información de Ironic. Para habilitar Multus con Cilium, se crea un archivo en el directorio de manifiestos del servidor rke2 llamado rke2-cilium-config.yaml con la configuración que se va a usar. El último bloque de información contiene la versión de Kubernetes que se va a usar. ${RKE2_VERSION} es la versión de RKE2 que se va a usar en sustitución de este valor (por ejemplo, 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"

El objeto Metal3MachineTemplate especifica la información siguiente:

  • La plantilla de datos (dataTemplate) que se usará como referencia para la plantilla.

  • El selector de host (hostSelector) que se usará que coincida con la etiqueta creada durante el proceso de inscripción.

  • La imagen (image) que se usará como referencia para la imagen generada mediante EIB en la sección anterior (Sección 42.2, “Preparación de la imagen del clúster descendente para entornos conectados”), y la suma de comprobación (checksum) y el tipo de suma (checksumType) que se usarán para validar la imagen.

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

El objeto Metal3DataTemplate especifica los metadatos (metaData) para el clúster descendente.

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

Una vez creado el archivo uniendo los bloques anteriores, se debe ejecutar el comando siguiente en el clúster de gestión para iniciar el aprovisionamiento del nuevo host bare metal:

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

42.5 Aprovisionamiento de clústeres descendentes con aprovisionamiento de red dirigida (varios nodos)

En esta sección se describe el flujo de trabajo usado para automatizar el aprovisionamiento de un clúster descendente de varios nodos con el método de aprovisionamiento de red dirigida y MetalLB como equilibrador de carga. Esta es la forma más sencilla de automatizar el aprovisionamiento de un clúster descendente. El siguiente diagrama muestra el flujo de trabajo utilizado para automatizar el aprovisionamiento de un clúster descendente de varios nodos con el método de aprovisionamiento de red dirigida y MetalLB.

Requisitos

Flujo de trabajo

El diagrama siguiente muestra el flujo de trabajo usado para automatizar el aprovisionamiento de un clúster descendente de varios nodos con el método de aprovisionamiento de red dirigida:

atip automatizado de varios nodos 1
  1. Inscriba los tres hosts bare metal para que estén disponibles para el proceso de aprovisionamiento.

  2. Aprovisione los tres hosts bare metal para instalar y configurar el sistema operativo y el clúster de Kubernetes con MetalLB.

Inscripción de los hosts bare metal

El primer paso es inscribir los tres hosts bare metal en el clúster de gestión para que estén disponibles para su aprovisionamiento. Para ello, se deben crear los archivos bmh-example-node1.yaml, bmh-example-node2.yaml y bmh-example-node3.yaml en el clúster de gestión para especificar las credenciales de BMC que se van a utilizar y el objeto BaremetalHost que se va a inscribir en el clúster de gestión.

Nota
Nota
  • Solo los valores entre $\{…​\} deben sustituirse por los valores reales.

  • Le guiaremos por el proceso para un solo host. Los mismos pasos se aplican a los otros dos nodos.

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

Donde:

  • ${BMC_NODE1_USERNAME}: es el nombre de usuario para el BMC del primer host bare metal.

  • ${BMC_NODE1_PASSWORD}: es la contraseña para el BMC del primer host bare metal.

  • ${BMC_NODE1_MAC}: es la dirección MAC del primer host bare metal que se utilizará.

  • ${BMC_NODE1_ADDRESS}: es la URL del primer host BMC bare metal (por ejemplo, redfish-virtualmedia://192.168.200.75/redfish/v1/Systems/1/). Para obtener más información sobre las opciones disponibles en función de su proveedor de hardware, consulte el siguiente enlace.

Nota
Nota
  • Si no se ha especificado ninguna configuración de red para el host, ya sea en el momento de la creación de la imagen o en la definición BareMetalHost, se utilizará un mecanismo de configuración automática (DHCP, DHCPv6 o SLAAC). Para obtener más detalles o configuraciones complejas, consulte la Sección 42.6, “Configuración de red avanzada”.

  • Aún no se admiten clústeres de varios nodos con doble pila o solo IPv6.

Una vez creado el archivo, se debe ejecutar el comando siguiente en el clúster de gestión para comenzar a inscribir los hosts bare metal en el clúster de gestión:

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

Los nuevos objetos host bare metal se inscriben y cambian su estado de "registering" (en registro) a "inspecting" (en inspección) y "available" (disponible). Los cambios se pueden comprobar con el siguiente comando:

$ kubectl get bmh -o wide
Nota
Nota

El objeto BaremetalHost permanece en estado registering (en registro) hasta que se validan las credenciales de BMC. Una vez validadas las credenciales, el objeto BaremetalHost cambia su estado a inspecting (en inspección), y este paso puede tardar algún tiempo dependiendo del hardware (hasta 20 minutos). Durante la fase de inspección, se recupera la información del hardware y se actualiza el objeto de Kubernetes. Compruebe la información con el siguiente comando: kubectl get bmh -o yaml.

Paso de aprovisionamiento

Una vez que los tres hosts bare metal se han inscrito y están disponibles, el siguiente paso es aprovisionar los hosts bare metal para instalar y configurar el sistema operativo y el clúster de Kubernetes, creando un equilibrador de carga para gestionarlos. Para ello, se debe crear el archivo capi-provisioning-example.yaml en el clúster de gestión con la siguiente información (el archivo capi-provisioning-example.yaml se puede generar uniendo los siguientes bloques).

Nota
Nota
  • Solo los valores entre $\{…​\} deben sustituirse por los valores reales.

  • La dirección IP virtual es una dirección IP reservada que no se asigna a ningún nodo y se utiliza para configurar el equilibrador de carga.

A continuación, se muestra la definición del clúster, donde la red del clúster se puede configurar utilizando los bloques pods y services. Además, contiene las referencias al plano de control y a los objetos de infraestructura (utilizando el proveedor de Metal3) que se van a utilizar.

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

El objeto Metal3Cluster especifica el punto final de plano de control que usa la dirección IP virtual ya reservada (en sustitución de ${DOWNSTREAM_VIP_ADDRESS}) que se va a configurar y noCloudProvider porque se utilizan los tres nodos 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

El objeto RKE2ControlPlane especifica la configuración de plano de control que se va a utilizar, y el objeto Metal3MachineTemplate especifica la imagen de plano de control que se va a utilizar.

  • El número de réplicas que se utilizarán (en este caso, tres).

  • El modo de anuncios que utilizará el equilibrador de carga (en address se usa la implementación L2), así como la dirección que se va a usar (sustituyendo ${EDGE_VIP_ADDRESS} por la dirección IP virtual).

  • El serverConfig con el complemento de CNI que se va a usar (en este caso, Cilium) y el tlsSan que se va a usar para configurar la dirección IP virtual.

  • El bloque agentConfig contiene el formato de Ignition que se va a usar y el bloque additionalUserData que se va a usar para configurar el nodo RKE2 con información como:

    • El servicio systemd denominado rke2-preinstall.service que sustituye automáticamente a BAREMETALHOST_UUID y node-name durante el proceso de aprovisionamiento con la información de Ironic.

    • El bloque storage que contiene los charts de Helm que se van a usar para instalar MetalLB y endpoint-copier-operator.

    • El archivo de recurso personalizado de metalLB con el IPaddressPool y el L2Advertisement que se van a usar (sustituyendo ${EDGE_VIP_ADDRESS} por la dirección IP virtual).

    • El archivo endpoint-svc.yaml que se va a usar para configurar el servicio kubernetes-vip que utilizará MetalLB para gestionar la dirección IP virtual.

  • El último bloque de información contiene la versión de Kubernetes que se va a usar. ${RKE2_VERSION} es la versión de RKE2 que se va a usar en sustitución de este valor (por ejemplo, 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"

El objeto Metal3MachineTemplate especifica la información siguiente:

  • La plantilla de datos (dataTemplate) que se usará como referencia para la plantilla.

  • El selector de host (hostSelector) que se usará que coincida con la etiqueta creada durante el proceso de inscripción.

  • La imagen (image) que se va a usar como referencia para la imagen generada con EIB en la sección anterior (Sección 42.2, “Preparación de la imagen del clúster descendente para entornos conectados”), y la suma de comprobación (checksum) y el tipo de suma (checksumType) que se van a usar para validar la imagen.

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

El objeto Metal3DataTemplate especifica los metadatos (metaData) para el clúster descendente.

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

Una vez creado el archivo uniendo los bloques anteriores, se debe ejecutar el comando siguiente en el clúster de gestión para iniciar el aprovisionamiento de los tres nuevos hosts bare metal:

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

42.6 Configuración de red avanzada

El flujo de trabajo de aprovisionamiento de red dirigida permite configuraciones de red específicas en clústeres descendentes, como direcciones IP estáticas, vinculación, VLAN, IPv6, etc.

Las secciones siguientes describen los pasos adicionales necesarios para habilitar el aprovisionamiento de clústeres descendentes con el método de configuración de red avanzada.

Requisitos

Configuración

Antes de continuar, consulte en las secciones siguientes los pasos necesarios para inscribir y aprovisionar los hosts:

Cualquier configuración de red avanzada debe aplicarse en el momento de la inscripción mediante la definición de host BareMetalHost y un secreto asociado que contenga un bloque networkData con formato nmstate. El siguiente archivo de ejemplo define un secreto que contiene el bloque networkData necesario que solicita una IP estática y una VLAN para el host del clúster descendente:

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 puede ver, el ejemplo muestra la configuración para habilitar la interfaz con direcciones IP estáticas, así como la configuración para habilitar la VLAN utilizando la interfaz base, una vez que las siguientes variables se sustituyan por los valores reales de su infraestructura:

  • ${CONTROLPLANE1_INTERFACE}: es la interfaz de plano de control que se usará para el clúster periférico (por ejemplo, eth0). Si se incluye identificador: dirección MAC, el nombre se comprueba automáticamente por su dirección MAC, por lo que se puede utilizar cualquier nombre de interfaz.

  • ${CONTROLPLANE1_IP}: es la dirección IP que se usará como punto final para el clúster periférico (debe coincidir con el punto final kubeapi-server).

  • ${CONTROLPLANE1_PREFIX}: es el CIDR que se usará para el clúster periférico (por ejemplo, 24 si desea /24 o 255.255.255.0).

  • ${CONTROLPLANE1_GATEWAY}: es el gateway que se usará para el clúster periférico (por ejemplo, 192.168.100.1).

  • ${CONTROLPLANE1_MAC}: es la dirección MAC que se usará para la interfaz de plano de control (por ejemplo, 00:0c:29:3e:3e:3e).

  • ${DNS_SERVER}: es el servidor DNS que se usará para el clúster periférico (por ejemplo, 192.168.100.2).

  • ${VLAN_ID}: es el ID de VLAN que se usará para el clúster periférico (por ejemplo, 100).

Se puede usar cualquier otra definición compatible con nmstate para configurar la red del clúster descendente y adaptarla a los requisitos específicos. Por ejemplo, es posible especificar una configuración estática de doble pila:

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}

En el ejemplo anterior, sustituya las variables siguientes por los valores reales de su infraestructura:

  • ${CONTROLPLANE_IP_V4}: la dirección IPv4 que se asignará al host

  • ${CONTROLPLANE_PREFIX_V4}: el prefijo IPv4 de la red a la que pertenece la IP del host

  • ${CONTROLPLANE_IP_V6}: la dirección IPv6 que se asignará al host

  • ${CONTROLPLANE_PREFIX_V6}: el prefijo IPv6 de la red a la que pertenece la IP del host

  • ${CONTROLPLANE_GATEWAY_V4}: la dirección IPv4 del gateway para el tráfico que coincide con la ruta predeterminada

  • ${CONTROLPLANE_GATEWAY_V6}: la dirección IPv6 del gateway para el tráfico que coincide con la ruta predeterminada

  • ${CONTROLPLANE_INTERFACE}: el nombre de la interfaz a la que se asignarán las direcciones y que se usará para el tráfico de salida que coincida con la ruta predeterminada, tanto para IPv4 como para IPv6

  • ${DNS_SERVER_V4} y/o ${DNS_SERVER_V6}: las direcciones IP de los servidores DNS que se van a usar, que pueden especificarse como entradas únicas o múltiples. Se admiten direcciones IPv4 y/o IPv6

Importante
Importante

Los despliegues de IPv6 y doble pila se encuentran en fase de tecnología en fase preliminar y no son compatibles oficialmente.

Nota
Nota

En el repositorio de ejemplos de SUSE Edge for Telco encontrará ejemplos más complejos, incluidas configuraciones solo de IPv6 y de doble pila.

Por último, independientemente de los detalles de la configuración de red, asegúrese de que se haga referencia al secreto añadiendo preprovisioningNetworkDataName al objeto BaremetalHost para inscribir correctamente el host en el clúster de gestión.

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
  • Si necesita desplegar un clúster de varios nodos, debe realizar el mismo proceso para cada nodo.

  • Actualmente, Metal3DataTemplate, networkData y Metal3 IPAM no se admiten; solo se admite plenamente la configuración mediante secretos estáticos.

42.7 Funciones para telecomunicaciones (DPDK, SR-IOV, aislamiento de CPU, páginas enormes, NUMA, etc.)

El flujo de trabajo de aprovisionamiento de red dirigida permite automatizar las funciones de telecomunicaciones que se usarán en los clústeres descendentes para ejecutar cargas de trabajo de telecomunicaciones en esos servidores.

Requisitos

Configuración

Use las dos secciones siguientes como base para inscribir y aprovisionar los hosts:

Las funciones de telecomunicaciones que se tratan en esta sección son las siguientes:

  • DPDK y creación de funciones virtuales

  • Asignación de SR-IOV y funciones virtuales que usarán las cargas de trabajo

  • Aislamiento de CPU y optimización del rendimiento

  • Configuración de páginas enormes

  • Optimización de los parámetros del kernel

Nota
Nota

Para obtener más información sobre las funciones de telecomunicaciones, consulte el Capítulo 41, Configuración de funciones de telecomunicaciones.

Todos los cambios necesarios para habilitar las funciones de telecomunicaciones indicados arriba se encuentran en el bloque RKE2ControlPlane del archivo de aprovisionamiento capi-provisioning-example.yaml. El resto de la información contenida en el archivo capi-provisioning-example.yaml es la misma que se proporciona en la sección sobre aprovisionamiento (Sección 42.4, “Aprovisionamiento de clústeres descendentes con aprovisionamiento de red dirigida (nodo único)”).

Para que el proceso quede claro, los cambios necesarios en ese bloque (RKE2ControlPlane) para habilitar las funciones de telecomunicaciones son los siguientes:

  • Los comandos preRKE2Commands que se usarán para ejecutar los comandos antes del proceso de instalación de RKE2. En este caso, use el comando modprobe para habilitar los módulos del kernel vfio-pci y SR-IOV.

  • El archivo de Ignition /var/lib/rancher/rke2/server/manifests/configmap-sriov-custom-auto.yaml se usará para definir las interfaces, los controladores y el número de funciones virtuales que se crearán y expondrán a las cargas de trabajo.

    • Los valores del mapa de configuración sriov-custom-auto-config son los únicos que deben sustituirse por valores reales.

      • ${RESOURCE_NAME1}: el nombre del recurso que se va a usar para la primera interfaz de función física PF (por ejemplo, sriov-resource-du1). Se añade al prefijo rancher.io para usarse como etiqueta que utilizarán las cargas de trabajo (por ejemplo, rancher.io/sriov-resource-du1).

      • ${SRIOV-NIC-NAME1}: el nombre de la primera interfaz de función física PF que se usará (por ejemplo, eth0).

      • ${PF_NAME1}: el nombre de la primera función física PF que se usará. Con esto, puede generar filtros más complejos (por ejemplo, eth0#2-5).

      • ${DRIVER_NAME1}: el nombre del controlador que se usará para la primera interfaz de función virtual VF (por ejemplo, vfio-pci).

      • ${NUM_VFS1}: el número de funciones virtuales que se crearán para la primera interfaz de función física PF (por ejemplo, 8).

  • El archivo /var/sriov-auto-filler.sh que se usará como traductor entre el mapa de configuración general sriov-custom-auto-config y el archivo sriovnetworknodepolicy, que contiene la información de hardware de bajo nivel. Este guion se ha creado para evitar al usuario la complejidad que supone que tenga que conocer de antemano la información de hardware. No es necesario realizar cambios en este archivo, pero debe estar presente si necesitamos habilitar sr-iov y crear funciones virtuales.

  • Los argumentos del kernel que se usarán para habilitar las siguientes funciones:

Parámetro

Valor

Descripción

isolcpus

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

Aísla los núcleos 1-30 y 33-62.

skew_tick

1

Permite al kernel distribuir las interrupciones del temporizador entre las CPU aisladas.

nohz

on

Permite al kernel ejecutar la marca del temporizador en una sola CPU cuando el sistema está inactivo.

nohz_full

1-30,33-62

El parámetro de arranque del kernel es la interfaz principal actual para configurar dynticks completos junto con el aislamiento de la CPU.

rcu_nocbs

1-30,33-62

Permite al kernel ejecutar las retrollamadas de RCU en una sola CPU cuando el sistema está inactivo.

irqaffinity

0,31,32,63

Permite al kernel ejecutar las interrupciones en una sola CPU cuando el sistema está inactivo.

idle

poll

Minimiza la latencia al salir del estado inactivo.

iommu

pt

Permite usar vfio para las interfaces dpdk.

intel_iommu

on

Habilita el uso de vfio para funciones virtuales.

hugepagesz

1G

Permite establecer el tamaño de las páginas enormes en 1 GB.

hugepages

40

El número de páginas enormes definidas anteriormente.

default_hugepagesz

1G

Valor predeterminado para habilitar las páginas enormes.

nowatchdog

 

Inhabilita el watchdog.

nmi_watchdog

0

Inhabilita el watchdog de NMI.

  • Los siguientes servicios systemd se utilizan para habilitar lo siguiente:

    • rke2-preinstall.service para sustituir automáticamente BAREMETALHOST_UUID y node-name durante el proceso de aprovisionamiento utilizando la información de Ironic.

    • cpu-partitioning.service para habilitar los núcleos de aislamiento de la CPU (por ejemplo, 1-30,33-62).

    • performance-settings.service para habilitar la optimización del rendimiento de la CPU.

    • sriov-custom-auto-vfs.service para instalar el chart de Helm sriov. Espere hasta que se creen los recursos personalizados y ejecute /var/sriov-auto-filler.sh para reemplazar los valores en el mapa de configuración sriov-custom-auto-config y crear el sriovnetworknodepolicy que utilizarán las cargas de trabajo.

  • ${RKE2_VERSION} es la versión de RKE2 que se usará en sustitución de este valor (por ejemplo, v1.32.4+rke2r1).

Con todos estos cambios mencionados, el bloque RKE2ControlPlane del archivo capi-provisioning-example.yaml tendrá el siguiente aspecto:

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"

Una vez creado el archivo uniendo los bloques anteriores, se debe ejecutar el siguiente comando en el clúster de gestión para iniciar el aprovisionamiento del nuevo clúster descendente utilizando las funciones de telecomunicaciones:

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

42.8 Registro privado

Es posible configurar un registro privado como duplicado de las imágenes usadas por las cargas de trabajo.

Para ello, creamos el secreto que contiene la información sobre el registro privado que usará el clúster descendente.

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}

Los archivos tls.crt, tls.key y ca.crt son los certificados que se usarán para autenticar el registro privado. username y password son las credenciales que se usarán para autenticar el registro privado.

Nota
Nota

Los campos tls.crt, tls.key, ca.crt, username y password deben cifrarse en formato base64 antes de utilizarse en el secreto.

Con todos estos cambios mencionados, el bloque RKE2ControlPlane del archivo capi-provisioning-example.yaml tendrá el siguiente aspecto:

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"

Donde registry.example.com es el nombre de ejemplo del registro privado que usará el clúster descendente, y debe sustituirse por los valores reales.

42.9 Aprovisionamiento de clústeres descendentes en entornos aislados

El flujo de trabajo de aprovisionamiento de red dirigida permite automatizar el aprovisionamiento de clústeres descendentes en entornos aislados.

42.9.1 Requisitos para entornos aislados

  1. La imagen raw generada con EIB debe incluir las imágenes de contenedor específicas (OCI de chart de Helm e imágenes de contenedor) necesarias para ejecutar el clúster descendente en un entorno aislado. Para obtener más información, consulte la Sección 42.3, “Preparación de la imagen del clúster descendente para entornos aislados”.

  2. En caso de usar SR-IOV o cualquier otra carga de trabajo personalizada, las imágenes necesarias para ejecutar las cargas de trabajo deben cargarse previamente en su registro privado siguiendo las instrucciones de la Sección 42.3.2.7, “Carga previa del registro privado con las imágenes necesarias para situaciones de entornos aislados y SR-IOV (opcional)”.

42.9.2 Inscripción de los hosts bare metal en entornos aislados

El proceso para inscribir los hosts bare metal en el clúster de gestión es el mismo que se describe en la Sección 42.4, “Aprovisionamiento de clústeres descendentes con aprovisionamiento de red dirigida (nodo único)”.

42.9.3 Aprovisionamiento del clúster descendente en entornos aislados

Hay algunos cambios importantes que se deben realizar para aprovisionar el clúster descendente en entornos aislados:

  1. El bloque RKE2ControlPlane del archivo capi-provisioning-example.yaml debe incluir la directiva spec.agentConfig.airGapped: true.

  2. La configuración del registro privado debe incluirse en el bloque RKE2ControlPlane del archivo capi-provisioning-airgap-example.yaml, después de la sección del registro privado (Sección 42.8, “Registro privado”).

  3. Si usa SR-IOV o cualquier otra configuración AdditionalUserData (guion de Combustion) que requiera la instalación del chart de Helm, debe modificar el contenido para que haga referencia al registro privado en lugar de utilizar el registro público.

El siguiente ejemplo muestra la configuración SR-IOV del bloque AdditionalUserData del archivo capi-provisioning-airgap-example.yaml con las modificaciones necesarias para hacer referencia al registro privado.

  • Referencias de secretos del registro privado

  • Definición del chart de Helm que usa el registro privado en lugar de las imágenes 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"

43 Acciones del ciclo de vida

Esta sección describe las acciones de gestión del ciclo de vida de los clústeres desplegados con SUSE Edge for Telco.

43.1 Actualizaciones del clúster de gestión

La actualización del clúster de gestión implica varios componentes. Para obtener una lista de los componentes generales que requieren una actualización, consulte la documentación sobre el clúster de gestión de día 2 (Capítulo 35, Clúster de gestión).

El procedimiento de actualización de los componentes específicos de esta configuración se indica a continuación.

Actualización de Metal3

Para actualizar Metal3, use el comando siguiente para actualizar la caché del repositorio de Helm y obtener el chart más reciente para instalar Metal3 desde el repositorio de charts de Helm:

helm repo update
helm fetch suse-edge/metal3

Después, la forma más fácil de actualizar es exportar las configuraciones actuales a un archivo y, a continuación, actualizar la versión de Metal3 utilizando ese archivo anterior. Si es necesario realizar algún cambio en la nueva versión, el archivo se puede editar antes de la actualización.

helm get values metal3 -n metal3-system -o yaml > metal3-values.yaml
helm upgrade metal3 suse-edge/metal3 \
  --namespace metal3-system \
  -f metal3-values.yaml \
  --version=303.0.7+up0.11.5

43.2 Actualización de clústeres descendentes

Para actualizar los clústeres descendentes hay que actualizar varios componentes. Las siguientes secciones describen el proceso de actualización de cada uno de los componentes.

Actualización del sistema operativo

Para este proceso, consulte la siguiente referencia (Sección 42.2, “Preparación de la imagen del clúster descendente para entornos conectados”) para crear la nueva imagen con una nueva versión del sistema operativo. Con esta nueva imagen generada por EIB, la siguiente fase de aprovisionamiento utiliza la nueva versión operativa proporcionada. En el siguiente paso, la nueva imagen se utiliza para actualizar los nodos.

Actualización del clúster RKE2

Los cambios necesarios para actualizar el clúster RKE2 utilizando el flujo de trabajo automatizado son los siguientes:

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
  version: ${RKE2_NEW_VERSION}
  replicas: 1
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  serverConfig:
    cni: cilium
  rolloutStrategy:
    rollingUpdate:
      maxSurge: 0
  registrationMethod: "control-plane-endpoint"
  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"
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3MachineTemplate
metadata:
  name: single-node-cluster-controlplane
  namespace: default
spec:
  nodeReuse: True
  template:
    spec:
      automatedCleaningMode: metadata
      dataTemplate:
        name: single-node-cluster-controlplane-template
      hostSelector:
        matchLabels:
          cluster-role: control-plane
      image:
        checksum: http://imagecache.local:8080/${NEW_IMAGE_GENERATED}.sha256
        checksumType: sha256
        format: raw
        url: http://imagecache.local:8080/${NEW_IMAGE_GENERATED}.raw

Después de realizar estos cambios, el archivo capi-provisioning-example.yaml se puede aplicar al clúster con este comando:

kubectl apply -f capi-provisioning-example.yaml

Parte VIII Solución de problemas

En esta sección se proporcionan instrucciones para diagnosticar y resolver problemas comunes relacionados con los despliegues y operaciones de SUSE Edge. Abarca diversos temas y ofrece pasos específicos para la resolución de problemas de componentes, herramientas clave y la ubicación de los registros relevantes.

44 Principios generales para resolver problemas

Antes de profundizar en cuestiones específicas de los componentes, tenga en cuenta estos principios generales:

  • Consulte los registros: los registros son la principal fuente de información. La mayoría de las veces, los errores se explican por sí mismos y contienen pistas sobre lo que ha fallado.

  • Compruebe los relojes: la diferencia horaria entre sistemas pueden provocar todo tipo de errores. Asegúrese de que los relojes estén sincronizados. Se puede indicar a EIB que fuerce la sincronización del reloj al arrancar el sistema. Consulte la sección sobre cómo configurar la hora del sistema operativo (Capítulo 3, Clústeres independientes con Edge Image Builder).

  • Problemas de arranque: si el sistema se bloquea durante el arranque, anote los últimos mensajes que se muestran. Acceda al panel de control (físico o a través de BMC) para leer los mensajes de arranque.

  • Problemas de red: verifique la configuración de la interfaz de red (ip a), la tabla de enrutamiento (ip route), pruebe la conectividad desde y hacia otros nodos y servicios externos (ping, nc). Asegúrese de que las reglas del cortafuegos no estén bloqueando los puertos necesarios.

  • Verifique el estado de los componentes: use kubectl get y kubectl describe para los recursos de Kubernetes. Use kubectl get events --sort-by='.lastTimestamp' -n <espaciodenombres> para ver los eventos de un espacio de nombres concreto de Kubernetes.

  • Verifique el estado de los servicios: use systemctl status <servicio> para los servicios systemd.

  • Compruebe la sintaxis: el software espera una estructura y sintaxis determinadas en los archivos de configuración. Para los archivos yaml, por ejemplo, utilice yamllint o herramientas similares para verificar que la sintaxis sea correcta.

  • Aísle el problema: intente delimitar el problema a un componente o capa específicos (por ejemplo, la red, el almacenamiento, el sistema operativo, Kubernetes, Metal3, Ironic, etc.​).

  • Documentación: consulte siempre la documentación oficial de SUSE Edge y la documentación original para obtener información detallada.

  • Versiones: SUSE Edge es una versión rigurosa y exhaustivamente probada de diferentes componentes de SUSE. Las versiones de cada componente en cada versión de SUSE Edge se pueden consultar en la matriz de asistencia de SUSE Edge.

  • Problemas conocidos: en las notas de cada versión de SUSE Edge hay una sección titulada "Problemas conocidos" que contiene información sobre problemas que se solucionarán en futuras versiones, pero que pueden afectar a la actual.

45 Resolución de problemas de Kiwi

Kiwi se usa para generar imágenes actualizadas de SUSE Linux Micro que se utilizarán con Edge Image Builder.

Problemas comunes
  • La versión de SL Micro no coincide: la versión del sistema operativo del host debe coincidir con la del sistema operativo que se está creando (host SL Micro 6.0 → imagen SL Micro 6.0).

  • SELinux en estado forzado: debido a ciertas limitaciones, es necesario inhabilitar SELinux temporalmente para poder crear imágenes con Kiwi. Compruebe el estado de SELinux con getenforce e inhabilítelo antes de ejecutar el proceso de creación con setenforce 0.

  • Host de creación no registrado: el proceso de creación utiliza las suscripciones del host de creación para poder extraer paquetes del Centro de servicios al cliente de SUSE. Si el host no está registrado, se produce un error.

  • Error en la prueba del dispositivo de bucle: la primera vez que se ejecuta el proceso de creación de Kiwi, falla poco después de iniciarse con el mensaje "ERROR: Early loop device test failed, please retry the container run" (Error: la prueba inicial del dispositivo de bucle ha fallado. Intente ejecutar el contenedor de nuevo.). Esto se debe a que se están creando dispositivos de bucle en el sistema host subyacente que no son visibles inmediatamente dentro de la imagen del contenedor. Vuelva a ejecutar el proceso de creación de Kiwi y debería continuar sin problemas.

  • Faltan permisos: se espera que sea el usuario root quien ejecute el proceso de creación (o que se haga mediante sudo).

  • Privilegios incorrectos: el proceso de creación espera el indicador --privileged al ejecutar el contenedor. Compruebe que está presente.

Registros
  • Registros del contenedor de creación: compruebe los registros del contenedor de creación. Los registros se generan en el directorio que se utilizó para almacenar los artefactos. Compruebe también los registros de Docker o Podman para obtener la información necesaria.

  • Directorios temporales de creación: Kiwi crea directorios temporales durante el proceso de creación. Compruebe esos directorios en busca de registros intermedios o artefactos si el resultado principal es insuficiente.

Pasos para resolver problemas
  1. Revise el resultado de build-image: el mensaje de error que aparece en el panel de control suele ser muy explicativo.

  2. Compruebe el entorno de creación: asegúrese de que se cumplen todos los requisitos previos para Kiwi (por ejemplo, docker/podman, SElinux, espacio suficiente en disco) en el equipo donde se ejecuta.

  3. Inspeccione los registros del contenedor de creación: revise los registros del contenedor que ha fallado para obtener información más detallada sobre los errores (véase más arriba).

  4. Verifique el archivo de definición: si usa un archivo de definición de imagen de Kiwi personalizado, compruebe que no haya errores ortográficos ni sintácticos en el archivo.

46 Resolución de problemas de Edge Image Builder (EIB)

EIB se usa para crear imágenes personalizadas de SUSE Edge.

Problemas comunes
  • Código erróneo del SCC: asegúrese de que el código del Centro de servicios al cliente de SUSE utilizado en el archivo de definición de EIB coincida con la versión y la arquitectura de SL Micro.

  • Faltan dependencias: asegúrese de que no falte ningún paquete o herramienta en el entorno de creación.

  • Tamaño de imagen incorrecto: para las imágenes raw, se requiere el parámetro diskSize, que depende en gran medida de las imágenes, los RPM y otros artefactos incluidos en la imagen.

  • Permisos: si almacena un guion en el directorio custom/files, asegúrese de que tenga permisos de ejecución, ya que esos archivos solo están disponibles cuando se ejecuta Combustion, pero EIB no realiza ningún cambio.

  • Dependencias del grupo del sistema operativo: al crear una imagen con usuarios y grupos personalizados, los grupos que se definan como primaryGroup deben crearse explícitamente.

  • Las claves SSH de los usuarios del sistema operativo requieren una carpeta de inicio: al crear una imagen con usuarios con claves SSH, también es necesario crear la carpeta de inicio con createHomeDir=true.

  • Problemas de Combustion: EIB utiliza Combustion para la personalización del sistema operativo y el despliegue de todos los demás componentes de SUSE Edge. Esto también incluye guiones personalizados que se colocan en la carpeta custom/scripts. Tenga en cuenta que el proceso Combustion se ejecuta en el momento de initrd, por lo que el sistema no está completamente arrancado cuando se ejecutan los guiones.

  • Tamaño de la máquina de Podman: como se explica en la sección de consejos y trucos de EIB (Parte IV, “Consejos y trucos”), compruebe que la máquina de Podman tenga suficiente CPU/memoria para ejecutar el contenedor de EIB en sistemas operativos que no sean Linux.

Registros
  • Salida de EIB: el resultado del panel de control del comando eib build es fundamental.

  • Registros del contenedor de creación: compruebe los registros del contenedor de creación. Los registros se generan en el directorio que se utilizó para almacenar los artefactos. Compruebe también los registros de Docker o Podman para obtener la información necesaria.

    Nota
    Nota

    Para obtener más información, consulte la sección Debugging (Depuración).

  • Directorios temporales de creación: EIB crea directorios temporales durante el proceso de creación. Compruebe si hay registros intermedios o artefactos en ellos si el resultado principal es insuficiente.

  • Registros de Combustion: si la imagen que se está creando con EIB no arranca por cualquier motivo, hay disponible una shell raíz. Conéctese al panel de control del host (ya sea físicamente, a través de BMC, etc.) y compruebe los registros de Combustion con journalctl -u combustion y, en general, todos los registros del sistema operativo con journalctl para encontrar la causa raíz del fallo.

Pasos para resolver problemas
  1. Revise el resultado de eib-build: el mensaje de error que aparece en el panel de control suele ser muy explicativo.

  2. Compruebe el entorno de creación: asegúrese de que se cumplen todos los requisitos previos de EIB (por ejemplo, docker/podman, espacio suficiente en disco) en el equipo donde se ejecuta EIB.

  3. Inspeccione los registros del contenedor de creación: revise los registros del contenedor que ha fallado para obtener información más detallada sobre los errores (véase más arriba).

  4. Verifique la configuración de eib: compruebe bien el archivo de configuración eib para detectar posibles errores ortográficos o rutas incorrectas a los archivos de origen o a los guiones de creación.

    • Pruebe los componentes individualmente: si su versión EIB incluye guiones o etapas personalizados, ejecútelos de forma independiente para aislar los fallos.

Nota
Nota

Consulte la sección Edge Image Builder Debugging (Depuración de Edge Image Builder).

47 Resolución de problemas de redes periféricas (NMC)

NMC se inyecta en las imágenes de EIB de SL Micro para configurar la red de los hosts de Edge en el momento del arranque mediante Combustion. También se ejecuta en el flujo de trabajo Metal3 como parte del proceso de inspección. Pueden surgir problemas cuando se arranca el host por primera vez o durante el proceso de inspección de Metal3.

Problemas comunes
  • El host no puede arrancar correctamente la primera vez: los archivos de definición de red que no están bien formados pueden provocar que la fase de Combustion falle y que el host pierda el control de la shell raíz.

  • Los archivos no se han generado correctamente: asegúrese de que los archivos de red cumplan el formato NMState.

  • Las interfaces de red no están configuradas correctamente: asegúrese de que las direcciones MAC coincidan con las interfaces que se utilizan en el host.

  • Los nombres no coinciden entre las interfaces: el argumento del kernel net.ifnames=1 permite un esquema de nomenclatura predecible para interfaces de red, por lo que ya no existe eth0, sino otros esquemas de nomenclatura como enp2s0.

Registros
  • Registros de Combustion: dado que nmc se utiliza al mismo tiempo que Combustion, compruebe los registros de Combustion con journalctl -u combustion en el host que se está aprovisionando.

  • Registros de NetworkManager: en el flujo de trabajo de despliegue de Metal3, nmc forma parte de la ejecución de IPA y se ejecuta como dependencia del servicio NetworkManager usando la funcionalidad ExecStartPre de systemd. Compruebe los registros de NetworkManager en el host de IPA con journalctl -u NetworkManager (consulte la sección de resolución de problemas de aprovisionamiento de red dirigida (Capítulo 49, Resolución de problemas de aprovisionamiento de red dirigida) para comprender cómo acceder al host cuando se inicia con IPA).

Pasos para resolver problemas
  1. Verifique la sintaxis de YAML: los archivos de configuración nmc son archivos YAML. Compruebe que la sintaxis sea correcta con yamllint o herramientas similares.

  2. Ejecute nmc manualmente: dado que nmc forma parte del contenedor EIB, para depurar cualquier problema se puede utilizar un comando de Podman local.

    1. Cree una carpeta temporal para almacenar los archivos de nmc.

      mkdir -p ${HOME}/tmp/foo
    2. Guarde los archivos de nmc en esa ubicación.

      ❯ tree --noreport ${HOME}/tmp/foo
      /Users/johndoe/tmp/foo
      ├── host1.example.com.yaml
      └── host2.example.com.yaml
    3. Ejecute el contenedor de EIB con nmc como punto de entrada y el comando generate para realizar las mismas tareas que nmc haría al mismo tiempo que Combustion:

      podman run -it --rm -v ${HOME}/tmp/foo:/tmp/foo:Z --entrypoint=/usr/bin/nmc registry.suse.com/edge/3.3/edge-image-builder:1.2.0 generate --config-dir /tmp/foo --output-dir /tmp/foo/
      
      [2025-06-04T11:58:37Z INFO  nmc::generate_conf] Generating config from "/tmp/foo/host2.example.com.yaml"...
      [2025-06-04T11:58:37Z INFO  nmc::generate_conf] Generating config from "/tmp/foo/host1.example.com.yaml"...
      [2025-06-04T11:58:37Z INFO  nmc] Successfully generated and stored network config
    4. Observe los registros y archivos que se generan en la carpeta temporal.

48 Resolución de problemas en escenarios "phone home"

En los escenarios "phone home" se usa Elemental para volver a conectarse al clúster de gestión y EIB a fin de crear una imagen del sistema operativo que incluya los bits de registro de Elemental. Pueden surgir problemas cuando se arranca el host por primera vez, durante el proceso de creación de EIB o al intentar registrarse en el clúster de gestión.

Problemas comunes
  • El sistema no se registra: el nodo no se registra en la interfaz del usuario. Asegúrese de que el host se haya arrancado correctamente y pueda comunicarse con Rancher, que el reloj esté sincronizado y que los servicios de Elemental funcionen correctamente.

  • El sistema no se puede aprovisionar: el nodo está registrado, pero no se puede aprovisionar. Asegúrese de que el host pueda comunicarse con Rancher, que el reloj esté sincronizado y que los servicios de Elemental funcionen correctamente.

Registros
  • Registros del sistema: journalctl

  • Registros de elemental-system-agent: journalctl -u elemental-system-agent

  • Registros de K3s/RKE2: journalctl -u k3s o journalctl -u rke2-server (o rke2-agent)

  • Pod del operador de Elemental: kubectl logs -n cattle-elemental-system -l app=elemental-operator

Pasos para resolver problemas
  1. Consulte los registros: compruebe los registros del pod del operador de Elemental para ver si hay algún problema. Compruebe los registros del host si el nodo se ha arrancado.

  2. Compruebe MachineRegistration y TPM: de forma predeterminada, TPM se utiliza para la autenticación, pero existen alternativas para hosts sin TPM.

49 Resolución de problemas de aprovisionamiento de red dirigida

En el aprovisionamiento de red dirigida se usan Metal3 y CAPI para aprovisionar el clúster descendente. También se usa EIB para crear una imagen del sistema operativo. Pueden surgir problemas cuando se arranca el host por primera vez o durante los procesos de inspección o aprovisionamiento.

Problemas comunes
  • Firmware antiguo: compruebe que todo el firmware de los hosts físicos que se utilizan esté actualizado. Esto incluye el firmware de BMC, ya que en ocasiones Metal3 requiere un firmware específico/actualizado.

  • El aprovisionamiento falla con errores de SSL: si el servidor Web que proporciona las imágenes utiliza https, Metal3 debe configurarse para inyectar y confiar en el certificado de la imagen IPA. Consulte la carpeta de Kubernetes (Sección 40.3.4, “Carpeta kubernetes”) para obtener información sobre cómo incluir un archivo ca-additional.crt en el chart de Metal3.

  • Problemas con los certificados al arrancar los hosts con IPA: algunos proveedores de servidores verifican la conexión SSL al conectar imágenes ISO de medios virtuales al BMC, lo que puede causar un problema porque los certificados generados para el despliegue de Metal3 son autofirmados. Puede ocurrir que el host se esté arrancando, pero caiga a una shell UEFI. Consulte la sección sobre cómo inhabilitar TLS para la conexión de ISO de medios virtuales (Sección 1.6.2, “Inhabilitación de TLS para la conexión ISO de medios virtuales”) para averiguar cómo solucionar este problema.

  • Referencia de nombre o etiqueta incorrecta: si el clúster hace referencia a un nodo con un nombre o etiqueta incorrectos, el clúster se despliega correctamente, pero el BMH permanece con el estado "Available" (Disponible). Compruebe bien las referencias de los objetos involucrados para los BMH.

  • Problemas de comunicación de BMC: asegúrese de que los pods de Metal3 que se ejecutan en el clúster de gestión puedan acceder al BMC de los hosts que se están aprovisionando (normalmente, la red de BMC está muy restringida).

  • Estado incorrecto del host bare metal: el objeto BMH pasa por diferentes estados (inspección, preparación, aprovisionamiento, etc.) durante su ciclo de vida Lifestyle of State machine (Ciclo de vida de la máquina de estados). Si se detecta un estado incorrecto, compruebe el campo status del objeto BMH, ya que contiene más información, como kubectl get bmh <nombre> -o jsonpath=’{.status}’| jq.

  • El host no se ha desaprovisionado: en caso de que falle el desaprovisionamiento de un host, se puede intentar eliminarlo después de añadir la anotación "detached" al objeto BMH de la siguiente manera: kubectl annotate bmh/<BMH> baremetalhost.metal3.io/detached=””.

  • Errores de imagen: compruebe que la imagen que se está creando con EIB para el clúster descendente esté disponible, tenga una suma de comprobación correcta y no sea demasiado grande para descomprimirla ni para el disco.

  • Discrepancia en el tamaño del disco: de forma predeterminada, el disco no se expandirá hasta ocupar todo el espacio disponible. Como se explica en la sección del guion Growfs (Sección 1.3.4.1.2, “Guion Growfs”), es necesario incluir un guion growfs en la imagen que se está creando con EIB para los hosts del clúster descendente.

  • Proceso de limpieza bloqueado: el proceso de limpieza se reintenta varias veces. Si debido a un problema con el host ya no es posible realizar la limpieza, inhabilite primero la limpieza definiendo en el campo automatedCleanMode el valor disabled en el objeto BMH.

    Aviso
    Aviso

    No se recomienda eliminar manualmente el finalizador cuando el proceso de limpieza tarda más de lo deseado o falla. Si se hiciera, se eliminaría el registro del host de Kubernetes, pero se dejaría en Ironic. La acción que se está ejecutando actualmente continuaría en segundo plano, y es posible que el intento de volver a añadir el host fallara debido al conflicto.

  • Problemas en los pods de Metal3/Rancher Turtles/CAPI: el flujo de despliegue para todos los componentes necesarios es:

    • El controlador de Rancher Turtles despliega el controlador del operador de CAPI.

    • A continuación, el controlador del operador de CAPI despliega los controladores del proveedor (plano de control/arranque del núcleo de CAPI, CAPM3 y RKE2).

Compruebe que todos los pods funcionen correctamente y, si no fuera así, revise los registros.

Registros
  • Registros de Metal3: consulte los registros de los distintos pods.

    kubectl logs -n metal3-system -l app.kubernetes.io/component=baremetal-operator
    kubectl logs -n metal3-system -l app.kubernetes.io/component=ironic
    Nota
    Nota

    El pod metal3-ironic contiene al menos 4 contenedores distintos (ironic-httpd,` ironic-log-watch`, ironic e ironic-ipa-downloader (init)) en el mismo pod. Use el indicador -c cuando utilice kubectl logs para verificar los registros de cada contenedor.

    Nota
    Nota

    El contenedor ironic-log-watch expone los registros del panel de control de los hosts tras la inspección o el aprovisionamiento, siempre que la conectividad de red permita enviar estos registros al clúster de gestión. Esto puede resultar útil en casos en los que se producen errores de aprovisionamiento, pero no se tiene acceso directo a los registros del panel de control de BMC.

  • Registros de Rancher Turtles: consulte los registros de los diferentes pods.

    kubectl logs -n rancher-turtles-system -l control-plane=controller-manager
    kubectl logs -n rancher-turtles-system -l app.kubernetes.io/name=cluster-api-operator
    kubectl logs -n rke2-bootstrap-system -l cluster.x-k8s.io/provider=bootstrap-rke2
    kubectl logs -n rke2-control-plane-system -l cluster.x-k8s.io/provider=control-plane-rke2
    kubectl logs -n capi-system -l cluster.x-k8s.io/provider=cluster-api
    kubectl logs -n capm3-system -l cluster.x-k8s.io/provider=infrastructure-metal3
  • Registros de BMC: por lo general, los BMC tienen una interfaz de usuario en la que se puede realizar la mayor parte de la interacción. Suele haber una sección de "registros" en la que se pueden observar posibles problemas (imposibilidad de acceder a la imagen, fallos de hardware, etc.).

  • Registros del panel de control: conéctese al panel de control de BMC (a través de la interfaz Web de BMC, en serie, etc.) y compruebe si hay errores en los registros que se están escribiendo.

Pasos para resolver problemas
  1. Compruebe el estado de BareMetalHost:

    • kubectl get bmh -A muestra el estado actual, que puede ser provisioning, ready, error o registering.

    • kubectl describe bmh -n <espaciodenombres> <nombre_bmh> proporciona información detallada sobre los eventos y condiciones que explican por qué un BMH podría estar bloqueado.

  2. Pruebe la conectividad de Redfish:

    • Use curl desde el plano de control de Metal3 para comprobar la conectividad con los BMC a través de Redfish.

    • Asegúrese de que se proporcionan las credenciales de BMC correctas en la definición de BareMetalHost-Secret.

  3. Verifique el estado del pod de turtles/CAPI/metal3: asegúrese de que los contenedores del clúster de gestión estén activos y en ejecución: kubectl get pods -n metal3-system y kubectl get pods -n rancher-turtles-system (consulte también capi-system, capm3-system, rke2-bootstrap-system y rke2-control-plane-system).

  4. Verifique que se pueda acceder al punto final de Ironic desde el host que se está aprovisionando: el host que se está aprovisionando debe poder acceder al punto final de Ironic para informar a Metal3. Compruebe la IP con kubectl get svc -n metal3-system metal3-metal3-ironic e intente acceder a ella mediante curl/nc.

  5. Verifique que se pueda acceder a la imagen IPA desde el BMC: el punto final Ironic proporciona la imagen IPA, a la que se debe poder acceder desde el BMC, ya que se utiliza como un CD virtual.

  6. Verifique que se pueda acceder a la imagen del sistema operativo desde el host que se está aprovisionando: debe poder accederse a la imagen que se utiliza para aprovisionar el host desde el propio host (cuando se ejecuta IPA), ya que se descargará temporalmente y se escribirá en el disco.

  7. Examine los registros de componentes de Metal3: consulte las secciones anteriores.

  8. Vuelva a lanzar la inspección de BMH: si una inspección falla o cambia el hardware de un host disponible, se puede iniciar un nuevo proceso de inspección anotando el objeto BMH con inspect.metal3.io: "". Consulte la guía de inspección de control de Metal3 para obtener más información.

  9. Panel de control IPA bare metal: para solucionar problemas relacionados con IPA, existen varias alternativas:

    • Habilite el "inicio de sesión automático". Esto permite que el usuario root inicie sesión automáticamente al conectarse al panel de control de IPA.

      Aviso
      Aviso

      Esto es solo para fines de depuración, ya que proporciona acceso completo al host.

      Para habilitar el inicio de sesión automático, el valor de helm global.ironicKernelParams de Metal3 debe tener el siguiente aspecto: console=ttyS0 suse.autologin=ttyS0 (dependiendo del panel de control, ttyS0 puede cambiarse). A continuación, se debe realizar un nuevo despliegue del chart de Metal3. (Nota: ttyS0 es un ejemplo, debe coincidir con el terminal real, por ejemplo, puede ser tty1 en muchos casos en bare metal. Esto se puede verificar mirando la salida del panel de control desde el ramdisk de IPA al arrancar, donde /etc/issue produce el nombre del panel de control).

      Otra forma de hacerlo es cambiando el parámetro IRONIC_KERNEL_PARAMS en el mapa de configuración ironic-bmo del espacio de nombres metal3-system. Esto puede resultar más sencillo, ya que se puede hacer editando kubectl, pero se sobrescribirá al actualizar el chart. A continuación, es necesario reiniciar el pod de Metal3 con kubectl delete pod -n metal3-system -l app.kubernetes.io/component=ironic.

    • Inyecte una clave ssh para el usuario root en el IPA.

      Aviso
      Aviso

      Esto es solo para fines de depuración, ya que proporciona acceso completo al host.

      Para inyectar la clave ssh para el usuario root, se debe utilizar el valor de helm debug.ironicRamdiskSshKey de Metal3. A continuación, se debe realizar un nuevo despliegue del chart de Metal3.

      Otra forma de hacerlo es cambiando el parámetro IRONIC_RAMDISK_SSH_KEY en el mapa de configuración ironic-bmo del espacio de nombres metal3-system. Esto puede resultar más sencillo, ya que se puede hacer editando kubectl, pero se sobrescribirá al actualizar el chart. A continuación, es necesario reiniciar el pod de Metal3 con kubectl delete pod -n metal3-system -l app.kubernetes.io/component=ironic.

50 Resolución de problemas de otros componentes

Es posible consultar otras guías de resolución de problemas de componentes de SUSE Edge en su documentación oficial respectiva:

También puede consultar la Base de conocimientos de SUSE.

51 Recopilación de diagnóstico para la asistencia

Al ponerse en contacto con el servicio de asistencia técnica de SUSE, es fundamental proporcionar información de diagnóstico completa.

Información esencial que se debe recopilar
  • Descripción detallada del problema: ¿Qué ha ocurrido?, ¿cuándo?, ¿qué estaba haciendo?, ¿cuál es el comportamiento esperado?, y ¿cuál es el comportamiento real?

  • Pasos para reproducir el problema: ¿Puede reproducir el problema de forma fiable? Si es así, indique los pasos exactos.

  • Versiones de los componentes: Versión de SUSE Edge, versiones de los componentes (RKE2/K3, EIB, Metal3, Elemental, etc.).

  • Registros relevantes:

    • Resultado de journalctl (filtrado por servicio, si es posible, o registros de arranque completos).

    • Registros de pod de Kubernetes (registros kubectl).

    • Registros de componente de Metal³/Elemental.

    • Registros de creación de EIB y otros registros

  • Información del sistema:

    • uname -a

    • df -h

    • ip a

    • /etc/os-release

  • Archivos de configuración: archivos de configuración relevantes para Elemental, Metal3, EIB, tales como valores de charts de helm, mapas de configuración, etc.

  • Información de Kubernetes: nodos, servicios, despliegues, etc.

  • Objetos de Kubernetes afectados: BMH, MachineRegistration, etc.

Cómo recopilar la información
  • Registros: redirija la salida del comando a archivos (por ejemplo, journalctl -u k3s > k3s_logs.txt).

  • Recursos de Kubernetes: use kubectl get <recurso> -o yaml > <nombre_de_recurso>.yaml para obtener definiciones YAML detalladas.

  • Información del sistema: recopile los resultados de los comandos indicados anteriormente.

  • SL Micro: consulte en la guía de resolución de problemas de SUSE Linux Micro cómo recopilar información del sistema para obtener asistencia con supportconfig.

  • RKE2/Rancher: consulte el artículo The Rancher v2.x Linux log collector script (Guion de recopilación de registros de Linux de Rancher v2.x) para ejecutar dicho guion.

Póngase en contacto con el servicio de asistencia. Consulte el artículo How-to effectively work with SUSE Technical Support (Cómo trabajar eficazmente con el servicio de asistencia técnica de SUSE) y el manual de asistencia técnica disponible en SUSE Technical Support Handbook para obtener más detalles sobre cómo ponerse en contacto con el servicio de asistencia técnica de SUSE.

Parte IX Apéndice

  • 52 Notas de la versión
  • SUSE Edge 3.3 es una solución integral, estrechamente integrada y validada de forma exhaustiva para abordar los retos únicos que plantea el despliegue de infraestructura y aplicaciones nativas de la nube en el perímetro. Su objetivo principal es proporcionar una plataforma propia, pero altamente fle…

52 Notas de la versión

52.1 Resumen

SUSE Edge 3.3 es una solución integral, estrechamente integrada y validada de forma exhaustiva para abordar los retos únicos que plantea el despliegue de infraestructura y aplicaciones nativas de la nube en el perímetro. Su objetivo principal es proporcionar una plataforma propia, pero altamente flexible, escalable y segura que abarque la creación de imágenes de distribución inicial, el aprovisionamiento y la incorporación de nodos, el despliegue de aplicaciones, la observabilidad y las operaciones completas del ciclo de vida.

La solución se ha diseñado partiendo de la idea de que no existe una plataforma periférica única "válida para todo", debido a la gran variedad de requisitos y expectativas de los clientes. Los despliegues periféricos nos obligan a evolucionar para resolver continuamente problemas difíciles, como la escalabilidad masiva, la disponibilidad limitada de la red, las restricciones de espacio físico, las nuevas amenazas de seguridad y vectores de ataque, las variaciones en la arquitectura del hardware y los recursos del sistema, la necesidad de implantar e interactuar con infraestructuras y aplicaciones heredadas, y las soluciones de los clientes que tienen una vida útil prolongada.

La plataforma se basa por completo en el mejor software de código abierto, en consonancia con nuestros más de 30 años de historia proporcionando plataformas SUSE Linux seguras, estables y certificadas, y en nuestra experiencia en la gestión de Kubernetes altamente escalable y rica en funciones con nuestra cartera de productos Rancher. SUSE Edge se basa en estas capacidades para ofrecer funcionalidades que pueden aplicarse a numerosos segmentos de mercado, incluyendo el comercio minorista, la medicina, el transporte, la logística, las telecomunicaciones, la fabricación inteligente y el IoT industrial.

Nota
Nota

SUSE Edge for Telco (anteriormente conocido como Adaptive Telco Infrastructure Platform/ATIP) es un producto derivado de SUSE Edge, con optimizaciones y componentes adicionales que permiten a la plataforma adaptarse al uso práctico en el sector de las telecomunicaciones. A menos que se indique explícitamente lo contrario, todas las notas de la versión son aplicables tanto a SUSE Edge 3.3 como a SUSE Edge for Telco 3.3.

52.2 Acerca de

Estas notas de la versión son, salvo que se especifique y explique explícitamente lo contrario, idénticas en todas las arquitecturas, y la versión más reciente, junto con las notas de la versión de todos los demás productos SUSE, están siempre disponibles en línea en https://www.suse.com/releasenotes.

Las entradas solo se muestran una vez, pero pueden aparecer referenciadas en varios lugares si son importantes y pertenecen a más de una sección. Las notas de la versión suelen mostrar solo los cambios que se han producido entre dos versiones consecutivas. Es posible que se repitan algunas entradas importantes de las notas de la versión de versiones anteriores del producto. Para facilitar la identificación de estas entradas, se incluye una nota al respecto.

Sin embargo, las entradas repetidas se proporcionan únicamente como cortesía. Por lo tanto, si se salta una o más versiones, compruebe también las notas de las versiones omitidas. Si solo lee las notas de la versión actual, podría perderse cambios importantes que pueden afectar al comportamiento del sistema. Las versiones de SUSE Edge se definen como x.y.z, donde "x" denota la versión principal; "y", la secundaria y "z", la versión del parche, también conocida como "z-stream". Los ciclos de vida de los productos SUSE Edge se definen en función de una versión secundaria determinada, por ejemplo, "3.3", pero se envían con actualizaciones de parches posteriores a lo largo de su ciclo de vida, por ejemplo, "3.3.1".

Nota
Nota

Las versiones z-stream de SUSE Edge están estrechamente integradas y se han probado exhaustivamente como una pila de versión. La actualización de cualquier componente individual a una versión diferente a las indicadas anteriormente probablemente provocará una interrupción del sistema. Aunque es posible ejecutar clústeres de Edge en configuraciones no probadas, no es recomendable y es posible que la resolución a través de los canales de asistencia técnica lleve más tiempo.

52.3 Versión 3.3.1

Fecha de lanzamiento: 13 de junio de 2025

Resumen: SUSE Edge 3.3.1 es la primera versión z-stream de SUSE Edge 3.3.

52.3.1 Funciones nuevas

52.3.2 Soluciones de seguridad y errores

  • En algunos casos, al usar un clúster de gestión que se ha actualizado de Edge 3.2 a 3.3.0, realizar actualizaciones progresivas descendentes a través de CAPI podría provocar que los equipos se quedaran bloqueados en el estado "Deleting" (Eliminando). Esto se ha resuelto mediante una actualización del proveedor CAPI de RKE2: Problema 661 de versión superior del proveedor de RKE2

  • Al configurar la red mediante nm-configurator, algunas configuraciones que identifican interfaces por MAC en la versión 3.3.0 no funcionaban. Esto se ha resuelto actualizando NMC a la versión 0.3.3 con las correspondientes actualizaciones de las imágenes de contenedor de descarga de IPA de EIB y Metal3: Problema de versión superior de NM Configurator

  • En los clústeres de gestión de Metal3 de larga duración de la versión 3.3.0, era posible que la caducidad del certificado provocara un fallo en la conexión del operador bare metal con Ironic, lo que requería una solución alternativa de reinicio manual del pod. Esto se ha resuelto mediante actualizaciones del chart de Metal3: Problema con los charts de SUSE Edge

  • Anteriormente, la interfaz de usuario de Rancher no podría mostrar los charts de SUSE Edge desde el registro de OCI del catálogo de aplicaciones. Este problema se ha resuelto con la actualización a Rancher 2.11.2: Problema de Rancher

52.3.3 Problemas conocidos

Aviso
Aviso

Si va a desplegar nuevos clústeres, siga las instrucciones del Capítulo 28, Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi para crear primero imágenes nuevas, ya que ahora este es el primer paso necesario para crear clústeres tanto para las arquitecturas AMD64/Intel 64 y AArch64 como para los clústeres de gestión y los clústeres descendentes.

  • Cuando se usa toolbox en SUSE Linux Micro 6.1, la imagen de contenedor predeterminada no contiene algunas herramientas que se incluían en la versión 5.5 anterior. La solución alternativas es configurar toolbox para que use la imagen de contenedor suse/sle-micro/5.5/toolbox anterior. Consulte toolbox --help para ver las opciones de configuración de la imagen.

  • En algunos casos, las actualizaciones progresivas a través de CAPI pueden provocar que las máquinas se queden bloqueadas en el estado "Deleting" (Eliminando). Esto se resolverá mediante una futura actualización: Problema 655 de versión superior del proveedor de RKE2

  • Debido a las correcciones relacionadas con la CVE-2025-1974 mencionadas en la versión 3.3.0, SUSE Linux Micro 6.1 debe actualizarse para incluir el kernel >=6.4.0-26-default o >=6.4.0-30-rt (kernel en tiempo real) debido a los parches necesarios para el kernel SELinux. Si no se aplican, el pod ingress-nginx permanecerá en estado CrashLoopBackOff. Para aplicar la actualización del kernel, ejecute transactional-update en el propio host (para actualizar todos los paquetes) o transactional-update pkg update kernel-default (o el kernel en tiempo real) para actualizar solo el kernel y, a continuación, rearranque el host. Si va a desplegar nuevos clústeres, siga el Capítulo 28, Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi para crear imágenes nuevas que contengan el kernel más reciente.

  • Se ha identificado un error en el controlador de trabajos de Kubernetes que, en determinadas condiciones, puede provocar que los nodos RKE2/K3s permanezcan en estado NotReady (consulte el problema n.º 8357 de RKE2). Los errores pueden tener el siguiente aspecto:

E0605 23:11:18.489721   »···1 job_controller.go:631] "Unhandled Error" err="syncing job: tracking status: adding uncounted pods to status: Operation cannot be fulfilled on jobs.batch \"helm-install-rke2-ingress-nginx\": StorageError: invalid object, Code: 4, Key: /registry/jobs/kube-system/helm-install-rke2-ingress-nginx, ResourceVersion: 0, AdditionalErrorMsg: Precondition failed: UID in precondition: 0aa6a781-7757-4c61-881a-cb1a4e47802c, UID in object meta: 6a320146-16b8-4f83-88c5-fc8b5a59a581" logger="UnhandledError"

Como solución, el pod kube-controller-manager se puede reiniciar con crictl como:

export CONTAINER_RUNTIME_ENDPOINT=unix:///run/k3s/containerd/containerd.sock
export KUBEMANAGER_POD=$(/var/lib/rancher/rke2/bin/crictl ps --label io.kubernetes.container.name=kube-controller-manager --quiet)
/var/lib/rancher/rke2/bin/crictl stop ${KUBEMANAGER_POD} && \
/var/lib/rancher/rke2/bin/crictl rm ${KUBEMANAGER_POD}
  • En las versiones 1.31 y 1.32 de RKE2/K3s, es posible que el directorio /etc/cni utilizado para almacenar las configuraciones de CNI no active una notificación de los archivos que se escriben allí en containerd debido a ciertas condiciones relacionadas con overlayfs (consulte el problema n.º 8356 de RKE2). Esto, a su vez, provoca que el despliegue de RKE2/K3s se quede bloqueado a la espera de que se inicie la CNI y que los nodos RKE2/K3s permanecen en estado NotReady. Puede observar este problema en cada nodo con kubectl describe node <nodo_afectado>:

<200b><200b>Conditions:
  Type         »Status  LastHeartbeatTime             »·LastTransitionTime            »·Reason                   »··Message
  ----         »------  -----------------             »·------------------            »·------                   »··-------
  Ready        »False   Thu, 05 Jun 2025 17:41:28 +0000   Thu, 05 Jun 2025 14:38:16 +0000   KubeletNotReady          »··container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized

Como solución alternativa, se puede montar un volumen tmpfs en el directorio /etc/cni antes de que se inicie RKE2. Esto evita el uso de overlayfs, lo que provoca que containerd pierda notificaciones y que las configuraciones deban reescribirse cada vez que se reinicia el nodo y se vuelven a ejecutar los contenedores de inicio de los pods. Si se utiliza EIB, esto puede hacerse con un guion 04-tmpfs-cni.sh en el directorio custom/scripts (como se explica aquí [https://github.com/suse-edge/edge-image-builder/blob/release-1.2/docs/building-images.md#custom), que tiene el siguiente aspecto:

#!/bin/bash
mkdir -p /etc/cni
mount -t tmpfs -o mode=0700,size=5M tmpfs /etc/cni
echo "tmpfs /etc/cni tmpfs defaults,size=5M,mode=0700 0 0" >> /etc/fstab

52.3.4 Versiones de componentes

La siguiente tabla describe los componentes individuales que conforman la versión 3.3.1, incluyendo la versión, la versión del chart de Helm (si procede) y desde donde se puede obtener el artefacto publicado en formato binario. Consulte la documentación asociada para ver ejemplos de uso y despliegue.

Nombre

Versión

Versión del chart de Helm

Ubicación del artefacto (URL/Imagen)

SUSE Linux Micro

6.1 (más reciente)

N/D

Página de descarga de SUSE Linux Micro
SL-Micro.x86_64-6.1-Base-SelfInstall-GM.install.iso (sha256 70b9be28f2d92bc3b228412e4fc2b1d5026e691874b728e530b8063522158854)
SL-Micro.x86_64-6.1-Base-RT-SelfInstall-GM.install.iso (sha256 9ce83e4545d4b36c7c6a44f7841dc3d9c6926fe32dbff694832e0fbd7c496e9d)
SL-Micro.x86_64-6.1-Base-GM.raw.xz (sha256 36e3efa55822113840dd76fdf6914e933a7b7e88a1dce5cb20c424ccf2fb4430)
SL-Micro.x86_64-6.1-Base-RT-GM.raw.xz (sha256 2ee66735da3e1da107b4878e73ae68f5fb7309f5ec02b5dfdb94e254fda8415e)

SUSE Multi-Linux Manager

5.0.3

N/D

Página de descarga de SUSE Multi-Linux Manager

K3s

1.32.4

N/D

Versión superior de K3s

RKE2

1.32.4

N/D

Versión superior de RKE2

SUSE Rancher Prime

2.11.2

2.11.2

Repositorio de Helm de Rancher Prime
Imágenes de contenedor de Rancher 2.11.1

SUSE Storage

1.8.1

106.2.0+up1.8.1

Repositorio de charts de Helm de Rancher
registry.suse.com/rancher/mirrored-longhornio-csi-attacher:v4.8.1
registry.suse.com/rancher/mirrored-longhornio-csi-provisioner:v5.2.0
registry.suse.com/rancher/mirrored-longhornio-csi-resizer:v1.13.2
registry.suse.com/rancher/mirrored-longhornio-csi-snapshotter:v8.2.0
registry.suse.com/rancher/mirrored-longhornio-csi-node-driver-registrar:v2.13.0
registry.suse.com/rancher/mirrored-longhornio-livenessprobe:v2.15.0
registry.suse.com/rancher/mirrored-longhornio-backing-image-manager:v1.8.1
registry.suse.com/rancher/mirrored-longhornio-longhorn-engine:v1.8.1
registry.suse.com/rancher/mirrored-longhornio-longhorn-instance-manager:v1.8.1
registry.suse.com/rancher/mirrored-longhornio-longhorn-manager:v1.8.1
registry.suse.com/rancher/mirrored-longhornio-longhorn-share-manager:v1.8.1
registry.suse.com/rancher/mirrored-longhornio-longhorn-ui:v1.8.1
registry.suse.com/rancher/mirrored-longhornio-support-bundle-kit:v0.0.52
registry.suse.com/rancher/mirrored-longhornio-longhorn-cli:v1.8.1

SUSE Security

5.4.4

106.0.1+up2.8.6

Repositorio de charts de Helm de Rancher
registry.suse.com/rancher/neuvector-controller:5.4.4
registry.suse.com/rancher/neuvector-enforcer:5.4.4
registry.suse.com/rancher/neuvector-manager:5.4.4
registry.suse.com/rancher/neuvector-compliance-config:1.0.5
registry.suse.com/rancher/neuvector-registry-adapter:0.1.6
registry.suse.com/rancher/neuvector-scanner:6
registry.suse.com/rancher/neuvector-updater:0.0.3

Rancher Turtles (CAPI)

0.20.0

303.0.4+up0.20.0

registry.suse.com/edge/charts/rancher-turtles:303.0.3_up0.20.0
registry.rancher.com/rancher/rancher/turtles:v0.20.0
registry.rancher.com/rancher/cluster-api-operator:v0.17.0
registry.rancher.com/rancher/cluster-api-metal3-controller:v1.9.3
registry.rancher.com/rancher/cluster-api-metal3-ipam-controller:v1.9.4
registry.suse.com/rancher/cluster-api-controller:v1.9.5
registry.suse.com/rancher/cluster-api-provider-rke2-bootstrap:v0.16.1
registry.suse.com/rancher/cluster-api-provider-rke2-controlplane:v0.16.1

Recursos de Rancher Turtles para entornos aislados

0.20.0

303.0.4+up0.20.0

registry.suse.com/edge/charts/rancher-turtles-airgap-resources:303.0.3_up0.20.0

Metal3

0.11.5

303.0.7+up0.11.5

registry.suse.com/edge/charts/metal3:303.0.7_up0.11.5
registry.suse.com/edge/3.3/baremetal-operator:0.9.1.1
registry.suse.com/edge/3.3/ironic:26.1.2.4
registry.suse.com/edge/3.3/ironic-ipa-downloader:3.0.7
registry.suse.com/edge/mariadb:10.6.15.1

MetalLB

0.14.9

303.0.0+up0.14.9

registry.suse.com/edge/charts/metallb:303.0.0_up0.14.9
registry.suse.com/edge/3.3/metallb-controller:v0.14.8
registry.suse.com/edge/3.3/metallb-speaker:v0.14.8
registry.suse.com/edge/3.3/frr:8.4
registry.suse.com/edge/3.3/frr-k8s:v0.0.14

Elemental

1.6.8

1.6.8

registry.suse.com/rancher/elemental-operator-chart:1.6.8
registry.suse.com/rancher/elemental-operator-crds-chart:1.6.8
registry.suse.com/rancher/elemental-operator:1.6.8

Extensión de panel de control de Elemental

3.0.1

3.0.1

Chart de Helm de extensión de Elemental

Edge Image Builder

1.2.1

N/D

registry.suse.com/edge/3.3/edge-image-builder:1.2.1

NM Configurator

0.3.3

N/D

Versión superior de NM Configurator

KubeVirt

1.4.0

303.0.0+up0.5.0

registry.suse.com/edge/charts/kubevirt:303.0.0_up0.5.0
registry.suse.com/suse/sles/15.6/virt-operator:1.4.0
registry.suse.com/suse/sles/15.6/virt-api:1.4.0
registry.suse.com/suse/sles/15.6/virt-controller:1.4.0
registry.suse.com/suse/sles/15.6/virt-exportproxy:1.4.0
registry.suse.com/suse/sles/15.6/virt-exportserver:1.4.0
registry.suse.com/suse/sles/15.6/virt-handler:1.4.0
registry.suse.com/suse/sles/15.6/virt-launcher:1.4.0

Extensión de panel de control KubeVirt

1.3.2

303.0.2+up1.3.2

registry.suse.com/edge/charts/kubevirt-dashboard-extension:303.0.2_up1.3.2

Containerized Data Importer

1.61.0

303.0.0+up0.5.0

registry.suse.com/edge/charts/cdi:303.0.0_up0.5.0
registry.suse.com/suse/sles/15.6/cdi-operator:1.61.0
registry.suse.com/suse/sles/15.6/cdi-controller:1.61.0
registry.suse.com/suse/sles/15.6/cdi-importer:1.61.0
registry.suse.com/suse/sles/15.6/cdi-cloner:1.61.0
registry.suse.com/suse/sles/15.6/cdi-apiserver:1.61.0
registry.suse.com/suse/sles/15.6/cdi-uploadserver:1.61.0
registry.suse.com/suse/sles/15.6/cdi-uploadproxy:1.61.0

Endpoint Copier Operator

0.2.0

303.0.0+up0.2.1

registry.suse.com/edge/charts/endpoint-copier-operator:303.0.0_up0.2.1
registry.suse.com/edge/3.3/endpoint-copier-operator:0.2.0

Akri (tecnología en fase preliminar)

0.12.20

303.0.0+up0.12.20

registry.suse.com/edge/charts/akri:303.0.0_up0.12.20
registry.suse.com/edge/charts/akri-dashboard-extension:303.0.0_up1.3.1
registry.suse.com/edge/3.3/akri-agent:v0.12.20
registry.suse.com/edge/3.3/akri-controller:v0.12.20
registry.suse.com/edge/3.3/akri-debug-echo-discovery-handler:v0.12.20
registry.suse.com/edge/3.3/akri-onvif-discovery-handler:v0.12.20
registry.suse.com/edge/3.3/akri-opcua-discovery-handler:v0.12.20
registry.suse.com/edge/3.3/akri-udev-discovery-handler:v0.12.20
registry.suse.com/edge/3.3/akri-webhook-configuration:v0.12.20

Operador de red SR-IOV

1.5.0

303.0.2+up1.5.0

registry.suse.com/edge/charts/sriov-network-operator:303.0.2_up1.5.0
registry.suse.com/edge/charts/sriov-crd:303.0.2_up1.5.0

System Upgrade Controller

0.15.2

106.0.0

Repositorio de charts de Helm de Rancher
registry.suse.com/rancher/system-upgrade-controller:v0.15.2

Upgrade Controller

0.1.1

303.0.1+up0.1.1

registry.suse.com/edge/charts/upgrade-controller:303.0.1_up0.1.1
registry.suse.com/edge/3.3/upgrade-controller:0.1.1
registry.suse.com/edge/3.3/kubectl:1.32.4
registry.suse.com/edge/3.3/release-manifest:3.3.1

Kiwi Builder

10.2.12.0

N/D

registry.suse.com/edge/3.3/kiwi-builder:10.2.12.0

52.4 Versión 3.3.0

Fecha de lanzamiento: 20 de mayo de 2025

Resumen: SUSE Edge 3.3.0 es la primera versión de SUSE Edge 3.3.

52.4.1 Funciones nuevas

52.4.2 Soluciones de seguridad y errores

  • Soluciona la CVE-2025-1974 con parches para ingress-nginx en RKE2. Encontrará más información aquí.

  • SUSE Storage (Longhorn) 1.8.1 contiene varias correcciones de errores, como:

  • La actualización del chart de Metal3 contiene varias correcciones de errores, como:

    • Se ha solucionado un error que se producía al desplegar clústeres con direcciones IP estáticas en redes con servidores DHCP: Problema de versión superior.

  • El chart de MetalLB contiene una corrección para garantizar que se usen imágenes descendentes si frr-k8s está habilitado.

  • Kiwi Builder se ha actualizado a la versión 10.2.12 para adaptarse a los recientes cambios de seguridad en Kiwi, pasando de los métodos de suma de verificación md5 a sha256 para la verificación de imágenes.

  • La imagen de Edge Image Builder se ha reconstruido para incluir la versión actualizada de MetalLB y abordar los cambios de Kiwi, ambos mencionados anteriormente.

52.4.3 Problemas conocidos

Aviso
Aviso

Si va a desplegar nuevos clústeres, siga las instrucciones del Capítulo 28, Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi para crear primero imágenes nuevas, ya que ahora este es el primer paso necesario para crear clústeres tanto para las arquitecturas AMD64/Intel 64 y AArch64 como para los clústeres de gestión y los clústeres descendentes.

  • Cuando se usa toolbox en SUSE Linux Micro 6.1, la imagen de contenedor predeterminada no contiene algunas herramientas que se incluían en la versión 5.5 anterior. La solución alternativas es configurar toolbox para que use la imagen de contenedor suse/sle-micro/5.5/toolbox anterior. Consulte toolbox --help para ver las opciones de configuración de la imagen.

  • En algunos casos, las actualizaciones progresivas a través de CAPI pueden provocar que las máquinas se queden bloqueadas en el estado "Deleting" (Eliminando). Esto se resolverá mediante una futura actualización: Problema 655 de versión superior del proveedor de RKE2

  • En algunos casos, al usar un clúster de gestión que se ha actualizado desde Edge 3.2, las actualizaciones progresivas descendentes a través de CAPI pueden provocar que los equipos se queden bloqueados en el estado "Deleting" (Eliminando). Esto se resolverá en una futura actualización: Problema 661 de versión superior del proveedor de RKE2

  • Al usar la versión 1.32.3 de RKE2, que resuelve la CVE-2025-1974, SUSE Linux Micro 6.1 debe actualizarse para incluir el kernel >=6.4.0-26-default o >=6.4.0-30-rt (kernel en tiempo real) debido a los parches necesarios para el kernel de SELinux. Si no se aplica, el pod ingress-nginx permanecerá en estado CrashLoopBackOff. Para aplicar la actualización del kernel, ejecute transactional-update en el propio host (para actualizar todos los paquetes) o transactional-update pkg update kernel-default (o el kernel en tiempo real) para actualizar solo el kernel y, a continuación, rearranque el host. Si va a desplegar nuevos clústeres, siga el Capítulo 28, Creación de imágenes actualizadas de SUSE Linux Micro con Kiwi para crear imágenes nuevas que contengan el kernel más reciente.

  • Al configurar la red mediante nm-configurator, algunas configuraciones que identifican interfaces por su MAC no funcionan actualmente, esto se resolverá en una futura actualización: Problema de versión superior de NM Configurator

  • En clústeres de gestión de Metal3 que llevan mucho tiempo en funcionamiento, es posible que la caducidad del certificado provoque un fallo en la conexión del operador bare metal con Ironic, lo que requiere una solución alternativa consistente en reiniciar manualmente el pod: Problema de charts de SUSE Edge

  • Se ha identificado un error en el controlador de trabajos de Kubernetes que, en determinadas condiciones, puede provocar que los nodos RKE2/K3s permanezcan en estado NotReady (consulte el problema n.º 8357 de RKE2). Los errores pueden tener el siguiente aspecto:

E0605 23:11:18.489721   	1 job_controller.go:631] "Unhandled Error" err="syncing job: tracking status: adding uncounted pods to status: Operation cannot be fulfilled on jobs.batch \"helm-install-rke2-ingress-nginx\": StorageError: invalid object, Code: 4, Key: /registry/jobs/kube-system/helm-install-rke2-ingress-nginx, ResourceVersion: 0, AdditionalErrorMsg: Precondition failed: UID in precondition: 0aa6a781-7757-4c61-881a-cb1a4e47802c, UID in object meta: 6a320146-16b8-4f83-88c5-fc8b5a59a581" logger="UnhandledError"

Como solución, el pod kube-controller-manager se puede reiniciar con crictl como:

export CONTAINER_RUNTIME_ENDPOINT=unix:///run/k3s/containerd/containerd.sock
export KUBEMANAGER_POD=$(/var/lib/rancher/rke2/bin/crictl ps --label io.kubernetes.container.name=kube-controller-manager --quiet)
/var/lib/rancher/rke2/bin/crictl stop ${KUBEMANAGER_POD} && \
/var/lib/rancher/rke2/bin/crictl rm ${KUBEMANAGER_POD}
  • En las versiones 1.31 y 1.32 de RKE2/K3s, es posible que el directorio /etc/cni utilizado para almacenar las configuraciones de CNI no active una notificación de los archivos que se escriben allí en containerd debido a ciertas condiciones relacionadas con overlayfs (consulte el problema n.º 8356 de RKE2). Esto, a su vez, provoca que el despliegue de RKE2/K3s se quede bloqueado a la espera de que se inicie la CNI y que los nodos RKE2/K3s permanecen en estado NotReady. Puede observar este problema en cada nodo con kubectl describe node <nodo_afectado>:

​​Conditions:
  Type         	Status  LastHeartbeatTime             	LastTransitionTime            	Reason                   	Message
  ----         	------  -----------------             	------------------            	------                   	-------
  Ready        	False   Thu, 05 Jun 2025 17:41:28 +0000   Thu, 05 Jun 2025 14:38:16 +0000   KubeletNotReady          	container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized

Como solución alternativa, se puede montar un volumen tmpfs en el directorio /etc/cni antes de que se inicie RKE2. Esto evita el uso de overlayfs, lo que provoca que containerd pierda notificaciones y que las configuraciones deban reescribirse cada vez que se reinicia el nodo y se vuelven a ejecutar los contenedores de inicio de los pods. Si se utiliza EIB, esto puede hacerse con un guion 04-tmpfs-cni.sh en el directorio custom/scripts (como se explica aquí [https://github.com/suse-edge/edge-image-builder/blob/release-1.2/docs/building-images.md#custom), que tiene el siguiente aspecto:

#!/bin/bash
mkdir -p /etc/cni
mount -t tmpfs -o mode=0700,size=5M tmpfs /etc/cni
echo "tmpfs /etc/cni tmpfs defaults,size=5M,mode=0700 0 0" >> /etc/fstab

52.4.4 Versiones de componentes

La siguiente tabla describe los componentes individuales que conforman la versión 3.3.0, incluyendo la versión, la versión del chart de Helm (si procede) y desde dónde se puede obtener el artefacto publicado en formato binario. Siga la documentación asociada para ver ejemplos de uso y distribución.

Nombre

Versión

Versión del chart de Helm

Ubicación del artefacto (URL/Imagen)

SUSE Linux Micro

6.1 (más reciente)

N/D

Página de descarga de SUSE Linux Micro
SL-Micro.x86_64-6.1-Base-SelfInstall-GM.install.iso (sha256 70b9be28f2d92bc3b228412e4fc2b1d5026e691874b728e530b8063522158854)
SL-Micro.x86_64-6.1-Base-RT-SelfInstall-GM.install.iso (sha256 9ce83e4545d4b36c7c6a44f7841dc3d9c6926fe32dbff694832e0fbd7c496e9d)
SL-Micro.x86_64-6.1-Base-GM.raw.xz (sha256 36e3efa55822113840dd76fdf6914e933a7b7e88a1dce5cb20c424ccf2fb4430)
SL-Micro.x86_64-6.1-Base-RT-GM.raw.xz (sha256 2ee66735da3e1da107b4878e73ae68f5fb7309f5ec02b5dfdb94e254fda8415e)

SUSE Multi-Linux Manager

5.0.3

N/D

Página de descarga de SUSE Multi-Linux Manager

K3s

1.32.3

N/D

Versión superior de K3s

RKE2

1.32.3

N/D

Versión superior de RKE2

SUSE Rancher Prime

2.11.1

2.11.1

Repositorio de Helm de Rancher Prime
Imágenes de contenedor de Rancher 2.11.1

SUSE Storage

1.8.1

106.2.0+up1.8.1

Repositorio de charts de Helm de Rancher
registry.suse.com/rancher/mirrored-longhornio-csi-attacher:v4.7.0
registry.suse.com/rancher/mirrored-longhornio-csi-provisioner:v4.0.1-20241007
registry.suse.com/rancher/mirrored-longhornio-csi-resizer:v1.12.0
registry.suse.com/rancher/mirrored-longhornio-csi-snapshotter:v7.0.2-20241007
registry.suse.com/rancher/mirrored-longhornio-csi-node-driver-registrar:v2.12.0
registry.suse.com/rancher/mirrored-longhornio-livenessprobe:v2.14.0
registry.suse.com/rancher/mirrored-longhornio-backing-image-manager:v1.7.2
registry.suse.com/rancher/mirrored-longhornio-longhorn-engine:v1.7.2
registry.suse.com/rancher/mirrored-longhornio-longhorn-instance-manager:v1.7.2
registry.suse.com/rancher/mirrored-longhornio-longhorn-manager:v1.7.2
registry.suse.com/rancher/mirrored-longhornio-longhorn-share-manager:v1.7.2
registry.suse.com/rancher/mirrored-longhornio-longhorn-ui:v1.7.2
registry.suse.com/rancher/mirrored-longhornio-support-bundle-kit:v0.0.45
registry.suse.com/rancher/mirrored-longhornio-longhorn-cli:v1.7.2

SUSE Security

5.4.3

106.0.0+up2.8.5

Repositorio de charts de Helm de Rancher
registry.suse.com/rancher/neuvector-controller:5.4.3
registry.suse.com/rancher/neuvector-enforcer:5.4.3
registry.suse.com/rancher/neuvector-manager:5.4.3
registry.suse.com/rancher/neuvector-compliance-config:1.0.4
registry.suse.com/rancher/neuvector-registry-adapter:0.1.6
registry.suse.com/rancher/neuvector-scanner:6
registry.suse.com/rancher/neuvector-updater:0.0.2

Rancher Turtles (CAPI)

0.19.0

303.0.2+up0.19.0

registry.suse.com/edge/charts/rancher-turtles:303.0.2_up0.19.0
registry.rancher.com/rancher/rancher/turtles:v0.19.0
registry.rancher.com/rancher/cluster-api-operator:v0.17.0
registry.rancher.com/rancher/cluster-api-metal3-controller:v1.9.3
registry.rancher.com/rancher/cluster-api-metal3-ipam-controller:v1.9.4
registry.suse.com/rancher/cluster-api-controller:v1.9.5
registry.suse.com/rancher/cluster-api-provider-rke2-bootstrap:v0.15.1
registry.suse.com/rancher/cluster-api-provider-rke2-controlplane:v0.15.1

Recursos de Rancher Turtles para entornos aislados

0.19.0

303.0.2+up0.19.0

registry.suse.com/edge/charts/rancher-turtles-airgap-resources:303.0.2_up0.19.0

Metal3

0.11.3

303.0.5+up0.11.3

registry.suse.com/edge/charts/metal3:303.0.5_up0.11.3
registry.suse.com/edge/3.3/baremetal-operator:0.9.1
registry.suse.com/edge/3.3/ironic:26.1.2.4
registry.suse.com/edge/3.3/ironic-ipa-downloader:3.0.6
registry.suse.com/edge/mariadb:10.6.15.1

MetalLB

0.14.9

303.0.0+up0.14.9

registry.suse.com/edge/charts/metallb:303.0.0_up0.14.9
registry.suse.com/edge/3.3/metallb-controller:v0.14.8
registry.suse.com/edge/3.3/metallb-speaker:v0.14.8
registry.suse.com/edge/3.3/frr:8.4
registry.suse.com/edge/3.3/frr-k8s:v0.0.14

Elemental

1.6.8

1.6.8

registry.suse.com/rancher/elemental-operator-chart:1.6.8
registry.suse.com/rancher/elemental-operator-crds-chart:1.6.8
registry.suse.com/rancher/elemental-operator:1.6.8

Extensión de panel de control de Elemental

3.0.1

3.0.1

Chart de Helm de extensión de Elemental

Edge Image Builder

1.2.0

N/D

registry.suse.com/edge/3.3/edge-image-builder:1.2.0

NM Configurator

0.3.2

N/D

Versión superior de NM Configurator

KubeVirt

1.4.0

303.0.0+up0.5.0

registry.suse.com/edge/charts/kubevirt:303.0.0_up0.5.0
registry.suse.com/suse/sles/15.6/virt-operator:1.4.0
registry.suse.com/suse/sles/15.6/virt-api:1.4.0
registry.suse.com/suse/sles/15.6/virt-controller:1.4.0
registry.suse.com/suse/sles/15.6/virt-exportproxy:1.4.0
registry.suse.com/suse/sles/15.6/virt-exportserver:1.4.0
registry.suse.com/suse/sles/15.6/virt-handler:1.4.0
registry.suse.com/suse/sles/15.6/virt-launcher:1.4.0

Extensión de panel de control KubeVirt

1.3.2

303.0.2+up1.3.2

registry.suse.com/edge/charts/kubevirt-dashboard-extension:303.0.2_up1.3.2

Containerized Data Importer

1.61.0

303.0.0+up0.5.0

registry.suse.com/edge/charts/cdi:303.0.0_up0.5.0
registry.suse.com/suse/sles/15.6/cdi-operator:1.61.0
registry.suse.com/suse/sles/15.6/cdi-controller:1.61.0
registry.suse.com/suse/sles/15.6/cdi-importer:1.61.0
registry.suse.com/suse/sles/15.6/cdi-cloner:1.61.0
registry.suse.com/suse/sles/15.6/cdi-apiserver:1.61.0
registry.suse.com/suse/sles/15.6/cdi-uploadserver:1.61.0
registry.suse.com/suse/sles/15.6/cdi-uploadproxy:1.61.0

Endpoint Copier Operator

0.2.0

303.0.0+up0.2.1

registry.suse.com/edge/charts/endpoint-copier-operator:303.0.0_up0.2.1
registry.suse.com/edge/3.3/endpoint-copier-operator:0.2.0

Akri (tecnología en fase preliminar)

0.12.20

303.0.0+up0.12.20

registry.suse.com/edge/charts/akri:303.0.0_up0.12.20
registry.suse.com/edge/charts/akri-dashboard-extension:303.0.0_up1.3.1
registry.suse.com/edge/3.3/akri-agent:v0.12.20
registry.suse.com/edge/3.3/akri-controller:v0.12.20
registry.suse.com/edge/3.3/akri-debug-echo-discovery-handler:v0.12.20
registry.suse.com/edge/3.3/akri-onvif-discovery-handler:v0.12.20
registry.suse.com/edge/3.3/akri-opcua-discovery-handler:v0.12.20
registry.suse.com/edge/3.3/akri-udev-discovery-handler:v0.12.20
registry.suse.com/edge/3.3/akri-webhook-configuration:v0.12.20

Operador de red SR-IOV

1.5.0

303.0.2+up1.5.0

registry.suse.com/edge/charts/sriov-network-operator:303.0.2_up1.5.0
registry.suse.com/edge/charts/sriov-crd:303.0.2_up1.5.0

System Upgrade Controller

0.15.2

106.0.0

Repositorio de charts de Helm de Rancher
registry.suse.com/rancher/system-upgrade-controller:v0.15.2

Upgrade Controller

0.1.1

303.0.0+up0.1.1

registry.suse.com/edge/charts/upgrade-controller:303.0.0_up0.1.1
registry.suse.com/edge/3.3/upgrade-controller:0.1.1
registry.suse.com/edge/3.3/kubectl:1.30.3
registry.suse.com/edge/3.3/release-manifest:3.3.0

Kiwi Builder

10.2.12.0

N/D

registry.suse.com/edge/3.3/kiwi-builder:10.2.12.0

52.5 Tecnologías en fase preliminar

A menos que se indique lo contrario, esto se aplica a la versión 3.3.0 y a todas las versiones z-stream posteriores.

  • Akri se ofrece como tecnología en fase preliminar y no está sujeta al alcance estándar de la asistencia técnica.

  • Los despliegues de IPv6 y de doble pila descendentes se ofrecen como tecnologías en fase preliminar y no están sujetas al alcance estándar de la asistencia técnica.

  • El protocolo de tiempo de precisión (PTP) en despliegues descendentes se ofrece como tecnología en fase preliminar y no está sujeto al alcance estándar de la asistencia técnica.

52.6 Verificación de componentes

Los componentes mencionados anteriormente pueden verificarse utilizando los datos de la lista de materiales de software (SBOM), por ejemplo, utilizando cosign como se describe a continuación:

Descargue la clave pública del contenedor de SUSE Edge desde la fuente de claves de firma de SUSE:

> cat key.pem
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA7N0S2d8LFKW4WU43bq7Z
IZT537xlKe17OQEpYjNrdtqnSwA0/jLtK83m7bTzfYRK4wty/so0g3BGo+x6yDFt
SVXTPBqnYvabU/j7UKaybJtX3jc4SjaezeBqdi96h6yEslvg4VTZDpy6TFP5ZHxZ
A0fX6m5kU2/RYhGXItoeUmL5hZ+APYgYG4/455NBaZT2yOywJ6+1zRgpR0cRAekI
OZXl51k0ebsGV6ui/NGECO6MB5e3arAhszf8eHDE02FeNJw5cimXkgDh/1Lg3KpO
dvUNm0EPWvnkNYeMCKR+687QG0bXqSVyCbY6+HG/HLkeBWkv6Hn41oeTSLrjYVGa
T3zxPVQM726sami6pgZ5vULyOleQuKBZrlFhFLbFyXqv1/DokUqEppm2Y3xZQv77
fMNogapp0qYz+nE3wSK4UHPd9z+2bq5WEkQSalYxadyuqOzxqZgSoCNoX5iIuWte
Zf1RmHjiEndg/2UgxKUysVnyCpiWoGbalM4dnWE24102050Gj6M4B5fe73hbaRlf
NBqP+97uznnRlSl8FizhXzdzJiVPcRav1tDdRUyDE2XkNRXmGfD3aCmILhB27SOA
Lppkouw849PWBt9kDMvzelUYLpINYpHRi2+/eyhHNlufeyJ7e7d6N9VcvjR/6qWG
64iSkcF2DTW61CN5TrCe0k0CAwEAAQ==
-----END PUBLIC KEY-----

Verifique el hash de la imagen del contenedor; por ejemplo, usando crane:

> crane digest registry.suse.com/edge/3.3/baremetal-operator:0.9.1 --platform linux/amd64
sha256:02c5590cd51b1a1ea02f9908f2184ef4fbc856eb0197e804a7d57566d9278ddd
Nota
Nota

Para imágenes de varias arquitecturas, también es necesario especificar una plataforma al obtener el resumen; por ejemplo, --platform linux/amd64 o --platform linux/arm64. Si no se hace, en el siguiente paso se producirá el error Error: no matching attestations (Error: no hay certificaciones que coincidan).

Verifíquelo con cosign:

> cosign verify-attestation --type spdxjson --key key.pem registry.suse.com/edge/3.3/baremetal-operator@sha256:02c5590cd51b1a1ea02f9908f2184ef4fbc856eb0197e804a7d57566d9278ddd > /dev/null
#
Verification for registry.suse.com/edge/3.3/baremetal-operator@sha256:02c5590cd51b1a1ea02f9908f2184ef4fbc856eb0197e804a7d57566d9278ddd --
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - The claims were present in the transparency log
  - The signatures were integrated into the transparency log when the certificate was valid
  - The signatures were verified against the specified public key

Extraiga los datos SBOM como se describe en la documentación de SBOM de SUSE:

> cosign verify-attestation --type spdxjson --key key.pem registry.suse.com/edge/3.2/baremetal-operator@sha256:d85c1bcd286dec81a3806a8fb8b66c0e0741797f23174f5f6f41281b1e27c52f | jq '.payload | @base64d | fromjson | .predicate'

52.7 Pasos para la actualización

Consulte la Parte VI, “Operaciones de día 2” para obtener información sobre cómo actualizar a una versión nueva.

52.8 Ciclo de vida de la asistencia técnica del producto

SUSE Edge cuenta con el galardonado servicio de asistencia técnica de SUSE, un líder tecnológico consolidado con una trayectoria probada en la prestación de servicios de asistencia técnica de calidad empresarial. Para obtener más información, consulte https://www.suse.com/lifecycle y la página de la política de asistencia técnica en https://www.suse.com/support/policy.html. Si tiene alguna pregunta sobre cómo abrir un caso de asistencia, cómo clasifica SUSE los niveles de gravedad o el alcance de la asistencia, consulte el Manual de asistencia técnica en https://www.suse.com/support/handbook/.

SUSE Edge "3.3" cuenta con 18 meses de asistencia para producción, con 6 meses iniciales de "asistencia completa", seguidos de 12 meses de "asistencia de mantenimiento". Tras estas fases, el producto alcanza el "fin de vida útil" y deja de recibir asistencia. En la siguiente tabla se ofrece más información sobre las fases del ciclo de vida:

Asistencia completa (6 meses)

Durante el periodo de asistencia completa, se publicarán correcciones de errores urgentes y seleccionadas de alta prioridad. El resto de parches (no urgentes, mejoras, nuevas capacidades) se publicarán según el calendario de lanzamientos habitual.

Asistencia de mantenimiento (12 meses)

Durante este periodo, solo se publicarán correcciones críticas mediante parches. Otras correcciones de errores podrán publicarse a discreción de SUSE, pero no deben esperarse.

Fin de vida útil

Una vez que un producto alcanza su fecha de fin de vida útil, el cliente puede seguir utilizándolo dentro de los términos del contrato de licencia del producto. Los planes de asistencia de SUSE no se aplican a los productos que hayan superado su fecha de fin de vida útil.

A menos que se indique explícitamente lo contrario, todos los componentes mostrados se consideran de disponibilidad general y están cubiertos por el alcance estándar de la asistencia técnica de SUSE. Algunos componentes pueden aparecer como "tecnología en fase preliminar", lo que significa que SUSE proporciona a los clientes acceso a características y funcionalidades antes de que estén disponibles de forma generalizada para su evaluación, pero no están sujetos a las políticas de asistencia técnica estándar y no se recomiendan para casos de uso en producción. SUSE agradece enormemente los comentarios y sugerencias sobre las mejoras que se pueden realizar en los componentes de tecnología en fase preliminar, pero se reserva el derecho de descartar una función de tecnología en fase preliminar antes de que pase a estar disponible de forma generalizada si no satisface las necesidades de nuestros clientes o no alcanza el estado de madurez que requerimos.

Tenga en cuenta que SUSE debe, ocasionalmente, dejar de utilizar funciones o cambiar las especificaciones de la API. Las razones para dejar de utilizar una función o cambiar la API pueden incluir la actualización o sustitución de una función por una nueva implementación, un nuevo conjunto de funciones, la indisponibilidad de la tecnología original o la introducción de cambios incompatibles por parte de la comunidad original. No se pretende que esto ocurra nunca dentro de una versión menor determinada (x.z), por lo que todas las versiones z-stream mantendrán la compatibilidad de la API y la funcionalidad de las funciones. SUSE se esforzará por proporcionar avisos de descatalogación con suficiente antelación en las notas de la versión, junto con soluciones alternativas, sugerencias y medidas paliativas para minimizar la interrupción del servicio.

El equipo de SUSE Edge también agradece los comentarios de la comunidad, que pueden plantear sus cuestiones dentro del repositorio de código correspondiente en https://www.github.com/suse-edge.

52.9 Obtención del código fuente

Este producto de SUSE incluye materiales licenciados a SUSE bajo la Licencia Pública General de GNU (GPL) y otras licencias de código abierto. La GPL exige a SUSE que proporcione el código fuente correspondiente al material licenciado bajo la GPL, y SUSE cumple con todos los demás requisitos de las licencias de código abierto. Por lo tanto, SUSE pone a disposición todo el código fuente, que generalmente se puede encontrar en el repositorio GitHub de SUSE Edge (https://www.github.com/suse-edge), el repositorio GitHub de SUSE Rancher (https://www.github.com/rancher) para los componentes dependientes y, específicamente para SUSE Linux Micro, el código fuente está disponible para su descarga en https://www.suse.com/download/sle-micro en "Medium 2".

Documentation survey