Garantir alta disponibilidade para MongoDB no Kubernetes
Avalie esse Tutorial
Um banco de dados é uma coleção estruturada de dados que permite armazenamento, recuperação e manipulação eficientes de informações. Os bancos de dados são fundamentais para aplicativos modernos e oferecem suporte a funções críticas, como armazenamento de contas de usuário, transações e muito mais. Garantir a alta disponibilidade de um banco de dados é vital, pois o tempo de inatividade pode levar a interrupções significativas, perda de dados e impactos financeiros. A alta disponibilidade garante que um banco de dados permaneça acessível e funcional, mesmo diante de falhas de hardware, problemas de rede ou outras interrupções. Neste tutorial, vamos nos concentrar em obter alta disponibilidade com o MongoDB.
MongoDB, quando implantado no Kubernetes, pode aproveitar os recursos de orquestração e automação da plataforma para aumentar sua disponibilidade e resiliência. Com seus recursos robustos para gerenciamento, dimensionamento e recuperação de contêineres, o Kubernetes fornece um ambiente ideal para a implantação de instâncias MongoDB altamente disponíveis. Este tutorial guiará você pelas etapas necessárias para implantar o MongoDB no Kubernetes, configurá-lo para alta disponibilidade, configurar mecanismos de backup usando o mongodumpe implementar o dimensionamento automático para lidar com cargas de trabalho variáveis.
Para acompanhar este tutorial, verifique se você tem:
- Docker instalado em sua máquina.
- Um cluster Kubernetes com pelo menos três nós. Este tutorial usa um cluster Kubernetes baseado em nuvem.
- Kubectl instalado e configurado em sua máquina para interagir com o cluster Kubernetes.
Para começar, você precisará definir os recursos e as configurações necessárias para implantar o MongoDB em seu cluster Kubernetes. Você criará um volume persistente para garantir que seus dados do MongoDB sejam mantidos mesmo que os pods sejam reagendados. Você também configurará um serviço headless para permitir uma comunicação de rede estável entre os pods do MongoDB. Por fim, você distribuirá o MongoDB usando um StatefulSet, que gerenciará a implantação e o dimensionamento dos pods do MongoDB enquanto mantém suas identidades exclusivas.
Observação: se quiser ler mais sobre os conceitos mencionados, você pode acessar a documentação do Kubernetes.
Adicione as seguintes definições de configuração em um arquivo chamado
pv-pvc.yaml
. Isso criará um volume persistente chamado mongodb-pv
e uma reivindicação de volume persistente chamada mongodb-pvc
:O PersistentVolume (PV) fornecerá o armazenamento real, enquanto o PersistentVolumeClaim (PVC) solicitará o armazenamento a partir do VP disponível.
1 apiVersion: v1 2 kind: PersistentVolume 3 metadata: 4 name: mongodb-pv 5 spec: 6 capacity: 7 storage: 5Gi 8 accessModes: 9 - ReadWriteOnce 10 hostPath: 11 path: /data/mongodb 12 --- 13 apiVersion: v1 14 kind: PersistentVolumeClaim 15 metadata: 16 name: mongodb-pvc 17 spec: 18 storageClassName: "" 19 accessModes: 20 - ReadWriteOnce 21 resources: 22 requests: 23 storage: 5Gi
Execute os seguintes comandos para criar o PersistentVolume e oPersistentVolumeClaim:
1 kubectl apply -f pv-pvc.yaml
Confirme que eles foram criados com os seguintes comandos:
1 kubectl get pv 2 kubectl get pvc
Você deverá ver uma saída semelhante à seguinte, confirmando que PersistentVolume e PersistentVolumeClaim foram criados com sucesso:
Em seguida, crie um serviço headless para gerenciar identidades de rede estáveis para os pods MongoDB. Em um arquivo chamado
headless-service.yaml
, adicione a seguinte configuração; isto criará um serviço headless para seu MongoDB database chamado mongodb-service
:1 apiVersion: v1 2 kind: Service 3 metadata: 4 name: mongodb-service 5 spec: 6 clusterIP: None 7 selector: 8 app: mongodb 9 ports: 10 - port: 27017
Aplique o serviço headless ao seu cluster Kubernetes usando o comando:
1 kubectl apply -f headless-service.yaml
Confirme que o serviço headless foi criado usando o seguinte comando:
1 kubectl get svc
A seguinte saída é esperada:
Configure a autenticação para seu conjunto de réplicas MongoDB utilizando os seguintes comandos:
Configurar a autenticação para seu conjunto de réplicas MongoDB usando o mongodb-keyfile é crucial para proteger a comunicação entre os membros, evitar o acesso não autorizado e garantir que somente nós confiáveis possam ingressar no conjunto de réplicas, mantendo assim a integridade e a segurança dos dados.
1 sudo bash -c "openssl rand -base64 756 > mongodb-keyfile" 2 sudo chmod 400 mongodb-keyfile
Crie um segredo do Kubernetes para armazenar o arquivo de chave:
1 kubectl create secret generic mongodb-keyfile --from-file=mongodb-keyfile
Por fim, crie um StatefulSet para implantar o MongoDB com armazenamento persistente e identidades de rede estáveis. Em um arquivo chamado
statefulset.yaml
, adicione a seguinte configuração:1 apiVersion: apps/v1 2 kind: StatefulSet 3 metadata: 4 name: mongodb # Specifies the name of the statefulset 5 spec: 6 serviceName: "mongodb-service" # Specifies the service to use 7 replicas: 3 8 selector: 9 matchLabels: 10 app: mongodb 11 template: 12 metadata: 13 labels: 14 app: mongodb 15 spec: 16 containers: 17 - name: mongodb 18 image: mongo:latest 19 command: 20 - mongod 21 - "--replSet" 22 - rs0 23 - "--bind_ip_all" 24 ports: 25 - containerPort: 27017 26 volumeMounts: 27 - name: mongodb-storage 28 mountPath: /data/db 29 - name: keyfile 30 mountPath: /etc/mongodb-keyfile 31 readOnly: true 32 resources: 33 requests: 34 cpu: "100m" 35 memory: "256Mi" 36 limits: 37 cpu: "500m" 38 memory: "512Mi" 39 volumes: 40 - name: keyfile 41 secret: 42 secretName: mongodb-keyfile 43 defaultMode: 0400 44 volumeClaimTemplates: 45 - metadata: 46 name: mongodb-storage 47 spec: 48 accessModes: ["ReadWriteOnce"] 49 resources: 50 requests: 51 storage: 5Gi
Aplique o StatefulSet ao seu cluster Kubernetes:
1 kubectl apply -f statefulset.yaml
Confirme que o StatefulSet foi criado com sucesso com todos os pods íntegros e em execução:
1 kubectl get statefulsets 2 kubectl get pods
Você deverá ter a seguinte saída com o StatefulSet criando três pods do MongoDB denominados
mongodb-0
, mongodb-1
e mongodb-2
:Para garantir alta disponibilidade para seu banco de MongoDB database, você configurará um conjunto de réplicas. Um conjunto de réplicas no MongoDB é um grupo de instânciasmongod que mantém o mesmo conjunto de dados, fornecendo redundância e alta disponibilidade.
Antes de configurar o conjunto de réplicas, é útil ter alguns dados presentes. Esta etapa é opcional, mas ter dados em seu banco de dados ajudará você a entender o processo de backup com mais clareza nas subseções a seguir.
Primeiro,
exec
em um dos pods do MongoDB e inicialize o conjunto de réplicas. Normalmente, você usaria o primeiro pod (por exemplo, mongodb-0
).1 kubectl exec -it mongodb-0 -- mongosh 2 3 rs.initiate({ 4 _id: "rs0", 5 members: [ 6 { _id: 0, host: "mongodb-0.mongodb-service:27017", priority: 2 }, 7 { _id: 1, host: "mongodb-1.mongodb-service:27017", priority: 1 }, 8 { _id: 2, host: "mongodb-2.mongodb-service:27017", priority: 1 } 9 ] 10 })
Você deve ver a seguinte saída:
1 test> rs.initiate({ 2 ... _id: "rs0", 3 ... members: [ 4 ... { _id: 0, host: "mongodb-0.mongodb-service:27017", priority: 2 }, 5 ... { _id: 1, host: "mongodb-1.mongodb-service:27017", priority: 1 }, 6 ... { _id: 2, host: "mongodb-2.mongodb-service:27017", priority: 1 } 7 ... ] 8 ... }) 9 { 10 ok: 1, 11 '$clusterTime': { 12 clusterTime: Timestamp({ t: 1718718451, i: 1 }), 13 signature: { 14 hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0), 15 keyId: Long('0') 16 } 17 }, 18 operationTime: Timestamp({ t: 1718718451, i: 1 }) 19 } 20 rs0 [direct: secondary] test>
Quando se trata de conjuntos de réplicas, a inserção ocorre apenas no primário. Como definimos o primeiro pod
mongodb-0
para servir como principal, podemos fazer inserções. No entanto, se você não tiver certeza de qual pod é o principal, pode fazer isso usando o comando:1 rs.status()
Mude para um banco de dados chamado “users” e insira alguns dados usando os seguintes comandos:
1 use users 2 3 db.femaleusers.insertOne({ name: "Jane Doe", age: 30, email: "jane.doe@example.com" }) 4 db.femaleusers.insertOne({ name: "Mary Smith", age: 25, email: "mary.smith@example.com" }) 5 db.femaleusers.insertOne({ name: "Alice Johnson", age: 28, email: "alice.johnson@example.com" }) 6 db.femaleusers.insertOne({ name: "Emily Davis", age: 32, email: "emily.davis@example.com" }) 7 db.femaleusers.insertOne({ name: "Sarah Brown", age: 27, email: "sarah.brown@example.com" }) 8 9 db.femaleusers.find() 10 exit
Observação: você pode usar o comando
find()
para listar os usuários que acabamos de inserir. Esse comando pode ser executado em qualquer um dos membros do conjunto de réplicas, incluindo os pods secundários.Depois de executar os comandos, você deverá ver as seguintes saídas indicando a inserção bem-sucedida dos documentos na collection
femaleusers
no banco de dadosusers
:Com alguns dados já inseridos em seu MongoDB database, agora você está pronto para iniciar a primeira etapa de alta disponibilidade do MongoDB database usando mongodump.
Primeiro, crie um PV e um PVC separados para armazenar backups adicionando as seguintes definições de configuração em um arquivo
backup-pv-pvc.yaml
:1 apiVersion: v1 2 kind: PersistentVolume 3 metadata: 4 name: backup-pv 5 spec: 6 capacity: 7 storage: 5Gi 8 accessModes: 9 - ReadWriteOnce 10 hostPath: 11 path: /mnt/backup 12 --- 13 apiVersion: v1 14 kind: PersistentVolumeClaim 15 metadata: 16 name: backup-pvc 17 spec: 18 accessModes: 19 - ReadWriteOnce 20 resources: 21 requests: 22 storage: 5Gi
Aplique isso com o seguinte comando:
1 kubectl apply -f backup-pv-pvc.yaml
Confirme se eles foram criados com os seguintes comandos:
1 kubectl get pv 2 kubectl get pvc
Para fazer backup dos dados do MongoDB, você criará um Kubernetes CronJob que usará o utilitário
mongodump
. Usar um CronJob aqui significa que você pode agendar quando deseja que os backups ocorram automaticamente.Crie um arquivo denominado
mongodb-backup-cronjob.yaml
com o seguinte conteúdo:1 apiVersion: batch/v1 2 kind: CronJob 3 metadata: 4 name: mongodb-backup 5 spec: 6 schedule: "*/5 * * * *" # Runs backup every five minutes 7 jobTemplate: 8 spec: 9 template: 10 spec: 11 containers: 12 - name: mongodump 13 image: mongo:latest 14 command: 15 - sh 16 - -c 17 - | 18 # Perform backup 19 mongodump --host=mongodb-service --port=27017 --out=/backup/$(date +\%Y-\%m-\%dT\%H-\%M-\%S) 20 # Remove backups older than 7 days 21 find /backup -type d -mtime +7 -exec rm -rf {} + 22 volumeMounts: 23 - name: backup-storage 24 mountPath: /backup 25 restartPolicy: Never 26 volumes: 27 - name: backup-storage 28 persistentVolumeClaim: 29 claimName: backup-pvc
Aplique a configuração para criar o CronJob e verifique se o CronJob foi criado:
1 kubectl apply -f mongodb-backup-cronjob.yaml 2 kubectl get cronjob
Você deverá ver um resultado semelhante ao seguinte, confirmando que o CronJob foi criado com sucesso:
Após cinco minutos, você pode confirmar o status dos pods usando o seguinte comando:
1 kubectl get pods
Você deve ver um pod com um nome semelhante a este que foi criado pelo CronJob:
Para verificar se o backup foi criado com sucesso, verifique os registros do pod de backup:
1 kubectl logs mongodb-backup-28635290-jfsjn
A saída do log deve ser semelhante a esta:
Para acessar os arquivos de backup, é necessário visualizar o conteúdo do volume persistente onde os backups estão armazenados. Crie um pod temporário para acessar esses arquivos criando um arquivo chamado
backup-access.yaml
com o seguinte conteúdo:Isso criará um
busybox
pod temporário que monta a reivindicação de backup-pvc
volume persistente (PVC) no /backup
diretório dentro do container, permitindo acessar e explorar os arquivos de backup armazenados no PV.1 apiVersion: v1 2 kind: Pod 3 metadata: 4 name: backup-access 5 spec: 6 containers: 7 - name: busybox 8 image: busybox 9 command: ["sh", "-c", "sleep 3600"] 10 volumeMounts: 11 - name: backup-storage 12 mountPath: /backup 13 volumes: 14 - name: backup-storage 15 persistentVolumeClaim: 16 claimName: backup-pvc
Aplique a configuração e acesse o pod temporário:
1 kubectl apply -f backup-access.yaml 2 kubectl exec -it backup-access -- sh
Uma vez dentro do pod, navegue até o diretório
/backup
para visualizar os arquivos de backup:1 cd /backup 2 ls 3 cd <file> 4 ls 5 cd users
Você deve ver a seguinte saída:
Agora, saia do contêiner do busybox digitando
exit
.Para garantir a alta disponibilidade do seu conjunto de réplicas MongoDB, você precisa testar os processos de failover e recuperação. Esta seção orientará você a simular uma falha e a verificar se a configuração do MongoDB pode lidar com isso normalmente.
Em um conjunto de réplicas do MongoDB, um membro é o nó primário responsável por lidar com as operações de gravação, enquanto os outros membros são nós secundários que replicam dados do primário. Se o nó primário falhar, o conjunto de réplicas elegerá automaticamente um novo primário dos nós secundários restantes.
Observação: para saber mais sobre conjuntos de réplicas no MongoDB, acesse a documentação sobre conjuntos de réplicas no MongoDB.
Comece identificando o nó primário atual:
1 kubectl exec -it mongodb-0 -- mongosh --eval "rs.status()"
Procure o membro com o atributo
"stateStr" : "PRIMARY"
:1 { 2 "_id" : 0, 3 "name" : "mongodb-0.mongodb-service:27017", 4 "stateStr" : "PRIMARY", 5 ... 6 }
Simule uma falha excluindo o pod de nó primário atual:
1 kubectl delete pod mongodb-0
Monitore o status do conjunto de réplicas e observe a eleição de uma nova primária:
1 kubectl exec -it mongodb-1 -- mongosh --eval "rs.status()"
Você deve ver que um dos nós secundários foi promovido a primary:
1 { 2 "_id" : 1, 3 "name" : "mongodb-1.mongodb-service:27017", 4 "stateStr" : "PRIMARY", 5 ... 6 }
Verifique se o pod excluído foi recriado e se juntou novamente ao conjunto de réplicas como um nó secundário:
1 kubectl get pods
Confirme se o pod está de volta e em execução:
1 NAME READY STATUS RESTARTS AGE 2 mongodb-0 1/1 Running 0 70s 3 mongodb-1 1/1 Running 0 77m 4 mongodb-2 1/1 Running 0 73m
Verifique novamente o status do conjunto de réplicas para garantir que o novo nó seja reeleito como primário, pois ele tinha a prioridade mais alta:
1 kubectl exec -it mongodb-0 -- mongosh --eval "rs.status()"
Você deve ver:
1 { 2 "_id" : 0, 3 "name" : "mongodb-0.mongodb-service:27017", 4 "stateStr" : "PRIMARY", 5 ... 6 }
Em um ambiente dinâmico, as demandas de carga de trabalho podem flutuar, exigindo que sua implantação do MongoDB seja dimensionada automaticamente para garantir um desempenho consistente. O Kubernetes fornece um recurso chamado Horizontal Pod Autoscaler (HPA) para gerenciar esse escalonamento.
O Kubernetes horizontal Pod Autoscaler dimensiona automaticamente o número de pods em um sistema, controlador de replicação ou conjunto de réplicas com base na utilização observada da CPU (ou em outras métricas selecionadas). Isso ajuda a garantir que seu aplicativo tenha a quantidade certa de recursos para lidar com níveis variados de tráfego.
Para configurar o dimensionamento automático para sua implementação do MongoDB , primeiro instale oServidor de Métricas MongoDB usando os comandos a seguir.
O HPA depende do servidor de métricas para coletar métricas do cluster Kubernetes.
1 kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
Você verá a seguinte saída se aplicado com sucesso:
Execute o comando
kubectl get pods -n kube-system
para visualizar o status dos pods do servidor de métricas. Você deve ver o seguinte:1 ~$ kubectl get pods -n kube-system 2 NAME READY STATUS RESTARTS AGE 3 ... 4 metrics-server-6d94bc8694-mkdrb 0/1 Running 0 60s
Neste momento, os contêineres no Metrics Server não estão em execução devido a problemas com o certificado TLS. Para resolver isso, execute o seguinte comando para editar a implantação do servidor de métricas:
1 kubectl edit deployment metrics-server -n kube-system
O comando
kubectl edit deployment metrics-server -n kube-system
abre a configuração de implantação em um editor vim por padrão. Para editar o arquivo, mova o cursor para a seção apropriada usando as teclas de seta. Digite i
para entrar no modo de inserção e fazer suas alterações. Depois de terminar a edição, pressione a teclaEsc
para sair do modo de inserção e digite :wq
para salvar as alterações e fechar o editor.Adicione os seguintes comandos à especificação do container para ignorar a verificação TLS:
1 spec: 2 containers: 3 - args: 4 ... 5 command: 6 - /metrics-server 7 - --kubelet-insecure-tls 8 - --kubelet-preferred-address-types=InternalIP
Depois de fazer essas alterações, confirme se os container estão em funcionamento executando:
1 kubectl get pods -n kube-system
Você deve ver a seguinte saída:
1 ~$ kubectl get pods -n kube-system 2 NAME READY STATUS RESTARTS AGEcalico-kube-controllers-67dfb8c8c9-spmcs 1/1 Running 0 16m 3 ... 4 metrics-server-777dff589b-b56lg 1/1 Running 0 117s
Verifique o uso de recursos dos Pods em seu cluster:
1 kubectl top pods
Você vê a seguinte saída:
Defina um recurso HPHA que especifique como e quando dimensionar o MongoDB StatefulSet usando o seguinte comando:
1 kubectl autoscale statefulset mongodb --min=3 --max=10 --cpu-percent=50
Essa configuração definirá o número mínimo de réplicas como
3
e permitirá o dimensionamento até um máximo de 10
réplicas com base na utilização da CPU.Você deve ver a seguinte saída:
1 horizontalpodautoscaler.autoscaling/mongodb autoscaled
Monitore o status do HPA usando o seguinte comando:
1 kubectl get hpa
Isso mostrará o status atual do HPA, incluindo o número atual de réplicas e as métricas usadas para o dimensionamento.
Alta disponibilidade é crucial para o bom funcionamento de qualquer sistema de banco de dados. Este tutorial demonstra como implantar o MongoDB no Kubernetes, configurá-lo para alta disponibilidade com um conjunto de réplicas, configurar mecanismos de backup usando o MongoDump e configurar o dimensionamento automático usando o HPA do Kubernetes. Seguindo as etapas destacadas neste tutorial, você pode manter o acesso contínuo aos seus dados para evitar tempos de inatividade significativos, o que pode levar à perda de dados e impactos financeiros. Como resultado, você terá durabilidade de dados e alta disponibilidade ao seu alcance.
Se você tiver alguma dúvida ou comentário, sinta-se à vontade para se juntar a nós na Comunidade de Desenvolvedores do MongoDB.
Principais comentários nos fóruns
Premanshu_MukherjiPremanshu Mukherji4 semanas atrás
Olá Misericórdia,
Esse foi um artigo muito útil. Foi exatamente o que eu precisei configurar, especialmente a configuração da réplica. Obrigado.
Tenho uma sugestão e uma query
Sugestão: Inclua um trecho de código sobre como se conectar ao MongoDB a partir de um Python Python ou Go Go lang. A string de conexão é o que eu estava tentando descobrir. Isso tornaria o artigo útil para os desenvolvedores.
Consulta: Uma implantação headless fornece todos os registros A para os pods do MongoDB . Quando nos conectamos ao MongoDB a partir de um aplicação, como é determinado qual pod será usado para escrever? Estou usando uma string de conexão que não tem nenhuma informação do pod e ainda posso me conectar. Quem faz a milagrosidade?
Foi uma sorte ver este artigo no primeiro resultado de pesquisa. Salvado muito.
Aguardando sua resposta,
Prem