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
traffic is isolated to maintain tenant
separation. In Cloud-Native Contrail Networking, 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 on one routing table can access
resources from devices on 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 Cloud-Native Contrail Networking.
VirtualNetworkRouter Use Cases
The following examples are common use cases that demonstrate the functionality of VNR in Cloud-Native Contrail Networking.
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 Cloud-Native Contrail Networking. - 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: VNR-web and VNR-db of type mesh already exist in namespace-1. Only VNRs connected to respective VNRs communicate with each other.
- 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
- Fig-1: VNR-web selects VN1 and VN2. Pods in VN1 and VN2 communicate with each other. VN1 and VN2 cannot communicate with VN3 and VN4.
- Fig-2: VNR-db selects VN3 and VN4. Pods in VN3 and VN4 communicate with each other. VN3 and VN4 cannot communicate with VN1 and VN2.
- Fig-3: The user updates VNR-web to select VNR-db.
- Fig-3: The user updates VNR-db to select VNR-web.
- Fig-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.
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 other's RTs. As a result, pods in VN1 and VN2 communicate with VN3. Pods in VN1 and VN2 cannot communicate.
Hub and Spoke VNRs in Different Namespaces
- Figure-1-Figure-3 are the same as Hub and Spoke VNRs in the Same Namespace, except 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. but VN3, VN4. Also resources on VN3, VN4 can communicate each other
- Figure-2: Create VNR-spoke selecting VN1, VN2, VNR-hub selecting VN3, VN4, VNR-mesh selecting VN3, VN4
- Figure-3: VNR-spoke ensures VN1, VN2 can not communicate each other, VNR-hub lets VN1, VN2 to reach VN3, VN4 while VNR-mesh enable communication between VN3, 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 two VirtualNetworks
(vn-1
,
vn-2
) in namespace ns-single-mesh
. Both virtual networks
have the label
vn: web
. Each VirtualNetwork
contains a single pod. The
VirtualNetwork
vn-1
contains pod-vn-1
. The
VirtualNetwork
vn-2
contains pod-vn-2
. A type: mesh
VNR
with the name vnr-1
establishes connectivity between the two
VirtualNetworks
using matchExpressions
vn: web
. The VNR imports the RI and routing table of vn-1
to vn-2
and vice versa. Since vnr-1
is a mesh-type VNR,
all pods in connected VirtualNetworks
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 with an additional type: mesh
VNR to connect two new
VirtualNetworks
(vn-3
, vn-4
) in
namespace ns-single-mesh
. The VNR shown has the name vnr-2
in namespace ns-single-mesh
with matchExpressions: db,
middlware
. The VirtualNetwork
vn-3
has the label vn: db
and vn-4
has
the label vn: 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
This YAML 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
This YAML 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
This YAML 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
.