Configure um cluster altamente disponível do Elasticsearch no Kubernetes

10 min de leitura
Patrocinado
Imagem de: Configure um cluster altamente disponível do Elasticsearch no Kubernetes
Avatar do autor

Equipe TecMundo

O Elasticsearch consiste em um popular motor de busca e análise de código aberto de natureza distribuída. Os recursos de gestão de shards e réplicas do Elasticsearch o tornam robusto e escalável e, se você implementar o Elasticsearch no Kubernetes, em vez de em máquinas virtuais ou físicas tradicionais, vai notar que ele é superfácil de instalar, configurar e gerenciar.

Quando se trata de implementações em nível empresarial, você precisa ter um cluster Elasticsearch altamente disponível em múltiplas zonas para que, se uma delas cair, o cluster ainda fique disponível. Neste tutorial, você aprenderá como configurar um cluster desse tipo.

Em praticamente todos os tipos de ambientes de nuvem, você pode ter um cluster de Kubernetes em uma região que se estende por múltiplas zonas que, por sua vez, tipicamente consistem em centros de dados bastante próximos uns dos outros. Afinal, você quer ter a aplicação disponível mesmo quando poucos nós em uma zona — ou uma zona inteira — se tornam indisponíveis.

Um cluster típico em nível de produção do Elasticsearch no Kubernetes é formado por pods-mestres, pods de dados e pods de ingestão. O componente de visualização consiste no pod A Kibana, enquanto os pods-mestres controlam o cluster do Elasticsearch, incluindo a criação ou a exclusão de índices, rastreamento de membros do cluster e alocação de shards para diferentes pods de dados. O Elasticsearch requer um nó-mestre estável para o seu funcionamento, e os pods de dados guardam as informações e realizam operações de CRUD, de busca e de agregações. Os nós de ingestão ajudam na transformação e no enriquecimento de dados antes que eles sejam armazenados no índice como documentos. O pod de dados e o pod-mestre requerem armazenamento persistente e, por isso, são implementados no Kubernetes como StatefulSets. Os Kibana e os pods de ingestão não exigem armazenamento persistente e são instalados como controladores de implementação do Kubernetes.

Um requisito importante para o Elasticsearch é ter unidades de estado sólido (SSDs) locais para armazenamento e melhor desempenho. Neste tutorial, você usará SSDs locais para o Elasticsearch, e sua solução de exemplo atingirá tanto alta disponibilidade quanto alta tolerância a falhas em uma única zona.

Requisitos

Antes seguir adiante com este tutorial, verifique se você tem o seguinte ambiente:

  • Um cluster do Kubernetes que se estenda por três zonas. Se você estiver utilizando o IBM Cloud, será mais fácil criar um cluster de múltiplas zonas com o serviço Kubernetes.

  • Um mínimo de dois nós de trabalho por zona; o recomendado são três nós de trabalho por zona.

  • Os nós de trabalho no cluster que contenham discos de estado sólido locais.

Tempo estimado

Este tutorial deve levar cerca de 30 minutos para ser concluído.

Uma visão geral da arquitetura

A ilustração a seguir exibe a arquitetura dessa solução. Existem três zonas, e o ideal é que você tenha pelo menos um pod-mestre disponível em cada uma. Da mesma forma, o recomendado é que você tenha um mínimo de um pod de dados por zona. Quando você precisar adicionar mais pods de dados, adicione um múltiplo de três (sendo um para cada zona).

Visão geral da arquitetura

O Elasticsearch tem a capacidade de levar em conta a sua configuração física de hardware ao alocar shards. Se o Elasticsearch souber quais são os pods que se encontram em uma mesma mesma zona, ele poderá distribuir o shard primário e suas réplicas para pods em várias zonas. Essa distribuição minimiza o risco de perda de todas as cópias de shards no caso de falha de uma zona. Você pode utilizar esse recurso para identificar as respectivas zonas para cada um dos pods de dados. Nessa configuração, os shards são alocados de maneira que todos se encontrem em uma mesma zona, enquanto os shards primários ou suas réplicas ficam disponíveis nas outras duas, o que permite que você mantenha uma zona com falha.

Verifique o código disponível no Github. Há um StatefulSet para implementar três pods-mestres. Também existem outros três StatefulSets para implementar os pods de dados. A diferença entre esses três StatefulSets está na afinidade entre os nós, que você implementa em nós classificados por zona usando a especificação nodeAffinity. Além disso, o atributo zona é definido na variável de ambiente node.attr.zone do container com valores definidos para a, b ou c em cada pod de dados StatefulSet.

O es-config ConfigMap se aplica a todos os pods de dados e de ingestão, enquanto o es-master-config ConfigMap se aplica aos pods-mestres. O nome do cluster em todas essas configurações é definido como sandbox-es, que compõe um cluster do ElasticSearch usando pods de diferentes StatefulSets e implementações.

Etapas

Imagine um cenário no qual você tem nove clusters de nós com três nós em cada zona. Nas etapas seguintes, você configurará um cluster do Elasticsearch com dois pods de dados e um pod-mestre em cada zona. Portanto, se um ou mais nós em uma zona se tornarem indisponíveis, as suas operações no cluster do Elasticsearch não serão afetadas.

  • 1. Você precisa de um provisionador de armazenamento local-path para provisionar o PersistentVolume nos nós. Assim, instale essa ferramenta:

kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-

  • 2. Identifique os nós para indicar em qual zona eles estão presentes. Você tem três zonas (a, b e c) e nove nós (nomeados r1, r2, r3, d1, d2, d3, r4, r5 e r6), com três nós em cada zona:

kubectl label node r1 r2 r3 zone=a

 kubectl label node d1 d2 d3 zone=b

 kubectl label node r4 r5 r6 zone=c

Observação: ao fazer a implementação no Cloud, você terá a opção de escolher a rotulagem padrão para as zonas, por exemplo:

failure-domain.beta.kubernetes.io/zone=dal12

 failure-domain.beta.kubernetes.io/region=us-south

 ibm-cloud.kubernetes.io/zone: dal12

 ibm-cloud.kubernetes.io/region=us-south

No Kubernetes 1.17 e em versões mais recentes, você pode usar os rótulos de topologia com o IBM Cloud. Caso você decida usar algum desses rótulos, certifique-se de modificar os arquivos yaml para usá-los. No exemplo presente na próxima etapa, você continuará usando o rótulo personalizado zone=a, b ou c.

  • 3. Rotule os nós para indicar qual função eles suportam; por exemplo, dados Elastic ou mestres:

kubectl label node r1 r2 d1 d2 r4 r5 es-data=yes

 kubectl label node r3 d3 r6 es-master=yes

Dessa forma, você terá seis nós de dados e três nós-mestres para que um nó-mestre fique disponível em cada zona e dois nós de dados fiquem disponíveis em cada zona. Como os nós de ingestão do Elastic e Kibana não usam o armazenamento de persistência, você pode deixá-los livres para circular por qualquer nó.

  • 4. Procure nos arquivos .yaml qualquer customização necessária (por exemplo, kibana.yaml para configuração do serviço).
  • 5. Clone o Git repo, crie um namespace e implemente:

git clone https://github.com/ideagw/elasticsearch-k8s.git

 kubectl create ns es      

 kubectl -n es apply -f ./multizone/

  •  6. Revise a lista de pods:

kubectl -n es get pods -o wide

 NAME                       READY   STATUS    RESTARTS   AGE   IP             NODE                   

 es-data-a-0                1/1     Running   0          25m   10.244.1.35    r1.sl.cloud9.ibm.com   

 es-data-a-1                1/1     Running   0          25m   10.244.2.43    r2.sl.cloud9.ibm.com   

 es-data-b-0                1/1     Running   0          25m   10.244.6.159   d1.sl.cloud9.ibm.com   

 es-data-b-1                1/1     Running   0          25m   10.244.7.240   d2.sl.cloud9.ibm.com   

 es-data-c-0                1/1     Running   0          25m   10.244.4.196   r4.sl.cloud9.ibm.com   

 es-data-c-1                1/1     Running   0          25m   10.244.5.210   r5.sl.cloud9.ibm.com   

 es-ingest-dbc9ddc8-8sqqc   1/1     Running   0          25m   10.244.3.143   r3.sl.cloud9.ibm.com   

 es-ingest-dbc9ddc8-qf5f9   1/1     Running   0          25m   10.244.5.206   r6.sl.cloud9.ibm.com   

 es-master-0                1/1     Running   0          25m   10.244.5.208   r6.sl.cloud9.ibm.com   

 es-master-1                1/1     Running   0          25m   10.244.3.145   r3.sl.cloud9.ibm.com   

 es-master-2                1/1     Running   0          25m   10.244.8.77    d3.sl.cloud9.ibm.com   

 kibana-5fdfbcbc97-8wvsv    1/1     Running   0          25m   10.244.6.160   d1.sl.cloud9.ibm.com

Como você pode ver, cada zona tem o seu próprio conjunto de dois pods de dados cada. Existem dois pods de ingestão, três pods-mestres, com um em cada zona, e um pod kibana. Leva alguns minutos para o Elasticsearch formar o cluster, e você pode confirmar o progresso do processo checando os logs dos dados ou dos pods-mestres. Para interagir com o Elasticsearch, utilize seus REST APIs. Acione os REST APIs usando o curl ou a funcionalidade DevTools do Kibana. Os passos seguintes usam o comando curl.

  • 7. Para acionar os REST APIs, você precisará do endereço de IP do cluster no Elasticsearch. Verifique o endereço de IP do serviço Elasticsearch:

kubectl -n es get service elasticsearch

 NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE

 elasticsearch   ClusterIP   10.102.46.55           9200/TCP   25m

Como você pode ver, não há IP externo exposto, o que significa que você deverá executar os comandos do curl a partir do nó-mestre do Kubernetes. Se você estiver usando o IBM Cloud, use o terminal web para ter acesso à rede interna do pod.

Agora você está pronto para verificar o estado do cluster:

curl "http://10.102.46.55:9200/_cluster/health?pretty"

Na resposta JSON, procure o campo status. Se o seu valor for green, isso significa que o cluster está pronto para entrar em ação.

  • 8. Crie um índice chamado twitter com três shards e uma réplica cada:

curl -X PUT "http://10.102.46.55:9200/twitter?pretty" -H 'Content-Type: application/json' -d'

 {

     "settings" : {

     "index" : {

         "number_of_shards" : 3,

           "number_of_replicas" : 1

         }

     }

 }

 '

 O resultado será esse que você pode conferir no exemplo a seguir:

{

 "acknowledged" : true,

     "shards_acknowledged" : true,

     "index" : "twitter"

 }

  • 9. Verifique se para cada shard a alocação primária e a réplica se encontram em zonas diferentes:

curl http://10.102.46.55:9200/_cat/shards/twitter?pretty=true

 

 twitter 2 p STARTED 0 230b 10.244.7.242 es-data-b-1

 twitter 2 r STARTED 0 230b 10.244.4.197 es-data-c-0

 twitter 1 p STARTED 0 230b 10.244.1.36  es-data-a-0

 twitter 1 r STARTED 0 230b 10.244.5.212 es-data-c-1

 twitter 0 p STARTED 0 230b 10.244.2.44  es-data-a-1

 twitter 0 r STARTED 0 230b 10.244.6.161 es-data-b-0

  • 10. Insira alguns dados no índice do twitter:

curl -X  POST "http://10.102.46.55:9200/twitter/_doc/" -H 'Content-Type: application/json' -d'

{

"user" : "elasticuser",

"post_date" : "2019-11-15T14:12:12",

"message" : "trying out Elasticsearch"

}

'

A resposta será como o exemplo a seguir:

{

  "_index" : "twitter",

  "_type" : "_doc",

  "_id" : "352akW8B4tm0-AjGic8M",

  "_version" : 1,

  "result" : "created",

  "_shards" : {

    "total" : 2,

    "successful" : 2,

    "failed" : 0

  },

  "_seq_no" : 0,

  "_primary_term" : 1

}

  • 11. Simule a falha de zona “derrubando” os pods. Uma maneira fácil de desativá-los consiste em simplesmente diminuir os statefulsets para que o mestre da zona c e os pods de dados desapareçam:

kubectl -n es scale sts es-master --replicas=2

kubectl -n es scale sts es-data-c --replicas=0

Essa etapa remove o pod es-master-2 e os dois pods de dados da zona c.

  • 12. Agora verifique os shards:

curl http://10.102.46.55:9200/_cat/shards/twitter?pretty=true

twitter 1 p STARTED    0 283b 10.244.1.36  es-data-a-0

twitter 1 r UNASSIGNED                     

twitter 2 p STARTED    0 283b 10.244.7.242 es-data-b-1

twitter 2 r UNASSIGNED                     

twitter 0 p STARTED    0 283b 10.244.2.44  es-data-a-1

twitter 0 r STARTED    0 283b 10.244.6.161 es-data-b-0

Como você pode ver, os shards 1 (réplica) e 2 (réplica) ficam sem atribuição. Entretanto, se houver algum dado nesses shards, ele ainda estará disponível quando você fizer uma busca. Da mesma forma, você ainda poderá inserir dados no cluster. A capacidade de chamar essa API prova que o cluster ainda se encontra acessível.

  • 13. Faça uma busca para ter certeza que você ainda pode ver os dados:

curl http://10.102.46.55:9200/twitter/_search?q=user:elastic*

O resultado aparecerá como no exemplo seguinte:

{

        "user" : "elasticuser",

        "post_date" : "2019-11-15T14:12:12",

        "message" : "trying out Elasticsearch"

}

A busca ainda funciona e você obterá o resultado. Você pode inserir mais registros e realizar mais testes se quiser.

Resumo

Como você pode ver pela alocação de shards expostas nas etapas anteriores, o shard 0 se encontra nas zonas a e b, o shard 1 nas zonas a e c, e o shard 2 nas zonas b e c. Se uma zona cair, o shard 0 (primário) e o shard 1 (primário) não estarão disponíveis, mas suas réplicas estarão disponíveis nas zonas b e c, respectivamente. Da mesma forma, se qualquer outra zona cair, o shard primário ou a réplica dessa zona estará disponível nas outras duas. Você viu esse comportamento na zona c anterior.

Portanto, você poderá obter alta disponibilidade do cluster Elasticsearch de dentro de uma região. Caso você tenha que planejar alta disponibilidade entre regiões, a função de replicação cruzada do Elasticsearch será bastante útil. Agora, você tem o conhecimento necessário para configurar clusters Elasticsearch de múltiplas zonas similares em outra região e configurar a replicação entre os dois clusters do Elasticsearch. Essa abordagem também dá a você proteção contra falhas de região.

...

Quer ler mais conteúdo especializado de programação? Conheça a IBM Blue Profile e tenha acesso a matérias exclusivas, novas jornadas de conhecimento e testes personalizados. Confira agora mesmo, consiga as badges e dê um upgrade na sua carreira!

Você sabia que o TecMundo está no Facebook, Instagram, Telegram, TikTok, Twitter e no Whatsapp? Siga-nos por lá.