Introduction

NetworkPolicies are used to control and secure communication between pods within a cluster. They provide a declarative approach to define and enforce network traffic rules, allowing you to specify the desired network behavior. By using NetworkPolicies, you can enhance the overall security of your applications by isolating and segmenting different components within the cluster. These policies enable fine-grained control over network access, allowing you to define ingress and egress rules based on criteria such as IP addresses, ports, and pod selectors.

For this module we will be applying networkpolices to the previously created 'microsweeper-ex' namespace and using the 'microsweeper' app to test these policies. In addition, we will deploy two new applications to test against the 'microsweeper' app.

Applying Network Policies

  1. First, let’s create a new project for us to deploy a new test application. To do so, run the following command:

     oc new-project networkpolicy-test
  2. Next, we will create a new application that will allow us to test connectivity to the microsweeper application. To do so, run the following command:

    cat << EOF | oc apply -f -
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: networkpolicy-pod
      namespace: networkpolicy-test
      labels:
        app: networkpolicy
    spec:
      securityContext:
        allowPrivilegeEscalation: false
      containers:
        - name: networkpolicy-pod
          image: registry.access.redhat.com/ubi9/ubi-minimal
          command: ["sleep", "infinity"]
    EOF

    You may ignore any warnings you may see about PodSecurity violations.

  3. Now we will change to the microsweeper-ex project to start applying the network policies

     oc project microsweeper-ex
  4. Fetch the IP address of the microsweeper Pod

    MS_IP=$(oc -n microsweeper-ex get pod -l \
      "app.kubernetes.io/name=microsweeper-appservice" \
      -o jsonpath="{.items[0].status.podIP}")
    echo $MS_IP
    Sample Output
    10.128.2.242
  5. Now, let’s validate that the networkpolicy-pod can access the microsweeper pod. By default, ARO does not implement any NetworkPolicy, so we should be able to easily verify that we can access the microsweeper application. To test this, let’s run the following command:

    oc -n networkpolicy-test exec -ti pod/networkpolicy-pod -- curl $MS_IP:8080 | head
    Sample Output
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Microsweeper</title>
        <link rel="stylesheet" href="css/main.css">
        <script
                src="https://code.jquery.com/jquery-3.2.1.min.js"
  6. While ARO doesn’t block inter-project pod traffic by default, it is a common use case to not allow pods to cross communicate between projects (namespaces). This can be done by a fairly simple NetworkPolicy.

    This Network Policy will restrict ingress to the pods in the project microsweeper-ex to only allow traffic from the OpenShift IngressController and only on port 8080.

    cat << EOF | oc apply -f -
    ---
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-from-openshift-ingress
      namespace: microsweeper-ex
    spec:
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              network.openshift.io/policy-group: ingress
      podSelector: {}
      policyTypes:
      - Ingress
    EOF
    Sample Output
    networkpolicy.networking.k8s.io/allow-from-openshift-ingress created
  7. Now that we’ve implemented that NetworkPolicy, let’s try to access the microsweeper pod from the networkpolicy-pod pod again. To do so, run the following command:

    oc -n networkpolicy-test exec -ti pod/networkpolicy-pod -- curl $MS_IP:8080 | head

    This time it should fail to connect - it will just sit there. Hit Ctrl-C to avoid having to wait until a timeout.

    If you have your browser still open to the microsweeper app, you can refresh and see that you can still access it.

  8. In other cases, you may want to allow your application to be accessible to only certain namespaces. In this example, let’s allow access to just your microsweeper application from only the networkpolicy-pod in the networkpolicy-test namespace using a label selector. To do so, run the following command:

    cat <<EOF | oc apply -f -
    ---
    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: allow-networkpolicy-pod-ap
      namespace: microsweeper-ex
    spec:
      podSelector:
        matchLabels:
          app.kubernetes.io/name: microsweeper-appservice
      ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                kubernetes.io/metadata.name: networkpolicy-test
            podSelector:
              matchLabels:
                app: networkpolicy
    EOF
    Sample Output
    networkpolicy.networking.k8s.io/allow-networkpolicy-pod-ap created
  9. Now, let’s check to see if networkpolicy-pod can access the pod. To do so, run the following command:

    oc -n networkpolicy-test exec -ti pod/networkpolicy-pod -- curl $MS_IP:8080 | head
    Sample Output
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Microsweeper</title>
        <link rel="stylesheet" href="css/main.css">
        <script
                src="https://code.jquery.com/jquery-3.2.1.min.js"
  10. Now, let’s try a different pod (with a different label) in the networkpolicy-test namespace. Let’s create a new pod called new-test. To do so, run the following command:

    cat << EOF | oc apply -f -
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: new-test
      namespace: networkpolicy-test
      labels:
        app: new-test
    spec:
      securityContext:
        allowPrivilegeEscalation: false
      containers:
        - name: new-test
          image: registry.access.redhat.com/ubi9/ubi-minimal
          command: ["sleep", "infinity"]
    EOF

    Again you may ignore any PodSecurity violation warnings you may see.

  11. Now, let’s try to curl the microsweeper application by running the following command:

    oc -n networkpolicy-test exec -ti pod/new-test -- curl $MS_IP:8080 | head

    This will fail with a timeout again. Hit Ctrl-C to avoid waiting for a timeout.

To learn more about configuring NetworkPolicy objects, visit the Red Hat documentation on NetworkPolicy. Interested in creating a set of default NetworkPolicy objects for new projects? Read more at the Red Hat documentation on modifying the default project template.

Summary

Here you learned:

  • Network Policies are a powerful way to apply zero-trust networking patterns.

  • Access to pods can be restricted to other Pods, Namespaces, or other labels.

  • Access can be completely denied, allowed, or set to particular ports or services.