Como Configurar um Cluster Kubernetes Usando Kubespray

Como Configurar um Cluster Kubernetes Usando Kubespray

Se você ainda não sabe o que é o Kubernetes, então acesse o artigo que foi preparado para dar esse embasamento inicial. O que é Kubernetes.

Esta é uma receita de bolo sobre como instalar o Kubernetes (k8s) usando Kubespray. Este how-to mostrará como instalar o Kubernetes Cluster usando Kubespray em ambientes Linux.

O que é o Kubespray

É uma ferramenta gratuita e de código aberto que fornece playbooks ansible para implantar e gerenciar clusters Kubernetes. Ele foi projetado para simplificar o processo de instalação de clusters Kubernetes em vários nós, permitindo que os usuários implantem e gerenciem um cluster Kubernetes prontos para produção de forma rápida e fácil.

Sistemas Operacionais suportados

Ele suporta uma variedade de sistemas operacionais, incluindo Ubuntu, CentOS, Rocky Linux e Red Hat Enterprise Linux, e pode implantar o Kubernetes em uma variedade de plataformas, incluindo bare metal, nuvem pública e nuvem privada.

Para este How-to usaremos o seguinte laboratório:

Máquina Física:

Notebook Acer Nitro 32GB RAM, Intel Core i7 (12 Threads), 1TB SSD com Linux PopOS! 22.04 LTS.

Essa máquina será o Ansible Host (Kubespray).

Devemos contar com 5 VMs que serão criadas através de VagrantFile usando VirtualBox que deverão possuir os IPs 192.168.50.11 ao 15 com Sistema Operacional Ubuntu 22.04. Todas devem ser 2x2, ou seja, 2CPU e 2GB RAM.

Dentro do Kubespray vamos organizar o Cluster para ficar dividido da seguinte forma:

  • 3 Masters: Nodes 01 ao 03

  • 3 ETCDs: Nodes 01 ao 03

  • 5 Nodes: Nodes 01 ao 05

Configurando o Cluster Kubernetes

Preparação do Ansible Host (Notebook)

Vamos criar uma pasta para organizar toda a estrutura:

No meu caso estou criando dentro da minha pasta Documentos.

$ mkdir -p /home/nilson/Documentos/lab-k8s/

Com os repositórios criados vamos agora preparar a máquina host. Atualizando pacotes e instalando as dependências necessárias.

$ sudo apt update
$ sudo apt install git python3 python3-pip -y
$ git clone https://github.com/kubernetes-sigs/kubespray.git
$ cd kubespray
$ pip install -r requirements

Após isso verifique a versão do Ansible com o comando ansible --version . A saída deve ser parecida com a seguinte:

ansible [core 2.14.10]
  config file = None
  configured module search path = ['/home/nilson/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/nilson/.local/lib/python3.10/site-packages/ansible
  ansible collection location = /home/nilson/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/nilson/.local/bin/ansible
  python version = 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.1.2
  libyaml = True

Preparação do Kubespray

Vamos agora preparar o ambiente do kubespray, copiando o diretório sample para outro, no meu caso usei mycluster, para trabalhar nele e realizar os ajustes necessários.

Seguindo ainda a documentação do próprio kubespray vamos declarar os IPs adicionando-os em uma variável para em seguida usar um script python para gerar o arquivo hosts.yaml que será a base estrutural do nosso ambiente.

$ cp -rfp inventory/sample inventory/mycluster
$ declare -a IPS=(192.168.50.11 192.168.50.12 192.168.50.13 192.168.50.14 192.168.50.15)
$ CONFIG_FILE=inventory/mycluster/hosts.yaml python3 contrib/inventory_builder/inventory.py ${IPS[@]}

Feito isso, vamos modificar e deixar de acordo como planejamos acima:

$ vi inventory/mycluster/hosts.yaml

O arquivo deve ficar assim:

all:
  hosts:
    k8s-node-1:
      ansible_host: 192.168.50.11
      ip: 192.168.50.11
      access_ip: 192.168.50.11
    k8s-node-2:
      ansible_host: 192.168.50.12
      ip: 192.168.50.12
      access_ip: 192.168.50.12
    k8s-node-3:
      ansible_host: 192.168.50.13
      ip: 192.168.50.13
      access_ip: 192.168.50.13
    k8s-node-4:
      ansible_host: 192.168.50.14
      ip: 192.168.50.14
      access_ip: 192.168.50.14
    k8s-node-5:
      ansible_host: 192.168.50.15
      ip: 192.168.50.15
      access_ip: 192.168.50.15
  children:
    kube_control_plane:
      hosts:
        k8s-node-1:
        k8s-node-2:
        k8s-node-3:
    kube_node:
      hosts:
        k8s-node-1:
        k8s-node-2:
        k8s-node-3:
        k8s-node-4:
        k8s-node-5:
    etcd:
      hosts:
        k8s-node-1:
        k8s-node-2:
        k8s-node-3:
    k8s_cluster:
      children:
        kube_control_plane:
        kube_node:
    calico_rr:
      hosts: {}
  vars:
      ansible_ssh_private_key_file: ~/.ssh/id_rsa

O arquivo de chave deve ser o par da chave ssh que será enviada às VMs Hosts através do VagrantFile.

Observe também a disposição dos nodes, se ficou como definimos mais acima. Segue novamente:

  • 3 Masters: Nodes 01 ao 03

  • 3 ETCDs: Nodes 01 ao 03

  • 5 Nodes: Nodes 01 ao 05

Eu gosto de trabalhar com Balanceador Externo, então temos que habilitar o mesmo dentro do arquivo /inventory/mycluster/group_vars/all/all.yml deixando assim:

loadbalancer_apiserver:
  address: 192.168.1.12
  port: 6443

Node que o IP 192.168.1.12 é o IP da máquina HOST ANSIBLE, no nosso caso o Notebook.

Pronto, parte do kubespray configurada, agora vamos para o Balanceador.

Configurando e Iniciando o Balanceador Externo

O balanceador deve estar configurado e UP antes do playbook rodar, pois ele é uma dependência conforme configuramos no kubespray.

No nosso caso como balanceador, vamos usar o haproxy conteinerizado. Vamos aos passos:

Primeiramente vamos criar um diretório para deixar mais organizado. Entao sairemos da pasta do kubespray e criamos a do Haproxy:

$ cd ../ 
$ mkdir haproxy
cd haproxy

Feito isso vamos criar um arquivo de configuração chamado haproxy.cfg.

global
        log /dev/log    local0
        log /dev/log    local1 notice
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

defaults
        log     global
        timeout connect 5s  
        timeout client  50s  
        timeout server  50s  

listen stats
        bind *:81
        mode http
        stats enable
        stats refresh 30s
        stats uri /stats
        stats hide-version
        stats auth admin:admin

listen kubernetes-apiserver
        bind *:6443
        mode tcp
        option log-health-checks
        timeout client 300s
        timeout server 300s
        balance roundrobin
        server k8s-master-01 192.168.50.11:6443 check check-ssl verify none
        server k8s-master-02 192.168.50.12:6443 check check-ssl verify none
        server k8s-master-03 192.168.50.13:6443 check check-ssl verify none

Feito isso saímos do diretório e criamos o compose.

$ cd ../
$ touch docker-compose.yaml

Dentro do arquivo deve conter:

version: "3.9"
services:
  haproxy:
    container_name: haproxy
    image: haproxy:2.8.3
    volumes:
      - ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
    ports:
      - "81:81"
      - "8081:8081"
      - "6443:6443"

Ao finalizar vamos iniciar o container:

$ docker compose up -d

Após isso para validar acesse http://localhost:81/stats e use usuário e senha admin.

Deve aparecer algo assim:

Configurando o Vagrant e Subindo as VMs

Configurado o Balanceador Externo, vamos agora trabalhar nas máquinas virtuais. Vamos criar um arquivo nomeado Vagrantfile.

$ touch Vagrantfile

Dentro dele adicionamos o seguinte:

IMAGE_NAME = "bento/ubuntu-22.04"
NODES = 5
NET_IP="192.168.50."
INIT_IP=1

Vagrant.configure(2) do |config|
        config.vm.provision "file", source: "./.ssh/id_rsa.pub", destination: "~/.ssh/me.pub"
        config.vm.provision "shell", env:{"NET_IP" => NET_IP, "INIT_IP" => INIT_IP}, inline: <<-SCRIPT
        apt-get update -y && apt install -y vim net-tools telnet git nfs-common
        cat /home/vagrant/.ssh/me.pub >> /home/vagrant/.ssh/authorized_keys
        SCRIPT

    config.vm.box = IMAGE_NAME
    config.vm.box_check_update = true

    (1..NODES).each do |i|
        config.vm.define "node-#{i}" do |node|
            node.vm.hostname = "k8s-node-#{i}"
            node.vm.network "private_network", ip: NET_IP + "#{i + 10}"
            node.vm.provider "virtualbox" do |vb|
                vb.name = "k8s-node-#{i}"
                vb.memory = 2048
                vb.cpus = 2
            end
        end
    end
end
💡
Antes de executar lembre-se de criar uma pasta .ssh e copie a sua chave pública para dentro

Para rodar basta executar:

vagrant up

Pronto! Agora vamos configurar nosso cluster Kubernetes.

Executando o Playbook

Antes de tudo recomendo deixar a chave salva no bash pra evitar que fique solicitando autorização e digitação da senha a todo momento.

eval `ssh-agent`
ssh-add

Pronto! Podemos rodar o playbook.

$ cd kubespray
$ ansible-playbook -i inventory/mycluster/hosts.yaml -u vagrant --become --become-user=root cluster.yml

Ao final, sem erros você pode copiar o texto do arquivo /etc/kubernetes/admin.conf de dentro de uma das VMS Master (nodes 01 ao 03) e colar em um Gerenciador como o Lens, por exemplo.

Cluster ponto para uso! :)

Referências

KUBESPRAY. Kubernetes Sigs: Kubespray: Disponível em: <kubernetes-sigs/kubespray: Deploy a Production Ready Kubernetes Cluster (github.com)\>. Acessado em: <02/10/2023>

Did you find this article valuable?

Support Nilson Vieira by becoming a sponsor. Any amount is appreciated!