Última atualização: 23 de abril de 2026

Conduit

O Conduit é uma plataforma open-source (Apache 2.0) de streaming de dados nativa em Go, mantida pela Meroxa e pela comunidade ConduitIO. Cada deploy no Guara Cloud executa um único binário /app/conduit rodando exatamente um pipeline: um connector de origem, processadores in-line opcionais e um connector de destino, tudo descrito em um único arquivo pipeline.yml.

Em relação à alternativa baseada em JVM, o Conduit troca um pouco de profundidade em CDC puro por um footprint muito menor e uma superfície de connectors mais ampla: subjects NATS, tópicos Kafka e endpoints HTTP são origens e destinos de primeira classe, lado a lado com os bancos usuais. O estado fica em um BadgerDB local em /app/conduit.db sobre um PVC Longhorn, de modo que restarts retomam do último ponto comitado.

Quando usar o Conduit

O Conduit é a escolha certa quando:

  • Você quer um runtime Go leve — sem heap Java para dimensionar, sem custo de warm-up do Quarkus. O Conduit roda tranquilamente no plano Hobby.
  • Sua origem ou destino não é um banco: um subject NATS, um endpoint HTTP ou um segundo banco (Postgres-para-MySQL, Postgres-para-Postgres).
  • Você quer remoção de PII in-line via o processor built-in field.exclude — remover colunas sensíveis antes que elas cheguem ao destino, de forma declarativa e sem escrever código.
  • Você prefere um pipeline declarativo em YAML, legível de ponta a ponta num único arquivo.

Use o Debezium no lugar quando precisar de CDC consagrado contra um banco OLTP de produção, ou quando a origem for MongoDB (o Conduit v1 não traz connector de origem para MongoDB — veja a seção de troubleshooting).

Walkthrough de deploy

  1. Provisione a origem e o destino antes (apenas no modo sibling). Num fluxo típico Postgres-para-NATS, implante um serviço PostgreSQL pelo catálogo e um serviço NATS pelo catálogo e espere os dois ficarem Running. Origens e destinos externos não precisam deste passo.
  2. Abra o wizard do catálogo. No dashboard do projeto, clique em Novo Serviço, selecione a aba Catálogo de Serviços e escolha Conduit.
  3. Escolha a versão. Duas tags estão disponíveis: v0.14.0 (padrão) e v0.13.6.
  4. Configure a origem.
    • sourceKindPostgreSQL, MySQL, NATS JetStream ou HTTP.
    • sourceModeServiço sibling do catálogo ou URL externa.
    • sourceServiceSlug — no modo sibling, selecione qualquer serviço Postgres/MySQL/NATS do projeto.
    • sourceExternalUrl — no modo externo, cole a URL completa. PostgreSQL: postgresql://host:5432/db. NATS: nats://user:senha@host:4222 (o connector NATS do Conduit lê a autenticação da própria URL — veja a seção de troubleshooting).
    • tableFilter — opcional. Para origens de banco, lista separada por vírgulas no formato schema.tabela. Para NATS, o padrão do subject; para HTTP, deixe em branco.
    • topicPrefix — opcional. Prefixo aplicado ao tópico ou subject emitido no destino.
  5. Configure o destino.
    • sinkKindNATS JetStream, Apache Kafka, PostgreSQL, MySQL ou Webhook HTTP.
    • sinkModeSibling ou Externo.
    • sinkServiceSlug — no modo sibling, o picker lista todos os serviços de catálogo compatíveis.
    • sinkExternalUrl — no modo externo, a URL completa.
  6. Formato do pipeline e processors.
    • pipelineName — opcional. Nome legível do pipeline; quando em branco, usa o slug do serviço.
    • processorPiiFields — opcional. Lista separada por vírgulas de referências dot-path a remover em voo via o processor field.exclude. Os caminhos precisam começar com ponto e apontar para dentro do envelope do registro OpenCDC — para origens de banco, isso é .Payload.After.<coluna>. Exemplo: .Payload.After.email,.Payload.After.cpf remove essas duas colunas de cada registro antes de chegar ao destino.
  7. Credenciais externas. Quando um lado é externo, preencha sourceExternalUsername, sourceExternalPassword, sinkExternalUsername, sinkExternalPassword. Elas caem no Secret criptografado do serviço e viram SOURCE_EXTERNAL_USERNAME, etc., dentro do pod.
  8. Deploy. Clique em Deploy. O primeiro boot demora um pouco mais quando é preciso um connector standalone (MySQL, NATS JetStream ou HTTP) — um initContainer baixa o binário pinado do GitHub Releases antes do Conduit subir. Restarts subsequentes reaproveitam o binário já baixado no PVC.

Aba Insights

A aba Insights é alimentada pelo exporter Prometheus nativo do Conduit na porta HTTP — sem sidecar e sem adaptador de scrape extra. Os painéis estão agrupados em duas seções:

Throughput do Pipeline

  • Throughput — área, registros por segundo em todos os conectores (rate(conduit_connector_execution_duration_seconds_count[1m])). A linha de base depende do volume da origem; o que você olha é o formato.
  • Conectores Ativos — gauge, número de conectores atualmente vivos (tipicamente 2: origem + destino). Cair para 1 ou 0 indica connector down.
  • Duração p95 do Processador — sparkline, latência p95 adicionada pelos processors in-line. O field.exclude costuma ficar bem abaixo de 1 ms; picos sugerem payloads inchados.

Saúde do Pipeline

  • Bytes na DLQ — área empilhada, total de bytes gravados na dead-letter queue (conduit_dlq_bytes_sum). Qualquer crescimento indica registros falhando ao gravar no destino e sendo registrados no log.
  • Duração p95 do Conector — área, latência p95 de leitura e gravação do connector. Picos sustentados no connector de origem apontam para origem lenta; picos no de destino indicam backpressure do destino.
  • Status do Pipeline — indicador de status, saúde binária do pipeline (1 = rodando, 0 = parado ou degradado).

Troubleshooting

Pipeline travado com crescimento de DLQ

O Conduit roteia registros que falham na gravação para uma DLQ built-in do tipo log. O painel Bytes na DLQ da aba Insights mostra se o crescimento está acontecendo; os logs do pod (filtre por log.format=json) trazem o motivo completo de cada falha.

Causas comuns:

  • O schema do destino não bate com o da origem (por exemplo, uma coluna esperada não existe na tabela Postgres de destino). Corrija o schema do destino e reinicie o pipeline — registros já na DLQ não são reprocessados automaticamente.
  • Um destino externo passa a rejeitar a autenticação porque a credencial foi rotacionada. Atualize as credenciais externas pelo wizard do catálogo; o Conduit as relê no próximo restart do pod.

Connector standalone falha ao subir

Os connectors de MySQL, NATS JetStream e HTTP são baixados por um initContainer no primeiro boot. Se o init falha, o kubectl describe pod (ou a aba de logs do pod no Guara Cloud) mostra um erro claro de download failed ou permission denied. Três causas possíveis:

  • Disponibilidade arm64. O Guara Cloud roda em arm64 (OCI Ampere A1). Toda release de connector pinada precisa publicar binário arm64; todas as versões suportadas o fazem.
  • Network policy. O pod precisa de egress para github.com na porta 443 para o download. Projetos em rede privada que bloqueiam egress externo precisam usar apenas connectors built-in (PostgreSQL ou Kafka).
  • Mirror upstream mudou. Se a release do connector foi retirada upstream, o initContainer retorna 404. Faça redeploy com uma versão anterior do Conduit ou abra um chamado de suporte.

Replication slot do Postgres não foi removido após deletar o serviço

Apagar um serviço Conduit com origem PostgreSQL destrói o pod e seu PVC; no caminho feliz, o replication slot e a publicação na origem são removidos automaticamente durante o shutdown. Se o pod foi terminado antes do cleanup concluir, o slot e a publicação podem sobreviver. Slots retidos seguram arquivos WAL para sempre, o que lota o disco da origem.

O Conduit nomeia o slot guara_slot_<service-slug> e a publicação guara_pub_<service-slug>. Como identificadores Postgres não aceitam hífen, os - do slug do serviço são convertidos para _ no momento de carregar o pipeline. Rode, no banco de origem:

-- Troque os hífens do slug do serviço por underscores (ex.: my-pipe → my_pipe).
SELECT pg_drop_replication_slot('guara_slot_SEU_SERVICE_SLUG');
DROP PUBLICATION IF EXISTS guara_pub_SEU_SERVICE_SLUG;

Liste os slots ativos com SELECT slot_name, active FROM pg_replication_slots; se precisar confirmar o nome exato.

MongoDB como origem não está disponível

O Conduit v1 no Guara, por escolha, não oferece origem MongoDB. O formato de configuração do conduit-connector-mongo upstream diverge o bastante dos outros connectors para considerarmos alto demais o risco de erro de configuração no load do pipeline para a v1. Se você precisa de CDC de MongoDB, implante um serviço Debezium no lugar — ele já entrega um connector de MongoDB bem testado hoje.

URLs externas de NATS precisam embutir as credenciais

O connector NATS do Conduit lê a autenticação da própria URL, não de campos separados de usuário e senha:

nats://usuario:senha@host:4222

Serviços NATS sibling do catálogo já injetam uma URL com credenciais embutidas via credential bridge. Ao apontar para um cluster NATS externo, pré-codifique usuário e senha na URL que você cola em sourceExternalUrl ou sinkExternalUrl. Os campos sourceExternalUsername / sourceExternalPassword são ignorados pelo connector NATS e podem ser deixados em branco.

O processor silenciosamente remove o campo errado

O processor field.exclude remove campos do registro através de uma referência dot-path exata. Os caminhos precisam começar com ponto e apontar para dentro do envelope do registro OpenCDC — para origens de banco, quase sempre .Payload.After.<coluna>. Exemplo:

.Payload.After.email,.Payload.After.cpf

Pegadinhas comuns:

  • O caminho sempre começa com .; Payload.After.email (sem ponto inicial) não casa com nada.
  • Caminhos aninhados seguem a mesma sintaxe de ponto (.Payload.After.metadata.pii), não JSON pointer.
  • Nomes de campo são case-sensitive.
  • Nomes de colunas PostgreSQL são convertidos para minúsculas por padrão; um Email no seu schema chega como email no processor.

Confirme pelos logs do pod com log.level=debug (temporariamente, via redeploy) para ver o schema de cada registro antes e depois do processamento.

Recursos upstream

Próximos passos