Kubernetes: clústeres y charts de ayuda
Kubernetes: clústeres y charts de ayuda
1) Arquitectura del clúster - vista desde arriba
Control Plano: 'kube-apiserver', 'etcd', 'kube-scheduler', 'kube-controller-manager', (en las nubes controladas, una parte está oculta).
Worker: 'kubelet', CRI-rantime (containerd/CRI-O), plugin CNI, kube-proxy/ebpf-proxy.
Red intramuros: Pod-to-Pod, Service-VIP/ClusterIP, DNS CoreDNS.
Almacenamiento: controladores CSI, provisión dinámica de PVC → PV (StorageClass).
Límites de falla: nodo/AZ/región. Colocar réplicas por zona (TopologySpreadConstraints/anti-affinity).
los papeles Tipo
Equipo de plataforma: crea/actualiza clústeres, CNI/CSI/Ingress, políticas y GitOps.
Equipos de productos: desploye listas/lanzamientos, sigue las políticas de seguridad y recursos.
2) Ciclo de vida del clúster
Creación: kOps, kubeadm, Rancher, EKS/AKS/GKE. Active inmediatamente la autenticación OIDC y la auditoría.
Actualizaciones: versiones minor por turnos (control plane → nodos), controladas por maxUnavailable, pruebas de stage.
Add-ons (todos a través de Helm/GitOps): CNI (Calico/Cilium), controlador CSI, controlador Ingress (NGINX/Gateway API/Contour/Traefik), Metinx/Gateway rics-Server, Cluster-Autoscaler, Node-Local DNS, lógica/métricas/trace.
Backups: etcd snapshot (si se ha autogestionado), Velero para namespace/PVC.
3) Redes, servicios e ingress
CNI: Calico (NetworkPolicy), Cilium (eBPF/servicemesh-фичи).
Servicio: 'ClusterIP', 'NodePort', 'LoadBalancer' (equilibrio de nube L4), 'ExternalName'.
API de Ingress/Gateway: Enrutamiento L7, TLS, historial de rate-limit/WAF en el perímetro.
NetworkPolicy: el valor predeterminado es deny-all + allow explícito por namespace/label.
Servicio principal ('clusterIP: None') para StatefulSet y servicio discovery.
4) Almacenamiento (CSI) y estados
StorageClass: 'reclaimPolicy', 'volumeBindingMode' ('WaitForFirstConsumer' para una mejor colocación).
StatefulSet: nombres/volúmenes estables ('volumeClaimTemplates'), 'podManagementPolicy: Parallel' para implementaciones rápidas.
ReadWriteMany: use archivos distribuidos (EFS/Filestore) cuidadosamente - evalúe la latencia.
Instantáneas: 'VolumenSnapshotClass' + cron-backs.
5) Polivalencia y política
Namespaces por producto/entorno.
RBAC: roles mínimos, cuentas de servicio individuales, 'Role '/' RoleBinding' en lugar de 'ClusterRole' donde sea posible.
PSA (Pod Security Admission): modos 'baseline '/' restricted' (sustitución de PSP).
ResourceQuota / LimitRange: потолки CPU/Memory/PVC/LoadBalancer.
OPA Gatekeeper/Kyverno: política de admisión (por ejemplo, prohibición ': latest', requisito de 'resources', 'readOnlyRootFilesystem').
ImagePolicy/webhooks: verificación de la firma de imágenes (cosign/policy-controller).
6) Observabilidad y explotación
Métricas: Prometheus-stack, kube-state-metrics, node-exportadores.
Logs: Fluent Bit/Vector → objeto/ES/OpenSearch, rotación en nodos.
Tracks: OpenTelemetry Collector.
SLO-dashboards: modelo RED en ingress y servicios clave.
Auto Scale: HPA (por métricas de aplicación), VPA para fondo, Cluster-Autoscaler para nodos.
7) Patrones de manifiestos (parche)
Deployment (extracto):yaml apiVersion: apps/v1 kind: Deployment metadata: { name: api, labels: { app: api } }
spec:
replicas: 3 strategy: { type: RollingUpdate, rollingUpdate: { maxUnavailable: 0, maxSurge: 1 } }
selector: { matchLabels: { app: api } }
template:
metadata:
labels: { app: api }
spec:
serviceAccountName: api-sa securityContext: { runAsNonRoot: true, fsGroup: 2000 }
containers:
- name: api image: registry. example. com/api:1. 2. 3 ports: [{ containerPort: 8080 }]
resources: { requests: { cpu: "200m", memory: "256Mi" }, limits: { cpu: "1", memory: "512Mi" } }
readinessProbe: { httpGet: { path: /healthz, port: 8080 }, periodSeconds: 5 }
livenessProbe: { httpGet: { path: /livez, port: 8080 }, initialDelaySeconds: 20 }
StatefulSet (fragmento):
yaml apiVersion: apps/v1 kind: StatefulSet metadata: { name: db }
spec:
serviceName: db replicas: 3 podManagementPolicy: Parallel selector: { matchLabels: { app: db } }
template:
metadata: { labels: { app: db } }
spec:
containers:
- name: db image: postgres:16-alpine volumeMounts: [{ name: data, mountPath: /var/lib/postgresql/data }]
volumeClaimTemplates:
- metadata: { name: data }
spec:
accessModes: ["ReadWriteOnce"]
resources: { requests: { storage: 100Gi } }
storageClassName: fast-ssd
PDB (PodDisruptionBudget):
yaml apiVersion: policy/v1 kind: PodDisruptionBudget metadata: { name: api-pdb }
spec:
minAvailable: 2 selector: { matchLabels: { app: api } }
Ingress (Nginx, breve):
yaml apiVersion: networking. k8s. io/v1 kind: Ingress metadata:
name: api annotations:
nginx. ingress. kubernetes. io/proxy-read-timeout: "30"
spec:
tls: [{ hosts: ["api. example. com"], secretName: api-tls }]
rules:
- host: api. example. com http:
paths:
- path: /
pathType: Prefix backend: { service: { name: api, port: { number: 80 } } }
8) Helm v3 - fundamentos y estructura
Chart = plantillas + valores + metadatos.
mychart/
Chart. yaml # name, version (semver), type (application/library), dependencies values. yaml # default values. schema. json # (recommended) validation values templates/# .yaml. gotmpl (Deployment, Service, Ingress, …)
templates/tests/ # helm tests (smoke)
charts/# local dependencies (or OCI dependencies)
Chart. yaml (ejemplo):
yaml apiVersion: v2 name: api description: API service type: application version: 1. 4. 0 # chart version (semver)
appVersion: "1. 2. 3" # dependencies application version:
- name: redis version: 17. x.x repository: "oci://registry. example. com/charts"
9) Plantillas de Helm - Prácticas
Utilice helpers en '_ helpers. tpl 'para nombres/etiquetas/anotaciones.
En todas partes especifique 'recursos', 'seguridadContext',' readiness/liveness '.
Generar labels siguiendo un esquema estandarizado ('app. kubernetes. io/`).
Hacer fiches opcionales a través de 'valores' (ingress/hpa/pdb/servicemonitor).
Habilita 'valores. schema. json '- parar de confecciones incorrectas.
Para datos sensibles, Secretos de operadores externos (Outternal Secrets, SOPS) en lugar de almacenarlos en valores.
gotmpl
{{- define "api. fullname" -}}
{{- printf "%s-%s".Chart. Name. Release. Name trunc 63 trimSuffix "-" -}}
{{- end -}}
Deployment. tpl (fragmento):
gotmpl apiVersion: apps/v1 kind: Deployment metadata:
name: {{ include "api. fullname". }}
labels: {{- include "api. labels". nindent 4 }}
spec:
replicas: {{.Values. replicaCount }}
strategy:
rollingUpdate:
maxSurge: 1 maxUnavailable: 0 selector:
matchLabels: {{- include "api. selectorLabels". nindent 6 }}
template:
metadata:
labels: {{- include "api. selectorLabels". nindent 8 }}
spec:
serviceAccountName: {{ include "api. serviceAccountName". }}
securityContext: {{- toYaml. Values. podSecurityContext nindent 8 }}
containers:
- name: {{.Chart. Name }}
image: "{{.Values. image. repository }}:{{.Values. image. tag }}"
imagePullPolicy: IfNotPresent ports: [{ containerPort: {{.Values. service. port }} }]
resources: {{- toYaml. Values. resources nindent 10 }}
envFrom:
- secretRef: { name: {{.Values. secretsRef }} }
10) Dependencias, repositorios y OCI
Helm v3 admite registros OCI: 'oci ://registry/org/charts'.
Coloque las versiones de las dependencias ('^ 1. 2. 0`, `~1. 2 ') y corre' helm dependency build'.
Firme la lista (prov), almacene los artefactos en el repositorio de artefactos de CI.
Tablas de biblioteca: plantillas compartidas (ingress/servicemonitor) para volver a usar.
11) Hooks, CRD y orden de operaciones
Hooks: `pre-install`, `post-install`, `pre-upgrade`, `post-upgrade`, `test`. Añadir policies ('before-hook-creation', 'hook-succeeded').
CRD: ponga en 'crds/' (se instalarán hasta los templates), evite los apdates de CRD «sobre la marcha» - haga migraciones por separado.
Migraciones de DB/inicialización - job-hook con idempotency y timeout.
12) Prueba de lista y CI
'helm lint' + validación del esquema.
Helm unittest (unidad), chart-testing (ct) - montaje/instalación en kind/minikube en CI.
Pruebas de patrones Snapshot ('helm template' → compararse con la referencia).
Smoke pruebas 'helm test' (levantar 'Pod' con chequeos).
13) GitOps (Argo CD/Flux)
La fuente de la verdad es el repositorio. La lista se almacena como HelmRelease/HelmChart (Flux) o Application (Argo).
Políticas xinca: auto-sync con preune/self-heal, estados y checks de salud.
Versiones promocionales: tag-bots/semver-range, PR-flow.
Divide el repo en apps (listas) y env (overrides/values).
Gestión secreta: SOPS (age/KMS), Secrets externos.
14) Seguridad: mínimo necesario
PSA restringido: sin privilegios, sin hostPath, con capabilities limitadas, rootfs read-only.
ImagePolicy: sólo imágenes firmadas/de confianza.
NetworkPolicy: «está bloqueado de forma predeterminada».
RBAC: cuenta de servicio per-app, 'Role '/' RoleBinding' en namespace.
Control de administración: Gatekeeper/Kyverno reglas (recursos/límites, labels, no latest).
Secretos: SOPS/Secrets externos; no poner secretos en values/plain Git.
15) Anti-patrones
': latest' en listas e imágenes; ausencia de 'valores. schema. json`.
Una enorme lista «para todo» en lugar de una modular.
Los CRD se actualizan con plantillas en 'templates/' → caos en las actualizaciones.
Nombres/puerto/namespace rígidos en las plantillas.
La falta de recursos/límites y muestras → la deriva de latencia y la inestabilidad.
No hay PDB → no es posible un downtime cero con drain/upgrades.
Secretos en Git sin cifrado; manifiestos sin políticas-cheques.
16) Lista de verificación de implementación (0-45 días)
0-10 días
Crear un esqueleto base con '_ helpers. tpl', labels, probes, resources, PDB/Ingress opcional.
Включить PSA restricted, NetworkPolicy deny-all, ResourceQuota/LimitRange.
Configurar GitOps (Argo/Flux), registro privado, firma de imágenes/listas.
11-25 días
Dividir la lista en módulos/dependencias, añadir 'valores. schema. json ', pruebas (' helm lint', unit, ct).
Conectar observabilidad (ServiceMonitor/PodMonitor), agente de registro, OTel.
Introduzca el proceso de actualización: staging → canary → prod, hook-migration con rollback.
26-45 días
Automatizar actualizaciones de dependencias (bots/semver-ranges + PR).
Agregue las políticas de Gatekeeper/Kyverno y los informes de políticas a CI.
Documentar la actualización de clúster runbook, procedimientos DR (Velero/etc snapshot).
17) Métricas de madurez
El 100% de las aplicaciones se desinflan a través de Helm/GitOps, sin 'kubectl apply' manualmente.
Todas las listas tienen 'valores. schema. json ', pruebas, firma y versiones fijas de las dependencias.
PSA restricted/NetworkPolicy está habilitado en todo el namespace.
PDB y HPA están presentes en todos los servicios críticos.
Secretos seguros (SOPS/External Secrets), política «no latest», firma de imágenes.
Las actualizaciones del clúster y la lista se realizan sin downtime (canario/azul-verde), las pruebas de restauración son regulares.
18) Conclusión
Fuerte fundación de Kubernetes = arquitectura de clúster confiable + estricta política + Listas de calidad industrial de Helm bajo GitOps. Estandarice las plantillas, proteja el entorno PSA/NetworkPolicy/RBAC, valide los valores y automatice las pruebas, la firma y la promoción. Luego, las actualizaciones y lanzamientos se volverán predecibles y la plataforma será sostenible y conveniente para los equipos de productos.