Deploy VirtualNetworkRouter in Cloud-Native Contrail Networking
SUMMARY Cloud-Native Contrail® Networking™ supports the
VirtualNetworkRouter (VNR) construct. This construct provides connectivity
between VirtualNetworks.
VirtualNetworkRouter Overview
Typically, VirtualNetwork (VN) traffic is isolated to maintain tenant
separation. In Cloud-Native Contrail Networking (CN2), VirtualNetworkRouter
(VNR) performs route leaking. Route leaking establishes connectivity between
VirtualNetworks by importing routing instances (RI) and the routing
tables associated with these instances. As a result, devices in one routing table can access
resources from devices in another routing table.
The VNR provides connectivity for the following two common network models:
-
Mesh: Pods in all connected
VirtualNetworkscommunicate with each other. -
Hub-spoke:
VirtualNetworksconnect to two different VNR types (spoke, hub).VirtualNetworksconnected to spoke-type VNRs communicate withVirtualNetworksconnected to hub-type VNRs and vice versa.VirtualNetworksconnected to spoke VNRs cannot communicate with otherVirtualNetworksattached to spoke VNRs.
VNR is a Kubernetes construct deployed within CN2.
VirtualNetworkRouter Use Cases
The following examples are common use cases that demonstrate the functionality of VNR in CN2.
Mesh Use Cases
Hub-spoke Use Cases
Mesh VNR That Connects Two or More Virtual Networks in the Same Namespace

- Figure-1: The user creates VN1 and VN2 in namespace-1. Pods in VN1 cannot connect to
pods in VN2. This is the default behavior of
VirtualNetworksin CN2. - Figure-2: The user defines a VNR of type mesh that selects VN1 and VN2. This VNR allows Pods in VN1 to communicate with Pods in VN2 and vice-versa.
- Figure-3: Pods in VN1 connect to Pods in VN2. The route-target of VNR is
importExportedto bothVirtualNetworks.
Add New Virtual Networks Within the Same Namespace to an Existing Mesh-Type VNR

- Figure-1: Two
VirtualNetworks(VN1, VN2) connect to VNR in namespace-1. - Figure-2: The user creates two new
VirtualNetworks(VN3, VN4). - Figure-3: VN3 and VN4 connect to VNR. As a result, all
VirtualNetworksconnected to the VNR receive connectivity.
Two Mesh VNRs in the Same Namespace

-
Figure 1 and Figure 2: VNR-web and VNR-db of type mesh already exist in namespace-1. Only VNRs connected to respective VNRs communicate with each other.
-
Figure 1 and Figure 2: VNR-web and VNR-db communicate with each other.
- Figure 3: All
VirtualNetworksconnected to both VNR-web and VNR-db communicate with each other.
Two Mesh VNRs with Different Namespaces

-
Figure 1: VNR-web selects VN1 and VN2. Pods in VN1 and VN2 communicate with each other. VN1 and VN2 cannot communicate with VN3 or VN4.
-
Figure 2: VNR-db selects VN3 and VN4. Pods in VN3 and VN4 communicate with each other. VN3 and VN4 cannot communicate with VN1 or VN2.
-
Figure 3: The user updates VNR-web to select VNR-db.
-
Figure 3: The user updates VNR-db to select VNR-web.
-
Figure 3: Since two VNRs select each other, VNR-web's RT (route target) is added to VN3 and VN4. VNR-db's RT is added to VN1 and VN2. Pods in VN1, VN2, VN3, and VN4 communicate with each other.
Note:VNRs select VNs based on
matchExpressionlabels in avirtualNetworkSelectorspec. For example, in the illustration above, VNR-web in namespace-1 selects VN1 and VN2 based on the labelvn: webfrom namespace-1. AvirtualNetworkSelectoronly looks for matching labels within it's own namespace.
Hub and Spoke VNRs in the Same Namespace

-
Figure-1: Pods in VN1 cannot communicate with pods in VN2. VN1 and VN2 cannot communicate with VN3.
-
Figure-2: The user creates a VNR of type "spoke" and "hub." VNR-spoke and VNR-hub import each other's RTs.
-
Figure-3: VNR-spoke and VNR-hub's RTs are added to VN1, VN2, and VN3 because they import each others' RTs. As a result, pods in VN1 and VN2 communicate with VN3. Pods in VN1 and VN2 cannot communicate with each other.
Hub and Spoke VNRs in Different Namespaces

-
Figure 1 through Figure 3 are the same as Hub and Spoke VNRs in the Same Namespace, except that VNR-spoke and VNR-hub operate in different namespaces.
Same Virtual Networks Under Multiple VNRs

-
Figure 1: Pods in VN1 and VN2 cannot communicate with each other. Also resources on VN3, VN4 can communicate with each other.
-
Figure 2: You create a VNR-spoke by selecting VN1 and VN2. You create a VNR-hub by selecting VN3 and VN4. You create a VNR-mesh by selecting VN3 and VN4.
-
Figure 3: VNR-spoke ensures that VN1 and VN2 cannot communicate each other, VNR-hub lets VN1 and VN2 reach VN3 and VN4, and VNR-mesh enables communication between VN3 and VN4.
Use Case Explanation
This section comprises the following two VNR use cases along with end-to-end explanations of each use case:
Standard Use Case: Single VNR Connecting Two Virtual Networks
apiVersion: v1
kind: Namespace
metadata:
name: ns-single-mesh
labels:
ns: ns-single-mesh
spec:
finalizers:
- kubernetes
---
apiVersion: core.contrail.juniper.net/v1alpha1
kind: Subnet
metadata:
namespace: ns-single-mesh
name: subnet-1
annotations:
core.juniper.net/display-name: subnet_vn_1
spec:
cidr: "10.10.1.0/24"
defaultGateway: 10.10.1.254
---
apiVersion: core.contrail.juniper.net/v1alpha1
kind: Subnet
metadata:
namespace: ns-single-mesh
name: subnet-2
annotations:
core.juniper.net/display-name: subnet_vn_2
spec:
cidr: "10.10.2.0/24"
defaultGateway: 10.10.2.254
---
apiVersion: core.contrail.juniper.net/v1alpha1
kind: VirtualNetwork
metadata:
namespace: ns-single-mesh
name: vn-1
annotations:
core.juniper.net/display-name: vn-1
labels:
vn: web
spec:
v4SubnetReference:
apiVersion: core.contrail.juniper.net/v1alpha1
kind: Subnet
namespace: ns-single-mesh
name: subnet-1
---
apiVersion: core.contrail.juniper.net/v1alpha1
kind: VirtualNetwork
metadata:
namespace: ns-single-mesh
name: vn-2
annotations:
core.juniper.net/display-name: vn-2
labels:
vn: web
spec:
v4SubnetReference:
apiVersion: core.contrail.juniper.net/v1alpha1
kind: Subnet
namespace: ns-single-mesh
name: subnet-2
---
apiVersion: core.contrail.juniper.net/v1alpha1
kind: VirtualNetworkRouter
metadata:
namespace: ns-single-mesh
name: vnr-1
annotations:
core.juniper.net/display-name: vnr-1
labels:
vnr: web
spec:
type: mesh
virtualNetworkSelector:
matchExpressions:
- key: vn
operator: In
values:
- web
---
apiVersion: v1
kind: Pod
metadata:
name: pod-vn-1
namespace: ns-single-mesh
annotations:
k8s.v1.cni.cncf.io/networks: vn-1
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: agent-mode
operator: NotIn
values:
- dpdk
containers:
- name: pod-vn-1
image: svl-artifactory.juniper.net/atom-docker/cn2/bazel-build/dev/google-containers/toolbox
command: ["bash","-c","while true; do sleep 60s; done"]
securityContext:
privileged: true
imagePullPolicy: IfNotPresent
restartPolicy: OnFailure
---
apiVersion: v1
kind: Pod
metadata:
name: pod-vn-2
namespace: ns-single-mesh
annotations:
k8s.v1.cni.cncf.io/networks: vn-2
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: agent-mode
operator: NotIn
values:
- dpdk
containers:
- name: pod-vn-2
image: svl-artifactory.juniper.net/atom-docker/cn2/bazel-build/dev/google-containers/toolbox
command: ["bash","-c","while true; do sleep 60s; done"]
securityContext:
privileged: true
imagePullPolicy: IfNotPresent
restartPolicy: OnFailure
This use case comprises the following:
-
Two
VirtualNetworks(vn-1andvn-2) in namespacens-single-mesh. Both virtual networks have thelabelvn: web. EachVirtualNetworkcontains a single pod. TheVirtualNetworkvn-1containspod-vn-1. TheVirtualNetworkvn-2containspod-vn-2. -
A
type: meshVNR with the namevnr-1. This VNR establishes connectivity between the twoVirtualNetworksusingmatchExpressionsandvn: web. he VNR imports the RI and routing table ofvn-1tovn-2and vice versa. Sincevnr-1is a mesh-type VNR, all pods in connectedVirtualNetworkscommunicate with each other.
Update Use Case: Single VNR Connecting Two Additional Virtual Networks
apiVersion: v1
kind: Namespace
metadata:
name: ns-single-mesh
labels:
ns: ns-single-mesh
spec:
finalizers:
- kubernetes
---
apiVersion: core.contrail.juniper.net/v1alpha1
kind: Subnet
metadata:
namespace: ns-single-mesh
name: subnet-2
annotations:
core.juniper.net/display-name: subnet_vn_1
spec:
cidr: "10.10.3.0/24"
defaultGateway: 10.10.3.254
---
apiVersion: core.contrail.juniper.net/v1alpha1
kind: Subnet
metadata:
namespace: ns-single-mesh
name: subnet-4
annotations:
core.juniper.net/display-name: subnet_vn_2
spec:
cidr: "10.10.4.0/24"
defaultGateway: 10.10.4.254
---
apiVersion: core.contrail.juniper.net/v1alpha1
kind: VirtualNetwork
metadata:
namespace: ns-single-mesh
name: vn-3
annotations:
core.juniper.net/display-name: vn-1
labels:
vn: db
spec:
v4SubnetReference:
apiVersion: core.contrail.juniper.net/v1alpha1
kind: Subnet
namespace: ns-single-mesh
name: subnet-3
---
apiVersion: core.contrail.juniper.net/v1alpha1
kind: VirtualNetwork
metadata:
namespace: ns-single-mesh
name: vn-4
annotations:
core.juniper.net/display-name: vn-2
labels:
vn: middleware
spec:
v4SubnetReference:
apiVersion: core.contrail.juniper.net/v1alpha1
kind: Subnet
namespace: ns-single-mesh
name: subnet-4
---
apiVersion: core.contrail.juniper.net/v1alpha1
kind: VirtualNetworkRouter
metadata:
namespace: ns-single-mesh
name: vnr-2
annotations:
core.juniper.net/display-name: vnr-1
labels:
vnr: db
vnr: middleware
spec:
type: mesh
virtualNetworkSelector:
matchExpressions:
- key: vn
operator: In
values:
- db, middlware
---
apiVersion: v1
kind: Pod
metadata:
name: pod-vn-3
namespace: ns-single-mesh
annotations:
k8s.v1.cni.cncf.io/networks: vn-1
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: agent-mode
operator: NotIn
values:
- dpdk
containers:
- name: pod-vn-3
image: svl-artifactory.juniper.net/atom-docker/cn2/bazel-build/dev/google-containers/toolbox
command: ["bash","-c","while true; do sleep 60s; done"]
securityContext:
privileged: true
imagePullPolicy: IfNotPresent
restartPolicy: OnFailure
---
apiVersion: v1
kind: Pod
metadata:
name: pod-vn-4
namespace: ns-single-mesh
annotations:
k8s.v1.cni.cncf.io/networks: vn-2
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: agent-mode
operator: NotIn
values:
- dpdk
containers:
- name: pod-vn-4
image: svl-artifactory.juniper.net/atom-docker/cn2/bazel-build/dev/google-containers/toolbox
command: ["bash","-c","while true; do sleep 60s; done"]
securityContext:
privileged: true
imagePullPolicy: IfNotPresent
restartPolicy: OnFailure
This use case is similar to the standard use case, except that in this use case the user
updates the YAML file with an additional type: mesh VNR to connect two new
VirtualNetworks (vn-3 and vn-4) in
namespace ns-single-mesh. Note the following:
-
The VNR shown has the name
vnr-2in namespacens-single-meshwithmatchExpressions: db, middlware. -
The
VirtualNetworkvn-3has the labelvn: db, andvn-4has the labelvn: middleware.
As a result, vnr-2 imports the RI and routing table of
vn-3 to vn-4 and vice versa.
VirtualNetworkRouter Configuration
The following section provides YAML configuration information for the following resources:
API Type (Schema)
type VirtualNetworkRouterSpec struct {
// Common spec fields
CommonSpec `json:",inline" protobuf:"bytes,1,opt,name=commonSpec"`
// Type of VirtualNetworkRouter. valid types - mesh, spoke, hub
Type VirtualNetworkRouterType `json:"type,omitempty" protobuf:"bytes,2,opt,name=type"`
// Select VirtualNetworks to which this VNR's RT be shared
VirtualNetworkSelector *metav1.LabelSelector `json:"virtualNetworkSelector,omitempty" protobuf:"bytes,3,opt,name=virtualNetworkSelector"`
// Import Router targets from other virtualnetworkrouters
Import ImportVirtualNetworkRouter `json:"import,omitempty" protobuf:"bytes,4,opt,name=import"`
}
type ImportVirtualNetworkRouter struct {
VirtualNetworkRouters []VirtualNetworkRouterEntry `json:"virtualNetworkRouters,omitempty" protobuf:"bytes,1,opt,name=virtualNetworkRouters"`
}
type VirtualNetworkRouterEntry struct {
VirtualNetworkRouterSelector *metav1.LabelSelector `json:"virtualNetworkRouterSelector,omitempty" protobuf:"bytes,1,opt,name=virtualNetworkRouterSelector"`
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,2,opt,name=namespaceSelector"`
}
Mesh VNR
apiVersion: core.contrail.juniper.net/v1alpha1
kind: VirtualNetworkRouter
metadata:
namespace: frontend
name: vnr-1
annotations:
core.juniper.net/display-name: vnr-1
labels:
vnr: web
ns: frontend
spec:
type: mesh
virtualNetworkSelector:
matchLabels:
vn: web
import:
virtualNetworkRouters:
- virtualNetworkRouterSelector:
matchLabels:
vnr: db
namespaceSelector:
matchLabels:
ns: backend
The preceding YAML file is an example of a mesh VNR with the name vnr-1 in
namespace frontend, with the labels
vnr: web and ns: frontend. This VNR imports its
route-target to any VNR in the namespace backend with
matchLabel
vnr: db.
Spoke VNR
kind: VirtualNetworkRouter
metadata:
namespace: frontend
name: vnr-1
annotations:
core.juniper.net/display-name: vnr-1
labels:
vnrgroup: spokes
ns: frontend
spec:
type: spoke
virtualNetworkSelector:
matchLabels:
vngroup: spokes
import:
virtualNetworkRouters:
- virtualNetworkRouterSelector:
matchLabels:
vnrgroup: hubs
namespaceSelector:
matchLabels:
ns: backend
The preceding YAML file is an example of a spoke VNR with the name vnr-1
in namespace frontend with the labels
vnrgroup: spokes and ns: frontend. This VNR imports its
route-targets to any VNR in the namespace backend with
matchLabel
vnrgroup: hubs.
Hub VNR
apiVersion: core.contrail.juniper.net/v1alpha1
kind: VirtualNetworkRouter
metadata:
namespace: backend
name: vnr-2
annotations:
core.juniper.net/display-name: vnr-2
labels:
vnrgroup: hubs
ns: backend
spec:
type: hub
virtualNetworkSelector:
matchLabels:
vngroup: hubs
import:
virtualNetworkRouters:
- virtualNetworkRouterSelector:
matchLabels:
vnrgroup: spokes
namespaceSelector:
matchLabels:
ns: frontend
The preceding YAML file is an example of a hub VNR with the name vnr-2 in
the namespace backend with labels
vnrgroup: hubs and ns: backend. This VNR imports its
route-targets to any VNR in the namespace frontend with
matchLabels
vnrgroup: spokes.