# Deployment com Kubernetes (Helm)

Guia para deploy do Monetarie PIX em qualquer cluster Kubernetes usando o Helm chart oficial. Para guias especificos de provedores cloud, consulte as paginas dedicadas (AWS, GCP, Azure, OCI).

## Pre-requisitos

- Cluster Kubernetes 1.25+ operacional
- Helm 3.14+ instalado e configurado
- kubectl configurado com acesso ao cluster
- PostgreSQL 16 acessivel pelo cluster
- Redis 7 acessivel pelo cluster
- NATS 2.10 com JetStream acessivel pelo cluster
- Registro de imagens Docker com as imagens Monetarie PIX

Verifique os pre-requisitos:

```bash
kubectl version --client
# Esperado: Client Version: v1.28.x ou superior

helm version
# Esperado: version.BuildInfo{Version:"v3.14.x"...}

kubectl cluster-info
# Esperado: Kubernetes control plane is running at https://...
```

## Estrutura do Helm Chart

```
deploy/kubernetes/helm/pix/
├── Chart.yaml              # monetarie-pix v1.0.0
├── values.yaml             # Valores padrao
├── values-aws.yaml         # Override para AWS (EKS)
├── values-gcp.yaml         # Override para GCP (GKE)
├── values-azure.yaml       # Override para Azure (AKS)
├── values-oci.yaml         # Override para OCI (OKE)
├── values.schema.json      # Schema de validacao
└── templates/
    ├── backend-deployment.yaml   # Backend pods (2 replicas padrao)
    ├── backend-service.yaml      # ClusterIP :4003
    ├── admin-deployment.yaml     # Admin pods (2 replicas padrao)
    ├── admin-service.yaml        # ClusterIP :80
    ├── ingress.yaml              # Ingress com TLS
    ├── pdb.yaml                  # PodDisruptionBudget
    ├── networkpolicy.yaml        # NetworkPolicy granular
    ├── serviceaccount.yaml       # ServiceAccount
    ├── _helpers.tpl              # Template helpers
    └── NOTES.txt                 # Mensagem pos-instalacao
```

## Passo 1: Criar Namespace

```bash
kubectl create namespace pix
```

Saida esperada:
```
namespace/pix created
```

## Passo 2: Criar Secrets

Crie os Kubernetes Secrets com as credenciais do banco de dados, chaves JWT e secret key base.

### Secret de Banco de Dados

```bash
kubectl create secret generic db-credentials \
  --namespace pix \
  --from-literal=database-url="ecto://postgres:<SENHA>@<DB_HOST>:5432/monetarie"
```

::: warning CARACTERES ESPECIAIS
Se a senha contiver caracteres especiais, use URL-encoding: `/` --> `%2F`, `=` --> `%3D`, `@` --> `%40`.
:::

### Secret do PIX

```bash
kubectl create secret generic pix-secrets \
  --namespace pix \
  --from-literal=secret-key-base="$(openssl rand -base64 64 | tr -d '\n')"
```

### Secret JWT Compartilhado (Core Banking)

```bash
kubectl create secret generic monetarie-shared-jwt-secret \
  --namespace pix \
  --from-literal=secret="<GUARDIAN_SECRET_KEY_DO_CORE>"
```

### Verificar Secrets

```bash
kubectl get secrets -n pix
```

Saida esperada:
```
NAME                       TYPE     DATA   AGE
db-credentials             Opaque   1      10s
pix-secrets                Opaque   1      8s
monetarie-shared-jwt-secret   Opaque   1      5s
```

## Passo 3: Preparar Values

Crie um arquivo `values-custom.yaml` com as configuracoes especificas do seu ambiente:

```yaml
# values-custom.yaml
backend:
  replicaCount: 2
  image:
    repository: <SEU_REGISTRO>/pix-backend
    tag: latest

  env:
    PHX_HOST: pixapi.seudominio.com.br
    POOL_SIZE: "50"
    NATS_ENABLED: "true"
    BACEN_ENABLED: "false"
    SIMULATOR_ENABLED: "false"

admin:
  replicaCount: 2
  image:
    repository: <SEU_REGISTRO>/pix-admin
    tag: latest

database:
  poolSize: 50
  ssl: true

redis:
  host: "<REDIS_HOST>"
  port: 6379

nats:
  enabled: true
  host: "<NATS_HOST>"
  port: 4222
  cluster:
    - "<NATS_NODE_1>:4222"
    - "<NATS_NODE_2>:4222"
    - "<NATS_NODE_3>:4222"

ingress:
  enabled: true
  className: ""  # Ajustar conforme seu ingress controller
  hosts:
    backend:
      - host: pixapi.seudominio.com.br
        paths:
          - path: /
            pathType: Prefix
    admin:
      - host: pixadmin.seudominio.com.br
        paths:
          - path: /
            pathType: Prefix
  tls:
    - secretName: pix-tls
      hosts:
        - pixapi.seudominio.com.br
        - pixadmin.seudominio.com.br

auth:
  rateLimit:
    mode: "strict"
    bypassAuth: false
```

## Passo 4: Instalar com Helm

```bash
helm install monetarie-pix deploy/kubernetes/helm/pix \
  --namespace pix \
  -f values-custom.yaml
```

Saida esperada:
```
NAME: monetarie-pix
LAST DEPLOYED: ...
NAMESPACE: pix
STATUS: deployed
REVISION: 1

NOTES:
Monetarie PIX has been deployed successfully!

Backend API: https://pixapi.seudominio.com.br
Admin Portal: https://pixadmin.seudominio.com.br

To check the status:
  kubectl get pods -n pix
```

## Passo 5: Verificar Deployment

```bash
# Verificar pods
kubectl get pods -n pix
```

Saida esperada:
```
NAME                            READY   STATUS    RESTARTS   AGE
monetarie-pix-backend-xxxxx-yyy    1/1     Running   0          2m
monetarie-pix-backend-xxxxx-zzz    1/1     Running   0          2m
monetarie-pix-admin-xxxxx-aaa      1/1     Running   0          2m
monetarie-pix-admin-xxxxx-bbb      1/1     Running   0          2m
```

```bash
# Verificar services
kubectl get svc -n pix
```

Saida esperada:
```
NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
monetarie-pix-backend   ClusterIP   10.x.x.x     <none>        4003/TCP   2m
monetarie-pix-admin     ClusterIP   10.x.x.x     <none>        80/TCP     2m
```

```bash
# Verificar ingress
kubectl get ingress -n pix
```

## Passo 6: Executar Migrations

```bash
kubectl exec -n pix deployment/monetarie-pix-backend -- \
  bin/monetarie_pix eval "Shared.Release.migrate()"
```

Saida esperada:
```
== Running migrations ==
== Migrated 20260201000001 in 0.1s ==
...
== Migrated 20260210000001 in 0.2s ==
Migrations complete.
```

## Passo 7: Popular Seeds

```bash
kubectl exec -n pix deployment/monetarie-pix-backend -- \
  bin/monetarie_pix eval "Shared.Release.seed()"
```

## Passo 8: Verificar Saude

```bash
# Port-forward para testar localmente
kubectl port-forward -n pix svc/monetarie-pix-backend 4003:4003 &

# Health check
curl -s http://localhost:4003/health
# Esperado: {"status":"ok"}

# Metricas
curl -s http://localhost:4003/metrics | head -5
```

## Ingress

### Configuracao com Traefik

```yaml
ingress:
  enabled: true
  className: ""
  annotations:
    kubernetes.io/ingress.class: "traefik"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
```

### Configuracao com nginx Ingress Controller

```yaml
ingress:
  enabled: true
  className: nginx
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    nginx.ingress.kubernetes.io/websocket-services: "monetarie-pix-backend"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
```

### TLS com cert-manager

Se voce utiliza cert-manager, o certificado sera provisionado automaticamente:

```bash
# Verificar certificado
kubectl get certificate -n pix
```

Saida esperada:
```
NAME      READY   SECRET    AGE
pix-tls   True    pix-tls   5m
```

## HPA (Horizontal Pod Autoscaler)

Habilite o auto-scaling no `values-custom.yaml`:

```yaml
autoscaling:
  backend:
    enabled: true
    minReplicas: 2
    maxReplicas: 10
    targetCPUUtilizationPercentage: 70
    targetMemoryUtilizationPercentage: 80

  admin:
    enabled: true
    minReplicas: 2
    maxReplicas: 5
    targetCPUUtilizationPercentage: 70
```

Verifique o HPA:

```bash
kubectl get hpa -n pix
```

Saida esperada:
```
NAME                 REFERENCE                   TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
monetarie-pix-backend   Deployment/monetarie-pix-...   25%/70%   2         10        2          5m
monetarie-pix-admin     Deployment/monetarie-pix-...   10%/70%   2         5         2          5m
```

## PodDisruptionBudget

O chart inclui PDB habilitado por padrao para garantir disponibilidade durante manutencao:

```yaml
backend:
  podDisruptionBudget:
    enabled: true
    minAvailable: 1
```

```bash
kubectl get pdb -n pix
```

Saida esperada:
```
NAME                 MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
monetarie-pix-backend   1               N/A               1                     5m
```

## NetworkPolicy

O chart inclui NetworkPolicy granular:

```yaml
networkPolicy:
  enabled: true
  ingressController:
    podSelector:
      matchLabels:
        app.kubernetes.io/name: traefik  # Ajustar conforme seu ingress
```

A NetworkPolicy permite:
- Ingress do ingress controller para backend (porta 4003) e admin (porta 80)
- Egress do backend para PostgreSQL (5432), Redis (6379), NATS (4222)
- Comunicacao interna entre pods do namespace `pix`

```bash
kubectl get networkpolicy -n pix
```

## Upgrade

### Atualizar Versao

```bash
# Atualizar imagem
helm upgrade monetarie-pix deploy/kubernetes/helm/pix \
  --namespace pix \
  -f values-custom.yaml \
  --set backend.image.tag=v1.1.0

# Executar migrations apos upgrade
kubectl exec -n pix deployment/monetarie-pix-backend -- \
  bin/monetarie_pix eval "Shared.Release.migrate()"
```

### Verificar Historico

```bash
helm history monetarie-pix -n pix
```

### Rollback

```bash
# Rollback para revisao anterior
helm rollback monetarie-pix 1 -n pix

# Verificar status
kubectl rollout status deployment/monetarie-pix-backend -n pix
```

## Desinstalacao

```bash
helm uninstall monetarie-pix -n pix

# Remover secrets (se desejar)
kubectl delete secret db-credentials pix-secrets monetarie-shared-jwt-secret -n pix

# Remover namespace (se desejar)
kubectl delete namespace pix
```

## Resultado Esperado

Ao final deste guia, voce tera:

- Monetarie PIX rodando em Kubernetes com 2+ replicas do backend e admin
- Secrets configurados para banco de dados, JWT e chave secreta
- Ingress com TLS configurado para acesso externo
- PodDisruptionBudget garantindo disponibilidade durante manutencao
- NetworkPolicy restringindo trafego de rede
- Capacidade de escalar, atualizar e fazer rollback via Helm
