Pular para o conteúdo principal

Design Kubernetes Cluster

Podemos instalar o kubernetes de várias maneiras. Qual delas é a ideal para o que você quer fazer?

Vamos colocar algumas perguntas sobre a mesa.

Propósito do cluster

Qual o propósito desse cluster? WHY?

  • Aprendizado?
    • Se tiver começando e for a primeira vez, pode usar um minikube que simula um cluster de somente 1 node master é suficiente e podemos deployar os pods dentro do próprio master.
    • Uma ótima opção é o kind que cria nodes como containers na sua máquina local. Evita criar vms e podemos simular mais nodes masters e workers.
  • Desenvolvimento?
    • Em um ambiente desenvolvimento 1 master e vários workers é um cenário.
    • Um cluster baremetal pode ser uma ótima escolha para diminuir custos.
    • Setup com kubeadm ou kubespray seria uma forma fácil de fazer.
  • Produção?
    • Vários masters, no mínimo 3.
    • Pode ser provisionado com o kubespray, kops, kubeadm ou usando soluções gerenciadas pela cloud que inclusive eu considero a melhor opção quando possível.

https://kubernetes.io/docs/setup/best-practices/cluster-large/

O kubernetes suporta até 5000 nodes 150000 pods no cluster 300000 containers totais 100 pods por node.

Dimensionando o Cluster

Existe um ponto ótimo entre cpu e memória para evitar gargalos. Claro que cada tipo de aplicação pode variar nos recursos. Uma aplicação com uso intenso de cpu e pouca memória ou o contrário fogem do padrão e precisa ser analisado.

Se você tiver muita CPU e pouca memória, o sistema pode ficar ocioso esperando que os dados sejam buscados na memória. Da mesma forma, se você tiver muita memória e pouca CPU, o sistema pode não conseguir processar os dados rapidamente o suficiente.

Para propósitos gerais, se você ainda não sabe o que será montado, pense em pelo menos 1CPU para cada 4GB RAM.

Outro ponto importante é quantos worker nodes você pretende ter. É melhor muitos nodes com menos recursos ou menos nodes com mais recurso?

Toda vez que temos um daemonset que executa um pod em cada node obrigatoriamente, se você tiver muitos nodes, você perderá também muito recurso. Toda vez que um node sobe se for muito pequeno ele já perdeu parte da sua ram para executar o sistema operacional. Precisamos encontrar um ponto ideal em que a aplicação rode em alta disponibilidade.

Acredito que no mínimo 2 worker nodes é ideal para começar com alta disponibilidade. Alguns recursos no kubernetes seriam ideal pelo menos 3 workers nodes que seria o melhor cenário.

Para entender qual opção de dimensionamento selecionar, considere os prós e contras.

Preços de instância: Geralmente, você pode presumir que o custo da instância por CPU/RAM é linear entre as principais plataformas de nuvem.

Ao determinar a capacidade do seu cluster, há muitas maneiras de abordar o dimensionamento dos nós. Por exemplo, se você calculou um tamanho de cluster de 16 CPU e 64 GB de RAM, poderá dividir o tamanho do nó nestas opções:

2 nós: 8 CPU / 32 GB de RAM 4 nós: 4 CPU / 16 GB de RAM 8 nós: 2 CPU / 8 GB de RAM 16 nós: 1 CPU / 4 GB de RAM


Menos nós maiores

Prós

Se você tiver aplicativos que usam muita CPU ou RAM, ter nós maiores pode garantir que seu aplicativo tenha recursos suficientes.

Contras A alta disponibilidade é difícil de conseguir com um conjunto mínimo de nós. Se seu aplicativo tiver 50 pods em dois nós (25 pods por nó) e um nó ficar inativo, você perderá 50% do seu serviço.

Dimensionamento: ao dimensionar automaticamente o cluster, o tamanho do incremento torna-se maior, o que pode resultar no provisionamento de mais hardware do que o necessário.

Mais nós menores

Prós

  • A alta disponibilidade é mais fácil de manter. Se você tiver 50 instâncias com dois pods por nó (25 nós) e um nó ficar inativo, você reduzirá sua capacidade de serviço em apenas 4%.

Contras

  • Mais sobrecarga do sistema para gerenciar todos os nós.
  • Possível subutilização, pois os nós podem ser demasiado pequenos para adicionar serviços adicionais.
  • Um simples daemonset como node exporter do Prometheus teria nesse caso 50 pods.

Equilíbrio

Esse cenário seria bastante interessante:

  • 4 nodes com 16gb se as aplicações forem maiores
  • 8 nodes com 8GB aplicações menores

Onde será criado? WHERE?

Será um cluster na cloud? Se for na cloud facilite tudo para que possa se concentrar nas aplicações e deixe a cloud cuidar do control plane. AWS temos o EKS que pode ser lançado com o Kops ou módulos no terraform. GCP temos o GKS Azure temos o AKS.

Será on-premises? kubespray e kubeadm são ótimas ferramentas para ajudar a implantar o cluster

Dicas:

  • Sempre que possível utilize SSD no armazenamento para ter uma performance maior.
  • Para múltiplos pods acessando o mesmo storage, dê preferência para Network storage
  • Defina labels nos tipos de storage para facilitar a implantação usando o armazenamento correto
  • Crie node selectors para colocar os pods nos nodes com melhor desempenho para este pod
  • A boa prática recomenda reservar os masters para não implantar nada, apenas os componentes do Kubernetes. Garanta que um taint esteja aplicado nesses masters.
  • Defina recursos dedicados para o kubelet em cada worker node.

O que teremos no cluster? WHAT? Quantas aplicações estarão no cluster? Que tipo de aplicações será usada no cluster? Os recursos podem variar se for aplicativos web, aplicativos efêmeros, big data, etc Tipo de recursos usados por essas aplicações? Uso intenso de cpu ou de memória. Serão aplicações com uso intenso de rede?

Um detalhe que deve ser avaliado é em clusters muito grandes ter um cluster ETCD dedicado separado dos masters. Somente leve isso em consideração em cluster extremamente grandes. Enquanto puder manter o etcd junto aos masters mantenha.

Kubernetes Infrastructure

Podemos implantar o Kubernetes na nossa máquina local, em máquinas físicas dedicadas, na cloud, em máquinas virtualizadas, etc.

Local e Desenvolvimento

No Windows não é possível rodar diretamente os componentes do Kubernetes pois não há binários disponíveis. É necessário virtualizar uma máquina Linux para esse propósito, seja usando o Hyper-V, VMware, VirtualBox, etc. No Linux poderíamos simplesmente levantar todos os componentes diretamente como serviço se quisermos.

Outro cenário muito utilizado é utilizar esses componentes como containers. Da mesma forma, Windows não roda um Docker nativamente, por baixo dos panos ele cria uma VM e roda no Linux.

Mas de um jeito ou de outro você precisará estar no Linux seja virtualizado ou não. Containers são do mundo Linux.

Minikube cria uma máquina virtual já com um cluster single node. Pode ser usado vários virtualizadores como VirtualBox, VMware, Hyper-V, etc.

Gosto bastante das ferramentas kind e K3D que utilizam Docker in Docker. Os containers atuam "como um sistema operacional com Docker instalado" que sobe mais containers dentro dele. Container dentro de container. Criando uma ideia de NODE. É preciso ter o Docker instalado ou algum container runtime.

O kubeadm espera que a máquina já esteja provisionada. Um bom cenário é ter máquinas virtuais prontas para formar um cluster com a ferramenta kubeadm, pois este binário espera que as VMs estejam provisionadas Pode criar single ou múltiplos nodes. O Vagrant é uma ótima opção para automatizar o processo localmente.

Produção

Existem dois tipos de soluções

Turnkey Solutions

Essas são ferramentas ou scripts que funcionam para criar o cluster. Você pode fornecer as VMs necessárias e essas ferramentas ajudam a configurar o cluster. Você é responsável por manter as VMs, aplicar patches, atualizações, etc.

  • Você provisiona as VMs
  • Você configura as VMs
  • Usa as ferramentas para implantar o cluster
  • Você mantém as VMs

Kubespray e kops seriam ótimos exemplos.

OpenShift seria um exemplo Cloud Foundry Container Runtime VMware Cloud PKS Vagrant

Hosted Solutions ou Managed Solutions

São como Kubernetes as a Service. Geralmente soluções prontas de alguma cloud.

  • O provedor provisiona as VMs
  • O provedor instala o Kubernetes e mantém as VMs

OpenShift Online AKS GKS EKS

Alta Disponibilidade

O que acontece com o resto do cluster quando perdemos o master se só tivermos um?

![singlemaster](/docs/kubernetes/certifications/cka/Installation Configuration Validation/pics/singlemaster.gif)

Enquanto os workers estiverem funcionando e os containers estiverem rodando, e as aplicações estiverem respondendo, tudo continuará normal até que algo comece a falhar.

Se algum container falhar ele não subirá mais pois não temos os controllers para monitorá-los e garantir e avisar ao worker que precisa carregar um novo pod.

O acesso ao cluster através das APIs ou kubectl não será possível.

Por isso deve considerar mais master nodes.

Em todos os nós master devem rodar os mesmos componentes do Kubernetes a fim de evitar um único ponto de falha.

Da mesma forma, os worker nodes com as aplicações. Se um worker node que roda a aplicação parar, todos os pods não estarão disponíveis naquele node e começará a mover os pods para outro node, mas existirá um tempo de indisponibilidade até que tudo seja reconhecido. Por isso é bom ter mais workers e definir critérios para que as replicas do mesmo pod evitem ao máximo estarem no mesmo node.

Vamos focar no master, sabendo que precisamos ter os mesmos componentes dentro deles.

O kube-apiserver funciona no modo active-active. Isso quer dizer que se apontarmos o kubeconfig para qualquer um dos master nodes teremos a resposta. O ideal é ter um load balancer na frente do cluster que enviará as requisições de modo balanceado para definir qual kube-apiserver deve responder.

Os outros componentes (kube-controller-manager, kube-scheduler, etcd) do master trabalham no modo active-passive. Isso quer dizer que o líder é quem define as coisas e os outros ficam em modo passivo conferindo se o líder está rodando. Caso pare, os passivos entrarão em ação para ser o novo líder.

Como isso funciona?

Toda vez que os componentes active-passive iniciam, eles tentam pegar o endpoint para o componente em questão para se tornar líder.

apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
component: kube-controller-manager
tier: control-plane
name: kube-controller-manager
namespace: kube-system
spec:
containers:
- command:
- kube-controller-manager
- --allocate-node-cidrs=true
- --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf
- --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf
- --bind-address=127.0.0.1
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --cluster-cidr=10.244.0.0/16
- --cluster-name=kind-cluster
- --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
- --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
- --controllers=*,bootstrapsigner,tokencleaner
- --enable-hostpath-provisioner=true
- --kubeconfig=/etc/kubernetes/controller-manager.conf
- --leader-elect=true # Habilitação da eleição de líder
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
- --root-ca-file=/etc/kubernetes/pki/ca.crt
- --service-account-private-key-file=/etc/kubernetes/pki/sa.key
- --service-cluster-ip-range=10.96.0.0/16
- --use-service-account-credentials=true
image: registry.k8s.io/kube-controller-manager:v1.29.1

Outros parâmetros são default e não especificados aqui

  • --leader-elect-lease-duration 15s : que define o tempo de duração que ele será o líder
  • --leader-elect-renew-deadline 10s : que avisa que ele tentará renovar para ser o líder a cada 10 segundos. Ou seja, antes do lease acabar ele já atualiza para 10 segundos depois para mais 15s
  • --leader-elect-retry-period 2s : É o tempo que quem não for o líder irá conferir se pode ser o novo líder.

No caso do ETCD temos a opção de removê-los dos masters e criar um cluster de ETCD (não é outro cluster Kubernetes) chamado external ETCD.

Implantar o ETCD nos masters e gerenciar é mais fácil com certeza, além de economizar recursos. Essa topologia com o ETCD dentro dos masters é chamada de Stacked Topology.

Quando um master node para de responder a redundância é comprometida, mas por quê?