TL;DR; Vamos aprender a criar um cluster de Kubernetes em cloud da forma mais simples possível utilizando o kubeadm. No fim desse tutorial você terá uma aplicação em Node.js entregue e replicada no cluster para ser consumida externamente via API.
Não teremos a preocupação de abordar conceitos básicos do funcionamento do Kubernetes. Para entender a arquitetura de um cluster de uma forma mais detalhada, você pode conferir a documentação nesse link mágico.
Arquitetura Básica
A ideia desse tutorial é não focar em um provedor de cloud específico, você terá que levar em conta todas as peculiaridades de cada um na hora de provisionar a infra base necessária.
Nesse tutorial, teremos a seguinte estrutura:
- 1 servidor master; responsável por orquestrar as operações do cluster, realizar deploys, comandar os healthchecks e etc.
- 2 servidores workers; estes serão responsáveis por receber os pods da aplicação, fazer proxy entre os mesmos e garantir a quantidade de containers solicitada rodando entre eles.
Bootstrap Inicial das Máquinas do Cluster
Precisamos rodar algumas coisinhas pra fazer o Kubernetes funcionar, como o Docker e alguns CLI’s de bootstrap e administração, como o kubectl e o mágico kubeadm. Execute esses passos em todas as máquinas do cluster, tanto master quanto os nodes.
Instalando o Docker
Vamos fazer o download do Docker na versão mais recente.
apt-get update apt-get install -y apt-transport-https ca-certificates curl software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - add-apt-repository "deb https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") $(lsb_release -cs) stable" apt-get update && apt-get install -y docker-ce=$(apt-cache madison docker-ce | grep 17.03 | head -1 | awk '{print $3}')
Instalando as ferramentas do Kubernetes
O Kubernetes possui uma gama muito grande de plugins, extensões e CLI’s de produtividade. Nesse exemplo, o principal agente da criação do cluster será o kubeadm, ele irá abstrair toda a dificuldade da criação de clusters.
Mais em detalhes:
- kubeadm — Tool para realizar o bootstrap do Cluster
- kubelet — Tool que roda em todos os nodes gerenciando os papéis, iniciando pods, containers e mantendo os mesmos saudáveis.
- kubectl — Tool para realizar a comunicação com o cluster e executar todas as operações de orquestração.
apt-get update && apt-get install -y apt-transport-https curl curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - cat </etc/apt/sources.list.d/kubernetes.list deb http://apt.kubernetes.io/ kubernetes-xenial main EOF apt-get update apt-get install -y kubelet kubeadm kubectl
Iniciando o Node Master
Vamos iniciar o cluster utilizando o mágico kubeadm . Conecte-se no node master do cluster, após realizar a instalação do Docker e das ferramentas de CLI, e execute o comando:
kubeadm init
Após o termino do comando, ele irá cuspir alguns outros comandos a serem executados para finalizar a configuração, e principalmente o comando que iremos utilizar para ingressar os nodes no nosso cluster.
Your Kubernetes master has initialized successfully! To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ You can now join any number of machines by running the following on each node as root: Your Kubernetes master has initialized successfully! To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ You can now join any number of machines by running the following on each node as root: kubeadm join 172.31.85.6:6443 --token izzg7r.ueqzp7ndzxp8g5xq --discovery-token-ca-cert-hash sha256:e0244a52257be9e8cba49303e0472eb25020c6bd6c68f583653ed1700260fd0a
Agora temos que fazer algo bem importante, que é fazer deploy da rede do cluster. Neste exemplo, vamos utilizar o Project Calico para gerenciar a rede do nosso cluster.
kubectl apply -f https://docs.projectcalico.org/v2.6/getting-started/kubernetes/installation/hosted/kubeadm/1.6/calico.yaml
Iniciando os Nodes
Após instalarem o Docker e os CLI’s do Kubernetes em todos os nodes vamos rodar o comando informado na inicialização do cluster. Ele é baseado na seguinte estrutura.
kubeadm join :6443 --token --discovery-token-ca-cert-hash sha256:
No caso do exemplo é só entrar em todos os nodes e executar
kubeadm join 172.31.85.6:6443 --token izzg7r.ueqzp7ndzxp8g5xq --discovery-token-ca-cert-hash sha256:e0244a52257be9e8cba49303e0472eb25020c6bd6c68f583653ed1700260fd0a
Após executar o comando gerado na criação to cluster em todos os Nodes, podemos a partir do master listar todos os nodes vinculados ao cluster.
kubectl get nodes
O output deverá ser parecido com:
root@k8s-master:/home/ubuntu# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready master 1h v1.10.4 k8s-worker01 Ready xyz 15m v1.10.4 k8s-worker02 Ready xyz 15m v1.10.4 root@k8s-master:/home/ubuntu#
Realizando o Deploy de uma aplicação no Cluster
Vamos fazer deploy de uma aplicação simples que eu criei para esse exemplo.
Crie um arquivo chamado deploy.yml. Nele vamos criar um Replication Controller para garantir a quantidade de pods que queremos rodando no cluster. Nele vamos export a porta 3000 dos containers.
Depois criar um Service de NodePort que irá mapear a porta do host para o container. Vamos fazer um mapeamento da porta 30001 dos nodes para a 3000 do containers. Funciona como um load balancer/proxy simplificado. Bem simples.
apiVersion: v1 kind: ReplicationController metadata: name: microapi spec: replicas: 5 template: metadata: labels: app: microapi spec: containers: - name: microapi image: msfidelis/micro-api:latest imagePullPolicy: Always ports: - containerPort: 3000 --- apiVersion: v1 kind: Service apiVersion: v1 metadata: name: microapi spec: type: NodePort ports: - port: 3000 nodePort: 30001 selector: app: microapi
Agora vamos aplicar as modificações.
kubectl apply -f deploy.yml
O output deverá ser parecido com esse:
replicationcontroller "microapi" created service "microapi-ports" created
Agora vamos listar nossos pods existentes no cluster para conferir se está tudo ok:
kubectl get pods
O output deverá ser parecido com esse, mostrando 5 pods que estão rodando a nossa aplicação.
NAME DESIRED CURRENT READY AGE microapi 5 5 5 3m NAME READY STATUS RESTARTS AGE microapi-4xgj9 1/1 Running 0 3m microapi-h255v 1/1 Running 0 3m microapi-h9wrj 1/1 Running 0 3m microapi-hk7th 1/1 Running 0 3m microapi-lxv2h 1/1 Running 0 3m root@k8s-master:/home/ubuntu#
Desse modo, podemos fazer uma requisição para qualquer um dos nodes na porta 30001 para acessar os recursos da nossa API.
curl -i http://localhost:30001/system #oooou curl -i http://ip-do-node:30001/system
O output deverá apresentar informações do sistema em que o container está rodando. Faça várias requisições e veja a variação da key hostname, para validar como o proxy entre os nodes está funcionando.
HTTP/1.1 200 OK content-type: application/json; charset=utf-8 cache-control: no-cache content-length: 322 accept-ranges: bytes Date: Mon, 18 Jun 2018 18:12:57 GMT Connection: keep-alive {"hostname":"microapi-h255v","os":{"type":"Linux","platform":"linux","release":"4.4.0-1060-aws","arch":"x64"},"resources":{"memory":{"limit":1038864384,"free":174473216},"cpus":[{"model":"Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz","speed":2400,"times":{"user":1117800,"nice":51400,"sys":419300,"idle":82950000,"irq":0}}]}}
Esse modo exposição do serviço usando NodePorts é muito bacana caso você tenha algum outro balanceador de carga na frente dos nodes do seu cluster, como o ALB ou ELB da AWS. Funciona que é bala 🙂
- Esse exemplo foi construído em cima de máquinas EC2 na AWS. A ideia era não focar em nenhum provider de cloud em especifico, porém nesse caso, você vai ter que liberar o tráfego total entre os nodes para garantir um bom funcionamento.
- Uma dica é criar um Security Group para o cluster e liberar todo o tráfego entre todas as portas para conexões que compartilhem o mesmo security group, dessa forma:
Espero ter ajudado!
20/06/2018 at 9:11 pm
Muito bom! Ótima linguagem e exemplos perfeitos.
CurtirCurtido por 1 pessoa