Como Configurar um Cluster Kubernetes Usando Kubespray

Hi there 👋 I'm a DevOps Enginner working in São Luis - MA, Brazil.
I have a degree in Information Systems from UNDB - Unidade de Ensino Superior Dom Bosco, a postgraduate degree in Information Security and a passionate by Technology.
I had my first contact with a computer when I was 11 years old, in a community course in my neighborhood. At the age of 12, I was intentionally teaching at the same association, which brought me much pleasure and more knowledge.
My first CLT job was at the age of 17 and also teaching at several computer schools in the capital of Maranhão.
Linux is my Favorite OS, my favorite distribution is Pop!OS, but I work daily with MacOs and Windows OS. ;)
🏢 I'm currently working at Grupo Mateus ⚙️ I use daily: .sh, .js, .cpp, .go, .py, .jar, .tf, .yaml, .json 🌍 I'm mostly active within the DevOps Culture in My Organization 🌱 Reading all about Open Source, DevOps, Clean Architecture, Cloud Computing and more... ⚡️ Fun fact: I'm a huge fan of Harry Potter and Lord Of Kings and Geek Culture. ✨ My Website is nilsonvieira.com.br;
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
.ssh e copie a sua chave pública para dentroPara 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>




