In Red Hat OpenShift Container Platform (OCP), NetworkPolicies govern how pods are allowed to communicate with each other, with services in other namespaces, and with external network endpoints.
By default, OpenShift follows a non-isolated network model: all pods within a cluster can send and receive traffic from any other pod or service across all namespaces. NetworkPolicies allow you to implement a Zero-Trust network architecture by restricting ingress (incoming) and egress (outgoing) traffic.
1. Underlying Engine: OVN-Kubernetes
OpenShift uses OVN-Kubernetes (Open Virtual Network) as its default Container Network Interface (CNI).
When you apply a NetworkPolicy object, the OVN-Kubernetes controller translates your high-level declarative Kubernetes manifest into low-level OpenFlow rules directly on the Open vSwitch (br-int) bridges across every host node.
- Default State: Allow all traffic.
- Policy Active State: Once a
NetworkPolicyselects a pod, that pod enters an implicit default-deny state for the traffic directions specified in the policy (Ingress,Egress, or both). - Evaluation Model: NetworkPolicies are additive (allow-lists). You cannot write explicit “deny” rules—traffic is denied unless an explicit rule allows it.
2. The Core NetworkPolicy Manifest Anatomy
A standard NetworkPolicy targets a set of pods using podSelector and defines rules based on three match types:
podSelector: Matches pods within the same namespace.namespaceSelector: Matches pods inside other namespaces based on namespace labels.ipBlock: Matches CIDR IP ranges (for external or non-pod traffic).
YAML
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-frontend-to-backend namespace: my-app-prodspec: # 1. Target Pods: This policy applies to pods with the 'app: backend' label podSelector: matchLabels: app: backend policyTypes: - Ingress - Egress # 2. Ingress Rules: Allow traffic ON TO port 8080 ONLY IF... ingress: - from: # ...it comes from pods labeled 'app: frontend' in the SAME namespace - podSelector: matchLabels: app: frontend # ...OR from pods inside namespaces labeled 'environment: prod' - namespaceSelector: matchLabels: environment: prod ports: - protocol: TCP port: 8080 # 3. Egress Rules: Allow backend pods to communicate OUT TO... egress: - to: # ...a specific external database IP range - ipBlock: cidr: 10.0.100.0/24 ports: - protocol: TCP port: 5432
3. Essential Production NetworkPolicy Patterns
Pattern A: Global “Default Deny All” Ingress & Egress
Place this in every production namespace to enforce a Zero-Trust baseline. All traffic is blocked until explicit allow rules are created.
YAML
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-deny-all namespace: my-app-prodspec: podSelector: {} # Empty selector selects ALL pods in the namespace policyTypes: - Ingress - Egress
Pattern B: Allow Traffic from OpenShift Ingress Routers
If you enforce a default-deny policy, external users won’t be able to reach your application via an OpenShift Route. You must explicitly allow ingress from the OpenShift router pods:
YAML
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-from-openshift-ingress namespace: my-app-prodspec: podSelector: matchLabels: app: web-frontend policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: network.openshift.io/policy-group: ingress
Pattern C: Allow CoreDNS Resolution for Egress
When egress is locked down via a default-deny policy, pods cannot resolve internal or external domain names because DNS requests to openshift-dns are blocked. You must allow UDP/TCP port 53:
YAML
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-dns-access namespace: my-app-prodspec: podSelector: {} policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: openshift-dns ports: - protocol: UDP port: 53 - protocol: TCP port: 53
4. OpenShift-Specific Extensions: AdminNetworkPolicy
Standard Kubernetes NetworkPolicy objects are namespaced—meaning cluster administrators cannot easily enforce global security rules across all namespaces without developers overriding them.
In newer OpenShift releases, OVN-Kubernetes supports the AdminNetworkPolicy (ANP) and BaselineAdminNetworkPolicy (BANP) APIs (from the Kubernetes Network Policy Working Group):
- Cluster-Scoped: Defined at the cluster level by admins, not developers.
- Precedence: Evaluated before namespaced
NetworkPolicyobjects. - Explicit Deny Rules: Unlike standard NetworkPolicies,
AdminNetworkPolicysupports explicitPass,Allow, andDenyactions.
Example Admin Policy to globally block developer pods from hitting host metadata endpoints:
YAML
apiVersion: policy.networking.k8s.io/v1alpha1kind: AdminNetworkPolicymetadata: name: block-cloud-metadataspec: priority: 10 subject: namespaces: {} egress: - action: Deny to: - ipBlock: 169.254.169.254/32 # AWS/GCP/Azure Metadata IP
5. Debugging NetworkPolicies
- Verify Applied Policies in a Namespace:
Bashoc get networkpolicy -n <namespace> - Check for Dropped Packets in OVN Trace:Use the
ovs-appctltrace command on the host node (viaoc debug node/<node-name>) to verify if OVN is dropping packets due to an ACL block:Bashovs-appctl ofproto/trace br-int in_port=<OVS_PORT>,tcp,nw_src=10.128.2.15,nw_dst=10.128.4.20,tp_dst=80