Skip to content

Commit 6d10e3b

Browse files
alexelliswelteki
authored andcommitted
Add cloud-provider for Slicer
Slicer launches microVMs on KVM-enabled hosts with K3s and a join token to add and remove new nodes dynamically, which are fully isolated through Firecracker. Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
1 parent ffcbfee commit 6d10e3b

File tree

12 files changed

+990
-3
lines changed

12 files changed

+990
-3
lines changed

cluster-autoscaler/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ You should also take a look at the notes and "gotchas" for your specific cloud p
3939
* [OVHcloud](./cloudprovider/ovhcloud/README.md)
4040
* [Rancher](./cloudprovider/rancher/README.md)
4141
* [Scaleway](./cloudprovider/scaleway/README.md)
42+
* [Slicer](./cloudprovider/slicer/README.md)
4243
* [TencentCloud](./cloudprovider/tencentcloud/README.md)
4344
* [Utho](./cloudprovider/utho/README.md)
4445
* [Vultr](./cloudprovider/vultr/README.md)
@@ -242,6 +243,7 @@ Supported cloud providers:
242243
* OVHcloud https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/ovhcloud/README.md
243244
* Rancher https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/rancher/README.md
244245
* Scaleway https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/scaleway/README.md
246+
* Slicer https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/slicer/README.md
245247
* TencentCloud https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/tencentcloud/README.md
246248
* Utho https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/utho/README.md
247249
* Vultr https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/vultr/README.md

cluster-autoscaler/charts/cluster-autoscaler/templates/clusterrole.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ rules:
5656
{{- if (eq .Values.cloudProvider "kwok") }}
5757
- create
5858
{{- end }}
59-
{{- if or (eq .Values.cloudProvider "kwok") (eq .Values.cloudProvider "huaweicloud") }}
59+
{{- if or (eq .Values.cloudProvider "kwok") (eq .Values.cloudProvider "huaweicloud") (eq .Values.cloudProvider "slicer") }}
6060
- delete
6161
{{- end }}
6262
- get

cluster-autoscaler/cloudprovider/builder/builder_all.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
//go:build !gce && !aws && !azure && !kubemark && !alicloud && !magnum && !digitalocean && !clusterapi && !huaweicloud && !ionoscloud && !linode && !hetzner && !bizflycloud && !brightbox && !equinixmetal && !oci && !vultr && !tencentcloud && !scaleway && !externalgrpc && !civo && !rancher && !volcengine && !baiducloud && !cherry && !cloudstack && !exoscale && !kamatera && !ovhcloud && !kwok && !utho && !coreweave
2-
// +build !gce,!aws,!azure,!kubemark,!alicloud,!magnum,!digitalocean,!clusterapi,!huaweicloud,!ionoscloud,!linode,!hetzner,!bizflycloud,!brightbox,!equinixmetal,!oci,!vultr,!tencentcloud,!scaleway,!externalgrpc,!civo,!rancher,!volcengine,!baiducloud,!cherry,!cloudstack,!exoscale,!kamatera,!ovhcloud,!kwok,!utho,!coreweave
1+
//go:build !gce && !aws && !azure && !kubemark && !alicloud && !magnum && !digitalocean && !clusterapi && !huaweicloud && !ionoscloud && !linode && !hetzner && !bizflycloud && !brightbox && !equinixmetal && !oci && !vultr && !tencentcloud && !scaleway && !externalgrpc && !civo && !rancher && !volcengine && !baiducloud && !cherry && !cloudstack && !exoscale && !kamatera && !ovhcloud && !kwok && !utho && !coreweave && !slicer
2+
// +build !gce,!aws,!azure,!kubemark,!alicloud,!magnum,!digitalocean,!clusterapi,!huaweicloud,!ionoscloud,!linode,!hetzner,!bizflycloud,!brightbox,!equinixmetal,!oci,!vultr,!tencentcloud,!scaleway,!externalgrpc,!civo,!rancher,!volcengine,!baiducloud,!cherry,!cloudstack,!exoscale,!kamatera,!ovhcloud,!kwok,!utho,!coreweave,!slicer
33

44
/*
55
Copyright 2018 The Kubernetes Authors.
@@ -48,6 +48,7 @@ import (
4848
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/ovhcloud"
4949
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/rancher"
5050
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/scaleway"
51+
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/slicer"
5152
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/tencentcloud"
5253
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/utho"
5354
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/volcengine"
@@ -89,6 +90,7 @@ var AvailableCloudProviders = []string{
8990
cloudprovider.VolcengineProviderName,
9091
cloudprovider.UthoProviderName,
9192
cloudprovider.CoreWeaveProviderName,
93+
cloudprovider.SlicerProviderName,
9294
}
9395

9496
// DefaultCloudProvider is GCE.
@@ -161,6 +163,9 @@ func buildCloudProvider(opts *coreoptions.AutoscalerOptions,
161163
return utho.BuildUtho(opts, do, rl)
162164
case cloudprovider.CoreWeaveProviderName:
163165
return coreweave.BuildCoreWeave(opts, do, rl)
166+
case cloudprovider.SlicerProviderName:
167+
return slicer.BuildSlicer(opts, do, rl)
164168
}
169+
165170
return nil
166171
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//go:build slicer
2+
// +build slicer
3+
4+
/*
5+
Copyright 2024 The Kubernetes Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
*/
19+
20+
package builder
21+
22+
import (
23+
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
24+
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/slicer"
25+
coreoptions "k8s.io/autoscaler/cluster-autoscaler/core/options"
26+
"k8s.io/client-go/informers"
27+
)
28+
29+
// AvailableCloudProviders supported by the slicer cloud provider builder.
30+
var AvailableCloudProviders = []string{
31+
cloudprovider.SlicerProviderName,
32+
}
33+
34+
// DefaultCloudProvider for Slicer-only build is Slicer.
35+
const DefaultCloudProvider = cloudprovider.SlicerProviderName
36+
37+
func buildCloudProvider(opts *coreoptions.AutoscalerOptions, do cloudprovider.NodeGroupDiscoveryOptions, rl *cloudprovider.ResourceLimiter, _ informers.SharedInformerFactory) cloudprovider.CloudProvider {
38+
switch opts.CloudProviderName {
39+
case cloudprovider.SlicerProviderName:
40+
return slicer.BuildSlicer(opts, do, rl)
41+
}
42+
43+
return nil
44+
}

cluster-autoscaler/cloudprovider/cloud_provider.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ const (
9494
RancherProviderName = "rancher"
9595
// UthoProviderName gets the provider name of utho
9696
UthoProviderName = "utho"
97+
// SlicerProviderName gets the provider name of slicer
98+
SlicerProviderName = "slicer"
9799
)
98100

99101
// GpuConfig contains the label, type and the resource name for a GPU.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
## Slicer Cloud Provider for Cluster Autoscaler
2+
3+
The cluster autoscaler for [Slicer](https://slicervm.com/) scales nodes on lightweight slicer microVMs.
4+
5+
The architecture is as follows:
6+
7+
* Slicer runs a K3s control plane on one virtualisation host.
8+
* Slicer runs all agents on one or more additional virtualisation hosts running the Slicer REST API. Starting off with zero microVMs and relying on cluster autoscaler to add new ones as Pods cannot be scheduled to the existing set of nodes.
9+
10+
Check the documentation on [SlicerVM.com](https://docs.slicervm.com/examples/autoscaling-k3s/) for instructions on how to setup the cluster-autoscaler with with Slicer.
11+
12+
## Configuration
13+
14+
The `cluster-autoscaler` with Slicer needs a configuration file to work by using the `--cloud-config` parameter, it is an INI file with the following fields:
15+
16+
| Key | Value | Mandatory | Default |
17+
|-----|-------|-----------|---------|
18+
| `global/k3s-url` | The URL of the K3s control plane API server | yes | none |
19+
| `global/k3s-token` | The K3s join token for adding new agent nodes | yes | none |
20+
| `global/default-min-size` | Default minimum size of a node group (must be > 0) | no | 1 |
21+
| `global/default-max-size` | Default maximum size of a node group | no | 8 |
22+
| `nodegroup \"slicer_host_group_name\"/slicer-url` | The URL of the Slicer API server for this node group | yes | none |
23+
| `nodegroup \"slicer_host_group_name\"/slicer-token` | The authentication token for the Slicer API server | yes | none |
24+
| `nodegroup \"slicer_host_group_name\"/min-size` | Minimum size for a specific node group | no | global/defaut-min-size |
25+
| `nodegroup \"slicer_host_group_name\"/max-size` | Maximum size for a specific node group | no | global/defaut-max-size |
26+
27+
## Development
28+
29+
Follow the instructions in the [slicer docs](https://docs.slicervm.com/examples/autoscaling-k3s/) to setup a K3S cluster and host groups for nodes.
30+
31+
Make sure you are inside the `cluster-autoscaler` path of the [autoscaler repository](https://github.com/kubernetes/autoscaler).
32+
33+
### Run out of cluster
34+
35+
Start the cluster-autoscaler:
36+
37+
```bash
38+
#!/bin/bash
39+
go run . \
40+
--cloud-provider=slicer \
41+
--kubeconfig $HOME/k3s-cp-kubeconfig \
42+
--scale-down-enabled=true \
43+
--scale-down-delay-after-add=30s \
44+
--scale-down-unneeded-time=30s \
45+
--expendable-pods-priority-cutoff=-10 \
46+
--cloud-config="$HOME/cloud-config.ini" \
47+
--v=4
48+
```
49+
50+
### Run in cluster.
51+
52+
Build and publish an image:
53+
54+
```sh
55+
REGISTRY=ttl.sh/openfaasltd BUILD_TAGS=slicer TAG=dev make dev-release
56+
```
57+
58+
Create a the cloud-config secret:
59+
60+
```sh
61+
kubectl create secret generic cluster-autoscaler-cloud-config \
62+
--from-file=cloud-config=cloud-config.ini \
63+
-n kube-system
64+
```
65+
66+
Create a `values.yaml` for the cluster-autoscaler chart:
67+
68+
```yaml
69+
image:
70+
repository: ttl.sh/openfaasltd/cluster-autoscaler-slicer-amd64
71+
tag: dev
72+
73+
cloudProvider: slicer
74+
75+
fullnameOverride: cluster-autoscaler-slicer
76+
77+
autoDiscovery:
78+
clusterName: k3s-slicer
79+
80+
# Mount the cluster-autoscaler-cloud-config secret
81+
extraVolumeSecrets:
82+
cluster-autoscaler-cloud-config:
83+
name: cluster-autoscaler-cloud-config
84+
mountPath: /etc/slicer/
85+
items:
86+
- key: cloud-config
87+
path: cloud-config
88+
89+
# All your required parameters
90+
extraArgs:
91+
cloud-config: /etc/slicer/cloud-config
92+
# Standard logging
93+
logtostderr: true
94+
stderrthreshold: info
95+
v: 4
96+
97+
scale-down-enabled: true
98+
scale-down-delay-after-add: "30s"
99+
scale-down-unneeded-time: "30s"
100+
expendable-pods-priority-cutoff: -10
101+
```
102+
103+
Deploy with Helm:
104+
105+
```sh
106+
helm install cluster-autoscaler-slicer charts/cluster-autoscaler \
107+
--namespace=kube-system \
108+
--values=values.yaml
109+
```
110+
111+
To test the autoscaler do one of the following:
112+
113+
* Scale a deployment higher than can fit on the current set of control-plane nodes, then wait for the autoscaler to scale up the cluster.
114+
* Or, create a taint / affinity / anti-affinity rule that will prevent a pod from being scheduled to the existing set of nodes, then wait for the autoscaler to scale up the cluster.

0 commit comments

Comments
 (0)