Container Apps resolvió el motor de disponibilidad con muy poco esfuerzo, y esa es la mejor noticia de la lección anterior. Pero en Contoso Airlines hay un frente distinto: la plataforma de operaciones de vuelo, doce microservicios que coordinan asignación de puertas, rotación de tripulaciones, carga de combustible y retrasos, escritos por tres equipos, con un componente que exige nodos con mucha memoria y otro que necesita afinidad entre pods. Ese sistema pide control fino de la programación, políticas de red entre servicios y operadores de terceros. Ahí sí, Kubernetes.
Esta lección enseña Azure Kubernetes Service con honestidad: qué te da, qué sigue siendo trabajo tuyo, cuánto cuesta de verdad y en qué casos adoptarlo es sobreingeniería. Contoso lo adopta para operaciones de vuelo, no para toda la plataforma, y esa decisión es la primera lección.
Contenido
- Cuándo Kubernetes está justificado y cuándo no
- Conceptos de Kubernetes, lo imprescindible
- Qué gestiona AKS y qué sigue siendo tuyo
- Crear
aks-contoso-operacionesy elegir el modelo de red - Identidad: Entra ID, RBAC e identidad de carga de trabajo
- Desplegar la aplicación con manifiestos y
kubectl - Entrada gestionada y certificados
- Escalado, solicitudes y límites
- Actualizaciones, interrupciones y mantenimiento
- Almacenamiento persistente, observabilidad, Helm y coste realista
- Errores Comunes y Consejos
- Ejercicios
- Conclusión
- Cuándo Kubernetes está justificado y cuándo no
| Señal | ¿Kubernetes? |
|---|---|
| Un puñado de APIs sin estado con carga irregular | No: Container Apps, más barato |
| Doce o más servicios con dependencias entre ellos | Sí |
| Necesitas operadores, mallas de servicio o CRD, o hardware por carga (GPU) | Sí |
| Portabilidad real entre nubes o centro de datos propio | Sí |
| «Es lo que se usa ahora», o nadie sabe operar un clúster | No, y son las dos razones más frecuentes |
El coste oculto de Kubernetes no es la factura de los nodos, es el tiempo del equipo: actualizaciones trimestrales, versiones de API que se retiran, depuración de la red, gestión de certificados. Si nadie va a dedicar tiempo a eso, un clúster envejece hasta convertirse en un riesgo. Contoso lo asume solo donde el retorno lo compensa.
- Conceptos de Kubernetes, lo imprescindible
graph TD
subgraph PC["Plano de control (gestionado por AKS, gratuito)"]
API[Servidor de API] --- ETCD[(etcd)]
API --- PROG[Programador] --- CTRL[Controladores]
end
subgraph NODOS["Grupos de nodos (tus maquinas virtuales, se pagan)"]
N1["Nodo 1: pod puertas + pod tripulaciones"]
N2["Nodo 2: pod puertas + pod combustible"]
end
API --> N1
API --> N2
ING[Ingreso: operaciones.contosoairlines.example] --> SVC[Servicio: puertas]
SVC --> N1
SVC --> N2
- Plano de control: el cerebro. El servidor de API recibe todas las órdenes, etcd guarda el estado deseado, el programador decide en qué nodo cabe cada pod y los controladores corrigen sin parar la diferencia entre lo que hay y lo que debería haber. Ese bucle de reconciliación es la idea central de Kubernetes: tú declaras el destino, el sistema se encarga del camino.
- Nodo: una máquina virtual que ejecuta pods, agrupada con otras en grupos de nodos. Y pod: la unidad mínima programable, uno o más contenedores que comparten red y almacenamiento. Es efímero: si muere, no revive; nace otro con otra dirección IP.
- Despliegue y conjunto de réplicas: el despliegue declara «quiero N réplicas de este pod con esta imagen»; el conjunto de réplicas mantiene la cuenta y orquesta las actualizaciones progresivas.
- Servicio e ingreso: el servicio da IP y nombre DNS estables por delante de un conjunto cambiante de pods —resuelve que los pods no tengan dirección fija—; el ingreso enruta el tráfico HTTP de entrada por nombre de host y ruta, con TLS, en un solo punto de entrada para muchos servicios.
- Espacio de nombres: partición lógica del clúster con cuotas y permisos propios; Contoso usa
operaciones-vuelo,integracionymonitorizacion. Y mapa de configuración y secreto: configuración y datos sensibles inyectados como variables de entorno o ficheros. Ojo: un secreto de Kubernetes solo va codificado en base64, no cifrado, por eso Contoso los saca dekv-contoso-pro.
- Qué gestiona AKS y qué sigue siendo tuyo
| Responsabilidad | AKS | Tú |
|---|---|---|
| Plano de control (API, etcd, programador) | Sí, y es gratuito | — |
| Copias de seguridad de etcd | Sí | — |
| Nodos: máquinas virtuales y discos | Aprovisiona | Los pagas |
| Parcheo del SO y versión de Kubernetes | Publica imágenes y versiones | Decidir y lanzar la actualización |
| Manifiestos, límites, políticas de red, alertas | Integraciones | Tuyo |
Dilo claro, porque genera muchas facturas sorpresa: el plano de control de AKS es gratuito en el nivel Free; lo que se paga son los nodos, que son máquinas virtuales normales con su precio de cómputo y sus discos. Un clúster «vacío» con tres nodos cuesta lo mismo que tres máquinas virtuales encendidas. El nivel Standard añade un SLA con coste por hora de clúster, y es lo que corresponde en producción.
- Crear
aks-contoso-operaciones y elegir el modelo de red
aks-contoso-operaciones y elegir el modelo de redaz aks create \
--resource-group rg-contoso-reservas-pro --name aks-contoso-operaciones \
--location westeurope --tier standard --kubernetes-version 1.30.4 \
--nodepool-name sistema --node-count 3 --node-vm-size Standard_D4s_v5 --zones 1 2 3 \
--enable-cluster-autoscaler --min-count 3 --max-count 6 \
--network-plugin azure --network-plugin-mode overlay --network-policy cilium \
--vnet-subnet-id $(az network vnet subnet show -g rg-contoso-red-pro \
--vnet-name vnet-contoso-pro -n snet-app --query id -o tsv) \
--enable-aad --enable-azure-rbac --enable-managed-identity \
--enable-oidc-issuer --enable-workload-identity \
--attach-acr acrcontosopro --enable-addons monitoring \
--workspace-resource-id $(az monitor log-analytics workspace show \
-g rg-contoso-seguridad-pro -n log-contoso-pro --query id -o tsv) \
--tags entorno=produccion proyecto=contoso-reservas \
centro-coste=CC-1042 [email protected]Y a continuación el grupo de nodos de usuario, porque mezclar cargas de sistema y de aplicación en el mismo grupo es un error clásico:
az aks nodepool add \
--resource-group rg-contoso-reservas-pro --cluster-name aks-contoso-operaciones \
--name aplicaciones --mode User \
--node-vm-size Standard_D8s_v5 --node-count 2 --zones 1 2 3 \
--enable-cluster-autoscaler --min-count 2 --max-count 12Las decisiones que hay detrás:
--nodepool-name sistemacon--mode System(implícito encreate): aloja CoreDNS,metrics-servery los complementos. Si una carga de aplicación desbocada consume su memoria, se cae el DNS del clúster entero. Sepáralos.--zones 1 2 3reparte los nodos entre zonas de disponibilidad —sin esto, un incidente de zona se lleva el clúster— y--enable-cluster-autoscalerañade y quita nodos según los pods que no caben, que es distinto del escalado de pods (apartado 8).--attach-acr acrcontosoproasigna por ti el rolAcrPulla la identidad de tipo kubelet del clúster; sin ella, los pods fallan conImagePullBackOffy el error es opaco. Y--enable-workload-identitymás--enable-oidc-issueres la base del apartado 5.
Redes: kubenet, Azure CNI y CNI Overlay
| kubenet | Azure CNI | Azure CNI Overlay | |
|---|---|---|---|
| IP del pod | Red superpuesta interna | De la subred de la red virtual | Red superpuesta gestionada |
| Consumo de IP de la subred | Muy bajo | Muy alto | Muy bajo |
| Conectividad directa al pod | No, con saltos | Sí | No directa |
| Rendimiento y estado | Menor; en retirada | Máximo; vigente | Casi como CNI; recomendado |
El fallo de diseño más caro en AKS es elegir Azure CNI sin echar cuentas: cada nodo reserva por adelantado tantas IP como pods máximos admita (30 por defecto), así que 20 nodos consumen 600 direcciones y una /24 se agota antes de empezar. Contoso usa CNI Overlay sobre snet-app (10.20.2.0/24): los nodos toman IP de la subred, los pods de un espacio superpuesto, y la subred aguanta el crecimiento. Se añade política de red (Cilium) para poder prohibir explícitamente que un pod hable con otro; sin ella, dentro del clúster todo habla con todo.
- Identidad: Entra ID, RBAC e identidad de carga de trabajo
Con --enable-aad --enable-azure-rbac, quién entra al clúster lo decide Microsoft Entra ID y qué puede hacer lo decide RBAC de Azure, con los mismos grupos del módulo 4:
idClus=$(az aks show -g rg-contoso-reservas-pro -n aks-contoso-operaciones --query id -o tsv)
# Infraestructura: administracion completa del cluster
az role assignment create --role "Azure Kubernetes Service RBAC Cluster Admin" \
--assignee-object-id $(az ad group show -g Contoso-Infraestructura --query id -o tsv) \
--assignee-principal-type Group --scope $idClus
# Desarrollo: solo escritura dentro de SU espacio de nombres
az role assignment create --role "Azure Kubernetes Service RBAC Writer" \
--assignee-object-id $(az ad group show -g Contoso-Desarrollo --query id -o tsv) \
--assignee-principal-type Group --scope "$idClus/namespaces/operaciones-vuelo"La identidad de carga de trabajo es la pieza que elimina los secretos dentro del clúster. Una cuenta de servicio de Kubernetes se federa con id-contoso-api-pro: el pod recibe un token firmado por el emisor OIDC del clúster, lo cambia por un token de Entra ID y accede a kv-contoso-pro y a db-reservas con DefaultAzureCredential, el mismo código de 04-02, sin ninguna clave.
# Federar la cuenta de servicio del espacio de nombres con la identidad administrada
az identity federated-credential create \
--name fed-operaciones --identity-name id-contoso-api-pro \
--resource-group rg-contoso-seguridad-pro \
--issuer $(az aks show -g rg-contoso-reservas-pro -n aks-contoso-operaciones \
--query oidcIssuerProfile.issuerUrl -o tsv) \
--subject system:serviceaccount:operaciones-vuelo:sa-operaciones \
--audience api://AzureADTokenExchange
- Desplegar la aplicación con manifiestos y
kubectl
kubectlAntes del despliegue hace falta la cuenta de servicio sa-operaciones en el espacio de nombres operaciones-vuelo, anotada con azure.workload.identity/client-id apuntando al identificador de cliente de id-contoso-api-pro. Es la contraparte en el clúster de la credencial federada anterior.
apiVersion: apps/v1
kind: Deployment
metadata: { name: panel-operaciones, namespace: operaciones-vuelo }
spec:
replicas: 3
selector: { matchLabels: { app: panel-operaciones } }
template:
metadata:
labels:
app: panel-operaciones
azure.workload.identity/use: "true" # inyecta el token federado
spec:
serviceAccountName: sa-operaciones
containers:
- name: panel
image: acrcontosopro.azurecr.io/panel-operaciones:4821
ports: [ { containerPort: 8080 } ]
resources: # el apartado 8 explica por que
requests: { cpu: "250m", memory: "256Mi" }
limits: { cpu: "1000m", memory: "512Mi" }
readinessProbe: { httpGet: { path: /salud, port: 8080 } } # listo para trafico
livenessProbe: { httpGet: { path: /salud, port: 8080 } } # vivo; si no, reinicio
topologySpreadConstraints: # reparte las 3 replicas entre las 3 zonas
- { maxSkew: 1, topologyKey: topology.kubernetes.io/zone,
whenUnsatisfiable: DoNotSchedule,
labelSelector: { matchLabels: { app: panel-operaciones } } }
---
apiVersion: v1
kind: Service
metadata: { name: svc-panel-operaciones, namespace: operaciones-vuelo }
spec:
type: ClusterIP # interno; el ingreso es quien publica
selector: { app: panel-operaciones }
ports: [ { port: 80, targetPort: 8080 } ]
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata: { name: ing-operaciones, namespace: operaciones-vuelo }
spec:
ingressClassName: webapprouting.kubernetes.azure.com
rules:
- host: operaciones.contosoairlines.example
http:
paths:
- { path: /, pathType: Prefix,
backend: { service: { name: svc-panel-operaciones, port: { number: 80 } } } }
tls:
- hosts: [ operaciones.contosoairlines.example ]
secretName: tls-operaciones # certificado sincronizado desde Key VaultCampo a campo, lo que no es evidente:
selector.matchLabelsdel despliegue ylabelsde la plantilla deben coincidir: es la unión entre el despliegue y sus pods, y desalinearlos deja el despliegue sin réplicas.serviceAccountNamemás la etiquetaazure.workload.identity/useson lo que activa la federación del apartado 5.- La imagen lleva la etiqueta
4821, el identificador de compilación del pipeline (05-03), nuncalatest. readinessProbefrente alivenessProbe: la primera controla si el pod entra en el balanceo; la segunda si se reinicia. Confundirlas produce reinicios en cascada bajo carga. YtopologySpreadConstraintsobliga a repartir las tres réplicas entre las tres zonas: sin esto, el programador puede colocarlas las tres en el mismo nodo.type: ClusterIP: el servicio no se publica solo. UsarLoadBalancerpor servicio crea una IP pública por cada uno y multiplica coste y superficie expuesta.
kubectl esencial: kubectl apply -f manifiestos/ aplica; kubectl get pods -n operaciones-vuelo -o wide lista con nodo y IP; kubectl describe pod <nombre> da los eventos, que es donde está siempre la causa del fallo; kubectl logs -f <pod> sigue los registros; kubectl rollout status deploy/panel-operaciones espera al despliegue y kubectl rollout undo lo revierte; kubectl top pods muestra el consumo real, imprescindible para ajustar el apartado 8.
- Entrada gestionada y certificados
Instalar y mantener a mano un controlador de entrada es trabajo recurrente. El complemento de enrutamiento de aplicaciones despliega un NGINX gestionado y lo integra con DNS y Key Vault:
az aks approuting enable -g rg-contoso-reservas-pro -n aks-contoso-operaciones \
--enable-kv --attach-kv $(az keyvault show -n kv-contoso-pro --query id -o tsv)Con eso, el certificado de operaciones.contosoairlines.example vive en kv-contoso-pro, se sincroniza como secreto de Kubernetes y se renueva sin intervención. El certificado nunca se copia a un repositorio ni a un manifiesto.
- Escalado, solicitudes y límites
Tres escaladores que se confunden constantemente:
| Escalador | Qué hace | Señal |
|---|---|---|
| Horizontal de pods (HPA) | Añade o quita réplicas | CPU, memoria o métrica personalizada |
| Automático de clúster | Añade o quita nodos | Pods pendientes que no caben |
| Nodos virtuales | Programa pods en ACI, sin nodo | Ráfagas inmediatas, sin arrancar máquinas |
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata: { name: hpa-panel, namespace: operaciones-vuelo }
spec:
scaleTargetRef: { apiVersion: apps/v1, kind: Deployment, name: panel-operaciones }
minReplicas: 3
maxReplicas: 20
metrics:
- { type: Resource,
resource: { name: cpu, target: { type: Utilization, averageUtilization: 70 } } }Los dos primeros escaladores trabajan en cadena: el HPA pide más réplicas, no caben, quedan pendientes y el escalador de clúster arranca nodos. Y aquí está el punto clave de toda la lección: el HPA calcula el porcentaje de uso sobre la solicitud (requests), y el programador decide dónde cabe un pod mirando su solicitud. Sin requests no hay porcentaje que calcular ni información para programar.
Las solicitudes y los límites son la causa número uno de clústeres inestables. Sin requests, el programador cree que el pod no consume nada y amontona pods en un nodo hasta agotarlo. Sin limits de memoria, una fuga en un pod consume la memoria del nodo y el núcleo empieza a matar procesos: caen pods sanos ajenos al problema. Con limits de CPU demasiado bajos, el pod sufre limitación y la latencia se dispara sin que la CPU parezca alta.
La regla práctica: fija requests en el consumo del percentil 50 medido con kubectl top, y limits en torno al doble. Refuérzalo con ResourceQuota y LimitRange en el espacio de nombres para que ningún manifiesto sin límites llegue a aplicarse.
- Actualizaciones, interrupciones y mantenimiento
Kubernetes publica versiones a buen ritmo y AKS solo da soporte a unas pocas. Actualizar no es opcional; es una tarea de calendario.
az aks get-upgrades -g rg-contoso-reservas-pro -n aks-contoso-operaciones -o table
az aks upgrade -g rg-contoso-reservas-pro -n aks-contoso-operaciones \
--kubernetes-version 1.31.1 --control-plane-only # primero el plano
az aks nodepool upgrade -g rg-contoso-reservas-pro --cluster-name aks-contoso-operaciones \
-n aplicaciones --kubernetes-version 1.31.1 # despues cada grupoActualiza siempre el plano de control primero y los grupos de nodos después, uno a uno, y de una versión menor a la siguiente, sin saltos. Los nodos se sustituyen mediante acordonado y vaciado, y ahí entra el presupuesto de interrupción de pods, que impide que el vaciado deje un servicio por debajo de un mínimo:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata: { name: pdb-panel, namespace: operaciones-vuelo }
spec:
minAvailable: 2 # el vaciado nunca deja menos de 2 replicas
selector: { matchLabels: { app: panel-operaciones } }Sin él, un vaciado puede llevarse las tres réplicas a la vez y el panel de operaciones desaparece durante la actualización. Complétalo con una ventana de mantenimiento planificado (az aks maintenanceconfiguration add) para que las actualizaciones automáticas del sistema operativo del nodo no caigan en hora punta de facturación.
- Almacenamiento, observabilidad, Helm y coste
El disco de un pod es efímero. Para persistir, se declara una reclamación de volumen persistente contra una clase de almacenamiento:
| Clase | Respaldo | Acceso | Uso en Contoso |
|---|---|---|---|
managed-csi (y -premium) |
Disco de Azure | Un solo nodo | Datos de un pod único; la variante Premium para E/S exigente |
azurefile-csi |
Azure Files (SMB/NFS) | Varios nodos a la vez | Ficheros compartidos entre réplicas |
La distinción decisiva es el modo de acceso: un disco de Azure lo monta un solo nodo, así que no sirve para tres réplicas repartidas por zonas; para eso hace falta Azure Files. Y por defecto la política de reclamación es Delete: al borrar la reclamación desaparece el disco y los datos. En producción, Retain.
La observabilidad se resuelve con Container Insights, ya habilitado en el az aks create contra log-contoso-pro: métricas de nodos y pods, registros de contenedor y del plano de control consultables con KQL. Cómo explotarlos es el módulo 7 (07-01 y 07-02); aquí basta con dejarlo activado desde el principio, porque nadie lo activa a tiempo cuando el clúster ya falla.
Helm, GitOps y coste realista
Helm es el gestor de paquetes de Kubernetes: empaqueta un conjunto de manifiestos en un chart con valores parametrizados, de modo que desplegar en desarrollo y en produccion sea el mismo chart con otro fichero de valores; es a los manifiestos lo que los módulos de Bicep a las plantillas (05-06). GitOps con Flux es la evolución natural: en lugar de que el pipeline empuje con kubectl apply, un agente dentro del clúster vigila el repositorio contoso-infra y reconcilia el clúster hacia lo que dice Git; el repositorio pasa a ser la única fuente de verdad y la desviación de configuración se corrige sola. AKS lo ofrece como extensión gestionada.
Coste realista. Un clúster de producción como el de Contoso, con 3 nodos Standard_D4s_v5 de sistema y 2 a 12 nodos Standard_D8s_v5 de aplicación, más el nivel Standard, discos, balanceador e ingesta de registros, se sitúa en el orden de varios miles de euros al mes, y la ingesta de Log Analytics sorprende más de lo que nadie espera. Cómo reducirlo:
- Instancias de acceso puntual (
az aks nodepool add --priority Spot --eviction-policy Delete --spot-max-price -1) en un grupo dedicado para cargas tolerantes a interrupciones —lotes, pruebas—: hasta un 80-90 % menos, a cambio de un desalojo con dos minutos de aviso. - Escalar a cero los grupos de usuario con
--min-count 0, y parar el clúster de desarrollo conaz aks stop/az aks start: un clúster parado no factura nodos. Automatízalo por la noche y el fin de semana con Azure Automation (07-04). - Ajustar
requestsa lo que se consume de verdad: las solicitudes infladas obligan al escalador a arrancar nodos medio vacíos. Es el ahorro menos visible y a menudo el mayor.
Errores Comunes y Consejos
- Adoptar AKS sin necesidad: si el caso lo cubre Container Apps, AKS solo añade factura y trabajo. Y desplegar sin
requestsnilimits, causa número uno de clústeres inestables; impónlo conLimitRange. - Elegir Azure CNI sin calcular las IP. La subred se agota y ampliarla obliga a rehacer el clúster. Usa CNI Overlay.
- Mezclar cargas de aplicación con el grupo de sistema. Un pod desbocado tira CoreDNS y con él el clúster.
- Guardar secretos como
Secretde Kubernetes (solo base64) o poner unServicede tipoLoadBalancerpor microservicio (doce IP públicas). Identidad de carga de trabajo contrakv-contoso-pro, y un solo ingreso con enrutamiento por host. - Dejar el clúster sin actualizar: las versiones salen de soporte y la actualización acumulada se vuelve arriesgada. Calendario trimestral.
- Consejo:
kubectl describe podantes que cualquier otra cosa. El 90 % de los fallos (ImagePullBackOff,CrashLoopBackOff,Pendingpor falta de recursos) se explican en su sección de eventos. Y aplica políticas de red desde el principio: retrofitarlas en un clúster en producción es doloroso.
Ejercicios
Ejercicio 1. Un microservicio de operaciones se queda en estado Pending y el escalador de clúster no arranca nodos. Su manifiesto pide requests: { cpu: "8000m", memory: "32Gi" } y el grupo aplicaciones usa Standard_D8s_v5 (8 vCPU, 32 GiB).
- Explica por qué el pod nunca se programará y por qué el escalador de clúster no lo arregla añadiendo nodos.
- Da dos soluciones distintas y di cuál elegirías.
Ejercicio 2. Diseña el clúster de la plataforma «Contoso Millas»: seis microservicios, tráfico de día y casi nulo de noche, más un proceso nocturno de recálculo de puntos que tolera interrupciones.
- Define los grupos de nodos con su modo, tamaño, zonas y límites del escalador.
- Justifica el uso de instancias de acceso puntual y sus riesgos, indica las etiquetas obligatorias del proyecto secundario y dos medidas de ahorro adicionales.
Ejercicio 3. Un pod debe leer un secreto de kv-contoso-pro y consultar db-reservas.
- Enumera los pasos para conseguirlo sin ninguna credencial en el clúster, y explica qué relación hay entre el emisor OIDC, la cuenta de servicio y
id-contoso-api-pro. - ¿Por qué es mejor que montar un
Secretde Kubernetes con la cadena de conexión?
Soluciones
Solución 1:
- Porque la solicitud consume todo el nodo, y el sistema operativo, el kubelet y los complementos del sistema ya reservan una parte: la capacidad asignable de un
Standard_D8s_v5es inferior a 8 vCPU y 32 GiB, así que ningún nodo de ese tamaño tiene hueco. El escalador solo arranca nodos si el pod cabría en un nodo nuevo del grupo; como no cabe, concluye que añadir nodos es inútil y no hace nada. Es correcto, aunque el silencio despiste. - (a) Reducir la solicitud a lo que consume de verdad, medido con
kubectl top—por ejemplo 4 vCPU y 16 GiB—. (b) Crear un grupo de nodos con máquinas mayores, del tipoStandard_E16s_v5, y dirigir el pod connodeSelector. Elegiría (a) primero, porque casi siempre la solicitud está inflada «por si acaso»; (b) solo si la medición confirma que la carga necesita de verdad ese tamaño.
Solución 2:
- Grupo
sistemaen modo System, 2 nodosStandard_D2s_v5, zonas 1-2-3, escalador de 2 a 3. Grupoaplicacionesen modo User,Standard_D4s_v5, zonas 1-2-3, escalador de 2 a 8 durante el día. Grupolotesen modo User con--priority Spot,Standard_D8s_v5, escalador de 0 a 6, con su contaminación correspondiente para que solo el proceso nocturno se programe ahí. - El recálculo de puntos es idempotente, reanudable y no tiene usuario esperando: si Azure desaloja un nodo con dos minutos de aviso, el trabajo se reprograma y solo se pierde tiempo, a cambio de un ahorro enorme. El riesgo real es usar instancias puntuales para servicios en línea, donde el desalojo se traduce en errores para el usuario; por eso el grupo está separado y contaminado. Etiquetas:
entorno,proyecto=contoso-millas,centro-coste=CC-2077ypropietario. Ahorro adicional: escalar a cero el grupolotesfuera de la ventana nocturna y parar el clúster de desarrollo conaz aks stopdesde un runbook por la noche y el fin de semana.
Solución 3:
- (a) Crear el clúster con
--enable-oidc-issuer --enable-workload-identity. (b) Crear la cuenta de serviciosa-operacionesenoperaciones-vueloanotada con el identificador de cliente deid-contoso-api-pro. (c) Crear la credencial federada conaz identity federated-credential createy el sujetosystem:serviceaccount:operaciones-vuelo:sa-operaciones. (d) Dar aid-contoso-api-proel rol Usuario de secretos de Key Vault sobrekv-contoso-proy crear el usuario externo endb-reservas. (e) En el pod,serviceAccountNamey la etiquetaazure.workload.identity/use: "true", y en el códigoDefaultAzureCredential. En cuanto a la relación: el emisor OIDC del clúster firma el token de la cuenta de servicio y la credencial federada declara ante Entra ID que ese emisor y ese sujeto concretos pueden obtener tokens deid-contoso-api-pro; la confianza es criptográfica, no una contraseña compartida. - Porque un
Secretde Kubernetes está codificado en base64, no cifrado: quien pueda leerlo en el espacio de nombres, o quien acceda a una copia de seguridad de etcd, lo lee en claro. Además hay que rotarlo a mano en todos los clústeres. Con identidad de carga de trabajo no existe el secreto: hay tokens de vida corta emitidos y revocables desde Entra ID, con trazabilidad en los registros de inicio de sesión.
Conclusión
Kubernetes deja de ser una palabra y pasa a ser una herramienta con criterio de uso. Sabes cuándo está justificado y cuándo es sobreingeniería, y has visto a Contoso adoptarlo solo para la plataforma de operaciones de vuelo mientras el motor de disponibilidad se queda tranquilamente en Container Apps. Manejas los conceptos imprescindibles —plano de control y nodos, pod, despliegue, réplica, servicio, ingreso, espacio de nombres, mapa de configuración y secreto— y entiendes el bucle de reconciliación que los sostiene. Tienes clara la frontera de responsabilidades: el plano de control es gratuito, los nodos se pagan, y las actualizaciones, los límites y las políticas siguen siendo tuyos.
Has creado aks-contoso-operaciones con grupos de sistema y de usuario separados, zonas de disponibilidad, escalador automático, CNI Overlay para no agotar la subred, política de red, integración con Entra ID y RBAC de Azure por espacio de nombres, extracción de imágenes desde acrcontosopro con --attach-acr, e identidad de carga de trabajo que da a los pods acceso a kv-contoso-pro y db-reservas sin un solo secreto. Has desplegado con manifiestos explicados campo a campo, publicado con el complemento de enrutamiento y certificados de Key Vault, y sabes usar kubectl para diagnosticar. Dominas los tres escaladores y, sobre todo, por qué la ausencia de requests y limits es la causa número uno de clústeres inestables. Sabes actualizar en el orden correcto protegiendo la disponibilidad con presupuestos de interrupción y ventanas de mantenimiento, persistir con discos frente a Azure Files según el modo de acceso, y dejar Container Insights encendido desde el minuto uno. Y conoces el camino de madurez —Helm, GitOps con Flux— y el coste real con sus palancas: instancias de acceso puntual, grupos que escalan a cero, parar el clúster de desarrollo y ajustar las solicitudes.
Contoso tiene ahora dos formas de ejecutar código propio y una duda razonable: para muchas tareas, mantener algo ejecutándose es absurdo. Generar el PDF de una tarjeta de embarque ocupa dos segundos y ocurre cuando se confirma una reserva; sincronizar el catálogo de tarifas ocurre cuando cambia un documento en cosmos-contoso-tarifas-pro. Para eso no quieres un contenedor esperando ni un pod encendido, quieres que el código se ejecute cuando pasa algo y no exista el resto del tiempo. Esa es la computación sin servidor, y la siguiente lección, Azure Functions, la lleva al detalle: desencadenadores y enlaces, planes de hospedaje, las dos funciones reales de Contoso, Durable Functions para orquestar el check-in y la lección dura que nadie se salta, la idempotencia.
Curso de Azure
Módulo 1: Introducción a Azure
- ¿Qué es Azure?
- Modelos de servicio, regiones y zonas de disponibilidad
- Crear y configurar tu cuenta de Azure
- Recorrido por el portal de Azure
- Azure Resource Manager: suscripciones, grupos de recursos y etiquetas
- Azure CLI, PowerShell y Cloud Shell
Módulo 2: Servicios principales de Azure
- Máquinas virtuales de Azure
- Escalado y alta disponibilidad del cómputo
- Azure App Service
- Azure Storage: blobs, archivos, colas y tablas
- Redes en Azure: redes virtuales, subredes y NSG
- Conectividad híbrida y entrega global
Módulo 3: Bases de datos de Azure
- Elegir el servicio de datos adecuado
- Azure SQL Database
- Azure Cosmos DB
- Azure Database for MySQL
- Azure Database for PostgreSQL
- Analítica de datos: Data Lake, Data Factory y Synapse
Módulo 4: Seguridad en Azure
- Microsoft Entra ID y gestión de identidades
- RBAC e identidades administradas
- Azure Key Vault
- Protección DDoS y firewall de aplicaciones web
- Microsoft Defender for Cloud
- Gobernanza y cumplimiento con Azure Policy
Módulo 5: Azure DevOps
- Introducción a Azure DevOps
- Azure Repos
- Azure Pipelines: integración continua
- Despliegue continuo con entornos y aprobaciones
- Azure Artifacts
- Infraestructura como código con Bicep
Módulo 6: Servicios avanzados de Azure
- Contenedores en Azure: Container Registry y Container Apps
- Azure Kubernetes Service (AKS)
- Azure Functions
- Azure Logic Apps
- Mensajería y eventos: Service Bus, Event Grid y Event Hubs
- Servicios de IA de Azure
Módulo 7: Monitoreo y gestión
- Azure Monitor: métricas, alertas y paneles
- Log Analytics y consultas KQL
- Application Insights
- Azure Automation y runbooks
- Copias de seguridad y recuperación ante desastres
Módulo 8: Gestión y optimización de costos
- Calculadora de precios y estimación de costes
- Azure Cost Management: análisis, presupuestos y alertas
- Reservas, planes de ahorro y Azure Hybrid Benefit
- Azure Advisor
- Estrategias de optimización y cultura FinOps
