Skip to content

Commit 1e0b433

Browse files
authored
Merge pull request kubernetes#3470 from exoscale/master
Add Exoscale provider Cluster Autoscaler
2 parents 91da9c4 + f117bdc commit 1e0b433

File tree

128 files changed

+23775
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

128 files changed

+23775
-0
lines changed

cluster-autoscaler/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,4 @@ Supported cloud providers:
143143
* Alibaba Cloud https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/alicloud/README.md
144144
* OpenStack Magnum https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/magnum/README.md
145145
* DigitalOcean https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/digitalocean/README.md
146+
* Exoscale https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/exoscale/README.md

cluster-autoscaler/cloudprovider/builder/builder_all.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/baiducloud"
2727
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/clusterapi"
2828
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/digitalocean"
29+
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/exoscale"
2930
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/gce"
3031
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud"
3132
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/magnum"
@@ -42,6 +43,7 @@ var AvailableCloudProviders = []string{
4243
cloudprovider.BaiducloudProviderName,
4344
cloudprovider.MagnumProviderName,
4445
cloudprovider.DigitalOceanProviderName,
46+
cloudprovider.ExoscaleProviderName,
4547
cloudprovider.HuaweicloudProviderName,
4648
clusterapi.ProviderName,
4749
}
@@ -63,6 +65,8 @@ func buildCloudProvider(opts config.AutoscalingOptions, do cloudprovider.NodeGro
6365
return baiducloud.BuildBaiducloud(opts, do, rl)
6466
case cloudprovider.DigitalOceanProviderName:
6567
return digitalocean.BuildDigitalOcean(opts, do, rl)
68+
case cloudprovider.ExoscaleProviderName:
69+
return exoscale.BuildExoscale(opts, do, rl)
6670
case cloudprovider.MagnumProviderName:
6771
return magnum.BuildMagnum(opts, do, rl)
6872
case cloudprovider.HuaweicloudProviderName:
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// +build exoscale
2+
3+
/*
4+
Copyright 2020 The Kubernetes Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package builder
20+
21+
import (
22+
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
23+
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/exoscale"
24+
"k8s.io/autoscaler/cluster-autoscaler/config"
25+
)
26+
27+
// AvailableCloudProviders supported by the Exoscale cloud provider builder.
28+
var AvailableCloudProviders = []string{
29+
cloudprovider.ExoscaleProviderName,
30+
}
31+
32+
// DefaultCloudProvider is Exoscale.
33+
const DefaultCloudProvider = cloudprovider.ExoscaleProviderName
34+
35+
func buildCloudProvider(opts config.AutoscalingOptions, do cloudprovider.NodeGroupDiscoveryOptions, rl *cloudprovider.ResourceLimiter) cloudprovider.CloudProvider {
36+
switch opts.CloudProviderName {
37+
case cloudprovider.ExoscaleProviderName:
38+
return exoscale.BuildExoscale(opts, do, rl)
39+
}
40+
41+
return nil
42+
}

cluster-autoscaler/cloudprovider/cloud_provider.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ const (
3737
BaiducloudProviderName = "baiducloud"
3838
// DigitalOceanProviderName gets the provider name of digitalocean
3939
DigitalOceanProviderName = "digitalocean"
40+
// ExoscaleProviderName gets the provider name of exoscale
41+
ExoscaleProviderName = "exoscale"
4042
// GceProviderName gets the provider name of gce
4143
GceProviderName = "gce"
4244
// MagnumProviderName gets the provider name of magnum
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Cluster Autoscaler for Exoscale
2+
3+
The Cluster Autoscaler (CA) for Exoscale scales worker nodes running in
4+
Exoscale Instance Pools.
5+
6+
7+
## Configuration
8+
9+
> Note: the following guide assumes you have the permissions to create
10+
> resources in the `kube-system` namespace of the target Kubernetes cluster.
11+
12+
In order to interact with the Exoscale API, the Exoscale CA must be configured
13+
with API credentials. This can be achieved using Kubernetes
14+
[*Secrets*][k8s-secrets], by exposing those as container environment variables.
15+
16+
We provide a convenience script that generates and applies a k8s manifest
17+
declaring Exoscale API credentials as a k8s *Secret* in your cluster from your
18+
local shell environment variables: once created, this *Secret* can be used in
19+
the CA *Deployment*.
20+
21+
First, start by exporting the Exoscale API credentials (we recommend that you
22+
create dedicated API credentials using the [Exoscale IAM][exo-iam] service) to
23+
provide to the CA in your shell:
24+
25+
```sh
26+
export EXOSCALE_API_KEY="EXOxxxxxxxxxxxxxxxxxxxxxxxx"
27+
export EXOSCALE_API_SECRET="xxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
28+
```
29+
30+
Next, run the following command from the same shell:
31+
32+
```
33+
./examples/generate-secret.sh
34+
```
35+
36+
Finally, ensure that the `exoscale-secret` *Secret* has been created
37+
successfully by running the following command:
38+
39+
```
40+
kubectl get secret --namespace kube-system exoscale-credentials
41+
```
42+
43+
44+
### Deploying the Cluster Autoscaler
45+
46+
To deploy the CA on your Kubernetes cluster, you can use the manifest provided
47+
as example:
48+
49+
```
50+
kubectl apply -f ./examples/cluster-autoscaler-run-on-master.yaml
51+
```
52+
53+
54+
## ⚠️ Important Notes
55+
56+
* The minimum node group size is 1
57+
* The maximum node group size is computed based on the current [Compute
58+
instances limit][exo-limits] of the Exoscale account the Cluster Autoscaler
59+
is running in.
60+
* It is not possible to target which Exoscale Instance Pool will be scaled. The
61+
Instance Pool candidate for scaling is determined based on the Compute
62+
instance the Kubernetes node is running on, depending on cluster resource
63+
constraining events emitted by the Kubernetes scheduler.
64+
65+
66+
[exo-iam]: https://community.exoscale.com/documentation/iam/quick-start/
67+
[exo-limits]: https://portal.exoscale.com/account/limits
68+
[k8s-secrets]: https://kubernetes.io/docs/concepts/configuration/secret/
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
---
2+
apiVersion: v1
3+
kind: ServiceAccount
4+
metadata:
5+
labels:
6+
k8s-addon: cluster-autoscaler.addons.k8s.io
7+
k8s-app: cluster-autoscaler
8+
name: cluster-autoscaler
9+
namespace: kube-system
10+
---
11+
apiVersion: rbac.authorization.k8s.io/v1
12+
kind: ClusterRole
13+
metadata:
14+
name: cluster-autoscaler
15+
labels:
16+
k8s-addon: cluster-autoscaler.addons.k8s.io
17+
k8s-app: cluster-autoscaler
18+
rules:
19+
- apiGroups: [""]
20+
resources: ["events", "endpoints"]
21+
verbs: ["create", "patch"]
22+
- apiGroups: [""]
23+
resources: ["pods/eviction"]
24+
verbs: ["create"]
25+
- apiGroups: [""]
26+
resources: ["pods/status"]
27+
verbs: ["update"]
28+
- apiGroups: [""]
29+
resources: ["endpoints"]
30+
resourceNames: ["cluster-autoscaler"]
31+
verbs: ["get", "update"]
32+
- apiGroups: [""]
33+
resources: ["nodes"]
34+
verbs: ["watch", "list", "get", "update"]
35+
- apiGroups: [""]
36+
resources:
37+
- "pods"
38+
- "services"
39+
- "replicationcontrollers"
40+
- "persistentvolumeclaims"
41+
- "persistentvolumes"
42+
verbs: ["watch", "list", "get"]
43+
- apiGroups: ["extensions"]
44+
resources: ["replicasets", "daemonsets"]
45+
verbs: ["watch", "list", "get"]
46+
- apiGroups: ["policy"]
47+
resources: ["poddisruptionbudgets"]
48+
verbs: ["watch", "list"]
49+
- apiGroups: ["apps"]
50+
resources: ["statefulsets", "replicasets", "daemonsets"]
51+
verbs: ["watch", "list", "get"]
52+
- apiGroups: ["storage.k8s.io"]
53+
resources: ["storageclasses", "csinodes"]
54+
verbs: ["watch", "list", "get"]
55+
- apiGroups: ["batch", "extensions"]
56+
resources: ["jobs"]
57+
verbs: ["get", "list", "watch", "patch"]
58+
- apiGroups: ["coordination.k8s.io"]
59+
resources: ["leases"]
60+
verbs: ["create"]
61+
- apiGroups: ["coordination.k8s.io"]
62+
resourceNames: ["cluster-autoscaler"]
63+
resources: ["leases"]
64+
verbs: ["get", "update"]
65+
---
66+
apiVersion: rbac.authorization.k8s.io/v1
67+
kind: Role
68+
metadata:
69+
name: cluster-autoscaler
70+
namespace: kube-system
71+
labels:
72+
k8s-addon: cluster-autoscaler.addons.k8s.io
73+
k8s-app: cluster-autoscaler
74+
rules:
75+
- apiGroups: [""]
76+
resources: ["configmaps"]
77+
verbs: ["create","list","watch"]
78+
- apiGroups: [""]
79+
resources: ["configmaps"]
80+
resourceNames: ["cluster-autoscaler-status", "cluster-autoscaler-priority-expander"]
81+
verbs: ["delete", "get", "update", "watch"]
82+
83+
---
84+
apiVersion: rbac.authorization.k8s.io/v1
85+
kind: ClusterRoleBinding
86+
metadata:
87+
name: cluster-autoscaler
88+
labels:
89+
k8s-addon: cluster-autoscaler.addons.k8s.io
90+
k8s-app: cluster-autoscaler
91+
roleRef:
92+
apiGroup: rbac.authorization.k8s.io
93+
kind: ClusterRole
94+
name: cluster-autoscaler
95+
subjects:
96+
- kind: ServiceAccount
97+
name: cluster-autoscaler
98+
namespace: kube-system
99+
100+
---
101+
apiVersion: rbac.authorization.k8s.io/v1
102+
kind: RoleBinding
103+
metadata:
104+
name: cluster-autoscaler
105+
namespace: kube-system
106+
labels:
107+
k8s-addon: cluster-autoscaler.addons.k8s.io
108+
k8s-app: cluster-autoscaler
109+
roleRef:
110+
apiGroup: rbac.authorization.k8s.io
111+
kind: Role
112+
name: cluster-autoscaler
113+
subjects:
114+
- kind: ServiceAccount
115+
name: cluster-autoscaler
116+
namespace: kube-system
117+
118+
---
119+
apiVersion: apps/v1
120+
kind: Deployment
121+
metadata:
122+
name: cluster-autoscaler
123+
namespace: kube-system
124+
labels:
125+
app: cluster-autoscaler
126+
spec:
127+
replicas: 1
128+
selector:
129+
matchLabels:
130+
app: cluster-autoscaler
131+
template:
132+
metadata:
133+
labels:
134+
app: cluster-autoscaler
135+
annotations:
136+
prometheus.io/scrape: 'true'
137+
prometheus.io/port: '8085'
138+
spec:
139+
serviceAccountName: cluster-autoscaler
140+
tolerations:
141+
- effect: NoSchedule
142+
operator: "Equal"
143+
value: "true"
144+
key: node-role.kubernetes.io/master
145+
nodeSelector:
146+
kubernetes.io/role: master
147+
containers:
148+
- image: k8s.gcr.io/autoscaling/cluster-autoscaler:latest
149+
name: cluster-autoscaler
150+
resources:
151+
limits:
152+
cpu: 100m
153+
memory: 300Mi
154+
requests:
155+
cpu: 100m
156+
memory: 300Mi
157+
command:
158+
- ./cluster-autoscaler
159+
- --cloud-provider=exoscale
160+
- --stderrthreshold=info
161+
#- --scale-down-delay-after-add=1m # For development
162+
#- --scale-down-unneeded-time=1m # For development
163+
#- --unremovable-node-recheck-timeout=1m # For development
164+
env:
165+
- name: EXOSCALE_API_KEY
166+
valueFrom:
167+
secretKeyRef:
168+
key: api-key
169+
name: exoscale-credentials
170+
- name: EXOSCALE_API_SECRET
171+
valueFrom:
172+
secretKeyRef:
173+
key: api-secret
174+
name: exoscale-credentials
175+
- name: EXOSCALE_API_ENDPOINT
176+
valueFrom:
177+
secretKeyRef:
178+
key: api-endpoint
179+
name: exoscale-credentials
180+
volumeMounts:
181+
- name: ssl-certs
182+
mountPath: /etc/ssl/certs/ca-certificates.crt
183+
readOnly: true
184+
- name: cloud-config
185+
mountPath: /config
186+
readOnly: true
187+
imagePullPolicy: "Always"
188+
volumes:
189+
- name: ssl-certs
190+
hostPath:
191+
path: "/etc/ssl/certs/ca-certificates.crt"
192+
- name: cloud-config
193+
secret:
194+
secretName: cluster-autoscaler-cloud-config
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/sh
2+
# Copyright 2020 The Kubernetes Authors.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
cat <<EOF | kubectl apply -f -
17+
apiVersion: v1
18+
kind: Secret
19+
metadata:
20+
name: exoscale-credentials
21+
namespace: kube-system
22+
type: Opaque
23+
data:
24+
api-endpoint: '$(printf "%s" "$EXOSCALE_API_ENDPOINT" | base64)'
25+
api-key: '$(printf "%s" "$EXOSCALE_API_KEY" | base64)'
26+
api-secret: '$(printf "%s" "$EXOSCALE_API_SECRET" | base64)'
27+
EOF

0 commit comments

Comments
 (0)