Introduction

With a focus on having minimal human actions required, both in its deployment and operation, MetalK8s also intends to ease deployment and operation of complex applications, named Solutions, on its cluster.

This document defines what a Solution refers to, the responsibilities of each party in this integration, and will link to relevant documentation pages for detailed information.

What is a Solution?

We use the term Solution to describe a packaged Kubernetes application, archived as an ISO disk image, containing:

  • A set of OCI images to inject in MetalK8s image registry

  • An Operator to deploy on the cluster

  • Optionally, a UI for managing and monitoring the application

For more details, see the following documentation pages:

Once a Solution is imported in MetalK8s, a user can deploy one or more versions of the Solution Operator, using either the MetalK8s Solution CLI (./solutions.sh) or the MetalK8s UI Environment page, into separate Environments (namespaces). Using the Operator-defined CustomResource(s), the user can then effectively deploy the application packaged in the Solution.

How is a Solution declared in MetalK8s?

MetalK8s uses a BootstrapConfiguration object, stored in /etc/metalk8s/bootstrap.yaml, to define how the cluster should be configured from the bootstrap node, and what versions of MetalK8s are available to the cluster.

In the same vein, we use a SolutionsConfiguration object, stored in /etc/metalk8s/solutions.yaml, to declare which Solutions are available to the cluster, from the bootstrap node.

Here is how it looks like:

apiVersion: metalk8s.scality.com/v1alpha1
kind: SolutionsConfiguration
archives:
  - /solutions/storage_1.0.0.iso
  - /solutions/storage_latest.iso
  - /other_solutions/computing.iso
active:
  storage: 1.0.0

There is no explicit information about what an archive contains. Instead, we want the archive itself to contain such information (more details in Solution archive guidelines), and to discover it at import time.

Note that Solutions are imported based on this file contents, i.e. the images they contain are made available in the registry and the Operator is deployed, however deploying subsequent application(s) is left to the user, through manual operations or the Solution UI.

Note

Removing an archive path from the Solutions list effectively removes its related resources (CRDs, images) from a MetalK8s cluster.

Responsibilities of each party

This section intends to define the boundaries between MetalK8s and the Solutions to integrate with, in terms of “who is doing what?”.

Note

This is still a work in progress.

MetalK8s

MUST:

  • Handle reading and mounting of the Solution ISO archive

  • Provide tooling to deploy/upgrade a Solution’s CRDs and Operator

MAY:

  • Provide tooling to verify signatures in a Solution ISO

  • Expose management of Solutions in its own UI

Solution

MUST:

  • Comply with the standard archive structure defined by MetalK8s

  • If providing a UI, expose management of its Operator instances

  • Handle monitoring of its own services (both Operator and application)

SHOULD:

  • Use MetalK8s monitoring services (Prometheus and Grafana)

Note

Solutions can leverage the Prometheus Operator CRs for setting up the monitoring of their components. For more information, see Monitoring and Solution Operator guidelines.

Interaction diagrams

We include a detailed interaction sequence diagram for describing how MetalK8s will handle user input when deploying / upgrading Solutions.

Note

Open the image in a new tab to see it in full resolution.

@startuml

actor user as "User"
control ui as "MetalK8s UI"
control saltmaster as "Salt Master"
entity bootstrap as "Bootstrap node"
control apiserver as "Kubernetes API"
control registry as "MetalK8s registry"

== Import a new Solution (version) ==

user -> bootstrap : Upload Solution ISO
user -> bootstrap ++ : Run Solutions CLI to import archive
bootstrap -> bootstrap : Update SolutionsConfiguration file
bootstrap -> saltmaster ++ : Request Solutions import "orchestrate.solutions.import-components"

saltmaster -> bootstrap ++ : Run "metalk8s.solutions.available" formula
|||

loop For each ISO defined in "SolutionsConfiguration"

    |||
    saltmaster -> bootstrap ++ : Check ISO file (against our standards/constraints)
    |||
    bootstrap --> saltmaster -- : Return status (valid or not) and metadata if any
    |||

    alt ISO is invalid
        |||
        saltmaster -> saltmaster : Fail early
        |||
    else ISO is valid
        |||
        saltmaster -> bootstrap : Mount ISO
        bootstrap -> registry : Configure new ISO source
        bootstrap -> saltmaster : Solution imported successfully
        |||
    end
    |||
end
|||

loop For each Solution version in "metalk8s-solutions" ConfigMap not in "SolutionsConfiguration"
    |||
    bootstrap -> registry : Remove configuration for this Solution version
    bootstrap -> bootstrap : Unmount ISO
    bootstrap -> saltmaster : Solution removed successfully
    |||
end
|||

bootstrap -> saltmaster -- : All Solutions imported/removed successfully

saltmaster <-> apiserver : Update "metalk8s-solutions" ConfigMap

saltmaster -> saltmaster : Mount Solution content into Salt Master container

saltmaster -> bootstrap -- : Solution import finished

bootstrap -> user -- : Solutions imported successfully

|||

== Activate a Solution (version) ==

user -> bootstrap ++ : Run Solutions CLI to activate a version
bootstrap -> bootstrap : Update SolutionsConfiguration file
bootstrap -> saltmaster ++ : Request Solutions components deployment "orchestrate.solutions.deploy-components"

loop For each Solution version in SolutionsConfiguration
    |||

    alt Solution version is active
        |||
        saltmaster -> apiserver : Deploy/Update Solution version components
        |||
    else Solution version is not active
        |||
        saltmaster -> apiserver : Remove Solution version components
        |||
    end

    |||
    saltmaster -> apiserver : Update "metalk8s-solutions" ConfigMap
    |||
end
|||

saltmaster -> bootstrap -- : Solutions components deployment finished
bootstrap -> user -- : Solutions successfully activated


== Create an Environment ==

user -> bootstrap ++ : Run Solutions CLI to create an Environment
bootstrap -> apiserver : Create Environment Namespace
bootstrap -> apiserver : Set Environment name label on Namespace
bootstrap -> apiserver : Set Environment description annotation on Namespace
bootstrap -> apiserver : Create Environment ConfigMap "metalk8s-environment"
bootstrap -> user -- : Environment successfully created

== Add a Solution (version) to an Environment ==

user -> bootstrap ++ : Run Solutions CLI to add a Solution to an Environment
bootstrap -> apiserver : Update Environment ConfigMap "metalk8s-environment"
bootstrap -> saltmaster ++ : Request Environment preparation "orchestration.solutions.prepare-environment"
saltmaster <-> apiserver : Retrieve "metalk8s-environment" ConfigMap

loop For each Solution in "metalk8s-environment" ConfigMap
    |||

    alt Solution version is available
        |||
        saltmaster -> apiserver : Deploy Solution Operator ServiceAccount
        saltmaster -> apiserver : Deploy Solution Operator Role
        saltmaster -> apiserver : Deploy Solution Operator RoleBinding
        saltmaster -> apiserver : Deploy Solution Operator ConfigMap
        saltmaster -> apiserver : Deploy Solution Operator Deployment
        saltmaster -> apiserver : Deploy Solution UI ConfigMap
        saltmaster -> apiserver : Deploy Solution UI Deployment
        saltmaster -> apiserver : Deploy Solution UI Service
        saltmaster -> apiserver : Deploy Solution UI Ingress
        |||
    else Solution version is not available
        |||
        saltmaster -> saltmaster : Environment preparation failure
        |||
    end
    |||

end
|||

saltmaster -> bootstrap -- : Environment preparation finished
bootstrap -> user -- : Solutions successfully added to Environment

@enduml