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
VirtualNetworks
communicate with each other. -
Hub-spoke:
VirtualNetworks
connect to two different VNR types (spoke, hub).VirtualNetworks
connected to spoke-type VNRs communicate withVirtualNetworks
connected to hub-type VNRs and vice versa.VirtualNetworks
connected to spoke VNRs cannot communicate with otherVirtualNetworks
attached 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
VirtualNetworks
in 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
importExported
to 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
VirtualNetworks
connected 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
VirtualNetworks
connected 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
matchExpression
labels in avirtualNetworkSelector
spec. For example, in the illustration above, VNR-web in namespace-1 selects VN1 and VN2 based on the labelvn: web
from namespace-1. AvirtualNetworkSelector
only 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-1
andvn-2
) in namespacens-single-mesh
. Both virtual networks have thelabel
vn: web
. EachVirtualNetwork
contains a single pod. TheVirtualNetwork
vn-1
containspod-vn-1
. TheVirtualNetwork
vn-2
containspod-vn-2
. -
A
type: mesh
VNR with the namevnr-1
. This VNR establishes connectivity between the twoVirtualNetworks
usingmatchExpressions
andvn: web
. he VNR imports the RI and routing table ofvn-1
tovn-2
and vice versa. Sincevnr-1
is a mesh-type VNR, all pods in connectedVirtualNetworks
communicate 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-2
in namespacens-single-mesh
withmatchExpressions: db, middlware
. -
The
VirtualNetwork
vn-3
has the labelvn: db
, andvn-4
has 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
.