The Liqo namespace model extends the Kubernetes namespace concept introducing the support for remote namespaces, “twins” of the local namespace. Those “twin” namespaces map the home cluster namespace and its associated resources (e.g., Service, Configmap) on remote clusters. Regarding pod offloading, remote namespaces host the offloaded pods belonging to the home twin namespace, as if they were executed in the home cluster.
Liqo provides a label-based mechanism to set up namespace offloading over remote clusters. To enable it, you should label a target namespace:
kubectl label namespace target-namespace liqo.io/enabled=true
Pods scheduled in the “target-namespace” will be potentially offloaded inside remote clusters. With the quick offloading approach, you are selecting all peered clusters suitable for offloading. If you need a fine-grained approach, you can rely on custom offloading and the NamespaceOffloading resource.
To control all different aspects of the namespace extension, Liqo provides a NamespaceOffloading resource. The policies defined inside the NamespaceOffloading object specify how the local namespace can be replicated on peered clusters.
Any namespace inside the home cluster can have its NamespaceOffloading resource and its corresponding offloading policy. In other words, the NamespaceOffloading object defines “per-namespace boundaries", limiting the scope where pods can be remotely offloaded.
As presented in the following example, the NamespaceOffloading resource is composed of three main fields:
apiVersion: offloading.liqo.io/v1alpha1 kind: NamespaceOffloading metadata: name: offloading namespace: target-namespace spec: namespaceMappingStrategy: DefaultName podOffloadingStrategy: LocalAndRemote clusterSelector: nodeSelectorTerms: - matchExpressions: - key: liqo.io/type operator: In values: - virtual-node
The resource name must always be “offloading” to ensure the uniqueness of a single configuration for each local namespace. A resource created with a different name will not trigger the topology creation.
The NamespaceMappingStrategy defines the naming strategy used to create the remote namespaces. The accepted values are:
|DefaultName (Default)||The remote namespaces have the name of the local namespace followed by the local cluster-id to guarantee the absence of conflicts.|
|EnforceSameName||The remote namespaces have the same name as the namespace in the local cluster (this approach can lead to conflicts if a namespace with the same name already exists inside the selected remote clusters).|
The DefaultName value is recommended if you do not have particular constraints related to the remote namespaces name. However, using the DefaultName policy, the namespace name cannot be longer than 63 characters according to the RFC 1123. Since the cluster-id is 37 characters long, the home namespace name can have at most 26 characters.
The PodOffloadingStrategy defines constraints about pod scheduling.
|LocalAndRemote (Default)||The pods deployed in the local namespace can be scheduled both locally and remotely.|
|Local||The pods deployed in the local namespace are always scheduled inside the local cluster, never remotely.|
|Remote||The pods deployed in the local namespace are always scheduled inside the remote clusters, never locally.|
Unlike pods, standard Kubernetes Services are always replicated inside all the selected clusters.
The LocalAndRemote strategy does not impose any constraints, and it leaves the scheduler the choice to select both local and remote nodes. The Remote and Local strategies force the pods to be scheduled respectively only remotely and only locally.
If you specify pod NodeSelectorTerms not compatible with these constraints, the pod will remain unscheduled and pending.
The ClusterSelector specifies the NodeSelectorTerms to target specific clusters of the topology.
Such NodeSelectorTerms can be specified by using the Kubernetes NodeAffinity syntax.
These selector terms specified inside the NamespaceOffloading resource are applied on every pod created inside the namespace.
If not specified at creation time, the ClusterSelector will target all virtual nodes available, enabling the offloading on all peered clusters. More precisely, the default value corresponds to:
clusterSelector: nodeSelectorTerms: - matchExpressions: - key: liqo.io/type operator: In values: - virtual-node
In Liqo 0.3, the NamespaceOffloading object must contain the configuration at creation time. If you want to modify its structure at run-time, you should delete the resource and recreate it with a new configuration. This triggers the deletion of all remote “twin” namespaces and the creation of new ones.
The MatchExpressions specified in the ClusterSelector term select labels attached to Liqo virtual nodes. More precisely, at Liqo installation time, you may identify a set of labels to expose the most relevant features of your cluster. After the peering phase, the virtual node will expose those labels, enabling the possibility to select it during the offloading configuration. Moreover, the scheduler will also be able to use these virtual nodes’ labels to impose affinity/anti-affinity policies at run-time.
It is worth noting that there is no restriction on the labels to choose. Labels can characterize your clusters showing their geographical location, the underlying provider, or the presence of specific hardware devices.
If you want to create deployment topologies that include all available clusters, you are not required to choose labels at installation time.
All virtual nodes expose the label
liqo.io/type = virtual-node by default.
Also the quick offloading approach relies on the NamespaceOffloading resource.
In fact, when the label
liqo.io/enabled = true is added to a namespace, this event triggers the creation of a default NamespaceOffloading resource inside the namespace.
The generated resource is equal to the template seen above, setting all fields to the default values:
|ClusterSelector||All remote clusters selection.|
Using the quick offloading approach, it is not possible to customize the generated NamespaceOffloading resource. If a NamespaceOffloading object is already present in the namespace, you should remove the label first and create the new resource.
If you create a custom NamespaceOffloading resource inside the namespace, the
liqo.io/enabled = true label is not necessary.
As previously said, this label is just a way to configure a quick offloading.
The Liqo controllers update the NamespaceOffloading object every time there is a change in the deployment topology. The resource status provides different information:
kubectl get namespaceoffloading offloading -n target-namespace -o yaml
The OffloadingPhase informs you about the namespaces offloading status. It can assume different values:
|Ready||Remote Namespaces have been correctly created inside previously selected clusters.|
|NoClusterSelected||No cluster matches user constraints or constraints are not specified with the right syntax (in this second case, an annotation is also set on the NamespaceOffloading resource, specifying what is wrong with the syntax)|
|SomeFailed||There was an error during some remote namespaces creation.|
|AllFailed||There was an error during all remote namespaces creation.|
|Terminating||Remote namespaces are undergoing graceful termination.|
The RemoteNamespacesConditions allows you to verify remote namespaces’ presence and their status inside all remote clusters. This field is a map that has the remote cluster-id as key and as value, a vector of conditions for the namespace created inside that remote cluster. There are two types of conditions:
|True||The remote namespace is successfully created.|
|False||There was a problem during the remote namespace creation.|
|True||The creation of a remote namespace inside this cluster is required|
|False||The creation of a remote namespace inside this cluster is not required.|
The RemoteNamespacesConditions syntax is the same of the standard v1.NamespaceCondition.
To terminate the offloading, you can remove the NamespaceOffloading resource inside the namespace or, in case of the quick offloading approach, the previously inserted label
liqo.io/enabled = true.
Deleting the NamespaceOffloading object or removing the label, all remote namespaces will be deleted with everything inside them.