Skip to content

Commit

Permalink
Merge pull request #90 from elisasre/fix/portname
Browse files Browse the repository at this point in the history
Autodetect Prometheus port name
  • Loading branch information
zetaab authored May 26, 2023
2 parents d36ed51 + c867c1e commit 5fdea86
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 33 deletions.
42 changes: 19 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

### Installation

```
export PLUGIN_VERSION=1.0.5
```bash
export PLUGIN_VERSION=1.1.0

# MacOS (x86_64)
curl -sLo /usr/local/bin/kubectl-advisory https://github.com/elisasre/kubernetes-resource-advisor/releases/download/${PLUGIN_VERSION}/resource-advisor-darwin-amd64
Expand All @@ -26,48 +26,46 @@ The [prometheus-operator](https://github.com/prometheus-operator/prometheus-oper

### Usage

```
kubectl advisory --help
I0916 13:28:02.492261 96935 start.go:23] Starting application...
```bash
% kubectl advisory --help
Kubernetes resource-advisor

Usage:
resource-advisor [flags]

Flags:
-h, --help help for resource-advisor
--limit-margin string Limit margin (default "1.2")
--namespace-selector string Namespace selector
--namespaces string Comma separated namespaces to be scanned
--quantile string Quantile to be used (default "0.95")
-m, --limit-margin string Limit margin (default "1.2")
-l, --namespace-selector string Namespace selector
-n, --namespaces string Comma separated namespaces to be scanned
-q, --quantile string Quantile to be used (default "0.95")
```

```
```bash
% kubectl advisory
I0916 13:26:56.442083 96863 start.go:23] Starting application...
Namespaces: logging
Quantile: 0.95
Limit margin: 1.2
Using mode: sum_irate
+-----------+----------------------+------------+--------------------+--------------------+------------------+------------------+
| NAMESPACE | RESOURCE | CONTAINER | REQUEST CPU (SPEC) | REQUEST MEM (SPEC) | LIMIT CPU (SPEC) | LIMIT MEM (SPEC) |
+-----------+----------------------+------------+--------------------+--------------------+------------------+------------------+
| logging | daemonset/fluent-bit | fluent-bit | 10m (25m) | 100Mi (100Mi) | 100m (400m) | 100Mi (200Mi) |
| logging | daemonset/fluent-bit | fluent-bit | 10m (25m) | 100Mi (100Mi) | 100m (400m) | 200Mi (200Mi) |
+-----------+----------------------+------------+--------------------+--------------------+------------------+------------------+
Total savings:
You could save 0.32 vCPUs and 102.0 MB Memory by changing the settings
You could save 0.27 vCPUs and 87.4 MB Memory by changing the settings
```

What these numbers mean? The idea of this tool is to find out `quantile` (default is 95%) CPU & memory real usage for single POD using Prometheus operator. We use that real usage value for specifying `requests`. Then there is another variable called `limit-margin` which is used for specifying `limits`. The default settings means that 95% of time the POD has quarantee for the resources, and 5% of time it uses burstable capacity between 95% -> 120% of POD maximum usage in history.


#### Using namespace-selector

```
```bash
% kubectl advisory --namespace-selector maintainer=a_crowd_devops
I0916 14:37:52.758305 5980 start.go:23] Starting application...
Namespaces: actions-runner-system,cert-manager,default,gha,kaas-test-infra
Quantile: 0.95
Limit margin: 1.2
Using mode: sum_irate
+-----------------------+-------------------------------------------------+-----------------+--------------------+--------------------+------------------+------------------+
| NAMESPACE | RESOURCE | CONTAINER | REQUEST CPU (SPEC) | REQUEST MEM (SPEC) | LIMIT CPU (SPEC) | LIMIT MEM (SPEC) |
+-----------------------+-------------------------------------------------+-----------------+--------------------+--------------------+------------------+------------------+
Expand All @@ -85,14 +83,12 @@ You could save 0.12 vCPUs and -380.6 MB Memory by changing the settings

#### Using as library

```
import "github.com/elisasre/kubernetes-resource-advisor/pkg/advisor"
...
```go
import "github.com/elisasre/kubernetes-resource-advisor/pkg/advisor"

response, err := advisor.Run(&advisor.Options{
Namespaces: "logging,monitoring",
})
response, err := advisor.Run(&advisor.Options{
Namespaces: "logging,monitoring",
})
```

### Motivation
Expand Down
7 changes: 4 additions & 3 deletions pkg/advisor/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,12 @@ func Run(o *Options) (*Response, error) {
if err != nil {
return nil, err
}
if len(prom_service.Items) == 0 {
return nil, fmt.Errorf("Prometheus-operator not detected!")
if len(prom_service.Items) == 0 || len(prom_service.Items[0].Spec.Ports) == 0 {
return nil, fmt.Errorf("prometheus-operator not detected!")

}

o.promClient, err = makePrometheusClientForCluster(prom_service.Items[0].Namespace)
o.promClient, err = makePrometheusClientForCluster(prom_service.Items[0].Namespace, prom_service.Items[0].Spec.Ports[0].Name)
if err != nil {
return nil, err
}
Expand Down
14 changes: 7 additions & 7 deletions pkg/advisor/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
)

const (
promOperatorClusterURL = "%s/api/v1/namespaces/%s/services/prometheus-operated:web/proxy/"
promOperatorClusterURL = "%s/api/v1/namespaces/%s/services/prometheus-operated:%s/proxy/"
podCPURequest = `quantile_over_time(%s, node_namespace_pod_container:container_cpu_usage_seconds_total:%s{pod="%s", container!=""}[1w])`
podCPULimit = `max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:%s{pod="%s", container!=""}[1w]) * %s`
podMemoryRequest = `quantile_over_time(%s, container_memory_working_set_bytes{pod="%s", container!=""}[1w]) / 1024 / 1024`
Expand Down Expand Up @@ -58,7 +58,7 @@ func queryStatistic(ctx context.Context, client *promClient, request string, now
output := make(map[string]float64)
response, _, err := queryPrometheus(ctx, client, request, now)
if err != nil {
return output, fmt.Errorf("Error querying statistic %v", err)
return output, fmt.Errorf("error querying statistic %v", err)
}
asSamples := response.(prommodel.Vector)

Expand Down Expand Up @@ -136,13 +136,13 @@ func findReplicaset(replicasets *appsv1.ReplicaSetList, dep appsv1.Deployment) (
return nil, fmt.Errorf("could not find replicaset for deployment '%s' gen '%v'", dep.Name, generation)
}

func makePrometheusClientForCluster(namespace string) (*promClient, error) {
func makePrometheusClientForCluster(namespace string, portname string) (*promClient, error) {
config, _, err := findConfig()
if err != nil {
return nil, err
}

promurl := fmt.Sprintf(promOperatorClusterURL, config.Host, namespace)
promurl := fmt.Sprintf(promOperatorClusterURL, config.Host, namespace, portname)
transport, err := rest.TransportFor(config)
if err != nil {
return nil, err
Expand Down Expand Up @@ -181,7 +181,7 @@ func (o *Options) detectMode(ctx context.Context) (string, error) {
request := fmt.Sprintf(cpuUsage, "sum_irate")
response, _, err := queryPrometheus(ctx, o.promClient, request, now)
if err != nil {
return "", fmt.Errorf("Error detecting mode %v", err)
return "", fmt.Errorf("error detecting mode %v", err)
}
asSamples := response.(prommodel.Vector)
if len(asSamples) > 0 {
Expand All @@ -191,13 +191,13 @@ func (o *Options) detectMode(ctx context.Context) (string, error) {
request = fmt.Sprintf(cpuUsage, "sum_rate")
response, _, err = queryPrometheus(ctx, o.promClient, request, now)
if err != nil {
return "", fmt.Errorf("Error detecting mode %v", err)
return "", fmt.Errorf("error detecting mode %v", err)
}
asSamples = response.(prommodel.Vector)
if len(asSamples) > 0 {
return "sum_rate", nil
}
return "", fmt.Errorf("Could not find cpu mode")
return "", fmt.Errorf("could not find cpu mode")
}

func (c *promClient) URL(ep string, args map[string]string) *url.URL {
Expand Down

0 comments on commit 5fdea86

Please sign in to comment.