iGRPIGRP 3.0Documentation

Instalação de produção

Instalar o igrp-stack sem segredos no git — por Sealed Secrets (recomendado) ou por Secrets criados directamente no cluster.

O values.yaml do chart é o perfil de teste: instala sem passos manuais, mas traz passwords públicas. Em produção nenhum valor sensível pode ficar em ficheiros versionados. Há dois caminhos, e ambos partem do mesmo princípio — aplicar sempre values.prod.yaml por cima do values.yaml, e o ficheiro local de segredos por último.

CaminhoQuando usar
Sealed SecretsRecomendado. Os segredos ficam cifrados em manifests versionáveis; só o controller do cluster os decifra.
Secrets directosQuando não há controller de Sealed Secrets. Os Secrets criam-se à mão no cluster e nunca passam pelo git.

Ordem dos ficheiros de values

--values values.yaml --values values.prod.yaml --values <ficheiro-local>, sempre por esta ordem. O values.prod.yaml esvazia as passwords de teste e sobe o PostgreSQL para 3 instâncias; o ficheiro local sobrepõe-se a tudo.


Sealed Secrets

Mantém as credenciais cifradas em manifests SealedSecret. Só o controller instalado no cluster consegue criar os Kubernetes Secrets reais.

1. Controller e namespace

export NS=igrp-prod
kubectl create namespace "$NS" --dry-run=client -o yaml | kubectl apply -f -
helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets
helm upgrade --install sealed-secrets sealed-secrets/sealed-secrets \
  -n kube-system --set fullnameOverride=sealed-secrets
kubectl get secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key -o yaml \
  > sealed-secrets-key.backup.yaml

Guarda o backup da chave fora do Git

Perder a chave do controller impede a recuperação de todos os dados cifrados existentes. Não há segunda via.

2. Gerar e cifrar os Secrets

export AM_DB_PASSWORD="$(openssl rand -base64 32)"
export KC_DB_PASSWORD="$(openssl rand -base64 32)"
export PM_DB_PASSWORD="$(openssl rand -base64 32)"
export PS_DB_PASSWORD="$(openssl rand -base64 32)"
# --- só com o módulo de notificações activo ---
export NOTIF_DB_PASSWORD="$(openssl rand -base64 32)"
export TEMPORAL_DB_PASSWORD="$(openssl rand -base64 32)"
export OAUTH_CLIENT_SECRET="$(openssl rand -hex 32)"
export MINIO_ROOT_PASSWORD="$(openssl rand -base64 32)"
export REDIS_PASSWORD="$(openssl rand -base64 32)"
export KEYCLOAK_ADMIN_PASSWORD="$(openssl rand -base64 32)"
export NEXTAUTH_SECRET="$(openssl rand -base64 32)"
export SMTP_PASSWORD='<password-ou-token-fornecido-pelo-SMTP>'

./scripts/bootstrap-secrets.sh -n "$NS" --seal --out sealed-secrets/
kubectl apply -f sealed-secrets/
kubectl get sealedsecrets,secrets -n "$NS"

Versiona apenas os ficheiros cifrados de sealed-secrets/. Os valores originais vão para o gestor de passwords.

3. SealedSecret das chaves RSA

workdir=$(mktemp -d)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out "$workdir/private.pem"
openssl rsa -pubout -in "$workdir/private.pem" -out "$workdir/public.pem"
kubectl create secret generic igrp-access-management-oauth-keys -n "$NS" \
  --from-file=private.pem="$workdir/private.pem" --from-file=public.pem="$workdir/public.pem" \
  --dry-run=client -o yaml |
  kubeseal --controller-name sealed-secrets --controller-namespace kube-system --format yaml \
  > sealed-secrets/igrp-access-management-oauth-keys.yaml
kubectl apply -f sealed-secrets/igrp-access-management-oauth-keys.yaml
rm -rf "$workdir"

4. Deploy

helm dependency build .
helm upgrade --install igrp-stack . -n "$NS" \
  --values values.yaml --values values.prod.yaml \
  --values values.prod-secrets.local.yaml \
  --wait --timeout 15m
kubectl get sealedsecrets,secrets,pods,jobs -n "$NS"

Em modo Autentika, acrescenta --values values.autentika.prod.yaml antes do ficheiro local, mais o --set dos dois campos da Autentika (ver o cabeçalho desse ficheiro).


Secrets directos

Cria-se tudo à mão no cluster. Os valores nunca chegam ao git.

1. Preparação

export NS=igrp-prod
kubectl create namespace "$NS" --dry-run=client -o yaml | kubectl apply -f -

export AM_DB_PASSWORD="$(openssl rand -base64 32)"
export KC_DB_PASSWORD="$(openssl rand -base64 32)"
export PM_DB_PASSWORD="$(openssl rand -base64 32)"
export PS_DB_PASSWORD="$(openssl rand -base64 32)"
export OAUTH_CLIENT_SECRET="$(openssl rand -hex 32)"
export MINIO_ROOT_PASSWORD="$(openssl rand -base64 32)"
export REDIS_PASSWORD="$(openssl rand -base64 32)"
export KEYCLOAK_ADMIN_PASSWORD="$(openssl rand -base64 32)"
export NEXTAUTH_SECRET="$(openssl rand -base64 32)"
export SMTP_PASSWORD='<password-ou-token-fornecido-pelo-SMTP>'
export KEYCLOAK_AM_CLIENT_SECRET="$(openssl rand -hex 32)"

Guarda estes valores no gestor de passwords antes de continuar. O cluster deve ter encryption at rest para Secrets/etcd e RBAC restrito no namespace.

2. Secrets da plataforma

db_secret() {
  kubectl create secret generic "$1" -n "$NS" --type=kubernetes.io/basic-auth \
    --from-literal=username="$2" --from-literal=password="$3" \
    --dry-run=client -o yaml |
    kubectl label --local -f - cnpg.io/reload=true --dry-run=client -o yaml |
    kubectl apply -f -
}
db_secret igrp-access-management-db-user access_management_user "$AM_DB_PASSWORD"
db_secret igrp-keycloak-db-user keycloak_user "$KC_DB_PASSWORD"
db_secret igrp-process-management-db-user process_management_user "$PM_DB_PASSWORD"
db_secret igrp-process-studio-db-user process_studio_user "$PS_DB_PASSWORD"
# --- só com o módulo de notificações activo ---
db_secret igrp-notification-db-user notification_user "$NOTIF_DB_PASSWORD"
db_secret igrp-notification-temporal-db-user temporaldb_user "$TEMPORAL_DB_PASSWORD"

kubectl create secret generic igrp-access-management-secrets -n "$NS" \
  --from-literal=smtp-password="$SMTP_PASSWORD" --dry-run=client -o yaml | kubectl apply -f -
kubectl create secret generic igrp-access-management-oauth-client -n "$NS" \
  --from-literal=client-id=igrp-access-management --from-literal=client-secret="$OAUTH_CLIENT_SECRET" \
  --dry-run=client -o yaml | kubectl apply -f -
kubectl create secret generic igrp-minio-creds -n "$NS" \
  --from-literal=MINIO_ROOT_USER=admin --from-literal=MINIO_ROOT_PASSWORD="$MINIO_ROOT_PASSWORD" \
  --dry-run=client -o yaml | kubectl apply -f -
kubectl create secret generic igrp-app-center-nextauth -n "$NS" \
  --from-literal=nextauth-secret="$NEXTAUTH_SECRET" --dry-run=client -o yaml | kubectl apply -f -
kubectl create secret generic igrp-redis-auth -n "$NS" \
  --from-literal=redis-password="$REDIS_PASSWORD" --dry-run=client -o yaml | kubectl apply -f -
kubectl create secret generic igrp-keycloak-admin -n "$NS" \
  --from-literal=admin-password="$KEYCLOAK_ADMIN_PASSWORD" --dry-run=client -o yaml | kubectl apply -f -

Módulo de notificações

Vem desligado no values.prod.yaml. Com os Secrets pré-criados (dbUsers.createSecrets: false, este guia) a validação validate-db-users não corre, e os dois db_secret de notificações só são precisos se o módulo for activado.

Se for o chart a criar os Secrets (createSecrets: true), as entradas notification e notificationTemporal herdadas do values.yaml exigem password por --set mesmo com o módulo desligado — um null não as remove.

Os Secrets igrp-notification-&#123;api,ui&#125;-oauth-client não se criam aqui: são gerados pelos Jobs m2m.autoRegister no primeiro deploy, porque o clientSecret só é devolvido na criação do cliente no Access Management.

A Web UI do Temporal não tem autenticação

Em produção mantém igrp-notification-temporal.webIngress.enabled: false.

3. Chaves RSA e realm Keycloak

./scripts/generate-oauth-keys.sh "$NS" igrp-access-management-oauth-keys

No ficheiro local de produção — não versionado, *.local.yaml já está no .gitignore — desliga-se a criação de Secrets pelo chart, que passa apenas a referenciar os Secrets criados acima:

# values.prod-secrets.local.yaml
igrp-pg-cluster:
  dbUsers:
    createSecrets: false
igrp-access-management:
  secret:
    create: false
  oauthClient:
    create: false
igrp-minio:
  credsSecret:
    create: false
igrp-app-center:
  nextauth:
    create: false
    existingSecret: igrp-app-center-nextauth
igrp-redis:
  authSecret:
    create: false
igrp-keycloak:
  keycloak:
    auth:
      existingSecret: igrp-keycloak-admin
  igrp:
    clientSecrets:
      accessManagement: "<valor de KEYCLOAK_AM_CLIENT_SECRET>"

Porque é que o segredo do Keycloak é a excepção

Entra no realm_config.json como ConfigMap durante o primeiro import do realm. Um Kubernetes Secret não consegue fornecer esse valor ao template Helm, por isso este único segredo tem de estar no ficheiro local de values.

4. Deploy e validação

helm dependency build .
helm upgrade --install igrp-stack . -n "$NS" \
  --values values.yaml --values values.prod.yaml \
  --values values.prod-secrets.local.yaml \
  --wait --timeout 15m
kubectl get pods,jobs,secrets -n "$NS"
kubectl get cluster,database -n "$NS"

Os Jobs do chart criam automaticamente os Secrets OAuth dos quatro serviços igrp-process-* quando m2m.autoRegister.enabled: true. Não os cries antes.

How is this guide?

Última atualização: