27 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á manualmente un servicio de Kubernetes de
tipo LoadBalancer. Después, se creará automáticamente un
objeto EndpointSlices que mantienen las IP de todos los
nodos de plano de control disponibles en el clúster. Para que EndpointSlices
esté continuamente sincronizado con los eventos que se producen 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 EndPointSlices
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.
27.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
27.2 Instalación de RKE2/K3s #
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 -Asegúrese de que se proporciona el indicador
--disable=servicelb en el comando k3s
server.
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/config27.3 Configuración de un clúster existente #
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}27.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 la dirección IP
VIP_SERVICE_IP no se superpone a los
IPAddressPools existentes en el clúster.
Cree una IpAddressPool y un
L2Advertisement independientes que se usarán únicamente
para el servicio gestionado.
NOTA: el IPAddressPool siguiente se
asignará a un servicio de tipo LoadBalancer en el espacio
de nombres default. Si en ese espacio hay varios
servicios LoadBalancer, podría haber ServiceSelectors
adicionales configurados que coincidan explícitamente con este servicio de
IP virtual.
# 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
EOFcat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: kubernetes-vip-l2-adv
namespace: metallb-system
spec:
ipAddressPools:
- kubernetes-vip-ip-pool
EOF27.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-namespaceEl 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 EndpointSlices 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
EOFPara 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
EOFVerifique 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 EdnpointSlices
kubernetes-vip-* y kubernetes del
espacio de nombres default señalan a las mismas IP.
kubectl get endpointslices | grep kubernetesSi 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/configA partir de ahora, todo kubectl pasará por el servicio
kubernetes-vip.
27.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 nodesSegundo terminal:
watch kubectl get endpointslicesAhora, 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.servicePara 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 -