Loading...
Loading...
Manage Cilium network policies: profile selection, access labels, Hubble debugging, platform namespace CNPs, and emergency escape hatch procedures. Use when: (1) Deploying a new application and setting network profile, (2) Debugging blocked traffic with Hubble, (3) Adding shared resource access, (4) Creating platform namespace CNPs, (5) Using the escape hatch for emergencies, (6) Verifying network policy enforcement. Triggers: "network policy", "hubble", "dropped traffic", "cilium", "blocked traffic", "network profile", "access label", "escape hatch", "cnp", "ccnp"
npx skill4agent add ionfury/homelab network-policynetwork-policy.homelab/profile=<value>kube-systemmonitoringdatabase| Profile | Ingress | Egress | Use Case |
|---|---|---|---|
| None | DNS only | Batch jobs, workers |
| Internal gateway | DNS only | Internal dashboards |
| Internal gateway | DNS + HTTPS | Internal apps calling external APIs |
| Both gateways | DNS + HTTPS | Public-facing web apps |
standardinternal-egressinternalisolatedkubectl applyapiVersion: v1
kind: Namespace
metadata:
name: my-app
labels:
network-policy.homelab/profile: standardlabels:
network-policy.homelab/profile: standard
access.network-policy.homelab/postgres: "true" # PostgreSQL (port 5432)
access.network-policy.homelab/dragonfly: "true" # Dragonfly/Redis (port 6379)
access.network-policy.homelab/garage-s3: "true" # Garage S3 (port 3900)
access.network-policy.homelab/kube-api: "true" # Kubernetes API (port 6443)hubble observe --verdict DROPPED --namespace my-app --since 5m# All drops in a namespace
hubble observe --verdict DROPPED --namespace my-app --since 5m
# With source/destination details
hubble observe --verdict DROPPED --namespace my-app --since 5m -o json | \
jq '{src: .source.namespace + "/" + .source.pod_name, dst: .destination.namespace + "/" + .destination.pod_name, port: (.l4.TCP.destination_port // .l4.UDP.destination_port)}'| Drop Pattern | Likely Cause | Fix |
|---|---|---|
Egress to | Missing DNS baseline | Should not happen — check if baseline CCNP exists |
Egress to | Missing postgres access label | Add |
Egress to | Missing dragonfly access label | Add |
Egress to internet | Profile doesn't allow HTTPS egress | Switch to |
Ingress from | Profile doesn't allow gateway ingress | Switch to |
Ingress from | Missing baseline | Should not happen — check baseline CCNP |
# DNS resolution
hubble observe --namespace my-app --protocol UDP --port 53 --since 5m
# Database connectivity
hubble observe --namespace my-app --to-namespace database --port 5432 --since 5m
# Internet egress
hubble observe --namespace my-app --to-identity world --port 443 --since 5m
# Gateway ingress
hubble observe --from-namespace istio-gateway --to-namespace my-app --since 5m
# Prometheus scraping
hubble observe --from-namespace monitoring --to-namespace my-app --since 5m# List all policies affecting a namespace
kubectl get cnp -n my-app
kubectl get ccnp | grep -E 'baseline|profile'
# Check which profile is active
kubectl get namespace my-app --show-labels | grep network-policykubectl label namespace <ns> network-policy.homelab/enforcement=disabledNetworkPolicyEnforcementDisabledNetworkPolicyEnforcementDisabledLonghubble observe --namespace <ns> --since 1mkubectl applykubectl label namespace <ns> network-policy.homelab/enforcement-docs/runbooks/network-policy-escape-hatch.mdkubernetes/platform/config/network-policy/platform/kube-system/kube-dnsmonitoringhealth169.254.0.0/16istio-system/ztunnel---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: <namespace>-default
namespace: <namespace>
spec:
description: "<Namespace purpose>: describe allowed traffic"
endpointSelector: {}
ingress:
# Health probes
- fromEntities: [health]
- fromCIDR: ["169.254.0.0/16"]
# Prometheus scraping
- fromEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: monitoring
app.kubernetes.io/name: prometheus
toPorts:
- ports:
- port: "<metrics-port>"
protocol: TCP
# HBONE (if mesh participant)
- fromEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: istio-system
app: ztunnel
toPorts:
- ports:
- port: "15008"
protocol: TCP
egress:
# DNS
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
# HBONE (if mesh participant)
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: istio-system
app: ztunnel
toPorts:
- ports:
- port: "15008"
protocol: TCPkubernetes/platform/config/network-policy/platform/kustomization.yamldefault-denyanykubectlkubectl apply