Skip to content

Commit 23e02c7

Browse files
authored
fix(multicluster)!: Link's probeSpec.period should be formatted as duration (#13586)
Before the refactoring from #13420, `link mc link` would generate a Link resource with `probeSpec.period` formatted as duration. After that change, it was generated as an integer and the service mirror was refactored as well to consume that integer and convert it into a duration. If a Link with the old semantics is consumed by a service mirror controller containing that change (or vice-versa) it will error out with "could not parse probe period". This could happen for example when re-linking as part of a multicluster upgrade, when pending the rollout the old controller would consume the upgraded Link. Or for folks upgrading just by bumping the controller image tag and not re-linking (unwise as that may be). This fix consists on: - Updating the Link CRD, constraining `period` to be formatted as duration - Having the `linkerd mc link` command produce a duration value for that period, being lenient to the gateway service annotation `mirror.linkerd.io/probe-period` either using an integer (which it does by default) or a duration - Having the probe worker consume that value as a duration BREAKING CHANGE: this realigns behavior with edge-24.11.8, but Links generated with edge-25.1.1 would be rejected.
1 parent 31a5806 commit 23e02c7

File tree

6 files changed

+19
-3
lines changed

6 files changed

+19
-3
lines changed

multicluster/charts/linkerd-multicluster/templates/link-crd.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ spec:
158158
type: string
159159
period:
160160
description: Interval in between probe requests
161+
format: duration
161162
type: string
162163
port:
163164
description: Port of remote gateway health endpoint

multicluster/cmd/link.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import (
77
"fmt"
88
"os"
99
"path"
10+
"strconv"
1011
"strings"
12+
"time"
1113

1214
"github.com/linkerd/linkerd2/controller/gen/apis/link/v1alpha2"
1315
"github.com/linkerd/linkerd2/multicluster/static"
@@ -599,10 +601,21 @@ func extractProbeSpec(gateway *corev1.Service) (v1alpha2.ProbeSpec, error) {
599601
return v1alpha2.ProbeSpec{}, err
600602
}
601603

604+
// the `mirror.linkerd.io/probe-period` annotation is initialized with a
605+
// default value of "3", but we require a duration-formatted string. So we
606+
// perform the conversion, if required.
607+
period := gateway.Annotations[k8s.GatewayProbePeriod]
608+
if secs, err := strconv.ParseInt(period, 10, 64); err == nil {
609+
dur := time.Duration(secs) * time.Second
610+
period = dur.String()
611+
} else if _, err := time.ParseDuration(period); err != nil {
612+
return v1alpha2.ProbeSpec{}, fmt.Errorf("could not parse probe period: %w", err)
613+
}
614+
602615
return v1alpha2.ProbeSpec{
603616
Path: path,
604617
Port: fmt.Sprintf("%d", port),
605-
Period: gateway.Annotations[k8s.GatewayProbePeriod],
618+
Period: period,
606619
}, nil
607620
}
608621

multicluster/cmd/testdata/install_default.golden

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

multicluster/cmd/testdata/install_ha.golden

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

multicluster/cmd/testdata/install_psp.golden

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

multicluster/service-mirror/probe_worker.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,11 @@ func (pw *ProbeWorker) run() {
7070
pw.log.Error("Probe spec is nil")
7171
return
7272
}
73-
probeTickerPeriodSeconds, err := strconv.ParseInt(pw.probeSpec.Period, 10, 64)
73+
probeTickerPeriod, err := time.ParseDuration(pw.probeSpec.Period)
7474
if err != nil {
7575
pw.log.Errorf("could not parse probe period: %s", err)
7676
return
7777
}
78-
probeTickerPeriod := time.Duration(probeTickerPeriodSeconds) * time.Second
7978
maxJitter := probeTickerPeriod / 10 // max jitter is 10% of period
8079
probeTicker := NewTicker(probeTickerPeriod, maxJitter)
8180
defer probeTicker.Stop()

0 commit comments

Comments
 (0)