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).
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!