Instalando e configurando um cluster Kubernetes 1.15 no CentOS 7

Se você já tem familiaridade com containers Docker, provavelmente já precisou manipular o ciclo de vida destes containers em conjunto.
Uma solução comum é utilizar o docker-compose, que permite a criação de um arquivo que descreve como os containers se relacionam. Assim, o docker-compose cuida de subir todos os containers, bem como mantê-los funcionais.
No entanto, quando precisamos orquestrar algo mais complexo que, por exemplo, execute os containers em diferentes hosts, o docker-compose não pode nos ajudar muito.
Para isso, existe uma ferramenta, desenvolvida pelo Google, que tem ganhado bastante espaço na comunidade: o Kubernetes. O Kubernetes é um poderoso orquestrador de containers que permite abstrair dos usuários toda complexidade de gerenciar múltiplos containers e mantê-los online.
O Kubernetes é um sistema distribuído e, por isso, roda em um cluster onde os hosts ficam disponíveis para executar os containers. Ou seja, o Kubernetes realiza todo o gerenciamento dos containers realizando o melhor esforço para mantê-los operacionais. Caso haja alguma perturbação no cenário, o Kubernetes se encarrega de realizar as operações necessárias de forma a manter a aplicação online.
Normalmente, o Kubernetes é utilizado junto com um serviço de cloud. O Google Cloud Platform, AWS e Azure são exemplos de serviços de cloud compatíveis com Kubernetes. No entanto, se você deseja instalar o Kubernetes do zero em um cluster próprio, este artigo foi escrito pensando em você!
Cenário

Para o nosso caso, vamos instalar o Kubernetes em três hosts, como mostra o diagrama acima. Todos os hosts já estão com CentOS 7 instalado. Um deles funcionará como o master e os outros dois como slaves. O nó master tem a função de realizar toda orquestração dos containers e os slaves são os hosts onde os containers serão, de fato, executados.
Chega de papo, vamos lá!
Configurações iniciais
Estas configurações deverão ser realizadas em todas os hosts que comporão o cluster, ou seja, tanto o nó master como os escravos.
Para iniciar, tome nota do hostname de cada máquina do cluster. Caso não saiba os nomes das máquinas você pode utilizar o seguinte comando para descobrir:
$ hostname
Essa informação será importante em toda configuração. No meu caso, tenho os seguintes hostnames:
- Master: kubernetes-master
- Node1: kubernetes-node-1.novalocal
- Node2: kubernetes-node-2.novalocal
Em cada um dos nós, edite o arquivo /etc/hosts e configure os ips de cada uns dos hosts.
$ sudo vi /etc/hosts

Os comandos a seguir devem ser executados como root.
Desabilite o SELinux do CentOS.
$ setenforce 0
$ sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
Desabilte o Firewall
$ systemctl stop firewalld$ systemctl disable firewalld
Desabilite o Swap
$ swapoff -a$ sed -i 's/.*swap.*/#&/' /etc/fstab
Execute o comando a seguir para corrigir possíveis falhas de roteamento.
$ echo "1" > /proc/sys/net/ipv4/ip_forward$ cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
Execute o comando abaixo para aplicar as configurações.
$ sysctl --system
Configure os repositorios do yum
$ yum install -y wget$ mkdir /etc/yum.repos.d/bak && mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak$ wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.cloud.tencent.com/repo/centos7_base.repo$ wget -O /etc/yum.repos.d/epel.repo http://mirrors.cloud.tencent.com/repo/epel-7.repo$ yum clean all && yum makecache
Adicione o repositório do Kubernetes no gerenciador de pacotes Yum.
$ cat <<EOF > /etc/yum.repos.d/kubernetes.repo[kubernetes]name=Kubernetesbaseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/enabled=1gpgcheck=1repo_gpgcheck=1gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpgEOF
Reinicie os hosts para aplicar as alterações, executando o seguinte comando:
$ sudo init 6
Instalando o Docker
O Docker é um pré-requisito para a instalação e funcionamento do Kubernetes. Sendo assim, instale o Docker em cada um dos hosts.
Para iniciar a instalação do Docker, primeiramente configure o repositório do yum.
$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
Em seguida instale o pacote yum-utils executando o seguinte comando:
$ sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2$ yum install pigz
Execute o seguinte comando para instalar o docker:
$ sudo yum install -y docker-ce-18.06.1.ce-3.el7
Habilite e inicie o Docker.
$ sudo systemctl enable docker && systemctl start docker
Adicione o seu usuário no grupo do Docker para garantir que possa usar os comandos Docker sem necessidade de sudo. Para isso, logue com seu usuário e execute o seguinte comando:
$ sudo groupadd docker
$ sudo usermod -aG docker $USER
Para que as configurações possam ter efeito, é necessário reiniciar a sessão.
Após logar novamente, cheque a versão a instalada com o seguinte comando:
$ docker --version
No meu caso, a versão instalada foi a 18.06.1-ce.

Para testar o pleno funcionamento do Docker execute o seguinte comando:
$ docker run hello-world
Se tudo ocorrer bem, a imagem do hello-world deverá ser baixada e executada no host. A figura abaixo mostra o resultado esperado.

Instalando o Kubernetes
UFA! Agora vamos de fato iniciar a instalação do Kubernetes. Este procedimento deve ainda ser executado em cada um dos nós do cluster. Vamos lá? Para começar, então, execute o seguinte comando:
$ sudo yum install -y kubelet kubeadm kubectl$ systemctl enable kubelet
Configurando o master
Agora vamos realizar a configuração do nó master do Kubernetes. Este é a única seção onde o procedimento deve ser executado apenas no nó master.
Inicie o Master com o seguinte comando tomando cuidado por trocar o IP 10.7.40.63 pelo IP do seu nó master.
$ sudo kubeadm init --kubernetes-version=1.15.0 --apiserver-advertise-address=10.7.40.63 --service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.0.0/16
Se tudo ocorrer bem você receberá uma resposta conforme a tela a seguir.

Tome nota do comando destacado de vermelho. Ele será utilizado logo a seguir!
O próximo passo deve ser executado no seu usuário comum. Perceba que em todo procedimento utilizamos sudo para elevar as permissões. Se você utilizou o atalho de logar diretamente com o root, agora é a hora de voltar ao seu usuário. Feito isso, execute os seguintes comandos:
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
Podemos executar o seguinte comando para verificar o pods em execução:
$ kubectl get pods --all-namespaces
Neste momento, o resultado deve ser como mostra a figura abaixo. Perceba que o pod do DNS permanece pendente. Isso ocorre por que ainda não configuramos a rede. Faremos isso na sequência.

Agora vamos instalar nossa rede que será responsável pela comunicação entre os nós. Existem vários tipos de redes suportadas pelo Kubernetes. Neste tutorial, utilizaremos a rede Flannel. Para iniciar, execute o seguinte comando:
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml
Pode levar algum tempo até todos os pods estarem rodando. Espere até que os pods fiquem todos no estado de Running. Para verificar o estado execute o seguinte comando:
$ kubectl get pods --all-namespaces
Após o tempo de inicialização, o seguinte resultado é esperado:

Agora vamos realizar a configuração de cada nós escravos.
Configurando os nós escravos
Em cada nós escravo, além do processo comum descrito neste artigo, é necessário executar o comando kubeadm join para entrar no cluster. O comando exato é mostrado logo após o comando kubeadm init no nó master. Recupere o comando mostrado e execute em cada nó escravo.
Como exemplo, o meu comando foi o seguinte:
$ sudo kubeadm join --token a2dc82.7e936a7ba007f01e 10.0.0.7:6443 --discovery-token-ca-cert-hash sha256:30aca9f9c04f829a13c925224b34c47df0a784e9ba94e132a983658a70ee2914
Para ter certeza que o nó entrou no cluster volte ao nó master e execute o seguinte comando:
$ kubectl get nodes
Este comando mostrará os nós disponíveis no cluster. Ao final, o resultado esperado é o seguinte:

$ kubeadm token create --print-join-command
Bem gente, é isso! Espero que consigam configurar o cluster de vocês. É um pouco trabalhoso, mas se seguir direitinho todos os passos dará certo. Abraços e até a próxima!