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

Cherrypick to support v1.26 #910

Open
wants to merge 18 commits into
base: support-1-26
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:
cover:
runs-on: ubuntu-latest
steps:
- name: Check architecture
run: uname -m
- name: Set up Go
uses: actions/setup-go@v2
with:
Expand Down
3 changes: 0 additions & 3 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ run:
linters:
disable-all: true
enable:
- deadcode
- unused
- varcheck
- ineffassign
- goimports
- gofmt
Expand All @@ -15,7 +13,6 @@ linters:
- unconvert
- govet
- errcheck
- structcheck
- staticcheck

linters-settings:
Expand Down
16 changes: 14 additions & 2 deletions cmd/craned/app/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"k8s.io/client-go/scale"
"k8s.io/component-base/logs"
"k8s.io/klog/v2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
Expand Down Expand Up @@ -52,6 +53,7 @@ import (
"github.com/gocrane/crane/pkg/recommendation"
"github.com/gocrane/crane/pkg/server"
serverconfig "github.com/gocrane/crane/pkg/server/config"
"github.com/gocrane/crane/pkg/utils"
"github.com/gocrane/crane/pkg/utils/target"
"github.com/gocrane/crane/pkg/webhooks"
)
Expand Down Expand Up @@ -83,6 +85,7 @@ func NewManagerCommand(ctx context.Context) *cobra.Command {

cmd.Flags().AddGoFlagSet(flag.CommandLine)
opts.AddFlags(cmd.Flags())
logs.AddFlags(cmd.Flags())
utilfeature.DefaultMutableFeatureGate.AddFlag(cmd.Flags())

return cmd
Expand Down Expand Up @@ -143,7 +146,7 @@ func Run(ctx context.Context, opts *options.Options) error {
}
}()

initControllers(podOOMRecorder, mgr, opts, predictorMgr, historyDataSources[providers.PrometheusDataSource])
initControllers(ctx, podOOMRecorder, mgr, opts, predictorMgr, historyDataSources[providers.PrometheusDataSource])
// initialize custom collector metrics
initMetricCollector(mgr)
runAll(ctx, mgr, predictorMgr, dataSourceProviders[providers.PrometheusDataSource], opts)
Expand Down Expand Up @@ -256,6 +259,8 @@ func initDataSources(mgr ctrl.Manager, opts *options.Options) (map[providers.Dat
hybridDataSources[providers.PrometheusDataSource] = provider
realtimeDataSources[providers.PrometheusDataSource] = provider
historyDataSources[providers.PrometheusDataSource] = provider

utils.SetExtensionLabels(opts.DataSourcePromConfig.ExtensionLabels)
}
}
return realtimeDataSources, historyDataSources, hybridDataSources
Expand All @@ -266,7 +271,7 @@ func initPredictorManager(opts *options.Options, realtimeDataSources map[provide
}

// initControllers setup controllers with manager
func initControllers(oomRecorder oom.Recorder, mgr ctrl.Manager, opts *options.Options, predictorMgr predictor.Manager, historyDataSource providers.History) {
func initControllers(ctx context.Context, oomRecorder oom.Recorder, mgr ctrl.Manager, opts *options.Options, predictorMgr predictor.Manager, historyDataSource providers.History) {
discoveryClientSet, err := discovery.NewDiscoveryClientForConfig(mgr.GetConfig())
if err != nil {
klog.Exit(err, "Unable to create discover client")
Expand Down Expand Up @@ -417,6 +422,13 @@ func initControllers(oomRecorder oom.Recorder, mgr ctrl.Manager, opts *options.O
}).SetupWithManager(mgr); err != nil {
klog.Exit(err, "unable to create controller", "controller", "RecommendationTriggerController")
}

checker := recommendationctrl.Checker{
Client: mgr.GetClient(),
MonitorInterval: opts.MonitorInterval,
OutDateInterval: opts.OutDateInterval,
}
checker.Run(ctx.Done())
}

// CnpController
Expand Down
9 changes: 9 additions & 0 deletions cmd/craned/app/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ type Options struct {

// CacheUnstructured indicates whether to cache Unstructured objects. When enabled, it will speed up reading Unstructured objects, but will increase memory usage.
CacheUnstructured bool

// MonitorInterval is the interval for recommendation checker
MonitorInterval time.Duration

// OutDateInterval is the checking interval for identify a recommendation is outdated
OutDateInterval time.Duration
}

// NewOptions builds an empty options.
Expand Down Expand Up @@ -115,6 +121,7 @@ func (o *Options) AddFlags(flags *pflag.FlagSet) {
flags.StringVar(&o.DataSourcePromConfig.AdapterConfigMapKey, "prometheus-adapter-configmap-key", "", "prometheus adapter-configmap key")
flags.StringVar(&o.DataSourcePromConfig.AdapterConfig, "prometheus-adapter-config", "", "prometheus adapter-config path")
flags.StringVar(&o.DataSourcePromConfig.AdapterExtensionLabels, "prometheus-adapter-extension-labels", "", "prometheus adapter extension-labels for expressionQuery")
flags.StringVar(&o.DataSourcePromConfig.ExtensionLabels, "extension-labels", "", "extension-labels for every prometheus query")
flags.StringVar(&o.DataSourcePromConfig.Auth.Username, "prometheus-auth-username", "", "prometheus auth username")
flags.StringVar(&o.DataSourcePromConfig.Auth.Password, "prometheus-auth-password", "", "prometheus auth password")
flags.StringVar(&o.DataSourcePromConfig.Auth.BearerToken, "prometheus-auth-bearertoken", "", "prometheus auth bearertoken")
Expand All @@ -139,4 +146,6 @@ func (o *Options) AddFlags(flags *pflag.FlagSet) {
flags.IntVar(&o.OOMRecordMaxNumber, "oom-record-max-number", 10000, "Max number for oom records to store in configmap")
flags.IntVar(&o.TimeSeriesPredictionMaxConcurrentReconciles, "time-series-prediction-max-concurrent-reconciles", 10, "Max concurrent reconciles for TimeSeriesPrediction controller")
flags.BoolVar(&o.CacheUnstructured, "cache-unstructured", true, "whether to cache Unstructured objects. When enabled, it will speed up reading Unstructured objects but will increase memory usage")
flags.DurationVar(&o.MonitorInterval, "recommendation-monitor-interval", time.Hour, "interval for recommendation checker")
flags.DurationVar(&o.OutDateInterval, "recommendation-outdate-interval", 24*time.Hour, "interval for identify a recommendation is outdated")
}
129 changes: 122 additions & 7 deletions deploy/craned/rbac.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,128 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: craned
namespace: crane-system
rules:
- apiGroups:
- ""
resources:
- configmaps
- secrets
verbs:
- create
- apiGroups:
- ""
resourceNames:
- craned
resources:
- configmaps
verbs:
- get
- patch
- update
- apiGroups:
- ""
resourceNames:
- clusters-secret-store
resources:
- secrets
verbs:
- get
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- patch
- update
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: craned
rules:
- apiGroups: [ '*' ]
resources: [ '*' ]
verbs: [ "*" ]
- apiGroups:
- ""
resources:
- configmaps
- pods
- nodes
verbs:
- get
- list
- watch
- apiGroups:
- analysis.crane.io
resources:
- "*"
verbs:
- "*"
- apiGroups:
- apps
resources:
- daemonsets
- deployments
- deployments/scale
- statefulsets
- statefulsets/scale
verbs:
- get
- list
- watch
- apiGroups:
- apps
resources:
- daemonsets/status
- deployments/status
- deployments/scale
- statefulsets/status
- statefulsets/scale
verbs:
- update
- apiGroups:
- autoscaling
resources:
- horizontalpodautoscalers
verbs:
- '*'
- apiGroups:
- autoscaling.crane.io
resources:
- '*'
verbs:
- '*'
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- update
- apiGroups:
- prediction.crane.io
resources:
- '*'
verbs:
- '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: craned
namespace: crane-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: craned
subjects:
- kind: ServiceAccount
name: craned
namespace: crane-system
---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
Expand All @@ -17,6 +132,6 @@ roleRef:
kind: ClusterRole
name: craned
subjects:
- kind: ServiceAccount
name: craned
namespace: crane-system
- kind: ServiceAccount
name: craned
namespace: crane-system
35 changes: 26 additions & 9 deletions pkg/controller/ehpa/hpa.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,30 @@ func (c *EffectiveHPAController) GetHPAMetrics(ctx context.Context, ehpa *autosc
var metricIdentifier string
var averageValue *resource.Quantity
switch metric.Type {
case autoscalingv2.ResourceMetricSourceType:
metricIdentifier = utils.GetMetricIdentifier(metric, metric.Resource.Name.String())
case autoscalingv2.ResourceMetricSourceType, autoscalingv2.ContainerResourceMetricSourceType:
var averageUtilization *int32
var containerName string
if metric.Resource != nil {
if metric.Resource.Target.AverageUtilization != nil {
averageUtilization = metric.Resource.Target.AverageUtilization
}
if metric.Resource.Target.AverageValue != nil {
averageValue = metric.Resource.Target.AverageValue
}
}
if metric.ContainerResource != nil {
containerName = metric.ContainerResource.Container
if metric.ContainerResource.Target.AverageUtilization != nil {
averageUtilization = metric.ContainerResource.Target.AverageUtilization
}
if metric.ContainerResource.Target.AverageValue != nil {
averageValue = metric.ContainerResource.Target.AverageValue
}
}

// When use AverageUtilization in EffectiveHorizontalPodAutoscaler's metricSpec, convert to AverageValue
if metric.Resource.Target.AverageUtilization != nil {
if averageUtilization != nil {
metricName := utils.GetMetricName(metric)
scale, _, err := utils.GetScale(ctx, c.RestMapper, c.ScaleClient, ehpa.Namespace, ehpa.Spec.ScaleTargetRef)
if err != nil {
return nil, err
Expand All @@ -231,24 +251,21 @@ func (c *EffectiveHPAController) GetHPAMetrics(ctx context.Context, ehpa *autosc
return nil, fmt.Errorf("failed to get available pods. ")
}

requests, err := utils.CalculatePodRequests(availablePods, metric.Resource.Name)
requests, err := utils.CalculatePodRequests(availablePods, v1.ResourceName(metricName), containerName)
if err != nil {
return nil, err
}

value := int64((float64(requests) * float64(*metric.Resource.Target.AverageUtilization) / 100) / float64(len(availablePods)))
value := int64((float64(requests) * float64(*averageUtilization) / 100) / float64(len(availablePods)))
averageValue = resource.NewMilliQuantity(value, resource.DecimalSI)
} else {
averageValue = metric.Resource.Target.AverageValue
}
case autoscalingv2.ExternalMetricSourceType:
metricIdentifier = utils.GetMetricIdentifier(metric, metric.External.Metric.Name)
averageValue = metric.External.Target.AverageValue
case autoscalingv2.PodsMetricSourceType:
metricIdentifier = utils.GetMetricIdentifier(metric, metric.Pods.Metric.Name)
averageValue = metric.Pods.Target.AverageValue
}

metricIdentifier = utils.GetPredictionMetricIdentifier(metric)
if metricIdentifier == "" {
continue
}
Expand Down
Loading
Loading