Create a LoadBalancer Service
SUMMARY This topic describes how to create a Load Balancer service in Juniper Cloud-Native Contrail® Networking™ (CN2).
LoadBalancer Service Overview
Juniper Networks supports LoadBalancer services using Cloud-Native Contrail Networking (CN2) Release 22.1 or later in a Kubernetes-orchestrated environment.
In Kubernetes, a service is an abstract way to expose an application running on a set of pods as a network service. See Kubernetes Services.
In CN2, the Kubernetes LoadBalancer service is implemented using the
InstanceIP
resource and FloatingIP
resource, both of
which are similar to the ClusterIP
service.
- The
FloatingIP
is used in the service implementation to expose an external IP to the LoadBalancer service. TheFloatingIP
resource is also associated with the pod'sVirtualMachineInterfaces
. - The
InstanceIP
resource is related to theVirtualNetwork
. TwoinstanceIPs
are created, one for the service network and one for the external network.
A controller service is implemented in Contrail's kubemanger. Kubemanager is the interface
between Kubernetes core resources, and the extended Contrail resources, such as the
VirtualNetwork
. When you create a LoadBalancer service, kubemanager
listens and allocates the IP from an external virtual network. This external virtual network
exposes the LoadBalancer service on the external IPs. Any requests received through the
provisioned external IP is ECMP load-balanced across the pods associated with the
LoadBalancer.
Create a LoadBalancer Service
The following sections describe how to create a LoadBalancer service in CN2.
- Prerequisites
- Define an External Virtual Network
- Specify the External Networks
- Define Service Level Annotations
- Examples: External Network Selection
Prerequisites
Before you create a LoadBalancer service, make sure of the following:
-
You have set up a working cloud networking environment using Kubernetes orchestration.
-
Cloud-Native Contrail Networking is operational.
-
You configured kubemanager to define the external networks to be used by the LoadBalancer service.
Define an External Virtual Network
Before you create a LoadBalancer service, you must define an external virtual network. You can define the virtual network two ways, by creating a NetworkAttachmentDefinition or by creating a virtual network.
A Multus deployment requires that you only use a NetworkAttachmentDefinition to define an external network.
The following example illustrates how to define an external virtual network using a
NetworkAttachmentDefinition
. In this example, the external IP is
allocated from the subnet range 192.168.102.0/24
.
apiVersion: "k8s.cni.cncf.io/v1" kind: NetworkAttachmentDefinition metadata: name: ecmp-default namespace: ecmp-project annotations: juniper.net/networks: '{ "ipamV4Subnet": "192.168.102.0/24", "fabricSNAT": false "core.juniper.net/display-name: "External Virtual Network" }' core.juniper.net/display-name: "External Virtual Network" labels: service.contrail.juniper.net/externalNetworkSelector: default-external spec: config: '{ "cniVersion": "0.3.1", "name": "ecmp-default", "type": "contrail-k8s-cni" }'
When you apply the NetworkAttachmentDefinition
, kubemanger creates a
virtual network with the name ecmp-default
in the namespace
ecmp-project
.
Specify the External Networks
By default, kubemanager allocates the external IP for a LoadBalancer service from the
default-external
network. To allocate the external IP from a different
network, you must define the external network using selectors.
The following is an example of a Kubemanager.yaml file specifying the
default-external
network selector and user-defined network selectors.
apiVersion: configplane.juniper.net/v1alpha1 kind: Kubemanager metadata: generation: 148 name: contrail-k8s-kubemanager namespace: contrail spec: externalNetworkSelectors: default-external: networkSelector: matchLabels: service.contrail.juniper.net/externalNetwork: default-external custom-external: namespaceSelector: matchLabels: customNamespaceKey: custom-namespace-value networkSelector: matchLabels: customNetworkKey: custom-network-value custom-external-in-service-namespace: networkSelector: matchLabels: customExternalInServiceNetworkKey: custom-external-in-service-network-value
The VirtualNetworks
listed below match the labels that shown in the
Kubemanager.yaml above (in relative order).
apiVersion: core.contrail.juniper.net/v1alpha1 kind: VirtualNetwork # matches example 1 metadata: name: default-external-vn namespace: contrail labels: service.contrail.juniper.net/externalNetworkSelector: default-external spec: v4SubnetReference: apiVersion: core.contrail.juniper.net/v1alpha1 attributes: ipamSubnets: - defaultGateway: 10.244.0.1 enableDHCP: true subnet: ipPrefix: 10.244.0.0 ipPrefixLen: "16" ---#this is how you define namespace selector # Namespace must have appropriate label if required by namespaceSelector apiVersion: v1 kind: Namespace metadata: labels: customNamespaceKey: custom-namespace-value #user for your external ip name: contrail namespace: custom-namespace --- apiVersion: core.contrail.juniper.net/v1alpha1 kind: VirtualNetwork metadata: name: external-vn-1 # matches example 2 and example 3 namespace: custom-namespace labels: customNetworkKey: custom-network-value spec: v4SubnetReference: apiVersion: core.contrail.juniper.net/v1alpha1 attributes: ipamSubnets: - defaultGateway: 10.0.0.1 enableDHCP: true subnet: ipPrefix: 10.0.0.0 ipPrefixLen: "16" --- apiVersion: core.contrail.juniper.net/v1alpha1 kind: VirtualNetwork metadata: name: external-vn-2 # matches example 4 namespace: custom-namespace labels: customExternalInServiceNetworkKey: custom-external-in-service-network-value spec: v4SubnetReference: apiVersion: core.contrail.juniper.net/v1alpha1 attributes: ipamSubnets: - defaultGateway: 192.168.0.1 enableDHCP: true subnet: ipPrefix: 192.168.0.0 ipPrefixLen: "16"
Define Service Level Annotations
Additionally, you can define the following service level annotations for external network discovery.
Annotation: externalNetwork .
In this example, the externalNetwork
annotation allocates an external IP
from the evn
virtual network in the namespace ns
.
apiVersion: v1 kind: Service metadata: name: my-service annotation: service.contrail.juniper.net/externalNetwork: ns/evn spec: type: LoadBalancer selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 9376
Annotation: externalNetworkSelector
In this example, the externalNetworkSelector
matches the name of the
externalNetworkSelector
defined in kubemanager.
apiVersion: v1 kind: Service metadata: name: my-service annotation: service.contrail.juniper.net/externalNetworkSelector: custom-external spec: type: LoadBalancer selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 9376
You can also define service level annotations in the namespace of the Kubernetes cluster, or in the namespace of the Contrail cluster. The service-level annotations takes precedence.
Examples: External Network Selection
The virtual networks defined in Specify the External Networks are linked to the annotations in the following examples.
The external virtual network is selected from one of the following in priority order:
Example 1: Default Selector.
Kubemanager first looks for the default external network. This example uses the
default-external
selector because no annotation is specified.
Matches the network contrail/default-external-vn
.
apiVersion: v1 kind: Service metadata: name: my-service spec: type: LoadBalancer selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 9376
Example 2: Custom namespace
Matches the network custom-namespace/external-vn-1
.
apiVersion: v1 kind: Service metadata: name: my-service annotation: service.contrail.juniper.net/externalNetwork: custom-namespace/external-vn-1 spec: type: LoadBalancer selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 9376
Example 3: External network matching preconfigured selector in a namespace.
Matches the network custom-namespace/external-vn-1
.
apiVersion: v1 kind: Service metadata: name: my-service annotation: service.contrail.juniper.net/externalNetworkSelector: custom-external spec: type: LoadBalancer selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 9376
Example 4: External network matching preconfigured selector in service namespace.
Matches the network custom-namespace/external-vn-2
.
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: custom-namespace
annotation:
customExternalInServiceNetworkKey: custom-external-in-service-network-value
spec:
type: LoadBalancer
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
Dual-Stack Networking Support
As an Administrator, you might need to select the IP family (IPv4 or IPv6) to use when defining a service. IPv4/IPv6 dual-stack networking enables the allocation of both IPv4 and IPv6 addresses to pods and services. If you do not define the IP family, the default IPv4 is used.
In this example, an IPv4 and IPv6 default external network is allocated for the LoadBalancer service.
apiVersion: v1 kind: Service metadata: name: MyService specs: ipFamilies: ["IPv4", "IPv6"]
For more information, see Overview: IPv4 and IPv6 Dual-Stack Networking.