
Este artigo continua nosso
material de migração
recente do RabbitMQ e é dedicado ao MongoDB. Como atendemos muitos clusters Kubernetes e MongoDB, chegamos à necessidade natural de migrar dados de uma instalação para outra e fazê-lo sem tempo de inatividade. Os principais cenários são os mesmos: transferência do MongoDB de um servidor virtual / iron para o Kubernetes ou transferência do MongoDB dentro de um cluster Kubernetes (de um espaço para nome para outro).
Nossa receita é destinada a casos em que o cluster antigo do MongoDB está funcionando (por exemplo, de 3 nós e já está localizado nos K8s ou em servidores antigos) com os quais um aplicativo hospedado no Kubernetes trabalha:

Como vamos transferir esse cluster para uma nova produção no Kubernetes?
Teoria
O algoritmo de migração geral é semelhante ao descrito na situação com o RabbitMQ.
É importante observar que a capacidade de mover exige que os servidores com MongoDB e Kubernetes estejam na mesma rede. Os nós do cluster do MongoDB se comunicarão pelo IP de servidores antigos (onde estão localizadas as antigas instalações do MongoDB) e pelos nomes DNS dos pods do MongoDB no K8s. Portanto, em servidores iron (com instalações antigas), será necessário encaminhar rotas para pods e configurá-las para usar o servidor DNS em execução no Kubernetes (ou registrar os nomes necessários em
/etc/hosts
, embora no geral seja melhor evitar essa possibilidade )
O próximo passo é aumentar o cluster do MongoDB nos pods do Kubernetes. No nosso caso, o cluster do banco de dados consiste em 3 nós e cada nó está localizado em um pod'8 K8s separado - no entanto, seu número pode ser diferente. No ConfigMap, você deve especificar o endereço do mestre do MongoDB a partir da instalação antiga: os nós do MongoDB localizados nos pods do K8s começarão a sincronizar imediatamente com ele.
Depois que todos os pods são ativados, um cluster MongoDB de 6 nós é formado:

Observe que os pods aumentarão por um longo tempo, pois cada pod é iniciado por sua vez e, no momento do lançamento, sincroniza os dados do assistente.
Depois disso, você pode alternar o aplicativo para usar os novos servidores MongoDB:

E resta apenas remover os nós antigos do cluster MongoDB, após o qual a movimentação pode ser considerada concluída:

Costumamos usar esse esquema na produção e, para sua conveniência, o implementamos no módulo
addon-operator (
anunciamos recentemente esse utilitário), o que nos permite distribuir configurações típicas do MongoDB em muitos clusters. Planejamos publicar nossos módulos em um futuro próximo, mas por enquanto apresentamos instruções separadas com as quais você pode tentar a solução proposta em ação e sem usar o operador addon.
Tentamos na prática
Exigências
Detalhes:
- Cluster Kubernetes (o minikube também é adequado);
- Cluster MongoDB (pode ser implantado no bare metal e criado como um cluster regular no Kubernetes a partir do gráfico oficial do Helm).
No exemplo descrito abaixo, o cluster antigo com o MongoDB será chamado
mongo-old
e instalado no mesmo cluster Kubernetes, onde no futuro instalaremos o novo (
mongo-new
).
Preparando o cluster antigo
1. Para um exemplo demonstrando o esquema descrito em ação, criaremos um cluster MongoDB “antigo” (isto é, sujeito a migração) diretamente no Kubernetes (na realidade, ele também pode estar localizado em servidores separados fora do K8s). Para fazer isso, baixe o gráfico Helm:
helm fetch --untar stable/mongodb-replicaset
... e edite-o um pouco configurando a autorização:
auth: enabled: true adminUser: mongo adminPassword: pa33w0rd # metricsUser: metrics # metricsPassword: password # key: keycontent # existingKeySecret: # existingAdminSecret: # exisitingMetricsSecret:
Também em
values.yaml
você pode configurar certificados e muito mais.
2. Defina o gráfico:
helm install . --name mongo-old --namespace mongo-old
Depois disso, a instalação "antiga" de teste do MongoDB será iniciada:
kubectl --namespace=mongo-old get pods

Vamos ao pod com seu mestre e criar uma base de teste:
kubectl --namespace=mongo-old exec -ti mongo-old-mongodb-replicaset-0 mongo use admin db.auth('mongo','password') use music db.artists.insert({ artistname: "The Tea Party" }) show dbs

Entrando em diferentes pods, descobri que o mestre é
mongo-old-mongodb-replicaset-0
. No entanto, para uma solução mais conveniente para esse problema, após a instalação do Helm-chart, um comando é exibido sobre como determinar o
MASTER_POD
. No meu caso (para o
mongo-old
de 3 nós), fica assim:
for ((i = 0; i < 3; ++i)); do kubectl exec --namespace mongo-old mongo-old-mongodb-replicaset-$i -- sh -c 'mongo --eval="printjson(rs.isMaster())"'; done
Nisso, a preparação da antiga instalação do MongoDB, cujos dados serão transferidos, está pronta.
Migração de cluster do MongoDB
Agora vamos implantar a nova instalação do MongoDB, que será localizada no Kubernetes e usada pelo aplicativo em produção.
Nota : Observe que a mesma versão do MongoDB deve ser usada como antes. Caso contrário, há um risco de problemas de compatibilidade.Por analogia com a seção anterior (onde imitamos a instalação “antiga” do MongoDB), pegamos o Helm-chart já mencionado (usando o
helm fetch
) e configuramos a autorização, bem como outros parâmetros, se usados. Além disso, corrigiremos o arquivo
init/on-start.sh
adicionando temporariamente na linha 165 o endereço do assistente obtido na etapa anterior (ou conhecido por você instalando o MongoDB em servidores separados):
peers='mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017'
Estamos prontos para criar uma nova instalação do MongoDB:
helm install . --name mongo-new --namespace mongo-new
Esperamos até o início de todos os pods (se houver muitos dados, o lançamento poderá levar horas):

Agora criamos
exec
em um novo pod e examinamos a lista de bases:
kubectl --namespace=mongo-new exec -ti mongo-new-mongodb-replicaset-0 mongo

Dois clusters do MongoDB são combinados em um, consistindo em 6 nós.
No momento, você já pode mudar o aplicativo para um novo cluster, mas existem algumas etapas para concluir a migração.
init/on-start.sh
na nova instalação, removemos a linha que adicionamos:
peers='mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017'
Agora vamos entrar no antigo mestre do cluster e "derrubá-lo" - um novo mestre será designado no cluster. Entramos no pod com o mestre do MongoDB:
kubectl --namespace=mongo-old exec -ti mongo-old-mongodb-replicaset-0 mongo use admin db.auth('mongo','password')
Depois disso, alteramos as prioridades dos nós e o assistente:
cfg = rs.conf() cfg.members[5].priority = 2 rs.reconfig(cfg) rs.stepDown(120)
O nó atual deixou de ser um mestre - uma nova eleição ocorrerá. Conforme mudamos as prioridades, o nó que precisamos se tornará o mestre.
NB : Por padrão, todos os nós do MongoDB têm uma prioridade igual a 1. Acima, aumentamos para 2 a prioridade do nó de que precisamos. Assim, um membro de um novo cluster se tornará definitivamente um mestre comum. Você pode ler mais sobre como esses mecanismos funcionam no MongoDB na documentação .Desative a instalação antiga do MongoDB, vá para o novo assistente e exclua os nós antigos:
rs.remove("mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017") rs.remove("mongo-old-mongodb-replicaset-1.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017") rs.remove("mongo-old-mongodb-replicaset-2.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017")
Depois disso, a migração pode ser considerada concluída: alternamos com êxito do cluster antigo do MongoDB para o novo!
Sumário
O esquema descrito é adequado para quase todos os casos em que você precisa transferir o MongoDB ou apenas mover para um novo cluster.
Talvez a principal nuance durante a transferência seja a necessidade de encaminhar os endereços IP de novos pods para os servidores da instalação antiga do MongoDB, se estiver fora dos K8s, e nomeá-los corretamente no DNS (ou
/etc/hosts
). No exemplo, essas etapas não eram necessárias, pois a migração ocorreu entre diferentes espaços para nome do mesmo cluster Kubernetes.
PS
Leia também em nosso blog: