#Espelhamento

0 Seguidores · 5 Postagens

Espelhamento é uma tecnologia da InterSystems para soluções de Alta Disponibilidade, Recuperação de Desastres, Backup de Banco de Dados e OLAP .

Documentação.

Artigo Danusa Calixto · Mar. 12, 2024 22m read

Olá, esta postagem foi escrita inicialmente para Caché. Em junho de 2023, finalmente a atualizei para IRIS. Se você está revisitando a postagem agora, a única mudança real foi a substituição do Caché pelo IRIS! Também atualizei os links para a documentação do IRIS e corrigi alguns erros de digitação e gramaticais. Aproveite :)


Nesta postagem, mostro estratégias para fazer backup do InterSystems IRIS usando o Backup Externo, incluindo exemplos da integração com soluções baseadas em cópias instantâneas. A maioria das soluções que vejo hoje são implantadas no Linux no VMware. Portanto, grande parte da postagem mostra as formas como as soluções integram a tecnologia de cópia instantânea VMware como exemplos.

Backup do IRIS - acompanha pilhas?

O backup online do IRIS está incluído na instalação do IRIS para backup contínuo dos bancos de dados do IRIS. Porém, há soluções de backup mais eficientes que você deve considerar ao ampliar os sistemas. O Backup Externo integrado com tecnologias de cópia instantânea é a solução recomendada para backup de sistemas, incluindo bancos de dados do IRIS.

Há alguma consideração especial para backup externo?

A documentação online do Backup Externo tem todos os detalhes. Uma consideração importante é:

"Para garantir a integridade cópia instantânea, o IRIS oferece métodos para congelar gravações em bancos de dados enquanto a cópia é criada. Somente as gravações físicas nos arquivos dos bancos de dados são congeladas durante a criação da cópia instantânea, permitindo que os processos do usuário continuem realizando atualizações na memória sem interrupções."

Também é importante observar que parte do processo de cópia em sistemas virtualizados causa uma pequena pausa no backup de uma VM, geralmente chamada de "tempo de stun". Ela costuma durar menos de um segundo, então não é percebida pelos usuários nem afeta a operação do sistema. Porém, em algumas circunstâncias, o stun pode durar mais tempo. Se o stun durar mais que o tempo limite de qualidade de serviço (QoS) para o espelhamento do banco de dados do IRIS, o nó de backup pensará que houve uma falha no primário e fará a tolerância a falhas. Mais adiante nesta postagem, explico como você pode revisar os tempos de stun caso precise alterar o tempo limite de QoS do espelhamento.


[Veja aqui uma lista de outras Plataformas de Dados da InterSystems e postagens da série de desempenho.](https://community.intersystems.com/post/capacity-planning-and-performance-series-index)

Leia também a Guia de Backup e Restauração da documentação online do IRIS para esta postagem.


Opções de backup

Solução de backup mínima - Backup Online do IRIS

Se você não tiver mais nada, ela vem incluída na plataforma de dados da InterSystems para backups de tempo de inatividade zero. Lembre-se: o backup online do IRIS só faz backup de arquivos dos bancos de dados do IRIS, capturando todos os blocos nos bancos de dados alocados para dados com a saída gravada em um arquivo sequencial. O Backup Online do IRIS é compatível com backups cumulativos e incrementais.

No contexto do VMware, o Backup Online do IRIS é uma solução de backup a nível de convidado. Como outras soluções de convidado, as operações do Backup Online do IRIS são praticamente as mesmas, quer o aplicativo seja virtualizado ou executado diretamente em um host. O Backup Online do IRIS precisa ser coordenado com um backup do sistema para copiar o arquivo de saída do backup online do IRIS para a mídia de backup e todos os outros sistemas de arquivos usados pelo seu aplicativo. No mínimo, o backup do sistema precisa incluir o diretório de instalação, o diário e os diretórios alternativos do diário, os arquivos do aplicativo e qualquer diretório com os arquivos externos usados pelo aplicativo.

O Backup Online do IRIS deve ser considerado como uma abordagem inicial para sites menores que querem implementar uma solução de baixo custo para fazer backup apenas de bancos de dados do IRIS ou backups ad hoc. Por exemplo, é útil na configuração do espelhamento. No entanto, como os bancos de dados crescem e o IRIS só costuma ser uma parte do cenário de dados do cliente, é uma prática recomendada combinar os Backups Externos com a tecnologia de cópia instantânea e utilitários de terceiros, o que possui vantagens como inclusão do backup de arquivos que não são dos bancos de dados, restaurações mais rápidas, visão de dados de toda a empresa e melhores ferramentas de gestão e catálogo.


Solução de backup recomendada - Backup Externo

Usando o VMware como exemplo, a virtualização no VMware adiciona funcionalidades e opções para proteger VMs inteiras. Depois de virtualizar uma solução, você encapsulará efetivamente seu sistema — incluindo o sistema operacional, o aplicativo e os dados —, tudo dentro de arquivos .vmdk (e alguns outros). Quando necessários, esses arquivos podem ser simples de gerenciar e usados para recuperar um sistema inteiro, o que difere muita da mesma situação em um sistema físico, onde você precisa recuperar e configurar os componentes separadamente – sistema operacional, drivers, aplicativos de terceiros, banco de dados, arquivos de bancos de dados etc.


# Cópia instantanea da VMware

A vSphere Data Protection (VDP) do VMware e outras soluções de backup de terceiros para o backup da VM, como Veeam ou Commvault, usam a funcionalidade de cópias instantâneas das máquinas virtuais do VMware para criar backups. Segue uma explicação de nível superior das cópias instantâneas do VMware. Veja a documentação do VMware para mais detalhes.

É importante lembrar que as cópias instantâneas são aplicados à VM inteira, e o sistema operacional e qualquer aplicativo ou mecanismo de banco de dados não sabem que a cópia está acontecendo. Além disso, lembre-se:

Sozinhas, as cópias instantâneas da VMware não são backups!

As cópias instantâneas permitem que o software de backup faça backups, mas eles não são backups por si sós.

O VDP e as soluções de backup de terceiros usam o processo de cópia do VMware em conjunto com o aplicativo de backup para gerenciar a criação e, mais importantemente, a exclusão da cópia instantânea. Em um nível superior, o processo e a sequência de eventos para um backup externo usando cópias instantâneas do VMware são os seguintes:

  • O software de backup de terceiros solicita que o host ESXi acione uma cópia instantânea do VMware.
  • Os arquivos .vmdk de uma VM são colocados em um estado somente leitura, e um arquivo delta .vmdk filho é criado para cada um dos arquivos .vmdk da VM.
  • A cópia na gravação é usada com todas as mudanças na VM gravadas nos arquivos delta. Quaisquer leituras são primeiro do arquivo delta.
  • O software de backup gerencia a cópia dos arquivos .vmdk pai somente leitura para o destino do backup.
  • Quando o backup é concluído, é feito o commit da cópia (os discos da VM retomam as gravações e atualizam os blocos nos arquivos delta gravados no pai).
  • A cópia instantânea do VMware é excluído agora.

As soluções de backup também usam outros recursos, como Changed Block Tracking (CBT), permitindo backups incrementais ou cumulativos para velocidade e eficiência (especialmente importante para a economia de espaço), e geralmente adicionam outras funções importantes, como deduplicação e compactação de dados, agendamento, montagem de VMs com endereços IP alterados para verificações de integridade etc., restaurações completas no nível da VM e do arquivo e gestão de catálogo.

As cópias instantâneas da VMware que não forem gerenciados adequadamente ou forem deixados em execução por um longo período podem usar armazenamento excessivo (quanto mais dados forem alterados, mais os arquivos delta continuarão a crescer) e deixar as VMs mais lentas.

Considere com cuidado antes de executar uma cópia instantânea manual em uma instância de produção. Por que você está fazendo isso? O que acontecerá se você reverter para quando a cópia instantânea foi criada? O que acontecerá com todas as transações do aplicativo entre a criação e a reversão?

Não tem problema se o seu software de backup criar e excluir uma cópia instantânea. A cópia instantânea deve existir apenas por um breve período. Uma parte fundamental da sua estratégia de backup será escolher um momento de baixo uso do sistema para minimizar qualquer impacto adicional nos usuários e no desempenho.

Considerações do banco de dados do IRIS para cópias instantâneas

Antes de obter a cópia instantânea, é preciso colocar o banco de dados no modo desativado. Assim, é realizado o commit de todas as gravações pendentes e o banco de dados fica em um estado consistente. O IRIS oferece métodos e uma API para fazer o commit e congelar (interromper) gravações no banco de dados por um breve período enquanto a cópia instantânea é criada. Assim, somente as gravações físicas nos arquivos do banco de dados são congeladas durante a criação da cópia instantânea, permitindo que os processos do usuário continuem realizando atualizações na memória sem interrupções. Depois que a cópia instantânea é acionada, as gravações no banco de dados são descongeladas e o backup continua copiando os dados para a mídia de backup. O tempo entre o congelamento e o descongelamento deve ser rápido (alguns segundos).

Além de pausar as gravações, o congelamento do IRIS também processa a troca de arquivos de diário e a gravação de um marcador de backup no diário. O arquivo de diário continua a ser gravado normalmente enquanto as gravações no banco de dados físico estão congeladas. Se o sistema falhar enquanto as gravações no banco de dados físico estiverem congeladas, os dados serão recuperados do diário normalmente durante a inicialização.

O diagrama a seguir mostra as etapas de congelamento e descongelamento com cópias instantâneas da VMware para criar um backup com uma imagem de banco de dados consistente.


Linha do tempo da cópia instantânea da VMware + congelamento/descongelamento do IRIS (não escalar)

image


Observe o breve período entre o congelamento e o descongelamento: apenas o suficiente para criar a cópia instantânea, e não copiar o pai somente leitura para o destino do backup​.


Resumo - Por que preciso congelar e descongelar o banco de dados do IRIS quando o VMware está criando uma cópia instantânea?

O processo de congelar e descongelar o banco de dados é fundamental para garantir a consistência e integridade dos dados. Isso ocorre porque:

Consistência dos dados: o IRIS pode escrever diários ou o WIJ ou fazer gravações aleatórias no banco de dados a qualquer momento. Uma cópia instantânea captura o estado da VM em um momento específico. Se o banco de dados estiver sendo ativamente gravado durante a cópia instantânea, isso poderá causar uma cópia com dados parciais ou inconsistentes. Congelar o banco de dados garante que todas as transações sejam concluídas e nenhuma transação nova seja iniciada durante a cópia, levando a um estado de disco consistente.

Desativação do sistema de arquivos: A tecnologia de cópia instantânea da VMware pode desativar o sistema de arquivos para garantir a consistência dele. No entanto, isso não abrange a consistência no nível do aplicativo ou do banco de dados. O congelamento do banco de dados garante que ele esteja em um estado consistente no nível do aplicativo, complementando o quiesce do VMware.

Redução do tempo de recuperação: a restauração de cópia instantânea obtida sem congelar o banco de dados pode exigir etapas adicionais, como o reparo do banco de dados ou verificações de consistência, o que pode aumentar significativamente o tempo de recuperação. O congelamento e descongelamento garantem que o banco de dados possa ser usado imediatamente após a restauração, diminuindo o tempo de inatividade.


Integração do congelamento e descongelamento do IRIS

O vSphere permite que um script seja chamado automaticamente em ambos os lados da criação da cópia instantânea. É quando são chamados o congelamento e descongelamento do IRIS. Observação: para essa funcionalidade funcionar corretamente, o host ESXi solicita que o sistema operacional convidado desative os discos pelas Ferramentas do VMware.

As ferramentas do VMware precisam ser instaladas no sistema operacional convidado.

Os scripts precisam obedecer regras rígidas de nome e localização. As permissões de arquivo também precisam ser definidas. Para o VMware no Linux, os nomes dos scripts são:

# /usr/sbin/pre-freeze-script
# /usr/sbin/post-thaw-script

Confira abaixo exemplos de scripts de congelamento e descongelamento que nossa equipe usa com o backup do Veeam para instâncias internas de laboratório de testes, mas eles também devem funcionar com outras soluções. Esses exemplos foram testados e usados no vSphere 6 e Red Hat 7.

Embora esses scripts possam ser usados como exemplos e ilustrem o método, você precisa validá-los para seus ambientes!

Exemplo de script pré-congelamento:

#!/bin/sh
#
# Script called by VMWare immediately prior to snapshot for backup.
# Tested on Red Hat 7.2
#

LOGDIR=/var/log
SNAPLOG=$LOGDIR/snapshot.log

echo >> $SNAPLOG
echo "`date`: Pre freeze script started" >> $SNAPLOG
exit_code=0

# Only for running instances
for INST in `iris qall 2>/dev/null | tail -n +3 | grep '^up' | cut -c5-  | awk '{print $1}'`; do

    echo "`date`: Attempting to freeze $INST" >> $SNAPLOG
    
    # Detailed instances specific log    
    LOGFILE=$LOGDIR/$INST-pre_post.log
    
    # Freeze
    irissession $INST -U '%SYS' "##Class(Backup.General).ExternalFreeze(\"$LOGFILE\",,,,,,1800)" >> $SNAPLOG $
    status=$?

    case $status in
        5) echo "`date`:   $INST IS FROZEN" >> $SNAPLOG
           ;;
        3) echo "`date`:   $INST FREEZE FAILED" >> $SNAPLOG
           logger -p user.err "freeze of $INST failed"
           exit_code=1
           ;;
        *) echo "`date`:   ERROR: Unknown status code: $status" >> $SNAPLOG
           logger -p user.err "ERROR when freezing $INST"
           exit_code=1
           ;;
    esac
    echo "`date`:   Completed freeze of $INST" >> $SNAPLOG
done

echo "`date`: Pre freeze script finished" >> $SNAPLOG
exit $exit_code

Exemplo de script de descongelamento:

#!/bin/sh
#
# Script called by VMWare immediately after backup snapshot has been created
# Tested on Red Hat 7.2
#

LOGDIR=/var/log
SNAPLOG=$LOGDIR/snapshot.log

echo >> $SNAPLOG
echo "`date`: Post thaw script started" >> $SNAPLOG
exit_code=0

if [ -d "$LOGDIR" ]; then

    # Only for running instances    
    for INST in `iris qall 2>/dev/null | tail -n +3 | grep '^up' | cut -c5-  | awk '{print $1}'`; do
    
        echo "`date`: Attempting to thaw $INST" >> $SNAPLOG
        
        # Detailed instances specific log
        LOGFILE=$LOGDIR/$INST-pre_post.log
        
        # Thaw
        irissession $INST -U%SYS "##Class(Backup.General).ExternalThaw(\"$LOGFILE\")" >> $SNAPLOG 2>&1
        status=$?
        
        case $status in
            5) echo "`date`:   $INST IS THAWED" >> $SNAPLOG
               irissession $INST -U%SYS "##Class(Backup.General).ExternalSetHistory(\"$LOGFILE\")" >> $SNAPLOG$
               ;;
            3) echo "`date`:   $INST THAW FAILED" >> $SNAPLOG
               logger -p user.err "thaw of $INST failed"
               exit_code=1
               ;;
            *) echo "`date`:   ERROR: Unknown status code: $status" >> $SNAPLOG
               logger -p user.err "ERROR when thawing $INST"
               exit_code=1
               ;;
        esac
        echo "`date`:   Completed thaw of $INST" >> $SNAPLOG
    done
fi

echo "`date`: Post thaw script finished" >> $SNAPLOG
exit $exit_code

Lembre-se de definir as permissões:

# sudo chown root.root /usr/sbin/pre-freeze-script /usr/sbin/post-thaw-script
# sudo chmod 0700 /usr/sbin/pre-freeze-script /usr/sbin/post-thaw-script

Teste de congelamento e descongelamento

Para testar se os scripts estão funcionando corretamente, você pode executar uma cópia instantânea manualmente em uma VM e verificar a saída do script. A captura de tela a seguir mostra a caixa de diálogo "Take VM Snapshot" (Tirar a cópia instantânea da VM) e as opções.

Desmarque- "Snapshot the virtual machine's memory" (Tirar a cópia instantânea da memória da máquina virtual).

Selecione - a caixa de seleção "Quiesce guest file system (Needs VMware Tools installed)", ou "Colocar o sistema de arquivos convidado em modo quiesced (as ferramentas do VMware precisam estar instaladas)", para pausar os processos em execução no sistema operacional convidado, deixando o conteúdo do sistema de arquivos em um estado consistente conhecido ao tirar a cópia instantânea.

Importante! Depois do teste, lembre-se de excluir a cópia instantânea!!!!

Se a sinalização quiesce for verdadeira e a máquina virtual estiver ligada ao tirar a cópia instantânea, as ferramentas do VMware serão usadas para o quiesce do sistema de arquivos na máquina virtual. O quiesce do sistema de arquivos é o processo de colocar os dados no disco em um estado adequado para backups. Esse processo pode incluir operações como a limpeza de buffers sujos no cache da memória do sistema operacional para o disco.

A saída a seguir mostra o conteúdo do arquivo de log $SNAPSHOT definido nos scripts de congelamento/descongelamento acima após executar um backup que inclui uma cópia instantânea como parte da sua operação.

Wed Jan  4 16:30:35 EST 2017: Pre freeze script started
Wed Jan  4 16:30:35 EST 2017: Attempting to freeze H20152
Wed Jan  4 16:30:36 EST 2017:   H20152 IS FROZEN
Wed Jan  4 16:30:36 EST 2017:   Completed freeze of H20152
Wed Jan  4 16:30:36 EST 2017: Pre freeze script finished

Wed Jan  4 16:30:41 EST 2017: Post thaw script started
Wed Jan  4 16:30:41 EST 2017: Attempting to thaw H20152
Wed Jan  4 16:30:42 EST 2017:   H20152 IS THAWED
Wed Jan  4 16:30:42 EST 2017:   Completed thaw of H20152
Wed Jan  4 16:30:42 EST 2017: Post thaw script finished

Esse exemplo mostra os 6 segundos decorridos entre o congelamento e o descongelamento (16:30:36-16:30:42). As operações dos usuários NÃO são interrompidas durante esse período. Você precisará coletar métricas dos seus próprios sistemas, mas, para um pouco de contexto, esse exemplo é de um sistema que está executando um benchmark de aplicativo em uma VM sem gargalos de IO e com uma média de mais de 2 milhões de glorefs/s, 170.000 de gloupds/s, 1.100 gravações físicas/s e 3.000 gravações por ciclo de daemon de gravação.

Lembre-se de que a memória não faz parte da cópia instantânea, portanto, ao reiniciar, a VM será reinicializada e recuperada. Os arquivos de banco de dados serão consistentes. Você não quer "retomar" um backup, e sim quer os arquivos em um momento conhecido. Então, você pode fazer o roll forward dos diários e quaisquer outras etapas de recuperação necessárias para o aplicativo e a consistência transacional assim que os arquivos forem recuperados.

Para proteção de dados adicional, a troca do diário pode ser feita por si só, e os diários podem ser armazenados em backup ou replicados em outro local, por exemplo, a cada hora.

Confira abaixo a saída de $LOGFILE nos scripts de congelamento/descongelamento acima, mostrando os detalhes do diário para a cópia instantânea.

01/04/2017 16:30:35: Backup.General.ExternalFreeze: Suspending system

Journal file switched to:
/trak/jnl/jrnpri/h20152/H20152_20170104.011
01/04/2017 16:30:35: Backup.General.ExternalFreeze: Start a journal restore for this backup with journal file: /trak/jnl/jrnpri/h20152/H20152_20170104.011

Journal marker set at
offset 197192 of /trak/jnl/jrnpri/h20152/H20152_20170104.011
01/04/2017 16:30:36: Backup.General.ExternalFreeze: System suspended
01/04/2017 16:30:41: Backup.General.ExternalThaw: Resuming system
01/04/2017 16:30:42: Backup.General.ExternalThaw: System resumed

Tempos de stun da VM

No ponto de criação de uma cópia instantânea da VM e após a conclusão do backup e o commit do snapshot, a VM precisa ser congelada por um breve período. Esse pequeno congelamento costuma ser chamado de "stun" da VM. Veja uma ótima postagem de blog sobre os tempos de stun aqui. Resumo os detalhes abaixo e os contextualizo para as considerações do banco de dados do IRIS.

Da postagem sobre os tempos de stun: "Para criar uma cópia instantânea da VM, é feito o 'stun' da VM para (i) serializar o estado do dispositivo no disco e (ii) encerrar o disco que está em execução e criar um ponto da cópia instantânea… Durante a consolidação, é feito o 'stun' da VM para encerrar os discos e colocá-los em um estado apropriado para a consolidação."

O tempo de stun é normalmente algumas centenas de milésimos. No entanto, se houver uma atividade muito alta de gravação em disco durante a fase de commit, o tempo de stun poderá ser de vários segundos.

Se a VM estiver participando do Espelhamento do Banco de Dados do IRIS como um membro Primário ou de Backup, e o tempo de stun for maior que o tempo limite de Qualidade de Serviço (QoS) do espelho, o espelho relatará a falha da VM Primária e assumirá o controle.

Atualização de março de 2018: Meu colega, Peter Greskoff, indicou que um membro espelho de backup poderia iniciar a tolerância a falhas na metade do tempo limite de QoS durante um stun da VM ou quando um membro espelho primário estiver indisponível.

Para conferir uma descrição detalhada das considerações de QoS e cenários de tolerância a falhas, consulte esta ótima postagem: Guia do Tempo Limite de Qualidade de Serviço para Espelhamento. Resumindo a questão dos tempos de stun da VM e QoS:

Se o espelho de backup não receber nenhuma mensagem do espelho primário dentro da metade do tempo limite de QoS, ele enviará uma mensagem para garantir que o primário ainda está ativo. Em seguida, o backup aguardará uma resposta da máquina primária pela outra metade do tempo de QoS. Se não houver resposta do primário, presume-se que ele está inativo, e o backup assumirá o controle.

Em um sistema ocupado, os diários são enviados continuamente do espelho primário para o espelho de backup, e o backup não precisa verificar se o primário ainda está ativo. No entanto, durante um período tranquilo — quando é mais provável que os backups ocorram —, se o aplicativo estiver ocioso, pode não haver mensagens entre o espelho primário e o de backup por mais da metade do tempo de QoS.

Confira abaixo o exemplo de Peter. Pense neste intervalo para um sistema ocioso com um tempo limite de QoS de 8 segundos e um tempo de stun da VM de 7 segundos:

  • :00 O primário dá um ping no árbitro com um keepalive, e o árbitro responde imediatamente
  • :01 O membro de backup envia o keepalive ao primário, e o primário responde imediatamente
  • :02
  • :03 Começa o stun da VM
  • :04 O primário tenta enviar o keepalive ao árbitro, mas não consegue até a conclusão do stun
  • :05 O membro de backup envia um ping ao primário, já que expirou metade da QoS
  • :06
  • :07
  • :08 O árbitro não recebe resposta do primário durante todo o tempo limite de QoS, então encerra a conexão
  • :09 O backup não recebeu uma resposta do primário e confirma com o árbitro que ele também perdeu a conexão, então assume o controle
  • :10 O stun da VM acaba, tarde mais!!

Leia também a seção Pitfalls and Concerns when Configuring your Quality of Service Timeout (Armadilhas e Preocupações ao Configurar o Tempo Limite de Qualidade de Serviço) na postagem do link acima para entender o equilíbrio de ter a QoS somente pelo tempo necessário. Ter a QoS por muito tempo, especialmente por mais de 30 segundos, também pode causar problemas.

Final da atualização de março de 2018:

Para obter mais informações sobre a QoS do Espelhamento, consulte também a documentação.

As estratégias para reduzir ao mínimo o tempo de stun incluem executar backups quando houver pouca atividade no banco de dados e configurar bem o armazenamento.

Como observado acima, ao criar uma cópia instantânea, há várias opções que você pode especificar. Uma delas é incluir o estado da memória na cópia - Lembre-se, o estado da memória NÃO é necessário para backups de bancos de dados do IRIS. Se estiver configurada a sinalização da memória, um dump do estado interno da máquina virtual será incluído na cópia. A criação de cópias instantâneas da memória demora muito mais. As cópias da memória são usados para reverter o estado de uma máquina virtual em execução para como estava quando a cópia foi obtida. Isso NÃO é necessário para o backup de arquivos de um banco de dados.

Ao tirar uma cópia instantânea da memória, será realizado o stun de todo o estado da máquina virtual. O tempo de stun varia.

Como observado anteriormente, para backups, a sinalização do quiesce precisa ser definida como verdadeira para cópias manuais ou pelo software de backup para garantir um backup consistente e utilizável.

Revisar tempos de stun em logs do VMware

A partir do ESXi 5.0, os tempos de stun das cópias são registrados no arquivo de log de cada máquina virtual (vmware.log) com mensagens semelhantes a:

2017-01-04T22:15:58.846Z| vcpu-0| I125: Checkpoint_Unstun: vm stopped for 38123 us

Os tempos de stun estão em microssegundos. Então, no exemplo acima, 38123 us é 38123/1.000.000 segundos ou 0,038 segundos.

Para garantir que os tempos de stun estão dentro dos limites aceitáveis ou para solucionar problemas se você suspeitar que eles estão longos e causando problemas, baixe e revise os arquivos vmware.log da pasta da VM em que tem interesse. Depois de baixar, você pode extrair e ordenar o log usando os comandos Linux de exemplo abaixo.

Exemplo de download dos arquivos vmware.log

Há várias formas de baixar os logs de suporte, incluindo criando um pacote de suporte do VMware através do console de gerenciamento do vSphere ou da linha de comando do host ESXi. Consulte a documentação do VMware para ver todos os detalhes, mas abaixo está um método simples para criar e reunir um pacote de suporte bem menor que inclui o arquivo vmware.log para você revisar os tempos de stun.

Você precisará do nome longo do diretório onde os arquivos da VM estão localizados. Faça login no host ESXi onde a VM do banco de dados está em execução usando ssh e use o comando: vim-cmd vmsvc/getallvms  para listar os arquivos vmx e os nomes longos exclusivos associados a eles.

Por exemplo, o nome longo da VM do banco de dados de exemplo usada nesta postagem fica assim: 26 vsan-tc2016-db1 [vsanDatastore] e2fe4e58-dbd1-5e79-e3e2-246e9613a6f0/vsan-tc2016-db1.vmx rhel7_64Guest vmx-11

Em seguida, execute o comando para reunir e empacotar apenas os arquivos de log:
vm-support -a VirtualMachines:logs.

O comando dará a localização do pacote de suporte, por exemplo: To see the files collected, check '/vmfs/volumes/datastore1 (3)/esx-esxvsan4.iscinternal.com-2016-12-30--07.19-9235879.tgz'.

Agora você pode usar o sftp para transferir o arquivo para fora do host para processamento e análise adicional.

Nesse exemplo, após descompactar o pacote de suporte, acesse o caminho correspondente ao nome longo da VM do banco de dados. Por exemplo, nesse caso: <bundle name>/vmfs/volumes/<host long name>/e2fe4e58-dbd1-5e79-e3e2-246e9613a6f0.

Você verá vários arquivos de log numerados. O arquivo de log mais recente não tem número, ou seja, vmware.log. O log pode ter só algumas centenas de KB, mas há muitas informações. Porém, queremos os tempos de stun/unstun, que são fáceis de encontrar com grep. Por exemplo:

$ grep Unstun vmware.log
2017-01-04T21:30:19.662Z| vcpu-0| I125: Checkpoint_Unstun: vm stopped for 1091706 us
--- 
2017-01-04T22:15:58.846Z| vcpu-0| I125: Checkpoint_Unstun: vm stopped for 38123 us
2017-01-04T22:15:59.573Z| vcpu-0| I125: Checkpoint_Unstun: vm stopped for 298346 us
2017-01-04T22:16:03.672Z| vcpu-0| I125: Checkpoint_Unstun: vm stopped for 301099 us
2017-01-04T22:16:06.471Z| vcpu-0| I125: Checkpoint_Unstun: vm stopped for 341616 us
2017-01-04T22:16:24.813Z| vcpu-0| I125: Checkpoint_Unstun: vm stopped for 264392 us
2017-01-04T22:16:30.921Z| vcpu-0| I125: Checkpoint_Unstun: vm stopped for 221633 us

Podemos ver dois grupos de tempos de stun no exemplo, um desde a criação da cópia instantânea e outro definido 45 minutos depois para cada disco quando a cópia foi excluído/consolidado (por exemplo, depois que o software de backup fez a cópia do arquivo vmx somente leitura). O exemplo acima mostra que a maioria dos tempos de stun é menor do que um segundo, mesmo que o tempo de stun inicial seja um pouco mais de um segundo.

Tempos de stun curtos não são perceptíveis para o usuário final. No entanto, os processos do sistema, como o Espelhamento do Banco de Dados do IRIS, verificam continuamente se uma instância está "ativa". Se o tempo de stun exceder o tempo limite de QoS do espelhamento, o nó poderá ser considerado fora de contato e "morto", e a tolerância a falhas será acionada.

Dica: para revisar todos os logs ou solucionar problemas, um comando útil é fazer o grep de todos os arquivos vmware*.log e procurar qualquer discrepância ou instância em que o tempo de stun chega próximo ao tempo limite de QoS. O seguinte comando canaliza a saída para awk para formatação:

grep Unstun vmware* | awk '{ printf ("%'"'"'d", $8)} {print " ---" $0}' | sort -nr


Resumo

Monitore seu sistema regularmente durante as operações normais para entender os tempos de stun e como eles podem afetar o tempo limite de QoS para HA, como o espelhamento. Como observado, as estratégias para reduzir ao mínimo o tempo de stun/unstun incluem executar backups quando houver pouca atividade no banco de dados e no armazenamento e configurar bem o armazenamento. Para monitoramento constante, os logs podem ser processados usando o VMware Log Insight ou outras ferramentas.

Em postagens futuras, revisitarei as operações de backup e restauração para as Plataformas de Dados da InterSystems. Por enquanto, caso você tenha algum comentário ou sugestão com base nos fluxos de trabalho dos seus sistemas, compartilhe nas seções de comentários abaixo.

0
0 89
Artigo Danusa Calixto · Fev. 8, 2024 8m read

Se você estiver executando o IRIS em uma configuração espelhada para alta disponibilidade (HA) no Azure, a questão de fornecer um [VIP espelho] (https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GHA_mirror_set_config#GHA_mirror_set_virtualip) (IP virtual) se torna relevante. O IP virtual oferece uma maneira de sistemas downstream interagirem com o IRIS usando um endereço IP. Mesmo quando ocorre uma tolerância a falhas, os sistemas downstream podem se reconectar ao mesmo endereço IP e continuar trabalhando.

O principal problema, ao implantar no Azure, é que um VIP IRIS requer que o IRIS seja basicamente um administrador de rede, de acordo com a documentação.

Para obter HA, os membros espelho IRIS precisam ser implantados em diferentes zonas de disponibilidade de uma sub-rede (o que é possível no Azure, já que as sub-redes podem abranger várias zonas). Uma das soluções pode ser os balanceadores de carga, mas eles têm um custo extra e você precisa administrá-los.

Neste artigo, quero fornecer uma maneira de configurar um VIP espelho sem usar os balanceadores de carga sugeridos na maioria das outras arquiteturas de referência do Azure.

Arquitetura

Architecture

Temos uma sub-rede em execução em duas zonas de disponibilidade (simplifiquei aqui: claro, você provavelmente terá sub-redes públicas, árbitro em outra az, e assim por diante, mas esse é o mínimo absoluto necessário para demonstrar essa abordagem). O CIDR da sub-rede é "10.0.0.0/24", ou seja, alocou os IPs "10.0.0.1" a "10.0.0.255". Como o Azure reserva os primeiros quatro endereços e o último, podemos usar "10.0.0.4" a "10.0.0.254".

Vamos implementar VIPs públicos e privados ao mesmo tempo. Se quiser, você pode implementar apenas o VIP privado.

Ideia

As máquinas virtuais (VM) no Azure têm interfaces de rede. Essas interfaces de rede têm configurações de IP. A configuração de IP é uma combinação de IPs públicos e/ou privados e é roteada automaticamente para a máquina virtual associada à interface de rede. Portanto, não é preciso atualizar as rotas. Faremos o seguinte: durante um evento de tolerância a falhas de espelho, vamos excluir a configuração de IP VIP da primária antiga e criar uma nova primária. Todas as operações envolvidas nisso levam de 5 a 20 segundos apenas para o VIP privado, de 5 segundos a um minuto para uma combinação de IP VIP público/privado.

Como implementar o VIP

  1. Aloque o IP externo para usar como VIP público. Pule essa etapa se você quiser apenas o VIP privado. Se você alocar o VIP, ele precisa residir no mesmo grupo de recursos e na mesma região e estar em todas as zonas com primária e backup. Você precisará de um nome de IP externo.
  2. Decida o valor do VIP privado. Usarei o último IP disponível: "10.0.0.254".
  3. Em cada VM, aloque o endereço IP VIP em cada interface de rede "eth0:1".
cat << EOFVIP >> /etc/sysconfig/network-scripts/ifcfg-eth0:1
          DEVICE=eth0:1
          ONPARENT=on
          IPADDR=10.0.0.254
          PREFIX=32
          EOFVIP
sudo chmod -x /etc/sysconfig/network-scripts/ifcfg-eth0:1
sudo ifconfig eth0:1 up

Se você só quiser testar, execute (mas ele não sobreviverá à reinicialização do sistema):

sudo ifconfig eth0:1 10.0.0.254

Dependendo do SO, talvez seja preciso executar o seguinte:

ifconfig eth0:1
systemctl restart network
  1. Para cada VM, ative a identidade atribuída pelo sistema ou usuário.
  2. Para cada identidade, atribua as permissões para modificar as interfaces de rede. Para isso, crie uma função personalizada, a permissão mínima definida nesse caso seria:
{
  "roleName": "custom_nic_write",
  "description": "IRIS Role to assign VIP",
  "assignableScopes": [
    "/subscriptions/{subscriptionid}/resourceGroups/{resourcegroupid}/providers/Microsoft.Network/networkInterfaces/{nicid_primary}",
    "/subscriptions/{subscriptionid}/resourceGroups/{resourcegroupid}/providers/Microsoft.Network/networkInterfaces/{nicid_backup}"
  ],
  "permissions": [
    {
      "actions": [
        "Microsoft.Network/networkInterfaces/write",
        "Microsoft.Network/networkInterfaces/read"
      ],
      "notActions": [],
      "dataActions": [],
      "notDataActions": []
    }
  ]
}

Para ambientes que não sejam de produção, você pode usar uma função de sistema contribuidor de rede no grupo de recursos, mas essa abordagem não é recomendada, já que contribuidor de rede é uma função muito ampla.

  1. Cada interface de rede no Azure pode ter um conjunto de configurações de IP. Quando um membro espelho atual se torna primário, vamos usar um retorno de chamadas ZMIRROR para excluir uma configuração de IP VIP na interface de rede de outro membro espelho e criar uma configuração de IP VIP que aponte para ela mesma:

Aqui estão os comandos de CLI do Azure para ambos os nós, considerando o grupo de recursos "rg", a configuração de IP "vip" e o IP externo "my_vip_ip":

az login --identity
az network nic ip-config delete --resource-group rg --name vip --nic-name mirrorb280_z2
az network nic ip-config create --resource-group rg --name vip --nic-name mirrora290_z1 --private-ip-address 10.0.0.254 --public-ip-address my_vip_ip

e:

az login --identity
az network nic ip-config delete --resource-group rg --name vip --nic-name mirrora290_z1
az network nic ip-config create --resource-group rg --name vip --nic-name mirrorb280_z2 --private-ip-address 10.0.0.254 --public-ip-address my_vip_ip

E o mesmo código como uma rotina "ZMIRROR":

ROUTINE ZMIRROR

NotifyBecomePrimary() PUBLIC {
    #include %occMessages
    set rg = "rg"
    set config = "vip"
    set privateVIP = "10.0.0.254"
    set publicVIP = "my_vip_ip"

    set nic = "mirrora290_z1"
    set otherNIC = "mirrorb280_z2"
    if ##class(SYS.Mirror).DefaultSystemName() [ "MIRRORB" {
        // estamos no nó mirrorb, troque
        set $lb(nic, otherNIC)=$lb(otherNIC, nic)
    }

    set rc1 = $zf(-100, "/SHELL", "export", "AZURE_CONFIG_DIR=/tmp", "&&", "az", "login", "--identity")
    set rc2 = $zf(-100, "/SHELL", "export", "AZURE_CONFIG_DIR=/tmp", "&&", "az", "network", "nic", "ip-config", "delete", "--resource-group", rg, "--name", config, "--nic-name", otherNIC)
    set rc3 = $zf(-100, "/SHELL", "export", "AZURE_CONFIG_DIR=/tmp", "&&", "az", "network", "nic", "ip-config", "create", "--resource-group", rg, "--name", config, "--nic-name",      nic,  "--private-ip-address", privateVIP, "--public-ip-address", publicVIP)
    quit 1
}

A rotina é a mesma para ambos os membros espelho, só trocamos os nomes NIC com base no nome do membro espelho atual. Você talvez não precise de "export AZURE_CONFIG_DIR=/tmp", mas, às vezes, "az" tenta gravar as credenciais no dir home raiz, o que pode falhar. Em vez de "/tmp", é melhor usar o subdiretório home do usuário IRIS (ou talvez você nem precise dessa variável de ambiente, dependendo da sua configuração).

Se você quiser usar o Embedded Python, aqui está o código do SDK Azure para Python:

from azure.identity import DefaultAzureCredential
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.network.models import NetworkInterface, NetworkInterfaceIPConfiguration, PublicIPAddress

sub_id = "AZURE_SUBSCRIPTION_ID"
client = NetworkManagementClient(credential=DefaultAzureCredential(), subscription_id=sub_id)

resource_group_name = "rg"
nic_name = "mirrora290_z1"
other_nic_name = "mirrorb280_z2"
public_ip_address_name = "my_vip_ip"
private_ip_address = "10.0.0.254"
vip_configuration_name = "vip"


# remova a configuração VIP antiga
nic: NetworkInterface = client.network_interfaces.get(resource_group_name, other_nic_name)
ip_configurations_old_length = len(nic.ip_configurations)
nic.ip_configurations[:] = [ip_configuration for ip_configuration in nic.ip_configurations if
                            ip_configuration.name != vip_configuration_name]

if ip_configurations_old_length != len(nic.ip_configurations):
    poller = client.network_interfaces.begin_create_or_update(
        resource_group_name,
        other_nic_name,
        nic
    )
    nic_info = poller.result()

# adicione a nova configuração VIP
nic: NetworkInterface = client.network_interfaces.get(resource_group_name, nic_name)
ip: PublicIPAddress = client.public_ip_addresses.get(resource_group_name, public_ip_address_name)
vip = NetworkInterfaceIPConfiguration(name=vip_configuration_name,
                                      private_ip_address=private_ip_address,
                                      private_ip_allocation_method="Static",
                                      public_ip_address=ip,
                                      subnet=nic.ip_configurations[0].subnet)
nic.ip_configurations.append(vip)

poller = client.network_interfaces.begin_create_or_update(
    resource_group_name,
    nic_name,
    nic
)
nic_info = poller.result()

Inicialização

"NotifyBecomePrimary" também é chamado automaticamente na inicialização do sistema (após a reconexão do espelho), mas, se você quiser que seus ambientes não espelhados adquiram o VIP da mesma maneira, use a rotina ZSTART:

SYSTEM() PUBLIC {
  if '$SYSTEM.Mirror.IsMember() {
    do NotifyBecomePrimary^ZMIRROR()
  }
  quit 1
}

Conclusão

E é isso! Mudamos a configuração de IP que aponta para um espelho primário atual quando ocorre o evento "NotifyBecomePrimary".

0
0 113
Anúncio Angelo Bruno Braga · Out. 24, 2022

Certifique-se em Administração de Sistema InterSystems IRIS!

Olá Comunidade,

Após o teste beta do novo exame de Certificação de Especialista em Administração de Sistemas InterSystems IRIS, a equipe de certificação dos Serviços de Aprendizagem InterSystems realizou a calibração e os ajustes necessários para liberá-lo para nossa comunidade. Já está pronto para compra e agendamento no catálogo de exames de certificação da InterSystems. Os candidatos em potencial podem analisar os tópicos do exame e as questões práticas para ajudar a orientá-los quanto às abordagens e conteúdo das questões do exame. A aprovação no exame permite que você reivindique um selo de certificação eletrônico que pode ser incorporado a contas de mídia social, como o Linkedin..  

0
0 73
Artigo Danusa Calixto · Jul. 27, 2022 12m read

Histórico

VersãoDataAtualizações
V12022-02-08Início
V1.12022-04-06Geração de certificados com arquivo sh em vez de pki-script
Usando variáveis de ambiente em arquivos de configuração

Olá Comunidade,

Vocês já configuraram um ambiente espelhado? Tem rede privada, IP virtual, e configuração SSL? Após fazer isso algumas vezes, eu me dei conta que isso é longo, e há várias ações manuais obrigatórias para gerar os certificados e configurar cada instancia IRIS. É uma dor no pescoço para quem tem que fazer isso muitas vezes.

Por exemplo, um time de Quality Assurance pode precisar criar um novo ambiente para cada nova versão da aplicação para testar. O time de suporte pode exigir a criação de um ambiente para reproduzir um problema complexo.

Nós definitivamente precisamos de ferramentas para criá-los rapidamente.

Neste artigo iremos criar um exemplo para configurar um Mirror com:

  • Arbitro
  • Primário
  • Membro de backup
  • Membro assíncrono de relatorio (leitura e escrita)
  • Configuração SSL para transferencia de Journal entre os nós
  • Rede privada para o Mirror
  • Endereço IP virtual
  • Um banco de dados espelhado

network-schema

À primeira vista, parece um pouco complexo e parece que precisa de muito código, mas não se preocupe. Existem bibliotecas hospedadas no OpenExchange para realizar facilmente a maioria das operações.

O objetivo deste artigo é fornecer um exemplo de como adaptar o processo às suas necessidades, mas não é um guia de práticas recomendadas em termos de segurança. Então, vamos criar nossa amostra.

Ferramentas e bibliotecas

  • config-api: Esta biblioteca será utilizada para configurar o IRIS. Ela suporta configuração de espelhamento desde a versão 1.1.0. Não iremos dar uma descrição detalhada de como usar esta biblioteca. Já existe uma série de artigos. here. Resumindo, config-api será usada para criar um modelo de arquivos de configuração IRIS (formato JSON) e carregá-los facilmente.
  • ZPM.
  • Docker.
  • OpenSSL.

Github

Você pode encontrar todos os arquivos necessários em iris-mirroring-samples repository.

Prepare o seu sistema

Clone o repositorio existente:

git clone https://github.com/lscalese/iris-mirroring-samples
cd iris-mirroring-samples

Se você preferir criar uma amostra do zero, ao invés de clonar o repositório, basta criar um novo diretório com subdiretórios: backup e config-files. Baixe irissession.sh :

mkdir -p iris-mirroring-samples/backup iris-mirroring-samples/config-files
cd  iris-mirroring-samples
wget -O session.sh https://raw.githubusercontent.com/lscalese/iris-mirroring-samples/master/session.sh

Para evitar o problema de "permissão negada" posteriormente, precisamos criar o grupo 'irisowner', o usuário 'irisowner', e alterar o grupo do diretório de backup para 'irisowner'

sudo useradd --uid 51773 --user-group irisowner
sudo groupmod --gid 51773 irisowner
sudo chgrp irisowner ./backup

Este diretório será utilizado como volume para compartilhar um backup do banco de dados após configurar o primeiro membro espelho com os outros nós.

Obtenha uma licença IRIS

O espelhamento não está disponível com a edição da comunidade IRIS. Se você ainda não tiver uma licença de contêiner IRIS válida, conecte-se ao Worldwide Response Center (WRC) com suas credenciais. Clique em "Ações" --> "Distribuição online", depois no botão "Avaliações" e selecione "Licença de avaliação"; Preencha o formulário. Copie seu arquivo de licença iris.key para este diretório.

Login no Intersystems Containers Registry

Por motivos de conveniência, usamos o Intersystems Containers Registry (ICR) para extrair imagens do docker. Se você não souber seu login\password do docker, basta conectar-se a SSO.UI.User.ApplicationTokens.cls com suas credenciais WRC, e você pode recuperar seu Token ICR.

docker login -u="YourWRCLogin" -p="YourICRToken" containers.intersystems.com

Crie o banco de dados myappdata e o mapeamento de global

Nós não criamos realmente o banco de dados myappdata agora, mas preparamos uma configuração para criá-lo no momento da compilação do docker. Para isso, basta criar um arquivo simples usando o formato JSON; A biblioteca config-api será usada para carregá-la nas instâncias IRIS.

Crie o arquivo config-files/simple-config.json

{
   "Defaults":{
       "DBDATADIR" : "${MGRDIR}myappdata/",
       "DBDATANAME" : "MYAPPDATA"
      
   },
   "SYS.Databases":{
       "${DBDATADIR}" : {}
   },
   "Databases":{
       "${DBDATANAME}" : {
           "Directory" : "${DBDATADIR}"
       }
   },
   "MapGlobals":{
       "USER": [{
           "Name" : "demo.*",
           "Database" : "${DBDATANAME}"
       }]
   },
   "Security.Services" : {
       "%Service_Mirror" : {                      /* Habilita o serviço de espelhamento nesta instancia */
           "Enabled" : true
       }
   }
}

Este arquivo de configuração permite que você crie um novo banco de dados com configurações padrão e faça o mapeamento global demo.* no namespace USER.

Para obter mais informações sobre os recursos do arquivo de configuração config-api, consulte o [artigo](https://community.intersystems.com/post/environment -setup-config-api) ou a página do github

O arquivo Docker

O arquivo docker é baseado no [modelo docker] existente (https://github.com/intersystems-community/objectscript-docker-template), mas precisamos fazer algumas alterações para criar um diretório de trabalho, instalar ferramentas para usar IP, instalar ZPM, etc…

Nossa imagem IRIS é a mesma para cada membro do espelho. O espelhamento será configurado no contêiner começando com a configuração correta dependendo de sua função (primeiro membro, backup ou relatório de leitura/gravação). Veja os comentários sobre o Dockerfile abaixo:

ARG IMAGE=containers.intersystems.com/intersystems/iris:2021.1.0.215.0
# Não precisa baixar a imagem do WRC. Ele será retirado do ICR no momento da construção.

FROM $IMAGE

USER root

COPY session.sh /
COPY iris.key /usr/irissys/mgr/iris.key

# /opt/demo será nosso diretório de trabalho usado para armazenar nossos arquivos de configuração e outros arquivos de instalação.
# Instale o iputils-arping para ter um comando arping. É necessário configurar o IP virtual.
# Baixe a versão mais recente do ZPM (o ZPM está incluído apenas na edição da comunidade).
RUN mkdir /opt/demo && \
    chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/demo && \
    chmod 666 /usr/irissys/mgr/iris.key && \
    apt-get update && apt-get install iputils-arping gettext-base && \
    wget -O /opt/demo/zpm.xml https://pm.community.intersystems.com/packages/zpm/latest/installer

USER ${ISC_PACKAGE_MGRUSER}

WORKDIR /opt/demo

# Defina a função de espelho padrão como mestre.
# Ele será substituído no arquivo docker-compose em tempo de execução (mestre para a primeira instância, backup e relatório)
ARG IRIS_MIRROR_ROLE=master

# Copie o conteúdo do diretório config-files em /opt/demo.
# Atualmente criamos apenas uma configuração simples para configurar nosso banco de dados e mapeamento de global.
# Mais adiante neste artigo adicionaremos outros arquivos de configuração para configurar o espelho.
ADD config-files .

SHELL [ "/session.sh" ]

# Instale o ZPM
# Use ZPM para instalar config-api
# Carregue o arquivo simple-config.json com config-api para:
#  - criar o banco de dados  "myappdata" ,
#  - adicionar o mapeamento de global no namespace "USER" para a global "demo.*" no banco de dados "myappdata" .
# Basicamente, o ponto de entrada para instalar seu aplicativo ObjectScript é aqui.
# Para este exemplo, carregaremos o simple-config.json para criar um banco de dados simples e um mapeamento de global.
RUN \
Do $SYSTEM.OBJ.Load("/opt/demo/zpm.xml", "ck") \
zpm "install config-api" \
Set sc = ##class(Api.Config.Services.Loader).Load("/opt/demo/simple-config.json")

# Copie o script de instalação do espelho 
COPY init_mirror.sh /

Construa a imagem IRIS

O Dockerfile está pronto; podemos construir a imagem:

docker build --no-cache --tag mirror-demo:latest .

Essa imagem será usada para executar nós primários, de backup e de relatório.

O arquivo .env

Os arquivos de configuração JSON e a composição do docker usam variáveis de ambiente. Seus valores são armazenados em um arquivo chamado .env, para este exemplo nosso arquivo env é:

APP_NET_SUBNET=172.16.238.0/24
MIRROR_NET_SUBNET=172.16.220.0/24

IRIS_HOST=172.16.238.100
IRIS_PORT=1972
IRIS_VIRTUAL_IP=172.16.238.100

ARBITER_IP=172.16.238.10

MASTER_APP_NET_IP=172.16.238.20
MASTER_MIRROR_NET_IP=172.16.220.20

BACKUP_APP_NET_IP=172.16.238.30
BACKUP_MIRROR_NET_IP=172.16.220.30

REPORT_APP_NET_IP=172.16.238.40
REPORT_MIRROR_NET_IP=172.16.220.40

Prepare o primeiro arquivo de configuração do membro espelho

A biblioteca config-api permite configurar um espelho, então temos que criar um arquivo de configuração dedicado ao primeiro membro do espelho config-files/mirror-master.json

Por conveniência, os comentários estão localizados diretamente no JSON. Você pode baixar o mirror-master.json sem comentários aqui.

{
    "Security.Services" : {
        "%Service_Mirror" : {
            "Enabled" : true
        }
    },
    "SYS.MirrorMaster" : {
        "Demo" : {
            "Config" : {
                "Name" : "Demo",                                /* O nome do nosso espelho */
                "SystemName" : "master",                        /* O nome da instancia no espelhamento */
                "UseSSL" : true,                
                "ArbiterNode" : "${ARBITER_IP}|2188",           /* Endereço IP e Porta do nó do Arbitro */
                "VirtualAddress" : "${IRIS_VIRTUAL_IP}/24",     /* Endereço IP virtual */
                "VirtualAddressInterface" : "eth0",             /* Interface de rede usada para o endereço de IP virtual  */
                "MirrorAddress": "${MASTER_MIRROR_NET_IP}",     /* Endereço IP deste nó na rede privada do espelho */
                "AgentAddress": "${MASTER_APP_NET_IP}"          /* Endereço IP deste nó (o Agente é istalado na mesma máquina) */
            },
            "Databases" : [{                                    /* Lista de banco de dados para adicionar ao espelhamento */
                "Directory" : "/usr/irissys/mgr/myappdata/",
                "MirrorDBName" : "MYAPPDATA"
            }],
            "SSLInfo" : {                                       /* SSL Configuration */
                "CAFile" : "/certificates/CA_Server.cer",
                "CertificateFile" : "/certificates/master_server.cer",
                "PrivateKeyFile" : "/certificates/master_server.key",
                "PrivateKeyPassword" : "",
                "PrivateKeyType" : "2"
            }
        }
    }
}

Prepare o arquivo de configuração do membro de failover

Crie um arquivo de configuração do membro de backup de failover config-files/mirror-backup.json.

Parece o primeiro membro:

{
    "Security.Services" : {
        "%Service_Mirror" : {
            "Enabled" : true
        }
    },
    "SYS.MirrorFailOver" : {
        "Demo" : {                                          /* Espelho para juntar */
            "Config": {
                "Name" : "Demo",
                "SystemName" : "backup",                    /* Este nome de instância no espelho */
                "InstanceName" : "IRIS",                    /* Nome da instancia IRIS do primeiro membro do espelho */
                "AgentAddress" : "${MASTER_APP_NET_IP}",    /* Endereço IP do agente do primeiro membro espelho */
                "AgentPort" : "2188",
                "AsyncMember" : false,
                "AsyncMemberType" : ""
            },  
            "Databases" : [{                                /* DB no espelho */
                 "Directory" : "/usr/irissys/mgr/myappdata/"    
            }],
            "LocalInfo" : {
                "VirtualAddressInterface" : "eth0",         /* Interface de rede usada para o endereço IP virtual. */
                "MirrorAddress": "${BACKUP_MIRROR_NET_IP}"  /* Endereço IP deste nó na rede espelho privada*/
            },
            "SSLInfo" : {
                "CAFile" : "/certificates/CA_Server.cer",
                "CertificateFile" : "/certificates/backup_server.cer",
                "PrivateKeyFile" : "/certificates/backup_server.key",
                "PrivateKeyPassword" : "",
                "PrivateKeyType" : "2"
            }
        }
    }
}

Prepare o arquivo de configuração do membro assíncrono de leitura e gravação

É bastante semelhante ao arquivo de configuração de failover. As diferenças são os valores de AsyncMember, AsyncMemberType e MirrorAddress. Crie o arquivo ./config-files/mirror-report.json:

{
    "Security.Services" : {
        "%Service_Mirror" : {
            "Enabled" : true
        }
    },
    "SYS.MirrorFailOver" : {
        "Demo" : {
            "Config": {
                "Name" : "Demo",
                "SystemName" : "report",
                "InstanceName" : "IRIS",
                "AgentAddress" : "${MASTER_APP_NET_IP}",
                "AgentPort" : "2188",
                "AsyncMember" : true,
                "AsyncMemberType" : "rw"
            },
            "Databases" : [{
                 "Directory" : "/usr/irissys/mgr/myappdata/"
            }],
            "LocalInfo" : {
                "VirtualAddressInterface" : "eth0",
                "MirrorAddress": "${REPORT_MIRROR_NET_IP}"
            },
            "SSLInfo" : {
                "CAFile" : "/certificates/CA_Server.cer",
                "CertificateFile" : "/certificates/report_server.cer",
                "PrivateKeyFile" : "/certificates/report_server.key",
                "PrivateKeyPassword" : "",
                "PrivateKeyType" : "2"
            }
        }
    }
} 

Gere os certificados e configure os nós IRIS

Todos os arquivos de configuração estão prontos!

Agora temos que adicionar script para gerar certificados para comunicação segura entre cada nós. Um script pronto para uso está disponível no repositório gen-certificates.sh

# sudo é necessário devido ao uso de chown, chgrp chmod.
sudo ./gen-certificates.sh

Para configurar cada nó o init_mirror.sh será executado no início dos containers. Ele será configurado posteriormente em docker-compose.yml na seção de comando command: ["-a","/init_mirror.sh"] :

#!/bin/bash

# Banco de dados usado para testar o espelho.
DATABASE=/usr/irissys/mgr/myappdata

# O diretório contém myappdata com backup feito pelo mestre para restaurar em outros nós e fazer o espelho.
BACKUP_FOLDER=/opt/backup

# Espelhar arquivo de configuração no formato json config-api para o nó mestre.
MASTER_CONFIG=/opt/demo/mirror-master.json

# Espelhar arquivo de configuração no formato json config-api para o nó de backup.
BACKUP_CONFIG=/opt/demo/mirror-backup.json

# Espelhar arquivo de configuração no formato json config-api para o nó assíncrono do relatório.
REPORT_CONFIG=/opt/demo/mirror-report.json

# O nome do espelho
MIRROR_NAME=DEMO

# Lista de membros do espelho .
MIRROR_MEMBERS=BACKUP,REPORT

# Realizado no mestre.
# Carregue a configuração do espelho usando config-api com o arquivo /opt/demo/simple-config.json.
# Inicie um Job para aceitar automaticamente outros membros chamados "backup" e "report" para ingressar no espelho (evite validação de manual no gerenciamento do portal).
mestre() {
rm -rf $BACKUP_FOLDER/IRIS.DAT
envsubst < ${MASTER_CONFIG} > ${MASTER_CONFIG}.resolved
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS <<- END
Set sc = ##class(Api.Config.Services.Loader).Load("${MASTER_CONFIG}.resolved")
Set ^log.mirrorconfig(\$i(^log.mirrorconfig)) = \$SYSTEM.Status.GetOneErrorText(sc)
Job ##class(Api.Config.Services.SYS.MirrorMaster).AuthorizeNewMembers("${MIRROR_MEMBERS}","${MIRROR_NAME}",600)
Hang 2
Halt
END
}

# Realizado pelo mestre, faça um backup de /usr/irissy
make_backup() {
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS "##class(SYS.Database).DismountDatabase(\"${DATABASE}\")"
md5sum ${DATABASE}/IRIS.DAT
cp ${DATABASE}/IRIS.DAT ${BACKUP_FOLDER}/IRIS.TMP
mv ${BACKUP_FOLDER}/IRIS.TMP ${BACKUP_FOLDER}/IRIS.DAT
chmod 777 ${BACKUP_FOLDER}/IRIS.DAT
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS "##class(SYS.Database).MountDatabase(\"${DATABASE}\")"
}

# Restaure o banco de dados espelhado "myappdata". Essa restauração é executada no nó "backup" e "report".
restore_backup() {
sleep 5
while [ ! -f $BACKUP_FOLDER/IRIS.DAT ]; do sleep 1; done
sleep 2
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS "##class(SYS.Database).DismountDatabase(\"${DATABASE}\")"
cp $BACKUP_FOLDER/IRIS.DAT $DATABASE/IRIS.DAT
md5sum $DATABASE/IRIS.DAT
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS "##class(SYS.Database).MountDatabase(\"${DATABASE}\")"
}

# Configura o membro "backup"
# - Carregar arquivo de configuração /opt/demo/mirror-backup.json se esta instância for o backup ou
# /opt/demo/mirror-report.json se esta instância do relatório (nó espelho R\W assíncrono).
other_node() {
sleep 5
envsubst < $1 > $1.resolved
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS <<- END
Set sc = ##class(Api.Config.Services.Loader).Load("$1.resolved")
Halt
END
}

if [ "$IRIS_MIRROR_ROLE" == "master" ]
then
  master
  make_backup
elif [ "$IRIS_MIRROR_ROLE" == "backup" ]
then
  restore_backup
  other_node $BACKUP_CONFIG
else
  restore_backup
  other_node $REPORT_CONFIG
fi

exit 0

Arquivo Docker-compose

Temos quatro contêineres para começar. Um arquivo de composição do Docker é perfeito para orquestrar nossa amostra.

version: '3.7'

services:
  arbiter:
    image: containers.intersystems.com/intersystems/arbiter:2021.1.0.215.0
    init: true
    container_name: mirror-demo-arbiter
    command: 
      - /usr/local/etc/irissys/startISCAgent.sh 2188
    networks:
      app_net:
        ipv4_address: ${ARBITER_IP}
    extra_hosts:
      - "master:${MASTER_APP_NET_IP}"
      - "backup:${BACKUP_APP_NET_IP}"
      - "report:${REPORT_APP_NET_IP}"
    cap_add:
      - NET_ADMIN

  master:
    build: .
    image: mirror-demo
    container_name: mirror-demo-master
    networks:
      app_net:
        ipv4_address: ${MASTER_APP_NET_IP}
      mirror_net:
        ipv4_address: ${MASTER_MIRROR_NET_IP}
    environment: 
      - IRIS_MIRROR_ROLE=master
      - WEBGATEWAY_IP=${WEBGATEWAY_IP}
      - MASTER_APP_NET_IP=${MASTER_APP_NET_IP}
      - MASTER_MIRROR_NET_IP=${MASTER_MIRROR_NET_IP}
      - ARBITER_IP=${ARBITER_IP}
      - IRIS_VIRTUAL_IP=${IRIS_VIRTUAL_IP}
    ports:
      - 81:52773
    volumes: 
      - ./backup:/opt/backup
      - ./init_mirror.sh:/init_mirror.sh
      # Mount certificates
      - ./certificates/master_server.cer:/certificates/master_server.cer
      - ./certificates/master_server.key:/certificates/master_server.key
      - ./certificates/CA_Server.cer:/certificates/CA_Server.cer
      #- ~/iris.key:/usr/irissys/mgr/iris.key
    hostname: master
    extra_hosts:
      - "backup:${BACKUP_APP_NET_IP}"
      - "report:${REPORT_APP_NET_IP}"
    cap_add:
      - NET_ADMIN
    command: ["-a", "/init_mirror.sh"]

  backup:
    image: mirror-demo
    container_name: mirror-demo-backup
    networks:
      app_net:
        ipv4_address: ${BACKUP_APP_NET_IP}
      mirror_net:
        ipv4_address: ${BACKUP_MIRROR_NET_IP}
    ports:
      - 82:52773
    environment: 
      - IRIS_MIRROR_ROLE=backup
      - WEBGATEWAY_IP=${WEBGATEWAY_IP}
      - BACKUP_MIRROR_NET_IP=${BACKUP_MIRROR_NET_IP}
      - MASTER_APP_NET_IP=${MASTER_APP_NET_IP}
      - BACKUP_APP_NET_IP=${BACKUP_APP_NET_IP}
    volumes: 
      - ./backup:/opt/backup
      - ./init_mirror.sh:/init_mirror.sh
      # Mount certificates
      - ./certificates/backup_server.cer:/certificates/backup_server.cer
      - ./certificates/backup_server.key:/certificates/backup_server.key
      - ./certificates/CA_Server.cer:/certificates/CA_Server.cer
      #- ~/iris.key:/usr/irissys/mgr/iris.key
    hostname: backup
    extra_hosts:
      - "master:${MASTER_APP_NET_IP}"
      - "report:${REPORT_APP_NET_IP}"
    cap_add:
      - NET_ADMIN
    command: ["-a", "/init_mirror.sh"]

  report:
    image: mirror-demo
    container_name: mirror-demo-report
    networks:
      app_net:
        ipv4_address: ${REPORT_APP_NET_IP}
      mirror_net:
        ipv4_address: ${REPORT_MIRROR_NET_IP}
    ports:
      - 83:52773
    environment: 
      - IRIS_MIRROR_ROLE=report
      - WEBGATEWAY_IP=${WEBGATEWAY_IP}
      - MASTER_APP_NET_IP=${MASTER_APP_NET_IP}
      - REPORT_MIRROR_NET_IP=${REPORT_MIRROR_NET_IP}
      - REPORT_APP_NET_IP=${REPORT_APP_NET_IP}
    volumes: 
      - ./backup:/opt/backup
      - ./init_mirror.sh:/init_mirror.sh
      # Montar certificados
      - ./certificates/report_server.cer:/certificates/report_server.cer
      - ./certificates/report_server.key:/certificates/report_server.key
      - ./certificates/CA_Server.cer:/certificates/CA_Server.cer
      #- ~/iris.key:/usr/irissys/mgr/iris.key
    hostname: report
    extra_hosts:
      - "master:${MASTER_APP_NET_IP}"
      - "backup:${BACKUP_APP_NET_IP}"
    cap_add:
      - NET_ADMIN
    command: ["-a", "/init_mirror.sh"]
  
networks:
  app_net:
    ipam:
      driver: default
      config:
        - subnet: "${APP_NET_SUBNET}"
  mirror_net:
    ipam:
      driver: default
      config:
        - subnet: "${MIRROR_NET_SUBNET}" 

O docker-compose.yml contém muitas variáveis de ambiente. Para ver o tipo de arquivo resolvido no terminal:

docker-compose config

Executar contêineres

docker-compose up

Aguarde para que cada instância tenha um bom status de espelhamento:

  • nó mestre com status 'Primário'.
  • nó de backup com status Backup.
  • nó de relatório com status 'Conectado'.

Por fim, você deve ver estas mensagens nos logs do docker:

mirror-demo-master | 01/09/22-11:02:08:227 (684) 1 [Utility.Event] Becoming primary mirror server
...
mirror-demo-backup | 01/09/22-11:03:06:398 (801) 0 [Utility.Event] Found MASTER as primary, becoming backup
...
mirror-demo-report | 01/09/22-11:03:10:745 (736) 0 [Generic.Event] MirrorClient: Connected to primary: MASTER (ver 4)

Você também pode verificar o status do espelho com o portal http://localhost:81/csp/sys/utilhome.csp

Mirror-Status

Acesso aos portais

No Docker-compose mapeamos as portas 81,82 e 83 para ter acesso a cada portal de gerenciamento. Este é o login\senha padrão para todas as instâncias:

Teste

Verifique o monitor do espelho (porta de gerenciamento; este é o usuário e a senha padrão.): [http://localhost:81/csp/sys/op/%25CSP.UI.Portal.Mirror.Monitor.zen](http:/ /localhost:81/csp/sys/op/%25CSP.UI.Portal.Mirror.Monitor.zen) Mirror-Monitor

Verifique as configurações do espelho:http://localhost:81/csp/sys/mgr/%25CSP.UI.Portal.Mirror.EditFailover.zen?$NAMESPACE=%25SYS

Mirror-Configuration

Podemos iniciar um teste simplesmente definindo um global começando por demo. Lembre-se que configuramos um mapeamento global demo.* no namespace USER.

Abra uma sessão de terminal no servidor primário:

docker exec -it mirror-demo-master irissession iris
Set ^demo.test = $zdt($h,3,1)

Verifique se os dados estão disponíveis no nó de backup:

docker exec -it mirror-demo-backup irissession iris
Write ^demo.test

Check if the data is available on report node :

docker exec -it mirror-demo-report irissession iris
Write ^demo.test

Bom! Temos um ambiente espelho pronto, totalmente criado programaticamente. Para ficar um pouco mais completo, devemos adicionar um web gateway com https e criptografia entre o web gateway e o IRIS, mas deixaremos para o próximo artigo.

Espero que este artigo seja útil para você se você decidir criar seu próprio script.

Fonte

O conteúdo deste artigo é inspirado em:

0
0 246
Artigo Angelo Bruno Braga · Fev. 25, 2022 27m read

Neste artigo iremos construir uma configuração IRIS de alta disponibilidade utilizando implantações Kubernetes com armazenamento persistente distribuído substituindo o "tradicional" espelhamento IRIS. Esta implantação será capaz de tolerar falhas relacionadas a infraestrutura como falhas em nós, armazenamento e de Zonas de Disponibilidade. A abordagem descrita reduz muito a complexidade da implantação em detrimento um objetivo de tempo de recuperação (RTO) ligeiramente estendido.

Figura 1 - Espelhamento Tradicional x Kubernetes com Armazenamento Distribuído

Todos os códigos fonte deste artigo estão disponíveis em https://github.com/antonum/ha-iris-k8s
TL;DR

Assumindo que você possui um cluster com 3 nós e também uma certa familiaridade com o Kubernetes – vá em frente:

kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/master/deploy/longhorn.yaml
kubectl apply -f https://github.com/antonum/ha-iris-k8s/raw/main/tldr.yaml

Se você não tem certeza sobre o que as duas linhas acima fazem ou não possui o sistema onde executá-las - pule para a seção “Requisitos de Alta Disponibilidade". Iremos explicar tudo detalhadamente conforme evoluirmos no artigo.

Esta primeira linha instala o Longhorn - armazenamento distribuído Kubernetes de código aberto. A segunda instala o InterSystems IRIS, utilizando um volume baseado no Longhorn para o Durable SYS.

Aguarde até que todos os pods atinjam o estado de "em execução". kubectl get pods -A

Agora você deve ser capaz de acessar o portal de administração do IRIS em http://<IP Público do IRIS>:52773/csp/sys/%25CSP.Portal.Home.zen  (a senha padrão é 'SYS') e a linha de comando do IRIS através de:

kubectl exec -it iris-podName-xxxx -- iris session iris

Simule a Falha

Agora pode começar a bagunçar as coisas. Mas, antes de fazê-lo, tente adicionar alguns dados na base de dados para se certificar que estarão lá quando o IRIS voltar a ficar disponível.

kubectl exec -it iris-6d8896d584-8lzn5 -- iris session iris
USER>set ^k8stest($i(^k8stest))=$zdt($h)_" running on "_$system.INetInfo.LocalHostName()
USER>zw ^k8stest
^k8stest=1
^k8stest(1)="01/14/2021 14:13:19 running on iris-6d8896d584-8lzn5"

Nossa "engenharia do caos" inicia aqui:

# Parar o IRIS - Contêiner será reiniciado automaticamente 
kubectl exec -it iris-6d8896d584-8lzn5 -- iris stop iris quietly
 
# Deletar o  pod - O Pod será recriado 
kubectl delete pod iris-6d8896d584-8lzn5
 
# "Drenar à força" o nó que está servindo o pod IRIS - O Pod seria recriado em outro nó
kubectl drain aks-agentpool-29845772-vmss000001 --delete-local-data --ignore-daemonsets --force
 
# Deletar o nó - O Pod seria recriado em outro nó
# bem... você não pode realmente fazê-lo com o kubectl. Localize a instância ou a VM e a destrua.
# se você possuir acesso à maquina - desligue a força ou desconecte o cabo de rede. Estou falando sério!

Requisitos de Alta Disponibilidade

 

Estamos construindo um sistema que possa tolerar uma falha das seguintes:

  • Instância IRIS dentro de um contêiner/VM. Falha a nível do IRIS.
  • Falha no Pod/Contêiner.
  • Indisponibilidade temporária do nó de cluster individual. Um bom exemplo seria quando uma Zona de Disponibilidade fica temporariamente fora do ar.
  • Falha permanente do nó de cluster individual ou disco.

Basicamente os cenários que executamos na seção ˜Simule a falha".

Se alguma destas falhas ocorrer, o sistema deverá se recuperar sem que necessite de nenhum envolvimento humano e sem que ocorra nenhuma perda de dados.. Tecnicamente existem limites do que a persistência de dados garante. O IRIS por si só provê com base no Ciclo do Journal e no uso de transações em uma aplicação: https://docs.intersystems.com/irisforhealthlatest/csp/docbook/Doc.View.cls?KEY=GCDI_journal#GCDI_journal_writecycle De qualquer forma, estamos falando de menos de dois segundos de objetivo de ponto de recuperação (RPO).

Outros componentes do sistema (Serviço de APIs Kubernetes, base de dados etcd, serviço de Balanceamento de Carga, DNS e outros) estão fora do escopo e são gerenciados tipicamente pelo Serviço Gerenciado Kubernetes como o Azure AKS ou AWS EKS, então assumimos que eles já estão em alta disponibilidade.

Outra forma de se ver – somos responsáveis por lidar com falhas individuais de componentes e armazenamento, assumindo que o resto é tratado pelo provedor de infraestrutura/nuvem.

Arquitetura

Quando se trata de alta disponibilidade para o InterSystems IRIS, a recomendação tradicional é a utilização de Espelhamento. Utilizando o Espelhamento você terá duas instâncias ligadas do IRIS replicando de forma síncrona os dados. Cada nó mantém uma cópia completa da base de dados e, se o nó principal falhar, os usuários reconectam no nó Backup. Essencialmente, com a abordagem de uso do Espelhamento, o IRIS é responsável pela redundância tanto de computação quanto de armazenamento.

Com os servidores de espelhamento implantados em zonas de disponibilidade distintas o espelhamento provê a redundância necessária tanto para falhas de computação quanto para falhas de armazenamento e permite o excelente objetivo de tempo de recuperação (RTO - tempo necessário para que um sistema se recupere após uma falha) de apenas poucos segundos. Você pode encontrar o modelo de implantação para o IRIS Espelhado na Nuvem AWS aqui: https://community.intersystems.com/post/intersystems-iris-deployment%C2%A0guide-aws%C2%A0using-cloudformation-template

O lado menos bonito do espelhamento é a complexidade de configurá-lo, realizando procedimentos de backups e restore e lidando com a falta de replicação para configurações de segurança e arquivos locais que não os de bases de dados.

Orquestradores de contêineres como o Kubernetes (espere, estamos em 2021… exitem outros?!) proveem uma redundância computacional através da implantação de objetosautomaticamente reiniciando o Pod/Contêiner IRIS no caso de falha. É por isso que você vê apenas um nó IRIS executando no diagrama de arquitetura Kubernetes. Ao invés de manter um segundo nó de IRIS executando nós terceirizamos a disponibilidade de computação para o Kubernetes. O Kubernetes se certificará que o pod IRIS pode ser recriado no caso de falha do pod original por qualquer motivo.

Figura 2 Cenario de Failover

Tudo bem até agora… Se o nó do IRIS falhar, o Kubernetes apenas cria um novo. Dependendo do seu cluster, ele leva algo entre 10 a 90 segundos para trazer o IRIS de volta ao ar após uma falha de computação. É um passo atrás comparado com apenas alguns segundos no espelhamento mas, se é algo que você pode tolerar no caso de um evento indesejado, a recompensa é a grande redução da complexidade. Sem configuração de espelhamento e nem configurações de segurança e replicações de arquivos com que se preocupar.

Sinceramente, se você se logar em um contêiner, executando o IRIS no Kubernetes, você nem mesmo perceberá que está executando em um ambiente de alta disponibilidade. Tudo parece e se comporta como uma implantação de uma instância individual de IRIS.

Espere, e quanto ao armazenamento? Estamos lidando com um banco de dados … Seja qual for o cenário de falha que possamos imaginar, nosso sistema deverá cuidar da persistência dos dados também. O Espelhamento depende da computação, local no nó IRIS. Se o nó morre ou fica temporariamente indisponível – o armazenamento para o nó também o fica. É por isso que na configuração de espelhamento o IRIS cuida da replicação das bases de dados no nível do IRIS.

Precisamos de um armazenamento que possa não só preservar o estado da base de dados na reinicialização do contêiner mas também possa prover redundância em casos como a queda do nó ou de um segmento inteiro da rede (Zona de Disponibilidade). A apenas alguns anos atrás não existia uma resposta fácil para isso.Como você pode supor a partir do diagrama acima – temos uma baita resposta agora. É chamada de armazenamento distribuído de contêineres.

O armazenamento distribuído abstrai os volumes de hospedeiros subjacentes e os apresenta como um armazenamento conjunto disponível para todos os nós do cluster k8s. Nós utilizamos o Longhorn https://longhorn.io neste artigo; é grátis, de código aberto e bem fácil de instalar. Mas, você também pode verificar outros como o OpenEBS, Portworx e StorageOS que devem disponibilizar as mesmas funcionalidades. Rook Ceph é outro projeto de incubação CNCF a se considerar. No outro lado do espectro existem soluções de armazenamento de nível empresarial como o NetApp, PureStorage e outros.

Guia Passo a Passo

Na seção TL;DR nós instalamos tudo de uma vez. O Apêndice B lhe guiará através da instalação passo a passo e dos procedimentos de validação.

Armazenamento Kubernetes

Vamos voltar um pouco por um segundo e falar sobre contêineres e armazenamento em geral e como o IRIS se encaixa no cenário.

Por padrão todos os dados dentro do contêiner são efêmeros. Quando o contêiner morre, o dado desaparece. No Docker, você pode utilizar o conceito de volumes. Essencialmente isto permite que você exponha o diretório de seu SO hospedeiro para o contêiner.

docker run --detach
  --publish 52773:52773
  --volume /data/dur:/dur
  --env ISC_DATA_DIRECTORY=/dur/iconfig
  --name iris21 --init intersystems/iris:2020.3.0.221.0

No exemplo acima estamos iniciando o contêiner IRIS e fazendo com que o diretório local do hospedeiro ‘/data/dur’ fique acessível no ponto de montagem ‘/dur’ do contêiner. Desta forma, se o contêiner estiver armazenando qualquer coisa neste diretório, ela será preservada e disponível para utilização quando o próximo contêiner iniciar.

Do lado IRIS das coisas, podemos instruir o IRIS para armazenar todos os dados que devem sobreviver ao reinicio do contêiner em um diretório determinado especificando ISC_DATA_DIRECTORY. Durable SYS é o nome da funcionalidade do IRIS que você pode precisar dar uma olhada na documentação https://docs.intersystems.com/irisforhealthlatest/csp/docbook/Doc.View.cls?KEY=ADOCK#ADOCK_iris_durable_running

No Kubernetes a sintaxe é diferente mas os conceitos são os mesmos.

Aqui está a Implantação Kubernetes básica para IRIS.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: iris
spec:
  selector:
    matchLabels:
      app: iris
  strategy:
    type: Recreate
  replicas: 1
  template:
    metadata:
      labels:
        app: iris
    spec:
      containers:
      - image: store/intersystems/iris-community:2020.4.0.524.0
        name: iris
        env:
        - name: ISC_DATA_DIRECTORY
          value: /external/iris
        ports:
        - containerPort: 52773
          name: smp-http
        volumeMounts:
        - name: iris-external-sys
          mountPath: /external
      volumes:
      - name: iris-external-sys
        persistentVolumeClaim:
          claimName: iris-pvc

 

Na especificação de implantação acima, a parte ‘volumes’ lista os volumes de armazenamento. Eles podem estar disponíveis fora do contêiner através do Requisição de Volume Persistente (PersistentVolumeClaim) como ‘iris-pvc’. O 'volumeMounts' expõe este volume dentro do contêiner. ‘iris-external-sys’ é o identificador que amarra a montagem do volume ao volume específico. Na verdade, podemos ter múltiplos volumes e este nome é utilizado apenas para distinguir um de outro. Você pode chamá-lo de ‘steve’ se quiser.

A variável de ambiente ISC_DATA_DIRECTORY, já familiar, instrui o IRIS a utilizar um ponto de montagem específico para armazenar todos os dados que precisam sobreviver ao reinício do contêiner.

Agora vamos dar uma olhada na Requisição de Volume Persistente iris-pvc.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: iris-pvc
spec:
  storageClassName: longhorn
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

 

Bastante direto. Requisitando 10 gigabytes, montado como Read/Write em apenas um nó, utilizando a classe de armazenamento de ‘longhorn’.

Aquela storageClassName: longhorn é de fato crítica aqui.

Vamos olhar quais classes de armazenamento estão disponíveis no meu cluster AKS:

kubectl get StorageClass
NAME                             PROVISIONER                     RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
azurefile                        kubernetes.io/azure-file        Delete          Immediate           true                   10d
azurefile-premium                kubernetes.io/azure-file        Delete          Immediate           true                   10d
default (default)                kubernetes.io/azure-disk        Delete          Immediate           true                   10d
longhorn                         driver.longhorn.io              Delete          Immediate           true                   10d
managed-premium                  kubernetes.io/azure-disk        Delete          Immediate           true                   10d

Existem poucas classes de armazenamento do Azure, instaladas por padrão e uma do Longhorn que instalamos como parte de nosso primeiro comando:

kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/master/deploy/longhorn.yaml

Se você comentar #storageClassName: longhorn na definição da Requisição de Volume Persistente, será utilizada a classe de armazenamento que estiver marcada como “default” que é o disco regular do Azure.

Para ilustrar porquê precisamos de armazenamento distribuído vamos repetir o experimento da “engenharia do caos” que descrevemos no início deste artigo sem o armazenamento longhorn. Os dois primeiros cenários (parar o IRIS e deletar o Pod) deveriam completar com sucesso e os sistemas deveriam se recuperar ao estado operacional. Ao tentar tanto drenar ou destruir o nó deveria deixar o sistema em estado de falha.

#drenar o nó a força
kubectl drain aks-agentpool-71521505-vmss000001 --delete-local-data --ignore-daemonsets

kubectl describe pods ...   Type     Reason            Age                  From               Message   ----     ------            ----                 ----               -------   Warning  FailedScheduling  57s (x9 over 2m41s)  default-scheduler  0/3 nodes are available: 1 node(s) were unschedulable, 2 node(s) had volume node affinity conflict.

Essencialmente, o Kubernetes tentará reiniciar o pod IRIS pod no cluster mas, o nó onde ele iniciou originalmente não está disponível e os outros dois nós apresentam “conflito de afinidade de nó de volume”. Com este tipo de armazenamento o volume só está disponível no nó onde ele foi originalmente criado, visto que ele é basicamente amarrado ao disco disponível no nó hospedeiro.

Com o longhorn como classe de armazenamento, tanto o experimento “drenar a força” quanto o “destruir nó” funcionam com sucesso e o pod IRIS retorna a operação brevemente. Para conseguí-lo o Longhorn assume controle dos armazenamentos disponíveis dos 3 nós do cluster e replica os dados através deles. O Longhorn prontamente repara o armazenamento do cluster se um dos nós fica permanentemente indisponível. No nosso cenário “Destruir nó” o pod IRIS é reiniciado em outro nó rapidamente utilizando as replicas nos dois outros volumes remanescentes.  Então, o AKS provisiona um novo nó para substituir o nó perdido e assim que ele está pronto, o Longhorn entra em ação e reconstrói os dados necessários no novo nó. Tudo é automático, sem seu envolvimento.

Figura 3 Longhorn reconstruindo a réplica do volume no nó substituído

Mais sobre implantação k8s

Vamos dar uma olhada em alguns outros aspectos de nossa implantação:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: iris
spec:
  selector:
    matchLabels:
      app: iris
  strategy:
    type: Recreate
  replicas: 1
  template:
    metadata:
      labels:
        app: iris
    spec:
      containers:
      - image: store/intersystems/iris-community:2020.4.0.524.0
        name: iris
        env:
        - name: ISC_DATA_DIRECTORY
          value: /external/iris
        - name: ISC_CPF_MERGE_FILE
          value: /external/merge/merge.cpf
        ports:
        - containerPort: 52773
          name: smp-http
        volumeMounts:
        - name: iris-external-sys
          mountPath: /external
        - name: cpf-merge
          mountPath: /external/merge
        livenessProbe:
          initialDelaySeconds: 25
          periodSeconds: 10
          exec:
            command:
            - /bin/sh
            - -c
            - "iris qlist iris | grep running"
      volumes:
      - name: iris-external-sys
        persistentVolumeClaim:
          claimName: iris-pvc
      - name: cpf-merge
        configMap:
          name: iris-cpf-merge

 

strategy: Recreate, replicas: 1 informa ao Kubernetes que em algum momento ele deve manter uma e exatamente uma instância de do pod IRIS executando. Isto é o que dá conta do nosso cenário “deletar pod”.

A seção livenessProbe garante que o IRIS está sempre ativo no contêiner e trata o cenário “IRIS está fora”. initialDelaySeconds garante algum tempo para que o IRIS inicie. Você pode querer aumentá-lo se o IRIS estiver levando um tempo considerável para iniciar em sua implementação.

CPF MERGE funcionalidade do IRIS que lhe permite modificar o conteúdo do arquivo de configuração iris.cpf durante a inicialização do contêiner. Veja https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI.Page.cls?KEY=RACS_cpf#RACS_cpf_edit_merge para a documentação referente a ela. Neste exemplo estou utilizando o Kubernetes Config Map para gerenciar o conteúdo do arquivo mesclado: https://github.com/antonum/ha-iris-k8s/blob/main/iris-cpf-merge.yaml Aqui ajustamos os valores para os global buffers e gmheap, utilizados pela instância do IRIS, mais tudo que você pode encontrar no arquivo iris.cpf. Você pode até mesmo alterar a senha padrão do IRIS utilizando o campo `PasswordHash`no arquivo CPF Merge. Leia mais em: https://docs.intersystems.com/irisforhealthlatest/csp/docbook/Doc.View.cls?KEY=ADOCK#ADOCK_iris_images_password_auth

Além da Requisição de Volume Persistente https://github.com/antonum/ha-iris-k8s/blob/main/iris-pvc.yaml da implantação https://github.com/antonum/ha-iris-k8s/blob/main/iris-deployment.yaml e ConfigMap com o conteúdo do CPF Merge https://github.com/antonum/ha-iris-k8s/blob/main/iris-cpf-merge.yaml nossa implantação precisa de um serviço que exponha a implantação IRIS para a Internet pública: https://github.com/antonum/ha-iris-k8s/blob/main/iris-svc.yaml

kubectl get svc
NAME         TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)           AGE
iris-svc     LoadBalancer   10.0.18.169   40.88.123.45   52773:31589/TCP   3d1h
kubernetes   ClusterIP      10.0.0.1      <none>          443/TCP           10d

O IP Externo do iris-svc pode ser utilizado para acessar o portal de administração do IRIS através de  http://40.88.123.45:52773/csp/sys/%25CSP.Portal.Home.zen. A senha padrão é 'SYS'.

Backup/Restore e Dimensionamento do Armazenamento

Longhorn disponibiliza uma interface web para usuários para configurar e gerenciar volumes.

Identificar o pod, executar o componente de interface para usuários (longhorn-ui) e estabelecer um encaminhamento de portas com kubectl:

kubectl -n longhorn-system get pods
# note the longhorn-ui pod id.

kubectl port-forward longhorn-ui-df95bdf85-gpnjv 9000:8000 -n longhorn-system

A interface para usuários Longhorn ficará disponível em http://localhost:9000

Figura 4 Longhorn UI

Além da alta disponibilidade, a maioria das soluções de armazenamento para contêineres disponibilizam opções convenientes para backup, snapshots e restore. Os detalhes são específicos para cada implantação mas a convenção comum é de que o backup é associado ao VolumeSnapshot. Também é assim para o Longhorn. Dependendo da sua versão do Kubernetes e do seu provedor você também pode precisar instalar o volume snapshotter https://github.com/kubernetes-csi/external-snapshotter

`iris-volume-snapshot.yaml` é um exemplo de um snapshot de volume. Antes de utilizá-lo você deve configurar backups ou para um bucket S3 ou para um volume NFS no Longhorn. https://longhorn.io/docs/1.0.1/snapshots-and-backups/backup-and-restore/set-backup-target/

# Realizar um backup consistente do volume IRIS
kubectl apply -f iris-volume-snapshot.yaml

Para o IRIS é recomendado que você execute o External Freeze antes de realizar o backup/snapshot e então o Thaw depois. Veja os detalhes aqui: https://docs.intersystems.com/irisforhealthlatest/csp/documatic/%25CSP.Documatic.cls?LIBRARY=%25SYS&CLASSNAME=Backup.General#ExternalFreeze  

Para aumentar o tamanho do volume IRIS - ajuste a requisição de armazenamento na requisição de volume persistente (arquivo `iris-pvc.yaml`), utilizado pelo IRIS.

...
  resources:
    requests:
      storage: 10Gi #altere este valor para o necessário

Então, aplique novamente a especificação pvc. O Longhorn não consegue aplicar esta alteração enquanto o volume está conectado ao Pod em execução. Temporariamente altere o contador de réplicas para zero na implantação para que o tamanho do volume possa ser aumentado.

Alta Disponibilidade – Visão Geral

No início deste artigo nós definimos alguns critérios para alta disponibilidade. Aqui está como conseguimos alcançá-los com esta arquitetura:

Domínio de Falha

Mitigado automaticamente por

Instância IRIS no contêiner/VM. Falha no nível do IRIS.

Sonda Deployment Liveness reinicia o contêiner no caso do IRIS estar fora

Falha de Pod/Contêiner.

Implantação recria o Pod

Indisponibilidade temporária de um nó do cluster individual. Um bom exemplo seria uma Zona de Disponibilidade fora.

Implantação recria o pod em outro nó. O Longhorn torna os dados disponíveis em outro nó.

Falha permanente de um nó de cluster individual ou disco.

Mesmo do anteiror + k8s cluster autoscaler substituindo um nó danificado por um novo. O Longhorn reconstrói os dados no novo nó.

Zumbis e outras coisas a considerar

Se você estiver familiarizado em executar o IRIS em contêineres Docker, você já deve ter utilizado a flag `--init`.

docker run --rm -p 52773:52773 --init store/intersystems/iris-community:2020.4.0.524.0

O objetivo desta flag é previnir a formação de processos "zumbis". No Kubernetes, você pode tanto utilizar ‘shareProcessNamespace: true’ (considerações de segurança se aplicam) ou em seus próprios contêineres utilizar `tini`. Exemplo de Dockerfile com tini:

FROM iris-community:2020.4.0.524.0
...
# Add Tini
USER root
ENV TINI_VERSION v0.19.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini
USER irisowner
ENTRYPOINT ["/tini", "--", "/iris-main"]

Desde 2021, todas as imagens de contêineres disponibilizadas pela InterSystems incluiria tini por padrão.

Você pode posteriormente diminuir o tempo de recuperação para os cenários “Drenar a força o nó/destruir nó” ajustando poucos parâmetros:

Política de Deleção de Pods do Longhorn https://longhorn.io/docs/1.1.0/references/settings/#pod-deletion-policy-when-node-is-down e despejo baseado em taint do kubernetes: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/#taint-based-evictions

Disclaimer

Como funcionário InterSystems, Eu tenho que colocar isto aqui: O Longhorn é utilizado neste artigo como um exemplo de Armazenamento em Blocos Distribuído para Kubernetes. A InterSystems não valida e nem emite uma declaração de suporte oficial para soluções ou produtos de armazenamento individual. Você precisa testar e validar se qualquer solução específica de armazenamento atende a suas necessidades.

Solucões para armazenamento distribuído podem possuir características substancialmente distintas de performance., quando comparadas a armazenamento em nó local. Especialmente para operações de escrita, onde os dados devem ser escritos em múltiplas localidades antes de ser considerado em estado persistente. Certifique-se de testar suas cargas de trabalho e entender o comportamento específico, bem como as opções que seu driver para Interface de Armazenamento de Contêiner (CSI) oferece.

Basicamente, a InterSystems não valida e/ou endossa soluções específicas de armazenamento como o Longhorn da mesma forma que não valida marcas de HDs ou fabricantes de hardware para servidores. Eu pessoalmente achei o Longhorn fácil de se utilizar e seu time de desenvolvimento extremamente responsivo e útil na página do projeto no GitHub. https://github.com/longhorn/longhorn 

Conclusão

O ecossistema Kubernetes evoluiu de forma significante nos últimos anos e, com a utilização de soluções de armazenamento em blocos distribuído, você pode agora construir uma configuração de Alta Disponibilidade que pode manter uma instância IRIS, nó de cluster e até mesmo falhas de Zonas de Disponibilidade.

Você pode terceirizar a alta disponibilidade de computação e armazenamento para componentes do Kubernetes, resultando em um sistema significativamente mais simples de se configurar e manter, comparando-se ao espelhamento tradicional do IRIS. Da mesma forma, esta configuração pode não lhe prover o mesmo RTO e nível de performance de armazenamento que uma configuração de Espelhamento.

Neste artigo criamos uma configuração IRIS de alta disponibilidade utilizando o Azure AKS como Kubernetes gerenciado e o sistema de armazenamento distribuído Longhorn. Você pode explorar múltiplas alternativas como AWS EKS, Google Kubernetes Engine para K8s gerenciados, StorageOS, Portworx e OpenEBS para armazenamento distribuído para contêiner ou mesmo soluções de armazenamento de nível empresarial como NetApp, PureStorage, Dell EMC e outras.

Apêndice A. Criando um Cluster Kubernetes na nuvem

Serviço Gerenciado Kubernetes de um dos provedores públicos de nuvem é uma forma fácil de criar um cluster k8s necessário para esta configuração.A configuração padrão do AKS da Azure é pronto para ser utilizado para a implantação descrita neste artigo.

Criar um novo cluster AKS com 3 nós. Deixe todo o resto padrão.

Figura 5 Criar um cluster AKS

Instale o kubectl em seu computador localmente: https://kubernetes.io/docs/tasks/tools/install-kubectl/

Registre seu cluster AKS com o kubectl local

 

Figura 6 Registre o cluster AKS com kubectl

Depois disto, você pode voltar para o início do artigoe instalar o longhorn e a implantação IRIS.

A instalação no AWS EKS é um pouco mais complicada. Você precisa se certificar que cada instância em seu grupo de nós tem o open-iscsi instalado.

sudo yum install iscsi-initiator-utils -y

Instalar o Longhorn no GKE necessita de um passo extra, descrito aqui: https://longhorn.io/docs/1.0.1/advanced-resources/os-distro-specific/csi-on-gke/

Apêndice B. Instalação Passo a Passo

Passo 1 – Cluster Kubernetes e kubectl

Você precisa um cluster k8s com 3 nós. Apêndice A descreve como conseguir um na Azure.

$ kubectl get nodes
NAME                                STATUS   ROLES   AGE   VERSION
aks-agentpool-29845772-vmss000000   Ready    agent   10d   v1.18.10
aks-agentpool-29845772-vmss000001   Ready    agent   10d   v1.18.10
aks-agentpool-29845772-vmss000002   Ready    agent   10d   v1.18.10

Passo 2 – Instalar o Longhorn

kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/master/deploy/longhorn.yaml

Certifique-se de que todos os pods no namespace ‘longhorn-system’ estão no estado de em execução. Isso pode levar alguns minutos.

$ kubectl get pods -n longhorn-system
NAME                                       READY   STATUS    RESTARTS   AGE
csi-attacher-74db7cf6d9-jgdxq              1/1     Running   0          10d
csi-attacher-74db7cf6d9-l99fs              1/1     Running   1          11d
...
longhorn-manager-flljf                     1/1     Running   2          11d
longhorn-manager-x76n2                     1/1     Running   1          11d
longhorn-ui-df95bdf85-gpnjv                1/1     Running   0          11d

Consulteo guia de instalação do Longhornpara detalhes e solução de problemas https://longhorn.io/docs/1.1.0/deploy/install/install-with-kubectl

Passo 3 – Faça um clone do repositório GitHub

$ git clone https://github.com/antonum/ha-iris-k8s.git
$ cd ha-iris-k8s
$ ls
LICENSE                   iris-deployment.yaml      iris-volume-snapshot.yaml
README.md                 iris-pvc.yaml             longhorn-aws-secret.yaml
iris-cpf-merge.yaml       iris-svc.yaml             tldr.yaml

Passo 4 – implemente e valide os componentes um a um

o arquivo tldr.yaml contém todos os componentes necessários para a implantação em um pacote. Aqui iremos instalá-los um a um e validar a configuração de cada um deles individualmente.

# Se você aplicou o tldr.yaml previamente, apague-o.
$ kubectl delete -f https://github.com/antonum/ha-iris-k8s/raw/main/tldr.yaml

Criar a Requisição de Volume Persistente

$ kubectl apply -f iris-pvc.yaml persistentvolumeclaim/iris-pvc created

$ kubectl get pvc NAME       STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE iris-pvc   Bound    pvc-fbfaf5cf-7a75-4073-862e-09f8fd190e49   10Gi       RWO            longhorn       10s

Criar o Mapa de Configuração

$ kubectl apply -f iris-cpf-merge.yaml

$ kubectl describe cm iris-cpf-merge Name:         iris-cpf-merge Namespace:    default Labels:       <none> Annotations:  <none>

Data

merge.cpf:

[config] globals=0,0,800,0,0,0 gmheap=256000 Events:  <none>

criar a implantação iris

$  kubectl apply -f iris-deployment.yaml deployment.apps/iris created

$ kubectl get pods                     NAME                    READY   STATUS              RESTARTS   AGE iris-65dcfd9f97-v2rwn   0/1     ContainerCreating   0          11s

Anote o nome do pod. Você irá utilizá-lo para conectar ao pod no próximo comando

$ kubectl exec -it iris-65dcfd9f97-v2rwn   -- bash

irisowner@iris-65dcfd9f97-v2rwn:~$ iris session iris Node: iris-65dcfd9f97-v2rwn, Instance: IRIS

USER>w $zv IRIS for UNIX (Ubuntu Server LTS for x86-64 Containers) 2020.4 (Build 524U) Thu Oct 22 2020 13:04:25 EDT

h<enter> to exit IRIS shell

exit<enter> to exit pod

acesse os logs do contêiner IRIS

$ kubectl logs iris-65dcfd9f97-v2rwn ... [INFO] ...started InterSystems IRIS instance IRIS 01/18/21-23:09:11:312 (1173) 0 [Utility.Event] Private webserver started on 52773 01/18/21-23:09:11:312 (1173) 0 [Utility.Event] Processing Shadows section (this system as shadow) 01/18/21-23:09:11:321 (1173) 0 [Utility.Event] Processing Monitor section 01/18/21-23:09:11:381 (1323) 0 [Utility.Event] Starting TASKMGR 01/18/21-23:09:11:392 (1324) 0 [Utility.Event] [SYSTEM MONITOR] System Monitor started in %SYS 01/18/21-23:09:11:399 (1173) 0 [Utility.Event] Shard license: 0 01/18/21-23:09:11:778 (1162) 0 [Database.SparseDBExpansion] Expanding capacity of sparse database /external/iris/mgr/iristemp/ by 10 MB.

crie o serviço iris

$ kubectl apply -f iris-svc.yaml    service/iris-svc created

$ kubectl get svc NAME         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)           AGE iris-svc     LoadBalancer   10.0.214.236   20.62.241.89   52773:30128/TCP   15s

Passo 5 – Acesse o portal de administração

Finalmente – conecte-se ao portal de administração do IRIS, utilizando o IP externo do serviço: http://20.62.241.89:52773/csp/sys/%25CSP.Portal.Home.zen usuário _SYSTEM, senha SYS. Será solicitado que você altere no seu primeiro login.

 

0
0 324