Flink

Senior

Como faço deploy de um cluster Flink no Kubernetes usando a integração nativa?

O Flink não só roda dentro do Kubernetes - com a integração nativa, ele fala diretamente com a API do Kubernetes para gerenciar seus próprios pods de TaskManager. Isso é um deploy significativamente diferente de "Flink em um container".

Ler em:
Integração nativa Standalone Deployment Kubernetes Operator
Aproximadamente como essas três abordagens se comparam em quanta consciência de Kubernetes o próprio Flink tem - não um levantamento medido.

Existem duas formas reais de rodar Flink no Kubernetes: o deploy standalone (o Flink não faz ideia de que está no K8s - você gerencia réplicas como qualquer outro Deployment sem estado) e a integração nativa (o próprio ResourceManager do Flink fala com a API do Kubernetes para solicitar e liberar pods de TaskManager conforme os jobs precisam).

O que "nativa" realmente significa aqui

Com o deploy standalone, os TaskManagers são só pods em um Deployment do Kubernetes - o Kubernetes os reinicia se morrerem, mas o próprio Flink não tem como pedir mais ou menos deles com base na demanda do job. Com a integração nativa, o ResourceManager do Flink chama a API do Kubernetes diretamente (criar/deletar pods) para escalar TaskManagers de acordo com o que um job realmente precisa - mais próximo em espírito de como a integração do Flink com YARN sempre funcionou, só falando com um scheduler diferente.

# inicia um cluster que gerencia seus próprios pods de TaskManager ./bin/flink run-application \ --target kubernetes-application \ -Dkubernetes.cluster-id=my-flink-app \ -Dkubernetes.container.image=my-flink:1.20 \ local:///opt/flink/usrlib/job.jar

O RBAC que isso realmente exige

Como o Flink está criando e deletando pods sozinho, sua service account precisa de permissões reais no namespace onde roda - não só o acesso somente-leitura que um pod de aplicação normal teria:

# RBAC mínimo viável para a integração nativa, um namespace rules: - apiGroups: [""] resources: ["pods", "services", "configmaps"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

Essa é uma superfície de permissões significativamente maior do que a maioria das cargas de trabalho de aplicação precisa, e vale a pena sinalizar a quem for dono da política de segurança do cluster antes que apareça como surpresa em uma revisão - é inerente a como a integração nativa funciona, não uma configuração errada.

Onde isso ainda deixa uma escolha

O Flink Kubernetes Operator (um projeto separado, mais novo) fica em cima de qualquer um dos modos de deploy e adiciona gerenciamento de ciclo de vida nativo do Kubernetes - fazer kubectl apply de um custom resource FlinkDeployment em vez de rodar flink run-application manualmente, com o operator cuidando de upgrades, redeploys baseados em savepoint, e reconciliação. Não é tanto um terceiro modo de deploy quanto uma camada de gerenciamento - vale a pena adotar quando você tem mais que um par de jobs Flink para operar, menos claramente valendo a pena como peça móvel extra para um único job.

Fora do escopo do opti-pipe: o motor de regras lê quaisquer métricas que um job Flink rodando ou concluído exporte - não importa se os TaskManagers daquele job foram provisionados pela integração nativa, um Deployment standalone, ou o Kubernetes Operator, já que nada disso muda o que as métricas significam.

Veja como isso fica no seu próprio pipeline.

Envie um event log real do Spark, um run_results.json do dbt ou uma exportação de métricas do Flink e receba recomendações concretas, para aprovar antes de aplicar - não mais uma regra geral.