|Index|SUSE Telco Cloud Documentação|Provisionamento de rede direcionado totalmente automatizado|Provisionamento de cluster downstream com provisionamento de rede direcionado (multi-nó)
Applies to SUSE Telco Cloud 3.6

52 Provisionamento de cluster downstream com provisionamento de rede direcionado (multi-nó)

Esta seção descreve o fluxo de trabalho usado para automatizar o provisionamento de um cluster downstream multi-nó usando provisionamento de rede direcionado e MetalLB como estratégia de balanceador de carga. Esta é a maneira mais simples de automatizar o provisionamento de um cluster downstream. O diagrama a seguir mostra o fluxo de trabalho usado para automatizar o provisionamento de um cluster downstream multi-nó usando provisionamento de rede direcionado e MetalLB.

Requisitos

Fluxo de trabalho

O diagrama a seguir mostra o fluxo de trabalho usado para automatizar o provisionamento de um cluster downstream multi-nó usando provisionamento de rede direcionado:

atip automate multinode1
  1. Registre os três hosts bare-metal para torná-los disponíveis para o processo de provisionamento.

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

Registre os hosts bare-metal

O primeiro passo é inscrever os três hosts bare-metal no cluster de gerenciamento para torná-los disponíveis para serem provisionados. Para fazer isso, os seguintes arquivos (bmh-example-node1.yaml, bmh-example-node2.yaml e bmh-example-node3.yaml) devem ser criados no cluster de gerenciamento, para especificar as credenciais BMC a serem usadas e o objeto BaremetalHost a ser inscrito no cluster de gerenciamento.

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

  • Nós o guiaremos pelo processo para apenas um host. As mesmas etapas se aplicam aos outros dois nós.

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

Onde:

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

  • ${BMC_NODE1_PASSWORD} — A senha para o BMC do primeiro host bare-metal.

  • ${BMC_NODE1_MAC} — O endereço MAC do primeiro host bare-metal a ser usado.

  • ${BMC_NODE1_ADDRESS} — A URL para o BMC do primeiro host bare-metal (por exemplo, redfish-virtualmedia://192.168.200.75/redfish/v1/Systems/1/). A parte do host da URL pode ser um endereço IP (v4 ou v6) ou um nome de domínio, onde a infraestrutura existente permita. Para saber mais sobre as diferentes opções disponíveis dependendo do seu provedor de hardware, verifique o seguinte link.

Note
Note
  • Se nenhuma configuração de rede para o host tiver sido especificada, seja no momento da criação da imagem ou por meio da definição BareMetalHost, um mecanismo de autoconfiguração (DHCP, DHCPv6, SLAAC) será usado. Para mais detalhes ou configurações complexas, verifique o Chapter 53, Configuração de rede avançada.

  • Clusters IPv6 de pilha única estão em status de prévia técnica e ainda não são oficialmente suportados.

  • A arquitetura deve ser x86_64 ou aarch64, dependendo da arquitetura do host bare-metal a ser inscrito.

  • Todos os servidores modernos vêm com um BMC capaz de dual-stack; no entanto, o suporte a IPv6 (e possivelmente a opção de usar nomes de host para a capacidade VirtualMedia) deve ser verificado antes do uso em produção em um ambiente dual-stack.

Uma vez que o arquivo seja criado, o seguinte comando deve ser executado no cluster de gerenciamento para começar a inscrever os hosts bare-metal no cluster de gerenciamento:

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

Os novos objetos de host bare-metal são inscritos, alterando seu estado de registering para inspecting e available. As alterações podem ser verificadas usando o seguinte comando:

$ kubectl get bmh -o wide
Note
Note

O objeto BaremetalHost fica no estado registering até que as credenciais BMC sejam validadas. Assim que as credenciais forem validadas, o objeto BaremetalHost altera seu estado para inspecting, e esta etapa pode levar algum tempo dependendo do hardware (até 20 minutos). Durante a fase de inspeção, as informações de hardware são recuperadas e o objeto Kubernetes é atualizado. Verifique as informações usando o seguinte comando: kubectl get bmh -o yaml.

Etapa de provisionamento

Uma vez que os três hosts bare-metal estejam inscritos e disponíveis, o próximo passo é provisionar os hosts bare-metal para instalar e configurar o sistema operacional e o cluster Kubernetes, criando um balanceador de carga para gerenciá-los. Para fazer isso, o seguinte arquivo (capi-provisioning-example.yaml) deve ser criado no cluster de gerenciamento com as seguintes informações (o `capi-provisioning-example.yaml pode ser gerado unindo os seguintes blocos).

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

  • O endereço VIP é um endereço IP reservado que não é atribuído a nenhum nó e é usado para configurar o balanceador de carga. Em um cluster dual-stack, tanto um IPv4 quanto um IPv6 podem ser especificados, mas nos exemplos a seguir será dada prioridade ao endereço IPv4.

Abaixo está a definição do cluster, onde a rede do cluster pode ser configurada usando os blocos pods e services. Além disso, ele contém as referências aos objetos do plano de controle e da infraestrutura (usando o provedor Metal3) a serem usados.

apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
  name: multinode-cluster
  namespace: default
  labels:
    cluster-api.cattle.io/rancher-auto-import: "true"
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - 192.168.0.0/18
        - fd00:1234:4321::/48
    services:
      cidrBlocks:
        - 10.96.0.0/12
        - fd00:5678:8765:4321::/112
  controlPlaneRef:
    apiGroup: controlplane.cluster.x-k8s.io
    kind: RKE2ControlPlane
    name: multinode-cluster
  infrastructureRef:
    apiGroup: infrastructure.cluster.x-k8s.io
    kind: Metal3Cluster
    name: multinode-cluster
Note
Note
  • Ambas as implantações single-stack e dual-stack são possíveis. Remova os CIDRs IPv6 e os endereços VIP IPv6 (nas seções subsequentes) para um cluster apenas IPv4.

  • Adicionar o rótulo cluster-api.cattle.io/rancher-auto-import: "true" aos objetos cluster.x-k8s.io importará o cluster para o Rancher (criando um objeto clusters.management.cattle.io correspondente). Consulte a documentação da API de Cluster para obter mais informações.

O objeto Metal3Cluster especifica o endpoint do plano de controle que usa o endereço VIP já reservado (substituindo o ${EDGE_VIP_ADDRESS_IPV4}) a ser configurado e o noCloudProvider porque os três nós bare-metal são usados.

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

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

  • Uma anotação de exclusão de balanceador de carga que informa aos balanceadores de carga externos, como o MetalLB, que um nó será drenado durante operações de ciclo de vida, como fazer upgrade de clusters downstream. Para obter os detalhes, consulte: Section 59.1, “Exclusão de balanceador de carga”

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

  • O modo de anúncio a ser usado pelo Balanceador de Carga (address usa a implementação L2), bem como o endereço a ser usado (substituindo o ${EDGE_VIP_ADDRESS} pelo endereço VIP).

  • O serverConfig com o plug-in CNI a ser usado (neste caso, Cilium), e o(s) endereço(s) e nome(s) VIP adicionais a serem listados em tlsSan.

  • O bloco agentConfig contém o Ignition formato a ser usado e o additionalUserData a ser usado para configurar o RKE2 nó com informações como:

    • O serviço systemd chamado rke2-preinstall.service para substituir automaticamente o BAREMETALHOST_UUID e o node-name durante o processo de provisionamento usando as informações do Ironic, além de adicionar o rótulo metal3.io/uuid aos objetos Node com o UUID BareMetalHost.

    • O serviço systemd chamado rke2-traefik-deployment.service para definir a opção de configuração server do RKE2 ingress-controller no arquivo /etc/rancher/rke2/config.yaml como traefik.

    • O bloco storage que contém os Helm charts a serem usados para instalar o MetalLB e o endpoint-copier-operator.

    • O arquivo de recurso personalizado metalLB com o IPaddressPool e o L2Advertisement a serem usados (substituindo ${EDGE_VIP_ADDRESS_IPV4} pelo endereço VIP).

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

  • O último bloco de informações contém a versão do Kubernetes a ser usada. O ${RKE2_VERSION} é a versão do RKE2 a ser usada substituindo este valor (por exemplo, v1.35.4+rke2r1).

apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: RKE2ControlPlane
metadata:
  name: multinode-cluster
  namespace: default
  annotations: {
    rke2.controlplane.cluster.x-k8s.io/load-balancer-exclusion: "true"
  }
spec:
  infrastructureRef:
    apiGroup: infrastructure.cluster.x-k8s.io
    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_IPV4}
      - ${EDGE_VIP_ADDRESS_IPV6}
      - https://${EDGE_VIP_ADDRESS_IPV4}.sslip.io
      - https://${EDGE_VIP_ADDRESS_IPV6}.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"
              ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStartPost=/bin/sh -c "umount /mnt"
              [Install]
              WantedBy=multi-user.target
          # rke2-traefik-deployment.service unit to be removed once "traefik" being the default ingress controller (starting with RKE2 v1.36)
          - name: rke2-traefik-deployment.service
            enabled: true
            contents: |
              [Unit]
              Description=rke2-traefik-deployment
              Wants=rke2-preinstall.service
              Before=rke2-install.service
              ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
              [Service]
              Type=oneshot
              User=root
              ExecStart=/bin/sh -c "echo \"ingress-controller: traefik\" >> /etc/rancher/rke2/config.yaml"
              [Install]
              WantedBy=multi-user.target
        storage:
          directories:
          - path: /var/lib/rancher/rke2/server/manifests
            overwrite: true
          files:
            # 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: 306.0.1+up0.3.0
                    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: 306.0.2+up0.15.3
                    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_IPV4}/32
                      - ${EDGE_VIP_ADDRESS_IPV6}/128
                    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:
                    ipFamilyPolicy: PreferDualStack
                    ports:
                    - name: rke2-api
                      port: 9345
                      protocol: TCP
                      targetPort: 9345
                    - name: k8s-api
                      port: 6443
                      protocol: TCP
                      targetPort: 6443
                    type: LoadBalancer
          - path: /var/lib/rancher/rke2/server/manifests/rke2-traefik-config.yaml
            overwrite: true
            contents:
              inline: |
                apiVersion: helm.cattle.io/v1
                kind: HelmChartConfig
                metadata:
                  name: rke2-traefik
                  namespace: kube-system
                spec:
                  valuesContent: |-
                    ingressClass:
                      isDefaultClass: true
                    ports:
                      web:
                        hostPort: null    # disallow hostPort
                        exposedPort: 80
                      websecure:
                        hostPort: null    # disallow hostPort
                        exposedPort: 443
                    service:
                      enabled: true
                      type: LoadBalancer
                      spec:
                        externalTrafficPolicy: Local
                        allocateLoadBalancerNodePorts: false  # k8s GA from 1.24; supported by MetalLB
            mode: 0644
            user:
              name: root
            group:
              name: root
    kubelet:
      extraArgs:
      - provider-id=metal3://BAREMETALHOST_UUID
    nodeName: "Node-multinode-cluster"

O objeto Metal3MachineTemplate especifica as seguintes informações:

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

O objeto Metal3DataTemplate especifica o metaData para o cluster downstream.

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

Os arquivos yaml a seguir são um exemplo de configuração para os nós de trabalho.

A MachineDeployment:

apiVersion: cluster.x-k8s.io/v1beta2
kind: MachineDeployment
metadata:
  labels:
    cluster.x-k8s.io/cluster-name: multinode-cluster
    nodepool: nodepool-0
  name: multinode-cluster-workers
  namespace: default
spec:
  clusterName: multinode-cluster
  replicas: 3
  selector:
    matchLabels:
      cluster.x-k8s.io/cluster-name: multinode-cluster
      nodepool: nodepool-0
  template:
    metadata:
      labels:
        cluster.x-k8s.io/cluster-name: multinode-cluster
        nodepool: nodepool-0
    spec:
      bootstrap:
        configRef:
          apiGroup: bootstrap.cluster.x-k8s.io
          kind: RKE2ConfigTemplate
          name: multinode-cluster-workers
      clusterName: multinode-cluster
      infrastructureRef:
        apiGroup: infrastructure.cluster.x-k8s.io
        kind: Metal3MachineTemplate
        name: multinode-cluster-workers
      deletion:
        nodeDrainTimeoutSeconds: 0
      version: ${RKE2_VERSION}

O objeto RKE2ConfigTemplate especifica o modelo de configuração a ser usado para nós de trabalho de cluster com vários nós.

apiVersion: bootstrap.cluster.x-k8s.io/v1beta2
kind: RKE2ConfigTemplate
metadata:
  name: multinode-cluster-workers
  namespace: default
spec:
  template:
    spec:
      agentConfig:
        format: ignition
        kubelet:
          extraArgs:
          - provider-id=metal3://BAREMETALHOST_UUID
        nodeName: "Node-multinode-cluster-worker"
        additionalUserData:
          config: |
            variant: fcos
            version: 1.4.0
            systemd:
              units:
              - name: rke2-preinstall.service
                enabled: true
                contents: |
                  [Unit]
                  Description=rke2-preinstall
                  Wants=network-online.target
                  Before=rke2-install.service
                  ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                  [Service]
                  Type=oneshot
                  User=root
                  ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                  ExecStart=/bin/sh -c "sed -i \"s/BAREMETALHOST_UUID/$(jq -r .uuid /mnt/openstack/latest/meta_data.json)/\" /etc/rancher/rke2/config.yaml"
                  ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                  ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
                  ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                  ExecStartPost=/bin/sh -c "umount /mnt"
                  [Install]
                  WantedBy=multi-user.target

O objeto Metal3MachineTemplate contém referências a dataTemplate, hostSelector e image para os nós de trabalho:

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

O objeto Metal3DataTemplate especifica o metaData para o cluster downstream para os nós de trabalho:

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

Assim que o arquivo for criado juntando os blocos anteriores, execute o seguinte comando no cluster de gerenciamento para iniciar o provisionamento dos três novos hosts bare-metal:

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