diff --git a/.proxy-version b/.proxy-version index e00842e8a6af4..13349f6deaef8 100644 --- a/.proxy-version +++ b/.proxy-version @@ -1 +1 @@ -v2.210.2 +v2.210.3 diff --git a/CHANGES.md b/CHANGES.md index abe4d46e36876..20ca3a1e58bc7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,30 @@ # Changes +## stable-2.14.4 + +This stable release improves observability for the control plane by adding +additional logging to the destination controller and by adding histograms which +can detect Kubernetes informer lag. It also adds the ability to configure +protocol detection. + +* Improved logging in the destination controller by adding the client pod's + name to the logging context. This will improve visibility into the messages + sent and received by the control plane from a specific proxy ([#11532]) +* helm: Introduce configurable values for protocol detection ([#11536]) +* Fixed an issue where the Destination controller could stop processing service + profile updates, if a proxy subscribed to those updates stops reading them; + this is a followup to the issue [#11491] fixed in [stable-2.14.2] ([#11546]) +* In the Destination controller, added informer lag histogram metrics to track + whenever the Kubernetes objects watched by the controller are falling behind + the state in the kube-apiserver ([#11534]) +* proxy: Fix grpc_status metric labels for inbound traffic + +[stable-2.14.2]: https://github.com/linkerd/linkerd2/releases/tag/stable-2.14.2 +[#11532]: https://github.com/linkerd/linkerd2/pull/11532 +[#11536]: https://github.com/linkerd/linkerd2/pull/11536 +[#11546]: https://github.com/linkerd/linkerd2/pull/11546 +[#11534]: https://github.com/linkerd/linkerd2/pull/11534 + ## stable-2.14.3 This stable release fixes an issue in the Destination controller that was diff --git a/charts/linkerd-control-plane/Chart.yaml b/charts/linkerd-control-plane/Chart.yaml index 8d09651e62d4b..63cb0e34dd9b4 100644 --- a/charts/linkerd-control-plane/Chart.yaml +++ b/charts/linkerd-control-plane/Chart.yaml @@ -16,7 +16,7 @@ dependencies: - name: partials version: 0.1.0 repository: file://../partials -version: 1.16.4 +version: 1.16.5 icon: https://linkerd.io/images/logo-only-200h.png maintainers: - name: Linkerd authors diff --git a/charts/linkerd-control-plane/README.md b/charts/linkerd-control-plane/README.md index ca27549e34c40..3f7d938d17ed5 100644 --- a/charts/linkerd-control-plane/README.md +++ b/charts/linkerd-control-plane/README.md @@ -3,7 +3,7 @@ Linkerd gives you observability, reliability, and security for your microservices — with no code change required. -![Version: 1.16.4](https://img.shields.io/badge/Version-1.16.4-informational?style=flat-square) +![Version: 1.16.5](https://img.shields.io/badge/Version-1.16.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: edge-XX.X.X](https://img.shields.io/badge/AppVersion-edge--XX.X.X-informational?style=flat-square) @@ -226,6 +226,8 @@ Kubernetes: `>=1.21.0-0` | proxy.await | bool | `true` | If set, the application container will not start until the proxy is ready | | proxy.cores | int | `0` | The `cpu.limit` and `cores` should be kept in sync. The value of `cores` must be an integer and should typically be set by rounding up from the limit. E.g. if cpu.limit is '1500m', cores should be 2. | | proxy.defaultInboundPolicy | string | "all-unauthenticated" | The default allow policy to use when no `Server` selects a pod. One of: "all-authenticated", "all-unauthenticated", "cluster-authenticated", "cluster-unauthenticated", "deny" | +| proxy.disableInboundProtocolDetectTimeout | bool | `false` | When set to true, disables the protocol detection timeout on the inbound side of the proxy by setting it to a very high value | +| proxy.disableOutboundProtocolDetectTimeout | bool | `false` | When set to true, disables the protocol detection timeout on the outbound side of the proxy by setting it to a very high value | | proxy.enableExternalProfiles | bool | `false` | Enable service profiles for non-Kubernetes services | | proxy.image.name | string | `"cr.l5d.io/linkerd/proxy"` | Docker image for the proxy | | proxy.image.pullPolicy | string | imagePullPolicy | Pull policy for the proxy container Docker image | diff --git a/charts/linkerd-control-plane/values.yaml b/charts/linkerd-control-plane/values.yaml index ee54757be5421..22e45c72fcb09 100644 --- a/charts/linkerd-control-plane/values.yaml +++ b/charts/linkerd-control-plane/values.yaml @@ -115,6 +115,12 @@ proxy: # -- Maximum time allowed before an unused inbound discovery result # is evicted from the cache inboundDiscoveryCacheUnusedTimeout: "90s" + # -- When set to true, disables the protocol detection timeout on the + # outbound side of the proxy by setting it to a very high value + disableOutboundProtocolDetectTimeout: false + # -- When set to true, disables the protocol detection timeout on the inbound + # side of the proxy by setting it to a very high value + disableInboundProtocolDetectTimeout: false image: # -- Docker image for the proxy name: cr.l5d.io/linkerd/proxy diff --git a/charts/partials/templates/_proxy.tpl b/charts/partials/templates/_proxy.tpl index 1f644894b9308..f5dd4c2cd3338 100644 --- a/charts/partials/templates/_proxy.tpl +++ b/charts/partials/templates/_proxy.tpl @@ -57,6 +57,14 @@ env: - name: LINKERD2_PROXY_INBOUND_DISCOVERY_IDLE_TIMEOUT value: {{.Values.proxy.inboundDiscoveryCacheUnusedTimeout | quote}} {{ end -}} +{{ if .Values.proxy.disableOutboundProtocolDetectTimeout -}} +- name: LINKERD2_PROXY_OUTBOUND_DETECT_TIMEOUT + value: "365d" +{{ end -}} +{{ if .Values.proxy.disableInboundProtocolDetectTimeout -}} +- name: LINKERD2_PROXY_INBOUND_DETECT_TIMEOUT + value: "365d" +{{ end -}} - name: LINKERD2_PROXY_CONTROL_LISTEN_ADDR value: 0.0.0.0:{{.Values.proxy.ports.control}} - name: LINKERD2_PROXY_ADMIN_LISTEN_ADDR @@ -92,7 +100,7 @@ env: {{ end -}} - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/doc.go b/cli/cmd/doc.go index 592a9e620c707..20867238085ea 100644 --- a/cli/cmd/doc.go +++ b/cli/cmd/doc.go @@ -252,6 +252,14 @@ func generateAnnotationsDocs() []annotationDoc { Name: k8s.ProxyInboundDiscoveryCacheUnusedTimeout, Description: "Maximum time allowed before an unused inbound discovery result is evicted from the cache. Defaults to `90s`", }, + { + Name: k8s.ProxyDisableOutboundProtocolDetectTimeout, + Description: "When set to true, disables the protocol detection timeout on the outbound side of the proxy by setting it to a very high value", + }, + { + Name: k8s.ProxyDisableInboundProtocolDetectTimeout, + Description: "When set to true, disables the protocol detection timeout on the inbound side of the proxy by setting it to a very high value", + }, { Name: k8s.ProxyWaitBeforeExitSecondsAnnotation, Description: "The proxy sidecar will stay alive for at least the given period after receiving SIGTERM signal from Kubernetes but no longer than pod's `terminationGracePeriodSeconds`. Defaults to `0`", diff --git a/cli/cmd/testdata/inject-filepath/expected/injected_nginx.yaml b/cli/cmd/testdata/inject-filepath/expected/injected_nginx.yaml index ee619c20a066a..a035e8a45f1fd 100644 --- a/cli/cmd/testdata/inject-filepath/expected/injected_nginx.yaml +++ b/cli/cmd/testdata/inject-filepath/expected/injected_nginx.yaml @@ -80,7 +80,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject-filepath/expected/injected_nginx_redis.yaml b/cli/cmd/testdata/inject-filepath/expected/injected_nginx_redis.yaml index 0af6c1d59fc21..2202a79c4b3c1 100644 --- a/cli/cmd/testdata/inject-filepath/expected/injected_nginx_redis.yaml +++ b/cli/cmd/testdata/inject-filepath/expected/injected_nginx_redis.yaml @@ -80,7 +80,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -294,7 +294,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject-filepath/expected/injected_redis.yaml b/cli/cmd/testdata/inject-filepath/expected/injected_redis.yaml index 928046ed3ebe8..7da2ca85f5d2f 100644 --- a/cli/cmd/testdata/inject-filepath/expected/injected_redis.yaml +++ b/cli/cmd/testdata/inject-filepath/expected/injected_redis.yaml @@ -80,7 +80,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_contour.golden.yml b/cli/cmd/testdata/inject_contour.golden.yml index a9ff22f2e1fa0..f8144419e3ee3 100644 --- a/cli/cmd/testdata/inject_contour.golden.yml +++ b/cli/cmd/testdata/inject_contour.golden.yml @@ -88,7 +88,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_already_injected.golden.yml b/cli/cmd/testdata/inject_emojivoto_already_injected.golden.yml index 1901cc986a1d2..3f4085bd42575 100644 --- a/cli/cmd/testdata/inject_emojivoto_already_injected.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_already_injected.golden.yml @@ -82,7 +82,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -307,7 +307,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -532,7 +532,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -757,7 +757,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_deployment.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment.golden.yml index e945992aecd4f..0733e684aea19 100644 --- a/cli/cmd/testdata/inject_emojivoto_deployment.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_deployment.golden.yml @@ -82,7 +82,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_access_log.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_access_log.golden.yml index c7217841315bf..b3904a4c9e139 100644 --- a/cli/cmd/testdata/inject_emojivoto_deployment_access_log.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_deployment_access_log.golden.yml @@ -83,7 +83,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_automountServiceAccountToken_false.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_automountServiceAccountToken_false.golden.yml index 8c7a14c9d2269..4469e39273153 100644 --- a/cli/cmd/testdata/inject_emojivoto_deployment_automountServiceAccountToken_false.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_deployment_automountServiceAccountToken_false.golden.yml @@ -83,7 +83,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_capabilities.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_capabilities.golden.yml index 4cbc27af336c8..6c4417e1f3f44 100644 --- a/cli/cmd/testdata/inject_emojivoto_deployment_capabilities.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_deployment_capabilities.golden.yml @@ -82,7 +82,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_config_overrides.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_config_overrides.golden.yml index efdbce80e7bde..d159bc91db81e 100644 --- a/cli/cmd/testdata/inject_emojivoto_deployment_config_overrides.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_deployment_config_overrides.golden.yml @@ -92,7 +92,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_controller_name.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_controller_name.golden.yml index 5b8ee7724e8f8..a13909723583e 100644 --- a/cli/cmd/testdata/inject_emojivoto_deployment_controller_name.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_deployment_controller_name.golden.yml @@ -82,7 +82,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -307,7 +307,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_debug.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_debug.golden.yml index 0342e61a7558a..b84740dcad488 100644 --- a/cli/cmd/testdata/inject_emojivoto_deployment_debug.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_deployment_debug.golden.yml @@ -83,7 +83,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_empty_resources.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_empty_resources.golden.yml index 75cc47819729f..c23e17076bab5 100644 --- a/cli/cmd/testdata/inject_emojivoto_deployment_empty_resources.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_deployment_empty_resources.golden.yml @@ -82,7 +82,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_hostNetwork_false.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_hostNetwork_false.golden.yml index 9440a525f4ea4..03dfa74d1df6c 100644 --- a/cli/cmd/testdata/inject_emojivoto_deployment_hostNetwork_false.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_deployment_hostNetwork_false.golden.yml @@ -82,7 +82,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_no_init_container.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_no_init_container.golden.yml index ad0a3909d20fe..54097aa8891fe 100644 --- a/cli/cmd/testdata/inject_emojivoto_deployment_no_init_container.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_deployment_no_init_container.golden.yml @@ -82,7 +82,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_opaque_ports.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_opaque_ports.golden.yml index 7b013cf1f101e..ff17eb4d92c75 100644 --- a/cli/cmd/testdata/inject_emojivoto_deployment_opaque_ports.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_deployment_opaque_ports.golden.yml @@ -83,7 +83,7 @@ spec: value: 3000,5000-6000,mysql - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_overridden.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_overridden.golden.yml index 42837477f367a..22e3edaa69fa0 100644 --- a/cli/cmd/testdata/inject_emojivoto_deployment_overridden.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_deployment_overridden.golden.yml @@ -83,7 +83,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_proxyignores.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_proxyignores.golden.yml index 4e7652394546d..c0c8e0ec57fde 100644 --- a/cli/cmd/testdata/inject_emojivoto_deployment_proxyignores.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_deployment_proxyignores.golden.yml @@ -84,7 +84,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_udp.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_udp.golden.yml index 54d223df114e4..699d96513c400 100644 --- a/cli/cmd/testdata/inject_emojivoto_deployment_udp.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_deployment_udp.golden.yml @@ -82,7 +82,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_list.golden.yml b/cli/cmd/testdata/inject_emojivoto_list.golden.yml index 5ec154d408cea..6bb7c4dbbf272 100644 --- a/cli/cmd/testdata/inject_emojivoto_list.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_list.golden.yml @@ -84,7 +84,7 @@ items: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -308,7 +308,7 @@ items: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_list_empty_resources.golden.yml b/cli/cmd/testdata/inject_emojivoto_list_empty_resources.golden.yml index 2ad6ff704ef3c..8667ce0c48157 100644 --- a/cli/cmd/testdata/inject_emojivoto_list_empty_resources.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_list_empty_resources.golden.yml @@ -84,7 +84,7 @@ items: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -308,7 +308,7 @@ items: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_pod.golden.yml b/cli/cmd/testdata/inject_emojivoto_pod.golden.yml index 8333a4fa1f87a..9a16bade90643 100644 --- a/cli/cmd/testdata/inject_emojivoto_pod.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_pod.golden.yml @@ -73,7 +73,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_pod_ingress.golden.yml b/cli/cmd/testdata/inject_emojivoto_pod_ingress.golden.yml index a63a395152ffa..618d5e1d898bf 100644 --- a/cli/cmd/testdata/inject_emojivoto_pod_ingress.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_pod_ingress.golden.yml @@ -76,7 +76,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_pod_proxyignores.golden.yml b/cli/cmd/testdata/inject_emojivoto_pod_proxyignores.golden.yml index 5d574dfcc4ca6..182c240b42b8e 100644 --- a/cli/cmd/testdata/inject_emojivoto_pod_proxyignores.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_pod_proxyignores.golden.yml @@ -75,7 +75,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_pod_with_requests.golden.yml b/cli/cmd/testdata/inject_emojivoto_pod_with_requests.golden.yml index ceb4898c97cb2..c9ebe123ff3a8 100644 --- a/cli/cmd/testdata/inject_emojivoto_pod_with_requests.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_pod_with_requests.golden.yml @@ -77,7 +77,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_emojivoto_statefulset.golden.yml b/cli/cmd/testdata/inject_emojivoto_statefulset.golden.yml index 0fa476c296db5..f789363fde9cd 100644 --- a/cli/cmd/testdata/inject_emojivoto_statefulset.golden.yml +++ b/cli/cmd/testdata/inject_emojivoto_statefulset.golden.yml @@ -83,7 +83,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_gettest_deployment.good.golden.yml b/cli/cmd/testdata/inject_gettest_deployment.good.golden.yml index 0b474ee7aa6aa..45f17705766a7 100644 --- a/cli/cmd/testdata/inject_gettest_deployment.good.golden.yml +++ b/cli/cmd/testdata/inject_gettest_deployment.good.golden.yml @@ -78,7 +78,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -305,7 +305,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/inject_tap_deployment_debug.golden.yml b/cli/cmd/testdata/inject_tap_deployment_debug.golden.yml index b696f8918ffb8..bd88527ee6d27 100644 --- a/cli/cmd/testdata/inject_tap_deployment_debug.golden.yml +++ b/cli/cmd/testdata/inject_tap_deployment_debug.golden.yml @@ -99,7 +99,7 @@ spec: value: 25,587,3306,4444,5432,6379,9300,11211 - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_controlplane_tracing_output.golden b/cli/cmd/testdata/install_controlplane_tracing_output.golden index c1b45513f35b6..1f0d7d1fbaacd 100644 --- a/cli/cmd/testdata/install_controlplane_tracing_output.golden +++ b/cli/cmd/testdata/install_controlplane_tracing_output.golden @@ -616,6 +616,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -952,7 +954,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1278,7 +1280,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1704,7 +1706,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_custom_domain.golden b/cli/cmd/testdata/install_custom_domain.golden index 25f44246e8308..998e7cd69a5fc 100644 --- a/cli/cmd/testdata/install_custom_domain.golden +++ b/cli/cmd/testdata/install_custom_domain.golden @@ -616,6 +616,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -951,7 +953,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1277,7 +1279,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1702,7 +1704,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_custom_registry.golden b/cli/cmd/testdata/install_custom_registry.golden index 0bae6565accfd..80c60d9850767 100644 --- a/cli/cmd/testdata/install_custom_registry.golden +++ b/cli/cmd/testdata/install_custom_registry.golden @@ -616,6 +616,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: my.custom.registry/linkerd-io/proxy @@ -951,7 +953,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1277,7 +1279,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1702,7 +1704,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_default.golden b/cli/cmd/testdata/install_default.golden index 25f44246e8308..998e7cd69a5fc 100644 --- a/cli/cmd/testdata/install_default.golden +++ b/cli/cmd/testdata/install_default.golden @@ -616,6 +616,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -951,7 +953,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1277,7 +1279,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1702,7 +1704,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_default_override_dst_get_nets.golden b/cli/cmd/testdata/install_default_override_dst_get_nets.golden index 13424ec771fa6..5b31c3dafc0bb 100644 --- a/cli/cmd/testdata/install_default_override_dst_get_nets.golden +++ b/cli/cmd/testdata/install_default_override_dst_get_nets.golden @@ -616,6 +616,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -951,7 +953,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1277,7 +1279,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1702,7 +1704,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_default_token.golden b/cli/cmd/testdata/install_default_token.golden index 3cec6f269700d..ad5759933dfb9 100644 --- a/cli/cmd/testdata/install_default_token.golden +++ b/cli/cmd/testdata/install_default_token.golden @@ -616,6 +616,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -951,7 +953,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1268,7 +1270,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1684,7 +1686,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_ha_output.golden b/cli/cmd/testdata/install_ha_output.golden index 69ff8e81a44aa..605dc8fb13bbc 100644 --- a/cli/cmd/testdata/install_ha_output.golden +++ b/cli/cmd/testdata/install_ha_output.golden @@ -643,6 +643,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -1028,7 +1030,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1394,7 +1396,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1855,7 +1857,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_ha_with_overrides_output.golden b/cli/cmd/testdata/install_ha_with_overrides_output.golden index 10a344b2847ab..15b1e479bef3a 100644 --- a/cli/cmd/testdata/install_ha_with_overrides_output.golden +++ b/cli/cmd/testdata/install_ha_with_overrides_output.golden @@ -643,6 +643,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -1028,7 +1030,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1394,7 +1396,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1855,7 +1857,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_heartbeat_disabled_output.golden b/cli/cmd/testdata/install_heartbeat_disabled_output.golden index 769754dc0c3ee..9618f3350b320 100644 --- a/cli/cmd/testdata/install_heartbeat_disabled_output.golden +++ b/cli/cmd/testdata/install_heartbeat_disabled_output.golden @@ -547,6 +547,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -882,7 +884,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1208,7 +1210,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1573,7 +1575,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_helm_control_plane_output.golden b/cli/cmd/testdata/install_helm_control_plane_output.golden index b440c9741803a..b2eccaff5e343 100644 --- a/cli/cmd/testdata/install_helm_control_plane_output.golden +++ b/cli/cmd/testdata/install_helm_control_plane_output.golden @@ -593,6 +593,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -924,7 +926,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1252,7 +1254,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1681,7 +1683,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_helm_control_plane_output_ha.golden b/cli/cmd/testdata/install_helm_control_plane_output_ha.golden index 2cd6a3cc30a35..67f8b84599bf6 100644 --- a/cli/cmd/testdata/install_helm_control_plane_output_ha.golden +++ b/cli/cmd/testdata/install_helm_control_plane_output_ha.golden @@ -620,6 +620,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -1001,7 +1003,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1369,7 +1371,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1834,7 +1836,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_helm_output_ha_labels.golden b/cli/cmd/testdata/install_helm_output_ha_labels.golden index 9acc79073a3e9..3bbc907fe1f1b 100644 --- a/cli/cmd/testdata/install_helm_output_ha_labels.golden +++ b/cli/cmd/testdata/install_helm_output_ha_labels.golden @@ -624,6 +624,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -1009,7 +1011,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1381,7 +1383,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1854,7 +1856,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_helm_output_ha_namespace_selector.golden b/cli/cmd/testdata/install_helm_output_ha_namespace_selector.golden index e65be022cb6de..bd624cb3c967c 100644 --- a/cli/cmd/testdata/install_helm_output_ha_namespace_selector.golden +++ b/cli/cmd/testdata/install_helm_output_ha_namespace_selector.golden @@ -615,6 +615,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -991,7 +993,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1359,7 +1361,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1824,7 +1826,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_no_init_container.golden b/cli/cmd/testdata/install_no_init_container.golden index 7d3c8d811e4b9..44372e6c6eb0e 100644 --- a/cli/cmd/testdata/install_no_init_container.golden +++ b/cli/cmd/testdata/install_no_init_container.golden @@ -616,6 +616,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -951,7 +953,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1271,7 +1273,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1690,7 +1692,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_output.golden b/cli/cmd/testdata/install_output.golden index b14675bee51ae..9df47990e74f1 100644 --- a/cli/cmd/testdata/install_output.golden +++ b/cli/cmd/testdata/install_output.golden @@ -596,6 +596,8 @@ data: await: true capabilities: null defaultInboundPolicy: default-allow-policy + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: ProxyImageName @@ -923,7 +925,7 @@ spec: value: "25,443,587,3306,5432,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1246,7 +1248,7 @@ spec: value: "25,443,587,3306,5432,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1675,7 +1677,7 @@ spec: value: "25,443,587,3306,5432,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_proxy_ignores.golden b/cli/cmd/testdata/install_proxy_ignores.golden index e486aa5b3b43b..bc723c1f92be1 100644 --- a/cli/cmd/testdata/install_proxy_ignores.golden +++ b/cli/cmd/testdata/install_proxy_ignores.golden @@ -616,6 +616,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -951,7 +953,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1277,7 +1279,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1702,7 +1704,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/cli/cmd/testdata/install_values_file.golden b/cli/cmd/testdata/install_values_file.golden index 0717eb8e646d4..92495abe17175 100644 --- a/cli/cmd/testdata/install_values_file.golden +++ b/cli/cmd/testdata/install_values_file.golden @@ -616,6 +616,8 @@ data: await: true capabilities: null defaultInboundPolicy: all-unauthenticated + disableInboundProtocolDetectTimeout: false + disableOutboundProtocolDetectTimeout: false enableExternalProfiles: false image: name: cr.l5d.io/linkerd/proxy @@ -951,7 +953,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1277,7 +1279,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: @@ -1702,7 +1704,7 @@ spec: value: "25,587,3306,4444,5432,6379,9300,11211" - name: LINKERD2_PROXY_DESTINATION_CONTEXT value: | - {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)"} + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} - name: _pod_sa valueFrom: fieldRef: diff --git a/controller/api/destination/destination_fuzzer.go b/controller/api/destination/destination_fuzzer.go index beba1adc6b766..1369581ef22d7 100644 --- a/controller/api/destination/destination_fuzzer.go +++ b/controller/api/destination/destination_fuzzer.go @@ -91,12 +91,11 @@ func FuzzProfileTranslatorUpdate(data []byte) int { return 0 } t := &testing.T{} - mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: []*pb.DestinationProfile{}} + mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: make(chan *pb.DestinationProfile, 50)} - translator := &profileTranslator{ - stream: mockGetProfileServer, - log: logging.WithField("test", t.Name()), - } + translator := newProfileTranslator(mockGetProfileServer, logging.WithField("test", t.Name()), "foo.bar.svc.cluster.local", 80, nil) + translator.Start() + defer translator.Stop() translator.Update(profile) return 1 } diff --git a/controller/api/destination/endpoint_profile_translator.go b/controller/api/destination/endpoint_profile_translator.go index 3f1fa90ec8d8c..8ca312b1563d8 100644 --- a/controller/api/destination/endpoint_profile_translator.go +++ b/controller/api/destination/endpoint_profile_translator.go @@ -6,7 +6,7 @@ import ( pb "github.com/linkerd/linkerd2-proxy-api/go/destination" "github.com/linkerd/linkerd2/controller/api/destination/watcher" "github.com/linkerd/linkerd2/controller/k8s" - log "github.com/sirupsen/logrus" + logging "github.com/sirupsen/logrus" ) type endpointProfileTranslator struct { @@ -19,7 +19,7 @@ type endpointProfileTranslator struct { k8sAPI *k8s.API metadataAPI *k8s.MetadataAPI - log *log.Entry + log *logging.Entry } // newEndpointProfileTranslator translates pod updates and protocol updates to @@ -29,6 +29,7 @@ func newEndpointProfileTranslator( controllerNS, identityTrustDomain string, defaultOpaquePorts map[uint32]struct{}, + log *logging.Entry, stream pb.Destination_GetProfileServer, k8sAPI *k8s.API, metadataAPI *k8s.MetadataAPI, diff --git a/controller/api/destination/profile_translator.go b/controller/api/destination/profile_translator.go index 1342dc4334025..05471b51d5afb 100644 --- a/controller/api/destination/profile_translator.go +++ b/controller/api/destination/profile_translator.go @@ -11,6 +11,8 @@ import ( sp "github.com/linkerd/linkerd2/controller/gen/apis/serviceprofile/v1alpha2" "github.com/linkerd/linkerd2/pkg/profiles" "github.com/linkerd/linkerd2/pkg/util" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" logging "github.com/sirupsen/logrus" ) @@ -18,22 +20,90 @@ const millisPerDecimilli = 10 // implements the ProfileUpdateListener interface type profileTranslator struct { - stream pb.Destination_GetProfileServer - log *logging.Entry fullyQualifiedName string port uint32 + + stream pb.Destination_GetProfileServer + endStream chan struct{} + log *logging.Entry + overflowCounter prometheus.Counter + + updates chan *sp.ServiceProfile + stop chan struct{} } -func newProfileTranslator(stream pb.Destination_GetProfileServer, log *logging.Entry, fqn string, port uint32) *profileTranslator { +var profileUpdatesQueueOverflowCounter = promauto.NewCounterVec( + prometheus.CounterOpts{ + Name: "profile_updates_queue_overflow", + Help: "A counter incremented whenever the profile updates queue overflows", + }, + []string{ + "fqn", + "port", + }, +) + +func newProfileTranslator(stream pb.Destination_GetProfileServer, log *logging.Entry, fqn string, port uint32, endStream chan struct{}) *profileTranslator { return &profileTranslator{ - stream: stream, - log: log.WithField("component", "profile-translator"), fullyQualifiedName: fqn, port: port, + + stream: stream, + endStream: endStream, + log: log.WithField("component", "profile-translator"), + overflowCounter: profileUpdatesQueueOverflowCounter.With(prometheus.Labels{"fqn": fqn, "port": fmt.Sprintf("%d", port)}), + updates: make(chan *sp.ServiceProfile, updateQueueCapacity), + stop: make(chan struct{}), } } +// Update is called from a client-go informer callback and therefore must not +// We enqueue an update in a channel so that it can be processed asyncronously. +// To ensure that enqueuing does not block, we first check to see if there is +// capacity in the buffered channel. If there is not, we drop the update and +// signal to the stream that it has fallen too far behind and should be closed. func (pt *profileTranslator) Update(profile *sp.ServiceProfile) { + select { + case pt.updates <- profile: + // Update has been successfully enqueued. + default: + // We are unable to enqueue because the channel does not have capacity. + // The stream has fallen too far behind and should be closed. + pt.overflowCounter.Inc() + select { + case <-pt.endStream: + // The endStream channel has already been closed so no action is + // necessary. + default: + pt.log.Error("profile update queue full; aborting stream") + close(pt.endStream) + } + } +} + +// Start initiates a goroutine which processes update events off of the +// profileTranslator's internal queue and sends to the grpc stream as +// appropriate. The goroutine calls non-thread-safe Send, therefore Start must +// not be called more than once. +func (pt *profileTranslator) Start() { + go func() { + for { + select { + case update := <-pt.updates: + pt.update(update) + case <-pt.stop: + return + } + } + }() +} + +// Stop terminates the goroutine started by Start. +func (pt *profileTranslator) Stop() { + close(pt.stop) +} + +func (pt *profileTranslator) update(profile *sp.ServiceProfile) { if profile == nil { pt.log.Debugf("Sending default profile") if err := pt.stream.Send(pt.defaultServiceProfile()); err != nil { diff --git a/controller/api/destination/profile_translator_test.go b/controller/api/destination/profile_translator_test.go index 2f926b82a35db..17612dd5a6b91 100644 --- a/controller/api/destination/profile_translator_test.go +++ b/controller/api/destination/profile_translator_test.go @@ -421,52 +421,49 @@ var ( func TestProfileTranslator(t *testing.T) { t.Run("Sends update", func(t *testing.T) { - mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: []*pb.DestinationProfile{}} + mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: make(chan *pb.DestinationProfile, 50)} - translator := &profileTranslator{ - stream: mockGetProfileServer, - log: logging.WithField("test", t.Name()), - } + translator := newProfileTranslator(mockGetProfileServer, logging.WithField("test", t.Name()), "", 80, nil) + translator.Start() + defer translator.Stop() translator.Update(profile) - numProfiles := len(mockGetProfileServer.profilesReceived) - if numProfiles != 1 { - t.Fatalf("Expecting [1] profile, got [%d]. Updates: %v", numProfiles, mockGetProfileServer.profilesReceived) - } - actualPbProfile := mockGetProfileServer.profilesReceived[0] + actualPbProfile := <-mockGetProfileServer.profilesReceived if !proto.Equal(actualPbProfile, pbProfile) { t.Fatalf("Expected profile sent to be [%v] but was [%v]", pbProfile, actualPbProfile) } + numProfiles := len(mockGetProfileServer.profilesReceived) + 1 + if numProfiles != 1 { + t.Fatalf("Expecting [1] profile, got [%d]. Updates: %v", numProfiles, mockGetProfileServer.profilesReceived) + } }) t.Run("Request match with more than one field becomes ALL", func(t *testing.T) { - mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: []*pb.DestinationProfile{}} + mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: make(chan *pb.DestinationProfile, 50)} - translator := &profileTranslator{ - stream: mockGetProfileServer, - log: logging.WithField("test", t.Name()), - } + translator := newProfileTranslator(mockGetProfileServer, logging.WithField("test", t.Name()), "", 80, nil) + translator.Start() + defer translator.Stop() translator.Update(multipleRequestMatches) - numProfiles := len(mockGetProfileServer.profilesReceived) - if numProfiles != 1 { - t.Fatalf("Expecting [1] profiles, got [%d]. Updates: %v", numProfiles, mockGetProfileServer.profilesReceived) - } - actualPbProfile := mockGetProfileServer.profilesReceived[0] + actualPbProfile := <-mockGetProfileServer.profilesReceived if !proto.Equal(actualPbProfile, pbRequestMatchAll) { t.Fatalf("Expected profile sent to be [%v] but was [%v]", pbRequestMatchAll, actualPbProfile) } + numProfiles := len(mockGetProfileServer.profilesReceived) + 1 + if numProfiles != 1 { + t.Fatalf("Expecting [1] profiles, got [%d]. Updates: %v", numProfiles, mockGetProfileServer.profilesReceived) + } }) t.Run("Ignores request match without any fields", func(t *testing.T) { - mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: []*pb.DestinationProfile{}} + mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: make(chan *pb.DestinationProfile, 50)} - translator := &profileTranslator{ - stream: mockGetProfileServer, - log: logging.WithField("test", t.Name()), - } + translator := newProfileTranslator(mockGetProfileServer, logging.WithField("test", t.Name()), "", 80, nil) + translator.Start() + defer translator.Stop() translator.Update(notEnoughRequestMatches) @@ -477,32 +474,30 @@ func TestProfileTranslator(t *testing.T) { }) t.Run("Response match with more than one field becomes ALL", func(t *testing.T) { - mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: []*pb.DestinationProfile{}} + mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: make(chan *pb.DestinationProfile, 50)} - translator := &profileTranslator{ - stream: mockGetProfileServer, - log: logging.WithField("test", t.Name()), - } + translator := newProfileTranslator(mockGetProfileServer, logging.WithField("test", t.Name()), "", 80, nil) + translator.Start() + defer translator.Stop() translator.Update(multipleResponseMatches) - numProfiles := len(mockGetProfileServer.profilesReceived) - if numProfiles != 1 { - t.Fatalf("Expecting [1] profiles, got [%d]. Updates: %v", numProfiles, mockGetProfileServer.profilesReceived) - } - actualPbProfile := mockGetProfileServer.profilesReceived[0] + actualPbProfile := <-mockGetProfileServer.profilesReceived if !proto.Equal(actualPbProfile, pbResponseMatchAll) { t.Fatalf("Expected profile sent to be [%v] but was [%v]", pbResponseMatchAll, actualPbProfile) } + numProfiles := len(mockGetProfileServer.profilesReceived) + 1 + if numProfiles != 1 { + t.Fatalf("Expecting [1] profiles, got [%d]. Updates: %v", numProfiles, mockGetProfileServer.profilesReceived) + } }) t.Run("Ignores response match without any fields", func(t *testing.T) { - mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: []*pb.DestinationProfile{}} + mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: make(chan *pb.DestinationProfile, 50)} - translator := &profileTranslator{ - stream: mockGetProfileServer, - log: logging.WithField("test", t.Name()), - } + translator := newProfileTranslator(mockGetProfileServer, logging.WithField("test", t.Name()), "", 80, nil) + translator.Start() + defer translator.Stop() translator.Update(notEnoughResponseMatches) @@ -513,12 +508,11 @@ func TestProfileTranslator(t *testing.T) { }) t.Run("Ignores response match with invalid status range", func(t *testing.T) { - mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: []*pb.DestinationProfile{}} + mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: make(chan *pb.DestinationProfile, 50)} - translator := &profileTranslator{ - stream: mockGetProfileServer, - log: logging.WithField("test", t.Name()), - } + translator := newProfileTranslator(mockGetProfileServer, logging.WithField("test", t.Name()), "", 80, nil) + translator.Start() + defer translator.Stop() translator.Update(invalidStatusRange) @@ -529,58 +523,57 @@ func TestProfileTranslator(t *testing.T) { }) t.Run("Sends update for one sided status range", func(t *testing.T) { - mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: []*pb.DestinationProfile{}} + mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: make(chan *pb.DestinationProfile, 50)} - translator := &profileTranslator{ - stream: mockGetProfileServer, - log: logging.WithField("test", t.Name()), - } + translator := newProfileTranslator(mockGetProfileServer, logging.WithField("test", t.Name()), "", 80, nil) + translator.Start() + defer translator.Stop() translator.Update(oneSidedStatusRange) - numProfiles := len(mockGetProfileServer.profilesReceived) + <-mockGetProfileServer.profilesReceived + + numProfiles := len(mockGetProfileServer.profilesReceived) + 1 if numProfiles != 1 { t.Fatalf("Expecting [1] profile, got [%d]. Updates: %v", numProfiles, mockGetProfileServer.profilesReceived) } }) t.Run("Sends empty update", func(t *testing.T) { - mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: []*pb.DestinationProfile{}} + mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: make(chan *pb.DestinationProfile, 50)} - translator := &profileTranslator{ - stream: mockGetProfileServer, - log: logging.WithField("test", t.Name()), - } + translator := newProfileTranslator(mockGetProfileServer, logging.WithField("test", t.Name()), "", 80, nil) + translator.Start() + defer translator.Stop() translator.Update(nil) - numProfiles := len(mockGetProfileServer.profilesReceived) - if numProfiles != 1 { - t.Fatalf("Expecting [1] profile, got [%d]. Updates: %v", numProfiles, mockGetProfileServer.profilesReceived) - } - actualPbProfile := mockGetProfileServer.profilesReceived[0] + actualPbProfile := <-mockGetProfileServer.profilesReceived if !proto.Equal(actualPbProfile, defaultPbProfile) { t.Fatalf("Expected profile sent to be [%v] but was [%v]", defaultPbProfile, actualPbProfile) } + numProfiles := len(mockGetProfileServer.profilesReceived) + 1 + if numProfiles != 1 { + t.Fatalf("Expecting [1] profile, got [%d]. Updates: %v", numProfiles, mockGetProfileServer.profilesReceived) + } }) t.Run("Sends update with custom timeout", func(t *testing.T) { - mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: []*pb.DestinationProfile{}} + mockGetProfileServer := &mockDestinationGetProfileServer{profilesReceived: make(chan *pb.DestinationProfile, 50)} - translator := &profileTranslator{ - stream: mockGetProfileServer, - log: logging.WithField("test", t.Name()), - } + translator := newProfileTranslator(mockGetProfileServer, logging.WithField("test", t.Name()), "", 80, nil) + translator.Start() + defer translator.Stop() translator.Update(profileWithTimeout) - numProfiles := len(mockGetProfileServer.profilesReceived) - if numProfiles != 1 { - t.Fatalf("Expecting [1] profile, got [%d]. Updates: %v", numProfiles, mockGetProfileServer.profilesReceived) - } - actualPbProfile := mockGetProfileServer.profilesReceived[0] + actualPbProfile := <-mockGetProfileServer.profilesReceived if !proto.Equal(actualPbProfile, pbProfileWithTimeout) { t.Fatalf("Expected profile sent to be [%v] but was [%v]", pbProfileWithTimeout, actualPbProfile) } + numProfiles := len(mockGetProfileServer.profilesReceived) + 1 + if numProfiles != 1 { + t.Fatalf("Expecting [1] profile, got [%d]. Updates: %v", numProfiles, mockGetProfileServer.profilesReceived) + } }) } diff --git a/controller/api/destination/server.go b/controller/api/destination/server.go index 2fb637b416567..4fadda88a6bce 100644 --- a/controller/api/destination/server.go +++ b/controller/api/destination/server.go @@ -126,21 +126,23 @@ func NewServer( } func (s *server) Get(dest *pb.GetDestination, stream pb.Destination_GetServer) error { - client, _ := peer.FromContext(stream.Context()) log := s.log + + client, _ := peer.FromContext(stream.Context()) if client != nil { - log = s.log.WithField("remote", client.Addr) + log = log.WithField("remote", client.Addr) } - log.Debugf("Get %s", dest.GetPath()) - - streamEnd := make(chan struct{}) var token contextToken if dest.GetContextToken() != "" { + log.Debugf("Dest token: %q", dest.GetContextToken()) token = s.parseContextToken(dest.GetContextToken()) - log.Debugf("Dest token: %v", token) + log = log.WithFields(logging.Fields{"context-pod": token.Pod, "context-ns": token.Ns}) } + log.Debugf("Get %s", dest.GetPath()) + + streamEnd := make(chan struct{}) // The host must be fully-qualified or be an IP address. host, port, err := getHostAndPort(dest.GetPath()) if err != nil { @@ -253,11 +255,20 @@ func (s *server) Get(dest *pb.GetDestination, stream pb.Destination_GetServer) e func (s *server) GetProfile(dest *pb.GetDestination, stream pb.Destination_GetProfileServer) error { log := s.log + client, _ := peer.FromContext(stream.Context()) if client != nil { log = log.WithField("remote", client.Addr) } - log.Debugf("Getting profile for %s with token %q", dest.GetPath(), dest.GetContextToken()) + + var token contextToken + if dest.GetContextToken() != "" { + log.Debugf("Dest token: %q", dest.GetContextToken()) + token = s.parseContextToken(dest.GetContextToken()) + log = log.WithFields(logging.Fields{"context-pod": token.Pod, "context-ns": token.Ns}) + } + + log.Debugf("Getting profile for %s", dest.GetPath()) // The host must be fully-qualified or be an IP address. host, port, err := getHostAndPort(dest.GetPath()) @@ -267,16 +278,17 @@ func (s *server) GetProfile(dest *pb.GetDestination, stream pb.Destination_GetPr } if ip := net.ParseIP(host); ip != nil { - return s.getProfileByIP(dest.GetContextToken(), ip, port, stream) + return s.getProfileByIP(token, ip, port, log, stream) } - return s.getProfileByName(dest.GetContextToken(), host, port, stream) + return s.getProfileByName(token, host, port, log, stream) } func (s *server) getProfileByIP( - token string, + token contextToken, ip net.IP, port uint32, + log *logging.Entry, stream pb.Destination_GetProfileServer, ) error { // Get the service that the IP currently maps to. @@ -286,16 +298,18 @@ func (s *server) getProfileByIP( } if svcID == nil { - return s.subscribeToEndpointProfile(nil, "", ip.String(), port, stream) + return s.subscribeToEndpointProfile(nil, "", ip.String(), port, log, stream) } fqn := fmt.Sprintf("%s.%s.svc.%s", svcID.Name, svcID.Namespace, s.clusterDomain) - return s.subscribeToServiceProfile(*svcID, token, fqn, port, stream) + return s.subscribeToServiceProfile(*svcID, token, fqn, port, log, stream) } func (s *server) getProfileByName( - token, host string, + token contextToken, + host string, port uint32, + log *logging.Entry, stream pb.Destination_GetProfileServer, ) error { service, hostname, err := parseK8sServiceName(host, s.clusterDomain) @@ -308,10 +322,10 @@ func (s *server) getProfileByName( // name. When we fetch the profile using a pod's DNS name, we want to // return an endpoint in the profile response. if hostname != "" { - return s.subscribeToEndpointProfile(&service, hostname, "", port, stream) + return s.subscribeToEndpointProfile(&service, hostname, "", port, log, stream) } - return s.subscribeToServiceProfile(service, token, host, port, stream) + return s.subscribeToServiceProfile(service, token, host, port, log, stream) } // Resolves a profile for a service, sending updates to the provided stream. @@ -319,21 +333,26 @@ func (s *server) getProfileByName( // This function does not return until the stream is closed. func (s *server) subscribeToServiceProfile( service watcher.ID, - token, fqn string, + token contextToken, + fqn string, port uint32, + log *logging.Entry, stream pb.Destination_GetProfileServer, ) error { - log := s.log. + log = log. WithField("ns", service.Namespace). WithField("svc", service.Name). WithField("port", port) canceled := stream.Context().Done() + streamEnd := make(chan struct{}) // We build up the pipeline of profile updaters backwards, starting from // the translator which takes profile updates, translates them to protobuf // and pushes them onto the gRPC stream. - translator := newProfileTranslator(stream, log, fqn, port) + translator := newProfileTranslator(stream, log, fqn, port, streamEnd) + translator.Start() + defer translator.Stop() // The opaque ports adaptor merges profile updates with service opaque // port annotation updates; it then publishes the result to the traffic @@ -359,11 +378,10 @@ func (s *server) subscribeToServiceProfile( // The primary lookup uses the context token to determine the requester's // namespace. If there's no namespace in the token, start a single // subscription. - tok := s.parseContextToken(token) - if tok.Ns == "" { - return s.subscribeToServiceWithoutContext(fqn, listener, canceled, log) + if token.Ns == "" { + return s.subscribeToServiceWithoutContext(fqn, listener, canceled, log, streamEnd) } - return s.subscribeToServicesWithContext(fqn, tok, listener, canceled, log) + return s.subscribeToServicesWithContext(fqn, token, listener, canceled, log, streamEnd) } // subscribeToServiceWithContext establishes two profile watches: a "backup" @@ -378,6 +396,7 @@ func (s *server) subscribeToServicesWithContext( listener watcher.ProfileUpdateListener, canceled <-chan struct{}, log *logging.Entry, + streamEnd <-chan struct{}, ) error { // We ned to support two subscriptions: // - First, a backup subscription that assumes the context of the server @@ -415,7 +434,9 @@ func (s *server) subscribeToServicesWithContext( select { case <-s.shutdown: case <-canceled: - log.Debug("Cancelled") + log.Debugf("GetProfile %s cancelled", fqn) + case <-streamEnd: + log.Errorf("GetProfile %s stream aborted", fqn) } return nil } @@ -425,8 +446,9 @@ func (s *server) subscribeToServicesWithContext( func (s *server) subscribeToServiceWithoutContext( fqn string, listener watcher.ProfileUpdateListener, - cancel <-chan struct{}, + canceled <-chan struct{}, log *logging.Entry, + streamEnd <-chan struct{}, ) error { id, err := profileID(fqn, contextToken{}, s.clusterDomain) if err != nil { @@ -442,8 +464,10 @@ func (s *server) subscribeToServiceWithoutContext( select { case <-s.shutdown: - case <-cancel: - log.Debug("Cancelled") + case <-canceled: + log.Debugf("GetProfile %s cancelled", fqn) + case <-streamEnd: + log.Errorf("GetProfile %s stream aborted", fqn) } return nil } @@ -457,6 +481,7 @@ func (s *server) subscribeToEndpointProfile( hostname, ip string, port uint32, + log *logging.Entry, stream pb.Destination_GetProfileServer, ) error { translator := newEndpointProfileTranslator( @@ -464,6 +489,7 @@ func (s *server) subscribeToEndpointProfile( s.controllerNS, s.identityTrustDomain, s.defaultOpaquePorts, + log, stream, s.k8sAPI, s.metadataAPI, @@ -521,6 +547,7 @@ func getSvcID(k8sAPI *k8s.API, clusterIP string, log *logging.Entry) (*watcher.S type contextToken struct { Ns string `json:"ns,omitempty"` NodeName string `json:"nodeName,omitempty"` + Pod string `json:"pod,omitempty"` } func (s *server) parseContextToken(token string) contextToken { diff --git a/controller/api/destination/test_util.go b/controller/api/destination/test_util.go index 1ab71eb1ad5ff..df79bab9a8249 100644 --- a/controller/api/destination/test_util.go +++ b/controller/api/destination/test_util.go @@ -563,11 +563,11 @@ func (m *mockDestinationGetServer) Send(update *pb.Update) error { type mockDestinationGetProfileServer struct { util.MockServerStream - profilesReceived []*pb.DestinationProfile + profilesReceived chan *pb.DestinationProfile } func (m *mockDestinationGetProfileServer) Send(profile *pb.DestinationProfile) error { - m.profilesReceived = append(m.profilesReceived, profile) + m.profilesReceived <- profile return nil } diff --git a/controller/api/destination/watcher/endpoints_watcher.go b/controller/api/destination/watcher/endpoints_watcher.go index 4afe6c89627bc..2fffb46a9b8f9 100644 --- a/controller/api/destination/watcher/endpoints_watcher.go +++ b/controller/api/destination/watcher/endpoints_watcher.go @@ -8,6 +8,7 @@ import ( "strconv" "strings" "sync" + "time" "github.com/linkerd/linkerd2/controller/gen/apis/server/v1beta1" "github.com/linkerd/linkerd2/controller/k8s" @@ -168,7 +169,7 @@ func NewEndpointsWatcher(k8sAPI *k8s.API, metadataAPI *k8s.MetadataAPI, log *log ew.svcHandle, err = k8sAPI.Svc().Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: ew.addService, DeleteFunc: ew.deleteService, - UpdateFunc: func(_, obj interface{}) { ew.addService(obj) }, + UpdateFunc: ew.updateService, }) if err != nil { return nil, err @@ -177,7 +178,7 @@ func NewEndpointsWatcher(k8sAPI *k8s.API, metadataAPI *k8s.MetadataAPI, log *log ew.srvHandle, err = k8sAPI.Srv().Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: ew.addServer, DeleteFunc: ew.deleteServer, - UpdateFunc: func(_, obj interface{}) { ew.addServer(obj) }, + UpdateFunc: ew.updateServer, }) if err != nil { return nil, err @@ -199,7 +200,7 @@ func NewEndpointsWatcher(k8sAPI *k8s.API, metadataAPI *k8s.MetadataAPI, log *log ew.epHandle, err = k8sAPI.Endpoint().Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: ew.addEndpoints, DeleteFunc: ew.deleteEndpoints, - UpdateFunc: func(_, obj interface{}) { ew.addEndpoints(obj) }, + UpdateFunc: ew.updateEndpoints, }) if err != nil { return nil, err @@ -292,6 +293,20 @@ func (ew *EndpointsWatcher) addService(obj interface{}) { sp.updateService(service) } +func (ew *EndpointsWatcher) updateService(oldObj interface{}, newObj interface{}) { + oldService := oldObj.(*corev1.Service) + newService := newObj.(*corev1.Service) + + oldUpdated := latestUpdated(oldService.ManagedFields) + updated := latestUpdated(newService.ManagedFields) + if !updated.IsZero() && updated != oldUpdated { + delta := time.Since(updated) + serviceInformerLag.Observe(delta.Seconds()) + } + + ew.addService(newObj) +} + func (ew *EndpointsWatcher) deleteService(obj interface{}) { service, ok := obj.(*corev1.Service) if !ok { @@ -330,6 +345,30 @@ func (ew *EndpointsWatcher) addEndpoints(obj interface{}) { sp.updateEndpoints(endpoints) } +func (ew *EndpointsWatcher) updateEndpoints(oldObj interface{}, newObj interface{}) { + oldEndpoints, ok := oldObj.(*corev1.Endpoints) + if !ok { + ew.log.Errorf("error processing endpoints resource, got %#v expected *corev1.Endpoints", oldObj) + return + } + newEndpoints, ok := newObj.(*corev1.Endpoints) + if !ok { + ew.log.Errorf("error processing endpoints resource, got %#v expected *corev1.Endpoints", newObj) + return + } + + oldUpdated := latestUpdated(oldEndpoints.ManagedFields) + updated := latestUpdated(newEndpoints.ManagedFields) + if !updated.IsZero() && updated != oldUpdated { + delta := time.Since(updated) + endpointsInformerLag.Observe(delta.Seconds()) + } + + id := ServiceID{newEndpoints.Namespace, newEndpoints.Name} + sp := ew.getOrNewServicePublisher(id) + sp.updateEndpoints(newEndpoints) +} + func (ew *EndpointsWatcher) deleteEndpoints(obj interface{}) { endpoints, ok := obj.(*corev1.Endpoints) if !ok { @@ -384,6 +423,12 @@ func (ew *EndpointsWatcher) updateEndpointSlice(oldObj interface{}, newObj inter ew.log.Errorf("error processing EndpointSlice resource, got %#v expected *discovery.EndpointSlice", newObj) return } + oldUpdated := latestUpdated(oldSlice.ManagedFields) + updated := latestUpdated(newSlice.ManagedFields) + if !updated.IsZero() && updated != oldUpdated { + delta := time.Since(updated) + endpointsliceInformerLag.Observe(delta.Seconds()) + } id, err := getEndpointSliceServiceID(newSlice) if err != nil { @@ -466,6 +511,19 @@ func (ew *EndpointsWatcher) addServer(obj interface{}) { } } +func (ew *EndpointsWatcher) updateServer(oldObj interface{}, newObj interface{}) { + oldServer := oldObj.(*v1beta1.Server) + newServer := newObj.(*v1beta1.Server) + oldUpdated := latestUpdated(oldServer.ManagedFields) + updated := latestUpdated(newServer.ManagedFields) + if !updated.IsZero() && updated != oldUpdated { + delta := time.Since(updated) + serverInformerLag.Observe(delta.Seconds()) + } + + ew.addServer(newObj) +} + func (ew *EndpointsWatcher) deleteServer(obj interface{}) { ew.Lock() defer ew.Unlock() @@ -1338,3 +1396,15 @@ func SetToServerProtocol(k8sAPI *k8s.API, address *Address, port Port) error { } return nil } + +func latestUpdated(managedFields []metav1.ManagedFieldsEntry) time.Time { + var latest time.Time + for _, field := range managedFields { + if field.Operation == metav1.ManagedFieldsOperationUpdate { + if latest.IsZero() || field.Time.After(latest) { + latest = field.Time.Time + } + } + } + return latest +} diff --git a/controller/api/destination/watcher/opaque_ports_watcher.go b/controller/api/destination/watcher/opaque_ports_watcher.go index 79c4bbc772507..3c017dba25c0e 100644 --- a/controller/api/destination/watcher/opaque_ports_watcher.go +++ b/controller/api/destination/watcher/opaque_ports_watcher.go @@ -3,6 +3,7 @@ package watcher import ( "strconv" "sync" + "time" "github.com/linkerd/linkerd2/controller/k8s" labels "github.com/linkerd/linkerd2/pkg/k8s" @@ -59,7 +60,7 @@ func NewOpaquePortsWatcher(k8sAPI *k8s.API, log *logging.Entry, opaquePorts map[ _, err := k8sAPI.Svc().Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: opw.addService, DeleteFunc: opw.deleteService, - UpdateFunc: func(_, obj interface{}) { opw.addService(obj) }, + UpdateFunc: opw.updateService, }) if err != nil { return nil, err @@ -133,6 +134,19 @@ func (opw *OpaquePortsWatcher) Unsubscribe(id ServiceID, listener OpaquePortsUpd } } +func (opw *OpaquePortsWatcher) updateService(oldObj interface{}, newObj interface{}) { + newSvc := newObj.(*corev1.Service) + oldSvc := oldObj.(*corev1.Service) + + oldUpdated := latestUpdated(oldSvc.ManagedFields) + updated := latestUpdated(newSvc.ManagedFields) + if !updated.IsZero() && updated != oldUpdated { + delta := time.Since(updated) + serviceInformerLag.Observe(delta.Seconds()) + } + opw.addService(newObj) +} + func (opw *OpaquePortsWatcher) addService(obj interface{}) { opw.Lock() defer opw.Unlock() diff --git a/controller/api/destination/watcher/pod_watcher.go b/controller/api/destination/watcher/pod_watcher.go index 89c4dab682ed0..ad19b9f2da4d0 100644 --- a/controller/api/destination/watcher/pod_watcher.go +++ b/controller/api/destination/watcher/pod_watcher.go @@ -7,7 +7,9 @@ import ( "strconv" "strings" "sync" + "time" + "github.com/linkerd/linkerd2/controller/gen/apis/server/v1beta1" "github.com/linkerd/linkerd2/controller/k8s" consts "github.com/linkerd/linkerd2/pkg/k8s" "github.com/linkerd/linkerd2/pkg/util" @@ -78,9 +80,9 @@ func NewPodWatcher(k8sAPI *k8s.API, metadataAPI *k8s.MetadataAPI, log *logging.E } _, err = k8sAPI.Srv().Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: pw.updateServer, - DeleteFunc: pw.updateServer, - UpdateFunc: func(_, obj interface{}) { pw.updateServer(obj) }, + AddFunc: pw.updateServers, + DeleteFunc: pw.updateServers, + UpdateFunc: pw.updateServer, }) if err != nil { return nil, err @@ -177,6 +179,14 @@ func (pw *PodWatcher) updatePod(oldObj any, newObj any) { // this is just a mark, wait for actual deletion event return } + + oldUpdated := latestUpdated(oldPod.ManagedFields) + updated := latestUpdated(newPod.ManagedFields) + if !updated.IsZero() && updated != oldUpdated { + delta := time.Since(updated) + podInformerLag.Observe(delta.Seconds()) + } + pw.log.Tracef("Updated pod %s.%s", newPod.Name, newPod.Namespace) go pw.submitPodUpdate(newPod, false) } @@ -205,10 +215,24 @@ func (pw *PodWatcher) submitPodUpdate(pod *corev1.Pod, remove bool) { } } +func (pw *PodWatcher) updateServer(oldObj interface{}, newObj interface{}) { + oldServer := oldObj.(*v1beta1.Server) + newServer := newObj.(*v1beta1.Server) + + oldUpdated := latestUpdated(oldServer.ManagedFields) + updated := latestUpdated(newServer.ManagedFields) + if !updated.IsZero() && updated != oldUpdated { + delta := time.Since(updated) + serverInformerLag.Observe(delta.Seconds()) + } + + pw.updateServers(newObj) +} + // updateServer triggers an Update() call to the listeners of the podPublishers // whose pod matches the Server's selector. This function is an event handler // so it cannot block. -func (pw *PodWatcher) updateServer(_ any) { +func (pw *PodWatcher) updateServers(_ any) { pw.mu.RLock() defer pw.mu.RUnlock() diff --git a/controller/api/destination/watcher/profile_watcher.go b/controller/api/destination/watcher/profile_watcher.go index ec52f96bd2811..08232053e0cf3 100644 --- a/controller/api/destination/watcher/profile_watcher.go +++ b/controller/api/destination/watcher/profile_watcher.go @@ -2,6 +2,7 @@ package watcher import ( "sync" + "time" sp "github.com/linkerd/linkerd2/controller/gen/apis/serviceprofile/v1alpha2" splisters "github.com/linkerd/linkerd2/controller/gen/client/listers/serviceprofile/v1alpha2" @@ -105,6 +106,16 @@ func (pw *ProfileWatcher) addProfile(obj interface{}) { } func (pw *ProfileWatcher) updateProfile(old interface{}, new interface{}) { + oldProfile := old.(*sp.ServiceProfile) + newProfile := new.(*sp.ServiceProfile) + + oldUpdated := latestUpdated(oldProfile.ManagedFields) + updated := latestUpdated(newProfile.ManagedFields) + if !updated.IsZero() && updated != oldUpdated { + delta := time.Since(updated) + serviceProfileInformerLag.Observe(delta.Seconds()) + } + pw.addProfile(new) } diff --git a/controller/api/destination/watcher/prometheus.go b/controller/api/destination/watcher/prometheus.go index 602134014303f..014a01dc5a005 100644 --- a/controller/api/destination/watcher/prometheus.go +++ b/controller/api/destination/watcher/prometheus.go @@ -34,6 +34,68 @@ type ( } ) +var ( + informer_lag_seconds_buckets = []float64{ + 0.5, // 500ms + 1, // 1s + 2.5, // 2.5s + 5, // 5s + 10, // 10s + 25, // 25s + 50, // 50s + 100, // 1m 40s + 250, // 4m 10s + 1000, // 16m 40s + } + endpointsInformerLag = promauto.NewHistogram( + prometheus.HistogramOpts{ + Name: "endpoints_informer_lag_seconds", + Help: "The amount of time between when an Endpoints resource is updated and when an informer observes it", + Buckets: informer_lag_seconds_buckets, + }, + ) + + endpointsliceInformerLag = promauto.NewHistogram( + prometheus.HistogramOpts{ + Name: "endpointslices_informer_lag_seconds", + Help: "The amount of time between when an EndpointSlice resource is updated and when an informer observes it", + Buckets: informer_lag_seconds_buckets, + }, + ) + + serviceInformerLag = promauto.NewHistogram( + prometheus.HistogramOpts{ + Name: "services_informer_lag_seconds", + Help: "The amount of time between when a Service resource is updated and when an informer observes it", + Buckets: informer_lag_seconds_buckets, + }, + ) + + serverInformerLag = promauto.NewHistogram( + prometheus.HistogramOpts{ + Name: "servers_informer_lag_seconds", + Help: "The amount of time between when a Server resource is updated and when an informer observes it", + Buckets: informer_lag_seconds_buckets, + }, + ) + + podInformerLag = promauto.NewHistogram( + prometheus.HistogramOpts{ + Name: "pods_informer_lag_seconds", + Help: "The amount of time between when a Pod resource is updated and when an informer observes it", + Buckets: informer_lag_seconds_buckets, + }, + ) + + serviceProfileInformerLag = promauto.NewHistogram( + prometheus.HistogramOpts{ + Name: "serviceprofiles_informer_lag_seconds", + Help: "The amount of time between when a ServiceProfile resource is updated and when an informer observes it", + Buckets: informer_lag_seconds_buckets, + }, + ) +) + func newMetricsVecs(name string, labels []string) metricsVecs { subscribers := promauto.NewGaugeVec( prometheus.GaugeOpts{ diff --git a/controller/proxy-injector/fake/data/pod-with-debug.patch.json b/controller/proxy-injector/fake/data/pod-with-debug.patch.json index 59b9d9a1eb181..5028f184cce0b 100644 --- a/controller/proxy-injector/fake/data/pod-with-debug.patch.json +++ b/controller/proxy-injector/fake/data/pod-with-debug.patch.json @@ -85,7 +85,7 @@ "readOnlyRootFilesystem": true, "seccompProfile": { "type": "RuntimeDefault" - } + } }, "terminationMessagePolicy": "FallbackToLogsOnError", "volumeMounts": [ @@ -257,7 +257,7 @@ }, { "name": "LINKERD2_PROXY_DESTINATION_CONTEXT", - "value": "{\"ns\":\"$(_pod_ns)\", \"nodeName\":\"$(_pod_nodeName)\"}\n" + "value": "{\"ns\":\"$(_pod_ns)\", \"nodeName\":\"$(_pod_nodeName)\", \"pod\":\"$(_pod_name)\"}\n" }, { "name": "_pod_sa", @@ -354,7 +354,7 @@ "runAsUser": 2102, "seccompProfile": { "type": "RuntimeDefault" - } + } }, "terminationMessagePolicy": "FallbackToLogsOnError", "volumeMounts": [ diff --git a/controller/proxy-injector/fake/data/pod-with-ns-annotations.patch.json b/controller/proxy-injector/fake/data/pod-with-ns-annotations.patch.json index 05dcca3507291..2716869a407a2 100644 --- a/controller/proxy-injector/fake/data/pod-with-ns-annotations.patch.json +++ b/controller/proxy-injector/fake/data/pod-with-ns-annotations.patch.json @@ -95,7 +95,7 @@ "readOnlyRootFilesystem": true, "seccompProfile": { "type": "RuntimeDefault" - } + } }, "terminationMessagePolicy": "FallbackToLogsOnError", "volumeMounts": [ @@ -257,7 +257,7 @@ }, { "name": "LINKERD2_PROXY_DESTINATION_CONTEXT", - "value": "{\"ns\":\"$(_pod_ns)\", \"nodeName\":\"$(_pod_nodeName)\"}\n" + "value": "{\"ns\":\"$(_pod_ns)\", \"nodeName\":\"$(_pod_nodeName)\", \"pod\":\"$(_pod_name)\"}\n" }, { "name": "_pod_sa", @@ -362,7 +362,7 @@ "runAsUser": 2102, "seccompProfile": { "type": "RuntimeDefault" - } + } }, "terminationMessagePolicy": "FallbackToLogsOnError", "volumeMounts": [ diff --git a/controller/proxy-injector/fake/data/pod.patch.json b/controller/proxy-injector/fake/data/pod.patch.json index 5df6a8ca5c6eb..9017a44fe1248 100644 --- a/controller/proxy-injector/fake/data/pod.patch.json +++ b/controller/proxy-injector/fake/data/pod.patch.json @@ -85,7 +85,7 @@ "readOnlyRootFilesystem": true, "seccompProfile": { "type": "RuntimeDefault" - } + } }, "terminationMessagePolicy": "FallbackToLogsOnError", "volumeMounts": [ @@ -247,7 +247,7 @@ }, { "name": "LINKERD2_PROXY_DESTINATION_CONTEXT", - "value": "{\"ns\":\"$(_pod_ns)\", \"nodeName\":\"$(_pod_nodeName)\"}\n" + "value": "{\"ns\":\"$(_pod_ns)\", \"nodeName\":\"$(_pod_nodeName)\", \"pod\":\"$(_pod_name)\"}\n" }, { "name": "_pod_sa", @@ -344,7 +344,7 @@ "runAsUser": 2102, "seccompProfile": { "type": "RuntimeDefault" - } + } }, "terminationMessagePolicy": "FallbackToLogsOnError", "volumeMounts": [ diff --git a/jaeger/charts/linkerd-jaeger/Chart.yaml b/jaeger/charts/linkerd-jaeger/Chart.yaml index a418d26cb09b2..3321edba93ca9 100644 --- a/jaeger/charts/linkerd-jaeger/Chart.yaml +++ b/jaeger/charts/linkerd-jaeger/Chart.yaml @@ -11,7 +11,7 @@ kubeVersion: ">=1.21.0-0" name: linkerd-jaeger sources: - https://github.com/linkerd/linkerd2/ -version: 30.12.4 +version: 30.12.5 icon: https://linkerd.io/images/logo-only-200h.png maintainers: - name: Linkerd authors diff --git a/jaeger/charts/linkerd-jaeger/README.md b/jaeger/charts/linkerd-jaeger/README.md index 1e673d7f0134c..4708ba9721cc8 100644 --- a/jaeger/charts/linkerd-jaeger/README.md +++ b/jaeger/charts/linkerd-jaeger/README.md @@ -3,7 +3,7 @@ The Linkerd-Jaeger extension adds distributed tracing to Linkerd using OpenCensus and Jaeger. -![Version: 30.12.4](https://img.shields.io/badge/Version-30.12.4-informational?style=flat-square) +![Version: 30.12.5](https://img.shields.io/badge/Version-30.12.5-informational?style=flat-square) ![AppVersion: edge-XX.X.X](https://img.shields.io/badge/AppVersion-edge--XX.X.X-informational?style=flat-square) diff --git a/multicluster/charts/linkerd-multicluster/Chart.yaml b/multicluster/charts/linkerd-multicluster/Chart.yaml index 9d54cf39917a0..b7bf4ec096c43 100644 --- a/multicluster/charts/linkerd-multicluster/Chart.yaml +++ b/multicluster/charts/linkerd-multicluster/Chart.yaml @@ -11,7 +11,7 @@ kubeVersion: ">=1.21.0-0" name: "linkerd-multicluster" sources: - https://github.com/linkerd/linkerd2/ -version: 30.11.4 +version: 30.11.5 icon: https://linkerd.io/images/logo-only-200h.png maintainers: - name: Linkerd authors diff --git a/multicluster/charts/linkerd-multicluster/README.md b/multicluster/charts/linkerd-multicluster/README.md index 4ef7426a4fafa..db067e8aa1886 100644 --- a/multicluster/charts/linkerd-multicluster/README.md +++ b/multicluster/charts/linkerd-multicluster/README.md @@ -3,7 +3,7 @@ The Linkerd-Multicluster extension contains resources to support multicluster linking to remote clusters -![Version: 30.11.4](https://img.shields.io/badge/Version-30.11.4-informational?style=flat-square) +![Version: 30.11.5](https://img.shields.io/badge/Version-30.11.5-informational?style=flat-square) ![AppVersion: edge-XX.X.X](https://img.shields.io/badge/AppVersion-edge--XX.X.X-informational?style=flat-square) diff --git a/pkg/charts/linkerd2/values.go b/pkg/charts/linkerd2/values.go index a219ce29e88f0..791318a45a61b 100644 --- a/pkg/charts/linkerd2/values.go +++ b/pkg/charts/linkerd2/values.go @@ -94,29 +94,31 @@ type ( Proxy struct { Capabilities *Capabilities `json:"capabilities"` // This should match .Resources.CPU.Limit, but must be a whole number - Cores int64 `json:"cores,omitempty"` - EnableExternalProfiles bool `json:"enableExternalProfiles"` - Image *Image `json:"image"` - LogLevel string `json:"logLevel"` - LogFormat string `json:"logFormat"` - SAMountPath *VolumeMountPath `json:"saMountPath"` - Ports *Ports `json:"ports"` - Resources *Resources `json:"resources"` - UID int64 `json:"uid"` - WaitBeforeExitSeconds uint64 `json:"waitBeforeExitSeconds"` - IsGateway bool `json:"isGateway"` - IsIngress bool `json:"isIngress"` - RequireIdentityOnInboundPorts string `json:"requireIdentityOnInboundPorts"` - OutboundConnectTimeout string `json:"outboundConnectTimeout"` - InboundConnectTimeout string `json:"inboundConnectTimeout"` - OutboundDiscoveryCacheUnusedTimeout string `json:"outboundDiscoveryCacheUnusedTimeout"` - InboundDiscoveryCacheUnusedTimeout string `json:"inboundDiscoveryCacheUnusedTimeout"` - PodInboundPorts string `json:"podInboundPorts"` - OpaquePorts string `json:"opaquePorts"` - Await bool `json:"await"` - DefaultInboundPolicy string `json:"defaultInboundPolicy"` - AccessLog string `json:"accessLog"` - ShutdownGracePeriod string `json:"shutdownGracePeriod"` + Cores int64 `json:"cores,omitempty"` + EnableExternalProfiles bool `json:"enableExternalProfiles"` + Image *Image `json:"image"` + LogLevel string `json:"logLevel"` + LogFormat string `json:"logFormat"` + SAMountPath *VolumeMountPath `json:"saMountPath"` + Ports *Ports `json:"ports"` + Resources *Resources `json:"resources"` + UID int64 `json:"uid"` + WaitBeforeExitSeconds uint64 `json:"waitBeforeExitSeconds"` + IsGateway bool `json:"isGateway"` + IsIngress bool `json:"isIngress"` + RequireIdentityOnInboundPorts string `json:"requireIdentityOnInboundPorts"` + OutboundConnectTimeout string `json:"outboundConnectTimeout"` + InboundConnectTimeout string `json:"inboundConnectTimeout"` + OutboundDiscoveryCacheUnusedTimeout string `json:"outboundDiscoveryCacheUnusedTimeout"` + InboundDiscoveryCacheUnusedTimeout string `json:"inboundDiscoveryCacheUnusedTimeout"` + DisableOutboundProtocolDetectTimeout bool `json:"disableOutboundProtocolDetectTimeout"` + DisableInboundProtocolDetectTimeout bool `json:"disableInboundProtocolDetectTimeout"` + PodInboundPorts string `json:"podInboundPorts"` + OpaquePorts string `json:"opaquePorts"` + Await bool `json:"await"` + DefaultInboundPolicy string `json:"defaultInboundPolicy"` + AccessLog string `json:"accessLog"` + ShutdownGracePeriod string `json:"shutdownGracePeriod"` } // ProxyInit contains the fields to set the proxy-init container diff --git a/pkg/charts/linkerd2/values_test.go b/pkg/charts/linkerd2/values_test.go index 10d05f37dbce4..91c6b3c6fb020 100644 --- a/pkg/charts/linkerd2/values_test.go +++ b/pkg/charts/linkerd2/values_test.go @@ -123,15 +123,17 @@ func TestNewValues(t *testing.T) { Request: "", }, }, - UID: 2102, - WaitBeforeExitSeconds: 0, - OutboundConnectTimeout: "1000ms", - InboundConnectTimeout: "100ms", - OpaquePorts: "25,587,3306,4444,5432,6379,9300,11211", - Await: true, - DefaultInboundPolicy: "all-unauthenticated", - OutboundDiscoveryCacheUnusedTimeout: "5s", - InboundDiscoveryCacheUnusedTimeout: "90s", + UID: 2102, + WaitBeforeExitSeconds: 0, + OutboundConnectTimeout: "1000ms", + InboundConnectTimeout: "100ms", + OpaquePorts: "25,587,3306,4444,5432,6379,9300,11211", + Await: true, + DefaultInboundPolicy: "all-unauthenticated", + OutboundDiscoveryCacheUnusedTimeout: "5s", + InboundDiscoveryCacheUnusedTimeout: "90s", + DisableOutboundProtocolDetectTimeout: false, + DisableInboundProtocolDetectTimeout: false, }, ProxyInit: &ProxyInit{ IptablesMode: "legacy", @@ -162,11 +164,11 @@ func TestNewValues(t *testing.T) { RunAsUser: 65534, }, NetworkValidator: &NetworkValidator{ - LogLevel: "debug", - LogFormat: "plain", - ConnectAddr: "1.1.1.1:20001", - ListenAddr: "0.0.0.0:4140", - Timeout: "10s", + LogLevel: "debug", + LogFormat: "plain", + ConnectAddr: "1.1.1.1:20001", + ListenAddr: "0.0.0.0:4140", + Timeout: "10s", EnableSecurityContext: true, }, Identity: &Identity{ diff --git a/pkg/inject/inject.go b/pkg/inject/inject.go index edf7f54616904..31bc0ef2dd12c 100644 --- a/pkg/inject/inject.go +++ b/pkg/inject/inject.go @@ -75,6 +75,8 @@ var ( k8s.ProxyShutdownGracePeriodAnnotation, k8s.ProxyOutboundDiscoveryCacheUnusedTimeout, k8s.ProxyInboundDiscoveryCacheUnusedTimeout, + k8s.ProxyDisableOutboundProtocolDetectTimeout, + k8s.ProxyDisableInboundProtocolDetectTimeout, } // ProxyAlphaConfigAnnotations is the list of all alpha configuration // (config.alpha prefix) that can be applied to a pod or namespace. @@ -954,6 +956,24 @@ func (conf *ResourceConfig) applyAnnotationOverrides(values *l5dcharts.Values) { } } + if override, ok := annotations[k8s.ProxyDisableOutboundProtocolDetectTimeout]; ok { + value, err := strconv.ParseBool(override) + if err == nil { + values.Proxy.DisableOutboundProtocolDetectTimeout = value + } else { + log.Warnf("unrecognised value used on pod annotation %s: %s", k8s.ProxyDisableOutboundProtocolDetectTimeout, err.Error()) + } + } + + if override, ok := annotations[k8s.ProxyDisableInboundProtocolDetectTimeout]; ok { + value, err := strconv.ParseBool(override) + if err == nil { + values.Proxy.DisableInboundProtocolDetectTimeout = value + } else { + log.Warnf("unrecognised value used on pod annotation %s: %s", k8s.ProxyDisableInboundProtocolDetectTimeout, err.Error()) + } + } + if override, ok := annotations[k8s.ProxyShutdownGracePeriodAnnotation]; ok { duration, err := time.ParseDuration(override) if err != nil { diff --git a/pkg/inject/inject_test.go b/pkg/inject/inject_test.go index 3f8599c07ff79..41177b8f53b98 100644 --- a/pkg/inject/inject_test.go +++ b/pkg/inject/inject_test.go @@ -72,6 +72,8 @@ func TestGetOverriddenValues(t *testing.T) { k8s.ProxyShutdownGracePeriodAnnotation: "30s", k8s.ProxyOutboundDiscoveryCacheUnusedTimeout: "50000ms", k8s.ProxyInboundDiscoveryCacheUnusedTimeout: "900s", + k8s.ProxyDisableOutboundProtocolDetectTimeout: "true", + k8s.ProxyDisableInboundProtocolDetectTimeout: "true", }, }, Spec: corev1.PodSpec{}, @@ -122,6 +124,8 @@ func TestGetOverriddenValues(t *testing.T) { values.Proxy.ShutdownGracePeriod = "30000ms" values.Proxy.OutboundDiscoveryCacheUnusedTimeout = "50s" values.Proxy.InboundDiscoveryCacheUnusedTimeout = "900s" + values.Proxy.DisableOutboundProtocolDetectTimeout = true + values.Proxy.DisableInboundProtocolDetectTimeout = true return values }, }, @@ -140,34 +144,36 @@ func TestGetOverriddenValues(t *testing.T) { }, {id: "use namespace overrides", nsAnnotations: map[string]string{ - k8s.ProxyImageAnnotation: "cr.l5d.io/linkerd/proxy", - k8s.ProxyImagePullPolicyAnnotation: pullPolicy, - k8s.ProxyInitImageAnnotation: "cr.l5d.io/linkerd/proxy-init", - k8s.ProxyControlPortAnnotation: "4000", - k8s.ProxyInboundPortAnnotation: "5000", - k8s.ProxyAdminPortAnnotation: "5001", - k8s.ProxyOutboundPortAnnotation: "5002", - k8s.ProxyPodInboundPortsAnnotation: "1234,5678", - k8s.ProxyIgnoreInboundPortsAnnotation: "4222,6222", - k8s.ProxyIgnoreOutboundPortsAnnotation: "8079,8080", - k8s.ProxyCPURequestAnnotation: "0.15", - k8s.ProxyMemoryRequestAnnotation: "120", - k8s.ProxyCPULimitAnnotation: "1.5", - k8s.ProxyMemoryLimitAnnotation: "256", - k8s.ProxyUIDAnnotation: "8500", - k8s.ProxyLogLevelAnnotation: "debug,linkerd=debug", - k8s.ProxyLogFormatAnnotation: "json", - k8s.ProxyEnableExternalProfilesAnnotation: "false", - k8s.ProxyVersionOverrideAnnotation: proxyVersionOverride, - k8s.ProxyWaitBeforeExitSecondsAnnotation: "123", - k8s.ProxyOutboundConnectTimeout: "6000ms", - k8s.ProxyInboundConnectTimeout: "600ms", - k8s.ProxyOpaquePortsAnnotation: "4320-4325,3306", - k8s.ProxyAwait: "enabled", - k8s.ProxyAccessLogAnnotation: "apache", - k8s.ProxyInjectAnnotation: "ingress", - k8s.ProxyOutboundDiscoveryCacheUnusedTimeout: "50s", - k8s.ProxyInboundDiscoveryCacheUnusedTimeout: "6000ms", + k8s.ProxyImageAnnotation: "cr.l5d.io/linkerd/proxy", + k8s.ProxyImagePullPolicyAnnotation: pullPolicy, + k8s.ProxyInitImageAnnotation: "cr.l5d.io/linkerd/proxy-init", + k8s.ProxyControlPortAnnotation: "4000", + k8s.ProxyInboundPortAnnotation: "5000", + k8s.ProxyAdminPortAnnotation: "5001", + k8s.ProxyOutboundPortAnnotation: "5002", + k8s.ProxyPodInboundPortsAnnotation: "1234,5678", + k8s.ProxyIgnoreInboundPortsAnnotation: "4222,6222", + k8s.ProxyIgnoreOutboundPortsAnnotation: "8079,8080", + k8s.ProxyCPURequestAnnotation: "0.15", + k8s.ProxyMemoryRequestAnnotation: "120", + k8s.ProxyCPULimitAnnotation: "1.5", + k8s.ProxyMemoryLimitAnnotation: "256", + k8s.ProxyUIDAnnotation: "8500", + k8s.ProxyLogLevelAnnotation: "debug,linkerd=debug", + k8s.ProxyLogFormatAnnotation: "json", + k8s.ProxyEnableExternalProfilesAnnotation: "false", + k8s.ProxyVersionOverrideAnnotation: proxyVersionOverride, + k8s.ProxyWaitBeforeExitSecondsAnnotation: "123", + k8s.ProxyOutboundConnectTimeout: "6000ms", + k8s.ProxyInboundConnectTimeout: "600ms", + k8s.ProxyOpaquePortsAnnotation: "4320-4325,3306", + k8s.ProxyAwait: "enabled", + k8s.ProxyAccessLogAnnotation: "apache", + k8s.ProxyInjectAnnotation: "ingress", + k8s.ProxyOutboundDiscoveryCacheUnusedTimeout: "50s", + k8s.ProxyInboundDiscoveryCacheUnusedTimeout: "6000ms", + k8s.ProxyDisableOutboundProtocolDetectTimeout: "true", + k8s.ProxyDisableInboundProtocolDetectTimeout: "false", }, spec: appsv1.DeploymentSpec{ Template: corev1.PodTemplateSpec{ @@ -213,15 +219,19 @@ func TestGetOverriddenValues(t *testing.T) { values.Proxy.IsIngress = true values.Proxy.OutboundDiscoveryCacheUnusedTimeout = "50s" values.Proxy.InboundDiscoveryCacheUnusedTimeout = "6s" + values.Proxy.DisableOutboundProtocolDetectTimeout = true + values.Proxy.DisableInboundProtocolDetectTimeout = false return values }, }, {id: "use invalid duration for proxy timeouts", nsAnnotations: map[string]string{ - k8s.ProxyOutboundConnectTimeout: "6000", - k8s.ProxyInboundConnectTimeout: "600", - k8s.ProxyOutboundDiscoveryCacheUnusedTimeout: "50", - k8s.ProxyInboundDiscoveryCacheUnusedTimeout: "5000", + k8s.ProxyOutboundConnectTimeout: "6000", + k8s.ProxyInboundConnectTimeout: "600", + k8s.ProxyOutboundDiscoveryCacheUnusedTimeout: "50", + k8s.ProxyInboundDiscoveryCacheUnusedTimeout: "5000", + k8s.ProxyDisableOutboundProtocolDetectTimeout: "9000", + k8s.ProxyDisableInboundProtocolDetectTimeout: "9", }, spec: appsv1.DeploymentSpec{ Template: corev1.PodTemplateSpec{ @@ -237,10 +247,12 @@ func TestGetOverriddenValues(t *testing.T) { {id: "use valid duration for proxy timeouts", nsAnnotations: map[string]string{ // Validate we're converting time values into ms for the proxy to parse correctly. - k8s.ProxyOutboundConnectTimeout: "6s5ms", - k8s.ProxyInboundConnectTimeout: "2s5ms", - k8s.ProxyOutboundDiscoveryCacheUnusedTimeout: "6s5000ms", - k8s.ProxyInboundDiscoveryCacheUnusedTimeout: "6s5000ms", + k8s.ProxyOutboundConnectTimeout: "6s5ms", + k8s.ProxyInboundConnectTimeout: "2s5ms", + k8s.ProxyOutboundDiscoveryCacheUnusedTimeout: "6s5000ms", + k8s.ProxyInboundDiscoveryCacheUnusedTimeout: "6s5000ms", + k8s.ProxyDisableOutboundProtocolDetectTimeout: "false", + k8s.ProxyDisableInboundProtocolDetectTimeout: "true", }, spec: appsv1.DeploymentSpec{ Template: corev1.PodTemplateSpec{ @@ -254,6 +266,8 @@ func TestGetOverriddenValues(t *testing.T) { values.Proxy.InboundConnectTimeout = "2005ms" values.Proxy.OutboundDiscoveryCacheUnusedTimeout = "11s" values.Proxy.InboundDiscoveryCacheUnusedTimeout = "11s" + values.Proxy.DisableOutboundProtocolDetectTimeout = false + values.Proxy.DisableInboundProtocolDetectTimeout = true return values }, }, diff --git a/pkg/k8s/labels.go b/pkg/k8s/labels.go index 64c62b0132460..00dbfd1709764 100644 --- a/pkg/k8s/labels.go +++ b/pkg/k8s/labels.go @@ -238,6 +238,16 @@ const ( // that will evict unused inbound discovery results ProxyInboundDiscoveryCacheUnusedTimeout = ProxyConfigAnnotationsPrefix + "/proxy-inbound-discovery-cache-unused-timeout" + // ProxyDisableOutboundProtocolDetectTimeout can be used to disable protocol + // detection timeouts for outbound connections by setting them to a very + // high value. + ProxyDisableOutboundProtocolDetectTimeout = ProxyConfigAnnotationsPrefix + "/proxy-disable-outbound-protocol-detect-timeout" + + // ProxyDisableInboundProtocolDetectTimeout can be used to disable protocol + // detection timeouts for inbound connections by setting them to a very + // high value. + ProxyDisableInboundProtocolDetectTimeout = ProxyConfigAnnotationsPrefix + "/proxy-disable-inbound-protocol-detect-timeout" + // ProxyEnableGatewayAnnotation can be used to configure the proxy // to operate as a gateway, routing requests that target the inbound router. ProxyEnableGatewayAnnotation = ProxyConfigAnnotationsPrefix + "/enable-gateway" diff --git a/viz/charts/linkerd-viz/Chart.yaml b/viz/charts/linkerd-viz/Chart.yaml index 6d3333cae5109..2f36c2dbc1536 100644 --- a/viz/charts/linkerd-viz/Chart.yaml +++ b/viz/charts/linkerd-viz/Chart.yaml @@ -11,7 +11,7 @@ kubeVersion: ">=1.21.0-0" name: "linkerd-viz" sources: - https://github.com/linkerd/linkerd2/ -version: 30.12.4 +version: 30.12.5 icon: https://linkerd.io/images/logo-only-200h.png maintainers: - name: Linkerd authors diff --git a/viz/charts/linkerd-viz/README.md b/viz/charts/linkerd-viz/README.md index 54e39bdc1aaca..8548f0df6835a 100644 --- a/viz/charts/linkerd-viz/README.md +++ b/viz/charts/linkerd-viz/README.md @@ -3,7 +3,7 @@ The Linkerd-Viz extension contains observability and visualization components for Linkerd. -![Version: 30.12.4](https://img.shields.io/badge/Version-30.12.4-informational?style=flat-square) +![Version: 30.12.5](https://img.shields.io/badge/Version-30.12.5-informational?style=flat-square) ![AppVersion: edge-XX.X.X](https://img.shields.io/badge/AppVersion-edge--XX.X.X-informational?style=flat-square) diff --git a/viz/cmd/root.go b/viz/cmd/root.go index 049f7d1033080..1f52026bd1e42 100644 --- a/viz/cmd/root.go +++ b/viz/cmd/root.go @@ -24,9 +24,9 @@ const ( defaultLinkerdNamespace = "linkerd" maxRps = 100.0 - jsonOutput = healthcheck.JSONOutput - tableOutput = healthcheck.TableOutput - wideOutput = healthcheck.WideOutput + jsonOutput = healthcheck.JSONOutput + tableOutput = healthcheck.TableOutput + wideOutput = healthcheck.WideOutput jsonPathOutput = "jsonpath" )