mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-10-11 05:13:53 +00:00
This updates the HPA controller to use the polymorphic scale client from client-go. This should enable HPAs to work with arbitrary scalable resources, instead of just those in the extensions API group (meaning we can deprecate the copy of ReplicationController in extensions/v1beta1). It also means that the HPA controller now pays attention to the APIVersion field in `scaleTargetRef` (more specifically, the group part of it). Note that currently, discovery information on which resources are available where is only fetched once (the first time that it's requested). In the future, we may want a refreshing discovery REST mapper.
106 lines
4.1 KiB
Go
106 lines
4.1 KiB
Go
/*
|
|
Copyright 2016 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 app implements a server that runs a set of active
|
|
// components. This includes replication controllers, service endpoints and
|
|
// nodes.
|
|
//
|
|
package app
|
|
|
|
import (
|
|
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
"k8s.io/client-go/discovery"
|
|
discocache "k8s.io/client-go/discovery/cached" // Saturday Night Fever
|
|
"k8s.io/client-go/dynamic"
|
|
"k8s.io/client-go/scale"
|
|
"k8s.io/kubernetes/pkg/controller/podautoscaler"
|
|
"k8s.io/kubernetes/pkg/controller/podautoscaler/metrics"
|
|
resourceclient "k8s.io/metrics/pkg/client/clientset_generated/clientset/typed/metrics/v1beta1"
|
|
"k8s.io/metrics/pkg/client/custom_metrics"
|
|
)
|
|
|
|
func startHPAController(ctx ControllerContext) (bool, error) {
|
|
if !ctx.AvailableResources[schema.GroupVersionResource{Group: "autoscaling", Version: "v1", Resource: "horizontalpodautoscalers"}] {
|
|
return false, nil
|
|
}
|
|
|
|
if ctx.Options.HorizontalPodAutoscalerUseRESTClients {
|
|
// use the new-style clients if support for custom metrics is enabled
|
|
return startHPAControllerWithRESTClient(ctx)
|
|
}
|
|
|
|
return startHPAControllerWithLegacyClient(ctx)
|
|
}
|
|
|
|
func startHPAControllerWithRESTClient(ctx ControllerContext) (bool, error) {
|
|
clientConfig := ctx.ClientBuilder.ConfigOrDie("horizontal-pod-autoscaler")
|
|
metricsClient := metrics.NewRESTMetricsClient(
|
|
resourceclient.NewForConfigOrDie(clientConfig),
|
|
custom_metrics.NewForConfigOrDie(clientConfig),
|
|
)
|
|
return startHPAControllerWithMetricsClient(ctx, metricsClient)
|
|
}
|
|
|
|
func startHPAControllerWithLegacyClient(ctx ControllerContext) (bool, error) {
|
|
hpaClient := ctx.ClientBuilder.ClientOrDie("horizontal-pod-autoscaler")
|
|
metricsClient := metrics.NewHeapsterMetricsClient(
|
|
hpaClient,
|
|
metrics.DefaultHeapsterNamespace,
|
|
metrics.DefaultHeapsterScheme,
|
|
metrics.DefaultHeapsterService,
|
|
metrics.DefaultHeapsterPort,
|
|
)
|
|
return startHPAControllerWithMetricsClient(ctx, metricsClient)
|
|
}
|
|
|
|
func startHPAControllerWithMetricsClient(ctx ControllerContext, metricsClient metrics.MetricsClient) (bool, error) {
|
|
hpaClientGoClient := ctx.ClientBuilder.ClientGoClientOrDie("horizontal-pod-autoscaler")
|
|
hpaClient := ctx.ClientBuilder.ClientOrDie("horizontal-pod-autoscaler")
|
|
hpaClientConfig := ctx.ClientBuilder.ConfigOrDie("horizontal-pod-autoscaler")
|
|
|
|
// TODO: we need something like deferred discovery REST mapper that calls invalidate
|
|
// on cache misses.
|
|
cachedDiscovery := discocache.NewMemCacheClient(hpaClientGoClient.Discovery())
|
|
restMapper := discovery.NewDeferredDiscoveryRESTMapper(cachedDiscovery, apimeta.InterfacesForUnstructured)
|
|
restMapper.Reset()
|
|
// we don't use cached discovery because DiscoveryScaleKindResolver does its own caching,
|
|
// so we want to re-fetch every time when we actually ask for it
|
|
scaleKindResolver := scale.NewDiscoveryScaleKindResolver(hpaClientGoClient.Discovery())
|
|
scaleClient, err := scale.NewForConfig(hpaClientConfig, restMapper, dynamic.LegacyAPIPathResolverFunc, scaleKindResolver)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
replicaCalc := podautoscaler.NewReplicaCalculator(
|
|
metricsClient,
|
|
hpaClient.Core(),
|
|
ctx.Options.HorizontalPodAutoscalerTolerance,
|
|
)
|
|
go podautoscaler.NewHorizontalController(
|
|
hpaClientGoClient.Core(),
|
|
scaleClient,
|
|
hpaClient.Autoscaling(),
|
|
restMapper,
|
|
replicaCalc,
|
|
ctx.InformerFactory.Autoscaling().V1().HorizontalPodAutoscalers(),
|
|
ctx.Options.HorizontalPodAutoscalerSyncPeriod.Duration,
|
|
ctx.Options.HorizontalPodAutoscalerUpscaleForbiddenWindow.Duration,
|
|
ctx.Options.HorizontalPodAutoscalerDownscaleForbiddenWindow.Duration,
|
|
).Run(ctx.Stop)
|
|
return true, nil
|
|
}
|