# Using dedicated networks for OpenShift Data Foundation
TODO - explain why I'm writing this. In short, I'm writing this in order to provide additional context to the official documentation.
[Planning Doc - 8.2 Multi network plug-in (Multus) support](https://docs.redhat.com/en/documentation/red_hat_openshift_data_foundation/4.18/html-single/planning_your_deployment/index#multi-network-plugin-multus-support_rhodf)
[Managing Doc - 7 Creating Multus networks](https://docs.redhat.com/en/documentation/red_hat_openshift_data_foundation/4.18/html-single/managing_and_allocating_storage_resources/index#creating-multus-networks_rhodf)
TODO - Add a visual diagram that shows overlapping and non-overlapping CIDRs/routes
TODO - Add these test commands below. Using these commands you can create Pods/Containers that simulate the OpenShift Data Foundation deployment and verify that you can `ping` between services running on different nodes and also verify that the Pods/Containers can ping the host (and vice-versa)
```bash
oc run -n openshift-storage jcall-test-pod --image=registry.redhat.io/rhel9/support-tools --annotations k8s.v1.cni.cncf.io/networks=odf-public -it --restart=Never
oc run -n openshift-storage jcall-test-pod --image=registry.redhat.io/rhel9/support-tools --annotations k8s.v1.cni.cncf.io/networks=odf-public -it --restart=Never --command -- ip route list
# optionally add a nodeSelector override
--overrides='{"spec": {"nodeSelector": {"kubernetes.io/hostname": "dell-r760-01"}}}'
```
:::info
Ian mentioned today that it may be possible to simplify the host configuration (NNCP) by setting the netmask to /17 instead of /24. This would eliminiate the need for a static route, when the smaller Node network is a part of the larger Pod network
:::
## Example using bonded NICs instead of a single NIC
### Node configuration (via NodeNetworkConfigurationPolicy)
The nodes need to connect with the pods...
Make note of the static route that allows the nodes to connect with the pods
```yaml=
# Node network: 192.168.255.0/24 (exclude from NetworkAttachmentDefintion's whereabouts)
# Pod network: 192.168.128.0/17 (see NetworkAttachmentDefinition)
---
apiVersion: nmstate.io/v1
kind: NodeNetworkConfigurationPolicy
metadata:
name: rhclient1-odf-public-net # [1]
spec:
nodeSelector:
kubernetes.io/hostname: rhclient1.dota-lab.iad.redhat.com # [2]
desiredState:
interfaces:
- name: bridge-data
description: Used by VMs (via net-attach-def) to access VLAN 999 (172.31.255.0/24)
state: up
type: linux-bridge
mtu: 9000
bridge:
options:
stp:
enabled: true
port:
- name: bond-data
ipv4:
enabled: false
ipv6:
enabled: false
- name: bond-data
description: LACP bond to arctica-data1
# 172.16.1.0/24 not used by guacamole
# 192.168.128.0/17 used by ODF pods
# 192.168.255.0/24 used by ODF nodes
# VLAN 999 (172.31.255.0/24) used by VMs
state: up
type: bond
mtu: 9000
link-aggregation:
mode: 802.3ad
port:
- ens2f0
- ens2f1
ipv4:
enabled: false
ipv6:
enabled: false
lldp:
enabled: true
- name: odf-public-shim # [3]
description: Used to connect each node to OpenShift Data Foundations' public multus network
type: mac-vlan # [4]
state: up
mtu: 9000
mac-vlan:
base-iface: bridge-data # [5]
mode: bridge
promiscuous: true
ipv4: # [6]
enabled: true
dhcp: false
address:
- ip: 192.168.255.101 # [7] STATIC IP FOR node-1
prefix-length: 24
routes: # [8]
config:
- destination: 192.168.128.0/17 # [9]
next-hop-interface: odf-public-shim
#1. For static IP management, each node must have a unique NodeNetworkConfigurationPolicy.
#2. Select individual nodes via hostname to configure static IPs.
#3. A “shim” interface is used to connect nodes to the Pods' multus public network.
#4. The node’s “shim” interface type must be the same as the Pod's NetworkAttachmentDefinition.
#5. The base-iface must match the Multus public network's parent/master interface (typically eth0 or bond0.)
#6. The ipv4 (or ipv6`) section configures node IP addresses on the Multus public network.
#7. Unique IP address assigned to this node. Don’t forget to change the IP for each node.
#8. The routes section instructs nodes how to reach pods on the Multus public network.
#9. The route destination(s) of the Pods' CIDR range.
```
### Pod configuration (via NetworkAttachmentDefinition)
https://docs.redhat.com/en/documentation/red_hat_openshift_data_foundation/4.16/html/planning_your_deployment/network-requirements_rhodf#multus-examples_rhodf
#### Option 1 - When Node network is a part of the larger Pod network
The ODF Pods need to connect with the Nodes. This "just works" if the (smaller CIDR) Node network is within the Pod's network (larger CIDR)
**Each Ceph service (mon, osd, etc...) gets an IP address from here**
```yaml=
# Node network: 192.168.255.0/24 (exclude from NetworkAttachmentDefintion's whereabouts)
# Pod network: 192.168.128.0/17 (see NetworkAttachmentDefinition)
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: odf-public
namespace: openshift-storage
spec:
config: '{
"cniVersion": "0.3.1",
"type": "macvlan", # [1]
"master": "bridge-data", # [2]
"mode": "bridge",
"mtu": 9000, # Omit unless switch config allows this
"ipam": {
"type": "whereabouts", # [3]
"range": "192.168.128.0/17", # [4]
"exclude": [
"192.168.255.0/24" # [5]
]
}
}'
#1. Pods must attach to the parent/master using the same interface type (macvlan) configured via NodeNetworkConfigurationPolicies
#2. The net-attach-def's parent/master interface must match the NNCP (typically eth0 or bond0)
#3. Using whereabouts instead of DHCP for simplicity. OpenShift will be responsible for address assignment
#4. Pods will be assigned IPs in the range 192.168.0.0/16 with the exception of a range allocated to nodes (see 5)
#5. Exclude the range assigned to nodes via NNCP
#6. The routes section instructs pods how to reach nodes on the Multus public network. A corresponding route should exist in the NNCP
#7. The route destination (dst) must match the CIDR range planned for nodes
```
#### Option 2 - When the Node network is not a part of the Pod network
But if the node network is outside of the pod CIDR, create a dedicated / static route.
I'm not sure why this makes sense, but I had to do it once before...
Please note, the Node configuration (NNCP) needs to define a statci route to the Pod network as well *(change #9 of NNCP above)*
**Each Ceph service (mon, osd, etc...) gets an IP address from here**
```yaml=
# Node network: 192.168.255.0/24 (add static route to Pods' NetworkAttachmentDefintion)
# Pod network: 10.252.15.0/24 (add static route to Nodes' NodeNetworkConfigurationPolicies)
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: odf-public
namespace: openshift-storage
spec:
config: '{
"cniVersion": "0.3.1",
"type": "macvlan", # [1]
"master": "bridge-data", # [2]
"mode": "bridge",
"mtu": 9000, # Omit unless switch config allows this
"ipam": {
"type": "whereabouts", # [3]
"range": "10.252.15.0/24", # [4]
"routes": [ # [6]
{"dst": "192.168.255.0/24"} # [7]
]
}
}'
#1. Pods must attach to the parent/master using the same interface type (macvlan) configured via NodeNetworkConfigurationPolicies
#2. The net-attach-def's parent/master interface must match the NNCP (typically eth0 or bond0)
#3. Using whereabouts instead of DHCP for simplicity. OpenShift will be responsible for address assignment
#4. Pods will be assigned IPs in the range 192.168.0.0/16 with the exception of a range allocated to nodes (see 5)
#5. Exclude the range assigned to nodes via NNCP
#6. The routes section instructs pods how to reach nodes on the Multus public network. A corresponding route should exist in the NNCP
#7. The route destination (dst) must match the CIDR range planned for nodes
```
# Validation tool
Download the tool from here: https://access.redhat.com/articles/7014721
Run the tool like this:
```bash
./rook multus validation config --help
./rook multus validation config converged > my-config
vi my-config #add public network, and cluster network if applicable
./rook multus validation run --help
./rook multus validation run --config my-config
```
**Caveat - don't upgrade to 4.17 until the "holder" pods are gone**
https://access.redhat.com/articles/7078648
## Example using single NIC instead of bonded NICs
### Node configuration (via NodeNetworkConfigurationPolicy)
Servers need static IP addresses. Only showing control-plane0. Please also create copies (with unique IP addresses) for other nodes.
```yaml=
# Node network: 192.168.255.0/24 (exclude from NetworkAttachmentDefintion's whereabouts)
# Pod network: 192.168.128.0/17 (see NetworkAttachmentDefinition)
---
apiVersion: nmstate.io/v1
kind: NodeNetworkConfigurationPolicy
metadata:
name: control-plane0-odf-public-shim
spec:
nodeSelector:
kubernetes.io/hostname: control-plane0.example.com ### HOSTNAME
desiredState:
interfaces:
- name: odf-public-shim
description: Shim interface used to connect host to OpenShift Data Foundation public Multus network
type: mac-vlan
state: up
mac-vlan:
base-iface: enp129s0f1
mode: bridge
promiscuous: true
ipv4:
enabled: true
dhcp: false
address:
- ip: 192.168.255.100 ### STATIC IP
prefix-length: 24
- name: enp129s0f1 ## This interface section can be omitted if you don't care about LLDP
type: ethernet
state: up
lldp:
enabled: true ## I love LLDP!
ipv4:
enabled: false
ipv6:
enabled: false
routes:
config:
- destination: 192.168.128.0/17
next-hop-interface: odf-public-shim
```
### Pod configuration (via NetworkAttachmentDefinition)
**Each Ceph service (mon, osd, etc...) gets an IP address from here**
```yaml=
# https://docs.redhat.com/en/documentation/red_hat_openshift_data_foundation/4.16/html/planning_your_deployment/network-requirements_rhodf#multus-examples_rhodf
# Node network: 192.168.255.0/24 (exclude from NetworkAttachmentDefintion's whereabouts)
# Pod network: 192.168.128.0/17 (see NetworkAttachmentDefinition)
# JCALL - the block below doesn't declare any static routes. I assume this is when the node network is within the pod/public/multus network
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: odf-public
namespace: openshift-storage
spec:
config: '{
"cniVersion": "0.3.1",
"type": "macvlan", # [1]
"master": "enp129s0f1", # [2]
"mode": "bridge",
"ipam": {
"type": "whereabouts", # [3]
"range": "192.168.128.0/17", # [4]
"exclude": [
"192.168.255.0/24" # [5]
]
}
}'
#1. Pods must attach to the parent/master using the same interface type (macvlan) configured via NodeNetworkConfigurationPolicies
#2. The net-attach-def's parent/master interface must match the NNCP (typically eth0 or bond0)
#3. Using whereabouts instead of DHCP for simplicity. OpenShift will be responsible for address assignment
#4. Pods will be assigned IPs in the range 192.168.0.0/16 with the exception of a range allocated to nodes (see 5)
#5. Exclude the range assigned to nodes via NNCP
#6. The routes section instructs pods how to reach nodes on the Multus public network. A corresponding route should exist in the NNCP
#7. The route destination (dst) must match the CIDR range planned for nodes
```
## Example using VLAN tags (non-overlapping)
### Node configuration (via NodeNetworkConfigurationPolicy)
```yaml=
# Node network: 192.168.252.0/24 (add static route to Pods' NetworkAttachmentDefintion)
# Pod network: 10.252.16.0/24 (add static route to Nodes' NodeNetworkConfigurationPolicies)
---
apiVersion: nmstate.io/v1
kind: NodeNetworkConfigurationPolicy
metadata:
name: control-plane-0-odf-public-shim-via-vlan-252
spec:
nodeSelector:
kubernetes.io/hostname: control-plane0.example.com ### HOSTNAME
desiredState:
interfaces:
- name: eth0.252
type: vlan
state: up
ipv4:
enabled: false
ipv6:
enabled: false
lldp:
enabled: true
vlan:
base-iface: eth0
id: 252
protocol: 802.1q
- name: odf-public-shim
type: mac-vlan
state: up
ipv4:
enabled: true
dhcp: false
address:
- ip: 192.168.252.11 ### Node network
prefix-length: 24
ipv6:
enabled: false
mac-vlan:
base-iface: eth0.252
mode: bridge
promiscuous: true
routes:
config:
- destination: 10.252.16.0/24 ### Pod network
next-hop-interface: odf-public-shim
```
### Pod configuration (via NetworkAttachmentDefinition)
```yaml=
# Node network: 192.168.252.0/24 (add static route to Pods' NetworkAttachmentDefintion)
# Pod network: 10.252.16.0/24 (add static route to Nodes' NodeNetworkConfigurationPolicies)
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: odf-public
namespace: openshift-storage
spec:
config: '{
"cniVersion": "0.3.1",
"type": "macvlan",
"master": "eth0.252",
"mode": "bridge",
"mtu": 9000, ### Omit MTU unless switch config allows this
"ipam": {
"type": "whereabouts",
"range": "10.252.16.0/24", ### Pod network
"routes": [
{"dst": "192.168.252.0/24"} ### Node network
]
}
}'
```