Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(image-builder): Add field to allow api server env vars to be propagated to kaniko jobs #621

Merged
merged 5 commits into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions api/cmd/api/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"gorm.io/gorm"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/utils/clock"
Expand Down Expand Up @@ -98,6 +99,11 @@ func initImageBuilder(cfg *config.Config) (webserviceBuilder imagebuilder.ImageB
log.Panicf("%s, unable to initialize image builder", err.Error())
}

_, err = kubeClient.CoreV1().Pods("").List(context.Background(), metav1.ListOptions{})
if err != nil {
log.Panicf("%s, error sending request to kube client at startup to verify connection", err.Error())
}

timeout, err := time.ParseDuration(cfg.ImageBuilderConfig.BuildTimeout)
if err != nil {
log.Panicf("unable to parse image builder timeout to time.Duration %s", cfg.ImageBuilderConfig.BuildTimeout)
Expand Down Expand Up @@ -132,6 +138,7 @@ func initImageBuilder(cfg *config.Config) (webserviceBuilder imagebuilder.ImageB
KanikoDockerCredentialSecretName: cfg.ImageBuilderConfig.KanikoDockerCredentialSecretName,
KanikoServiceAccount: cfg.ImageBuilderConfig.KanikoServiceAccount,
KanikoAdditionalArgs: cfg.ImageBuilderConfig.KanikoAdditionalArgs,
KanikoAPIServerEnvVars: cfg.ImageBuilderConfig.KanikoAPIServerEnvVars,
DefaultResources: cfg.ImageBuilderConfig.DefaultResources,
Tolerations: cfg.ImageBuilderConfig.Tolerations,
NodeSelectors: cfg.ImageBuilderConfig.NodeSelectors,
Expand Down
1 change: 1 addition & 0 deletions api/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ type ImageBuilderConfig struct {
KanikoPushRegistryType string `validate:"required,oneof=docker gcr" default:"docker"`
KanikoDockerCredentialSecretName string
KanikoAdditionalArgs []string
KanikoAPIServerEnvVars []string
DefaultResources ResourceRequestsLimits `validate:"required"`
// How long to keep the image building job resource in the Kubernetes cluster. Default: 2 days (48 hours).
Retention time.Duration `validate:"required" default:"48h"`
Expand Down
1 change: 1 addition & 0 deletions api/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ func TestLoad(t *testing.T) {
KanikoServiceAccount: "kaniko-merlin",
KanikoPushRegistryType: "docker",
KanikoAdditionalArgs: []string{"--test=true", "--no-logs=false"},
KanikoAPIServerEnvVars: []string{"TEST_ENV_VAR"},
DefaultResources: ResourceRequestsLimits{
Requests: Resource{
CPU: "1",
Expand Down
2 changes: 2 additions & 0 deletions api/config/testdata/base-configs-1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ ImageBuilderConfig:
KanikoAdditionalArgs:
- --test=true
- --no-logs=false
KanikoAPIServerEnvVars:
- TEST_ENV_VAR
DefaultResources:
Requests:
CPU: "1"
Expand Down
2 changes: 2 additions & 0 deletions api/pkg/imagebuilder/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ type Config struct {
KanikoServiceAccount string
// Kaniko additional args
KanikoAdditionalArgs []string
// Kaniko environment variables that are propagated from the Merlin API server
KanikoAPIServerEnvVars []string
// Kubernetes resource request and limits for kaniko
DefaultResources cfg.ResourceRequestsLimits
// Tolerations for Jobs Specification
Expand Down
18 changes: 12 additions & 6 deletions api/pkg/imagebuilder/imagebuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"errors"
"fmt"
"net/http"
"os"
"sort"
"strings"
"time"
Expand Down Expand Up @@ -638,12 +639,17 @@ func (c *imageBuilder) createKanikoJobSpec(
activeDeadlineSeconds := int64(c.config.BuildTimeoutDuration / time.Second)
var volumes []v1.Volume
var volumeMounts []v1.VolumeMount
var envVar []v1.EnvVar
var envVars []v1.EnvVar

// Configure additional credentials for specific image registries and artifact services
kanikoArgs = c.configureKanikoArgsToAddCredentials(kanikoArgs)
volumes, volumeMounts = c.configureVolumesAndVolumeMountsToAddCredentials(volumes, volumeMounts)
envVar = c.configureEnvVarsToAddCredentials(envVar)
envVars = c.configureEnvVarsToAddCredentials(envVars)
deadlycoconuts marked this conversation as resolved.
Show resolved Hide resolved

// Add all other env vars that are propagated from the API server as build args
for _, envVar := range c.config.KanikoAPIServerEnvVars {
kanikoArgs = append(kanikoArgs, fmt.Sprintf("--build-arg=%s=%s", envVar, os.Getenv(envVar)))
}

var resourceRequirements RequestLimitResources
cpuRequest := resource.MustParse(c.config.DefaultResources.Requests.CPU)
Expand Down Expand Up @@ -700,7 +706,7 @@ func (c *imageBuilder) createKanikoJobSpec(
Image: c.config.KanikoImage,
Args: kanikoArgs,
VolumeMounts: volumeMounts,
Env: envVar,
Env: envVars,
Resources: resourceRequirements.Build(),
TerminationMessagePolicy: v1.TerminationMessageFallbackToLogsOnError,
},
Expand Down Expand Up @@ -767,17 +773,17 @@ func (c *imageBuilder) configureVolumesAndVolumeMountsToAddCredentials(
return volumes, volumeMounts
}

func (c *imageBuilder) configureEnvVarsToAddCredentials(envVar []v1.EnvVar) []v1.EnvVar {
func (c *imageBuilder) configureEnvVarsToAddCredentials(envVars []v1.EnvVar) []v1.EnvVar {
if c.config.KanikoPushRegistryType == googleCloudRegistryPushRegistryType ||
c.artifactService.GetType() == googleCloudStorageArtifactServiceType {
if c.config.KanikoServiceAccount == "" {
envVar = append(envVar, v1.EnvVar{
envVars = append(envVars, v1.EnvVar{
Name: gacEnvKey,
Value: saFilePath,
})
}
}
return envVar
return envVars
}

func (c *imageBuilder) GetImageBuildingJobStatus(ctx context.Context, project mlp.Project, model *models.Model, version *models.Version) (status models.ImageBuildingJobStatus) {
Expand Down
Loading