Red Hat Training
A Red Hat training course is available for OpenShift Container Platform
Chapter 7. Configuring network policy with OpenShift SDN
7.1. About network policy
In a cluster using a Kubernetes Container Network Interface (CNI) plug-in that supports Kubernetes network policy, network isolation is controlled entirely by NetworkPolicy Custom Resource (CR) objects. In OpenShift Container Platform 4.1, OpenShift SDN supports using NetworkPolicy in its default network isolation mode.
The Kubernetes v1 NetworkPolicy features are available in OpenShift Container Platform except for egress policy types and IPBlock.
Network policy does not apply to the host network namespace. Pods with host networking enabled are unaffected by NetworkPolicy object rules.
By default, all Pods in a project are accessible from other Pods and network endpoints. To isolate one or more Pods in a project, you can create NetworkPolicy objects in that project to indicate the allowed incoming connections. Project administrators can create and delete NetworkPolicy objects within their own project.
If a Pod is matched by selectors in one or more NetworkPolicy objects, then the Pod will accept only connections that are allowed by at least one of those NetworkPolicy objects. A Pod that is not selected by any NetworkPolicy objects is fully accessible.
The following example NetworkPolicy objects demonstrate supporting different scenarios:
Deny all traffic:
To make a project deny by default, add a NetworkPolicy object that matches all Pods but accepts no traffic:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: deny-by-default spec: podSelector: ingress: []
Only allow connections from the OpenShift Container Platform Ingress Controller:
To make a project allow only connections from the OpenShift Container Platform Ingress Controller, add the following NetworkPolicy object:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-openshift-ingress spec: ingress: - from: - namespaceSelector: matchLabels: network.openshift.io/policy-group: ingress podSelector: {} policyTypes: - IngressIf the Ingress Controller is configured with
endpointPublishingStrategy: HostNetwork, then the Ingress Controller Pod runs on the host network. When running on the host network, the traffic from the Ingress Controller is assigned thenetid:0Virtual Network ID (VNID). Thenetidfor the namespace that is associated with the Ingress Operator is different, so thematchLabelin theallow-from-openshift-ingressnetwork policy does not match traffic from thedefaultIngress Controller. Because thedefaultnamespace is assigned thenetid:0VNID, you can allow traffic from thedefaultIngress Controller by labeling yourdefaultnamespace withnetwork.openshift.io/policy-group: ingress.Only accept connections from Pods within a project:
To make Pods accept connections from other Pods in the same project, but reject all other connections from Pods in other projects, add the following NetworkPolicy object:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-same-namespace spec: podSelector: ingress: - from: - podSelector: {}Only allow HTTP and HTTPS traffic based on Pod labels:
To enable only HTTP and HTTPS access to the Pods with a specific label (
role=frontendin following example), add a NetworkPolicy object similar to the following:kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-http-and-https spec: podSelector: matchLabels: role: frontend ingress: - ports: - protocol: TCP port: 80 - protocol: TCP port: 443Accept connections by using both namespace and Pod selectors:
To match network traffic by combining namespace and Pod selectors, you can use a NetworkPolicy object similar to the following:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-pod-and-namespace-both spec: podSelector: matchLabels: name: test-pods ingress: - from: - namespaceSelector: matchLabels: project: project_name podSelector: matchLabels: name: test-pods
NetworkPolicy objects are additive, which means you can combine multiple NetworkPolicy objects together to satisfy complex network requirements.
For example, for the NetworkPolicy objects defined in previous samples, you can define both allow-same-namespace and allow-http-and-https policies within the same project. Thus allowing the Pods with the label role=frontend, to accept any connection allowed by each policy. That is, connections on any port from Pods in the same namespace, and connections on ports 80 and 443 from Pods in any namespace.
7.2. Example NetworkPolicy object
The following annotates an example NetworkPolicy object:
kind: NetworkPolicy apiVersion: extensions/v1beta1 metadata: name: allow-27107 1 spec: podSelector: 2 matchLabels: app: mongodb ingress: - from: - podSelector: 3 matchLabels: app: app ports: 4 - protocol: TCP port: 27017
- 1
- The
nameof the NetworkPolicy object. - 2
- A selector describing the Pods the policy applies to. The policy object can only select Pods in the project that the NetworkPolicy object is defined.
- 3
- A selector matching the Pods that the policy object allows ingress traffic from. The selector will match Pods in any project.
- 4
- A list of one or more destination ports to accept traffic on.
7.3. Creating a NetworkPolicy object
To define granular rules describing Ingress network traffic allowed for projects in your cluster, you can create NetworkPolicy objects.
Prerequisites
-
A cluster using the OpenShift SDN network plug-in with
mode: NetworkPolicyset. This mode is the default for OpenShift SDN. -
Install the OpenShift Command-line Interface (CLI), commonly known as
oc. - You must log in to the cluster.
Procedure
Create a policy rule:
-
Create a
<policy-name>.yamlfile where<policy-name>describes the policy rule. In the file you just created define a policy object, such as in the following example:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: <policy-name> 1 spec: podSelector: ingress: []- 1
- Specify a name for the policy object.
-
Create a
Run the following command to create the policy object:
$ oc create -f <policy-name>.yaml -n <project>
In the following example, a new NetworkPolicy object is created in a project named
project1:$ oc create -f default-deny.yaml -n project1 networkpolicy "default-deny" created
7.4. Deleting a NetworkPolicy object
You can delete a NetworkPolicy object.
Prerequisites
-
A cluster using the OpenShift SDN network plug-in with
mode: NetworkPolicyset. This mode is the default for OpenShift SDN. -
Install the OpenShift Command-line Interface (CLI), commonly known as
oc. - You must log in to the cluster.
Procedure
To delete a NetworkPolicy object, run the following command:
$ oc delete networkpolicy -l name=<policy-name> 1- 1
- Specify the name of the NetworkPolicy object to delete.
7.5. Viewing NetworkPolicy objects
You can list the NetworkPolicy objects in your cluster.
Prerequisites
-
A cluster using the OpenShift SDN network plug-in with
mode: NetworkPolicyset. This mode is the default for OpenShift SDN. -
Install the OpenShift Command-line Interface (CLI), commonly known as
oc. - You must log in to the cluster.
Procedure
To view NetworkPolicy objects defined in your cluster, run the following command:
$ oc get networkpolicy
7.6. Configuring multitenant isolation using NetworkPolicy
You can configure your project to isolate it from Pods and Services in other projects.
Prerequisites
-
A cluster using the OpenShift SDN network plug-in with
mode: NetworkPolicyset. This mode is the default for OpenShift SDN. -
Install the OpenShift Command-line Interface (CLI), commonly known as
oc. - You must log in to the cluster.
Procedure
Create the following files containing NetworkPolicy object definitions:
A file named
allow-from-openshift-ingress.yamlcontaining the following:apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-openshift-ingress spec: ingress: - from: - namespaceSelector: matchLabels: network.openshift.io/policy-group: ingress podSelector: {} policyTypes: - IngressA file named
allow-from-openshift-monitoring.yamlcontaining the following:apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-openshift-monitoring spec: ingress: - from: - namespaceSelector: matchLabels: network.openshift.io/policy-group: monitoring podSelector: {} policyTypes: - Ingress
For each policy file, run the following command to create the NetworkPolicy object:
$ oc apply -f <policy-name>.yaml \ 1 -n <project> 2
If the
defaultIngress Controller configuration has thespec.endpointPublishingStrategy: HostNetworkvalue set, you must apply a label to thedefaultOpenShift Container Platform namespace to allow network traffic between the Ingress Controller and the project:Determine if your
defaultIngress Controller uses theHostNetworkendpoint publishing strategy:$ oc get --namespace openshift-ingress-operator ingresscontrollers/default \ --output jsonpath='{.status.endpointPublishingStrategy.type}'If the previous command reports the endpoint publishing strategy as
HostNetwork, set a label on thedefaultnamespace:$ oc label namespace default 'network.openshift.io/policy-group=ingress'
Optional: Confirm that the NetworkPolicy object exists in your current project by running the following command:
$ oc get networkpolicy <policy-name> -o yaml
In the following example, the
allow-from-openshift-ingressNetworkPolicy object is displayed:$ oc get networkpolicy allow-from-openshift-ingress -o yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-openshift-ingress namespace: project1 spec: ingress: - from: - namespaceSelector: matchLabels: network.openshift.io/policy-group: ingress podSelector: {} policyTypes: - Ingress
7.7. Creating default network policies for a new project
As a cluster administrator, you can modify the new project template to automatically include NetworkPolicy objects when you create a new project.
7.7.1. Modifying the template for new projects
As a cluster administrator, you can modify the default project template so that new projects are created using your custom requirements.
To create your own custom project template:
Procedure
-
Log in as a user with
cluster-adminprivileges. Generate the default project template:
$ oc adm create-bootstrap-project-template -o yaml > template.yaml
-
Use a text editor to modify the generated
template.yamlfile by adding objects or modifying existing objects. The project template must be created in the
openshift-confignamespace. Load your modified template:$ oc create -f template.yaml -n openshift-config
Edit the project configuration resource using the web console or CLI.
Using the web console:
- Navigate to the Administration → Cluster Settings page.
- Click Global Configuration to view all configuration resources.
- Find the entry for Project and click Edit YAML.
Using the CLI:
Edit the
project.config.openshift.io/clusterresource:$ oc edit project.config.openshift.io/cluster
Update the
specsection to include theprojectRequestTemplateandnameparameters, and set the name of your uploaded project template. The default name isproject-request.Project configuration resource with custom project template
apiVersion: config.openshift.io/v1 kind: Project metadata: ... spec: projectRequestTemplate: name: <template_name>- After you save your changes, create a new project to verify that your changes were successfully applied.
7.7.2. Adding network policy objects to the new project template
As a cluster administrator, you can add network policy objects to the default template for new projects. OpenShift Container Platform will automatically create all the NetworkPolicy CRs specified in the template in the project.
Prerequisites
-
A cluster using the OpenShift SDN network plug-in with
mode: NetworkPolicyset. This mode is the default for OpenShift SDN. -
Install the OpenShift Command-line Interface (CLI), commonly known as
oc. -
You must log in to the cluster with a user with
cluster-adminprivileges. - You must have created a custom default project template for new projects.
Procedure
Edit the default template for a new project by running the following command:
$ oc edit template <project_template> -n openshift-config
Replace
<project_template>with the name of the default template that you configured for your cluster. The default template name isproject-request.In the template, add each NetworkPolicy object as an element to the
objectsparameter. Theobjectsparameter accepts a collection of one or more objects.In the following example, the
objectsparameter collection includes several NetworkPolicy objects:objects: - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-same-namespace spec: podSelector: ingress: - from: - podSelector: {} - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-openshift-ingress spec: ingress: - from: - namespaceSelector: matchLabels: network.openshift.io/policy-group: ingress podSelector: {} policyTypes: - Ingress ...Optional: Create a new project to confirm that your network policy objects are created successfully by running the following commands:
Create a new project:
$ oc new-project <project> 1- 1
- Replace
<project>with the name for the project you are creating.
Confirm that the network policy objects in the new project template exist in the new project:
$ oc get networkpolicy NAME POD-SELECTOR AGE allow-from-openshift-ingress <none> 7s allow-from-same-namespace <none> 7s