From 10f212c5154c9bb2df9d6d71fdbbf96261859d2d Mon Sep 17 00:00:00 2001 From: nferraro Date: Wed, 5 Jun 2019 13:03:29 +0200 Subject: [PATCH] Fix #703: fix warming cache and affinity to work in global mode --- deploy/operator-role-kubernetes.yaml | 3 ++ deploy/operator-role-openshift.yaml | 3 ++ deploy/resources.go | 6 ++++ pkg/builder/kaniko/publisher.go | 36 +++++++++++++------ pkg/controller/build/schedule_pod.go | 31 +++++++++------- .../integrationplatform/initialize.go | 20 +++++++---- pkg/platform/operator.go | 31 +++++++++++----- 7 files changed, 93 insertions(+), 37 deletions(-) diff --git a/deploy/operator-role-kubernetes.yaml b/deploy/operator-role-kubernetes.yaml index c0c08cba3b..47c2acd7a3 100644 --- a/deploy/operator-role-kubernetes.yaml +++ b/deploy/operator-role-kubernetes.yaml @@ -20,6 +20,9 @@ rules: - persistentvolumeclaims - configmaps - secrets + - serviceaccounts + - roles + - rolebindings verbs: - create - delete diff --git a/deploy/operator-role-openshift.yaml b/deploy/operator-role-openshift.yaml index 41a5f72486..8b1a2b44a9 100644 --- a/deploy/operator-role-openshift.yaml +++ b/deploy/operator-role-openshift.yaml @@ -20,6 +20,9 @@ rules: - persistentvolumeclaims - configmaps - secrets + - serviceaccounts + - roles + - rolebindings verbs: - create - delete diff --git a/deploy/resources.go b/deploy/resources.go index 53af8b2656..cc87284194 100644 --- a/deploy/resources.go +++ b/deploy/resources.go @@ -10815,6 +10815,9 @@ rules: - persistentvolumeclaims - configmaps - secrets + - serviceaccounts + - roles + - rolebindings verbs: - create - delete @@ -10895,6 +10898,9 @@ rules: - persistentvolumeclaims - configmaps - secrets + - serviceaccounts + - roles + - rolebindings verbs: - create - delete diff --git a/pkg/builder/kaniko/publisher.go b/pkg/builder/kaniko/publisher.go index f11c19bca7..6de226efaf 100644 --- a/pkg/builder/kaniko/publisher.go +++ b/pkg/builder/kaniko/publisher.go @@ -24,6 +24,7 @@ import ( "time" "github.com/apache/camel-k/pkg/builder" + "github.com/apache/camel-k/pkg/platform" "github.com/apache/camel-k/pkg/util/kubernetes" "github.com/apache/camel-k/pkg/util/tar" @@ -131,19 +132,32 @@ func publisher(ctx *builder.Context) error { }, RestartPolicy: corev1.RestartPolicyNever, Volumes: volumes, - // Co-locate with builder pod for sharing the volume - 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", + }, + } + + + 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 + pod.Spec.Affinity = &corev1.Affinity{ + PodAffinity: &corev1.PodAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + labelKey: labelValue, }, }, + TopologyKey: "kubernetes.io/hostname", }, }, }, diff --git a/pkg/controller/build/schedule_pod.go b/pkg/controller/build/schedule_pod.go index 60a92784b1..ee84c54a76 100644 --- a/pkg/controller/build/schedule_pod.go +++ b/pkg/controller/build/schedule_pod.go @@ -156,6 +156,9 @@ func newBuildPod(build *v1alpha1.Build, operatorImage string) *corev1.Pod { ObjectMeta: metav1.ObjectMeta{ Namespace: build.Namespace, Name: buildPodName(build.Spec.Meta), + Labels: map[string]string{ + "camel.apache.org/build": build.Name, + }, }, Spec: corev1.PodSpec{ ServiceAccountName: "camel-k-operator", @@ -193,22 +196,26 @@ func newBuildPod(build *v1alpha1.Build, operatorImage string) *corev1.Pod { MountPath: build.Spec.BuildDir, }, } - // 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. - pod.Spec.Affinity = &corev1.Affinity{ - PodAffinity: &corev1.PodAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "camel.apache.org/component": "operator", + + // 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 + // persistent volume claim uses the default storage class which is likely relying + // on the host path provisioner. + pod.Spec.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", }, - TopologyKey: "kubernetes.io/hostname", }, }, - }, + } } } diff --git a/pkg/controller/integrationplatform/initialize.go b/pkg/controller/integrationplatform/initialize.go index 2ddd167572..0829b8f82f 100644 --- a/pkg/controller/integrationplatform/initialize.go +++ b/pkg/controller/integrationplatform/initialize.go @@ -161,13 +161,21 @@ func (action *initializeAction) Handle(ctx context.Context, ip *v1alpha1.Integra return err } - // Create the Kaniko warmer pod that caches the base image into the Camel K builder volume - action.L.Info("Create Kaniko cache warmer pod") - err = createKanikoCacheWarmerPod(ctx, action.client, target) - if err != nil { - return err + // Check if the operator is running in the same namespace before starting the cache warmer + if target.Namespace == platform.GetOperatorNamespace() { + // Create the Kaniko warmer pod that caches the base image into the Camel K builder volume + action.L.Info("Create Kaniko cache warmer pod") + err = createKanikoCacheWarmerPod(ctx, action.client, target) + if err != nil { + return err + } + + target.Status.Phase = v1alpha1.IntegrationPlatformPhaseWarming + } else { + // Skip the warmer pod creation + target.Status.Phase = v1alpha1.IntegrationPlatformPhaseCreating } - target.Status.Phase = v1alpha1.IntegrationPlatformPhaseWarming + } else { target.Status.Phase = v1alpha1.IntegrationPlatformPhaseCreating } diff --git a/pkg/platform/operator.go b/pkg/platform/operator.go index 2ffd051611..82ed950c15 100644 --- a/pkg/platform/operator.go +++ b/pkg/platform/operator.go @@ -24,6 +24,7 @@ import ( "strings" v1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -33,13 +34,9 @@ const operatorPodNameEnvVariable = "POD_NAME" // GetCurrentOperatorImage returns the image currently used by the running operator if present (when running out of cluster, it may be absent). func GetCurrentOperatorImage(ctx context.Context, c client.Client) (string, error) { - var podNamespace string - var podName string - var envSet bool - if podNamespace, envSet = os.LookupEnv(operatorNamespaceEnvVariable); !envSet || podNamespace == "" { - return "", nil - } - if podName, envSet = os.LookupEnv(operatorPodNameEnvVariable); !envSet || podName == "" { + podNamespace := GetOperatorNamespace() + podName := GetOperatorPodName() + if podNamespace == "" || podName == "" { return "", nil } @@ -49,7 +46,9 @@ func GetCurrentOperatorImage(ctx context.Context, c client.Client) (string, erro } pod := v1.Pod{} - if err := c.Get(ctx, podKey, &pod); err != nil { + if err := c.Get(ctx, podKey, &pod); err != nil && k8serrors.IsNotFound(err) { + return "", nil + } else if err != nil { return "", err } if len(pod.Spec.Containers) == 0 { @@ -65,3 +64,19 @@ func IsCurrentOperatorGlobal() bool { } return false } + +// GetOperatorNamespace returns the namespace where the current operator is located (if set) +func GetOperatorNamespace() string { + if podNamespace, envSet := os.LookupEnv(operatorNamespaceEnvVariable); envSet { + return podNamespace + } + return "" +} + +// GetOperatorPodName returns the pod that is running the current operator (if any) +func GetOperatorPodName() string { + if podName, envSet := os.LookupEnv(operatorPodNameEnvVariable); envSet { + return podName + } + return "" +}