Skip to content

Kubernetes NetworkPolicy versus CiliumNetworkPolicy: CCA practice questions

Cilium enforces the standard Kubernetes NetworkPolicy and adds its own resources next to it, and it can run all of them at once. Knowing where the standard API stops tells you when a Cilium resource is needed.

By Ibrahim Yesilay · Published · Updated

Independent community practice, not affiliated with or endorsed by CNCF or The Linux Foundation.

What Kubernetes NetworkPolicy versus CiliumNetworkPolicy covers in CCA

Cilium enforces the standard Kubernetes NetworkPolicy and adds its own resources next to it, and it can run all of them at once. Knowing where the standard API stops tells you when a Cilium resource is needed.

NetworkPolicy works at layers 3 and 4. A policy selects pods in its own namespace with a podSelector, declares policyTypes, and lists allowed peers as podSelector, namespaceSelector or ipBlock together with ports and endPort. Policies are additive allow-lists: a pod is isolated for a direction once any policy with that type selects it. The Kubernetes documentation lists what the API cannot express, and the list maps closely onto Cilium features. There is no explicit deny, no TLS or other application-layer logic, no node-specific policy, no default policy across all namespaces, no targeting of Services by name, and no logging of allowed or blocked connections.

CiliumNetworkPolicy keeps the same namespaced shape but covers layers 3 to 7. It adds HTTP and DNS rules under toPorts, DNS-name destinations with toFQDNs, entities such as world and kube-apiserver, toServices, ICMP type matching, and deny sections. Deny rules take precedence over every allow, including allows written as Kubernetes NetworkPolicy. CiliumClusterwideNetworkPolicy uses the same rule format without a namespace, which gives baselines for all namespaces, and with a nodeSelector it becomes a host policy for the nodes themselves once the host firewall is enabled. Observability of allowed and dropped flows comes from Hubble rather than from the policy API.

Some behaviour differs in detail. With Cilium, ipBlock and CIDR rules do not match in-cluster pod or node addresses by default, because those peers are identified by identity; the option policyCIDRMatchMode set to pods or nodes changes this at the cost of extra identities. Cilium 1.20 also supports the Kubernetes ClusterNetworkPolicy API behind k8sClusterNetworkPolicy.enabled. Its tiers are evaluated in order: Admin, then the NetworkPolicy tier that contains NetworkPolicy, CiliumNetworkPolicy and CiliumClusterwideNetworkPolicy, then Baseline. An Admin-tier rule cannot be overridden by anything below it.

Mixing types is supported but needs care. The Cilium docs warn that the combined set of allowed traffic across several policy types can be hard to reason about and may lead to unintended allows, so many teams pick one primary format and use the others deliberately.

Key points

  • Kubernetes NetworkPolicy is limited to L3/L4 allow rules for pods in its own namespace.
  • Cilium deny rules beat allows from NetworkPolicy, CiliumNetworkPolicy and the cluster-wide variant alike.
  • ipBlock does not select pod or node IPs under Cilium unless policyCIDRMatchMode is set.
  • Admin-tier ClusterNetworkPolicy rules outrank every policy in the NetworkPolicy tier.

Three sample questions

11 CCA questions on Kubernetes NetworkPolicy versus CiliumNetworkPolicy, 11 with explanations. How practice works

Question 1

Which of the following is true about CiliumNetworkPolicy compared to Kubernetes NetworkPolicy?
  1. A.CiliumNetworkPolicy only supports Layer 3/4 filtering
  2. B.CiliumNetworkPolicy can enforce restrictions based on DNS/FQDN
  3. C.CiliumNetworkPolicy requires a sidecar proxy for enforcement
  4. D.CiliumNetworkPolicy cannot be used alongside Kubernetes NetworkPolicy

Correct answer: B

Unlike standard Kubernetes NetworkPolicy, CiliumNetworkPolicy can enforce restrictions based on DNS/FQDN names using the toFQDNs field, allowing egress filtering based on domain names rather than just IP addresses.

Question 2

The following standard Kubernetes NetworkPolicy allows traffic from the "frontend" namespace to a pod labeled "app: backend". Which CiliumNetworkPolicy provides equivalent functionality?
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend
  namespace: backend
spec:
  podSelector:
    matchLabels:
      app: backend
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: frontend
  policyTypes:
  - Ingress
  1. A.
    apiVersion: cilium.io/v2
    kind: CiliumNetworkPolicy
    metadata:
      name: allow-frontend
      namespace: backend
    spec:
      endpointSelector:
        matchLabels:
          app: backend
      ingress:
      - fromNamespaces:
        - matchLabels:
            name: frontend
  2. B.
    apiVersion: cilium.io/v2
    kind: CiliumNetworkPolicy
    metadata:
      name: allow-frontend
      namespace: backend
    spec:
      endpointSelector:
        matchLabels:
          app: backend
      ingress:
      - fromEndpoints:
        - matchLabels:
            io.kubernetes.pod.namespace: frontend
  3. C.
    apiVersion: cilium.io/v2
    kind: CiliumNetworkPolicy
    metadata:
      name: allow-frontend
      namespace: backend
    spec:
      endpointSelector:
        matchLabels:
          app: backend
      ingress:
      - fromCIDR:
        - 10.0.0.0/16
  4. D.
    apiVersion: cilium.io/v2
    kind: CiliumNetworkPolicy
    metadata:
      name: allow-frontend
      namespace: backend
    spec:
      endpointSelector:
        matchLabels:
          app: backend
      ingress:
      - fromEntities:
        - "frontend"

Correct answer: B

Cilium adds the label io.kubernetes.pod.namespace to every endpoint, so fromEndpoints with io.kubernetes.pod.namespace: frontend selects every pod in the namespace named frontend, which is what a namespaceSelector on kubernetes.io/metadata.name: frontend selects in NetworkPolicy. Why the other options are wrong. The fromNamespaces version: CiliumNetworkPolicy has no fromNamespaces field. The fromCIDR version: CIDR rules are for peers not managed by Cilium and would not select pods by namespace. The fromEntities "frontend" version: entities are a fixed list (host, world, cluster and so on); frontend is not one of them.

Sources: Cilium docs: Using Kubernetes Constructs In Policy, Kubernetes: Network Policies

Question 3

Convert the following Kubernetes NetworkPolicy that denies all egress traffic except DNS to an equivalent CiliumNetworkPolicy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-except-dns
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
  1. A.
    apiVersion: cilium.io/v2
    kind: CiliumNetworkPolicy
    metadata:
      name: deny-all-except-dns
    spec:
      endpointSelector: {}
      egress:
      - toEndpoints:
        - matchLabels:
            k8s-app: kube-dns
            io.kubernetes.pod.namespace: kube-system
        toPorts:
        - ports:
          - port: "53"
            protocol: UDP
  2. B.
    apiVersion: cilium.io/v2
    kind: CiliumNetworkPolicy
    metadata:
      name: deny-all-except-dns
    spec:
      endpointSelector: {}
      egress:
      - toServices:
        - k8sService:
            serviceName: kube-dns
            namespace: kube-system
  3. C.
    apiVersion: cilium.io/v2
    kind: CiliumNetworkPolicy
    metadata:
      name: deny-all-except-dns
    spec:
      endpointSelector: {}
      egress:
      - toEntities:
        - "dns"
  4. D.
    apiVersion: cilium.io/v2
    kind: CiliumNetworkPolicy
    metadata:
      name: deny-all-except-dns
    spec:
      endpointSelector: {}
      egressDeny:
      - toEndpoints:
        - matchLabels:
            k8s-app: kube-dns
            io.kubernetes.pod.namespace: kube-system
        toPorts:
        - ports:
          - port: "53"
            protocol: UDP

Correct answer: A

This CiliumNetworkPolicy correctly converts the Kubernetes NetworkPolicy by using endpointSelector: {} to select all pods and allowing egress only to the kube-dns pods in the kube-system namespace on UDP port 53. Cilium's default behavior is to deny all traffic not explicitly allowed, so this policy effectively allows only DNS traffic.

Practice this topic

Focus mode keeps every question on Kubernetes NetworkPolicy versus CiliumNetworkPolicy until you leave it. 10 free guest answers, then a free account; no credit card.

Or open CCA practice across all topics.

Sources

The explanation above was checked against these official documents.