Skip to content
This repository has been archived by the owner on May 16, 2023. It is now read-only.

Disable service links to prevent very long startup times #542

Merged
merged 2 commits into from
Jun 17, 2020
Merged

Disable service links to prevent very long startup times #542

merged 2 commits into from
Jun 17, 2020

Conversation

floretan
Copy link
Contributor

The Elasticsearch docker image uses environment variables to set Elasticsearch configuration options. Kubernetes automatically adds environment variables for all services in the current namespace.

When trying to debug why Elasticsearch was taking a particularly long time (over 10 minutes) to boot in one of our projects, we noticed that this behavior was dependent on the namespace, even though no quotas or other limitations were in place. The slow start was also accompanied by a high cpu usage for a few minutes, even though Elasticsearch had no indices at that point. We recently had another issue where the massive number of environment variables was causing an issue, and when we disabled the service links with enableServiceLinks: false, the startup behavior went back to normal.

The service links are there to facilitate connecting to other services, but Elasticsearch doesn't usually connect to anything else, so there should be no side effects (when a node connects to another node in the cluster, it uses explicitly declared services, not the automatically generated environment variables).

I'm not sure if this small static configuration changes needs tests, but I'm happy to add them if needed.

  • Chart version not bumped (the versions are all bumped and released at the same time)
  • README.md updated with any new values or changes
  • Updated template tests in ${CHART}/tests/*.py
  • Updated integration tests in ${CHART}/examples/*/test/goss.yaml

@elasticmachine
Copy link
Collaborator

Since this is a community submitted pull request, a Jenkins build has not been kicked off automatically. Can an Elastic organization member please verify the contents of this patch and then kick off a build manually?

@jmlrt jmlrt added the enhancement New feature or request label Mar 25, 2020
@floretan
Copy link
Contributor Author

floretan commented May 5, 2020

This is becoming a blocker for us, it would be very nice to have it merged soon. What would be needed to move forward?

@jmlrt
Copy link
Member

jmlrt commented May 28, 2020

Hi @floretan, thanks for your PR.
Disable service links make sense for Elasticsearch chart.

enableServiceLinks was introduced in K8S 1.13. Elasticsearch chart README indicates that it requires K8S >= 1.8.

This PR should update the README requirements and we need to discuss it internally.

@jmlrt
Copy link
Member

jmlrt commented Jun 15, 2020

Hi @floretan,

After some internal discussion, we would prefer not breaking the current behavior or compatibility with older K8S versions with Elasticsearch chart default values.

Can you create an enableServiceLinks value which would be set to true by default and could be overrided to false?

@@ -22,6 +22,7 @@ spec:
podManagementPolicy: {{ .Values.podManagementPolicy }}
updateStrategy:
type: {{ .Values.updateStrategy }}
enableServiceLinks: false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
enableServiceLinks: false
enableServiceLinks: {{ .Values.enableServiceLinks }}

with enableServiceLinks set to true by default in values.yaml

@floretan
Copy link
Contributor Author

Thank you for taking a closer look at this issue. I hadn't considered the conflict with older kubernetes versions, and I'm glad such attention to details is put into these reviews.

One issue is that enableServiceLinks: true would not be a valid syntax for kubernetes < 1.13, even if this is the default behavior. So far I found three options:

  • I had a look at using semverCompare to check that we have kubernetes 1.13 or greater, but unfortunately I haven't found a way to access the built-in object .Capabilities.KubeVersion or .Capabilities.KubeVersion.Version as a string that works with both helm 2 and helm 3. Some type checking might work, but the logic wouldn't be very pretty.
  • Another solution would be to make .Values.enableServiceLinks a configuration option as suggested, but only output the enableServiceLinks field if the value is false. The default value of true in the chart would also match with the default kubernetes behaviour when the field is not specified. This solution would also not be self-explanatory, and would require some comments to explain why things are done this way.
  • A third option would be to simply ignore the fact that enableServiceLinks: true would not be valid syntax for kubernetes < 1.13. The schema validation was added in helm 3, and the probability that someone is using helm 3 with a kubernetes version as old as 1.12 is pretty small.

Which option would you prefer?

@jmlrt
Copy link
Member

jmlrt commented Jun 15, 2020

One issue is that enableServiceLinks: true would not be a valid syntax for kubernetes < 1.13, even if this is the default behavior. So far I found three options:

Yep, sorry I didn't think about that, when I reviewed it this morning.

  • I had a look at using semverCompare to check that we have kubernetes 1.13 or greater, but unfortunately I haven't found a way to access the built-in object .Capabilities.KubeVersion or .Capabilities.KubeVersion.Version as a string that works with both helm 2 and helm 3. Some type checking might work, but the logic wouldn't be very pretty.

We are using semverCompare with .Capabilities.KubeVersion.GitVersion to check K8S version:

{{- if semverCompare "<1.9-0" .Capabilities.KubeVersion.GitVersion -}}
{{- print "apps/v1beta2" -}}

This is working fine with Helm 2 but we didn't really tested it with Helm 3 yet. I just saw that it was no more in Helm 3 doc and is flagged as deprecated in Helm 3 code.

Note that we officially still don't support Helm 3 so staying with .Capabilities.KubeVersion.GitVersion in this PR is fine anyway and if there is an issue with Helm 3 we'll fix it in the same time that we'll fix all the other .Capabilities.KubeVersion.GitVersion references.

  • Another solution would be to make .Values.enableServiceLinks a configuration option as suggested, but only output the enableServiceLinks field if the value is false. The default value of true in the chart would also match with the default kubernetes behaviour when the field is not specified. This solution would also not be self-explanatory, and would require some comments to explain why things are done this way.

I'm also totally fine with using an enableServiceLinks value set to trueby default and having a conditional block:

{{- if not .Values.enableServiceLinks }}
enableServiceLinks: false
{{- end }}

This wouldn't change the current behavior and we would only need to mention that setting this value false is only with K8S >= 1.13 in the README config description which could avoid adding using .Capabilities.KubeVersion.GitVersion.

Prevents very long startup times when the namespace contains many services. Only valid for kubernetes versions >1.13
@floretan
Copy link
Contributor Author

After taking a closer look at the usage in other charts, I found that .Capabilities.KubeVersion.GitVersion is still the only version that I could find in use despite being deprecated in Helm 3, so I went ahead and updated the PR to include a check using this variable.

This gives us the performance improvement out of the box (as mentioned in the original description, there are no side effects), and prevents adding an unnecessary configuration option.

@floretan floretan requested a review from jmlrt June 16, 2020 15:48
@@ -143,6 +143,9 @@ spec:
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{ toYaml .Values.imagePullSecrets | indent 8 }}
{{- end }}
{{- if semverCompare ">1.13" .Capabilities.KubeVersion.GitVersion }}
enableServiceLinks: false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that we still want it to be configurable and enabled by default in values.yamlin addition of the K8S version check:

Suggested change
enableServiceLinks: false
enableServiceLinks: {{ .Values.enableServiceLinks }}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I made the value configurable and updated both values.yaml and README.md.

@floretan floretan requested a review from jmlrt June 17, 2020 10:40
@jmlrt
Copy link
Member

jmlrt commented Jun 17, 2020

jenkins test this please

Copy link
Member

@jmlrt jmlrt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM⛴

@floretan
Copy link
Contributor Author

The build failure seems to be caused by issues when downloading kubectl, so it's most likely a temporary network access issue rather than an issue with the changes.

@jmlrt
Copy link
Member

jmlrt commented Jun 17, 2020

Yep I'm fine with merging 😄
Thanks for this PR 👍

@jmlrt jmlrt merged commit 00f10e3 into elastic:master Jun 17, 2020
jmlrt pushed a commit that referenced this pull request Jun 17, 2020
…mes (#542)

Prevents very long startup times when the namespace contains many services. Only valid for kubernetes versions >1.13
jmlrt pushed a commit that referenced this pull request Jun 17, 2020
…mes (#542)

Prevents very long startup times when the namespace contains many services. Only valid for kubernetes versions >1.13
jmlrt pushed a commit that referenced this pull request Jun 17, 2020
…mes (#542)

Prevents very long startup times when the namespace contains many services. Only valid for kubernetes versions >1.13
@jmlrt
Copy link
Member

jmlrt commented Jun 17, 2020

backported to 6.8, 7.8and 7.x branches

@jmlrt jmlrt mentioned this pull request Jun 18, 2020
@jmlrt jmlrt mentioned this pull request Oct 28, 2020
This was referenced Nov 17, 2020
@jmlrt jmlrt mentioned this pull request Feb 8, 2021
This was referenced Mar 15, 2021
@jmlrt jmlrt mentioned this pull request May 25, 2021
@jmlrt jmlrt mentioned this pull request Mar 8, 2022
@jmlrt jmlrt mentioned this pull request Apr 21, 2022
This was referenced Sep 14, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request v6.8.11 v7.8.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants