Skip to content

Commit 371b2af

Browse files
authored
update ring with new ip address when instance is lost, rejoins, but heartbeat is disabled (#6271)
* update ring with new ip address when instance is lost, rejoins, but heartbeat is disabled Signed-off-by: Charlie Le <[email protected]> * Fix lint error (ineffassign) ``` pkg/ring/lifecycler_test.go:728:2: ineffectual assignment to l2 (ineffassign) l2 = startIngesterAndWaitActive("ing2", "0.0.0.0") ^ ``` Signed-off-by: Charlie Le <[email protected]> * Update changelog Signed-off-by: Charlie Le <[email protected]> * simplify logic for handling address change applying feedback from alanprot Signed-off-by: Charlie Le <[email protected]> --------- Signed-off-by: Charlie Le <[email protected]> Signed-off-by: Charlie Le <[email protected]>
1 parent 78a9e35 commit 371b2af

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@
3838
* [ENHANCEMENT] StoreGateway: Add new `cortex_bucket_store_chunk_pool_inuse_bytes` metric to track the usage in chunk pool. #6310
3939
* [BUGFIX] Runtime-config: Handle absolute file paths when working directory is not / #6224
4040
* [BUGFIX] Ruler: Allow rule evaluation to complete during shutdown. #6326
41+
* [BUGFIX] Ring: update ring with new ip address when instance is lost, rejoins, but heartbeat is disabled #6271
4142

4243
## 1.18.1 2024-10-14
4344

4445
* [BUGFIX] Backporting upgrade to go 1.22.7 to patch CVE-2024-34155, CVE-2024-34156, CVE-2024-34158 #6217 #6264
4546

47+
4648
## 1.18.0 2024-09-03
4749

4850
* [CHANGE] Ingester: Remove `-querier.query-store-for-labels-enabled` flag. Querying long-term store for labels is always enabled. #5984

pkg/ring/lifecycler.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,9 @@ func (i *Lifecycler) initRing(ctx context.Context) error {
738738

739739
level.Info(i.logger).Log("msg", "existing entry found in ring", "state", i.GetState(), "tokens", len(tokens), "ring", i.RingName)
740740

741+
// Update the address if it has changed
742+
instanceDesc.Addr = i.Addr
743+
741744
// Update the ring if the instance has been changed and the heartbeat is disabled.
742745
// We dont need to update KV here when heartbeat is enabled as this info will eventually be update on KV
743746
// on the next heartbeat

pkg/ring/lifecycler_test.go

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ func testLifecyclerConfig(ringConfig Config, id string) LifecyclerConfig {
4040
return lifecyclerConfig
4141
}
4242

43+
// testLifecyclerConfigWithAddr creates a LifecyclerConfig with the given address.
44+
// This is useful for testing when we want to set the address to a specific value.
45+
func testLifecyclerConfigWithAddr(ringConfig Config, id string, addr string) LifecyclerConfig {
46+
l := testLifecyclerConfig(ringConfig, id)
47+
l.Addr = addr
48+
return l
49+
}
50+
4351
func checkNormalised(d interface{}, id string) bool {
4452
desc, ok := d.(*Desc)
4553
return ok &&
@@ -644,8 +652,8 @@ func TestRestartIngester_DisabledHeartbeat_unregister_on_shutdown_false(t *testi
644652
}
645653

646654
// Starts Ingester and wait it to became active
647-
startIngesterAndWaitActive := func(ingId string) *Lifecycler {
648-
lifecyclerConfig := testLifecyclerConfig(ringConfig, ingId)
655+
startIngesterAndWaitActive := func(ingId string, addr string) *Lifecycler {
656+
lifecyclerConfig := testLifecyclerConfigWithAddr(ringConfig, ingId, addr)
649657
// Disabling heartBeat and unregister_on_shutdown
650658
lifecyclerConfig.UnregisterOnShutdown = false
651659
lifecyclerConfig.HeartbeatPeriod = 0
@@ -662,10 +670,10 @@ func TestRestartIngester_DisabledHeartbeat_unregister_on_shutdown_false(t *testi
662670
// test if the ingester 2 became active after:
663671
// * Clean Shutdown (LEAVING after shutdown)
664672
// * Crashes while in the PENDING or JOINING state
665-
l1 := startIngesterAndWaitActive("ing1")
673+
l1 := startIngesterAndWaitActive("ing1", "0.0.0.0")
666674
defer services.StopAndAwaitTerminated(context.Background(), l1) //nolint:errcheck
667675

668-
l2 := startIngesterAndWaitActive("ing2")
676+
l2 := startIngesterAndWaitActive("ing2", "0.0.0.0")
669677

670678
ingesters := poll(func(desc *Desc) bool {
671679
return len(desc.Ingesters) == 2 && desc.Ingesters["ing1"].State == ACTIVE && desc.Ingesters["ing2"].State == ACTIVE
@@ -684,7 +692,7 @@ func TestRestartIngester_DisabledHeartbeat_unregister_on_shutdown_false(t *testi
684692
assert.Equal(t, LEAVING, ingesters["ing2"].State)
685693

686694
// Start Ingester2 again - Should flip back to ACTIVE in the ring
687-
l2 = startIngesterAndWaitActive("ing2")
695+
l2 = startIngesterAndWaitActive("ing2", "0.0.0.0")
688696
require.NoError(t, services.StopAndAwaitTerminated(context.Background(), l2))
689697

690698
// Simulate ingester2 crash on startup and left the ring with JOINING state
@@ -698,7 +706,7 @@ func TestRestartIngester_DisabledHeartbeat_unregister_on_shutdown_false(t *testi
698706
})
699707
require.NoError(t, err)
700708

701-
l2 = startIngesterAndWaitActive("ing2")
709+
l2 = startIngesterAndWaitActive("ing2", "0.0.0.0")
702710
require.NoError(t, services.StopAndAwaitTerminated(context.Background(), l2))
703711

704712
// Simulate ingester2 crash on startup and left the ring with PENDING state
@@ -712,7 +720,26 @@ func TestRestartIngester_DisabledHeartbeat_unregister_on_shutdown_false(t *testi
712720
})
713721
require.NoError(t, err)
714722

715-
l2 = startIngesterAndWaitActive("ing2")
723+
l2 = startIngesterAndWaitActive("ing2", "0.0.0.0")
724+
require.NoError(t, services.StopAndAwaitTerminated(context.Background(), l2))
725+
726+
// Simulate ingester2 crashing and left the ring with ACTIVE state, but when it comes up
727+
// it has a different ip address
728+
startIngesterAndWaitActive("ing2", "0.0.0.0")
729+
ingesters = poll(func(desc *Desc) bool {
730+
return desc.Ingesters["ing2"].State == ACTIVE && desc.Ingesters["ing2"].Addr == "0.0.0.0:1"
731+
})
732+
assert.Equal(t, ACTIVE, ingesters["ing2"].State)
733+
assert.Equal(t, "0.0.0.0:1", ingesters["ing2"].Addr)
734+
735+
l2 = startIngesterAndWaitActive("ing2", "1.1.1.1")
736+
737+
// The ring should have the new ip address
738+
ingesters = poll(func(desc *Desc) bool {
739+
return desc.Ingesters["ing2"].State == ACTIVE && desc.Ingesters["ing2"].Addr == "1.1.1.1:1"
740+
})
741+
assert.Equal(t, ACTIVE, ingesters["ing2"].State)
742+
assert.Equal(t, "1.1.1.1:1", ingesters["ing2"].Addr)
716743
require.NoError(t, services.StopAndAwaitTerminated(context.Background(), l2))
717744
}
718745

0 commit comments

Comments
 (0)