From 243047213d6615ce27a8c1e556a7fbe09529e6c8 Mon Sep 17 00:00:00 2001 From: Soohyun Kim Date: Tue, 27 Sep 2022 17:50:40 +0200 Subject: [PATCH 1/2] METAL-3712 add ability to configure resource for the backup cronjob --- Dockerfile | 4 ++- Makefile | 8 +++-- README.md | 2 +- controllers/backup/cronjob.go | 38 ++++++++++++++++++++++ controllers/backup/cronjob_test.go | 14 ++++++++ controllers/backup/test/backup_config.yaml | 9 ++++- go.mod | 5 +-- go.sum | 7 ++++ pkg/config/config_test.go | 9 +++++ pkg/config/test/config_backup.yaml | 8 +++++ pkg/config/types.go | 11 +++++++ 11 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 pkg/config/test/config_backup.yaml diff --git a/Dockerfile b/Dockerfile index fee01448..fafd3d9f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,9 @@ RUN go mod download # build COPY . . -RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -tags build -o /usr/local/bin/db-operator main.go + +ARG GOARCH +RUN GOOS=linux GOARCH=$GOARCH CGO_ENABLED=0 go build -tags build -o /usr/local/bin/db-operator main.go FROM alpine:3.15 LABEL maintainer="dev@kloeckner-i.com" diff --git a/Makefile b/Makefile index 5e4bc82a..ed1b3bf8 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,11 @@ help: ## show this help @grep -E '^(.+)\:\ .*##\ (.+)' ${MAKEFILE_LIST} | sort | sed 's/:.*##/#/' | column -t -c 2 -s '#' build: $(SRC) ## build db-operator docker image - @docker build -t my-db-operator:v1.0.0-dev . + @docker build --build-arg GOARCH=amd64 -t my-db-operator:v1.0.0-dev . + @docker save my-db-operator > my-image.tar + +build_arm: $(SRC) ## build db-operator docker image for arm + @docker build --platform=linux/arm64 --build-arg GOARCH=arm64 -t my-db-operator:v1.0.0-dev . @docker save my-db-operator > my-image.tar addexamples: ## add examples via kubectl create -f examples/ @@ -46,7 +50,7 @@ k3s_mac_deploy: build k3s_mac_image ## build image and import image to local lim k3s_mac_image: ## import built image to local lima k8s limactl copy my-image.tar k3s:/tmp/db.tar - limactl shell k3s sudo k3s ctr images import /tmp/db.tar + limactl shell k3s sudo k3s ctr images import --all-platforms /tmp/db.tar limactl shell k3s rm -f /tmp/db.tar k3d_setup: k3d_install k3d_image ## install k3d and import image to your k3d cluster diff --git a/README.md b/README.md index f716aa40..0c652076 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ $ make k3s_mac_image ### Deploy ``` -helm upgrade my-release kloeckneri/db-operator --set image.repository=my-db-operator --set image.tag=v1.0.0-dev +helm upgrade my-release kloeckneri/db-operator --set image.repository=my-db-operator --set image.tag=1.0.0-dev --set image.pullPolicy=IfNotPresent ``` ### Run unit test locally diff --git a/controllers/backup/cronjob.go b/controllers/backup/cronjob.go index 8c40e7dc..aa694848 100644 --- a/controllers/backup/cronjob.go +++ b/controllers/backup/cronjob.go @@ -27,6 +27,7 @@ import ( batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -114,6 +115,41 @@ func buildJobTemplate(conf *config.Config, dbcr *kciv1alpha1.Database) (batchv1b }, nil } +func getResourceRequirements(conf *config.Config) v1.ResourceRequirements { + resourceRequirements := v1.ResourceRequirements{} + + requests := make(v1.ResourceList) + cpuRequests, err := resource.ParseQuantity(conf.Backup.Resource.Requests.Cpu) + if err == nil { + requests["cpu"] = cpuRequests + } + memRequests, err := resource.ParseQuantity(conf.Backup.Resource.Requests.Memory) + if err == nil { + requests["memory"] = memRequests + } + if len(requests) != 0 { + resourceRequirements.Requests = requests + } + + limits := make(v1.ResourceList) + cpuLimits, err := resource.ParseQuantity(conf.Backup.Resource.Limits.Cpu) + if err == nil { + limits["cpu"] = cpuLimits + } + memLimits, err := resource.ParseQuantity(conf.Backup.Resource.Limits.Memory) + if err == nil { + limits["memory"] = memLimits + } + + if len(limits) != 0 { + resourceRequirements.Limits = limits + } + // debug + logrus.Infof("resourceRequirements debug: %+v\n", resourceRequirements) + + return resourceRequirements +} + func postgresBackupContainer(conf *config.Config, dbcr *kciv1alpha1.Database) (v1.Container, error) { env, err := postgresEnvVars(conf, dbcr) if err != nil { @@ -126,6 +162,7 @@ func postgresBackupContainer(conf *config.Config, dbcr *kciv1alpha1.Database) (v ImagePullPolicy: v1.PullAlways, VolumeMounts: volumeMounts(), Env: env, + Resources: getResourceRequirements(conf), }, nil } @@ -141,6 +178,7 @@ func mysqlBackupContainer(conf *config.Config, dbcr *kciv1alpha1.Database) (v1.C ImagePullPolicy: v1.PullAlways, VolumeMounts: volumeMounts(), Env: env, + Resources: getResourceRequirements(conf), }, nil } diff --git a/controllers/backup/cronjob_test.go b/controllers/backup/cronjob_test.go index 8896da85..5416d78a 100644 --- a/controllers/backup/cronjob_test.go +++ b/controllers/backup/cronjob_test.go @@ -24,6 +24,8 @@ import ( kciv1alpha1 "github.com/kloeckner-i/db-operator/api/v1alpha1" "github.com/kloeckner-i/db-operator/pkg/config" "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" ) func TestGCSBackupCronGsql(t *testing.T) { @@ -95,3 +97,15 @@ func TestGCSBackupCronGeneric(t *testing.T) { assert.Equal(t, "TestNS-TestDB-backup", funcCronObject.Name) assert.Equal(t, "* * * * *", funcCronObject.Spec.Schedule) } + +func TestGetResourceRequirements(t *testing.T) { + os.Setenv("CONFIG_PATH", "./test/backup_config.yaml") + conf := config.LoadConfig() + + expected := v1.ResourceRequirements{ + Requests: map[v1.ResourceName]resource.Quantity{v1.ResourceCPU: resource.MustParse("50m"), v1.ResourceMemory: resource.MustParse("50Mi")}, + Limits: map[v1.ResourceName]resource.Quantity{v1.ResourceCPU: resource.MustParse("100m"), v1.ResourceMemory: resource.MustParse("100Mi")}, + } + result := getResourceRequirements(&conf) + assert.Equal(t, expected, result) +} diff --git a/controllers/backup/test/backup_config.yaml b/controllers/backup/test/backup_config.yaml index ca9e6def..d6190130 100644 --- a/controllers/backup/test/backup_config.yaml +++ b/controllers/backup/test/backup_config.yaml @@ -3,4 +3,11 @@ backup: postgres: image: postgresbackupimage:latest mysql: - image: mysqlbackupimage:latest \ No newline at end of file + image: mysqlbackupimage:latest + resources: + requests: + cpu: 50m + memory: 50Mi + limits: + cpu: 100m + memory: 100Mi \ No newline at end of file diff --git a/go.mod b/go.mod index 012dd7fe..06f2dbf4 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.52.1 github.com/prometheus/client_golang v1.11.0 github.com/sirupsen/logrus v1.8.1 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.8.0 golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 google.golang.org/api v0.77.0 gopkg.in/yaml.v2 v2.4.0 @@ -68,6 +68,7 @@ require ( github.com/prometheus/common v0.28.0 // indirect github.com/prometheus/procfs v0.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/objx v0.4.0 // indirect go.opencensus.io v0.23.0 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect @@ -84,7 +85,7 @@ require ( google.golang.org/grpc v1.45.0 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/component-base v0.23.5 // indirect k8s.io/klog/v2 v2.60.1 // indirect k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect diff --git a/go.sum b/go.sum index 541c54d2..0aeda2d5 100644 --- a/go.sum +++ b/go.sum @@ -579,6 +579,8 @@ github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -586,6 +588,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -1181,6 +1186,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index c6c3605d..327c70c9 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -48,3 +48,12 @@ func TestLoadConfigFailCases(t *testing.T) { LoadConfig() assert.Equal(t, expectedFatal, fatalCalled) } + +func TestBackupResourceConfig(t *testing.T) { + os.Setenv("CONFIG_PATH", "./test/config_backup.yaml") + conf := LoadConfig() + assert.Equal(t, conf.Backup.Resource.Requests.Cpu, "50m") + assert.Equal(t, conf.Backup.Resource.Requests.Memory, "50Mi") + assert.Equal(t, conf.Backup.Resource.Limits.Cpu, "100m") + assert.Equal(t, conf.Backup.Resource.Limits.Memory, "100Mi") +} diff --git a/pkg/config/test/config_backup.yaml b/pkg/config/test/config_backup.yaml new file mode 100644 index 00000000..2da7ca29 --- /dev/null +++ b/pkg/config/test/config_backup.yaml @@ -0,0 +1,8 @@ +backup: + resources: + requests: + cpu: 50m + memory: 50Mi + limits: + cpu: 100m + memory: 100Mi \ No newline at end of file diff --git a/pkg/config/types.go b/pkg/config/types.go index 0d442a85..27ddce22 100644 --- a/pkg/config/types.go +++ b/pkg/config/types.go @@ -54,6 +54,7 @@ type backupConfig struct { Mysql mysqlBackupConfig `yaml:"mysql"` NodeSelector map[string]string `yaml:"nodeSelector"` ActiveDeadlineSeconds int64 `yaml:"activeDeadlineSeconds"` + Resource ResourceRequirements `yaml:"resources"` } type postgresBackupConfig struct { @@ -64,6 +65,16 @@ type mysqlBackupConfig struct { Image string `yaml:"image"` } +type ResourceRequirements struct { + Limits ResourceList `yaml:"limits,omitempty"` + Requests ResourceList `yaml:"requests,omitempty"` +} + +type ResourceList struct { + Cpu string `yaml:"cpu,omitempty"` + Memory string `yaml:"memory,omitempty"` +} + // monitoringConfig defines prometheus exporter configurations // which will be created by db-operator when monitoring is enabled type monitoringConfig struct { From 0a8c7986e046f7aa6e41fd2fe92d544beebc5264 Mon Sep 17 00:00:00 2001 From: Soohyun Kim Date: Wed, 28 Sep 2022 10:23:49 +0200 Subject: [PATCH 2/2] METAL-3712 remove debug log --- controllers/backup/cronjob.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/controllers/backup/cronjob.go b/controllers/backup/cronjob.go index aa694848..eb3aa5e1 100644 --- a/controllers/backup/cronjob.go +++ b/controllers/backup/cronjob.go @@ -140,12 +140,9 @@ func getResourceRequirements(conf *config.Config) v1.ResourceRequirements { if err == nil { limits["memory"] = memLimits } - if len(limits) != 0 { resourceRequirements.Limits = limits } - // debug - logrus.Infof("resourceRequirements debug: %+v\n", resourceRequirements) return resourceRequirements }