From f0d0dac506da0dae1be20edeb3daf309eff1aa09 Mon Sep 17 00:00:00 2001 From: lamai93 Date: Tue, 4 Dec 2018 16:12:41 +0100 Subject: [PATCH 1/2] Added nodeSelector field that is forwarded to the created pods of the specific group. --- pkg/apis/deployment/v1alpha/server_group_spec.go | 10 ++++++++++ pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go | 7 +++++++ pkg/deployment/images.go | 2 +- pkg/deployment/resources/pod_creator.go | 5 +++-- pkg/util/k8sutil/pods.go | 11 ++++++----- 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/pkg/apis/deployment/v1alpha/server_group_spec.go b/pkg/apis/deployment/v1alpha/server_group_spec.go index d5e63db6e..20d3ec0c7 100644 --- a/pkg/apis/deployment/v1alpha/server_group_spec.go +++ b/pkg/apis/deployment/v1alpha/server_group_spec.go @@ -49,6 +49,8 @@ type ServerGroupSpec struct { Tolerations []v1.Toleration `json:"tolerations,omitempty"` // ServiceAccountName specifies the name of the service account used for Pods in this group. ServiceAccountName *string `json:"serviceAccountName,omitempty"` + // NodeSelector speficies a set of selectors for nodes + NodeSelector map[string]string `json:"nodeSelector,omitempty"` } // GetCount returns the value of count. @@ -56,6 +58,11 @@ func (s ServerGroupSpec) GetCount() int { return util.IntOrDefault(s.Count) } +// GetNodeSelector returns the selectors for nodes of this group +func (s ServerGroupSpec) GetNodeSelector() map[string]string { + return s.NodeSelector +} + // GetArgs returns the value of args. func (s ServerGroupSpec) GetArgs() []string { return s.Args @@ -194,6 +201,9 @@ func (s *ServerGroupSpec) SetDefaultsFrom(source ServerGroupSpec) { if s.ServiceAccountName == nil { s.ServiceAccountName = util.NewStringOrNil(source.ServiceAccountName) } + if s.NodeSelector == nil { + s.NodeSelector = source.NodeSelector + } setDefaultsFromResourceList(&s.Resources.Limits, source.Resources.Limits) setDefaultsFromResourceList(&s.Resources.Requests, source.Resources.Requests) } diff --git a/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go b/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go index 2886d19ff..47fd66ee1 100644 --- a/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go +++ b/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go @@ -626,6 +626,13 @@ func (in *ServerGroupSpec) DeepCopyInto(out *ServerGroupSpec) { *out = new(string) **out = **in } + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } return } diff --git a/pkg/deployment/images.go b/pkg/deployment/images.go index 4701b5707..efb18f2d5 100644 --- a/pkg/deployment/images.go +++ b/pkg/deployment/images.go @@ -179,7 +179,7 @@ func (ib *imagesBuilder) fetchArangoDBImageIDAndVersion(ctx context.Context, ima serviceAccountName := "" if err := k8sutil.CreateArangodPod(ib.KubeCli, true, ib.APIObject, role, id, podName, "", image, "", "", ib.Spec.GetImagePullPolicy(), "", false, terminationGracePeriod, args, nil, nil, nil, nil, - tolerations, serviceAccountName, "", ""); err != nil { + tolerations, serviceAccountName, "", "", nil); err != nil { log.Debug().Err(err).Msg("Failed to create image ID pod") return true, maskAny(err) } diff --git a/pkg/deployment/resources/pod_creator.go b/pkg/deployment/resources/pod_creator.go index 4a06262ac..5c8651ac9 100644 --- a/pkg/deployment/resources/pod_creator.go +++ b/pkg/deployment/resources/pod_creator.go @@ -529,7 +529,8 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, memberID string, requireUUID := group == api.ServerGroupDBServers && m.IsInitialized finalizers := r.createPodFinalizers(group) if err := k8sutil.CreateArangodPod(kubecli, spec.IsDevelopment(), apiObject, role, m.ID, m.PodName, m.PersistentVolumeClaimName, imageInfo.ImageID, lifecycleImage, alpineImage, spec.GetImagePullPolicy(), - engine, requireUUID, terminationGracePeriod, args, env, finalizers, livenessProbe, readinessProbe, tolerations, serviceAccountName, tlsKeyfileSecretName, rocksdbEncryptionSecretName); err != nil { + engine, requireUUID, terminationGracePeriod, args, env, finalizers, livenessProbe, readinessProbe, tolerations, serviceAccountName, tlsKeyfileSecretName, rocksdbEncryptionSecretName, + groupSpec.GetNodeSelector()); err != nil { return maskAny(err) } log.Debug().Str("pod-name", m.PodName).Msg("Created pod") @@ -600,7 +601,7 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, memberID string, affinityWithRole = api.ServerGroupDBServers.AsRole() } if err := k8sutil.CreateArangoSyncPod(kubecli, spec.IsDevelopment(), apiObject, role, m.ID, m.PodName, imageInfo.ImageID, lifecycleImage, spec.GetImagePullPolicy(), terminationGracePeriod, args, env, - livenessProbe, tolerations, serviceAccountName, tlsKeyfileSecretName, clientAuthCASecretName, masterJWTSecretName, clusterJWTSecretName, affinityWithRole); err != nil { + livenessProbe, tolerations, serviceAccountName, tlsKeyfileSecretName, clientAuthCASecretName, masterJWTSecretName, clusterJWTSecretName, affinityWithRole, groupSpec.GetNodeSelector()); err != nil { return maskAny(err) } log.Debug().Str("pod-name", m.PodName).Msg("Created pod") diff --git a/pkg/util/k8sutil/pods.go b/pkg/util/k8sutil/pods.go index 46a5f8550..da3d9a7be 100644 --- a/pkg/util/k8sutil/pods.go +++ b/pkg/util/k8sutil/pods.go @@ -389,7 +389,7 @@ func initLifecycleContainer(image string) (v1.Container, error) { } // newPod creates a basic Pod for given settings. -func newPod(deploymentName, ns, role, id, podName string, finalizers []string, tolerations []v1.Toleration, serviceAccountName string) v1.Pod { +func newPod(deploymentName, ns, role, id, podName string, finalizers []string, tolerations []v1.Toleration, serviceAccountName string, nodeSelector map[string]string) v1.Pod { hostname := CreatePodHostName(deploymentName, role, id) p := v1.Pod{ ObjectMeta: metav1.ObjectMeta{ @@ -403,6 +403,7 @@ func newPod(deploymentName, ns, role, id, podName string, finalizers []string, t RestartPolicy: v1.RestartPolicyNever, Tolerations: tolerations, ServiceAccountName: serviceAccountName, + NodeSelector: nodeSelector, }, } return p @@ -416,9 +417,9 @@ func CreateArangodPod(kubecli kubernetes.Interface, developmentMode bool, deploy engine string, requireUUID bool, terminationGracePeriod time.Duration, args []string, env map[string]EnvValue, finalizers []string, livenessProbe *HTTPProbeConfig, readinessProbe *HTTPProbeConfig, tolerations []v1.Toleration, serviceAccountName string, - tlsKeyfileSecretName, rocksdbEncryptionSecretName string) error { + tlsKeyfileSecretName, rocksdbEncryptionSecretName string, nodeSelector map[string]string) error { // Prepare basic pod - p := newPod(deployment.GetName(), deployment.GetNamespace(), role, id, podName, finalizers, tolerations, serviceAccountName) + p := newPod(deployment.GetName(), deployment.GetNamespace(), role, id, podName, finalizers, tolerations, serviceAccountName, nodeSelector) terminationGracePeriodSeconds := int64(math.Ceil(terminationGracePeriod.Seconds())) p.Spec.TerminationGracePeriodSeconds = &terminationGracePeriodSeconds @@ -519,9 +520,9 @@ func CreateArangodPod(kubecli kubernetes.Interface, developmentMode bool, deploy // If another error occurs, that error is returned. func CreateArangoSyncPod(kubecli kubernetes.Interface, developmentMode bool, deployment APIObject, role, id, podName, image, lifecycleImage string, imagePullPolicy v1.PullPolicy, terminationGracePeriod time.Duration, args []string, env map[string]EnvValue, livenessProbe *HTTPProbeConfig, tolerations []v1.Toleration, serviceAccountName string, - tlsKeyfileSecretName, clientAuthCASecretName, masterJWTSecretName, clusterJWTSecretName, affinityWithRole string) error { + tlsKeyfileSecretName, clientAuthCASecretName, masterJWTSecretName, clusterJWTSecretName, affinityWithRole string, nodeSelector map[string]string) error { // Prepare basic pod - p := newPod(deployment.GetName(), deployment.GetNamespace(), role, id, podName, nil, tolerations, serviceAccountName) + p := newPod(deployment.GetName(), deployment.GetNamespace(), role, id, podName, nil, tolerations, serviceAccountName, nodeSelector) terminationGracePeriodSeconds := int64(math.Ceil(terminationGracePeriod.Seconds())) p.Spec.TerminationGracePeriodSeconds = &terminationGracePeriodSeconds From 2f4f4d8e381a49e14461102f5cd1a03640f4f62f Mon Sep 17 00:00:00 2001 From: lamai93 Date: Tue, 4 Dec 2018 16:21:30 +0100 Subject: [PATCH 2/2] Updated documentation. --- .../Manual/Deployment/Kubernetes/DeploymentResource.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/Manual/Deployment/Kubernetes/DeploymentResource.md b/docs/Manual/Deployment/Kubernetes/DeploymentResource.md index b6f3fb9bb..ed2283873 100644 --- a/docs/Manual/Deployment/Kubernetes/DeploymentResource.md +++ b/docs/Manual/Deployment/Kubernetes/DeploymentResource.md @@ -342,7 +342,7 @@ for `spec.mode: Single` and `2` for `spec.mode: ActiveFailover`). For the `syncworkers` group, it is highly recommended to use the same number as for the `dbservers` group. -### `spec..args: [string]` +### `spec..args: []string` This setting specifies additional commandline arguments passed to all servers of this group. The default value is an empty array. @@ -383,7 +383,7 @@ for each server of this group. This setting is not available for group `coordinators`, `syncmasters` & `syncworkers` because servers in these groups do not need persistent storage. -### `spec..tolerations: [Toleration]` +### `spec..tolerations: []Toleration` This setting specifies the `tolerations` for the `Pod`s created for each server of this group. @@ -395,3 +395,9 @@ By default, suitable tolerations are set for the following keys with the `NoExec - `node.alpha.kubernetes.io/unreachable` (will be removed in future version) For more information on tolerations, consult the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). + +### `spec..nodeSelector: map[string]string` + +This setting specifies a set of labels to be used as `nodeSelector` for Pods of this node. + +For more information on node selectors, consult the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/).