Instalação do RKE2 em HA

7 min read

1. Apresentação

Neste artigo, demonstro a instalação de um cluster em HA (High Availability -> Alta disponibilidade) utilizando a distribuição Kubernetes RKE2, mantida pela SUSE. A distribuição RKE2 foca em boas práticas e conformidade com requisitos de segurança. Existe uma distribuição mais antiga, apenas RKE, aqui será utilizada a RKE2. A sigla RKE vem de Rancher Kubernetes Engine.
Mais informações sobre RKE vs RKE2, aqui.

O sistema operacional base validado aqui será o Oracle Linux 8. Porém, possivelmente o mesmo procedimento em distribuições Red Hat like (CentOS, Alma Linux, Rocky Linux, etc) funcionará sem problemas.

2. O Cluster RKE2 – Topologia Básica

Esta instalação considera cinco nodes:

  • 03 nodes com as roles control-plane + etcd
  • 02 nodes com a role agent (worker)

Image description

Outras configurações de cluster podem ser consultadas na documentação oficial.

2.1. Sugestão de recursos

Uma sugestão de capacidade computacional, pode ser a listada abaixo:

  • Control-plane: 4GB de RAM, 4 cpus, espaço em disco para o /var de 150GB. Mínimo de 3 nodes.
  • Worker: 16GB de RAM, 8 cpus, espaço em disco para o /var de 250GB. Mínimo de 3 nodes.

Cada ambiente é único, e uma análise detalhada das suas necessidades é essencial para dimensionar adequadamente o cluster Kubernetes com RKE2.

Uma dica útil é usar volumes lógicos (LVM) para o /var, assim ficará mais fácil realizar aumento do volume.

2.2. Esclarecimentos

  • O cluster RKE2 que será implantado utilizará como plugin de rede o Canal;
  • O RKE2 denomina como server uma instalação de node que terá a role de control-plane. E os nodes que terão a role de worker, denomina como agent.

3.Preparação do ambiente

Nesse artigo tutorial, é utilizado DNS. Assim, é essencial que o DNS interno da sua rede funcione corretamente, pois será necessário criar os devidos apontamentos..

Para facilitar a execução dos passos desse tutorial, será realizado apontamento no arquivo /etc/hosts de cada node, conforme abaixo:

192.168.100.101    rke01.devsecops.local.in
192.168.100.102    rke02.devsecops.local.in
192.168.100.103    rke03.devsecops.local.in
192.168.100.104    rke04.devsecops.local.in
192.168.100.105    rke05.devsecops.local.in

Caso vá validar esse tutorial em seu ambiente, adeque os ips e nomes conforme seu ambiente.

Vamos ao trabalho!

3.1. Entradas DNS

Adicionando as entradas no /etc/hosts de cada node:

sudo tee -a /etc/hosts > /dev/null << EOF
192.168.100.101    rke01.devsecops.local.in
192.168.100.102    rke02.devsecops.local.in
192.168.100.103    rke03.devsecops.local.in
192.168.100.104    rke04.devsecops.local.in
192.168.100.105    rke05.devsecops.local.in
EOF

3.2. Desabilitar SWAP

O uso de swap em ambientes Kubernetes não é recomendado. Assim, desabilite o swap em cada node.:

systemctl disable swap.target
swapoff -a

3.3. Configuração do firewall host

Este passo é opcional, mas altamente recomendado. Embora aumente a complexidade da configuração, é essencial em ambientes que exigem maior controle. Se esse for o seu cenário, aqui será demonstrada a configuração do FirewallD, disponível em distribuições Linux baseadas no Red Hat.

O firewall do host será configurado em cada node utilizando o comando CLI do FirewallD, firewall-cmd. No geral, a configuração é parecida em cada node, com algumas pequenas diferenças:

  • Certifique-se de não adicionar o próprio IP do node como origem (source), pois isso pode causar problemas.
  • A configuração nos nodes workers é um pouco menor.

Esta configuração segue as orientações da documentação oficialsobre as portas que devem ser liberadas. Lembre-se, aqui trata-se de uma liberação na rede interna de seu ambiente, considerando um cenário de um ambiente que tenha mais controle.

Em cada node, crie uma nova zona no FirewallD com o comando abaixo:

firewall-cmd --permanent --new-zone=rke2-zone

Aqui, denominei a zona de “rke2-zone”.

a. Configuração no node rke01 (control-plane):
Associe os IPs dos outros nodes como origens (sources) à zona criada:

firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.102 #rke02
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.103 #rke03
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.104 #rke04
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.105 #rke05

Criação das regras:

firewall-cmd --permanent --zone=rke2-zone --add-port=2379/tcp #etcd client port
firewall-cmd --permanent --zone=rke2-zone --add-port=2380/tcp #etcd peer port
firewall-cmd --permanent --zone=rke2-zone --add-port=2381/tcp #etcd metrics
firewall-cmd --permanent --zone=rke2-zone --add-port=6443/tcp #Kubernetes API
firewall-cmd --permanent --zone=rke2-zone --add-port=9345/tcp #RKE2 Supervisor API
firewall-cmd --permanent --zone=rke2-zone --add-port=8472/udp #Canal VXLAN
firewall-cmd --permanent --zone=rke2-zone --add-port=9099/tcp #Canal CNI health checks
firewall-cmd --permanent --zone=rke2-zone --add-port=10250/tcp #Kubelet metrics

Regras para zone public:

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --permanent --zone=public --add-port=30000-32767/tcp

Aplicando a configuração de forma efetiva com um reload:

firewall-cmd --reload

b. Configuração no node rke02 (control-plane):
Associe os IPs dos outros nodes como origens (sources) à zona criada:

firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.101 #rke01
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.103 #rke03
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.104 #rke04
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.105 #rke05

Criação das regras:

firewall-cmd --permanent --zone=rke2-zone --add-port=2379/tcp  # etcd client port
firewall-cmd --permanent --zone=rke2-zone --add-port=2380/tcp  # etcd peer port
firewall-cmd --permanent --zone=rke2-zone --add-port=2381/tcp  # etcd metrics
firewall-cmd --permanent --zone=rke2-zone --add-port=6443/tcp  # Kubernetes API
firewall-cmd --permanent --zone=rke2-zone --add-port=9345/tcp  # RKE2 Supervisor API
firewall-cmd --permanent --zone=rke2-zone --add-port=8472/udp  # Canal VXLAN
firewall-cmd --permanent --zone=rke2-zone --add-port=9099/tcp  # Canal CNI health checks
firewall-cmd --permanent --zone=rke2-zone --add-port=10250/tcp # Kubelet metrics

Regras para zone public:

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --permanent --zone=public --add-port=30000-32767/tcp

Aplicando a configuração de forma efetiva com um reload:

firewall-cmd --reload

c. Configuração no node rke03 (control-plane):

Associe os IPs dos outros nodes como origens (sources) à zona criada:

firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.101 #rke01
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.102 #rke02
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.104 #rke04
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.105 #rke05

Criação das regras:

firewall-cmd --permanent --zone=rke2-zone --add-port=2379/tcp  # etcd client port
firewall-cmd --permanent --zone=rke2-zone --add-port=2380/tcp  # etcd peer port
firewall-cmd --permanent --zone=rke2-zone --add-port=2381/tcp  # etcd metrics
firewall-cmd --permanent --zone=rke2-zone --add-port=6443/tcp  # Kubernetes API
firewall-cmd --permanent --zone=rke2-zone --add-port=9345/tcp  # RKE2 Supervisor API
firewall-cmd --permanent --zone=rke2-zone --add-port=8472/udp  # Canal VXLAN
firewall-cmd --permanent --zone=rke2-zone --add-port=9099/tcp  # Canal CNI health checks
firewall-cmd --permanent --zone=rke2-zone --add-port=10250/tcp # Kubelet metrics

Regras para zone public:

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --permanent --zone=public --add-port=30000-32767/tcp

Aplicando a configuração de forma efetiva com um reload:

firewall-cmd --reload

d. Configuração no node rke04 (worker):
Associe os IPs dos outros nodes como origens (sources) à zona criada:

firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.101 #rke01
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.102 #rke02
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.103 #rke03
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.105 #rke05

Criação das regras:

firewall-cmd --permanent --zone=rke2-zone --add-port=8472/udp #Canal VXLAN
firewall-cmd --permanent --zone=rke2-zone --add-port=9099/tcp #Canal CNI health checks
firewall-cmd --permanent --zone=rke2-zone --add-port=10250/tcp #Kubelet metrics

Regras para zone public:

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --permanent --zone=public --add-port=30000-32767/tcp

Aplicando a configuração de forma efetiva com um reload:

firewall-cmd --reload

e. Configuração no node rke05 (worker):
Associe os IPs dos outros nodes como origens (sources) à zona criada:

firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.101 #rke01
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.102 #rke02
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.103 #rke03
firewall-cmd --permanent --zone=rke2-zone --add-source=192.168.100.104 #rke04

Criação das regras:

firewall-cmd --permanent --zone=rke2-zone --add-port=8472/udp  # Canal VXLAN
firewall-cmd --permanent --zone=rke2-zone --add-port=9099/tcp  # Canal CNI health checks
firewall-cmd --permanent --zone=rke2-zone --add-port=10250/tcp # Kubelet metrics

Regras para zone public:

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --permanent --zone=public --add-port=30000-32767/tcp

Aplicando a configuração de forma efetiva com um reload:

firewall-cmd --reload

Embora este processo possa ser automatizado com um shell script ou uma playbook Ansible, executá-lo manualmente ajuda a compreender melhor cada etapa antes de criar automações.

Para visualizar a configuração em cada zona:

firewall-cmd --list-all --zone=rke2-zone
firewall-cmd --list-all --zone=public

4. Instalação do RKE2 – Cluster em HA

Agora, finalmente, chegou o momento de subir o cluster RKE2.

4.1. Primeiro control-plane (rke01)

É necessário subir primeiro um node control-plane. Aqui no cenário, o node rke01 será o primeiro.

Passos:
a. Criação de diretórios necessários:

mkdir -p /etc/rancher/rke2/
mkdir -p  /var/lib/rancher/rke2/server/manifests/

b. Criação do arquivo de configuração config.yaml:

cat<<EOF|tee /etc/rancher/rke2/config.yaml
tls-san:
  - rke01.devsecops.local.in
  - 192.168.100.101
  - rke02.devsecops.local.in
  - 192.168.100.102
  - rke03.devsecops.local.in
  - 192.168.100.103
  - rke04.devsecops.local.in
  - 192.168.100.104
  - rke05.devsecops.local.in
  - 192.168.100.105
write-kubeconfig-mode: "0600"
etcd-expose-metrics: true
selinux: true
cni:
  - canal

EOF

Mais detalhes sobre os parâmetros e configuração para servers aqui.

c. Criação de manifest para implantação de um Ingress Controller baseado no Nginx:

cat<<EOF| tee /var/lib/rancher/rke2/server/manifests/rke2-ingress-nginx-config.yaml
---
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: rke2-ingress-nginx
  namespace: kube-system
spec:
  valuesContent: |-
    controller:
      metrics:
        service:
          annotations:
            prometheus.io/scrape: "true"
            prometheus.io/port: "10254"
      config:
        use-forwarded-headers: "true"
      allowSnippetAnnotations: "true"
EOF

d. Inciar a instalação:

curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE=server sh -

A execução do script oficial instalará o RKE2 em modo server. Configurará os repositórios de pacotes RPM e a instalação será via gerenciador de pacotes padrão do S.O.

Também será instalado o kubectl, assim será possível interagir com o cluster kubernetes.

e. Iniciar o serviço rke2-server:

systemctl start rke2-server

Esse processo de subir o serviço pode demorar um pouco, é normal. Aguarde terminar.

Depois, consulte o status do serviço:

systemctl status rke2-server

Não ocorrendo nenhum erro, pode-se prosseguir.

Deve-se habilitar o serviço, assim, ao reiniciar o sistema operacional, o rke2-server iniciará automaticamente:

systemctl enable rke2-server

f. Adicionando algumas variáveis de ambiente

Por padrão, os binários do RKE2 ficam em /var/lib/rancher/rke2/bin. Então, é necessário adicionar esse caminho ao PATH do sistema, a fim de facilidar a execução dos comandos, sem precisar indicar o caminho todo.

export PATH=$PATH:/var/lib/rancher/rke2/bin
export KUBECONFIG=/etc/rancher/rke2/rke2.yaml

Além dos binários em si, também foi criada a variável KUBECONFIG apontando para o arquivo de configuração, assim será possível usar o kubectl dentro do node

Para tornar essas variáveis persistentes no ambiente, pode-se adicioná-las no .bashrc do usuário:

echo "export PATH=$PATH:/var/lib/rancher/rke2/bin" >> $HOME/.bashrc
echo "export KUBECONFIG=/etc/rancher/rke2/rke2.yaml"  >> $HOME/.bashrc 

Pode-se executar um kubectl no node para confirmar o status do node no cluster kubernetes:

kubectl get nodes

g. Coletar o token de instalação
Para adicionar outros nodes, é necessário coletar o token que foi gerado na instalação:

cat /var/lib/rancher/rke2/server/node-token

4.2. Demais nodes control-plane (rke02 e rke03)

Os passos são praticamente os mesmos. A diferença está no arquivo de configuração config.yaml e no fato de não ser necessário coletar o token de instalação nesses nodes.

a. Criação do arquivo config.yaml:

cat<<EOF|tee /etc/rancher/rke2/config.yaml
server: https://192.168.100.101:9345
token: <TOKEN_COLETADO_NO_NODE_01_AQUI>
write-kubeconfig-mode: "0644"
tls-san:
  - rke01.devsecops.local.in
  - 192.168.100.101
  - rke02.devsecops.local.in
  - 192.168.100.102
  - rke03.devsecops.local.in
  - 192.168.100.103
  - rke04.devsecops.local.in
  - 192.168.100.104
  - rke05.devsecops.local.in
  - 192.168.100.105
write-kubeconfig-mode: "0644"
selinux: true
etcd-expose-metrics: true
cni:
  - canal

EOF

Perceba que a diferença no arquivo de configuração está na adição da linha que deve conter o token que foi coletado no node 01 (rke01).

4.3. Instalação de Worker node (rke04 e rke05)

Agora vamos a etapa de instalação dos nodes workers (agent). Os passos a seguir devem ser executados nos dois nodes workers.

a. Criação de diretório necessário:

mkdir -p /etc/rancher/rke2/

b. Criação do arquivo de configuração config.yaml

cat<<EOF|tee /etc/rancher/rke2/config.yaml
server: https://192.168.100.101:9345
token: <TOKEN_COLETADO_NO_NODE_01_AQUI>
write-kubeconfig-mode: "0644"
selinux: true

EOF

c. Iniciar a instalação

curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE=agent sh -

d. Iniciar o serviço rke2-agent

Após a execução do passo c, basta inciar o serviço:

systemctl start rke2-agent.service

O processo de start pode demorar um pouco, aguarde finalizar.

Para consultar o status e verificar se está tudo certo:

systemctl status rke2-agent.service

Deve-se habilitar o serviço, assim, ao reiniciar o sistema operacional, o rke2-agent iniciará automaticamente:

systemctl enable rke2-agent

Pronto, se tudo foi feito corretamente, nesse momento temos um cluster kubernetes implantado com a distribuição RKE2.

Referência

Leave a Reply

Your email address will not be published. Required fields are marked *