Skip to content

Commit

Permalink
feat: support autoscaling based on instance's RPS metrics (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
nettoclaudio authored May 31, 2023
1 parent f41e9db commit 9684f2b
Show file tree
Hide file tree
Showing 29 changed files with 1,171 additions and 532 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
- uses: actions/setup-go@v3
with:
go-version: 1.18
go-version: "1.20"
- run: make test

lint:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v3
with:
go-version: 1.18
go-version: "1.20"
- uses: actions/checkout@v2
- uses: golangci/golangci-lint-action@v3
with:
Expand All @@ -40,9 +40,9 @@ jobs:
- uses: azure/setup-helm@v1
with:
version: v3.7.0
- uses: actions/setup-go@v2
- uses: actions/setup-go@v3
with:
go-version: 1.18
go-version: "1.20"
- uses: actions/cache@v2
with:
path: |
Expand Down Expand Up @@ -195,9 +195,9 @@ jobs:
}
}
EOF
- uses: actions/setup-go@v2
- uses: actions/setup-go@v3
with:
go-version: 1.18
go-version: "1.20"
- uses: goreleaser/goreleaser-action@v1
with:
version: latest
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile.api
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
FROM golang:1.18-alpine3.15 AS builder
FROM golang:1.20-alpine3.18 AS builder
COPY . /go/src/github.com/tsuru/rpaas-operator
WORKDIR /go/src/github.com/tsuru/rpaas-operator
RUN apk add --update gcc git make musl-dev && \
make build/api

FROM alpine:3.15
FROM alpine:3.18
COPY --from=builder /go/src/github.com/tsuru/rpaas-operator/bin/api /bin/rpaas-api
RUN apk update && \
apk add --no-cache ca-certificates && \
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile.operator
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
FROM golang:1.18-alpine3.15 AS builder
FROM golang:1.20-alpine3.18 AS builder
COPY . /go/src/github.com/tsuru/rpaas-operator
WORKDIR /go/src/github.com/tsuru/rpaas-operator
RUN apk add --update gcc git make musl-dev && \
make build/manager

FROM alpine:3.15
FROM alpine:3.18
COPY --from=builder /go/src/github.com/tsuru/rpaas-operator/bin/manager /bin/rpaas-operator
RUN apk update && \
apk add --no-cache ca-certificates && \
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile.purger
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
FROM golang:1.18-alpine3.15 AS builder
FROM golang:1.20-alpine3.18 AS builder
COPY . /go/src/github.com/tsuru/rpaas-operator
WORKDIR /go/src/github.com/tsuru/rpaas-operator
RUN apk add --update gcc git make musl-dev && \
make build/purger

FROM alpine:3.15
FROM alpine:3.18
COPY --from=builder /go/src/github.com/tsuru/rpaas-operator/bin/purger /bin/rpaas-purger
RUN apk update && \
apk add --no-cache ca-certificates && \
Expand Down
4 changes: 4 additions & 0 deletions api/v1alpha1/rpaasinstance_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ type RpaasInstanceAutoscaleSpec struct {
// int32(80) equals to 80%.
// +optional
TargetMemoryUtilizationPercentage *int32 `json:"targetMemoryUtilizationPercentage,omitempty"`
// TargetRequestsPerSecond is the target rate of HTTP requests (in a second)
// pods should keep before scaling up/down pods.
// +optional
TargetRequestsPerSecond *int32 `json:"targetRequestsPerSecond,omitempty"`
}

type TLSSessionResumption struct {
Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 37 additions & 24 deletions cmd/plugin/rpaasv2/cmd/autoscale.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"encoding/json"
"fmt"
"io"
"strconv"

"github.com/olekukonko/tablewriter"
rpaasclient "github.com/tsuru/rpaas-operator/pkg/rpaas/client"
Expand Down Expand Up @@ -56,19 +55,24 @@ func NewCmdUpdateAutoscale() *cli.Command {
Required: true,
},
&cli.IntFlag{
Name: "cpu",
Aliases: []string{"cpu-utilization"},
Usage: "the target average CPU utilization on all replicas (in percentage format, e.g. 80 equals to 80%)",
Required: false,
Name: "cpu",
Aliases: []string{"cpu-utilization"},
Usage: "the target average CPU utilization on all replicas (in percentage format, e.g. 80 equals to 80%)",
DefaultText: "N/A",
},
&cli.IntFlag{
Name: "memory",
Aliases: []string{"memory-utilization"},
Usage: "the target average memory utilization on all the replicas (in percentage format, e.g. 80 equals to 80%)",
Required: false,
Name: "memory",
Aliases: []string{"memory-utilization"},
Usage: "the target average memory utilization on all the replicas (in percentage format, e.g. 80 equals to 80%)",
DefaultText: "N/A",
},
&cli.IntFlag{
Name: "rps",
Aliases: []string{"requests-per-second"},
Usage: "the target average of HTTP requests per seconds between replicas (e.g. 100, means 100 req/s)",
DefaultText: "N/A",
},
},

Before: setupClient,
Action: runUpdateAutoscale,
}
Expand Down Expand Up @@ -99,6 +103,10 @@ func runUpdateAutoscale(c *cli.Context) error {
updateArgs.Memory = pointerToInt32(int32(c.Int("memory")))
}

if c.IsSet("rps") {
updateArgs.RPS = pointerToInt32(int32(c.Int("rps")))
}

err = client.UpdateAutoscale(c.Context, updateArgs)
if err != nil {
return err
Expand Down Expand Up @@ -221,36 +229,41 @@ func writeAutoscale(w io.Writer, autoscale *clientTypes.Autoscale) {
return
}
table := tablewriter.NewWriter(w)
table.SetHeader([]string{"Replicas", "Target Utilization"})
table.SetHeader([]string{"Replicas", "Target"})
table.SetAutoFormatHeaders(false)
table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
table.SetAutoWrapText(true)
table.SetRowLine(false)
var max, min, cpuPercentage, memPercentage string

max := "Max: N/A"
if autoscale.MaxReplicas != nil {
max = fmt.Sprintf("Max: %s", strconv.Itoa(int(*autoscale.MaxReplicas)))
} else {
max = "Max: N/A"
max = fmt.Sprintf("Max: %d", *autoscale.MaxReplicas)
}

min := "Min: N/A"
if autoscale.MinReplicas != nil {
min = fmt.Sprintf("Min: %s", strconv.Itoa(int(*autoscale.MinReplicas)))
} else {
min = "Min: N/A"
min = fmt.Sprintf("Min: %d", *autoscale.MinReplicas)
}

cpuPercentage := "CPU: N/A"
if autoscale.CPU != nil {
cpuPercentage = fmt.Sprintf("CPU: %s%%", strconv.Itoa(int(*autoscale.CPU)))
} else {
cpuPercentage = "CPU: N/A"
cpuPercentage = fmt.Sprintf("CPU: %d%%", *autoscale.CPU)
}

memPercentage := "Memory: N/A"
if autoscale.Memory != nil {
memPercentage = fmt.Sprintf("Memory: %s%%", strconv.Itoa(int(*autoscale.Memory)))
} else {
memPercentage = "Memory: N/A"
memPercentage = fmt.Sprintf("Memory: %d%%", *autoscale.Memory)
}

rps := "RPS: N/A"
if autoscale.RPS != nil {
rps = fmt.Sprintf("RPS: %d req/s", *autoscale.RPS)
}

data := [][]string{
{max, cpuPercentage},
{min, memPercentage},
{"", rps},
}
table.AppendBulk(data)
table.Render()
Expand Down
17 changes: 10 additions & 7 deletions cmd/plugin/rpaasv2/cmd/autoscale_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,17 @@ func TestGetAutoscale(t *testing.T) {
MinReplicas: int32Ptr(2),
CPU: int32Ptr(50),
Memory: int32Ptr(55),
RPS: int32Ptr(100),
}, nil
},
},
expected: `+----------+--------------------+
| Replicas | Target Utilization |
+----------+--------------------+
| Max: 5 | CPU: 50% |
| Min: 2 | Memory: 55% |
+----------+--------------------+
expected: `+----------+----------------+
| Replicas | Target |
+----------+----------------+
| Max: 5 | CPU: 50% |
| Min: 2 | Memory: 55% |
| | RPS: 100 req/s |
+----------+----------------+
`,
},
{
Expand All @@ -68,10 +70,11 @@ func TestGetAutoscale(t *testing.T) {
MinReplicas: int32Ptr(2),
CPU: int32Ptr(50),
Memory: int32Ptr(55),
RPS: int32Ptr(100),
}, nil
},
},
expected: "{\n\t\"minReplicas\": 2,\n\t\"maxReplicas\": 5,\n\t\"cpu\": 50,\n\t\"memory\": 55\n}\n",
expected: "{\n\t\"minReplicas\": 2,\n\t\"maxReplicas\": 5,\n\t\"cpu\": 50,\n\t\"memory\": 55,\n\t\"rps\": 100\n}\n",
},
}
for _, tt := range tests {
Expand Down
14 changes: 8 additions & 6 deletions cmd/plugin/rpaasv2/cmd/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ func TestInfo(t *testing.T) {
MinReplicas: int32Ptr(2),
CPU: int32Ptr(55),
Memory: int32Ptr(77),
RPS: int32Ptr(100),
},
Pods: []clientTypes.Pod{
{
Expand Down Expand Up @@ -391,12 +392,13 @@ Errors:
+--------------------+------------------------------+----------------------------------------------+
Autoscale:
+----------+--------------------+
| Replicas | Target Utilization |
+----------+--------------------+
| Max: 5 | CPU: 55% |
| Min: 2 | Memory: 77% |
+----------+--------------------+
+----------+----------------+
| Replicas | Target |
+----------+----------------+
| Max: 5 | CPU: 55% |
| Min: 2 | Memory: 77% |
| | RPS: 100 req/s |
+----------+----------------+
ACLs:
+----------------------+------+
Expand Down
Loading

0 comments on commit 9684f2b

Please sign in to comment.