in pkg/controller/build/build_pod.go [426:552]
func addKanikoTaskToPod(ctx context.Context, c ctrl.Reader, build *v1.Build, task *v1.KanikoTask, pod *corev1.Pod) error {
cache := false
if task.Cache.Enabled != nil && *task.Cache.Enabled {
cache = true
}
args := []string{
"--dockerfile=Dockerfile",
"--context=" + filepath.Join(builderDir, build.Name, builder.ContextDir),
"--destination=" + task.Image,
"--cache=" + strconv.FormatBool(cache),
"--cache-dir=" + builder.KanikoCacheDir,
}
if task.Verbose != nil && *task.Verbose {
args = append(args, "-v=debug")
}
affinity := &corev1.Affinity{}
env := make([]corev1.EnvVar, 0)
volumes := make([]corev1.Volume, 0)
volumeMounts := make([]corev1.VolumeMount, 0)
if task.Registry.Secret != "" {
secret, err := getRegistrySecret(ctx, c, build.Namespace, task.Registry.Secret, kanikoRegistrySecrets)
if err != nil {
return err
}
addRegistrySecret(task.Registry.Secret, secret, &volumes, &volumeMounts, &env)
}
if task.Registry.Insecure {
args = append(args, "--insecure")
args = append(args, "--insecure-pull")
}
env = append(env, proxyFromEnvironment()...)
if cache {
// Co-locate with the Kaniko warmer pod for sharing the host path volume as the current
// persistent volume claim uses the default storage class which is likely relying
// on the host path provisioner.
// This has to be done manually by retrieving the Kaniko warmer pod node name and using
// node affinity as pod affinity only works for running pods and the Kaniko warmer pod
// has already completed at that stage.
// Locate the kaniko warmer pod
pods := &corev1.PodList{}
err := c.List(ctx, pods,
ctrl.InNamespace(build.Namespace),
ctrl.MatchingLabels{
"camel.apache.org/component": "kaniko-warmer",
})
if err != nil {
return err
}
if len(pods.Items) != 1 {
return errors.New("failed to locate the Kaniko cache warmer pod")
}
// Use node affinity with the Kaniko warmer pod node name
affinity = &corev1.Affinity{
NodeAffinity: &corev1.NodeAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{
NodeSelectorTerms: []corev1.NodeSelectorTerm{
{
MatchExpressions: []corev1.NodeSelectorRequirement{
{
Key: "kubernetes.io/hostname",
Operator: "In",
Values: []string{pods.Items[0].Spec.NodeName},
},
},
},
},
},
},
}
// Mount the PV used to warm the Kaniko cache into the Kaniko image build
volumes = append(volumes, corev1.Volume{
Name: "kaniko-cache",
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
ClaimName: task.Cache.PersistentVolumeClaim,
},
},
})
volumeMounts = append(volumeMounts, corev1.VolumeMount{
Name: "kaniko-cache",
MountPath: builder.KanikoCacheDir,
})
}
image := task.ExecutorImage
if image == "" {
image = fmt.Sprintf("%s:v%s", builder.KanikoDefaultExecutorImageName, defaults.KanikoVersion)
}
container := corev1.Container{
Name: task.Name,
Image: image,
ImagePullPolicy: corev1.PullIfNotPresent,
Args: args,
Env: env,
WorkingDir: filepath.Join(builderDir, build.Name, builder.ContextDir),
VolumeMounts: volumeMounts,
}
// We may want to handle possible conflicts
pod.Spec.Affinity = affinity
pod.Spec.Volumes = append(pod.Spec.Volumes, volumes...)
// Warning: Kaniko requires root privileges to work correctly
// As we're planning to deprecate this building strategy we're fixing in the first
// releases of version 2
var ugfid int64 = 0
pod.Spec.SecurityContext = &corev1.PodSecurityContext{
RunAsUser: &ugfid,
RunAsGroup: &ugfid,
FSGroup: &ugfid,
}
addContainerToPod(build, container, pod)
return nil
}