You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by as...@apache.org on 2019/10/09 12:24:40 UTC
[camel-k] 01/04: fix(kaniko): Do not co-locate Kaniko warmer pod
with the operator pod
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 <an...@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",
- },
- },
- },
- },
},
}