Partilhar via


Recuperação de desastres no Azure Service Fabric

Uma parte crítica do fornecimento de alta disponibilidade é garantir que os serviços possam sobreviver a todos os diferentes tipos de falhas. Isso é especialmente importante para falhas não planejadas e fora do seu controle.

Este artigo descreve alguns modos de falha comuns que podem ser desastres se não forem modelados e gerenciados corretamente. Também discute mitigações e ações a serem tomadas se um desastre acontecer de qualquer maneira. O objetivo é limitar ou eliminar o risco de tempo de inatividade ou perda de dados quando ocorrem falhas, planejadas ou não.

Evitar catástrofes

O principal objetivo do Azure Service Fabric é ajudá-lo a modelar seu ambiente e seus serviços de tal forma que os tipos de falha comuns não sejam desastres.

Em geral, existem dois tipos de cenários de desastre/falha:

  • Falhas de hardware e software
  • Falhas operacionais

Falhas de hardware e software

As falhas de hardware e software são imprevisíveis. A maneira mais fácil de sobreviver a falhas é executar mais cópias do serviço através dos limites de falhas de hardware ou software.

Por exemplo, se o serviço estiver sendo executado em apenas uma máquina, a falha dessa máquina será um desastre para esse serviço. A maneira simples de evitar esse desastre é garantir que o serviço esteja sendo executado em várias máquinas. Os testes também são necessários para garantir que a falha de uma máquina não interrompa o serviço em execução. O planejamento de capacidade garante que uma instância de substituição possa ser criada em outro lugar e que a redução na capacidade não sobrecarregue os serviços restantes.

O mesmo padrão funciona independentemente do que você está tentando evitar o fracasso. Por exemplo, se você estiver preocupado com a falha de uma SAN, será executado em várias SANs. Se você está preocupado com a perda de um rack de servidores, você corre em vários racks. Se você estiver preocupado com a perda de datacenters, seu serviço deve ser executado em várias regiões do Azure, em várias Zonas de Disponibilidade do Azure ou em seus próprios datacenters.

Quando um serviço é estendido em várias instâncias físicas (máquinas, racks, datacenters, regiões), você ainda está sujeito a alguns tipos de falhas simultâneas. Mas falhas únicas e até mesmo múltiplas de um tipo específico (por exemplo, falha de uma única máquina virtual ou link de rede) são tratadas automaticamente e, portanto, não são mais um "desastre".

O Service Fabric fornece mecanismos para expandir o cluster e lida com a devolução de nós e serviços com falha. O Service Fabric também permite executar muitas instâncias de seus serviços para evitar que falhas não planejadas se transformem em desastres reais.

Pode haver razões pelas quais a execução de uma implantação grande o suficiente para abranger falhas não é viável. Por exemplo, pode levar mais recursos de hardware do que você está disposto a pagar em relação à chance de falha. Quando você lida com aplicativos distribuídos, saltos de comunicação adicionais ou custos de replicação de estado em distâncias geográficas podem causar latência inaceitável. O local onde esta linha é traçada difere para cada aplicação.

Para falhas de software especificamente, a falha pode estar no serviço que você está tentando dimensionar. Nesse caso, mais cópias não evitam o desastre, porque a condição de falha está correlacionada em todas as instâncias.

Falhas operacionais

Mesmo que o seu serviço esteja espalhado por todo o mundo com muitas redundâncias, ele ainda pode sofrer eventos desastrosos. Por exemplo, alguém pode acidentalmente reconfigurar o nome DNS para o serviço ou excluí-lo completamente.

Como exemplo, digamos que você tinha um serviço stateful Service Fabric e alguém excluiu esse serviço acidentalmente. A menos que haja alguma outra mitigação, esse serviço e todo o estado que ele tinha agora desapareceram. Esses tipos de desastres operacionais ("oops") exigem mitigações e etapas de recuperação diferentes das falhas não planejadas regulares.

As melhores maneiras de evitar esses tipos de falhas operacionais são:

  • Restrinja o acesso operacional ao ambiente.
  • Auditar rigorosamente operações perigosas.
  • Imponha automação, impeça alterações manuais ou fora de banda e valide alterações específicas em relação ao ambiente antes de implementá-las.
  • Certifique-se de que as operações destrutivas sejam "suaves". As operações suaves não entram em vigor imediatamente ou podem ser desfeitas dentro de uma janela de tempo.

O Service Fabric fornece mecanismos para evitar falhas operacionais, como o fornecimento de controle de acesso baseado em função para operações de cluster. No entanto, a maioria dessas falhas operacionais requer esforços organizacionais e outros sistemas. O Service Fabric fornece mecanismos para sobreviver a falhas operacionais, principalmente backup e restauração para serviços com monitoração de estado.

Gestão de falhas

O objetivo do Service Fabric é o gerenciamento automático de falhas. Mas para lidar com alguns tipos de falhas, os serviços devem ter código adicional. Outros tipos de falhas não devem ser resolvidos automaticamente por razões de segurança e continuidade de negócios.

Tratamento de falhas únicas

Máquinas individuais podem falhar por todos os tipos de razões. Às vezes, são causas de hardware, como fontes de alimentação e falhas de hardware de rede. Outras falhas estão no software. Isso inclui falhas do sistema operacional e do próprio serviço. O Service Fabric deteta automaticamente esses tipos de falhas, incluindo casos em que a máquina fica isolada de outras máquinas devido a problemas de rede.

Independentemente do tipo de serviço, a execução de uma única instância resulta em tempo de inatividade para esse serviço se essa única cópia do código falhar por qualquer motivo.

Para lidar com qualquer falha única, a coisa mais simples que você pode fazer é garantir que seus serviços sejam executados em mais de um nó por padrão. Para serviços sem monitoração de estado, certifique-se de que InstanceCount é maior que 1. Para serviços com monitoração de estado, a recomendação mínima é que TargetReplicaSetSize e MinReplicaSetSize ambos estão definidos como 3. Executar mais cópias do seu código de serviço garante que o serviço possa lidar com qualquer falha única automaticamente.

Tratamento de falhas coordenadas

As falhas coordenadas em um cluster podem ser devidas a falhas e alterações de infraestrutura planejadas ou não planejadas ou a alterações de software planejadas. O Service Fabric modela zonas de infraestrutura que apresentam falhas coordenadas como domínios de falha. As áreas que sofrerão alterações coordenadas de software são modeladas como domínios de atualização. Para obter mais informações sobre domínios de falha, domínios de atualização e topologia de cluster, consulte Descrever um cluster do Service Fabric usando o Gerenciador de Recursos de Cluster.

Por padrão, o Service Fabric considera domínios de falha e atualização ao planejar onde seus serviços devem ser executados. Por padrão, o Service Fabric tenta garantir que seus serviços sejam executados em vários domínios de falha e atualização para que, se ocorrerem alterações planejadas ou não planejadas, seus serviços permaneçam disponíveis.

Por exemplo, digamos que a falha de uma fonte de alimentação faz com que todas as máquinas de um rack falhem simultaneamente. Com várias cópias do serviço em execução, a perda de muitas máquinas em falha de domínio se transforma em apenas mais um exemplo de uma única falha para um serviço. É por isso que gerenciar domínios de falha e atualização é fundamental para garantir a alta disponibilidade de seus serviços.

Quando você executa o Service Fabric no Azure, os domínios de falha e os domínios de atualização são gerenciados automaticamente. Em outros ambientes, podem não ser. Se você estiver criando seus próprios clusters no local, certifique-se de mapear e planejar seu layout de domínio de falha corretamente.

Os domínios de atualização são úteis para modelar áreas onde o software será atualizado ao mesmo tempo. Por isso, os domínios de atualização também costumam definir os limites em que o software é retirado durante as atualizações planejadas. As atualizações do Service Fabric e dos seus serviços seguem o mesmo modelo. Para obter mais informações sobre atualizações contínuas, domínios de atualização e o modelo de integridade do Service Fabric que ajuda a evitar que alterações não intencionais afetem o cluster e seu serviço, consulte:

Você pode visualizar o layout do cluster usando o mapa de cluster fornecido no Service Fabric Explorer:

Nós espalhados entre domínios de falha no Service Fabric Explorer

Nota

Modelação de áreas de falha, atualizações contínuas, execução de muitas instâncias do código e estado de serviço, regras de posicionamento para garantir que os serviços sejam executados em domínios de falha e atualização e monitoramento de integridade interno são apenas alguns dos recursos que o Service Fabric fornece para evitar que problemas operacionais normais e falhas se transformem em desastres.

Tratamento simultâneo de falhas de hardware ou software

Temos falado de fracassos isolados. Como você pode ver, eles são fáceis de lidar para serviços sem estado e com monitoração de estado apenas mantendo mais cópias do código (e estado) em execução em domínios de falha e atualização.

Várias falhas aleatórias simultâneas também podem acontecer. É mais provável que isso leve a tempo de inatividade ou a um desastre real.

Serviços apátridas

A contagem de instâncias para um serviço sem estado indica o número desejado de instâncias que precisam ser executadas. Quando qualquer (ou todas) as instâncias falham, o Service Fabric responde criando automaticamente instâncias de substituição em outros nós. O Service Fabric continua a criar substituições até que o serviço volte à contagem de instâncias desejada.

Por exemplo, suponha que o serviço sem estado tenha um InstanceCount valor de -1. Esse valor significa que uma instância deve ser executada em cada nó do cluster. Se algumas dessas instâncias falharem, o Service Fabric detetará que o serviço não está no estado desejado e tentará criar as instâncias nos nós onde elas estão faltando.

Serviços com estado

Existem dois tipos de serviços com monitoração de estado:

  • Estadista com estado persistente.
  • Stateful com estado não persistente. (O estado é armazenado na memória.)

A recuperação de uma falha de um serviço com monitoração de estado depende do tipo de serviço com monitoração de estado, quantas réplicas o serviço tinha e quantas réplicas falharam.

Em um serviço com monitoração de estado, os dados de entrada são replicados entre réplicas (a primária e quaisquer secundárias ativas). Se a maioria das réplicas receber os dados, os dados serão considerados quórum comprometido. (Para cinco réplicas, três serão quórum.) Isso significa que, a qualquer momento, haverá pelo menos um quórum de réplicas com os dados mais recentes. Se as réplicas falharem (digamos, duas em cada cinco), podemos usar o valor de quórum para calcular se podemos recuperar. (Como as três réplicas restantes ainda estão ativas, é garantido que pelo menos uma réplica terá dados completos.)

Quando um quórum de réplicas falha, a partição é declarada como estando em um estado de perda de quórum. Digamos que uma partição tenha cinco réplicas, o que significa que pelo menos três têm a garantia de ter dados completos. Se um quórum (três em cinco) de réplicas falhar, o Service Fabric não poderá determinar se as réplicas restantes (duas em cinco) têm dados suficientes para restaurar a partição. Nos casos em que o Service Fabric deteta perda de quorum, seu comportamento padrão é impedir gravações adicionais na partição, declarar perda de quorum e aguardar a restauração de um quórum de réplicas.

Determinar se ocorreu um desastre para um serviço com monitoração de estado e, em seguida, gerenciá-lo segue três estágios:

  1. Determinar se houve perda de quórum ou não.

    A perda de quórum é declarada quando a maioria das réplicas de um serviço com monitoração de estado está inativa ao mesmo tempo.

  2. Determinar se a perda de quórum é permanente ou não.

    Na maioria das vezes, as falhas são transitórias. Os processos são reiniciados, os nós são reiniciados, as máquinas virtuais são reiniciadas e as partições de rede são recuperadas. Às vezes, porém, as falhas são permanentes. Se as falhas são permanentes ou não, depende se o serviço stateful persiste seu estado ou se ele o mantém apenas na memória:

    • Para serviços sem estado persistente, uma falha de quórum ou mais de réplicas resulta imediatamente em perda permanente de quórum. Quando o Service Fabric deteta perda de quórum em um serviço não persistente com monitoração de estado, ele prossegue imediatamente para a etapa 3, declarando (potencial) perda de dados. Proceder à perda de dados faz sentido porque o Service Fabric sabe que não adianta esperar que as réplicas voltem. Mesmo que recuperem, os dados serão perdidos devido à natureza não persistente do serviço.
    • Para serviços persistentes com monitoração de estado, uma falha de quórum ou mais de réplicas faz com que o Service Fabric aguarde que as réplicas voltem e restaurem o quórum. Isso resulta em uma interrupção de serviço para qualquer gravação na partição afetada (ou "conjunto de réplicas") do serviço. No entanto, as leituras ainda podem ser possíveis com garantias de consistência reduzidas. A quantidade padrão de tempo que o Service Fabric aguarda que o quórum seja restaurado é infinita, porque prosseguir é um evento (potencial) de perda de dados e acarreta outros riscos. Isso significa que o Service Fabric não prosseguirá para a próxima etapa, a menos que um administrador tome medidas para declarar a perda de dados.
  3. Determinar se os dados são perdidos e restaurar a partir de backups.

    Se a perda de quórum tiver sido declarada (automaticamente ou por meio de ação administrativa), o Service Fabric e os serviços passarão a determinar se os dados foram realmente perdidos. Neste ponto, o Service Fabric também sabe que as outras réplicas não vão voltar. Essa foi a decisão tomada quando deixámos de esperar que a perda de quórum se resolvesse. O melhor procedimento para o serviço é geralmente congelar e aguardar uma intervenção administrativa específica.

    Quando o Service Fabric chama o OnDataLossAsync método, é sempre devido a suspeita de perda de dados. O Service Fabric garante que essa chamada seja entregue à melhor réplica restante. Esta é a réplica que fez mais progressos.

    A razão pela qual sempre dizemos que suspeitamos de perda de dados é que é possível que a réplica restante tenha o mesmo estado que a principal quando o quórum foi perdido. No entanto, sem esse estado para compará-lo, não há uma boa maneira de o Service Fabric ou os operadores saberem com certeza.

    Então, o que faz uma implementação típica do OnDataLossAsync método?

    1. A implementação registra que OnDataLossAsync foi acionada e dispara todos os alertas administrativos necessários.

    2. Normalmente, a implementação pausa e aguarda novas decisões e ações manuais a serem tomadas. Isso ocorre porque, mesmo que os backups estejam disponíveis, eles podem precisar ser preparados.

      Por exemplo, se dois serviços diferentes coordenarem informações, esses backups talvez precisem ser modificados para garantir que, após a restauração, as informações com as quais esses dois serviços se preocupam sejam consistentes.

    3. Muitas vezes há alguma outra telemetria ou exaustão do serviço. Esses metadados podem estar contidos em outros serviços ou em logs. Essas informações podem ser usadas conforme necessário para determinar se houve chamadas recebidas e processadas no primário que não estavam presentes no backup ou replicadas para essa réplica específica. Essas chamadas podem precisar ser repetidas ou adicionadas ao backup antes que a restauração seja viável.

    4. A implementação compara o estado da réplica restante com o contido em todos os backups disponíveis. Se você estiver usando coleções confiáveis do Service Fabric, há ferramentas e processos disponíveis para isso. O objetivo é ver se o estado dentro da réplica é suficiente e ver o que o backup pode estar faltando.

    5. Depois que a comparação for feita e depois que a restauração for concluída (se necessário), o código de serviço deve retornar true se alguma alteração de estado tiver sido feita. Se a réplica determinou que era a melhor cópia disponível do estado e não fez alterações, o código retornará false.

      Um valor true indica que quaisquer outras réplicas restantes podem agora ser inconsistentes com esta. Eles serão descartados e reconstruídos a partir desta réplica. Um valor false indica que nenhuma alteração de estado foi feita, para que as outras réplicas possam manter o que têm.

É extremamente importante que os autores de serviços pratiquem possíveis cenários de perda de dados e falhas antes que os serviços sejam implantados em produção. Para se proteger contra a possibilidade de perda de dados, é importante fazer backup periódico do estado de qualquer um dos seus serviços stateful para um armazenamento com redundância geográfica.

Você também deve garantir que você tenha a capacidade de restaurar o estado. Como os backups de muitos serviços diferentes são feitos em momentos diferentes, você precisa garantir que, após uma restauração, seus serviços tenham uma visão consistente uns dos outros.

Por exemplo, considere uma situação em que um serviço gera um número e o armazena e, em seguida, envia-o para outro serviço que também o armazena. Após uma restauração, você pode descobrir que o segundo serviço tem o número, mas o primeiro não, porque seu backup não incluiu essa operação.

Se você descobrir que as réplicas restantes são insuficientes para continuar em um cenário de perda de dados e não puder reconstruir o estado do serviço a partir de telemetria ou exaustão, a frequência dos backups determinará seu melhor RPO (Recovery Point Objetive, objetivo de ponto de recuperação) possível. O Service Fabric fornece muitas ferramentas para testar vários cenários de falha, incluindo quórum permanente e perda de dados que requer restauração a partir de um backup. Esses cenários são incluídos como parte das ferramentas de capacidade de teste no Service Fabric, gerenciadas pelo Serviço de Análise de Falhas. Para obter mais informações sobre essas ferramentas e padrões, consulte Introdução ao Serviço de Análise de Falhas.

Nota

Os serviços do sistema também podem sofrer perda de quórum. O impacto é específico do serviço em questão. Por exemplo, a perda de quórum no serviço de nomeação afeta a resolução de nomes, enquanto a perda de quórum no serviço Gerenciador de Failover bloqueia a criação de novos serviços e failovers.

Os serviços do sistema Service Fabric seguem o mesmo padrão dos seus serviços para gerenciamento de estado, mas não recomendamos que você tente movê-los da perda de quórum para uma possível perda de dados. Em vez disso, recomendamos que procure apoio para encontrar uma solução direcionada para a sua situação. Normalmente, é preferível simplesmente esperar até que as réplicas retornem.

Solução de problemas de perda de quórum

As réplicas podem estar inativas intermitentemente devido a uma falha transitória. Aguarde algum tempo enquanto o Service Fabric tenta exibi-los. Se as réplicas estiverem inativas por mais do que o esperado, siga estas ações de solução de problemas:

  • As réplicas podem estar falhando. Verifique os relatórios de integridade no nível da réplica e os logs do aplicativo. Colete despejos de memória e tome as ações necessárias para se recuperar.
  • O processo de réplica pode ter deixado de responder. Inspecione os logs do aplicativo para verificar isso. Colete despejos de processo e, em seguida, pare o processo que não responde. O Service Fabric criará um processo de substituição e tentará trazer a réplica de volta.
  • Os nós que hospedam as réplicas podem estar inativos. Reinicie a máquina virtual subjacente para trazer os nós para cima.

Às vezes, pode não ser possível recuperar réplicas. Por exemplo, as unidades falharam ou as máquinas fisicamente não estão respondendo. Nesses casos, o Service Fabric precisa ser instruído a não esperar pela recuperação da réplica.

Não use esses métodos se a perda potencial de dados for inaceitável para colocar o serviço on-line. Nesse caso, todos os esforços devem ser feitos para recuperar máquinas físicas.

As ações a seguir podem resultar em perda de dados. Verifique antes de segui-los.

Nota

Nunca é seguro usar esses métodos a não ser de forma direcionada contra partições específicas.

  • Use a Repair-ServiceFabricPartition -PartitionId API ou System.Fabric.FabricClient.ClusterManagementClient.RecoverPartitionAsync(Guid partitionId) . Esta API permite especificar o ID da partição para sair da perda de quórum e entrar em potencial perda de dados.
  • Se o cluster encontrar falhas frequentes que façam com que os serviços entrem em um estado de perda de quórum e a perda potencial de dados for aceitável, especificar um valor QuorumLossWaitDuration apropriado pode ajudar o serviço a se recuperar automaticamente. O Service Fabric aguardará o valor fornecido QuorumLossWaitDuration (o padrão é infinito) antes de executar a recuperação. Não recomendamos esse método porque ele pode causar perdas de dados inesperadas.

Disponibilidade do cluster do Service Fabric

Em geral, o cluster do Service Fabric é um ambiente altamente distribuído sem pontos únicos de falha. Uma falha de qualquer nó não causará problemas de disponibilidade ou confiabilidade para o cluster, principalmente porque os serviços do sistema Service Fabric seguem as mesmas diretrizes fornecidas anteriormente. Ou seja, eles sempre são executados com três ou mais réplicas por padrão, e os serviços do sistema que são sem estado são executados em todos os nós.

As camadas subjacentes de rede e deteção de falhas do Service Fabric são totalmente distribuídas. A maioria dos serviços do sistema pode ser reconstruída a partir de metadados no cluster ou saber como ressincronizar seu estado de outros lugares. A disponibilidade do cluster pode ficar comprometida se os serviços do sistema entrarem em situações de perda de quórum como as descritas anteriormente. Nesses casos, talvez não seja possível executar determinadas operações no cluster (como iniciar uma atualização ou implantar novos serviços), mas o cluster em si ainda está ativo.

Os serviços em um cluster em execução continuarão em execução nessas condições, a menos que exijam gravações nos serviços do sistema para continuar funcionando. Por exemplo, se o Gerenciador de Failover estiver com perda de quórum, todos os serviços continuarão a ser executados. Mas os serviços que falharem não poderão ser reiniciados automaticamente, porque isso requer o envolvimento do Gerenciador de Failover.

Falhas de um datacenter ou de uma região do Azure

Em casos raros, um datacenter físico pode ficar temporariamente indisponível devido à perda de energia ou conectividade de rede. Nesses casos, seus clusters e serviços do Service Fabric nesse datacenter ou região do Azure não estarão disponíveis. No entanto, os seus dados são preservados.

Para clusters em execução no Azure, você pode exibir atualizações sobre interrupções na página de status do Azure. No caso altamente improvável de que um datacenter físico seja parcial ou totalmente destruído, quaisquer clusters do Service Fabric hospedados lá, ou os serviços dentro deles, podem ser perdidos. Essa perda inclui qualquer estado sem backup fora desse datacenter ou região.

Existem várias estratégias diferentes para sobreviver à falha permanente ou sustentada de um único datacenter ou região:

  • Execute clusters separados do Service Fabric em várias dessas regiões e use algum mecanismo para failover e failback entre esses ambientes. Esse tipo de modelo ativo/ativo ou ativo/passivo de vários clusters requer gerenciamento adicional e código de operações. Esse modelo também requer a coordenação de backups dos serviços em um datacenter ou região para que estejam disponíveis em outros datacenters ou regiões quando um falhar.

  • Execute um único cluster do Service Fabric que abranja vários datacenters. A configuração mínima suportada para essa estratégia é de três datacenters. Para obter mais, consulte Implantar um cluster do Service Fabric em zonas de disponibilidade.

    Este modelo requer configuração adicional. No entanto, o benefício é que a falha de um datacenter é convertida de um desastre em uma falha normal. Essas falhas podem ser tratadas pelos mecanismos que funcionam para clusters dentro de uma única região. Domínios de falha, domínios de atualização e regras de posicionamento do Service Fabric garantem que as cargas de trabalho sejam distribuídas para que tolerem falhas normais.

    Para obter mais informações sobre políticas que podem ajudar a operar serviços nesse tipo de cluster, consulte Políticas de posicionamento para serviços do Service Fabric.

  • Execute um único cluster do Service Fabric que abranja várias regiões usando o modelo Autônomo. O número recomendado de regiões é de três. Consulte Criar um cluster autônomo para obter detalhes sobre a configuração autônoma do Service Fabric.

Falhas aleatórias que levam a falhas de cluster

O Service Fabric tem o conceito de nós semente. Estes são nós que mantêm a disponibilidade do cluster subjacente.

Os nós de propagação ajudam a garantir que o cluster permaneça ativo, estabelecendo concessões com outros nós e servindo como critérios de desempate durante certos tipos de falhas. Se falhas aleatórias removerem a maioria dos nós de propagação no cluster e eles não forem trazidos de volta rapidamente, o cluster será desligado automaticamente. Em seguida, o cluster falha.

No Azure, o Provedor de Recursos do Service Fabric gerencia as configurações de cluster do Service Fabric. Por padrão, o Provedor de Recursos distribui nós de propagação entre domínios de falha e atualização para o tipo de nó primário. Se o tipo de nó primário estiver marcado como durabilidade Prata ou Ouro, quando você remover um nó semente (dimensionando o tipo de nó primário ou removendo-o manualmente), o cluster tentará promover outro nó não semente da capacidade disponível do tipo de nó primário. Essa tentativa falhará se você tiver menos capacidade disponível do que o nível de confiabilidade do cluster requer para o tipo de nó principal.

Nos clusters autônomos do Service Fabric e no Azure, o tipo de nó primário é aquele que executa as sementes. Ao definir um tipo de nó primário, o Service Fabric aproveitará automaticamente o número de nós fornecidos, criando até nove nós semente e sete réplicas de cada serviço do sistema. Se um conjunto de falhas aleatórias eliminar a maioria dessas réplicas simultaneamente, os serviços do sistema entrarão em perda de quórum. Se a maioria dos nós semente for perdida, o cluster será desligado logo depois.

Próximos passos