Files
Homelabv4/infrastructure/cilium/manifests/network-policies/baseline.yaml
T
Scooby Husky 7b3669e9a6 Fix CNPG operator -> instance status communication + add CNPG health check
Two related fixes, found while working through why authentik/n8n/gitlab
ArgoCD Applications showed Unknown/stuck health despite pods being fine:

1. ArgoCD has no built-in health check for CNPG's Cluster CRD, so it
   always reported "Unknown" - and since app-level health rolls up to
   the worst resource status, every app with a CNPG Cluster showed
   Unknown/Progressing regardless of actual state. Added a Lua health
   check (resource.customizations.health.postgresql.cnpg.io_Cluster)
   reading .status.conditions[Ready] / .status.phase.

2. Once that started reporting real status instead of masking it,
   pg-authentik showed a genuine problem: CNPG's operator couldn't
   reach its Postgres instances' status API (port 8000) - "Cannot
   extract Pod status ... context deadline exceeded" - because:
   a) authentik-ingress's CiliumNetworkPolicy never allowed cnpg-system
      as a source (crowdsec-ingress already had this exception,
      authentik-ingress was just missing it - inconsistency, not
      deliberate).
   b) Even after fixing (a), still blocked - pg-authentik's pods are
      ambient-mesh-enrolled, so the connection actually goes through
      ztunnel's HBONE tunnel (port 15008) first, same underlying issue
      as the argocd-redis fix from earlier today. Rather than keep
      finding and patching this per-namespace as it recurs, added a
      cluster-wide CiliumClusterwideNetworkPolicy allowing HBONE
      broadly - ztunnel's own mTLS/SPIFFE identity verification is the
      real security boundary for mesh traffic; Cilium blocking the
      tunnel port itself was only breaking legitimate traffic, not
      adding meaningful protection on top.

Verified live: CNPG operator immediately went from failing status
extraction to successfully reconciling (recreating a pod to reattach
its PVC) once both fixes were in place.
2026-08-17 16:41:11 -05:00

174 lines
5.4 KiB
YAML

# Baseline CiliumNetworkPolicies for critical infrastructure namespaces
# Provides L3/L4 ingress segmentation (Istio waypoints handle L7)
#
# IMPORTANT: CiliumNetworkPolicy egress rules with empty `{}` only match
# Cilium-managed endpoints — NOT kube-apiserver, host, remote-node, or world.
# Omit egress rules entirely to allow all egress (default behavior).
# Ingress rules must explicitly include fromEntities for host/kube-apiserver
# traffic (health probes, API server webhooks, kubelet).
# --- Vault: Only accessible from ESO, authentik sync scripts, and Prometheus ---
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: vault-ingress
namespace: vault
spec:
endpointSelector: {}
ingress:
# Kubernetes API server and kubelet (health probes, webhooks)
- fromEntities:
- host
- kube-apiserver
- remote-node
# Ingress gateways
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: istio-system
istio: ingressgateway
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: envoy-gateway-system
# External Secrets Operator
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: external-secrets
# Prometheus scraping
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: prometheus
# Vault internal (raft replication)
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: vault
# --- Authentik: Accessible from ingress, apps doing OIDC, and Prometheus ---
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: authentik-ingress
namespace: authentik
spec:
endpointSelector: {}
ingress:
# Kubernetes API server and kubelet (health probes, webhooks)
- fromEntities:
- host
- kube-apiserver
- remote-node
# Ingress gateways
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: istio-system
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: envoy-gateway-system
# Internal authentik traffic (server <-> worker, pg access)
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: authentik
# CNPG operator - status port (8000) queries on pg-authentik instances.
# crowdsec-ingress below already has this; was missing here, which broke
# CNPG's own health/status reporting for pg-authentik ("Cannot extract Pod
# status ... context deadline exceeded" in the operator logs) even though
# the database itself was working fine. Confirmed 2026-08-17.
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: cnpg-system
# Apps doing OIDC token exchange
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: argocd
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: gitlab
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: grafana
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: n8n
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: nextcloud
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: home-assistant
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: guacamole
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: netbird
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: cattle-system
# Prometheus scraping
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: prometheus
# --- CrowdSec: LAPI + agent + Prometheus + CNPG ---
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: crowdsec-ingress
namespace: crowdsec
spec:
endpointSelector: {}
ingress:
# Kubernetes API server and kubelet (health probes, webhooks)
- fromEntities:
- host
- kube-apiserver
- remote-node
# Intra-namespace (LAPI <-> agent)
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: crowdsec
# CNPG operator
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: cnpg-system
# Prometheus scraping
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: prometheus
# --- Rook-Ceph: Only internal + Prometheus + CSI consumers ---
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: rook-ceph-ingress
namespace: rook-ceph
spec:
endpointSelector: {}
ingress:
# Kubernetes API server and kubelet (health probes, webhooks, CSI mounts)
- fromEntities:
- host
- kube-apiserver
- remote-node
# Ingress gateways (Ceph dashboard)
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: istio-system
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: envoy-gateway-system
# Internal Ceph traffic
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: rook-ceph
# Prometheus scraping
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: prometheus
# CSI consumers (any namespace can mount Ceph volumes via CSI)
- fromEndpoints:
- {}