-
Notifications
You must be signed in to change notification settings - Fork 41.1k
SSL config does not watch for symlink file changes #44807
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
Comments
This looks very similar to the situation described in #43989 (comment). |
I think I'm missing something because I cannot reproduce this in our tests. I've updated our @Test
void shouldTriggerOnManyConfigMapUpdates(@TempDir Path tempDir) throws Exception {
Path configMap1 = createConfigMap(tempDir, "secret.txt");
Path configMap2 = createConfigMap(tempDir, "secret.txt");
Path data = tempDir.resolve("..data");
Files.createSymbolicLink(data, configMap1);
Path secretFile = tempDir.resolve("secret.txt");
Files.createSymbolicLink(secretFile, data.resolve("secret.txt"));
try {
WaitingCallback callback = new WaitingCallback();
this.fileWatcher.watch(Set.of(secretFile), callback);
// first update
Files.delete(data);
Files.createSymbolicLink(data, configMap2);
callback.expectChanges();
// reset callback state
callback.reset();
// second update
Files.delete(data);
Files.createSymbolicLink(data, configMap1);
callback.expectChanges();
}
finally {
FileSystemUtils.deleteRecursively(configMap1);
FileSystemUtils.deleteRecursively(configMap2);
Files.delete(data);
Files.delete(secretFile);
}
}
Path createConfigMap(Path parentDir, String secretFileName) throws IOException {
Path configMapFolder = parentDir.resolve(".." + UUID.randomUUID());
Files.createDirectory(configMapFolder);
Path secret = configMapFolder.resolve(secretFileName);
Files.createFile(secret);
return configMapFolder;
}
private static final class WaitingCallback implements Runnable {
private CountDownLatch latch = new CountDownLatch(1);
volatile boolean changed = false;
@Override
public void run() {
this.changed = true;
this.latch.countDown();
}
void expectChanges() throws InterruptedException {
waitForChanges(true);
assertThat(this.changed).as("changed").isTrue();
}
void expectNoChanges() throws InterruptedException {
waitForChanges(false);
assertThat(this.changed).as("changed").isFalse();
}
void waitForChanges(boolean fail) throws InterruptedException {
if (!this.latch.await(5, TimeUnit.SECONDS)) {
if (fail) {
fail("Timeout while waiting for changes");
}
}
}
void reset() {
this.latch = new CountDownLatch(1);
this.changed = false;
}
} Maybe this test is invalid and the file system changes we are simulating are not what they are in reality? Here's what the test is doing:
Can you share a set of bash commands that would simulate the tree structure and runtime filesystem changes that happen? |
From what I could find, Kubernetes uses rename2 to update symbolic links which says: This is what I think is used: https://github.com/kubernetes/kubernetes/blob/71eb04295ad273d6de3bc484f2280c5c3954a4b3/pkg/volume/util/atomic_writer.go#L139 Perhaps this test reproduces the issue?
|
I created a small application, installed cert-manager, and deployed the app to a local Kubernetes (Docker):
The directory structure and logs before running
First run
|
A branch with a test to replicate the issue. The issue does not occur on macOS but fails on both Linux and Windows. |
This branch contains both test and fix. |
This looks great @nosan , thanks a lot for looking into this. |
Thanks, @bclozel |
Thanks again @nosan ! |
Spring-boot version 3.3.9
I have configured a springboot application to use SSL bundles and enabled the hot reload functionality as below:
Certificates are generated by certmanager and stored as kubernetes secrets which are then mounted into the application pods at the volume paths below:
Observation:
/secret
and the application starts up just fine.Question:
Why would the SSL hot reload functionality pick up the first change to the certificate files but not pick up the second one or any further changes?
The text was updated successfully, but these errors were encountered: