This document covers design specification, functionality, details for VirtualRouter custom resource(CR) in KupenStack. A Virtual Router CR manages router resources in the associated OpenStack cluster.
In networking, routers are used to provide connectivity between hosts on different networks. They decide how a packet should be routed. In KupenStack there are various VirtualNetworks(VN) separated by namespaces. VirtualMachines(VM) connected to these VN may require to communicate with VMs in another VN. A Virtual Router can solve this problem.
Also, a VM may want to connect to an external network, a Virtual Router can solve this problem as well.
Therefore, it is required to have a Virtual Router CR that can dynamically connect to these VNs and an external network to provide required connectivity to workloads connected to them.
apiVersion: kupenstack.io/v1alpha1
kind: VirtualRouter
# shortName=vr
metadata:
# scope=Namespaced
name: sample-router
namespace: default
spec:
# Name of the External Network that the router uses as its gateway.
# required=false, type=string
externalNetwork: provider-net
# Virtual Networks that should connect to this router.
# required=false, type=object
virtualNetworks:
selector:
# MatchLabels takes multiple key:value labels. These labels are used to
# search the required virtual networks to connect.
matchLabels:
key: value
key2: value
# ExtendScope takes a list of the names of additional namespaces inside which router
# should search vitual networks, in addition to its own namespace.
# required=false, type=array
extendScope:
- "backend-ns"
- "database-ns"
- "dev-ns"
# Routes defines the static routes.
# required=false, type=array
routes:
- destinationCidr: "10.10.100.0/24"
nextHopIP: "172.168.10.5"
status:
# Id of router at openstack cloud.
# type=string
id: a29d8-1d73n-2dw45-h4hr2
# Whether virtual router is ready for use or not.
# type=boolean
ready: true
# Contains list of all the virtual networks connected to this virtual router.
# type=array
virtualNetworkList: [ "Namespace/Name" ]
# IP address of virtual router from external network
# type=string
exteranlIP: "172.29.249.149"
Output on kubectl get virtualrouters or kubectl get vr
NAME EXTERNAL-NETWORK EXTERNAL-IP AGE
sample-router provider-net 172.29.249.149 47m
Output on kubectl get vr -o wide
NAME EXTERNAL-NETWORK EXTERNAL-IP AGE
sample-router provider-net 172.29.249.149 47m
Virtual Router CR is a namespaced resource. It can connect to many virtual networks and only one external network. Virtual Router(VR) uses the external network as its default gateway. By default the scope of VR is limited to the namespace it is created in.
External networks are special networks in KupenStack. These are cluster scoped. A VR can connect to anyone from the available external networks. This external network is then used as the default gateway by this VR.
VR can connect to multiple virtual networks. This field uses the approach of labels and selectors to dynamically connect to all the available virtual networks with matching labels in its scope. By default the scope of VR is limited to the namespace it is created in.
This field takes a list of namespaces and extends the scope of VR from the current namespace to the new namespaces specified in the list. This may be required to provide connectivity between VN from different namespaces.
This field takes a list of static routes to use for this virtual router. Every route is defined by two fields destinationCidr and nextHopIP. The destinationCidr defines the IP range that the packet may be destined to and nextHopIP tells the IP to which this packet should be routed to.
All fields in a VR are optional, hence VR can be created with minimal configuration as follow:
# Minimal Virtual Network example
apiVersion: kupenstack.io/v1alpha1
kind: VirtualRouter
metadata:
name: sample-router
---Suppose the goal is to route traffic between workloads of two VNs namely, my-vn1 and my-vn2 in ns1 then we need to create a VR that connects these two VN. First, make sure that both VNs have some common labels that can be used to select them let's say router=my-vr1. Now create a VR in the same namespace ns1 that tries to connect to these two VN as follow:
# VR that connects to all VN with labels router=my-vr1 (VN in same namespace)
apiVersion: kupenstack.io/v1alpha1
kind: VirtualRouter
metadata:
name: sample-router
namespace: ns1
spec:
virtualNetworks:
selector:
matchLabels:
router: my-vr1
---Now, our two VNs have a virtual router connecting them.
Let us say that my-vn2 is in a different namespace called ns2 instead of ns1 then the above VR custom resource has to be slightly modified. We need to add ns2 in the scope of our VR as follow:
# VR that connects to all VN with labels router=my-vr1 (VN in different namespace)
apiVersion: kupenstack.io/v1alpha1
kind: VirtualRouter
metadata:
name: sample-router
namespace: ns1
spec:
extendScope:
- "ns2"
virtualNetworks:
selector:
matchLabels:
router: my-vr1
---VR does not have any pre-clean-up requirements. Deleting a VR deletes it. But it is to be noted that if a VR is deleted then all VN connected to it will loose connection to it.
All fields of VR are mutable and can be changed.
Nil.
Note: This section describes how Virtual Routers are implemented internally using OpenStack. This section serve as an extra documentation to explain what is happening behind at the OpenStack. Although as a KupenStack user who is working with custom resources, this knowledge may not be required. Feel free to skip this section.
- When a VR is created in KupenStack then a Router resource is created in OpenStack for it. VR stores the reference of the Router ID from OpenStack.
- VR creates a Router with Admin State True.