Kubernetes Avanzado — Más Allá de lo Básico
Guía avanzada de Kubernetes: operators, custom resources, admission controllers, multi-cluster management y hardening productivo para usuarios experimentados.
Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.
Overview
Kubernetes se ha convertido en la plataforma estándar para orquestación de containers, pero dominar sus features avanzadas requiere entender su modelo de extensibilidad, modelo de seguridad y patrones operacionales. Esta guía cubre operators, custom resources, admission controllers, gestión multi-cluster y prácticas de hardening para ambientes productivos.
When to Use
- Estás ejecutando workloads stateful en Kubernetes
- Necesitas hacer cumplir políticas organizacionales sobre recursos de cluster
- Gestionas múltiples clusters a través de regiones o clouds
- Quieres automatizar tareas operacionales complejas
Operators y Custom Resources
Custom Resource Definitions (CRDs)
Los CRDs extienden la API de Kubernetes con recursos específicos de dominio.
# crd.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: databases.mycompany.com
spec:
group: mycompany.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
engine:
type: string
enum: ["postgres", "mysql"]
replicas:
type: integer
minimum: 1
maximum: 5
scope: Namespaced
names:
plural: databases
singular: database
kind: Database
Escribir un Operator
Los operators reconcilian el estado deseado (spec del CRD) con el estado actual (recursos en ejecución).
func (r *DatabaseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
var db myv1.Database
if err := r.Get(ctx, req.NamespacedName, &db); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
var sts appsv1.StatefulSet
if err := r.Get(ctx, req.NamespacedName, &sts); errors.IsNotFound(err) {
sts = r.buildStatefulSet(db)
if err := r.Create(ctx, &sts); err != nil {
return ctrl.Result{}, err
}
}
if *sts.Spec.Replicas != db.Spec.Replicas {
sts.Spec.Replicas = &db.Spec.Replicas
if err := r.Update(ctx, &sts); err != nil {
return ctrl.Result{}, err
}
}
return ctrl.Result{}, nil
}
Frameworks populares: Operator SDK, kubebuilder, kopf (Python).
Admission Controllers
Validating Webhooks
Rechazan recursos que violan políticas antes de ser persistidos.
func (v *Validator) Handle(ctx context.Context, req admission.Request) admission.Response {
pod := &corev1.Pod{}
if err := v.Decoder.Decode(req, pod); err != nil {
return admission.Errored(http.StatusBadRequest, err)
}
for _, container := range pod.Spec.Containers {
if container.Resources.Limits == nil {
return admission.Denied("Todos los containers deben especificar resource limits")
}
}
return admission.Allowed("")
}
Mutating Webhooks
Modifican recursos antes de ser persistidos (ej. inyectar sidecars).
func (m *Mutator) Handle(ctx context.Context, req admission.Request) admission.Response {
pod := &corev1.Pod{}
if err := m.Decoder.Decode(req, pod); err != nil {
return admission.Errored(http.StatusBadRequest, err)
}
pod.Spec.Containers = append(pod.Spec.Containers, corev1.Container{
Name: "istio-proxy",
Image: "istio/proxyv2:1.20.0",
})
return admission.PatchResponseFromRaw(req.Object.Raw, pod)
}
Gestión Multi-Cluster
Federación de Clusters
Despliega workloads a través de múltiples clusters para alta disponibilidad y distribución geográfica.
apiVersion: types.kubefed.io/v1beta1
kind: FederatedDeployment
metadata:
name: frontend
spec:
template:
spec:
replicas: 3
selector:
matchLabels:
app: frontend
template:
spec:
containers:
- name: frontend
image: myapp/frontend:v1
overrides:
- clusterName: cluster-asia
clusterOverrides:
- path: "/spec/replicas"
value: 5
Service Mesh para Multi-Cluster
Istio y Linkerd proveen service discovery cross-cluster y mTLS.
┌─────────────────────┐ ┌─────────────────────┐
│ Cluster US │◀───────▶│ Cluster EU │
│ ┌───────────────┐ │ mTLS │ ┌───────────────┐ │
│ │ Service A │ │────────▶│ │ Service B │ │
│ └───────────────┘ │ │ └───────────────┘ │
│ ▲ │ │ ▲ │
│ Istio Gateway │ │ Istio Gateway │
└─────────────────────┘ └─────────────────────┘
Security Hardening
Pod Security Standards
apiVersion: v1
kind: Pod
metadata:
name: secure-app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:v1
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
limits:
memory: "256Mi"
cpu: "500m"
requests:
memory: "128Mi"
cpu: "250m"
Network Policies
Restringe tráfico pod-a-pod al mínimo requerido.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-policy
spec:
podSelector:
matchLabels:
app: frontend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 8080
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
RBAC Least Privilege
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: deployment-manager
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: deployment-manager-binding
subjects:
- kind: ServiceAccount
name: ci-cd
roleRef:
kind: Role
name: deployment-manager
apiGroup: rbac.authorization.k8s.io
Patrones Avanzados de Helm
Library Charts
Templates de Helm reutilizables compartidos entre múltiples charts.
# Chart.yaml (library chart)
apiVersion: v2
name: common
description: Common Helm templates
type: library
version: 1.0.0
Post-Renderers
Modifica manifests generados antes de aplicación (ej. inyectar patches de Kustomize).
helm install myapp ./chart --post-renderer ./kustomize.sh
Errores Comunes
- Ejecutar todo como root — siempre configura
runAsNonRoot: true - Sin resource limits — causa problemas de noisy neighbor y OOM kills
- Usar tag
latest— imposible hacer rollback; pin a digests o versiones semánticas - Ignorar network policies — los pods pueden hablar con todo por defecto
- Sin PodDisruptionBudgets — rolling updates drenan nodos y causan downtime
- Guardar secrets en ConfigMaps — usa external secret operators o sealed secrets
FAQ
¿Debería usar Helm o YAML plano? Helm para aplicaciones reusable y templated. YAML plano (con Kustomize) para overlays más simples y específicas de ambiente. Muchos equipos usan ambos: Helm para shared services, Kustomize para application manifests.
¿Cómo debuggeo admission webhooks?
Verifica conectividad del servicio webhook, certificados TLS y logs del API server. Usa kubectl describe en recursos rechazados y revisa logs del pod webhook.
¿Cuándo debería usar un operator? Cuando necesitas automatizar gestión compleja del lifecycle: backups, failover, upgrades o scaling para aplicaciones stateful. Para apps stateless simples, controladores estándar son suficientes.
Recursos Relacionados
Terraform Best Practices — Modules, State, and Workspaces
A practical guide to Terraform best practices: module design, remote state management, workspaces, and security for production-grade infrastructure as code.
GuideObservability — Metrics, Logs, and Traces Complete Guide
A practical guide to observability: the three pillars (metrics, logs, traces), implementing with Prometheus, Grafana, Loki, Tempo/Jaeger, and building SLO-driven alerting.
GuideAWS Basics — Core Services for Developers
A practical guide to AWS core services for developers: compute, storage, databases, networking, and security fundamentals with hands-on examples.