Preparación del entorno
Requisitos de hardware y software
Configuración mínima:
- Nodo de control: 2 núcleos de CPU / 4 GB de RAM / 50 GB de disco
- Nodo de trabajo: 2 núcleos de CPU / 4 GB de RAM / 100 GB de disco
- Sistema operativo: Ubuntu 20.04 / CentOS 7.9+
Planificación de red:
# Ejemplo de asignación de IPs para nodos
10.0.0.10 control-plane01
10.0.0.11 worker-node01
10.0.0.12 worker-node02
# CIDR de red para Pods: 172.16.0.0/16
# CIDR de red para Servicios: 10.96.0.0/12
Configuración inicial del sistema
# Ejecutar en todos los nodos
sudo swapoff -a && sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
sudo systemctl disable --now firewalld ufw
sudo setenforce 0 && sudo sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
# Configurar nombres de host
sudo hostnamectl set-hostname control-plane01
echo "10.0.0.10 control-plane01" | sudo tee -a /etc/hosts
echo "10.0.0.11 worker-node01" | sudo tee -a /etc/hosts
Instalación de componentes de Kubernetes
Instalación del motor de contenedores (containerd)
# Ejecutar en todos los nodos
sudo apt-get update && sudo apt-get install -y containerd
sudo mkdir -p /etc/containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl enable containerd && sudo systemctl restart containerd
Instalación de herramientas de clúster (kubeadm, kubelet, kubectl)
# Agregar repositorio de Kubernetes
sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
# Instalar paquetes
sudo apt-get update
sudo apt-get install -y kubelet=1.28.0-1.1 kubeadm=1.28.0-1.1 kubectl=1.28.0-1.1
sudo apt-mark hold kubelet kubeadm kubectl
Despliegue del plano de control
Enicialización del nodo principal
sudo kubeadm init \
--apiserver-advertise-address=10.0.0.10 \
--image-repository registry.k8s.io \
--kubernetes-version v1.28.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=172.16.0.0/16
# Configurar acceso con kubectl
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Unión de nodos trabajadores
# Ejecutar en los nodos trabajadores usando el comando generado tras la inicialización
kubeadm join 10.0.0.10:6443 \
--token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
Configuración de red y almacenamiento
Instalación del plugin de red Cilium
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium --version 1.14.1 \
--namespace kube-system \
--set kubeProxyReplacement=strict \
--set k8sServiceHost=10.0.0.10 \
--set k8sServicePort=6443
# Verificar estado
kubectl get pods -n kube-system -l k8s-app=cilium
Configuración de almacenamiento persistente con Ceph RBD
# En el servidor de almacenamiento (ejemplo simplificado)
sudo ceph osd pool create kube 128
sudo ceph auth get-or-create client.kube mon 'profile rbd' osd 'profile rbd pool=kube' -o /etc/ceph/ceph.client.kube.keyring
# Despliegue en Kubernetes
kubectl apply -f - <<EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ceph-rbd
provisioner: rook.io/rbd
parameters:
clusterID: rook-ceph
pool: kube
imageFormat: "2"
imageFeatures: layering
EOF
Observabilidad y registros
Stack de monitoreo con Mimir y Grafana
helm repo add grafana https://grafana.github.io/helm-charts
helm install monitoring-stack grafana/k8s-monitoring \
--namespace observability \
--create-namespace \
--set cluster.name="mi-cluster" \
--set metrics.enabled=true \
--set logs.enabled=true \
--set traces.enabled=false
Sistema de registros con Loki y Promtail
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: log-collector
namespace: observability
spec:
selector:
matchLabels:
app: log-agent
template:
metadata:
labels:
app: log-agent
spec:
containers:
- name: agent
image: grafana/promtail:2.9.0
args:
- -config.file=/etc/promtail/config.yml
volumeMounts:
- name: config
mountPath: /etc/promtail
- name: varlog
mountPath: /var/log
readOnly: true
volumes:
- name: config
configMap:
name: promtail-config
- name: varlog
hostPath:
path: /var/log
Seguridad y control de acceso
Implementación de políticas RBAC
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: app-deployer
rules:
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["create", "update", "patch", "get", "list", "watch"]
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch"]
Políticas de seguridad de red
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
Actualización y mantenimiento
Proceso de actualización del clúster
# Actualizar kubeadm
sudo apt-get update && sudo apt-get install -y kubeadm=1.29.0-1.1
kubeadm upgrade plan
sudo kubeadm upgrade apply v1.29.0
# Drenar y actualizar nodos
kubectl drain worker-node01 --ignore-daemonsets --delete-emptydir-data
sudo apt-get install -y kubelet=1.29.0-1.1 kubectl=1.29.0-1.1
sudo systemctl daemon-reload && sudo systemctl restart kubelet
kubectl uncordon worker-node01
Optimización de programación de recursos
apiVersion: v1
kind: Pod
metadata:
name: web-app
labels:
tier: frontend
spec:
containers:
- name: app-container
image: my-web-app:2.1
resources:
requests:
memory: "128Mi"
cpu: "200m"
limits:
memory: "256Mi"
cpu: "400m"
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: tier
operator: In
values: ["frontend"]
topologyKey: kubernetes.io/hostname
Alta disponibilidad y escalabilidad
Plano de control con múltiples nodos
# Usar balanceador de carga para punto final del clúster
sudo kubeadm init --control-plane-endpoint "lb.api.mi-dominio.com:6443" \
--upload-certs \
--pod-network-cidr=172.16.0.0/16
# Unir nodos de control adicionales
kubeadm join lb.api.mi-dominio.com:6443 \
--token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:... \
--control-plane --certificate-key ...
Autoescalado de pods basado en métricas personalizadas
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-gateway-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-gateway
minReplicas: 2
maxReplicas: 20
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 100
periodSeconds: 30
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: 1k
Diagnóstico y resolución de problemas
Guía de problemas comunes
| Síntoma | Comando de diagnóstico | Solución típica |
|---|---|---|
| Pod en estado CrashLoopBackOff | kubectl logs [pod-name] --previous |
Revisar variables de entorno y dependencias |
| Servicio no responde | kubectl describe svc [service-name] |
Verificar selector de etiquetas y endpoints |
| Nodo en estado NotReady | kubectl describe node [node-name] |
Comprobar kubelet, recursos y conectividad |
Conjunto de herramientas de diagnóstico
# Monitoreo de eventos del clúster
kubectl get events --field-selector type=Warning --sort-by='.lastTimestamp'
# Prueba de conectividad entre pods
kubectl run test-pod --image=busybox:1.36 --rm -it --restart=Never -- wget -qO- http://servicio-interno:8080
# Inspección de rendimiento
kubectl top pods -n kube-system --sort-by=cpu