This is an automated email from the ASF dual-hosted git repository.

astefanutti pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit ac7dee21b2ffbe34a764460fa489775e8daf79a3
Author: Antonin Stefanutti <anto...@stefanutti.fr>
AuthorDate: Tue Oct 8 15:23:38 2019 +0200

    fix(kaniko): Do not co-locate Kaniko warmer pod with the operator pod
---
 pkg/builder/kaniko/publisher.go                    | 16 +----
 pkg/controller/build/schedule_pod.go               | 73 ++++++++++++++++------
 pkg/controller/integrationplatform/kaniko_cache.go | 20 +-----
 3 files changed, 60 insertions(+), 49 deletions(-)

diff --git a/pkg/builder/kaniko/publisher.go b/pkg/builder/kaniko/publisher.go
index 6529dcb..535cfbb 100644
--- a/pkg/builder/kaniko/publisher.go
+++ b/pkg/builder/kaniko/publisher.go
@@ -26,7 +26,6 @@ import (
        "time"
 
        "github.com/apache/camel-k/pkg/builder"
-       "github.com/apache/camel-k/pkg/platform"
        "github.com/apache/camel-k/pkg/util/defaults"
        "github.com/apache/camel-k/pkg/util/kubernetes"
        "github.com/apache/camel-k/pkg/util/tar"
@@ -187,25 +186,14 @@ func publisher(ctx *builder.Context) error {
                },
        }
 
-       var labelKey string
-       var labelValue string
-       if ctx.Namespace == platform.GetOperatorNamespace() {
-               // Check if the operator is running in the same namespace
-               labelKey = "camel.apache.org/component"
-               labelValue = "operator"
-       } else {
-               labelKey = "camel.apache.org/build"
-               labelValue = ctx.Build.Meta.Name
-       }
-
-       // Co-locate with builder pod for sharing the volume
+       // Co-locate with the build pod for sharing the volume
        pod.Spec.Affinity = &corev1.Affinity{
                PodAffinity: &corev1.PodAffinity{
                        RequiredDuringSchedulingIgnoredDuringExecution: 
[]corev1.PodAffinityTerm{
                                {
                                        LabelSelector: &metav1.LabelSelector{
                                                MatchLabels: map[string]string{
-                                                       labelKey: labelValue,
+                                                       
"camel.apache.org/build": ctx.Build.Meta.Name,
                                                },
                                        },
                                        TopologyKey: "kubernetes.io/hostname",
diff --git a/pkg/controller/build/schedule_pod.go 
b/pkg/controller/build/schedule_pod.go
index b3b3dcd..affba9b 100644
--- a/pkg/controller/build/schedule_pod.go
+++ b/pkg/controller/build/schedule_pod.go
@@ -21,16 +21,18 @@ import (
        "context"
        "sync"
 
-       "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-       "github.com/apache/camel-k/pkg/platform"
-       "github.com/apache/camel-k/pkg/util/defaults"
-
        corev1 "k8s.io/api/core/v1"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+       "k8s.io/apimachinery/pkg/labels"
+       "k8s.io/apimachinery/pkg/selection"
 
        k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
        "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
 
+       "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+       "github.com/apache/camel-k/pkg/platform"
+       "github.com/apache/camel-k/pkg/util/defaults"
+
        "github.com/pkg/errors"
 )
 
@@ -96,7 +98,10 @@ func (action *schedulePodAction) Handle(ctx context.Context, 
build *v1alpha1.Bui
 
                // We may want to explicitly manage build priority as opposed 
to relying on
                // the reconcile loop to handle the queuing
-               pod = newBuildPod(build, operatorImage)
+               pod, err = action.newBuildPod(ctx, build, operatorImage)
+               if err != nil {
+                       return nil, err
+               }
 
                // Set the Build instance as the owner and controller
                if err := controllerutil.SetControllerReference(build, pod, 
action.client.GetScheme()); err != nil {
@@ -113,7 +118,7 @@ func (action *schedulePodAction) Handle(ctx 
context.Context, build *v1alpha1.Bui
        return build, nil
 }
 
-func newBuildPod(build *v1alpha1.Build, operatorImage string) *corev1.Pod {
+func (action *schedulePodAction) newBuildPod(ctx context.Context, build 
*v1alpha1.Build, operatorImage string) (*corev1.Pod, error) {
        builderImage := operatorImage
        if builderImage == "" {
                builderImage = defaults.ImageName + ":" + defaults.Version
@@ -127,7 +132,8 @@ func newBuildPod(build *v1alpha1.Build, operatorImage 
string) *corev1.Pod {
                        Namespace: build.Namespace,
                        Name:      buildPodName(build.Spec.Meta),
                        Labels: map[string]string{
-                               "camel.apache.org/build": build.Name,
+                               "camel.apache.org/build":     build.Name,
+                               "camel.apache.org/component": "builder",
                        },
                },
                Spec: corev1.PodSpec{
@@ -185,21 +191,52 @@ func newBuildPod(build *v1alpha1.Build, operatorImage 
string) *corev1.Pod {
                        },
                })
 
-               // Use affinity only when the operator is present in the 
namespaced
-               if build.Namespace == platform.GetOperatorNamespace() {
-                       // Co-locate with the builder pod for sharing the host 
path volume as the current
+               // Use affinity when Kaniko cache warming is enabled
+               if build.Spec.Platform.Build.IsKanikoCacheEnabled() {
+                       // 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
+                       byComponentLabel, err := 
labels.NewRequirement("camel.apache.org/component", selection.Equals, 
[]string{"kaniko-warmer"})
+                       if err != nil {
+                               return nil, err
+                       }
+
+                       selector := labels.NewSelector().Add(*byComponentLabel)
+
+                       options := &k8sclient.ListOptions{
+                               Namespace:     build.Namespace,
+                               LabelSelector: selector,
+                       }
+
+                       pods := &corev1.PodList{}
+                       err = action.client.List(ctx, options, pods)
+                       if err != nil {
+                               return nil, err
+                       }
+
+                       if len(pods.Items) != 1 {
+                               return nil, errors.New("failed to locate the 
Kaniko cache warmer pod")
+                       }
+
+                       // Use node affinity with the Kaniko warmer pod node 
name
                        pod.Spec.Affinity = &corev1.Affinity{
-                               PodAffinity: &corev1.PodAffinity{
-                                       
RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{
-                                               {
-                                                       LabelSelector: 
&metav1.LabelSelector{
-                                                               MatchLabels: 
map[string]string{
-                                                                       
"camel.apache.org/component": "operator",
+                               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},
+                                                                       },
                                                                },
                                                        },
-                                                       TopologyKey: 
"kubernetes.io/hostname",
                                                },
                                        },
                                },
@@ -207,5 +244,5 @@ func newBuildPod(build *v1alpha1.Build, operatorImage 
string) *corev1.Pod {
                }
        }
 
-       return pod
+       return pod, nil
 }
diff --git a/pkg/controller/integrationplatform/kaniko_cache.go 
b/pkg/controller/integrationplatform/kaniko_cache.go
index 3470663..217c50f 100644
--- a/pkg/controller/integrationplatform/kaniko_cache.go
+++ b/pkg/controller/integrationplatform/kaniko_cache.go
@@ -48,6 +48,9 @@ func createKanikoCacheWarmerPod(ctx context.Context, client 
client.Client, platf
                ObjectMeta: metav1.ObjectMeta{
                        Namespace: platform.Namespace,
                        Name:      platform.Name + "-cache",
+                       Labels: map[string]string{
+                               "camel.apache.org/component": "kaniko-warmer",
+                       },
                },
                Spec: corev1.PodSpec{
                        Containers: []corev1.Container{
@@ -93,23 +96,6 @@ func createKanikoCacheWarmerPod(ctx context.Context, client 
client.Client, platf
                                        },
                                },
                        },
-                       // Co-locate with the builder 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.
-                       Affinity: &corev1.Affinity{
-                               PodAffinity: &corev1.PodAffinity{
-                                       
RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{
-                                               {
-                                                       LabelSelector: 
&metav1.LabelSelector{
-                                                               MatchLabels: 
map[string]string{
-                                                                       
"camel.apache.org/component": "operator",
-                                                               },
-                                                       },
-                                                       TopologyKey: 
"kubernetes.io/hostname",
-                                               },
-                                       },
-                               },
-                       },
                },
        }
 

Reply via email to