AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / server / Perguntas / 1061100
Accepted
Mikhail T.
Mikhail T.
Asked: 2021-04-22 07:23:49 +0800 CST2021-04-22 07:23:49 +0800 CST 2021-04-22 07:23:49 +0800 CST

Sistemas Systemd e de Recuperação de Desastres Stand-By

  • 772

Estamos usando o systemd para executar vários serviços em produção. (Dã...)

Estamos construindo um site de "recuperação de desastres" correspondente, que terá o mesmo aplicativo instalado -- com as mesmas unidades de sistema para ativar seus vários componentes em caso de desastre .

Este ambiente de DR é "quente", pronto para assumir o controle em pouco tempo (quanto mais curto, melhor) - tornando-se assim a própria produção. Então, quando o "desastre" for resolvido, o outro ambiente se tornará o DR.

Minha pergunta é: como manter esses serviços do systemd prontos para iniciar, mas não iniciando até que uma determinada condição se torne verdadeira?

Para concluir que um determinado site é atualmente o primário (produção), um comando ( amIthePrimary) precisa ser executado e sair com um código de saída 0. A verificação é fácil e rápida - e pode ser realizada uma vez por minuto. Mas, porque requer a execução de um comando, não há Conditionpara isso fornecido pelo systemd .

Eu coloco esse comando em cada unidade ExecPre , ou isso se tornará um erro barulhento, incomodando desnecessariamente os administradores? Coloco-o em uma unidade própria, com todos os outros serviços Require?

Separadamente, uma vez que a condição é verdadeira -- e os serviços são iniciados -- como continuo verificando, para que todos sejam desligados, caso se torne falso novamente?

redhat disaster-recovery systemd rhel7
  • 1 1 respostas
  • 105 Views

1 respostas

  • Voted
  1. Best Answer
    mattpr
    2021-11-20T09:26:43+08:002021-11-20T09:26:43+08:00

    Como seu caso de uso é bastante personalizado e suas necessidades podem mudar no futuro, por que você não faz algo como o seguinte...

    crie um novo timer systemd (por exemplo failover-manager, ) em ambas as máquinas que execute uma vez por minuto. O timer systemd iniciará um serviço systemd one-shot associado em intervalos regulares.

    Esse serviço systemd one-shot pode apenas executar um script bash que contém sua lógica:

    • execute seu amIthePrimarycheque
    • se primário, inicie seu serviço systemd e verifique se ele foi iniciado sem erros.
    • se não for primário, pare o serviço systemd se estiver em execução.
    • se o seu script não puder iniciar/parar/verificar a execução, ele deverá falhar (monitorável), caso contrário, será bem-sucedido.
    • este script de temporizador não precisa produzir nada (ruído), exceto quando faz uma alteração, ou seja:
      • "Sou primário, mas o serviço não está em execução. Iniciando... Aguardando alguns segundos... o serviço verificado está sendo executado sem erros." ou
      • "Eu não sou o principal, mas o serviço ESTÁ em execução. Parando."

    Dessa forma, você sempre sabe que pode monitorar se sua verificação regular/temporizador está sendo executada sem erros. Se o seu serviço de timer tiver problemas (saída diferente de zero), você poderá detectar isso com o monitoramento. Você pode monitorar as falhas do seu serviço de aplicativo principal separadamente.

    Se suas necessidades mudarem, você pode facilmente adaptar seu script de timer ou a frequência em que ele é executado.

    Provavelmente existem maneiras mais limpas de fazer isso, mas elas provavelmente dependeriam de um evento sendo gerado a partir do que está por trás do seu amIthePrimarycheque... e você não forneceu nenhum detalhe sobre isso. ou seja, failover orientado a eventos em vez de polling.

    Você também pode colocar sua amIthePrimaryverificação em ExecStartPre=... mas quando ele falhar em impedir que o serviço seja iniciado, seu serviço estará em um estado FAILED, o que pode confundir seu monitoramento porque não é uma falha ruim, mas sim uma falha intencional. Portanto, talvez você prefira usar a abordagem do temporizador, pois pode monitorar seu processo de temporizador e seu processo de serviço principal separadamente. timer deve estar sempre em execução, ativo e não falhando. Seu serviço (se estiver em execução) nunca deve estar em um estado de falha ou o monitoramento deve ser desativado. Há outra questão sobre como saber se o serviço deve ou não estar sendo executado sob uma perspectiva de monitoramento, mas isso está além do escopo da questão.

    Atualização - incluindo exemplo de implementação de amostra

    Não testado, mas apenas para deixar minha sugestão mais clara.

    failover-manager.sh

    Digamos que este script seja implantado para/opt/failover-manager/failover-manager.sh

    #!/bin/bash
    
    # expected ENV.  Provided by the service that starts this script.
    #
    # APP_SERVICE (your main application)
    # SECONDS_TO_START (e.g. some java apps start very slowly)
    
    if [ -z "$APP_SERVICE" -o -z "$SECONDS_TO_START" ]; then
        echo "Missing environment"
        exit 1
    fi
    
    function is_running {
        systemctl is-active --quiet $1
        return $?
    }
    
    if amIthePrimary; then
        if is_running $APP_SERVICE; then   # no change, no log
            exit 0
        else
            echo "I AM primary, but service NOT running.  STARTING..."
            systemctl start $APP_SERVICE
            sleep $SECONDS_TO_START
            if is_running $APP_SERVICE; then 
                echo "Verified service is STARTED without error: $APP_SERVICE."
                exit 0
            else
                echo "Service $APP_SERVICE has not yet STARTED after $SECONDS_TO_START seconds."
                exit 1
            fi
        fi
    else
        if is_running $APP_SERVICE; then 
            echo "I am NOT primary, but service IS running.  Stopping..."
            systemctl stop $APP_SERVICE
            sleep $SECONDS_TO_START
            if is_running $APP_SERVICE; then 
                echo "Service $APP_SERVICE has not yet STOPPED after $SECONDS_TO_START seconds."
                exit 1
            else
                echo "Verified service is STOPPED: $APP_SERVICE."
                exit 0
            fi
        else   # no change, no log
            exit 0
        fi
    fi
    
    

    failover-manager.timer

    [Unit]
    Description=Timer that starts failover-manager.service
    Requires=failover-manager.service
    
    [Timer]
    Unit=failover-manager.service
    # every 1 minute
    OnCalendar=*:0/1
    AccuracySec=1s
    Persistent=true
    
    
    [Install]
    WantedBy=timers.target
    

    failover-manager.service

    Esse cara é executado pelo temporizador acima.

    [Unit]
    Description=Checks if we need to start or stop our application.
    
    [Service]
    Type=oneshot
    Environment=APP_SERVICE="my-application.service" SECONDS_TO_START="5"    
    WorkingDirectory=/opt/failover-manager/
    ExecStart=/opt/failover-manager/failover-manager.sh
    
    User=root
    Group=root
    
    

    opções puras do systemd?

    Se você estiver procurando por um mecanismo systemd puro para fazer isso de maneira limpa, talvez não seja possível.

    Seu caso de uso é personalizado e IMO além do escopo do systemd.

    Portanto, você pode "hackear" usando ExecStartPreou usando requires/ wantsmecanismos de dependência de tipo ... mas todas essas abordagens dependem de um processo estar no estado parado devido a uma falha (monitoramento de interrupções ... ... ou esse processo sendo iniciado/parado por "algo" que está ciente de algo fora do mundo systemd. O último não interrompe o monitoramento, mas requer algo além do systemd e o que propus é uma maneira de fazer isso.

    alternativas

    Como @anx sugeriu... talvez re-engenharia como seu failover de DR funciona.

    Essa também é a abordagem que adotamos. Se tivermos uma caixa de espera/nuvem/rack/etc, então gostamos de ter certeza de que tudo já está funcionando (por exemplo, serviços, etc).

    Então a questão é apenas... como fazer a transição.

    Há duas maneiras comuns de realizar o failover para um endpoint em espera...

    1 - Failover DNS

    Defina um ttl DNS baixo (tempo de cache) para seus terminais críticos e atualize seus registros DNS para apontar para o terminal em espera (por exemplo, atualização de DNS CNAME, A, AAAA) quando uma falha for detectada.

    Muitos provedores de DNS gerenciados (por exemplo, dnsmadeeasy, dynect) oferecem isso como parte de seu serviço (detecção e failover). Mas é claro que você pode implementar isso com seu próprio DNS ou qualquer provedor de DNS que permita definir um TTL baixo e facilmente, manual ou automaticamente (monitoramento + API DNS) atualizar seus registros DNS.

    Um problema potencial aqui é que você pode se preocupar com bots fazendo solicitações para o endpoint "não ativo". Isso definitivamente acontecerá, mas se seu aplicativo for bem projetado, não interromperá nada ter algumas solicitações chegando ao ponto de extremidade de DR em espera.

    O bom é que isso força você a pensar em como tornar sua arquitetura de aplicativo mais robusta em termos de vários endpoints simultâneos recebendo tráfego (compartilhamento de bancos de dados, replicação, etc).

    Se for um grande problema você pode adicionar regras do iptables para gerenciar isso...mas então você pode ter o mesmo problema de antes... para que o failover aconteça).

    2 - failover do balanceador de carga

    É bastante comum ter servidores em espera que não estão ativos em um balanceador de carga e podem ser rapidamente adicionados/trocados no pool de servidores ativos atrás do balanceador de carga.

    Nesse caso, o balanceador de carga ou um terceiro componente pode gerenciar as verificações de integridade e atualizar a configuração do balanceador de carga para trocar servidores íntegros por não íntegros.

    Isso não funciona tão bem para um caso de DR, pois os balanceadores de carga geralmente são locais de rack ou datacenter. Portanto, para DR, provavelmente é melhor criar um failover baseado em DNS para um data center/região diferente.

    • 1

relate perguntas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Você pode passar usuário/passar para autenticação básica HTTP em parâmetros de URL?

    • 5 respostas
  • Marko Smith

    Ping uma porta específica

    • 18 respostas
  • Marko Smith

    Verifique se a porta está aberta ou fechada em um servidor Linux?

    • 7 respostas
  • Marko Smith

    Como automatizar o login SSH com senha?

    • 10 respostas
  • Marko Smith

    Como posso dizer ao Git para Windows onde encontrar minha chave RSA privada?

    • 30 respostas
  • Marko Smith

    Qual é o nome de usuário/senha de superusuário padrão para postgres após uma nova instalação?

    • 5 respostas
  • Marko Smith

    Qual porta o SFTP usa?

    • 6 respostas
  • Marko Smith

    Linha de comando para listar usuários em um grupo do Windows Active Directory?

    • 9 respostas
  • Marko Smith

    O que é um arquivo Pem e como ele difere de outros formatos de arquivo de chave gerada pelo OpenSSL?

    • 3 respostas
  • Marko Smith

    Como determinar se uma variável bash está vazia?

    • 15 respostas
  • Martin Hope
    Davie Ping uma porta específica 2009-10-09 01:57:50 +0800 CST
  • Martin Hope
    kernel O scp pode copiar diretórios recursivamente? 2011-04-29 20:24:45 +0800 CST
  • Martin Hope
    Robert ssh retorna "Proprietário incorreto ou permissões em ~/.ssh/config" 2011-03-30 10:15:48 +0800 CST
  • Martin Hope
    Eonil Como automatizar o login SSH com senha? 2011-03-02 03:07:12 +0800 CST
  • Martin Hope
    gunwin Como lidar com um servidor comprometido? 2011-01-03 13:31:27 +0800 CST
  • Martin Hope
    Tom Feiner Como posso classificar a saída du -h por tamanho 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich O que é um arquivo Pem e como ele difere de outros formatos de arquivo de chave gerada pelo OpenSSL? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent Como determinar se uma variável bash está vazia? 2009-05-13 09:54:48 +0800 CST

Hot tag

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve