Skip to content

Commit fd91700

Browse files
authored
Merge pull request #367 from arangodb/bug-fix/container-resources
Container Resources
2 parents a1904cd + 48bed09 commit fd91700

File tree

5 files changed

+63
-5
lines changed

5 files changed

+63
-5
lines changed

pkg/deployment/images.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ func (ib *imagesBuilder) fetchArangoDBImageIDAndVersion(ctx context.Context, ima
198198
}
199199
}
200200
if err := k8sutil.CreateArangodPod(ib.KubeCli, true, ib.APIObject, role, id, podName, "", image, "", "", ib.Spec.GetImagePullPolicy(), "", false, terminationGracePeriod, args, env, nil, nil, nil,
201-
tolerations, serviceAccountName, "", "", "", nil); err != nil {
201+
tolerations, serviceAccountName, "", "", "", nil, v1.ResourceRequirements{}); err != nil {
202202
log.Debug().Err(err).Msg("Failed to create image ID pod")
203203
return true, maskAny(err)
204204
}

pkg/deployment/reconcile/plan_builder.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,9 +345,31 @@ func podNeedsRotation(log zerolog.Logger, p v1.Pod, apiObject metav1.Object, spe
345345
return true, "ServiceAccountName changed"
346346
}
347347

348+
// Check resource requirements
349+
if resourcesRequireRotation(spec.GetServerGroupSpec(group).Resources, k8sutil.GetArangoDBContainerFromPod(&p).Resources) {
350+
return true, "Resource Requirements changed"
351+
}
352+
348353
return false, ""
349354
}
350355

356+
// resourcesRequireRotation returns true if the resource requirements have changed such that a rotation is required
357+
func resourcesRequireRotation(wanted, given v1.ResourceRequirements) bool {
358+
checkList := func(wanted, given v1.ResourceList) bool {
359+
for k, v := range wanted {
360+
if gv, ok := given[k]; !ok {
361+
return true
362+
} else if v.Cmp(gv) != 0 {
363+
return true
364+
}
365+
}
366+
367+
return false
368+
}
369+
370+
return checkList(wanted.Limits, given.Limits) || checkList(wanted.Requests, given.Requests)
371+
}
372+
351373
// normalizeServiceAccountName replaces default with empty string, otherwise returns the input.
352374
func normalizeServiceAccountName(name string) string {
353375
if name == "default" {

pkg/deployment/resources/pod_creator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, memberID string,
607607
finalizers := r.createPodFinalizers(group)
608608
if err := k8sutil.CreateArangodPod(kubecli, spec.IsDevelopment(), apiObject, role, m.ID, m.PodName, m.PersistentVolumeClaimName, imageInfo.ImageID, lifecycleImage, alpineImage, spec.GetImagePullPolicy(),
609609
engine, requireUUID, terminationGracePeriod, args, env, finalizers, livenessProbe, readinessProbe, tolerations, serviceAccountName, tlsKeyfileSecretName, rocksdbEncryptionSecretName,
610-
clusterJWTSecretName, groupSpec.GetNodeSelector()); err != nil {
610+
clusterJWTSecretName, groupSpec.GetNodeSelector(), groupSpec.Resources); err != nil {
611611
return maskAny(err)
612612
}
613613
log.Debug().Str("pod-name", m.PodName).Msg("Created pod")

pkg/util/k8sutil/images.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,17 @@ func GetArangoDBImageIDFromPod(pod *corev1.Pod) string {
5353
}
5454
return ConvertImageID2Image(rawImageID)
5555
}
56+
57+
// GetArangoDBContainerFromPod returns the ArangoDB container from a pod
58+
func GetArangoDBContainerFromPod(pod *corev1.Pod) corev1.Container {
59+
arangoc := pod.Spec.Containers[0]
60+
if len(pod.Status.ContainerStatuses) > 1 {
61+
for _, container := range pod.Spec.Containers {
62+
if strings.Contains(container.Name, "server") {
63+
arangoc = container
64+
}
65+
}
66+
}
67+
68+
return arangoc
69+
}

pkg/util/k8sutil/pods.go

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,29 @@ func arangodInitContainer(name, id, engine, alpineImage string, requireUUID bool
263263
return c
264264
}
265265

266+
// filterStorageResourceRequirement filters resource requirements for Storage.
267+
func filterStorageResourceRequirement(resources v1.ResourceRequirements) v1.ResourceRequirements {
268+
269+
filterStorage := func(list v1.ResourceList) v1.ResourceList {
270+
newlist := make(v1.ResourceList)
271+
for k, v := range list {
272+
if k == v1.ResourceStorage {
273+
continue
274+
}
275+
newlist[k] = v
276+
}
277+
return newlist
278+
}
279+
280+
return v1.ResourceRequirements{
281+
Limits: filterStorage(resources.Limits),
282+
Requests: filterStorage(resources.Requests),
283+
}
284+
}
285+
266286
// arangodContainer creates a container configured to run `arangod`.
267287
func arangodContainer(image string, imagePullPolicy v1.PullPolicy, args []string, env map[string]EnvValue, livenessProbe *HTTPProbeConfig, readinessProbe *HTTPProbeConfig,
268-
lifecycle *v1.Lifecycle, lifecycleEnvVars []v1.EnvVar) v1.Container {
288+
lifecycle *v1.Lifecycle, lifecycleEnvVars []v1.EnvVar, resources v1.ResourceRequirements) v1.Container {
269289
c := v1.Container{
270290
Command: append([]string{"/usr/sbin/arangod"}, args...),
271291
Name: ServerContainerName,
@@ -279,6 +299,7 @@ func arangodContainer(image string, imagePullPolicy v1.PullPolicy, args []string
279299
Protocol: v1.ProtocolTCP,
280300
},
281301
},
302+
Resources: filterStorageResourceRequirement(resources), // Storage is handled via pvcs
282303
VolumeMounts: arangodVolumeMounts(),
283304
}
284305
for k, v := range env {
@@ -434,7 +455,8 @@ func CreateArangodPod(kubecli kubernetes.Interface, developmentMode bool, deploy
434455
engine string, requireUUID bool, terminationGracePeriod time.Duration,
435456
args []string, env map[string]EnvValue, finalizers []string,
436457
livenessProbe *HTTPProbeConfig, readinessProbe *HTTPProbeConfig, tolerations []v1.Toleration, serviceAccountName string,
437-
tlsKeyfileSecretName, rocksdbEncryptionSecretName string, clusterJWTSecretName string, nodeSelector map[string]string) error {
458+
tlsKeyfileSecretName, rocksdbEncryptionSecretName string, clusterJWTSecretName string, nodeSelector map[string]string,
459+
resources v1.ResourceRequirements) error {
438460
// Prepare basic pod
439461
p := newPod(deployment.GetName(), deployment.GetNamespace(), role, id, podName, finalizers, tolerations, serviceAccountName, nodeSelector)
440462
terminationGracePeriodSeconds := int64(math.Ceil(terminationGracePeriod.Seconds()))
@@ -457,7 +479,7 @@ func CreateArangodPod(kubecli kubernetes.Interface, developmentMode bool, deploy
457479
}
458480

459481
// Add arangod container
460-
c := arangodContainer(image, imagePullPolicy, args, env, livenessProbe, readinessProbe, lifecycle, lifecycleEnvVars)
482+
c := arangodContainer(image, imagePullPolicy, args, env, livenessProbe, readinessProbe, lifecycle, lifecycleEnvVars, resources)
461483
if tlsKeyfileSecretName != "" {
462484
c.VolumeMounts = append(c.VolumeMounts, tlsKeyfileVolumeMounts()...)
463485
}

0 commit comments

Comments
 (0)