Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a multi-dimensional pod autoscaler #7550

Open
wants to merge 39 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
e99ca87
added vendor files and go.mod
James-QiuHaoran Dec 2, 2024
1402100
added common/
James-QiuHaoran Dec 2, 2024
a032327
added mpa api-related files
James-QiuHaoran Dec 2, 2024
cb4eed3
added utils
James-QiuHaoran Dec 2, 2024
e6296f9
added mpa recommender
James-QiuHaoran Dec 2, 2024
344aaa3
added mpa updater
James-QiuHaoran Dec 2, 2024
118bd47
added mpa admission controller
James-QiuHaoran Dec 2, 2024
c83fcdc
added mpa deployment related scripts
James-QiuHaoran Dec 2, 2024
9a39e12
added mpa usage example
James-QiuHaoran Dec 2, 2024
c0e3d65
added mpa readme
James-QiuHaoran Dec 2, 2024
f77152c
fix: correct copyright year
davidspek Dec 2, 2024
ed9f5ab
fix: update packages and fix errors and tests
davidspek Dec 2, 2024
91d45bc
fix: add scripts for mpa
davidspek Dec 2, 2024
407956c
fix: update codegen
davidspek Dec 2, 2024
4064238
fix: bump k8s + vendor
davidspek Dec 2, 2024
2b4bb07
fix: correct boilerplate
davidspek Dec 2, 2024
b63064d
fix: more lint fixes
davidspek Dec 2, 2024
9a51d18
fix: update gofmt
davidspek Dec 2, 2024
a1ab09f
fix: more migrations
davidspek Dec 2, 2024
6389aef
fix: correct kubernetes version
davidspek Dec 2, 2024
dc78c05
fix: bump vpa + update container builds
davidspek Dec 2, 2024
e9e5094
fix: add some fixes for review comments on previous pr
davidspek Dec 2, 2024
2367de3
chore: some more cleanups
davidspek Dec 2, 2024
0778496
chore: more cleanups
davidspek Dec 2, 2024
9b767f4
fix: more cleanups
davidspek Dec 3, 2024
10a48ed
cleanup: temporarily remove vendored files
davidspek Dec 3, 2024
f2571e3
feat: add mpacheckpoint crd
davidspek Dec 4, 2024
507e6d8
cleanup: rename mpaCheckPoint
davidspek Dec 4, 2024
84e4d36
fix: more changes for mpa checkpoint
davidspek Dec 4, 2024
7060dcc
fix: add rbac for patching events
davidspek Dec 4, 2024
955ccdf
fix: remove requirement for vendored dependencies
davidspek Dec 10, 2024
33de40e
chore: update some deps
davidspek Dec 10, 2024
661ac22
fix: use nonroot final image
davidspek Dec 10, 2024
8dfbb96
fix: update crd gen logic
davidspek Dec 16, 2024
eefa91c
chore: update deps
davidspek Dec 16, 2024
5a0c905
feat: changes for using local vpa dependency
davidspek Dec 16, 2024
cafceb7
fix: recommender duplicate flag
davidspek Dec 16, 2024
ce04038
chore: start getting things in place for e2e testing
davidspek Dec 16, 2024
45ccdd9
fix: add missing rbac for status and leases
davidspek Dec 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 138 additions & 0 deletions multidimensional-pod-autoscaler/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Multi-dimensional Pod Autoscaler (MPA)

## Intro

Multi-dimensional Pod Autoscaler (MPA) combines Kubernetes [HPA](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)
and [VPA](../vertical-pod-autoscaler/README.md) so that scaling actions can be considered and actuated together in a holistic manner.
MPA separates the scaling recommendation and actuation completely so that any multi-dimensional autoscaling algorithms can be used as the "recommender".
The default recommender is a simple combination of HPA and VPA algorithm which

1) sets the requests automatically based on usage and
2) sets the number of replicas based on a target metric.

Like VPA, MPA is configured with a [Custom Resource Definition object](https://kubernetes.io/docs/concepts/api-extension/custom-resources/).
The custom resource is called [MultidimPodAutoscaler](./pkg/apis/autoscaling.k8s.io/v1alpha1/types.go).
It specifies which pods should be vertically and horizontally autoscaled as well as if/how the resource recommendations are applied.

To enable multi-dimensional pod autoscaling on your cluster please follow the installation procedure described below.

## Prerequisites

* `kubectl` should be connected to the cluster you want to install MPA.
* The metrics server must be deployed in your cluster. Read more about [Metrics Server](https://github.com/kubernetes-incubator/metrics-server).
* If you are using a GKE Kubernetes cluster, you will need to grant your current Google
identity `cluster-admin` role. Otherwise, you won't be authorized to grant extra
privileges to the MPA system components.
```console
$ gcloud info | grep Account # get current google identity
Account: [[email protected]]

$ kubectl create clusterrolebinding myname-cluster-admin-binding --clusterrole=cluster-admin [email protected]
Clusterrolebinding "myname-cluster-admin-binding" created
```
* You should make sure your API server supports Mutating Webhooks.
Its `--admission-control` flag should have `MutatingAdmissionWebhook` as one of
the values on the list and its `--runtime-config` flag should include
`admissionregistration.k8s.io/v1beta1=true`.
To change those flags, ssh to your API Server instance, edit
`/etc/kubernetes/manifests/kube-apiserver.manifest` and restart kubelet to pick
up the changes: ```sudo systemctl restart kubelet.service```
* Please upgrade `openssl` to version 1.1.1 or higher (needs to support `-addext` option).

## Installation

To install MPA, please download the source code of MPA
and run the following command inside the `multidimensional-pod-autoscaler` directory:

```
./hack/mpa-up.sh
```

Note: the script currently reads environment variables: `$REGISTRY` and `$TAG`.
Make sure they're unset unless you want to use a non-default version of MPA.

The script issues multiple `kubectl` commands to the
cluster that insert the configuration and start all needed pods
in the `kube-system` namespace. It also generates
and uploads a secret (a CA cert) used by MPA Admission Controller when communicating
with the API server.

## Tearing Down

To remove MPA installation:

```
./deploy/mpa-down.sh
```

## Quick Start

After [installation](#installation) the system is ready to recommend and set
resource requests for your pods.
In order to use it, you need to insert a *MultidimPodAutoscaler* resource for
each controller that you want to have automatically computed resource requirements.
This will be most commonly a **Deployment**.
There are four modes in which *MPAs* operate, same as [VPA modes](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler#quick-start).

#### Example Deployment

A simple way to check if Multidimensional Pod Autoscaler is fully operational in your
cluster is to create a sample deployment:

```
kubectl create -f examples/hamster.yaml
```

The above command creates a deployment with two pods, each running a single container
that requests 100 millicores and tries to utilize slightly above 200 millicores.

#### Example MPA Config

```
---
apiVersion: "autoscaling.k8s.io/v1alpha1"
kind: MultidimPodAutoscaler
metadata:
name: hamster-mpa
namespace: default
spec:
# recommenders field can be unset when using the default recommender.
# recommenders:
# - name: 'hamster-recommender'
scaleTargetRef:
apiVersion: "apps/v1"
kind: Deployment
name: hamster
resourcePolicy:
containerPolicies:
- containerName: '*'
minAllowed:
cpu: 100m
memory: 50Mi
maxAllowed:
cpu: 1
memory: 500Mi
controlledResources: ["cpu", "memory"]
constraints:
minReplicas: 1
maxReplicas: 6
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 30
```

Create an MPA:

```
kubectl create -f examples/hamster-mpa.yaml
```

To see MPA config and current recommended resource requests run:

```
kubectl describe mpa
```
47 changes: 47 additions & 0 deletions multidimensional-pod-autoscaler/common/kubeconfig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
Copyright 2024 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 common

import (
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/klog/v2"
)

// CreateKubeConfigOrDie builds and returns a kubeconfig from file or in-cluster configuration.
func CreateKubeConfigOrDie(kubeconfig string, kubeApiQps float32, kubeApiBurst int) *rest.Config {
var config *rest.Config
var err error
if len(kubeconfig) > 0 {
klog.V(1).InfoS("Using kubeconfig", "file", kubeconfig)
// use the current context in kubeconfig
config, err = clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
klog.Fatalf("Failed to build kubeconfig from file: %v", err)
}
} else {
config, err = rest.InClusterConfig()
if err != nil {
klog.Fatalf("Failed to create config: %v", err)
}
}

config.QPS = kubeApiQps
config.Burst = kubeApiBurst

return config
}
20 changes: 20 additions & 0 deletions multidimensional-pod-autoscaler/common/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
Copyright 2024 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 common

// MultidimPodAutoscalerVersion is the version of MPA.
const MultidimPodAutoscalerVersion = "0.0.1"
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mpa-admission-controller
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: mpa-admission-controller
template:
metadata:
labels:
app: mpa-admission-controller
spec:
serviceAccountName: mpa-admission-controller
securityContext:
runAsNonRoot: true
runAsUser: 65534 # nobody
containers:
- name: admission-controller
image: registry.k8s.io/autoscaling/mpa-admission-controller:latest
imagePullPolicy: IfNotPresent
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: tls-certs
mountPath: "/etc/tls-certs"
readOnly: true
resources:
limits:
cpu: 200m
memory: 500Mi
requests:
cpu: 50m
memory: 200Mi
ports:
- containerPort: 8000
- name: prometheus
containerPort: 8944
volumes:
- name: tls-certs
secret:
secretName: mpa-tls-certs
---
apiVersion: v1
kind: Service
metadata:
name: mpa-webhook
namespace: kube-system
spec:
ports:
- port: 443
targetPort: 8000
selector:
app: mpa-admission-controller
Loading
Loading