documentation.suse.com / Documentação do SUSE Edge / Guias de procedimentos / MetalLB na frente do servidor da API Kubernetes

26 MetalLB na frente do servidor da API Kubernetes

Este guia demonstra como usar um serviço do MetalLB para expor a API RKE2/K3s externamente em um cluster de alta disponibilidade com três nós do plano de controle. Para isso, um serviço do Kubernetes do tipo LoadBalancer e endpoints serão manualmente criados. Os endpoints armazenam os IPs de todos os nós do plano de controle disponíveis no cluster. Para que o endpoint sempre se mantenha sincronizado com os eventos que ocorrem no cluster (adicionar/remover um nó ou quando um nó fica offline), o Endpoint Copier Operator (Capítulo 20, Endpoint Copier Operator) é implantado. O operador monitora os eventos ocorridos no endpoint padrão kubernetes e atualiza aquele gerenciado automaticamente para mantê-los sincronizados. Como o serviço gerenciado é do tipo LoadBalancer, o MetalLB o atribui a um ExternalIP estático. Esse ExternalIP será usado para comunicação com o API Server.

26.1 Pré-requisitos

  • Três hosts para implantar o RKE2/K3s em cima.

    • Certifique-se de que os hosts tenham nomes diferentes.

    • Para teste, eles podem ser máquinas virtuais.

  • Pelo menos 2 IPs disponíveis na rede (um para o Traefik/Nginx e outro para o serviço gerenciado).

  • Helm

26.2 Instalando o RKE2/K3s

Nota
Nota

Se você não deseja usar um cluster novo, mas um existente, ignore esta etapa e avance para a próxima.

Primeiramente, é necessário reservar um IP livre para usar mais adiante como ExternalIP do serviço gerenciado.

Acesse o primeiro host por SSH e instale a distribuição desejada no modo de cluster.

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

Verifique se o sinalizador --disable=servicelb foi inserido no comando k3s server.

Importante
Importante

A partir de agora, os comandos devem ser executados na máquina local.

Para acessar o servidor da API de um ambiente externo, o IP da VM do RKE2/K3s será usado.

# 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 Configurando um cluster existente

Nota
Nota

Esta etapa é válida apenas se você pretende usar um cluster RKE2/K3s existente.

Modifique os sinalizadores tls-san para usar um cluster existente. Além disso, o LB servicelb deve ser desabilitado no K3s.

Para alterar os sinalizadores dos servidores RKE2 ou K3s, você precisa modificar o arquivo /etc/systemd/system/rke2.service ou /etc/systemd/system/k3s.service em todas as VMs no cluster, dependendo da distribuição.

Insira os sinalizadores em ExecStart. Por exemplo:

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' \

Na sequência, os seguintes comandos devem ser executados para carregar as novas configurações:

systemctl daemon-reload
systemctl restart ${KUBE_DISTRIBUTION}

26.4 Instalando o MetalLB

Para implantar o MetalLB, use o guia do MetalLB no K3s (Capítulo 25, MetalLB no K3s (usando o modo de camada 2)).

NOTA: Assegure que os endereços IP IPAddressPool do ip-pool não sobreponham os endereços IP já selecionados para o serviço LoadBalancer.

Crie um IpAddressPool separado para usar apenas para o serviço gerenciado.

# 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 Instalando o Endpoint Copier Operator

helm install \
endpoint-copier-operator oci://registry.suse.com/edge/charts/endpoint-copier-operator \
--namespace endpoint-copier-operator \
--create-namespace

O comando acima implanta o operador endpoint-copier-operator com duas réplicas: uma será a líder e a outra assumirá a função de líder se necessário.

Agora o serviço kubernetes-vip, que será reconciliado pelo operador, deve ser implantado, e um endpoint com as portas e o IP configurados será criado.

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 se o serviço kubernetes-vip tem o endereço IP correto:

kubectl get service kubernetes-vip -n default \
 -o=jsonpath='{.status.loadBalancer.ingress[0].ip}'

Garanta que os recursos dos endpoints kubernetes-vip e kubernetes no namespace default apontem para os mesmos IPs.

kubectl get endpoints kubernetes kubernetes-vip

Se tudo estiver correto, a última coisa a se fazer é usar o VIP_SERVICE_IP no Kubeconfig.

sed -i '' "s/${NODE_IP}/${VIP_SERVICE_IP}/g" ~/.kube/config

A partir de agora, o kubectl sempre vai passar pelo serviço kubernetes-vip.

26.6 Adicionando nós do plano de controle

Para monitorar o processo inteiro, é possível abrir mais duas guias do terminal.

Primeiro terminal:

watch kubectl get nodes

Segundo terminal:

watch kubectl get endpoints

Agora execute os comandos a seguir no segundo e no terceiro nó.

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 -
Documentation survey