Instalación y Configuración de Cilium CNI

Cilium es un plugin de red para Kubernetes que utiliza eBPF (extended Berkeley Packet Filter) para implementar networking, seguridad y observabilidad a nivel del kernel de Linux. A diferencia de otros CNIs, Cilium no depende de iptables, lo que le permite escalar mejor en clústeres grandes y ofrecer políticas de red más expresivas basadas en identidades de servicios.

Requisitos Previos

  • Kubernetes 1.27+ (kubeadm, k3s, EKS, GKE, AKS)
  • Kernel Linux 5.4+ en los nodos (5.10+ recomendado para funcionalidades completas)
  • helm v3 instalado
  • cilium CLI instalado
  • El CNI anterior debe estar desinstalado (o clúster nuevo sin CNI)
# Instalar el CLI de Cilium
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
curl -L --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-amd64.tar.gz
tar xzvf cilium-linux-amd64.tar.gz -C /usr/local/bin
chmod +x /usr/local/bin/cilium

# Verificar versión del kernel en los nodos
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.nodeInfo.kernelVersion}{"\n"}{end}'

Instalación con Helm

# Agregar el repositorio Helm de Cilium
helm repo add cilium https://helm.cilium.io/
helm repo update

# Instalación básica en un clúster existente
helm install cilium cilium/cilium \
  --namespace kube-system \
  --set rollOutCiliumPods=true \
  --set kubeProxyReplacement=true \
  --set k8sServiceHost=<IP-del-API-server> \
  --set k8sServicePort=6443

# Verificar la instalación
cilium status --wait

# Ejecutar la prueba de conectividad
cilium connectivity test

Instalación con configuración completa para producción:

# Crear el archivo de valores de Helm
cat > cilium-values.yaml << 'EOF'
# Configuración de producción de Cilium

# Reemplazar kube-proxy completamente con eBPF
kubeProxyReplacement: true
k8sServiceHost: 192.168.1.100
k8sServicePort: 6443

# Habilitar protocolo WireGuard para cifrado entre nodos
encryption:
  enabled: true
  type: wireguard
  nodeEncryption: true

# Habilitar Hubble para observabilidad
hubble:
  enabled: true
  relay:
    enabled: true
  ui:
    enabled: true
  metrics:
    enabled:
      - dns:query;ignoreAAAA
      - drop
      - tcp
      - flow
      - port-distribution
      - icmp
      - http

# Configuración del IPAM
ipam:
  mode: cluster-pool
  operator:
    clusterPoolIPv4PodCIDRList: ["10.244.0.0/16"]

# Habilitar el plano de datos nativo del host
routingMode: native
autoDirectNodeRoutes: true

# Métricas de Prometheus
prometheus:
  enabled: true
  port: 9962
  serviceMonitor:
    enabled: true

operator:
  prometheus:
    enabled: true
    serviceMonitor:
      enabled: true
EOF

helm install cilium cilium/cilium \
  --namespace kube-system \
  --values cilium-values.yaml

# Verificar pods de Cilium
kubectl get pods -n kube-system -l k8s-app=cilium

Políticas de Red

Las NetworkPolicy de Cilium son más expresivas que las estándar de Kubernetes, soportando políticas a nivel L7.

# Política de red básica: denegar todo el tráfico de entrada por defecto
cat > deny-all-ingress.yaml << 'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: produccion
spec:
  podSelector: {}  # Aplica a todos los pods del namespace
  policyTypes:
    - Ingress
EOF

kubectl apply -f deny-all-ingress.yaml
# CiliumNetworkPolicy avanzada: permitir solo tráfico HTTP GET al servicio API
cat > cilium-policy-api.yaml << 'EOF'
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: api-http-policy
  namespace: produccion
spec:
  endpointSelector:
    matchLabels:
      app: api-backend
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: frontend
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
          rules:
            http:
              - method: "GET"
                path: "/api/.*"
              - method: "POST"
                path: "/api/users"
  egress:
    - toEndpoints:
        - matchLabels:
            app: postgresql
      toPorts:
        - ports:
            - port: "5432"
              protocol: TCP
    # Permitir DNS
    - toEndpoints:
        - matchLabels:
            k8s:io.kubernetes.pod.namespace: kube-system
      toPorts:
        - ports:
            - port: "53"
              protocol: UDP
EOF

kubectl apply -f cilium-policy-api.yaml

Hubble: Observabilidad de Red

Hubble es la capa de observabilidad de Cilium que permite ver el flujo de tráfico entre todos los servicios.

# Instalar el CLI de Hubble
HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
curl -L --remote-name-all https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-amd64.tar.gz
tar xzvf hubble-linux-amd64.tar.gz -C /usr/local/bin
chmod +x /usr/local/bin/hubble

# Acceder a la API de Hubble
cilium hubble port-forward &

# Verificar el estado de Hubble
hubble status

# Ver el flujo de tráfico en tiempo real
hubble observe --follow

# Filtrar por namespace
hubble observe --namespace produccion --follow

# Filtrar por tipo de veredicto (dropped = tráfico bloqueado)
hubble observe --verdict DROPPED --follow

# Ver flujos HTTP
hubble observe --protocol http --follow

# Acceder a la UI de Hubble
kubectl port-forward -n kube-system svc/hubble-ui 8080:80
# Abrir http://localhost:8080 en el navegador

Service Mesh con Cilium

Cilium puede actuar como service mesh sin necesidad de sidecars mediante eBPF.

# Habilitar el modo de mutual TLS (mTLS) transparente
helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  --reuse-values \
  --set authentication.mutual.spire.enabled=true \
  --set authentication.mutual.spire.install.enabled=true

# Crear una política de autenticación mTLS entre servicios
cat > mtls-policy.yaml << 'EOF'
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: require-mtls
  namespace: produccion
spec:
  endpointSelector:
    matchLabels:
      app: api-backend
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: frontend
      authentication:
        mode: "required"  # Requiere mTLS
EOF

kubectl apply -f mtls-policy.yaml

Gestión de Ancho de Banda

# Limitar el ancho de banda de entrada/salida de un pod mediante anotaciones
cat > pod-bandwidth.yaml << 'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: app-limitada
  annotations:
    # Limitar el ancho de banda de entrada a 100 Mbps
    kubernetes.io/ingress-bandwidth: "100M"
    # Limitar el ancho de banda de salida a 50 Mbps
    kubernetes.io/egress-bandwidth: "50M"
spec:
  containers:
    - name: app
      image: nginx:alpine
EOF

kubectl apply -f pod-bandwidth.yaml

# Verificar que el límite está aplicado
cilium endpoint list | grep <pod-ip>

Cluster Mesh

Cluster Mesh permite conectar múltiples clústeres Kubernetes con Cilium.

# Habilitar Cluster Mesh en el primer clúster
cilium clustermesh enable \
  --service-type LoadBalancer \
  --context cluster1

# Habilitar en el segundo clúster
cilium clustermesh enable \
  --service-type LoadBalancer \
  --context cluster2

# Conectar los clústeres entre sí
cilium clustermesh connect \
  --context cluster1 \
  --destination-context cluster2

# Verificar el estado de la conexión
cilium clustermesh status --context cluster1

# Exponer un servicio globalmente (accesible desde ambos clústeres)
kubectl annotate service mi-servicio \
  service.cilium.io/global=true \
  service.cilium.io/shared=true

Solución de Problemas

Pods en estado Pending sin CNI:

# Verificar que Cilium está instalado correctamente
cilium status
kubectl get pods -n kube-system -l k8s-app=cilium -o wide

# Ver logs del pod de Cilium con problemas
kubectl logs -n kube-system <cilium-pod> --previous

# Verificar la instalación del CNI
ls -la /etc/cni/net.d/

Políticas de red bloqueando tráfico inesperado:

# Ver el tráfico bloqueado con Hubble
hubble observe --verdict DROPPED --follow

# Listar todas las políticas activas en un namespace
kubectl get ciliumnetworkpolicies -n produccion

# Ver la identidad de seguridad asignada a los pods
cilium endpoint list

Alto uso de CPU en nodos:

# Ver estadísticas de eBPF
cilium metrics list | grep -i bpf

# Verificar mapas de eBPF
cilium bpf map list

# Ver los logs del agente con nivel debug
kubectl logs -n kube-system <cilium-pod> -- cilium-agent --debug

Conclusión

Cilium con eBPF proporciona un CNI de alto rendimiento que va mucho más allá de las capacidades de networking básicas: las políticas L7, la observabilidad con Hubble y la capacidad de reemplazar kube-proxy lo convierten en una plataforma completa de networking para Kubernetes. Para clústeres que necesitan escalar a cientos de nodos o que requieren visibilidad detallada del tráfico de red, Cilium es la solución más avanzada disponible hoy en día.