Bookmark this page

Guided Exercise: Multus Secondary Networks

Expose a PostgreSQL database to external access by using a secondary network.

Outcomes

  • Make a PostgreSQL database accessible outside the cluster on an isolated network by using an existing node network interface.

As the student user on the workstation machine, use the lab command to prepare your system for this exercise.

This command ensures that the environment is ready.

[student@workstation ~]$ lab start non-http-multus

Instructions

  1. Deploy a sample database.

    1. Log in to the OpenShift cluster as the developer user with the developer password.

      [student@workstation ~]$ oc login -u developer -p developer \
        https://api.ocp4.example.com:6443
      Login successful.
      
      ...output omitted...
    2. Create a non-http-multus project.

      [student@workstation ~]$ oc new-project non-http-multus
      ...output omitted...
    3. Create the resources that the ~/DO280/labs/non-http-multus/deployment.yaml file contains.

      [student@workstation ~]$ oc apply -f ~/DO280/labs/non-http-multus/deployment.yaml
      secret/database created
      persistentvolumeclaim/database created
      deployment.apps/database created
    4. Wait until all resources are ready.

      [student@workstation ~]$ oc get all
      NAME                            READY   STATUS    RESTARTS   AGE
      pod/database-654db5f958-8p6m5   1/1     Running   0          3m36s
      
      NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
      deployment.apps/database   1/1     1            1           3m36s
      
      NAME                                  DESIRED   CURRENT   READY   AGE
      replicaset.apps/database-654db5f958   1         1         1       3m36s

      This application contains only a deployment, a persistent volume claim, and a secret. The application does not contain any services, so the database is not accessible outside the pod network.

      This application uses a database that requires exclusive access to the database data. On the database deployment, only one pod must be running at a time. To prevent multiple pods from running at a time, the deployment uses the recreate strategy.

      This scenario is part of the scenarios where you assign a network interface exclusively to a pod. In these scenarios, the host device strategy is suitable. A network attachment with the host device strategy is suitable only for a single pod.

      In other scenarios, you must use more complex network attachments.

  2. Examine the cluster nodes and inspect the network interface that you use in this exercise.

    1. Log in to the OpenShift cluster as the admin user with the redhatocp password.

      [student@workstation ~]$ oc login -u admin -p redhatocp \
        https://api.ocp4.example.com:6443
      Login successful.
      
      ...output omitted...
    2. Use the oc get node command to list the cluster nodes.

      [student@workstation ~]$ oc get node
      NAME       STATUS   ROLES                         AGE   VERSION
      master01   Ready    control-plane,master,worker   36d   v1.27.6+f67aeb3

      The cluster has a single node with the control plane and worker roles.

    3. Run the ip addr command in the node, by using the oc debug command to execute commands in the node.

      [student@workstation ~]$ oc debug node/master01 -- chroot /host ip addr
      Temporary namespace openshift-debug-mrchh is created for debugging node...
      Starting pod/master01-debug ...
      To use host binaries, run: chroot /host
      Pod IP: 192.168.50.10
      1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
      ...output omitted...
      2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master ovs-system state UP group default qlen 1000  1
          link/ether 52:54:00:00:32:0a brd ff:ff:ff:ff:ff:ff
      3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000  2
          link/ether 52:54:00:01:33:0a brd ff:ff:ff:ff:ff:ff
          inet 192.168.51.10/24 brd 192.168.51.255 scope global dynamic noprefixroute ens4
             valid_lft 461179517sec preferred_lft 461179517sec
          inet6 fe80::b9dd:9436:4fc7:738/64 scope link noprefixroute
             valid_lft forever preferred_lft forever
      4: ovs-system: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
          link/ether 22:31:45:7a:e2:e3 brd ff:ff:ff:ff:ff:ff
      5: ovn-k8s-mp0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue state UNKNOWN group default qlen 1000
      ...output omitted...
      6: br-int: <BROADCAST,MULTICAST> mtu 1400 qdisc noop state DOWN group default qlen 1000
          link/ether 52:db:28:19:51:94 brd ff:ff:ff:ff:ff:ff
      8: br-ex: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
          link/ether 52:54:00:00:32:0a brd ff:ff:ff:ff:ff:ff
          inet 192.168.50.10/24 brd 192.168.50.255 scope global dynamic noprefixroute br-ex
      ...output omitted...

      1

      The ens3 interface is the main network interface of the cluster.

      2

      The ens4 interface is an additional network interface for exercises that require an additional network. This interface is attached to a 192.168.51.0/24 network, with the 192.168.51.10 IP address.

      The system has other interfaces, including bridges and pod network interfaces.

  3. Examine the networking configuration of the workstation machine. The workstation machine has no access to the 192.168.51.0/24 network, which is the ens4 interface in the cluster node.

    1. Use the ip addr command to examine the network interfaces in the workstation machine.

      [student@workstation ~]$ ip addr
      1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
          link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
          inet 127.0.0.1/8 scope host lo
             valid_lft forever preferred_lft forever
          inet6 ::1/128 scope host
             valid_lft forever preferred_lft forever
      2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000  1
          link/ether 52:54:00:00:fa:09 brd ff:ff:ff:ff:ff:ff
          inet 172.25.250.9/24 brd 172.25.250.255 scope global noprefixroute eth0
             valid_lft forever preferred_lft forever
          inet6 fe80::5054:ff:fe00:fa09/64 scope link
             valid_lft forever preferred_lft forever
      ...output omitted...

      1

      The workstation machine has a single Ethernet interface. This interface is on a different network from the ens4 interface in the cluster node.

    2. Use the route command to view the routing table in the workstation machine.

      [student@workstation ~]$ ip route
      default via 172.25.250.254 dev eth0 proto static metric 100
      10.88.0.0/16 dev podman0 proto kernel scope link src 10.88.0.1
      172.25.250.0/24 dev eth0 proto kernel scope link src 172.25.250.9 metric 100
      192.168.50.0/24 via 172.25.250.253 dev eth0 proto static metric 100

      The workstation routing table does not have a route to the 192.168.51.0/24 network.

    3. Use the ping command to check connectivity to the ens4 interface in the cluster.

      [student@workstation ~]$ ping 192.168.51.10
      PING 192.168.51.10 (192.168.51.10) 56(84) bytes of data.
      ^C
      --- 192.168.51.10 ping statistics ---
      6 packets transmitted, 0 received, 100% packet loss, time 5137ms

      The command does not produce any output after printing the first line. Wait a few seconds, and then press Ctrl+C to interrupt the ping command. The ping command prints that after transmitting some packets, no response is received.

      The workstation machine cannot connect to the additional cluster network.

  4. Examine the networking configuration of the utility machine. The utility machine has access to the 192.168.51.0/24 network.

    1. Use the ssh command to connect to the utility machine.

      [student@workstation ~]$ ssh utility
      ...output omitted...
      [student@utility ~]$
    2. Use the ip addr command to examine the network interfaces in the utility machine.

      [student@utility ~]$ ip addr
      ...output omitted...
      4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000  1
          link/ether 52:54:00:02:33:fe brd ff:ff:ff:ff:ff:ff
          inet 192.168.51.254/24 brd 192.168.51.255 scope global noprefixroute eth2
      ...output omitted...

      1

      The eth2 interface is attached to the 192.168.51.0/24 network, with the 192.168.51.254 IP address.

    3. Use the ping command to check connectivity to the ens4 interface in the cluster.

      [student@utility ~]$ ping 192.168.51.10
      PING 192.168.51.10 (192.168.51.10) 56(84) bytes of data.
      64 bytes from 192.168.51.10: icmp_seq=1 ttl=64 time=0.687 ms
      64 bytes from 192.168.51.10: icmp_seq=2 ttl=64 time=0.169 ms
      ^C
      --- 192.168.51.10 ping statistics ---
      2 packets transmitted, 2 received, 0% packet loss, time 1058ms
      rtt min/avg/max/mdev = 0.169/0.428/0.687/0.259 ms

      Wait a few seconds, and then press Ctrl+C to interrupt the ping command. The ping command shows that the utility machine can connect to the additional cluster network.

    4. Exit the SSH session to go back to the workstation machine.

      [student@utility ~]$ exit
      logout
      Connection to utility closed.
      [student@workstation ~]$
  5. Configure a network attachment definition for the ens4 interface, so that the custom network can be attached to a pod.

    1. Edit the ~/DO280/labs/non-http-multus/network-attachment-definition.yaml file. Use the custom name, the host-device type, and the ens4 device. Configure IP address management to use the static type, with the 192.168.51.10/24 address.

      apiVersion: k8s.cni.cncf.io/v1
      kind: NetworkAttachmentDefinition
      metadata:
        name: custom
      spec:
        config: |-
          {
            "cniVersion": "0.3.1",
            "name": "custom",
            "type": "host-device",
            "device": "ens4",
            "ipam": {
              "type": "static",
              "addresses": [
                {"address": "192.168.51.10/24"}
              ]
            }
          }
    2. Use the diff command to compare your network attachment definition with the solution in the ~/DO280/solutions/non-http-multus/network-attachment-definition.yaml file. If the files are identical, then the diff command does not return any output.

      [student@workstation ~]$ diff \
        ~/DO280/labs/non-http-multus/network-attachment-definition.yaml \
        ~/DO280/solutions/non-http-multus/network-attachment-definition.yaml
    3. Use the oc create command to create the network attachment definition.

      [student@workstation ~]$ oc create \
        -f ~/DO280/labs/non-http-multus/network-attachment-definition.yaml
      networkattachmentdefinition.k8s.cni.cncf.io/custom created
  6. Edit the deployment to add the k8s.v1.cni.cncf.io/networks annotation with the custom value.

    1. Log in to the OpenShift cluster as the developer user with the developer password.

      [student@workstation ~]$ oc login -u developer -p developer \
        https://api.ocp4.example.com:6443
      Login successful.
      
      ...output omitted...
    2. Edit the ~/DO280/labs/non-http-multus/deployment.yaml file to add the k8s.v1.cni.cncf.io/networks annotation with the custom value.

      apiVersion: v1
      ...output omitted...
      - apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: database
        spec:
          replicas: 1
          strategy:
            type: Recreate
          selector:
            matchLabels:
              name: database
              app: database
          template:
            metadata:
              labels:
                name: database
                app: database
              annotations:
                k8s.v1.cni.cncf.io/networks: custom
            spec:
      ...output omitted...
    3. Use the oc apply command to add the annotation.

      [student@workstation ~]$ oc apply -f ~/DO280/labs/non-http-multus/deployment.yaml
      secret/database configured
      persistentvolumeclaim/database unchanged
      deployment.apps/database configured
    4. Wait until all resources are ready.

      [student@workstation ~]$ oc get all
      NAME                            READY   STATUS    RESTARTS   AGE
      pod/database-74d79685f7-8p6m5   1/1     Running   0          3m36s
      
      NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
      deployment.apps/database   1/1     1            1           3m36s
      
      NAME                                  DESIRED   CURRENT   READY   AGE
      replicaset.apps/database-654db5f958   0         0         0       15m
      replicaset.apps/database-74d79685f7   1         1         1       3m36s
    5. Examine the k8s.v1.cni.cncf.io/network-status annotation in the pod.

      [student@workstation ~]$ oc get pod database-74d79685f7-6schp \
        -o jsonpath='{.metadata.annotations.k8s\.v1\.cni\.cncf\.io/network-status}'
      [{
          "name": "ovn-kubernetes",
          "interface": "eth0",
          "ips": [
              "10.8.0.92"
          ],
          "mac": "0a:58:0a:08:00:5c",
          "default": true,
          "dns": {}
      },{
          "name": "non-http-multus/custom",
          "interface": "net1",
          "ips": [
              "192.168.51.10"
          ],
          "mac": "52:54:00:01:33:0a",
          "dns": {}
      }]

      Note

      The period is the JSONPath field access operator. Normally, you use the period to access parts of the resource, such as in the .metadata.annotations JSONPath expression. To access fields that contain periods with JSONPath, you must escape the periods with a backslash (\).

  7. Verify that you can access the database from the utility machine.

    1. Use the ssh command to connect to the utility machine.

      [student@workstation ~]$ ssh utility
      ...output omitted...
      [student@utility ~]$
    2. Log in to the classroom container registry for access to an image with database utilities.

      [student@utility ~]$ podman login --tls-verify=false \
        registry.ocp4.example.com:8443 -u developer -p developer
      Login Succeeded!
    3. Run a command to execute a query on the database. Use the IP address on the custom network to connect to the database. Use password as the password for the user.

      [student@utility ~]$ podman run -it --tls-verify=false \
        --entrypoint=/usr/bin/psql \
        registry.ocp4.example.com:8443/rhel8/postgresql-13:1-7 \
        -h 192.168.51.10 -U user sample -c 'SELECT 1;'
      ...output omitted...
      Password for user user: password
       ?column?
      ----------
              1
      (1 row)
    4. Exit the SSH session to return to the workstation machine.

      [student@utility ~]$ exit
      logout
      Connection to utility closed.
      [student@workstation ~]$
  8. Verify that you cannot use the same process to access the database from the workstation machine, because the workstation machine cannot access the custom network.

    1. Log in to the classroom container registry for access to an image with database utilities.

      [student@workstation ~]$ podman login --tls-verify=false \
        registry.ocp4.example.com:8443 -u developer -p developer
      Login Succeeded!
    2. Run a command to execute a query on the database. Use the IP address on the custom network to connect to the database.

      [student@workstation ~]$ podman run -it --tls-verify=false \
        --entrypoint=/usr/bin/psql \
        registry.ocp4.example.com:8443/rhel8/postgresql-13:1-7 \
        -h 192.168.51.10 -U user sample -c 'SELECT 1;'
      ...output omitted...
      Storing signatures
      psql: error: could not connect to server: Connection refused
      	Is the server running on host "192.168.51.10" and accepting
      	TCP/IP connections on port 5432?

      After the image is downloaded, the command pauses for over a minute, because you cannot access the custom network from the workstation machine.

      The deployment uses the custom network, and you can access the database only through the custom network.

Finish

On the workstation machine, use the lab command to complete this exercise. This step is important to ensure that resources from previous exercises do not impact upcoming exercises.

[student@workstation ~]$ lab finish non-http-multus

Revision: do280-4.14-08d11e1