Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Kubernetes Tentacle to use ConfigMap for configuration storage #674

Merged
merged 37 commits into from
Jan 22, 2024

Conversation

scme0
Copy link
Collaborator

@scme0 scme0 commented Nov 16, 2023

Background

Part of #project-k8s-agent

To make sure that the Kubernetes Tentacle is able to handle restarts (including when the nfs pod is restarted) we need to update Tentacle to be able to store its configuration into a ConfigMap.

Results

I've add a new IKeyValueStore and IWritableKeyValueStore implementation which stores data in a Kubernetes ConfigMap. It requires a namespace to make sure that each Kubernetes Tentacle in the cluster has a unique ConfigMap.

I've also added an IsRegistered value to the store so that we can skip registration for Kubernetes Tentacles. We also needed to update the configuration process to remove the "remove trust" step which breaks the configuration process if we're already registered. I thought about updating that command to not clear if we're already registered but that seems to defeat the purpose of the command.

How to review this PR

Quality ✔️

Pre-requisites

  • I have read How we use GitHub Issues for help deciding when and where it's appropriate to make an issue.
  • I have considered informing or consulting the right people, according to the ownership map.
  • I have considered appropriate testing for my change.

@scme0
Copy link
Collaborator Author

scme0 commented Nov 16, 2023

[sc-60480]

Copy link

@scme0 scme0 changed the title Spiked out the ability for Tentacle to save changes in a config map in kubernetes Spike: Add ability for Tentacle to save changes to a config map in kubernetes Nov 20, 2023
@scme0 scme0 force-pushed the scme/spikes/store-tentacle-config-in-configmap branch 3 times, most recently from 4240cfa to d8b14a5 Compare January 16, 2024 04:47
@scme0 scme0 changed the title Spike: Add ability for Tentacle to save changes to a config map in kubernetes Update Kubernetes Tentacle to use ConfigMap for configuration storage Jan 16, 2024
@@ -115,9 +115,6 @@ function configureTentacle() {
tentacle configure --instance "$instanceName" --port $internalListeningPort --noListen "False"
fi

echo "Updating trust ..."
tentacle configure --instance "$instanceName" --reset-trust
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This clears out the TrustedOctopusServers which is set when registering. If we skip registering when we've already registered, we effectively clear out the trusted servers and then never replace them meaning a restart of the container fails.

I've remove this because we set the trusted server once and then never clear it. Is this going to cause us issues?

Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than removing it, could we skip some of this configuration if we know it's configured? Or do we need to set some information before we start the tentacle app?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If we just skip it when "isRegistered" is true, the only time it would be executed is when "isRegistered" is false, which is when there would be no trusted servers configured anyway. So I thought it didn't really make sense to have it when running in kubernetes...

@@ -596,9 +596,6 @@ public async Task ShowConfigurationCommandLooksSensibleToHumans(TentacleConfigur
{{
""Thumbprint"": ""{clientAndTentacle.Server.Thumbprint}"",
""CommunicationStyle"": 2,
""KubernetesTentacleCommunicationMode"": {{
""Value"": ""Polling""
}},
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This property only shows up on serialisation if the CommunicationStyle is KubernetesTentacle now.

Copy link
Collaborator Author

@scme0 scme0 Jan 17, 2024

Choose a reason for hiding this comment

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

I did this because the example below is using CommunicationStyle of Passive but the KubernetesTentacleCommunicationMode says Polling which is confusing.

@@ -86,26 +87,14 @@ async Task StartAsync()

internal async Task CollectConfigurationSettings(DictionaryKeyValueStore outputStore)
Copy link
Collaborator Author

@scme0 scme0 Jan 17, 2024

Choose a reason for hiding this comment

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

This method was a PITA - The HomeConfiguration and TentacleConfiguration classes would take a Configuration store (IKeyValueStore) but also an instance selector which is what you're meant to use to get the IKeyValueStore. But it was used to collect the properties to output them in JSON format. It's just very unclear where values are sourced from and where values are set. I think I've made it clearer by using the WriteTo method so we know that the IKeyValueStore from the selector is used to source the data and it's written to the outputStore.

@scme0 scme0 marked this pull request as ready for review January 17, 2024 07:58
@scme0 scme0 force-pushed the scme/spikes/store-tentacle-config-in-configmap branch from c5d8cbf to feb31b8 Compare January 17, 2024 07:58
@scme0 scme0 requested a review from a team as a code owner January 17, 2024 07:58
Copy link
Contributor

@APErebus APErebus left a comment

Choose a reason for hiding this comment

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

Broadly I like the approach, there is just a few things that need cleaning up/addressing

@@ -115,9 +115,6 @@ function configureTentacle() {
tentacle configure --instance "$instanceName" --port $internalListeningPort --noListen "False"
fi

echo "Updating trust ..."
tentacle configure --instance "$instanceName" --reset-trust
Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than removing it, could we skip some of this configuration if we know it's configured? Or do we need to set some information before we start the tentacle app?

@scme0 scme0 requested a review from APErebus January 18, 2024 07:03
Copy link
Contributor

@APErebus APErebus left a comment

Choose a reason for hiding this comment

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

Looks good! Couple of minor things that aren't blocking. The only other piece missing is the setting encryption when ProectionLevel.MachineKey using a value in a secret

Comment on lines 80 to 86
if (appInstance is { instanceName: not null, configurationpath: null } &&
KubernetesConfig.Namespace is {} @namespace)
{
var message = !string.IsNullOrEmpty(instanceName)
? $"The configuration file for instance {instanceName} could not be located at the specified location {configurationPath}. " +
"The file might have been manually removed without properly removing the instance and as such it is still listed as present." +
"The instance must be created again before you can interact with it."
: $"The configuration file at {configurationPath} could not be located at the specified location.";

throw new ControlledFailureException(message);
log.Verbose($"Loading configuration from ConfigMap for namespace {@namespace}");
var configMapWritableStore = configMapStoreFactory.Value;
return (ContributeAdditionalConfiguration(configMapWritableStore), configMapWritableStore);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This check seems weird (checking the namespace). Should we be using the PlatformDetection here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah yep, good call!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed 👍

Task<V1ConfigMap> Patch(string name, IDictionary<string, string> data, CancellationToken cancellationToken);
}

public class KubernetesV1ConfigMapService : KubernetesService, IKubernetesV1ConfigMapService
Copy link
Contributor

Choose a reason for hiding this comment

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

You can drop the V1 here. I doubt we'll need to worry about V2 K8s apis/types for a while

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Removed 👍

@scme0 scme0 mentioned this pull request Jan 19, 2024
3 tasks
scme0 added 23 commits January 19, 2024 15:33
# Conflicts:
#	source/Octopus.Tentacle.Tests/Configuration/ApplicationInstanceSelectorFixture.cs
#	source/Octopus.Tentacle/Configuration/Instances/ConfigMapKeyValueStore.cs
#	source/Octopus.Tentacle/Kubernetes/KubernetesModule.cs
@scme0 scme0 force-pushed the scme/spikes/store-tentacle-config-in-configmap branch from 815a4de to 44f4e32 Compare January 19, 2024 05:05
@scme0 scme0 merged commit 913b571 into main Jan 22, 2024
47 of 48 checks passed
@scme0 scme0 deleted the scme/spikes/store-tentacle-config-in-configmap branch January 22, 2024 00:48
}

AggregatedKeyValueStore ContributeAdditionalConfiguration(XmlFileKeyValueStore writableConfig)
bool ConfigurationFileExists([NotNullWhen(true)] string? configurationPath)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Did these methods need to be pulled out? It may be best to leave what we can alone to avoid any chance of introducing inadvertent changes.

ultra nit: Also since this just throws we could have pulled out the entire if into a single method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants