Kahibaro
Discord Login Register

Network policies

Concept and Scope of NetworkPolicies

Network policies in OpenShift define how pods are allowed to communicate with each other and with other network endpoints. They are Kubernetes NetworkPolicy objects, enforced by the cluster’s CNI plugin, and apply at the pod level (L3/L4 – IP and port).

Key points:

Basic Structure of a NetworkPolicy

A NetworkPolicy resource has a standard shape:

Minimal example – allow only HTTP traffic from pods labeled role=frontend to pods labeled role=backend in the same namespace:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: my-app
spec:
  podSelector:
    matchLabels:
      role: backend
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              role: frontend
      ports:
        - protocol: TCP
          port: 8080

Interpretation:

Selecting Pods and Traffic Sources

Target pods: `podSelector`

podSelector defines which pods are protected by the policy:

Example – apply to all pods in payments namespace:

spec:
  podSelector: {}
  policyTypes: [Ingress]
  ingress:
    - {}  # some rules

Example – apply only to application pods:

spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/part-of: my-service

Sources/destinations: `from` and `to`

Within ingress and egress rules, you define where traffic can come from or go to using:

Pod-based selection

Allow traffic from any pod with label team=analytics in the same namespace:

ingress:
  - from:
      - podSelector:
          matchLabels:
            team: analytics

Cross-namespace selection

Allow traffic from pods in namespaces labeled env=staging:

ingress:
  - from:
      - namespaceSelector:
          matchLabels:
            env: staging

Combine pod and namespace selectors to restrict to certain pods in specific namespaces:

ingress:
  - from:
      - namespaceSelector:
          matchLabels:
            env: staging
        podSelector:
          matchLabels:
            role: api-client

IP-based selection (`ipBlock`)

ipBlock is useful to allow or deny traffic to/from external networks.

Allow traffic from a corporate subnet except a management range:

ingress:
  - from:
      - ipBlock:
          cidr: 10.0.0.0/16
          except:
            - 10.0.10.0/24

Notes:

Controlling Ports and Protocols

Network policies operate at TCP/UDP/SCTP layer with optional ports:

ports:
  - protocol: TCP
    port: 80
  - protocol: TCP
    port: 443

If ports is omitted:

You can also use named ports defined in the pod’s container spec:

ports:
  - port: http  # name defined in containerPorts

Ingress vs Egress Policies

Ingress policies

Control traffic into selected pods.

Example – only allow:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-ingress
  namespace: payments
spec:
  podSelector:
    matchLabels:
      app: payments-api
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              team: frontend
          podSelector:
            matchLabels:
              role: web
      ports:
        - protocol: TCP
          port: 443

Once this policy is applied, all other inbound traffic to app=payments-api pods is blocked.

Egress policies

Control outbound traffic from selected pods.

Example – limit outgoing connections from app=payments-api to:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: payments-egress
  namespace: payments
spec:
  podSelector:
    matchLabels:
      app: payments-api
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              name: databases
          podSelector:
            matchLabels:
              app: postgres
      ports:
        - protocol: TCP
          port: 5432
    - to:
        - ipBlock:
            cidr: 203.0.113.0/24
      ports:
        - protocol: TCP
          port: 443

When at least one egress policy selects these pods, all other outgoing traffic is denied, including DNS, unless explicitly allowed.

Typical Policy Patterns in OpenShift

Default deny for a namespace

A common security posture is to deny all traffic by default and explicitly allow necessary flows.

Deny all ingress to pods in a namespace:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: my-namespace
spec:
  podSelector: {}
  policyTypes:
    - Ingress
  ingress: []

Deny all egress:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-egress
  namespace: my-namespace
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress: []

Use these as a baseline, then add more specific allow policies.

Allow same-namespace traffic

After a default deny, you might allow all pods in the same namespace to talk to each other:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-same-namespace
  namespace: my-namespace
spec:
  podSelector: {}
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector: {}

This still blocks cross-namespace and external traffic, while permitting intra-namespace communication.

Layered policies for a microservice

For a backend microservice:

  1. Default deny ingress for the namespace.
  2. Specific policy to allow ingress from only selected frontends.
  3. Specific egress policy to limit dependencies.

Example set:



# 1. Default deny
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: shop
spec:
  podSelector: {}
  policyTypes: [Ingress]
  ingress: []
# 2. Allow frontend to backend
kind: NetworkPolicy
metadata:
  name: allow-web-to-orders
  namespace: shop
spec:
  podSelector:
    matchLabels:
      app: orders
  policyTypes: [Ingress]
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: web
      ports:
        - protocol: TCP
          port: 8080
# 3. Egress from backend only to db
kind: NetworkPolicy
metadata:
  name: orders-egress
  namespace: shop
spec:
  podSelector:
    matchLabels:
      app: orders
  policyTypes: [Egress]
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              name: databases
          podSelector:
            matchLabels:
              app: orders-db
      ports:
        - protocol: TCP
          port: 5432

OpenShift-Specific Considerations

Interaction with OpenShift SDN and OVN-K

OpenShift supports different network plugins (e.g. OpenShift SDN, OVN-Kubernetes). Both implement Kubernetes NetworkPolicy, but capabilities and performance characteristics can differ.

From a user perspective:

Namespaces and tenant isolation

OpenShift commonly uses namespaces as an isolation boundary between teams or applications. Network policies:

A typical multi-tenant pattern:

Interaction with Routes and external access

Network policies only control pod-level traffic. They do not directly manage:

However, they can affect traffic that originates from:

Practical implication:

Example – allow traffic from the default router namespace to your app:

ingress:
  - from:
      - namespaceSelector:
          matchLabels:
            network.openshift.io/policy-group: ingress

(Exact labels may vary; in practice you should check how router namespaces are labeled in your cluster.)

DNS and Egress Gotchas

When applying egress policies:

If you create a strict egress policy, you must explicitly allow DNS:

Example – allow DNS and specific external HTTPS:

spec:
  podSelector:
    matchLabels:
      app: my-service
  policyTypes: [Egress]
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: openshift-dns
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53
    - to:
        - ipBlock:
            cidr: 198.51.100.0/24
      ports:
        - protocol: TCP
          port: 443

Labels and namespaces for DNS may differ; inspect your cluster to identify the correct selectors.

Designing Network Policies Incrementally

Because policies can easily block traffic, an incremental approach is safer:

  1. Start with observation
    • Understand current communication patterns.
    • Document which pods/services talk to which, and on what ports.
  2. Introduce soft boundaries
    • Begin with less restrictive policies that allow known traffic patterns without yet adding global default denies.
    • Use labels to structure your application: tier, role, team, etc.
  3. Add default deny per namespace
    • After validating specific allow policies, introduce default deny for ingress (and optionally egress).
    • Monitor for any broken flows and adjust rules.
  4. Refine and group
    • Group common rules into reusable patterns (e.g. “allow monitoring namespace to scrape metrics”).
    • Standardize labels across teams to simplify selectors.

Testing and Troubleshooting Network Policies

When a pod cannot reach another:

  1. Check whether any NetworkPolicy exists in the source or destination namespace.
  2. For ingress issues:
    • Inspect policies with policyTypes: Ingress that select the destination pod.
    • Confirm that the source is allowed in from and correct port is open.
  3. For egress issues:
    • Inspect policies with policyTypes: Egress that select the source pod.
    • Confirm that the destination (pod, namespace, or IP) and port are allowed.
  4. Temporarily relax policies:
    • As a diagnostic step, you can add a policy that broadens access (e.g. allow from all pods) to verify if policies are the root cause, then tighten again.

Example quick diagnostic policy (namespace-local ingress allow):

kind: NetworkPolicy
metadata:
  name: debug-allow-all-ingress
  namespace: my-namespace
spec:
  podSelector: {}
  policyTypes: [Ingress]
  ingress:
    - from:
        - podSelector: {}

Remove diagnostic policies once you identify the issue to restore your intended security posture.

Best Practices for Network Policies in OpenShift

These practices help you use network policies as an effective, maintainable tool for in-cluster traffic control and multi-tenant isolation in OpenShift.

Views: 13

Comments

Please login to add a comment.

Don't have an account? Register now!