Instalar¶
Esta guía instala kubelatch en un cluster de gestión con su chart de Helm, con Postgres, TLS, la clave de cifrado y el primer administrador.
Cada versión se prueba repitiendo estos pasos en un cluster kind desechable, con la base de datos en CloudNativePG.
Public preview
kubelatch está en public preview. Funciona, pero le faltan piezas, que están en el roadmap, y todavía no hay compromiso de estabilidad entre versiones; solo se da soporte a la última.
Antes de empezar¶
| Pieza | Detalle |
|---|---|
| Cluster de gestión | Kubernetes 1.30 o superior, con kubectl de administrador. Puede ser uno de los clusters que kubelatch va a gestionar. |
| Helm | 3.8 o superior (charts OCI). |
| Postgres | El tuyo, versión 17, con la que se prueba kubelatch (RDS, Cloud SQL, Azure Database…), con un rol que pueda crear tablas en la base de datos: kubelatch crea el esquema al arrancar. O uno que crea el chart con el operador CloudNativePG: Base de datos con CloudNativePG. |
| Nombre DNS y certificado | Un nombre público o interno (kubelatch.example.com) y un certificado para él: cert-manager (recomendado) o uno propio. |
| Red | Los pods de kubelatch deben llegar por https al API server de cada cluster gestionado. Las personas y los runners de CI deben llegar a kubelatch por https. |
Todos los comandos de esta guía usan dos variables: el kubeconfig del cluster de gestión y la versión que se instala. Defínelas antes de empezar:
export MGMT_KUBECONFIG=<ruta-al-kubeconfig-del-cluster-de-gestión>
export KUBELATCH_VERSION=<versión> # sin la v: 1.2.3 (https://github.com/picaportelabs/kubelatch/releases)
Usa siempre un kubeconfig explícito
En una máquina con varios clusters, un kubectl o un helm sin --kubeconfig puede aplicar cambios en el cluster equivocado. Por eso todos los comandos de esta guía llevan --kubeconfig "$MGMT_KUBECONFIG".
Qué instala el chart¶
El chart es oci://ghcr.io/picaportelabs/charts/kubelatch. Su versión es la de kubelatch, e instala la imagen ghcr.io/picaportelabs/kubelatch de esa misma versión. Desde la release posterior a la 0.43.0, los dos van firmados: Verificar una release. En el namespace de la release crea:
- Una
ServiceAccountsin permisos y sin token montado: kubelatch no habla con el API server del cluster de gestión con ella. - Un
Deploymentde una réplica:maxSurge: 1,maxUnavailable: 0,terminationGracePeriodSeconds: 60, usuario no root, sistema de ficheros de solo lectura y sin capabilities. - El
ConfigMap kubelatch-config, a partir de los valuesconfig. Los pods llevan su hash: cambiarlo redespliega. - Un
ServiceLoadBalanceren el puerto 443 conexternalTrafficPolicy: Local. - Una
NetworkPolicyque solo deja entrar tráfico al puerto de kubelatch.
El pod monta, de solo lectura, el ConfigMap kube-root-ca.crt que Kubernetes publica en cada namespace: la CA del cluster donde se ejecuta kubelatch, para que enrolar ese cluster con tu identidad no pida pegar nada. No da ningún permiso, y el pod sigue sin token de ServiceAccount. clusterCA.mount: false lo apaga.
Según los values, crea además un Ingress, un Certificate de cert-manager, un PodDisruptionBudget, la clave de cifrado generada, una base de datos de CloudNativePG y la política de endurecimiento. Todos los values están en Values de Helm, y helm show values oci://ghcr.io/picaportelabs/charts/kubelatch --version "$KUBELATCH_VERSION" los muestra con sus comentarios.
Por defecto no crea el namespace, y nunca crea los Secrets que traes tú: la clave de cifrado, DATABASE_URL y el certificado.
Instalar paso a paso¶
-
Crea el namespace con el nivel
restrictedde Pod Security: kubelatch funciona con él, y en este namespace no debe haber nada más.kubectl --kubeconfig "$MGMT_KUBECONFIG" create namespace kubelatch kubectl --kubeconfig "$MGMT_KUBECONFIG" label namespace kubelatch pod-security.kubernetes.io/enforce=restrictedCon Helm 3.17 o superior, puede crearlo el chart:
namespace.create: trueen tus values y--create-namespace --take-ownershipen el paso 5. El namespace lleva entonces la etiqueta y se queda trashelm uninstall. Con un Helm anterior esa opción no funciona: Helm necesita el namespace para guardar la release antes de crear nada, y sin--take-ownershipse niega a adoptar el que acaba de crear--create-namespace. -
Crea los secretos. El chart carga entero el Secret
kubelatch-secrets(secrets.existingSecret):kubectl --kubeconfig "$MGMT_KUBECONFIG" -n kubelatch create secret generic kubelatch-secrets \ --from-literal=DATABASE_URL='postgres://kubelatch:<contraseña>@<host>:5432/kubelatch?sslmode=require' \ --from-literal=KUBELATCH_ENCRYPTION_KEY="$(head -c32 /dev/urandom | base64)"sslmode=requirecifra la conexión pero no comprueba el certificado del servidor. Usasslmode=verify-full, que además lo comprueba junto con el nombre del host. Si el certificado es de una CA pública, no hace falta más. Con una CA privada (RDS, Cloud SQL…), pon la CA en un Secret, móntala conextraVolumesyextraVolumeMountsen tus values (paso 4) y nómbrala consslrootcertenDATABASE_URL:kubectl --kubeconfig "$MGMT_KUBECONFIG" -n kubelatch create secret generic kubelatch-pg-ca --from-file=ca.crt=<bundle-de-la-ca>.pemextraVolumes: - name: pg-ca secret: secretName: kubelatch-pg-ca extraVolumeMounts: - name: pg-ca mountPath: /etc/kubelatch/pg-ca readOnly: trueDATABASE_URL=postgres://kubelatch:<contraseña>@<host>:5432/kubelatch?sslmode=verify-full&sslrootcert=/etc/kubelatch/pg-ca/ca.crtkubelatch vuelve a leer ese fichero cuando cambia, así que rotar la CA es solo actualizar el Secret, sin reiniciar. Funciona porque el Secret se monta como directorio: con
subPathel kubelet nunca actualiza el fichero.Con la base de datos en CloudNativePG, deja fuera
DATABASE_URL: sale del Secret del operador, y una enkubelatch-secretsse ignora. GuardaKUBELATCH_ENCRYPTION_KEYen tu gestor de secretos, aparte de las copias de Postgres: ver La clave de cifrado. -
Pon el certificado. Con un certificado propio:
kubectl --kubeconfig "$MGMT_KUBECONFIG" -n kubelatch create secret tls kubelatch-tls --cert=tls.crt --key=tls.keyCon cert-manager, el chart crea un
Certificateque rellenakubelatch-tls(siguiente paso). Si tienes que pasar por un Ingress, lee antes Exponer kubelatch. -
Escribe tus values en un
values.yaml. Como mínimoconfig.baseURL: la URL pública exacta, sin barra final. Todos los values, con su valor por defecto, están en Values de Helm, y qué hace cada variable de kubelatch, en Configuración. No actives todavía el login con GitHub ni con OIDC: eso viene después, siguiendo Login con GitHub o Login con OIDC (SSO). El repositorio público tiene dos ejemplos completos, con el LoadBalancer L4 y con un Ingress, enexamples/helm.config: baseURL: https://kubelatch.example.com # Con cert-manager en vez de tu propio Secret kubelatch-tls: # tls: # certManager: # enabled: true # issuerRef: {name: letsencrypt, kind: ClusterIssuer} # Con la base de datos en CloudNativePG (instala antes el operador): # postgres: # mode: cnpg -
Instala el chart. Mantén el nombre de release
kubelatch: los recursos se llaman entonceskubelatch, como en esta documentación (con otro nombre son<release>-kubelatch).helm --kubeconfig "$MGMT_KUBECONFIG" install kubelatch oci://ghcr.io/picaportelabs/charts/kubelatch \ --version "$KUBELATCH_VERSION" -n kubelatch -f values.yamlSi falta un value o no encaja (sin
config.baseURL, un Ingress sin host,postgres.mode: cnpgsin el operador…),helm installfalla con un mensaje que lo nombra y no instala nada. -
Comprueba el arranque.
kubectl --kubeconfig "$MGMT_KUBECONFIG" -n kubelatch rollout status deploy/kubelatch kubectl --kubeconfig "$MGMT_KUBECONFIG" -n kubelatch logs deploy/kubelatch | head curl https://kubelatch.example.com/readyzEl log muestra una línea
listeningconversion,tlsyaudit_retention./readyzrespondeok. Con CloudNativePG, el pod espera a los Secrets del operador y se reinicia hasta que la base de datos está lista: espera antes a la base de datos conkubectl --kubeconfig "$MGMT_KUBECONFIG" -n kubelatch wait --for=condition=Ready clusters.postgresql.cnpg.io/kubelatch-db --timeout=5m.
Las sondas funcionan así: el startupProbe da hasta dos minutos a las migraciones. /readyz hace ping a Postgres. /healthz solo comprueba el proceso: una caída de Postgres no reinicia el pod ni corta las sesiones abiertas, y el proxy responde 503 mientras tanto.
La clave de cifrado¶
KUBELATCH_ENCRYPTION_KEY cifra los tokens de las ServiceAccounts de cada cluster y firma las sesiones. No está en Postgres: si la pierdes, una base de datos restaurada no puede usar los tokens de los clusters (Si se pierde o se cambia la clave de cifrado). El chart la toma de uno de dos sitios:
| Opción | Cómo | Cuándo |
|---|---|---|
| Tu Secret (por defecto) | KUBELATCH_ENCRYPTION_KEY en kubelatch-secrets, como en el paso 2. |
Siempre vale. La generas tú y la guardas en tu gestor de secretos. |
| Generada por el chart | secrets.generateEncryptionKey: true. La primera instalación la genera en el Secret kubelatch-encryption-key (clave encryption-key); cada actualización la reutiliza, y helm uninstall la deja en su sitio. |
Solo en instalaciones nuevas, cuando nadie deba manejar la clave, y solo con helm install y helm upgrade contra el cluster. Cópiala a tu gestor de secretos nada más instalar. |
Para copiar la clave generada:
kubectl --kubeconfig "$MGMT_KUBECONFIG" -n kubelatch get secret kubelatch-encryption-key -o jsonpath='{.data.encryption-key}' | base64 -d
Cuando kubelatch ya funciona con una clave, conserva esa clave: activar después secrets.generateEncryptionKey daría al pod otra, y habría que rotar los tokens de cada cluster. Si kubelatch-secrets ya tiene KUBELATCH_ENCRYPTION_KEY, el chart se niega a generar una (Solución de problemas). Una clave que llega por extraEnvFrom no se detecta: la generada ocuparía su lugar en silencio, así que nunca combines las dos.
GitOps: trae tu propia clave
La clave generada depende de que Helm lea el cluster mientras renderiza. Las herramientas que renderizan el chart sin cluster (helm template, Argo CD o cualquier otra que renderice sin conexión) generarían una clave distinta en cada render. El Secret es inmutable, así que aplicar un render posterior da un error explícito en vez de rotar la clave. Tampoco se ejecutan las demás comprobaciones del chart sobre la clave (reutilizarla, rechazar un Secret kubelatch-encryption-key sin su campo, negarse a generar una cuando kubelatch-secrets ya tiene clave). Flux ejecuta Helm contra el cluster, así que allí la consulta funciona. Aun así, con cualquier herramienta GitOps, crea tú el Secret de la clave y usa secrets.existingSecret, nunca secrets.generateEncryptionKey: la clave vive entonces en tu gestor de secretos, no solo en el cluster. Los objetos que Helm conserva en helm uninstall (la base de datos, la clave generada, el namespace) llevan además el Delete=false,Prune=false de Argo CD; con otra herramienta, asegúrate de que nunca los poda.
Crear el primer administrador¶
La imagen no tiene shell: kubectl exec ejecuta el binario directamente, con las mismas variables que el servidor.
kubectl --kubeconfig "$MGMT_KUBECONFIG" -n kubelatch exec -it deploy/kubelatch -- /kubelatch-server user create admin --admin --display-name "Admin"
Pide la contraseña dos veces, sin eco (mínimo 12 caracteres). Sin terminal, pásala por la entrada estándar:
printf '%s' '<contraseña larga>' | kubectl --kubeconfig "$MGMT_KUBECONFIG" -n kubelatch exec -i deploy/kubelatch -- /kubelatch-server user create admin --admin --password-stdin
Si vas a activar el login con GitHub o con OIDC, marca ahora esta cuenta como cuenta break-glass (--break-glass). Lo explica Cuentas y recuperación.
Comprueba que funciona¶
- Abre
https://kubelatch.example.comy entra comoadmin. - Registra un cluster en «Clusters»: Registrar un cluster.
- Invita a las personas en «Usuarios» (Usuarios y bots) y concédeles niveles en «Permisos» (Conceder permisos).
- Cada persona entra en «Inicio» y emite su credencial: Obtener una credencial.
Exponer kubelatch: LoadBalancer L4 o Ingress¶
kubelatch lleva conexiones largas e inusuales: watch y logs -f de horas casi sin tráfico, exec/attach/port-forward como upgrades SPDY o WebSocket sobre HTTP/1.1, y apply de varios megabytes. Cualquier intermediario con timeouts o buffers de aplicación las rompe. Por eso la opción por defecto (exposure: loadBalancer) es L4.
LoadBalancer L4 (por defecto)¶
El balanceador pasa los bytes TLS tal cual y kubelatch termina el TLS en el puerto 8443 con el certificado kubelatch-tls. La IP de origen llega intacta (auditoría y límites por IP sin X-Forwarded-For), sin timeouts de aplicación ni límites de tamaño. Solo puede cortar una conexión el idle timeout TCP del balanceador. kubelatch envía keepalives TCP cada 15 s, que las tres nubes cuentan como actividad. Los ajustes de cada nube van en service.annotations:
| Nube | Idle timeout | Qué hacer |
|---|---|---|
| AWS NLB | 350 s, fijo | Nada: los keepalives lo reinician. Para un NLB: service.beta.kubernetes.io/aws-load-balancer-type: "external", service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance" y service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing". |
| Azure Load Balancer | 4 min por defecto | service.beta.kubernetes.io/azure-load-balancer-tcp-idle-timeout: "30" (el máximo, en minutos). |
| GCP (Network LB passthrough) | Sin timeout | Nada. |
| On-prem (MetalLB, kube-vip) | Sin timeout | Nada. Sin balanceador, service.type: NodePort (y service.nodePort). |
Con externalTrafficPolicy: Local solo pasan el health check los nodos con un pod de kubelatch. Es lo deseado. Deja config.trustedProxies vacío.
Ingress (alternativa)¶
Si tu organización obliga a pasar por un Ingress, usa exposure: ingress. Está pensado para ingress-nginx y no entra en las pruebas de cada versión: valídalo en tu cluster. El TLS termina en el controlador (el Secret kubelatch-tls, o cert-manager con tls.certManager.enabled) y kubelatch escucha HTTP en :8080, detrás de un Service ClusterIP.
exposure: ingress
config:
baseURL: https://kubelatch.example.com
trustedProxies: 10.244.0.0/16 # las IP de los pods del controlador: estréchalo para tu cluster
ingress:
host: kubelatch.example.com
className: nginx
networkPolicy:
ingressControllerNamespace: ingress-nginx
El chart pone en el Ingress los tres ajustes que necesita el proxy:
proxy-read-timeoutyproxy-send-timeouta3600. Los 60 s por defecto cortanwatch,logs -fy unexecinactivo.proxy-body-size: "0". Con 1 MiB por defecto, unkubectl applygrande recibe413antes de llegar a kubelatch.- Backend por HTTP/1.1 (
backend-protocol: HTTP). Nunca HTTP/2 ni gRPC hacia el backend: los upgrades SPDY/WebSocket viajan por HTTP/1.1.
Además desactiva el buffering de respuestas (proxy-buffering: "off"). ingress.annotations añade las tuyas (por ejemplo cert-manager.io/cluster-issuer).
Tienes que ajustar esto:
ingress.host: el host deconfig.baseURL, exactamente. Si no, el chart se para: kubelatch solo conoce un host público.- El certificado: o
tls.certManager.enabled(elCertificatedel chart) o una anotacióncert-manager.io/cluster-issuer(ocert-manager.io/issuer) eningress.annotations, nunca las dos: con las dos, el chart se para. config.trustedProxies: las IP de los pods del controlador y nada más (el rango más estrecho que las cubra, o el CIDR de los nodos si usahostNetwork). El chart no instala sin él. El valor de ejemplo,10.244.0.0/16, es el CIDR de pods de todo un cluster kind: no sirve para producción. Detalle en Proxies de confianza.networkPolicy.ingressControllerNamespace: laNetworkPolicydel chart solo deja llegar al:8080desde ese namespace (ingress-nginxpor defecto). La salida no se restringe: kubelatch necesita Postgres, los clusters, y GitHub o tu proveedor de identidad. DejanetworkPolicy.enabledactivado: conexposure: ingressy sinNetworkPolicy, el chart se para (Solución de problemas).
La NetworkPolicy necesita un CNI que la aplique
Sin un CNI que aplique NetworkPolicy (Calico, Cilium…), se ignora en silencio. kubelatch queda entonces expuesto en HTTP plano a cualquier pod, y cualquiera dentro del rango de confianza puede falsificar la IP de la auditoría.
Otros controladores (Traefik, HAProxy, ALB de AWS) tienen ajustes equivalentes: ingress.className e ingress.annotations. Con cualquiera, ingress-nginx incluido, haz tres pruebas antes de darlo por bueno: kubectl get pods -w durante más de 2 minutos, un kubectl exec inactivo 5 minutos y un kubectl create -f de 2 MB.
kubelatch trata cualquier cabecera Authorization en /api como un token de la CLI, así que un proxy delante que la inyecte (basic-auth del Ingress, oauth2-proxy con pass-authorization-header) rompe la interfaz web: no la añadas en el host de kubelatch.
Proxies de confianza y la IP de origen¶
La auditoría, el registro del plano de control y los limitadores por IP (login, acceso desde la CLI, canje de CI y fallos de autenticación del proxy) usan la IP de la conexión TCP. Detrás de un proxy L7 esa IP es la del proxy. config.trustedProxies (KUBELATCH_TRUSTED_PROXIES) dice de qué redes se acepta X-Forwarded-For:
- Se lee de derecha a izquierda. El primer salto que no es de confianza es el cliente; lo que un cliente falsifique queda a la izquierda y se ignora.
- Solo admite CIDR (
10.244.0.0/16,10.0.0.1/32). Una IP suelta impide el arranque. - Un prefijo más amplio que
/8en IPv4 o/16en IPv6 también impide el arranque. - Las direcciones IPv4 mapeadas en IPv6 (
::ffff:10.0.0.1) se comparan sin mapear.
Nunca pongas un rango que alcance un cliente (por ejemplo 0.0.0.0/0): podría elegir su IP en la auditoría y esquivar los límites. Si falta detrás de un Ingress, todo aparece como venido del controlador y el límite de login se aplica a todos a la vez.
Certificados y CA privada¶
kubelatch lee el certificado de /etc/kubelatch/tls y recarga el par certificado-clave cuando cambia en disco: comprueba las fechas como mucho cada 10 s. Una renovación de cert-manager no necesita reiniciar. Si el par nuevo no es válido (clave de otro certificado, fichero a medias), sigue sirviendo el anterior y lo registra (tls: reload failed). Cada hora avisa si quedan menos de 30 días.
Con tls.certManager.enabled el Certificate del chart reproduce el recomendado: ECDSA P-256, 90 días, renovado 30 días antes, para el host de config.baseURL (tls.certManager.dnsNames, duration y renewBefore los cambian).
Con una CA pública (Let's Encrypt), los kubeconfigs no llevan CA: kubectl confía por el almacén del sistema. Con una CA privada, apunta config.kubeconfigCA (KUBELATCH_KUBECONFIG_CA) al bundle PEM y cada kubeconfig emitido llevará certificate-authority-data. Con un issuer privado de cert-manager, el Secret ya trae ca.crt: usa /etc/kubelatch/tls/ca.crt (solo con exposure: loadBalancer: detrás de un Ingress, kubelatch no monta el certificado).
El fichero debe ser regular, de 1 MiB como mucho, y contener solo bloques CERTIFICATE. Una clave pegada por error u otro bloque PEM impide el arranque.
kubelatch nunca incluye la CA de los clusters gestionados en los kubeconfigs. kubectl verifica a kubelatch, y kubelatch verifica cada API server con la CA con la que se enroló.
Varias réplicas¶
Dos réplicas mantienen kubelatch en servicio mientras se drena un nodo o se reinicia un pod. Repártelas en dos nodos con affinity, porque el chart no lo hace por su cuenta. Usa la forma preferred: con la forma required en un cluster de dos nodos, el pod adicional de un rollout (maxSurge: 1) no tiene dónde ir.
replicas: 2
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
app.kubernetes.io/name: kubelatch
app.kubernetes.io/instance: kubelatch
Con replicas mayor que 1, el chart añade un PodDisruptionBudget con pdb.minAvailable (1). El balanceador o el Ingress no necesitan afinidad de sesión: cualquier réplica atiende cualquier petición.
Lo que comparten dos réplicas, porque está en Postgres o va firmado con la clave de cifrado que leen las dos:
- Los inicios de sesión. Una sesión web, un
kubelatch loginen el navegador o con código de dispositivo, la entrada OAuth de un agente, un login con GitHub o un login con OIDC pueden empezar en una réplica y acabar en la otra. El bloqueo de cuenta tras 5 logins fallidos cuenta en las dos. - Las aprobaciones de agentes. La llamada de un agente puede esperar la decisión en una réplica mientras un administrador la aprueba en la otra. La llamada ve la decisión en menos de un segundo.
- La revocación. Revocar una credencial o deshabilitar una cuenta corta sus
exec,port-forwardywatchabiertos en 10 s, en la réplica que los tenga. - Las tareas de fondo. Cada réplica ejecuta el reconciliador, la retención de la auditoría y la sincronización con GitHub, y un lock de Postgres impide que dos pasadas se solapen. «Reconciliar» responde que ya hay una pasada en marcha mientras la de la otra réplica tiene el cluster. Las migraciones se aplican en una réplica mientras la otra espera.
Lo que cada réplica guarda para sí:
| Qué | Con dos réplicas |
|---|---|
Los límites de frecuencia: login, abrir enlaces de invitación y de restablecimiento, inicio de sesión de la CLI, canje de CI, OAuth de agentes, peticiones a /mcp por credencial, búsquedas de credenciales y el límite por IP de las peticiones que el proxy rechaza |
Cada réplica lleva su propia cuenta, así que el límite efectivo es el doble del configurado. |
| Una clave de licencia pegada o quitada en «Edición» | La réplica que la recibe la aplica al momento, y la otra en su comprobación de cada hora. Hasta entonces, «Edición», los límites de Free y la ventana de la auditoría dependen de la réplica que responda. Pon la clave en KUBELATCH_LICENSE (el Secret), o reinicia los pods después de pegarla. |
| La última sincronización con GitHub que muestra «Usuarios» | Cada réplica muestra su última pasada. |
| La vigilancia de los namespaces de cada cluster, que reconcilia un cluster cuando un namespace con permisos cambia su etiqueta de Pod Security o desaparece (La reconciliación) | Cada réplica vigila todos los clusters y escribe en su log sus propios namespace watch down y namespace watch up. Un cluster que se enrola, recibe tokens nuevos o se borra en una réplica llega a la vigilancia de la otra en menos de un minuto. |
| El documento de descubrimiento del proveedor OIDC (se guarda un día) y sus claves (una hora), y su estado en «Usuarios» | Cada réplica lee los suyos; «Usuarios» muestra el estado de la réplica que responde. |
| «Comprobar ahora» en «Edición» | Solo comprueba la réplica que responde. |
Lo que no está soportado:
- Dos instalaciones sobre las mismas tablas. Dos releases necesitan cada una su base de datos, o al menos su esquema. Las réplicas de una misma release sí están soportadas.
- Pasar un stream a la otra réplica. Un rollout o un pod reiniciado cortan los
exec,port-forwardywatchque tienen. kubectl vuelve a abrir unwatchpor su cuenta, en la réplica que sigue en servicio, pero unexeco unport-forwardhay que volver a ejecutarlos: ver Qué pasa durante un rollout.
Siguientes pasos¶
- Login con GitHub, si tu organización usa GitHub.
- Login con OIDC (SSO), si en tu empresa se entra con Google Workspace, Microsoft Entra ID, Okta u otro proveedor de identidad.
- Registrar un cluster y, opcionalmente, endurecerlo.
- Base de datos con CloudNativePG, si el chart lleva tu Postgres.
- Actualizar y copias de seguridad, antes de ir a producción.