I’m implementing the kOps side of the system for elemento, taking inspiration from similar Cloud providers like Scaleway and Hetzner

Define a common VM and networking specification

Possible parameters kOps

// ClusterName is the name of the cluster to initialize.
+ ClusterName string  (req.name)

// Authorization is the authorization mode to use. The options are "RBAC" (default) and "AlwaysAllow".
Authorization string
// Channel is a channel location for initializing the cluster. It defaults to "stable".
Channel string
// ConfigBase is the location where we will store the configuration. It defaults to the state store.
ConfigBase string
// DiscoveryStore is the location where we will store public OIDC-compatible discovery documents, under a cluster-specific directory. It defaults to not publishing discovery documents.
DiscoveryStore string
// KubernetesVersion is the version of Kubernetes to deploy. It defaults to the version recommended by the channel.
+ KubernetesVersion string (req.kubernetes_version)
// KubernetesFeatureGates is the list of Kubernetes feature gates to enable/disable.
KubernetesFeatureGates []string
// AdminAccess is the set of CIDR blocks permitted to connect to the Kubernetes API. It defaults to "0.0.0.0/0" and "::/0".
AdminAccess []string
// SSHAccess is the set of CIDR blocks permitted to connect to SSH on the nodes. It defaults to the value of AdminAccess.
SSHAccess []string
// NetworkCIDRs is the set of CIDR blocks of the cluster network.
+ NetworkCIDRs []string (req.nodes_subnet.subnet_netmask)

// CloudProvider is the name of the cloud provider. The default is to guess based on the Zones name.
+ CloudProvider string (elemento)
// Zones are the availability zones in which to run the cluster.
+ Zones []string (ovh, ionos, gigas, arubacloud, atomos)
// ControlPlaneZones are the availability zones in which to run the control-plane nodes. Defaults to the list in the Zones field.
ControlPlaneZones []string

// Project is the cluster's GCE project.
Project string
// GCEServiceAccount specifies the service account with which the GCE VM runs.
GCEServiceAccount string

// Spotinst options
SpotinstProduct     string
SpotinstOrientation string

// NetworkID is the ID of the shared network (VPC).
// If empty, SubnetIDs are not empty, and on AWS or OpenStack, determines network ID from the first SubnetID.
// If empty otherwise, creates a new network/VPC to be owned by the cluster.
+ NetworkID string (SDN?)
// SubnetIDs are the IDs of the shared subnets.
// If empty, creates new subnets to be owned by the cluster.
SubnetIDs []string
// UtilitySubnetIDs are the IDs of the shared utility subnets. If empty and the topology is "private", creates new subnets to be owned by the cluster.
UtilitySubnetIDs []string
// Egress defines the method of traffic egress for subnets.
Egress string
// IPv6 adds IPv6 CIDRs to subnets
IPv6 bool

// OpenstackExternalNet is the name of the external network for the openstack router.
OpenstackExternalNet     string
OpenstackExternalSubnet  string
OpenstackStorageIgnoreAZ bool
OpenstackDNSServers      string
OpenstackLBSubnet        string
// OpenstackLBOctavia is whether to use use octavia instead of haproxy.
OpenstackLBOctavia       bool
OpenstackOctaviaProvider string

AzureSubscriptionID    string
AzureTenantID          string
AzureResourceGroupName string
AzureRouteTableName    string
AzureAdminUser         string

// ControlPlaneCount is the number of control-plane nodes to create. Defaults to the length of ControlPlaneZones.
// if ControlPlaneZones is explicitly nonempty, otherwise defaults to 1.
ControlPlaneCount int32
// APIServerCount is the number of API servers to create. Defaults to 0.
APIServerCount int32
// EncryptEtcdStorage is whether to encrypt the etcd volumes.
EncryptEtcdStorage *bool

// EtcdClusters contains the names of the etcd clusters.
EtcdClusters []string
// EtcdStorageType is the underlying cloud storage class of the etcd volumes.
EtcdStorageType string

// NodeCount is the number of nodes to create. Defaults to leaving the count unspecified
// on the InstanceGroup, which results in a count of 2.
+ NodeCount int32 (req.nodepool.min_nodes e max_nodes?)
// Bastion enables the creation of a Bastion instance.
Bastion bool
// BastionLoadBalancerType is the bastion loadbalancer type to use; "public" or "internal".
// Defaults to "public".
BastionLoadBalancerType string

// Networking is the networking provider/node to use.
Networking string
// Topology is the network topology to use. Defaults to "public" for IPv4 clusters and "private" for IPv6 clusters.
Topology string
// DNSType is the DNS type to use; "public" or "private". Defaults to "public".
DNSType string
// DNSZone is the DNS zone to use.
DNSZone string

// APILoadBalancerClass determines whether to use classic or network load balancers for the API
APILoadBalancerClass string
// APILoadBalancerType is the Kubernetes API loadbalancer type to use; "public" or "internal".
// Defaults to using DNS instead of a load balancer if using public topology and not gossip, otherwise "public".
APILoadBalancerType string
// APISSLCertificate is the SSL certificate to use for the API loadbalancer.
// Currently only supported in AWS.
APISSLCertificate string

// InstanceManager specifies which manager to use for managing instances.
InstanceManager string

Image             string
NodeImage         string
ControlPlaneImage string
BastionImage      string
ControlPlaneSizes []string
+ NodeSizes         []stringYes bool  (flavour -> helium, argon, ecc...)

// Target is the type of target we will operate against (direct, dry-run, terraform)
+ Target cloudup.Target -> {
	// TargetDirect means we will apply the changes directly to the cloud.
	+ TargetDirect Target = "direct"
	// TargetDryRun means we will not apply the changes but will print what would have been done.
	TargetDryRun Target = "dryrun"
	// TargetTerraform means we will generate terraform code.
	TargetTerraform Target = "terraform"
}

ControlPlaneVolumeSize     int32
+ NodeVolumeSize             int32
ContainerRuntime           string
OutDir                     string
DisableSubnetTags          bool
NodeSecurityGroups         []string
ControlPlaneSecurityGroups []string
AssociatePublicIP          *bool

// SSHPublicKeys is a map of the SSH public keys we should configure; required on AWS, not required on GCE
SSHPublicKeys map[string][]byte

// Sets allows setting values directly in the spec.
Sets []string
// Unsets allows unsetting values directly in the spec.
Unsets []string

// CloudLabels are cloud-provider-level tags for instance groups and volumes.
CloudLabels string

// Specify tenancy (default or dedicated) for control-plane and worker nodes
ControlPlaneTenancy string
NodeTenancy         string

// Allow custom public Kubernetes API name.
APIPublicName string

OpenstackNetworkID string

// DryRun mode output a cluster manifest of Output type.
DryRun bool
// Output type during a DryRun
Output string

// AddonPaths specify paths to additional components that we can add to a cluster
AddonPaths []string

Requirement Elemento meson

VM:
{
    "specs": {
        "req": {
            "cpu": {
                "smtEnabled": false,
                "numberOfCores": 2,
                "numberOfThreads": 1,
                "min_frequency": 1.0,
                "arch": [
                    "X86_64"
                ],
                "flags": []
            },
            "mem": {
                "capacity": 4096,
                "requireECC": 0
            },
            "pci": {
                "devices": {}
            },
            "misc": {
                "osDistribution": "Debian"
            }
        },
        "volumes": [
            {
                "name": "test",
                "size": 30,
                "private": "True",
                "shareable": "False",
                "bootable": "False",
                "readonly": "False"
            }
        ],
        "authentication": {
            "ssh-key":"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDB9k+e0SEnYMPDDLEOvmpaIpLJz0l7o9DHswEUdPIRjxh3HRYyHnl8aw51cFFsyLodxn8o24yx3s+gFNlH04WmrhP7gPsR9Q0LDG7aEyHSCbO6keT+FOimXjyHWjsDaxf/mWFqI+wlacl2pOwIjP6JnO5AXCVZuSBZtViVa94/iG2wW7yaBECvMZi4xZUj6skphMGDtXq1n+jdd1oo+Y3w/6ZeeBrg+N93GiHAxO0P3Jjhs4wLXFHTZQmF8Y8g+Jqfw0FZZTFW+fMlx/nFn/8O1B3YIG6iQXFZk1+jC5Dfsa+E7wUWZZWbAb96MU5t7Kyu6ydGNUpYi6UoRQPOyuEvSKs0ELPofSxx9vLye9diwfd6NETTCPrlZTtVZ6GDFU1ebYykKHOxA67JZdgSj6PVN3WsdzPz52+yqS5/nVJRdbHAeCryLdv69O3BOCyCFQTAVRb7DY3YoSfO82/UaQXtMEPrFDRxaFgg8y6AqJqZwAt92aiAkyj1g6SOh4/3N0M= [email protected]"
        },
        "vm_name": "test"
    },
    "provider": "ionos"
}

KAAS:
{
	"req": {
			"name": "test8",
			"metadata": {},
			"nodepool": [
					{
							"autoscale": false, 	
							"desired_nodes": 3, 	
							"max_nodes": 3,
							"min_nodes": 3, 
							"specs": {
								 "cpu": 2,
								 "ram": 4096,
								 "storage": 40,
								 "gpu": 0
							},
							"billing": "HOURLY",
							"pool_name": "1poolname"
					}
				],
			"nodes_subnet": {
					"dhcp": "True",
					"subnet_netmask": "192.168.1.0/24",
					"start_address": "192.168.1.0", 
					"last_address": "192.168.1.24"
			},
			"update_policy": "NEVER_UPDATE",
			"kubernetes_version": "1.29.2"
	},
	"provider": "arubacloud"
}

Command to create cluster kOps

Example AWS:

kops create cluster --cloud=aws --networking calico --name=demok8scluster.k8s.local --state=s3://kops-abhi-storage-1 --zones=us-east-la --node-count=1 --node-size=t2.micro --master-size=t2.micro --master-volume-size=8 --node-volume-size=8

Fields:

    --admin-access strings                    Restrict API access to this CIDR.  If not set, access will not be restricted by IP. (default [0.0.0.0/0,::/0])
    --api-loadbalancer-type string            Type of load balancer for the Kubernetes API: public or internal
    --api-public-name string                  Domain name of the public Kubernetes API
    --api-ssl-certificate string              ARN of the SSL Certificate to use for the Kubernetes API load balancer (AWS only)
    --associate-public-ip                     Specify --associate-public-ip=[true|false] to enable/disable association of public IP for control-plane ASG and nodes. Default is 'true'.
    --authorization string                    Authorization mode: AlwaysAllow or RBAC (default "RBAC")
    --bastion                                 Enable a bastion instance group. Only applies to private topology.
    --bastion-image string                    Machine image for bastions. Takes precedence over --image
    --channel string                          Channel for default versions and configuration to use (default "stable")
    --cloud string                            Cloud provider to use - aws, digitalocean, gce, hetzner, openstack
    --cloud-labels string                     A list of key/value pairs used to tag all instance groups (for example "Owner=John Doe,Team=Some Team").
    --control-plane-count int32               Number of control-plane nodes. Defaults to one control-plane node per control-plane-zone
    --control-plane-image string              Machine image for control-plane nodes. Takes precedence over --image
    --control-plane-security-groups strings   Additional pre-created security groups to add to control-plane nodes.
    --control-plane-size strings              Machine type(s) for control-plane nodes
    --control-plane-tenancy string            Tenancy of the control-plane group (AWS only): default or dedicated
    --control-plane-volume-size int32         Instance volume size (in GB) for control-plane nodes
    --control-plane-zones strings             Zones in which to run control-plane nodes. (must be an odd number)
    --disable-subnet-tags                     Disable automatic subnet tagging
    --discovery-store string                  A public location where we publish OIDC-compatible discovery information under a cluster-specific directory. Enables IRSA in AWS.
    --dns string                              DNS type to use: public, private, none
    --dns-zone string                         DNS hosted zone (defaults to longest matching zone)
    --dry-run                                 If true, only print the object that would be sent, without sending it. This flag can be used to create a cluster YAML or JSON manifest.
    --encrypt-etcd-storage                    Generate key in AWS KMS and use it for encrypt etcd volumes
    --etcd-clusters strings                   Names of the etcd clusters: main, events (default [main,events])
    --etcd-storage-type string                The default storage type for etcd members
    --gce-service-account string              Service account with which the GCE VM runs. Warning: if not set, VMs will run as default compute service account.
-h, --help                                    help for cluster
    --image string                            Machine image for all instances
    --instance-manager string                 Instance manager to use (cloudgroups or karpenter. Default: cloudgroups) (default "cloudgroups")
    --ipv6                                    Use IPv6 for the pod network (AWS only)
    --kubernetes-feature-gates strings        List of Kubernetes feature gates to enable/disable
    --kubernetes-version string               Version of Kubernetes to run (defaults to version in channel)
    --network-cidr strings                    Network CIDR(s) to use
    --network-id string                       Shared Network or VPC to use
    --networking string                       Networking mode.  kubenet, external, flannel-vxlan (or flannel), flannel-udp, calico, canal, kube-router, amazonvpc, cilium, cilium-etcd, kindnet, cni. (default "cilium")
    --node-count int32                        Total number of worker nodes. Defaults to one node per zone
    --node-image string                       Machine image for worker nodes. Takes precedence over --image
    --node-security-groups strings            Additional pre-created security groups to add to worker nodes.
    --node-size strings                       Machine type(s) for worker nodes
    --node-tenancy string                     Tenancy of the node group (AWS only): default or dedicated
    --node-volume-size int32                  Instance volume size (in GB) for worker nodes
    --os-dns-servers string                   comma separated list of DNS Servers which is used in network
    --os-ext-net string                       External network to use with the openstack router
    --os-ext-subnet string                    External floating subnet to use with the openstack router
    --os-kubelet-ignore-az                    Attach volumes across availability zones
    --os-lb-floating-subnet string            External subnet to use with the Kubernetes API
    --os-network string                       ID of the existing OpenStack network to use
    --os-octavia                              Use octavia load balancer API
    --os-octavia-provider string              Octavia provider to use
    --out string                              Path to write any local output
-o, --output string                           Output format. One of json or yaml. Used with the --dry-run flag.
    --project string                          Project to use (must be set on GCE)
    --set strings                             Directly set values in the spec (default [])
    --ssh-access strings                      Restrict SSH access to this CIDR.  If not set, uses the value of the admin-access flag.
    --ssh-public-key string                   SSH public key to use
    --subnets strings                         Shared subnets to use
    --target target                           Valid targets: "direct", "terraform". Set this flag to "terraform" if you want kOps to generate terraform (default direct)
-t, --topology string                         Network topology for the cluster: 'public' or 'private'. Defaults to 'public' for IPv4 clusters and 'private' for IPv6 clusters.
    --unset strings                           Directly unset values in the spec
    --utility-subnets strings                 Shared utility subnets to use
-y, --yes                                     Specify --yes to immediately create the cluster
    --zones strings                           Zones in which to run the cluster
    --config string   yaml config file (default is $HOME/.kops.yaml)
    --name string     Name of cluster. Overrides KOPS_CLUSTER_NAME environment variable

How i choose the underlying cloud provider

The Elemento system automatically chooses the best location and region to deploy the resources based on the chosen specifications and prices.

The user can choose the continent to deploy via the parameter —-zones in the future the location of deployment will be refined.

Vm flavours

From my understanding the node-size accepts a flavour. I should build a set of flavours with defined specs.

The ones of Amazon:

image.png

Elemento ones: https://github.com/Elemento-Modular-Cloud/elemento-vm-templates/tree/master/templates

Here a set of elemento configs: