Skip to content

Commit

Permalink
vultr autoscaler implementation
Browse files Browse the repository at this point in the history
* vultr implementation

* increase/decrease

* vultr cleanup + changse

* fix golint errors

* adding support for API fields

* fixing missing clusterID

* fixing http method

* added boilerplate header

* adding vultr to builder_all

* change to builder_all

* fixing headers on builder_all

* vultr manager test

* vultr cloudprovider test

* remaining tests

* docs

* readme updates

* ran verify-golint.sh
  • Loading branch information
ddymko authored Jan 28, 2022
1 parent a393fe2 commit fa05b56
Show file tree
Hide file tree
Showing 18 changed files with 1,634 additions and 2 deletions.
2 changes: 2 additions & 0 deletions cluster-autoscaler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ You should also take a look at the notes and "gotchas" for your specific cloud p
* [Linode](./cloudprovider/linode/README.md)
* [ClusterAPI](./cloudprovider/clusterapi/README.md)
* [BizflyCloud](./cloudprovider/bizflycloud/README.md)
* [Vultr](./cloudprovider/vultr/README.md)

# Releases

Expand Down Expand Up @@ -167,3 +168,4 @@ Supported cloud providers:
* Linode https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/linode/README.md
* Hetzner https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/hetzner/README.md
* Cluster API https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/clusterapi/README.md
* Vultr https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/vultr/README.md
8 changes: 6 additions & 2 deletions cluster-autoscaler/cloudprovider/builder/builder_all.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build !gce && !aws && !azure && !kubemark && !alicloud && !magnum && !digitalocean && !clusterapi && !huaweicloud && !ionoscloud && !linode && !hetzner && !bizflycloud && !brightbox && !packet
// +build !gce,!aws,!azure,!kubemark,!alicloud,!magnum,!digitalocean,!clusterapi,!huaweicloud,!ionoscloud,!linode,!hetzner,!bizflycloud,!brightbox,!packet
//go:build !gce && !aws && !azure && !kubemark && !alicloud && !magnum && !digitalocean && !clusterapi && !huaweicloud && !ionoscloud && !linode && !hetzner && !bizflycloud && !brightbox && !packet && !vultr
// +build !gce,!aws,!azure,!kubemark,!alicloud,!magnum,!digitalocean,!clusterapi,!huaweicloud,!ionoscloud,!linode,!hetzner,!bizflycloud,!brightbox,!packet,!vultr

/*
Copyright 2018 The Kubernetes Authors.
Expand Down Expand Up @@ -39,6 +39,7 @@ import (
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/magnum"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/ovhcloud"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/packet"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/vultr"
"k8s.io/autoscaler/cluster-autoscaler/config"
)

Expand All @@ -62,6 +63,7 @@ var AvailableCloudProviders = []string{
cloudprovider.BizflyCloudProviderName,
cloudprovider.BrightboxProviderName,
cloudprovider.PacketProviderName,
cloudprovider.VultrProviderName,
}

// DefaultCloudProvider is GCE.
Expand Down Expand Up @@ -105,6 +107,8 @@ func buildCloudProvider(opts config.AutoscalingOptions, do cloudprovider.NodeGro
return ionoscloud.BuildIonosCloud(opts, do, rl)
case cloudprovider.LinodeProviderName:
return linode.BuildLinode(opts, do, rl)
case cloudprovider.VultrProviderName:
return vultr.BuildVultr(opts, do, rl)
}
return nil
}
42 changes: 42 additions & 0 deletions cluster-autoscaler/cloudprovider/builder/builder_vultr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//go:build vultr
// +build vultr

/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package builder

import (
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
"k8s.io/autoscaler/cluster-autoscaler/config"
)

// AvailableCloudProviders supported by the cloud provider builder.
var AvailableCloudProviders = []string{
cloudprovider.VultrProviderName,
}

// DefaultCloudProvider for linode-only build is linode.
const DefaultCloudProvider = cloudprovider.VultrProviderName

func buildCloudProvider(opts config.AutoscalingOptions, do cloudprovider.NodeGroupDiscoveryOptions, rl *cloudprovider.ResourceLimiter) cloudprovider.CloudProvider {
switch opts.CloudProviderName {
case cloudprovider.VultrProviderName:
return vultr.BuildLinode(opts, do, rl)
}

return nil
}
2 changes: 2 additions & 0 deletions cluster-autoscaler/cloudprovider/cloud_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ const (
OVHcloudProviderName = "ovhcloud"
// LinodeProviderName gets the provider name of linode
LinodeProviderName = "linode"
// VultrProviderName gets the provider name of vultr
VultrProviderName = "vultr"
// PacketProviderName gets the provider name of packet
PacketProviderName = "packet"
)
Expand Down
Empty file.
37 changes: 37 additions & 0 deletions cluster-autoscaler/cloudprovider/vultr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Cluster Autoscaler for Vultr

The cluster autoscaler for Vultr scales nodes in a VKE cluster.

## Vultr Kubernetes Engine

Vultr Kubernetes Engine ([VKE](https://www.vultr.com/docs/vultr-kubernetes-engine/)) is the managed kubernetes solution provided by Vultr.

VKE lets users create Node Pools, i.e. groups of nodes each of the same type.

The size of a Node Pool can be configured at any moment. The user cannot select specific nodes to be deleted when downsizing a Node Pool, rather, VKE will randomly select nodes to be deleted to reach the defined size, even if a node is not healthy or has been manually deleted.

Nodes in a Node Pool are considered disposable: they can be deleted and recreated at any moment, deleting a single node outside of VKE will be recreated by Vultr after a small amount of time.


## Configuration

It is mandatory to define the cloud configuration file `cloud-config`. You can see an example of the cloud config file at [examples/cluster-autoscaler-secret.yaml](examples/cluster-autoscaler-secret.yaml), it is an INI file with the following fields:

The (JSON) configuration file of the Vultr cloud provider supports the following values:

- `cluster_id`: the ID of the VKE cluster.
- `token`: the Vultr API key literally defined.


Configuring the autoscaler such as if it should be monitoring node pools or what the minimum and maximum values. Should be configured through the [Vultr API](https://www.vultr.com/api/#tag/kubernetes).
The autoscaler will pick up any changes and adjust accordingly.

## Development

Make sure you are inside the `cluster-autoscaler` path of the [autoscaler repository](https://github.com/kubernetes/autoscaler).

Create the docker image:
```
make container
```
tag the generated docker image and push it to a registry.
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-addon: cluster-autoscaler.addons.k8s.io
k8s-app: cluster-autoscaler
name: cluster-autoscaler
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-autoscaler
labels:
k8s-addon: cluster-autoscaler.addons.k8s.io
k8s-app: cluster-autoscaler
rules:
- apiGroups: [""]
resources: ["events", "endpoints"]
verbs: ["create", "patch"]
- apiGroups: [""]
resources: ["pods/eviction"]
verbs: ["create"]
- apiGroups: [""]
resources: ["pods/status"]
verbs: ["update"]
- apiGroups: [""]
resources: ["endpoints"]
resourceNames: ["cluster-autoscaler"]
verbs: ["get", "update"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["watch", "list", "get", "update"]
- apiGroups: [""]
resources:
- "namespaces"
- "pods"
- "services"
- "replicationcontrollers"
- "persistentvolumeclaims"
- "persistentvolumes"
verbs: ["watch", "list", "get"]
- apiGroups: ["extensions"]
resources: ["replicasets", "daemonsets"]
verbs: ["watch", "list", "get"]
- apiGroups: ["policy"]
resources: ["poddisruptionbudgets"]
verbs: ["watch", "list"]
- apiGroups: ["apps"]
resources: ["statefulsets", "replicasets", "daemonsets"]
verbs: ["watch", "list", "get"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses", "csinodes", "csistoragecapacities", "csidrivers"]
verbs: ["watch", "list", "get"]
- apiGroups: ["batch", "extensions"]
resources: ["jobs"]
verbs: ["get", "list", "watch", "patch"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["create"]
- apiGroups: ["coordination.k8s.io"]
resourceNames: ["cluster-autoscaler"]
resources: ["leases"]
verbs: ["get", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: cluster-autoscaler
namespace: kube-system
labels:
k8s-addon: cluster-autoscaler.addons.k8s.io
k8s-app: cluster-autoscaler
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["create","list","watch"]
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["cluster-autoscaler-status", "cluster-autoscaler-priority-expander"]
verbs: ["delete", "get", "update", "watch"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-autoscaler
labels:
k8s-addon: cluster-autoscaler.addons.k8s.io
k8s-app: cluster-autoscaler
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-autoscaler
subjects:
- kind: ServiceAccount
name: cluster-autoscaler
namespace: kube-system

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: cluster-autoscaler
namespace: kube-system
labels:
k8s-addon: cluster-autoscaler.addons.k8s.io
k8s-app: cluster-autoscaler
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: cluster-autoscaler
subjects:
- kind: ServiceAccount
name: cluster-autoscaler
namespace: kube-system

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: cluster-autoscaler
namespace: kube-system
labels:
app: cluster-autoscaler
spec:
replicas: 1
selector:
matchLabels:
app: cluster-autoscaler
template:
metadata:
labels:
app: cluster-autoscaler
spec:
serviceAccountName: cluster-autoscaler
containers:
- image: k8s.gcr.io/autoscaling/cluster-autoscaler:latest
name: cluster-autoscaler
resources:
limits:
cpu: 100m
memory: 300Mi
requests:
cpu: 100m
memory: 300Mi
command:
- ./cluster-autoscaler
- --v=2
- --cloud-provider=vultr
- --cloud-config=/config/cloud-config
volumeMounts:
- name: ssl-certs
mountPath: /etc/ssl/certs/ca-certificates.crt
readOnly: true
- name: cloud-config
mountPath: /config
readOnly: true
imagePullPolicy: "Always"
volumes:
- name: ssl-certs
hostPath:
path: "/etc/ssl/certs/ca-certificates.crt"
- name: cloud-config
secret:
secretName: cluster-autoscaler-cloud-config
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
apiVersion: v1
kind: Secret
metadata:
name: cluster-autoscaler-cloud-config
namespace: kube-system
type: Opaque
stringData:
cloud-config: |-
{
"cluster_id": "6b8b7c8e-7314-4d17-bb0c-fcc9777230fa",
"token": "IAOBTDG35OTGH2UKCC3S6CNMDUPCN3ZNVBASQ"
}
Loading

0 comments on commit fa05b56

Please sign in to comment.