From 53091002f2cbc01b5c37b4ec9e3e34524d22be4a Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Mon, 29 Jul 2019 14:26:23 +0100 Subject: [PATCH 01/18] Adding test dockerfile --- build/executor/Dockerfile | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 build/executor/Dockerfile diff --git a/build/executor/Dockerfile b/build/executor/Dockerfile new file mode 100644 index 00000000000..2a21a4519ab --- /dev/null +++ b/build/executor/Dockerfile @@ -0,0 +1,13 @@ +FROM golang:1.12.6 + +RUN mkdir /app + +ADD . /app + +WORKDIR /app + +RUN ls + +RUN go build -o main cmd/executor/main.go + +CMD ["/app/main"] \ No newline at end of file From ad4faf8887ad33d67d6efd79e3840095071622e6 Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Mon, 29 Jul 2019 14:27:44 +0100 Subject: [PATCH 02/18] Building dockerfile in circleci --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5f103235652..169163f74b3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -23,3 +23,4 @@ jobs: - run: go get -v -d ./... - run: go test -v ./... - run: exit $(gofmt -l . | wc -l) + - run: docker build -t executor-test -f ./build/executor/Dockerfile . From 8991952eb8e9fbe9c99787d0745caf68b8c0bcff Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Mon, 29 Jul 2019 14:32:43 +0100 Subject: [PATCH 03/18] Setting docker to ON in cirlcleci --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 169163f74b3..f59043bf0e9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,6 +18,7 @@ jobs: working_directory: /go/src/github.com/{{ORG_NAME}}/{{REPO_NAME}} steps: - checkout + - setup_remote_docker # specify any bash command here prefixed with `run: ` - run: go get -v -d ./... From 8e1aef9d86fd340526ac876461f667ee2b25c11e Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Tue, 30 Jul 2019 10:00:35 +0100 Subject: [PATCH 04/18] Add Dockerfile for Armada and Dockerfiles to use multistage build The applications are now built statically linked and then placed into an alpine image This reduces the size of the final image - With plain golang image, the final images are ~1.2Gb - With alpine images are ~50Mb --- build/armada/Dockerfile | 19 +++++++++++++++++++ build/executor/Dockerfile | 14 ++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 build/armada/Dockerfile diff --git a/build/armada/Dockerfile b/build/armada/Dockerfile new file mode 100644 index 00000000000..d932a33dfe2 --- /dev/null +++ b/build/armada/Dockerfile @@ -0,0 +1,19 @@ +FROM golang:1.12.6 as builder + +RUN mkdir /app + +ADD . /app + +WORKDIR /app + +RUN env GOOS=linux GARCH=amd64 CGO_ENABLED=0 go build -o main cmd/armada/main.go + +FROM alpine:3.10 + +COPY --from=builder /app/main /app/ + +COPY --from=builder /app/config /app/config + +WORKDIR /app + +CMD ["./main"] \ No newline at end of file diff --git a/build/executor/Dockerfile b/build/executor/Dockerfile index 2a21a4519ab..2f0a8c539c1 100644 --- a/build/executor/Dockerfile +++ b/build/executor/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.12.6 +FROM golang:1.12.6 as builder RUN mkdir /app @@ -6,8 +6,14 @@ ADD . /app WORKDIR /app -RUN ls +RUN env GOOS=linux GARCH=amd64 CGO_ENABLED=0 go build -o main cmd/executor/main.go -RUN go build -o main cmd/executor/main.go +FROM alpine:3.10 -CMD ["/app/main"] \ No newline at end of file +COPY --from=builder /app/main /app/ + +COPY --from=builder /app/config /app/config + +WORKDIR /app + +CMD ["./main"] \ No newline at end of file From 7ef35071397e7e4dcee7754594d0a1fb5d9d55b5 Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Tue, 30 Jul 2019 13:38:12 +0100 Subject: [PATCH 05/18] Allowing users to specify the location of their configuration file The existing config file found in /config/(armada|executor)/config is now going to be the "default" config Users can specify their own, via passing a command line argument --config that specifies the location of their config file, i.e: --config /some/location/config.yaml This will be merged with the default, with the user specified config overwriting the default --- cmd/armada/main.go | 15 +++++++++++++-- cmd/executor/main.go | 15 +++++++++++++-- internal/common/startup.go | 30 ++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/cmd/armada/main.go b/cmd/armada/main.go index 91e26865733..f23e36f4dae 100644 --- a/cmd/armada/main.go +++ b/cmd/armada/main.go @@ -5,16 +5,27 @@ import ( "github.com/G-Research/k8s-batch/internal/armada/configuration" "github.com/G-Research/k8s-batch/internal/common" log "github.com/sirupsen/logrus" + "github.com/spf13/pflag" + "github.com/spf13/viper" "os" "os/signal" "syscall" ) -func main() { +const CustomConfigLocation string = "config" + +func init() { + pflag.String(CustomConfigLocation, "", "Fully qualified path to application configuration file") + pflag.Parse() +} +func main() { common.ConfigureLogging() + common.BindCommandlineArguments() + var config configuration.ArmadaConfig - common.LoadConfig(&config, "./config/armada") + userSpecifiedConfig := viper.GetString(CustomConfigLocation) + common.LoadConfig(&config, "./config/armada", userSpecifiedConfig) log.Info("Starting...") diff --git a/cmd/executor/main.go b/cmd/executor/main.go index 2e0730edd63..04f9dbc4c15 100644 --- a/cmd/executor/main.go +++ b/cmd/executor/main.go @@ -4,16 +4,27 @@ import ( "github.com/G-Research/k8s-batch/internal/common" "github.com/G-Research/k8s-batch/internal/executor" "github.com/G-Research/k8s-batch/internal/executor/configuration" + "github.com/spf13/pflag" + "github.com/spf13/viper" "os" "os/signal" "syscall" ) -func main() { +const CustomConfigLocation string = "config" + +func init() { + pflag.String(CustomConfigLocation, "", "Fully qualified path to application configuration file") + pflag.Parse() +} +func main() { common.ConfigureLogging() + common.BindCommandlineArguments() + var config configuration.ExecutorConfiguration - common.LoadConfig(&config, "./config/executor") + userSpecifiedConfig := viper.GetString(CustomConfigLocation) + common.LoadConfig(&config, "./config/executor", userSpecifiedConfig) shutdownChannel := make(chan os.Signal, 1) signal.Notify(shutdownChannel, syscall.SIGINT, syscall.SIGTERM) diff --git a/internal/common/startup.go b/internal/common/startup.go index 4ad3b230b21..59f42a7d5e0 100644 --- a/internal/common/startup.go +++ b/internal/common/startup.go @@ -2,17 +2,43 @@ package common import ( log "github.com/sirupsen/logrus" + "github.com/spf13/pflag" "github.com/spf13/viper" "os" + "path/filepath" + "strings" ) -func LoadConfig(config interface{}, path string) { +func BindCommandlineArguments() { + err := viper.BindPFlags(pflag.CommandLine) + if err != nil { + log.Error() + os.Exit(-1) + } +} + +func LoadConfig(config interface{}, defaultPath string, customConfigPath string) { viper.SetConfigName("config") - viper.AddConfigPath(path) + viper.AddConfigPath(defaultPath) if err := viper.ReadInConfig(); err != nil { log.Error(err) os.Exit(-1) } + + if customConfigPath != "" { + dir, file := filepath.Split(customConfigPath) + fileName := strings.TrimSuffix(file, filepath.Ext(file)) + + viper.SetConfigName(fileName) + viper.AddConfigPath(dir) + + err := viper.MergeInConfig() + if err != nil { + log.Error(err) + os.Exit(-1) + } + } + err := viper.Unmarshal(config) if err != nil { log.Error(err) From 2ebd83cf43e9c477243e6c147ecae79c9ee87724 Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Tue, 30 Jul 2019 13:40:19 +0100 Subject: [PATCH 06/18] Allowing kubernetes connection config location to be specified in the config This allows a custom kubernetes config file location to be used I was debating making this a command line argument - I thought it fit fine into its own section of the config along with inClusterDeployment There may be a case to swap (or add) a command line argument for this --- config/executor/config.yaml | 2 ++ go.mod | 1 + internal/executor/application.go | 2 +- internal/executor/configuration/types.go | 7 ++++++- internal/executor/kubernetes_client.go | 11 +++++++---- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/config/executor/config.yaml b/config/executor/config.yaml index 2bc4ab42860..12112380197 100644 --- a/config/executor/config.yaml +++ b/config/executor/config.yaml @@ -1,6 +1,8 @@ application: clusterId : "Cluster1" +kubernetes: inClusterDeployment: false + configLocation: "" task: utilisationReportingInterval: 10s missingJobEventReconciliationInterval: 10s diff --git a/go.mod b/go.mod index 95490864b29..3056635a30f 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/kjk/betterguid v0.0.0-20170621091430-c442874ba63a github.com/oklog/ulid v1.3.1 github.com/sirupsen/logrus v1.2.0 + github.com/spf13/pflag v1.0.3 github.com/spf13/viper v1.4.0 github.com/stretchr/testify v1.3.0 github.com/yuin/gopher-lua v0.0.0-20190514113301-1cd887cd7036 // indirect diff --git a/internal/executor/application.go b/internal/executor/application.go index 95fe2003a04..ea005b0ed3d 100644 --- a/internal/executor/application.go +++ b/internal/executor/application.go @@ -18,7 +18,7 @@ import ( ) func StartUp(config configuration.ExecutorConfiguration) (func(), *sync.WaitGroup) { - kubernetesClient, err := CreateKubernetesClientWithDefaultConfig(config.Application.InClusterDeployment) + kubernetesClient, err := CreateKubernetesClient(&config.Kubernetes) if err != nil { log.Errorf("Failed to connect to kubernetes because %s", err) os.Exit(-1) diff --git a/internal/executor/configuration/types.go b/internal/executor/configuration/types.go index 99e9c953b38..6e986241e32 100644 --- a/internal/executor/configuration/types.go +++ b/internal/executor/configuration/types.go @@ -3,8 +3,12 @@ package configuration import "time" type ApplicationConfiguration struct { - ClusterId string + ClusterId string +} + +type KubernetesConfiguration struct { InClusterDeployment bool + ConfigLocation string } type TaskConfiguration struct { @@ -24,6 +28,7 @@ type EventsConfiguration struct { type ExecutorConfiguration struct { Application ApplicationConfiguration + Kubernetes KubernetesConfiguration Task TaskConfiguration Armada ArmadaConfiguration Events EventsConfiguration diff --git a/internal/executor/kubernetes_client.go b/internal/executor/kubernetes_client.go index d203e4e3929..b22f49a0a25 100644 --- a/internal/executor/kubernetes_client.go +++ b/internal/executor/kubernetes_client.go @@ -1,13 +1,14 @@ package executor import ( + "github.com/G-Research/k8s-batch/internal/executor/configuration" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" ) -func CreateKubernetesClientWithDefaultConfig(inCluster bool) (kubernetes.Interface, error) { - config, err := loadConfig(inCluster) +func CreateKubernetesClient(kubernetesConfig *configuration.KubernetesConfiguration) (kubernetes.Interface, error) { + config, err := loadConfig(kubernetesConfig) if err != nil { return nil, err @@ -16,9 +17,11 @@ func CreateKubernetesClientWithDefaultConfig(inCluster bool) (kubernetes.Interfa return kubernetes.NewForConfig(config) } -func loadConfig(inCluster bool) (*rest.Config, error) { - if inCluster { +func loadConfig(kubernetesConfig *configuration.KubernetesConfiguration) (*rest.Config, error) { + if kubernetesConfig.InClusterDeployment { return rest.InClusterConfig() + } else if kubernetesConfig.ConfigLocation != "" { + return clientcmd.BuildConfigFromFlags("", kubernetesConfig.ConfigLocation) } else { rules := clientcmd.NewDefaultClientConfigLoadingRules() overrides := &clientcmd.ConfigOverrides{} From 75ca6b78f4585ae30afaa303b0b8142bcb132355 Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Tue, 30 Jul 2019 15:44:47 +0100 Subject: [PATCH 07/18] Adding git hash as docker image tag --- .circleci/config.yml | 2 +- build/armada/Dockerfile | 2 +- build/executor/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f59043bf0e9..81e241b6712 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -24,4 +24,4 @@ jobs: - run: go get -v -d ./... - run: go test -v ./... - run: exit $(gofmt -l . | wc -l) - - run: docker build -t executor-test -f ./build/executor/Dockerfile . + - run: docker build -t executor:${CIRCLE_SHA1} -f ./build/executor/Dockerfile . diff --git a/build/armada/Dockerfile b/build/armada/Dockerfile index d932a33dfe2..3d0335c4ac2 100644 --- a/build/armada/Dockerfile +++ b/build/armada/Dockerfile @@ -16,4 +16,4 @@ COPY --from=builder /app/config /app/config WORKDIR /app -CMD ["./main"] \ No newline at end of file +CMD ["./main"] diff --git a/build/executor/Dockerfile b/build/executor/Dockerfile index 2f0a8c539c1..521616a2d5e 100644 --- a/build/executor/Dockerfile +++ b/build/executor/Dockerfile @@ -16,4 +16,4 @@ COPY --from=builder /app/config /app/config WORKDIR /app -CMD ["./main"] \ No newline at end of file +CMD ["./main"] From 5cce24dfa3cf215b162aa4cb3d9bc3a634db7737 Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Tue, 30 Jul 2019 15:54:56 +0100 Subject: [PATCH 08/18] Setting working_directory to something sensible --- .circleci/config.yml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 81e241b6712..060eba91d36 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,17 +5,7 @@ jobs: - image: circleci/golang:1.12.6 environment: GO111MODULE: "on" - - # Specify service dependencies here if necessary - # CircleCI maintains a library of pre-built images - # documented at https://circleci.com/docs/2.0/circleci-images/ - # - image: circleci/postgres:9.4 - - #### TEMPLATE_NOTE: go expects specific checkout path representing url - #### expecting it in the form of - #### /go/src/github.com/circleci/go-tool - #### /go/src/bitbucket.org/circleci/go-tool - working_directory: /go/src/github.com/{{ORG_NAME}}/{{REPO_NAME}} + working_directory: /go/src/github.com/Gresearch/k8s-batch steps: - checkout - setup_remote_docker From ebc4a87960d142e368ff9dff681f53ae2b082505 Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Tue, 30 Jul 2019 15:56:32 +0100 Subject: [PATCH 09/18] Renaming executor config configLocation to kubernetesConfigLocation to be more explicit --- config/executor/config.yaml | 2 +- internal/executor/configuration/types.go | 4 ++-- internal/executor/kubernetes_client.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/executor/config.yaml b/config/executor/config.yaml index 12112380197..b3435ae3c45 100644 --- a/config/executor/config.yaml +++ b/config/executor/config.yaml @@ -2,7 +2,7 @@ application: clusterId : "Cluster1" kubernetes: inClusterDeployment: false - configLocation: "" + kubernetesConfigLocation: "" task: utilisationReportingInterval: 10s missingJobEventReconciliationInterval: 10s diff --git a/internal/executor/configuration/types.go b/internal/executor/configuration/types.go index 6e986241e32..0c88f0fd9f5 100644 --- a/internal/executor/configuration/types.go +++ b/internal/executor/configuration/types.go @@ -7,8 +7,8 @@ type ApplicationConfiguration struct { } type KubernetesConfiguration struct { - InClusterDeployment bool - ConfigLocation string + InClusterDeployment bool + KubernetesConfigLocation string } type TaskConfiguration struct { diff --git a/internal/executor/kubernetes_client.go b/internal/executor/kubernetes_client.go index b22f49a0a25..ae703cd0f37 100644 --- a/internal/executor/kubernetes_client.go +++ b/internal/executor/kubernetes_client.go @@ -20,8 +20,8 @@ func CreateKubernetesClient(kubernetesConfig *configuration.KubernetesConfigurat func loadConfig(kubernetesConfig *configuration.KubernetesConfiguration) (*rest.Config, error) { if kubernetesConfig.InClusterDeployment { return rest.InClusterConfig() - } else if kubernetesConfig.ConfigLocation != "" { - return clientcmd.BuildConfigFromFlags("", kubernetesConfig.ConfigLocation) + } else if kubernetesConfig.KubernetesConfigLocation != "" { + return clientcmd.BuildConfigFromFlags("", kubernetesConfig.KubernetesConfigLocation) } else { rules := clientcmd.NewDefaultClientConfigLoadingRules() overrides := &clientcmd.ConfigOverrides{} From e3508a1d86333c75d519be3cc9637494ad40719e Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Tue, 30 Jul 2019 16:02:37 +0100 Subject: [PATCH 10/18] Making working_directory set from CIRCLE CI values --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 060eba91d36..9cb4105e5dd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,7 +5,7 @@ jobs: - image: circleci/golang:1.12.6 environment: GO111MODULE: "on" - working_directory: /go/src/github.com/Gresearch/k8s-batch + working_directory: /go/src/github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME} steps: - checkout - setup_remote_docker From b9592e9ff2dc3940579c0a7fddeb42eecf86b413 Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Tue, 30 Jul 2019 16:05:35 +0100 Subject: [PATCH 11/18] Removing circleci variables from working_directory --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9cb4105e5dd..49dcecdbe88 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,7 +5,7 @@ jobs: - image: circleci/golang:1.12.6 environment: GO111MODULE: "on" - working_directory: /go/src/github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME} + working_directory: /go/src/github.com/G-Research/k8s-batch steps: - checkout - setup_remote_docker From 3a4c665fb660467e08e0912b37d87f7691b8b602 Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Wed, 31 Jul 2019 11:35:42 +0100 Subject: [PATCH 12/18] Setting entrypoint rather than cmd in dockerfiles This makes it easier to pass in commandline arguments to docker. We currently set CMD, which when you run docker, you'll need to say: docker run ./main I'd rather people not need to know the internal executable of the docker to make it run. With ENTRYPOINT this just defines the executable that is run when docker starts So now you can use it like: docker run --- build/armada/Dockerfile | 2 +- build/executor/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/armada/Dockerfile b/build/armada/Dockerfile index 3d0335c4ac2..3e87e2a6ba4 100644 --- a/build/armada/Dockerfile +++ b/build/armada/Dockerfile @@ -16,4 +16,4 @@ COPY --from=builder /app/config /app/config WORKDIR /app -CMD ["./main"] +ENTRYPOINT ["./main"] diff --git a/build/executor/Dockerfile b/build/executor/Dockerfile index 521616a2d5e..b199079c9bc 100644 --- a/build/executor/Dockerfile +++ b/build/executor/Dockerfile @@ -16,4 +16,4 @@ COPY --from=builder /app/config /app/config WORKDIR /app -CMD ["./main"] +ENTRYPOINT ["./main"] From f13de3fc592005488e9ba2865ab793542bce226b Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Wed, 31 Jul 2019 11:39:06 +0100 Subject: [PATCH 13/18] Simplifying LoadConfig to use full path of overrideConfig This means viper will just look at the exact file specified rather than looking for files in the given paths with the given names This simplifies the code and makes it more predictable what viper is loading (as it just loads the specific file set) --- internal/common/startup.go | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/internal/common/startup.go b/internal/common/startup.go index 59f42a7d5e0..33757807892 100644 --- a/internal/common/startup.go +++ b/internal/common/startup.go @@ -5,8 +5,6 @@ import ( "github.com/spf13/pflag" "github.com/spf13/viper" "os" - "path/filepath" - "strings" ) func BindCommandlineArguments() { @@ -17,7 +15,7 @@ func BindCommandlineArguments() { } } -func LoadConfig(config interface{}, defaultPath string, customConfigPath string) { +func LoadConfig(config interface{}, defaultPath string, overrideConfig string) { viper.SetConfigName("config") viper.AddConfigPath(defaultPath) if err := viper.ReadInConfig(); err != nil { @@ -25,12 +23,8 @@ func LoadConfig(config interface{}, defaultPath string, customConfigPath string) os.Exit(-1) } - if customConfigPath != "" { - dir, file := filepath.Split(customConfigPath) - fileName := strings.TrimSuffix(file, filepath.Ext(file)) - - viper.SetConfigName(fileName) - viper.AddConfigPath(dir) + if overrideConfig != "" { + viper.SetConfigFile(overrideConfig) err := viper.MergeInConfig() if err != nil { From b01085acb526740eada974eb2701324b7d18f9b1 Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Wed, 31 Jul 2019 17:36:13 +0100 Subject: [PATCH 14/18] Adding helm chart for executor component --- deployment/executor/Chart.yaml | 4 ++ deployment/executor/templates/_helpers.tpl | 35 ++++++++++++++++++ .../executor/templates/clusterrole.yaml | 29 +++++++++++++++ .../templates/clusterrolebinding.yaml | 15 ++++++++ deployment/executor/templates/configmap.yaml | 12 ++++++ deployment/executor/templates/deployment.yaml | 37 +++++++++++++++++++ deployment/executor/templates/namespace.yaml | 6 +++ .../executor/templates/serviceaccount.yaml | 7 ++++ deployment/executor/values.yaml | 28 ++++++++++++++ 9 files changed, 173 insertions(+) create mode 100644 deployment/executor/Chart.yaml create mode 100644 deployment/executor/templates/_helpers.tpl create mode 100644 deployment/executor/templates/clusterrole.yaml create mode 100644 deployment/executor/templates/clusterrolebinding.yaml create mode 100644 deployment/executor/templates/configmap.yaml create mode 100644 deployment/executor/templates/deployment.yaml create mode 100644 deployment/executor/templates/namespace.yaml create mode 100644 deployment/executor/templates/serviceaccount.yaml create mode 100644 deployment/executor/values.yaml diff --git a/deployment/executor/Chart.yaml b/deployment/executor/Chart.yaml new file mode 100644 index 00000000000..08529925258 --- /dev/null +++ b/deployment/executor/Chart.yaml @@ -0,0 +1,4 @@ +appVersion : v1 +description: A helm chart for armada-executor component +name: armada-executor +version: 0.0.1 \ No newline at end of file diff --git a/deployment/executor/templates/_helpers.tpl b/deployment/executor/templates/_helpers.tpl new file mode 100644 index 00000000000..9de64788dc6 --- /dev/null +++ b/deployment/executor/templates/_helpers.tpl @@ -0,0 +1,35 @@ + +{{- define "executor.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "executor.config.name" -}} +{{- printf "%s-%s" ( include "executor.name" .) "config" -}} +{{- end }} + +{{- define "executor.application.config.filename" -}} +{{- printf "%s%s" ( include "executor.config.name" .) ".yaml" -}} +{{- end }} + + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "executor.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "executor.labels.identity" -}} +app: {{ include "executor.name" . }} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "executor.labels.all" -}} +{{ include "executor.labels.identity" . }} +chart: {{ include "executor.chart" . }} +release: {{ .Release.Name }} +{{- end -}} + + diff --git a/deployment/executor/templates/clusterrole.yaml b/deployment/executor/templates/clusterrole.yaml new file mode 100644 index 00000000000..a79fd255d86 --- /dev/null +++ b/deployment/executor/templates/clusterrole.yaml @@ -0,0 +1,29 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "executor.name" . }} + labels: +{{ include "executor.labels.all" . | indent 4 }} +rules: +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - create + - delete + - deletecollection + - patch + - update +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch + diff --git a/deployment/executor/templates/clusterrolebinding.yaml b/deployment/executor/templates/clusterrolebinding.yaml new file mode 100644 index 00000000000..6b151d3f56b --- /dev/null +++ b/deployment/executor/templates/clusterrolebinding.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "executor.name" . }} + labels: +{{ include "executor.labels.all" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "executor.name" . }} +subjects: +- kind: ServiceAccount + name: {{ include "executor.name" . }} + namespace: {{ .Release.Namespace }} + diff --git a/deployment/executor/templates/configmap.yaml b/deployment/executor/templates/configmap.yaml new file mode 100644 index 00000000000..4ba8229e4a8 --- /dev/null +++ b/deployment/executor/templates/configmap.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "executor.config.name" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "executor.labels.all" . | indent 4 }} +data: + {{ include "executor.application.config.filename" . }}: | +{{- if .Values.applicationConfig }} +{{ toYaml .Values.applicationConfig | indent 4 }} +{{- end }} \ No newline at end of file diff --git a/deployment/executor/templates/deployment.yaml b/deployment/executor/templates/deployment.yaml new file mode 100644 index 00000000000..b53ce34b85a --- /dev/null +++ b/deployment/executor/templates/deployment.yaml @@ -0,0 +1,37 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "executor.name" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "executor.labels.all" . | indent 4 }} +spec: + replicas: 1 + selector: + matchLabels: +{{ include "executor.labels.identity" . | indent 6 }} + template: + metadata: + name: {{ include "executor.name" . }} + labels: +{{ include "executor.labels.all" . | indent 8 }} + spec: + terminationGracePeriodSeconds: {{ .Values.executor.terminationGracePeriodSeconds }} + serviceAccountName: {{ include "executor.name" . }} + containers: + - name: executor + imagePullPolicy: IfNotPresent + image: {{ .Values.executor.image.repository }}:{{ required "A value is required for .Values.executor.image.tag" .Values.executor.image.tag }} + args: + - --config + - /config/application_config.yaml + resources: +{{ toYaml .Values.executor.resources | indent 12 }} + volumeMounts: + - name: user-config + mountPath: /config/application_config.yaml + subPath: {{ include "executor.application.config.filename" . }} + volumes: + - name: user-config + configMap: + name: {{ include "executor.config.name" . }} diff --git a/deployment/executor/templates/namespace.yaml b/deployment/executor/templates/namespace.yaml new file mode 100644 index 00000000000..c857402b4e2 --- /dev/null +++ b/deployment/executor/templates/namespace.yaml @@ -0,0 +1,6 @@ +kind: Namespace +apiVersion: v1 +metadata: + name: {{ .Release.Namespace }} + labels: +{{ include "executor.labels.all" . | indent 4 }} diff --git a/deployment/executor/templates/serviceaccount.yaml b/deployment/executor/templates/serviceaccount.yaml new file mode 100644 index 00000000000..57303ab88d2 --- /dev/null +++ b/deployment/executor/templates/serviceaccount.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "executor.name" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "executor.labels.all" . | indent 4 }} diff --git a/deployment/executor/values.yaml b/deployment/executor/values.yaml new file mode 100644 index 00000000000..6d7883fb3bf --- /dev/null +++ b/deployment/executor/values.yaml @@ -0,0 +1,28 @@ +executor: + image: + repository: executor-test + tag: latest + resources: + limits: + memory: 1Gi + cpu: 300m + requests: + memory: 512Mi + cpu: 200m + terminationGracePeriodSeconds: 0 + +applicationConfig: + application: + clusterId: "Cluster2" + kubernetes: + inClusterDeployment: false + configLocation: "/home/jamesmu/.kube/kind-config-kind" + task: + utilisationReportingInterval: 20s + missingJobEventReconciliationInterval: 20s + jobLeaseRenewalInterval: 20s + allocateSpareClusterCapacityInterval: 20s + armada: + url: "localhost:99999" + events: + url: "localhost:99999" From 57ea8a3d808fcac7e0b3444ed3a20a79d2de06f8 Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Wed, 31 Jul 2019 17:43:15 +0100 Subject: [PATCH 15/18] Setting default helm chart applicationConfig to blank The application already has default values. Helm just allows people to override them easily and shouldn't set the application defaults again --- deployment/executor/values.yaml | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/deployment/executor/values.yaml b/deployment/executor/values.yaml index 6d7883fb3bf..77d7b3350e0 100644 --- a/deployment/executor/values.yaml +++ b/deployment/executor/values.yaml @@ -11,18 +11,4 @@ executor: cpu: 200m terminationGracePeriodSeconds: 0 -applicationConfig: - application: - clusterId: "Cluster2" - kubernetes: - inClusterDeployment: false - configLocation: "/home/jamesmu/.kube/kind-config-kind" - task: - utilisationReportingInterval: 20s - missingJobEventReconciliationInterval: 20s - jobLeaseRenewalInterval: 20s - allocateSpareClusterCapacityInterval: 20s - armada: - url: "localhost:99999" - events: - url: "localhost:99999" +applicationConfig: \ No newline at end of file From 38f51be0b300193c0bc2e14986a5f41db010e1a0 Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Thu, 1 Aug 2019 13:32:35 +0100 Subject: [PATCH 16/18] Moving inCluster and kubeConfigPath to command line flags rather than config These are setting up how the program run rather than configuring variables so it makes sense you declare them when running the application Also this makes it much easier to set the program to run as "inCluster" mode in Helm if we do it like this. Rather than having a default config in helm which overwrites the application default config --- cmd/executor/main.go | 24 ++++++++++++++++++++---- config/executor/config.yaml | 3 --- internal/executor/kubernetes_client.go | 4 ++++ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/cmd/executor/main.go b/cmd/executor/main.go index 04f9dbc4c15..ec9f0703808 100644 --- a/cmd/executor/main.go +++ b/cmd/executor/main.go @@ -12,19 +12,20 @@ import ( ) const CustomConfigLocation string = "config" +const InCluster string = "inCluster" +const KubeConfig string = "kubeConfigPath" func init() { pflag.String(CustomConfigLocation, "", "Fully qualified path to application configuration file") + pflag.Bool(InCluster, false, "When set executor will run using in cluster client connection details") + pflag.String(KubeConfig, "", "Fully qualified path to custom kube config file") pflag.Parse() } func main() { common.ConfigureLogging() common.BindCommandlineArguments() - - var config configuration.ExecutorConfiguration - userSpecifiedConfig := viper.GetString(CustomConfigLocation) - common.LoadConfig(&config, "./config/executor", userSpecifiedConfig) + config := loadConfig() shutdownChannel := make(chan os.Signal, 1) signal.Notify(shutdownChannel, syscall.SIGINT, syscall.SIGTERM) @@ -36,3 +37,18 @@ func main() { }() wg.Wait() } + +func loadConfig() configuration.ExecutorConfiguration { + var config configuration.ExecutorConfiguration + userSpecifiedConfig := viper.GetString(CustomConfigLocation) + common.LoadConfig(&config, "./config/executor", userSpecifiedConfig) + + inClusterDeployment := viper.GetBool(InCluster) + customKubeConfigLocation := viper.GetString(KubeConfig) + + config.Kubernetes = configuration.KubernetesConfiguration{ + InClusterDeployment: inClusterDeployment, + KubernetesConfigLocation: customKubeConfigLocation, + } + return config +} diff --git a/config/executor/config.yaml b/config/executor/config.yaml index b3435ae3c45..29a9b9d64fc 100644 --- a/config/executor/config.yaml +++ b/config/executor/config.yaml @@ -1,8 +1,5 @@ application: clusterId : "Cluster1" -kubernetes: - inClusterDeployment: false - kubernetesConfigLocation: "" task: utilisationReportingInterval: 10s missingJobEventReconciliationInterval: 10s diff --git a/internal/executor/kubernetes_client.go b/internal/executor/kubernetes_client.go index ae703cd0f37..2b3d8051722 100644 --- a/internal/executor/kubernetes_client.go +++ b/internal/executor/kubernetes_client.go @@ -2,6 +2,7 @@ package executor import ( "github.com/G-Research/k8s-batch/internal/executor/configuration" + log "github.com/sirupsen/logrus" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" @@ -19,10 +20,13 @@ func CreateKubernetesClient(kubernetesConfig *configuration.KubernetesConfigurat func loadConfig(kubernetesConfig *configuration.KubernetesConfiguration) (*rest.Config, error) { if kubernetesConfig.InClusterDeployment { + log.Info("Running with in cluster client configuration") return rest.InClusterConfig() } else if kubernetesConfig.KubernetesConfigLocation != "" { + log.Infof("Running with custom client configuration from %s", kubernetesConfig.KubernetesConfigLocation) return clientcmd.BuildConfigFromFlags("", kubernetesConfig.KubernetesConfigLocation) } else { + log.Info("Running with default client configuration") rules := clientcmd.NewDefaultClientConfigLoadingRules() overrides := &clientcmd.ConfigOverrides{} return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(rules, overrides).ClientConfig() From 7e68874c49de83d229a8ff8d9d0a28a8bbfbb4e9 Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Thu, 1 Aug 2019 13:35:06 +0100 Subject: [PATCH 17/18] Setting executor helm to run in inCluster mode We currently don't support running via helm without running as in cluster mode We'd need to allow you to set the kubernetes config in some way if we allowed it to be in non inCluster mode - Would involve allowing you to set a kube config file somewhere (secret/volume) then tell the program where it is - For now this isn't needed and likely won't be needed except in very odd setups (having one kubernetes manage another one) --- deployment/executor/templates/deployment.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/deployment/executor/templates/deployment.yaml b/deployment/executor/templates/deployment.yaml index b53ce34b85a..5d9cb08ad2d 100644 --- a/deployment/executor/templates/deployment.yaml +++ b/deployment/executor/templates/deployment.yaml @@ -25,6 +25,7 @@ spec: args: - --config - /config/application_config.yaml + - --inCluster resources: {{ toYaml .Values.executor.resources | indent 12 }} volumeMounts: From 7bd40aadcd374b96a651a398ac5be722f46f099f Mon Sep 17 00:00:00 2001 From: JamesMurkin Date: Thu, 1 Aug 2019 13:36:04 +0100 Subject: [PATCH 18/18] Renaming executor helm chart to just be "executor" rather than "armada-executor" --- deployment/executor/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/executor/Chart.yaml b/deployment/executor/Chart.yaml index 08529925258..fc465ea4708 100644 --- a/deployment/executor/Chart.yaml +++ b/deployment/executor/Chart.yaml @@ -1,4 +1,4 @@ appVersion : v1 description: A helm chart for armada-executor component -name: armada-executor +name: executor version: 0.0.1 \ No newline at end of file