diff --git a/.changes/unreleased/Feature-20260218-130149.yaml b/.changes/unreleased/Feature-20260218-130149.yaml new file mode 100644 index 0000000..5f61056 --- /dev/null +++ b/.changes/unreleased/Feature-20260218-130149.yaml @@ -0,0 +1,3 @@ +kind: Feature +body: Add the ability to override the helper image +time: 2026-02-18T13:01:49.668464-05:00 diff --git a/.changes/unreleased/Feature-20260218-130222.yaml b/.changes/unreleased/Feature-20260218-130222.yaml new file mode 100644 index 0000000..44f7587 --- /dev/null +++ b/.changes/unreleased/Feature-20260218-130222.yaml @@ -0,0 +1,3 @@ +kind: Feature +body: Add the ability to set the k8s api QPS +time: 2026-02-18T13:02:22.885166-05:00 diff --git a/src/cmd/root.go b/src/cmd/root.go index d47b52b..006794f 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -51,8 +51,12 @@ func init() { rootCmd.PersistentFlags().Int("job-pod-log-max-interval", 30, "The max amount of time between when pod logs are shipped to OpsLevel. Works in tandem with 'job-pod-log-max-size'") rootCmd.PersistentFlags().Int("job-pod-log-max-size", 1000000, "The max amount in bytes to buffer before pod logs are shipped to OpsLevel. Works in tandem with 'job-pod-log-max-interval'") rootCmd.PersistentFlags().Bool("job-agent-mode", false, "Enable agent mode with privileged security context for Container-in-Container support. WARNING: This grants elevated privileges and should only be enabled for trusted workloads.") + rootCmd.PersistentFlags().String("job-pod-helper-image", "", "Override the helper init container image. Defaults to the published ECR image matching the runner version. Useful for local development with kind.") rootCmd.PersistentFlags().String("queue", "", "The queue this runner should process jobs from. Empty means the default queue.") + rootCmd.PersistentFlags().Int("k8s-api-qps", 50, "The maximum sustained queries per second to the Kubernetes API server.") + rootCmd.PersistentFlags().Int("k8s-api-burst", 100, "The maximum burst of queries to the Kubernetes API server.") + rootCmd.PersistentFlags().String("runner-pod-name", "", "overrides environment variable 'RUNNER_POD_NAME'") rootCmd.PersistentFlags().String("runner-pod-namespace", "default", "The kubernetes namespace the runner pod is deployed in. Overrides environment variable 'RUNNER_POD_NAMESPACE'") rootCmd.PersistentFlags().String("runner-deployment", "runner", "The runner's kubernetes deployment name") @@ -74,8 +78,12 @@ func init() { viper.BindEnv("job-pod-log-max-interval", "OPSLEVEL_JOB_POD_LOG_MAX_INTERVAL") viper.BindEnv("job-pod-log-max-size", "OPSLEVEL_JOB_POD_LOG_MAX_SIZE") viper.BindEnv("job-agent-mode", "OPSLEVEL_JOB_AGENT_MODE") + viper.BindEnv("job-pod-helper-image", "OPSLEVEL_JOB_POD_HELPER_IMAGE") viper.BindEnv("queue", "OPSLEVEL_QUEUE") + viper.BindEnv("k8s-api-qps", "OPSLEVEL_K8S_API_QPS") + viper.BindEnv("k8s-api-burst", "OPSLEVEL_K8S_API_BURST") + viper.BindEnv("runner-pod-name", "RUNNER_POD_NAME") viper.BindEnv("runner-pod-namespace", "RUNNER_POD_NAMESPACE") viper.BindEnv("runner-deployment", "RUNNER_DEPLOYMENT") diff --git a/src/pkg/k8s.go b/src/pkg/k8s.go index ac7a6fa..e7a9e25 100644 --- a/src/pkg/k8s.go +++ b/src/pkg/k8s.go @@ -211,7 +211,7 @@ func (s *JobRunner) getPodObject(identifier string, labels map[string]string, jo InitContainers: []corev1.Container{ { Name: ContainerNameHelper, - Image: fmt.Sprintf("public.ecr.aws/opslevel/opslevel-runner:v%s", ImageTagVersion), + Image: s.podConfig.helperImage(), ImagePullPolicy: s.podConfig.PullPolicy, Command: []string{ "cp", @@ -368,6 +368,8 @@ func GetKubernetesConfig() (*rest.Config, error) { loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() configOverrides := &clientcmd.ConfigOverrides{} config, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides).ClientConfig() + config.QPS = float32(viper.GetInt("k8s-api-qps")) + config.Burst = viper.GetInt("k8s-api-burst") config.Timeout = time.Second * time.Duration(viper.GetInt("job-pod-exec-max-wait")) if err != nil { return nil, err diff --git a/src/pkg/k8s_config.go b/src/pkg/k8s_config.go index 1d1344d..e532c31 100644 --- a/src/pkg/k8s_config.go +++ b/src/pkg/k8s_config.go @@ -1,6 +1,7 @@ package pkg import ( + "fmt" "os" "github.com/spf13/viper" @@ -27,6 +28,7 @@ type K8SPodConfig struct { SecurityContext corev1.PodSecurityContext `yaml:"securityContext"` NodeSelector map[string]string `yaml:"nodeSelector"` AgentMode bool `yaml:"agentMode"` + HelperImage string `yaml:"helperImage"` } func ReadPodConfig(path string) (*K8SPodConfig, error) { @@ -48,6 +50,7 @@ func ReadPodConfig(path string) (*K8SPodConfig, error) { }, TerminationGracePeriodSeconds: 5, AgentMode: viper.GetBool("job-agent-mode"), + HelperImage: viper.GetString("job-pod-helper-image"), }, } // Early out with viper defaults if config file doesn't exist @@ -65,3 +68,10 @@ func ReadPodConfig(path string) (*K8SPodConfig, error) { return &config.Kubernetes, nil } + +func (c *K8SPodConfig) helperImage() string { + if c.HelperImage != "" { + return c.HelperImage + } + return fmt.Sprintf("public.ecr.aws/opslevel/opslevel-runner:v%s", ImageTagVersion) +}