Skip to content

Tags: linkerd/linkerd2

Tags

edge-26.8.2

Toggle edge-26.8.2's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
build(deps): gateway api 1.5.1 support via linkerd-kubert 0.27.0 (#15567

)

## kube-rs (a.k.a "kube") 1.1.0 -> 3.1.0

This forces the rest of the workspace along with it:

* k8s-openapi 0.25 -> 0.27
* schemars 0.8 -> 1
* ipnet switches from the `json` feature to `serde` + `schemars1`, since `json` still pulls in schemars 0.8
* chrono is replaced by jiff 0.2 and drops out of the tree entirely, because k8s-openapi 0.27 backs `metav1::Time` with `jiff::Timestamp` instead of `chrono::DateTime<Utc>`

Source changes:

* Timestamps: `creation_timestamp`, `last_transition_time` and the `Route::creation_timestamp` trait method move to `jiff::Timestamp`; `Utc::now()` becomes `Timestamp::now()` and `MIN_UTC`/`MAX_UTC` become `Timestamp::MIN`/`MAX`.
* schemars 1: the hand-written `JsonSchema` impl for `K8sDuration` uses `Cow<'static, str>` for `schema_name`, `inline_schema()` in place of the inverted `is_referenceable()`, and the `json_schema!` macro. The schema is unchanged; the format is still deliberately unset.
* kube 3.x deprecates `kube::error::ErrorResponse` in favor of `kube::core::Status`, and `Error::Api` now carries a `Box<Status>`.

## gateway-api-rs (a.k.a "gateway-api") 0.16.0 -> 0.21.0

This bumps the gateway api spec support from 1.2.1 to 1.5.1
Forced to be bumped in tandem with the kube-rs bump as gateway-api-rs 0.16.0 was pinned to kube-rs 1.1.0

* gateway-api renamed its generated sub-types, so `HTTPRoute*` becomes `HttpRoute*`, `GRPCRoute*` becomes `GrpcRoute*`, and likewise for TCP and TLS. The top-level CRD types keep their original names.
* Several gateway-api fields are no longer optional: `RouteStatusParents::conditions`, `Tls/TcpRouteRules::backend_refs`, and `TlsRouteSpec::hostnames`/`rules`. `Some(..)` wrappers and the matching `.flatten()` calls are dropped, and route spec literals gain the new `use_default_gateways` field.

Note one behavior change the type system forces: now that `RouteStatusParents::conditions` is a plain `Vec`, the `eq_time_insensitive_*_route_parent_statuses` helpers can no longer distinguish an empty condition list from an absent one, so those two cases now compare equal where they previously compared unequal.

### TLSRoute is pinned to `v1alpha2`

gateway-api-rs 0.21 moved its `TLSRoute` binding from `v1alpha2` to `v1`. The other three kinds are unaffected:

| kind      | 0.16.0   | 0.21.0   |
| --------- | -------- | -------- |
| HTTPRoute | v1       | v1       |
| GRPCRoute | v1       | v1       |
| TCPRoute  | v1alpha2 | v1alpha2 |
| TLSRoute  | v1alpha2 | **v1**   |

TLSRoute only graduated to `v1` in Gateway API v1.5:

| bundle | TLSRoute versions served |
| ------ | ------------------------ |
| v1.2.1 | v1alpha2                 |
| v1.3.0 | v1alpha2                 |
| v1.4.0 | v1alpha2, v1alpha3       |
| v1.5.1 | v1, v1alpha2, v1alpha3   |

In order to still support Gateway API v1.2.1, we now have in `policy-controller/k8s/api/src/lib.rs` a local type pinned to `v1alpha2` that shadows the one from the crate's glob import (`v1`). It reuses `TlsRouteSpec`/`TlsRouteStatus` unchanged, so it only overrides the group/version/kind the client addresses. It carries a hand-written `Serialize` because `kube::CustomResource` synthesizes `apiVersion`/`kind` rather than storing them as fields, plus a unit test asserting the pinned version.

### Backwards compatibility

CI now covers v1.2.1/standard as the minimum and v1.5.1/experimental as the maximum, alongside the CLI's vendored CRDs (still bundle v1.1.1; unchanged by this PR).

**No impact:**

* The webhook and RBAC are version-agnostic (`apiVersions: ["*"]`, and `is_kind` compares group and kind only), so TLSRoutes submitted as `v1` on a v1.5 cluster are still validated. Status patches address `v1alpha2`, which is served across the whole range.
* `useDefaultGateways`, new in v1.5 on all four route specs, is `Option` plus `skip_serializing_if`. Linkerd never sets it, and never writes route specs back (only the status subresource), so nothing is stripped from user objects.
* HTTPRoute and GRPCRoute keep their `v1` bindings, valid from v1.2 onward. Their v1.3.0 to v1.5.1 deltas are either additive (CORS and ExternalAuth filters, `requestRedirect.statusCode` widened from `[301, 302]` to `[301, 302, 303, 307, 308]`, GRPCRoute `matches` `maxItems` 8 to 64) or apiserver-side tightening that does not affect decoding.

**Worth watching: decoding is now stricter than the endpoints we address.**

The bindings are generated from the v1.5.1 schemas, so three fields lost their `Option`/`#[serde(default)]` and are mandatory on the wire:

| field                         | kinds              | required upstream since                                  |
| ----------------------------- | ------------------ | -------------------------------------------------------- |
| `status.parents[].conditions` | all four           | v1.5                                                     |
| `spec.rules[].backendRefs`    | TLSRoute, TCPRoute | v1.5                                                     |
| `spec.hostnames`              | TLSRoute           | only in the `v1`/`v1alpha3` schemas, never in `v1alpha2` |

On a pre-v1.5 cluster an object omitting the first two is perfectly legal but no longer decodes. The third is stricter still: `hostnames` is optional in `v1alpha2` in every release, so a TLSRoute without it fails to decode on any cluster in the supported range.

A failing object is logged and skipped rather than killing the watch; the route just never appears in the policy index. Admission is unaffected, since every Gateway API validator is `lenient()` and parse failures are admitted with a warning rather than denied, so there are no new rejections for users.

**Unchanged behaviour worth noting:** Linkerd still implements only the `RequestHeaderModifier`, `ResponseHeaderModifier` and `RequestRedirect` filters, so the new v1.5 `CORS` and `ExternalAuth` HTTPRoute filters are admitted and ignored, the same as the other filter types we do not support.

edge-26.8.1

Toggle edge-26.8.1's commit message

Verified

This tag was signed with the committer’s verified signature.
raykroeker Raymond Kroeker
Edge release for 2026-08-03.

edge-26.7.2

Toggle edge-26.7.2's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
build(deps): bump github.com/mattn/go-runewidth from 0.0.24 to 0.0.27 (

…#15516)

Bumps [github.com/mattn/go-runewidth](https://github.com/mattn/go-runewidth) from 0.0.24 to 0.0.27.
- [Commits](mattn/go-runewidth@v0.0.24...v0.0.27)

---
updated-dependencies:
- dependency-name: github.com/mattn/go-runewidth
  dependency-version: 0.0.27
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

edge-26.7.1

Toggle edge-26.7.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix(destination)!: Disallow requests to undefined service ports (#15473)

#14149 fixed #13922 in the case where no ServiceProfile was defined for the target service.

However, when a ServiceProfile is defined for a service, Linkerd will use the `GetProfile` API instead of the client policy API and requests will be allowed to ports not defined in the service.

Unfortunately, the `GetProfile` API does not have a mechanism to signal that connections should be denied.  Therefore, when we encounter a `GetProfile` request for a port which is not defined on the service, we return an empty `DestinationProfile`. This causes the proxy to fall back to the client policy API which correctly returns a Forbidden filter and causes the connection to be denied.

We also add an integration test for both the ServiceProfile and non-ServiceProfile cases.

Signed-off-by: Alex Leong <[email protected]>

version-2.20

Toggle version-2.20's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
chore(deps): upgrade containerd (#15405)

Signed-off-by: Alex Leong <[email protected]>

edge-26.6.3

Toggle edge-26.6.3's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
proxy: v2.359.0 (#15394)

Release notes: https://github.com/linkerd/linkerd2-proxy/releases/tag/release/v2.359.0

Signed-off-by: l5d-bot <[email protected]>
Co-authored-by: l5d-bot <[email protected]>

edge-26.6.2

Toggle edge-26.6.2's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
chore(build): update golang to 1.25.11 (#15378)

This addresses the following CVEs:
[GO-2026-5039](https://pkg.go.dev/vuln/GO-2026-5039) with alias [CVE-2026-42507](https://www.cve.org/CVERecord?id=CVE-2026-42507)
[GO-2026-5038](https://pkg.go.dev/vuln/GO-2026-5038) with alias [CVE-2026-42504](https://www.cve.org/CVERecord?id=CVE-2026-42504)
[GO-2026-5037](https://pkg.go.dev/vuln/GO-2026-5037) with alias [CVE-2026-27145](https://www.cve.org/CVERecord?id=CVE-2026-27145)

Signed-off-by: Allison Richardet <[email protected]>

edge-26.6.1

Toggle edge-26.6.1's commit message

Verified

This tag was signed with the committer’s verified signature.
raykroeker Raymond Kroeker
Edge release for 2026-06-05.

Verified

This tag was signed with the committer’s verified signature.
arichardet Allison Richardet

edge-26.5.4

Toggle edge-26.5.4's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix(policy-k8s): use correct resource labels in outbound indexer logs (

…#15314)

* fix(policy-k8s): use egress_network label in EgressNetwork indexer logs

The EgressNetwork indexer warning messages used service=name as the
structured log field, which is misleading when the resource being
indexed is an EgressNetwork. Change to egress_network=name in the four
warning lines (accrual config, timeouts, http retry, grpc retry) so
operators see the correct resource type when investigating parse
errors.

Signed-off-by: Alejandro Martinez Ruiz <[email protected]>

* fix(policy-k8s): use labeled fields in outbound indexer debug logs

The Service and EgressNetwork indexer debug!() calls used bare name
and ns fields, while their sibling warn!() calls used explicit
service=name and egress_network=name labels. Use labeled fields in
the debug lines as well so structured log output is consistent within
each indexer implementation.

Signed-off-by: Alejandro Martinez Ruiz <[email protected]>

---------

Signed-off-by: Alejandro Martinez Ruiz <[email protected]>