Repository: linkerd/linkerd2
Pull request #6980 (2021-09-27 17:17:51)

build(deps): bump schemars from 0.8.5 to 0.8.6
Bumps [schemars](https://github.com/GREsau/schemars) from 0.8.5 to 0.8.6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/GREsau/schemars/releases">schemars's releases</a>.</em></p>
<blockquote>
<h2>v0.8.6</h2>
<h2>[0.8.6] - 2021-09-26</h2>
<h3>Changed:</h3>
<ul>
<li>Use <code>oneOf</code> instead of <code>anyOf</code> for enums when possible (<a href="https://github-redirect.dependabot.com/GREsau/schemars/issues/108">GREsau/schemars#108</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/GREsau/schemars/blob/master/CHANGELOG.md">schemars's changelog</a>.</em></p>
<blockquote>
<h2>[0.8.6] - 2021-09-26</h2>
<h3>Changed:</h3>
<ul>
<li>Use <code>oneOf</code> instead of <code>anyOf</code> for enums when possible (<a href="https://github-redirect.dependabot.com/GREsau/schemars/issues/108">GREsau/schemars#108</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/GREsau/schemars/commit/515a87a5649ce1ea30fe80874baf581247aff315"><code>515a87a</code></a> Correct latest changelog entry</li>
<li><a href="https://github.com/GREsau/schemars/commit/33e54d3c424078e94cd0c4ac33023d1b8a7df275"><code>33e54d3</code></a> v0.8.6</li>
<li><a href="https://github.com/GREsau/schemars/commit/0a1200baac8e8136c2f9db4f1d85c06f9f7086b5"><code>0a1200b</code></a> Use oneOf for enums when possible (<a href="https://github-redirect.dependabot.com/GREsau/schemars/issues/108">#108</a>)</li>
<li>See full diff in <a href="https://github.com/GREsau/schemars/compare/v0.8.5...v0.8.6">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=schemars&package-manager=cargo&previous-version=0.8.5&new-version=0.8.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 51f541eeb..a39997467 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -132,6 +132,7 @@ jobs:
         - upgrade-edge
         - upgrade-stable
         - cni-calico-deep
+        - default-policy-deny
     needs: [docker_build, policy_controller_manifest]
     name: Integration tests (${{ matrix.integration_test }})
     timeout-minutes: 60
diff --git a/CHANGES.md b/CHANGES.md
index 1b7d83afb..058bed8a7 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,131 @@
 # Changes
 
+## stable-2.11.0
+
+This release introduces access control policies. Default policies may be
+configured at the cluster- and workspace-levels; and fine grained policies may
+be instrumented via the new `policy.linkerd.io/v1beta1` CRDs: `Server` and
+`ServerAuthorization`. These resources may be created to define how individual
+ports accept connections; and the `Server` resource will be a building block for
+future features that configure inbound proxy behavior.
+
+Furthermore, `ServiceProfile` retry configurations can now instrument retries
+for requests with bodies. This unlocks retry behavior for gRPC services.
+
+**Upgrade notes**: Please see the [upgrade instructions][upgrade-2110].
+
+* Proxy
+  * Reduced CPU & Memory usage by up to 30% in some load tests
+  * Updated retries to support requests with bodies up to 64KB. ServiceProfiles
+    may now configure retries for gRPC services
+  * The proxy's container image is now based on `gcr.io/distroless/cc` to
+    contain a minimal OS footprint that should not trigger unnecessary alerts in
+    security scanners
+  * Added the `inbound_http_errors_total` and `outbound_http_errors_total`
+    metrics to reflect errors that caused the proxy to respond with errors
+  * Added an `l5d-proxy-error` header that is included on responses on trusted
+    connections for debugging purposes
+  * Added a `l5d-client-id` header on mutually-authenticated inbound requests so
+    that applications can discover the client's identity
+  * Added metrics to reflect TCP and HTTP authorization decisions
+  * Added `srv_name` and `saz_name` labels to inbound HTTP metrics
+  * Fixed an issue that could cause the proxy to continually reconnect to
+    defunct service endpoints
+  * Dropped support for non-HTTP outbound services when `linkerd.io/inject:
+    ingress` is used
+  * Instrumented fuzz testing to help guard against unexpected panics
+
+* Control Plane
+  * Added a new `policy-controller` container to the `linkerd-destination`
+    pod--the first control plane component implemented in Rust
+  * Added a new admission controller to validate that multiple `Server`
+    resources do not reference the same port
+  * Added a `linkerd-identity-trust-roots` ConfigMap which configures the trust
+    root bundle for all pods in the core control plane namespace
+  * Eliminated the `linkerd-controller` deployment so that Linkerd's core
+    control plane now consists of only 3 deployments
+  * Updated the proxy injector to configure the `proxy-init` container with
+    `NET_RAW` and `NET_ADMIN` capabilities so that the container does not fail
+    when the pod drops these capabilities
+
+* CLI
+  * Enhanced `linkerd completion` to expand Kubernetes resources from the current
+    kubectl context
+  * Added an `authz` subcommand to display the authorization policies that
+    impact a workload
+  * Added a _short_ output mode for `linkerd check` that only prints failed
+    checks
+  * Added support for `ReplicaSets` to `linkerd stat` so that pods created by
+    Argo `Rollout` resources can be inspected
+
+* Helm: please see the [upgrade instructions][upgrade-2110].
+
+* Extensions:
+  * Introduced a new (optional) SMI extension responsible for reading
+    `specs.smi-spec.io` resources and converting them to Linkerd resources
+  * In `stable-2.12`, this extension will be required to use `TrafficSplit`
+    resources with Linkerd
+  * Added an extensions page to the Linkerd Web UI
+
+  * Viz
+    * Added `Server` and `ServerAuthorization` resources for all ports
+    * Added JSON log formatting
+
+  * Jaeger
+    * Added OpenTelemetry collector instead of OpenCensus
+
+  * Multicluster
+    * Added experimental support for `StatefulSet` workloads
+
+This release includes changes from a massive list of contributors. A special
+thank-you to everyone who helped make this release possible:
+
+Gustavo Fernandes de Carvalho @gusfcarvalho
+Oleg Vorobev @olegy2008
+Bart Peeters @bartpeeters
+Stepan Rabotkin @EpicStep
+LiuDui @xichengliudui
+Andrew Hemming @drewhemm
+Ujjwal Goyal @importhuman
+Knut Götz @knutgoetz
+Sanni Michael @sannimichaelse
+Brandon Sorgdrager @bsord
+Gerald Pape @ubergesundheit
+Alexey Kostin @rumanzo
+rdileep13 @rdileep13
+Takumi Sue @mikutas
+Akshit Grover @akshitgrover
+Sanskar Jaiswal @aryan9600
+Aleksandr Tarasov @aatarasoff
+Taylor @skinn
+Miguel Ángel Pastor Olivar @migue
+wangchenglong01 @wangchenglong01
+Josh Soref @jsoref
+Carol Chen @kipply
+Peter Smit @psmit
+Tarvi Pillessaar @tarvip
+James Roper @jroper
+Dominik Münch @muenchdo
+Szymon Gibała @Szymongib
+Mitch Hulscher @mhulscher
+
+[upgrade-2110]: https://linkerd.io/2/tasks/upgrade/#upgrade-notice-stable-2110
+
+## edge-21.9.5
+
+This edge is a release candidate for `stable-2.11.0`, containing a couple of
+improvements to `linkerd check`, some final tweaks before the stable release,
+and a couple of contributions from the community.
+
+* Had `linkerd check --proxy` stop failing on pods that are in Shutdown status
+  (thanks @olegy2008!)
+* Lowered from error to warning a failed check on misconfigured opaque ports
+  annotations, given that doesn't imply the installation is broken
+* Added log level and format settings to all the viz components (thanks
+  @gusfcarvalho!)
+* Removed label from the multicluster gateway and service-mirror pods to allow
+  them to be properly rolled out when upgrading
+
 ## edge-21.9.4
 
 This edge is a release candidate for `stable-2.11.0`! It introduces a new
diff --git a/Cargo.lock b/Cargo.lock
index 9a705e548..95c09d7f4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1478,9 +1478,9 @@ dependencies = [
 
 [[package]]
 name = "schemars"
-version = "0.8.5"
+version = "0.8.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b82485a532ef0af18878ad4281f73e58161cdba1db7918176e9294f0ca5498a5"
+checksum = "d7a48d098c2a7fdf5740b19deb1181b4fb8a9e68e03ae517c14cde04b5725409"
 dependencies = [
  "dyn-clone",
  "schemars_derive",
@@ -1490,9 +1490,9 @@ dependencies = [
 
 [[package]]
 name = "schemars_derive"
-version = "0.8.5"
+version = "0.8.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "791c2c848cff1abaeae34fef7e70da5f93171d9eea81ce0fe969a1df627a61a8"
+checksum = "4a9ea2a613fe4cd7118b2bb101a25d8ae6192e1975179b67b2f17afd11e70ac8"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/multicluster/charts/linkerd-multicluster-link/templates/proxy-admin-policy.yaml b/multicluster/charts/linkerd-multicluster-link/templates/proxy-admin-policy.yaml
new file mode 100644
index 000000000..61990f721
--- /dev/null
+++ b/multicluster/charts/linkerd-multicluster-link/templates/proxy-admin-policy.yaml
@@ -0,0 +1,29 @@
+---
+apiVersion: policy.linkerd.io/v1beta1
+kind: Server
+metadata:
+  namespace: {{.Values.namespace}}
+  name: service-mirror-proxy-admin
+  labels:
+    linkerd.io/extension: multicluster
+spec:
+  podSelector:
+    matchLabels:
+      linkerd.io/control-plane-component: linkerd-service-mirror
+  port: linkerd-admin
+  proxyProtocol: HTTP/1
+---
+apiVersion: policy.linkerd.io/v1beta1
+kind: ServerAuthorization
+metadata:
+  namespace: {{.Values.namespace}}
+  name: service-mirror-proxy-admin
+  labels:
+    linkerd.io/extension: multicluster
+spec:
+  server:
+    name: service-mirror-proxy-admin
+  client:
+    # for kubelet probes
+    unauthenticated: true
+
diff --git a/multicluster/charts/linkerd-multicluster-link/templates/service-mirror.yaml b/multicluster/charts/linkerd-multicluster-link/templates/service-mirror.yaml
index 375d8763c..be72efa6c 100644
--- a/multicluster/charts/linkerd-multicluster-link/templates/service-mirror.yaml
+++ b/multicluster/charts/linkerd-multicluster-link/templates/service-mirror.yaml
@@ -91,7 +91,6 @@ spec:
   replicas: 1
   selector:
     matchLabels:
-      linkerd.io/extension: multicluster
       linkerd.io/control-plane-component: linkerd-service-mirror
       mirror.linkerd.io/cluster-name: {{.Values.targetClusterName}}
   template:
@@ -99,7 +98,6 @@ spec:
       annotations:
         linkerd.io/inject: enabled
       labels:
-        linkerd.io/extension: multicluster
         linkerd.io/control-plane-component: linkerd-service-mirror
         mirror.linkerd.io/cluster-name: {{.Values.targetClusterName}}
     spec:
diff --git a/multicluster/charts/linkerd-multicluster/templates/gateway.yaml b/multicluster/charts/linkerd-multicluster/templates/gateway.yaml
index e4e5d93e9..6b3bcc6e2 100644
--- a/multicluster/charts/linkerd-multicluster/templates/gateway.yaml
+++ b/multicluster/charts/linkerd-multicluster/templates/gateway.yaml
@@ -18,7 +18,6 @@ spec:
   replicas: 1
   selector:
     matchLabels:
-      linkerd.io/extension: multicluster
       app: {{.Values.gateway.name}}
   template:
     metadata:
@@ -28,7 +27,6 @@ spec:
         config.linkerd.io/proxy-require-identity-inbound-ports: "{{.Values.gateway.port}}"
         config.linkerd.io/enable-gateway: "true"
       labels:
-        linkerd.io/extension: multicluster
         app: {{.Values.gateway.name}}
     spec:
       containers:
diff --git a/multicluster/charts/linkerd-multicluster/templates/proxy-admin-policy.yaml b/multicluster/charts/linkerd-multicluster/templates/proxy-admin-policy.yaml
index f64aadf58..821174f4d 100644
--- a/multicluster/charts/linkerd-multicluster/templates/proxy-admin-policy.yaml
+++ b/multicluster/charts/linkerd-multicluster/templates/proxy-admin-policy.yaml
@@ -3,7 +3,7 @@ apiVersion: policy.linkerd.io/v1beta1
 kind: Server
 metadata:
   namespace: {{.Values.namespace}}
-  name: proxy-admin
+  name: gateway-proxy-admin
   labels:
     linkerd.io/extension: multicluster
   annotations:
@@ -11,7 +11,7 @@ metadata:
 spec:
   podSelector:
     matchLabels:
-      linkerd.io/extension: multicluster
+      app: {{.Values.gateway.name}}
   port: linkerd-admin
   proxyProtocol: HTTP/1
 ---
@@ -26,7 +26,7 @@ metadata:
     {{ include "partials.annotations.created-by" . }}
 spec:
   server:
-    name: proxy-admin
+    name: gateway-proxy-admin
   client:
     # for kubelet probes
     unauthenticated: true
diff --git a/multicluster/cmd/link.go b/multicluster/cmd/link.go
index 6dcd5009b..f042e9c2a 100644
--- a/multicluster/cmd/link.go
+++ b/multicluster/cmd/link.go
@@ -262,6 +262,7 @@ A full list of configurable values can be found at https://github.com/linkerd/li
 				{Name: "templates/service-mirror-policy.yaml"},
 				{Name: "templates/psp.yaml"},
 				{Name: "templates/gateway-mirror.yaml"},
+				{Name: "templates/proxy-admin-policy.yaml"},
 			}
 
 			// Load all multicluster link chart files into buffer
diff --git a/pkg/healthcheck/healthcheck.go b/pkg/healthcheck/healthcheck.go
index fb81d9d67..9d4c5c265 100644
--- a/pkg/healthcheck/healthcheck.go
+++ b/pkg/healthcheck/healthcheck.go
@@ -1357,6 +1357,7 @@ func (hc *HealthChecker) allCategories() []*Category {
 				{
 					description: "opaque ports are properly annotated",
 					hintAnchor:  "linkerd-opaque-ports-definition",
+					warning:     true,
 					check: func(ctx context.Context) error {
 						return hc.checkMisconfiguredOpaquePortAnnotations(ctx)
 					},
@@ -2676,9 +2677,9 @@ func validateDataPlanePods(pods []corev1.Pod, targetNamespace string) error {
 
 	for _, pod := range pods {
 		status := k8s.GetPodStatus(pod)
-		// Skip validating meshed pods that are in the `Completed` state
+		// Skip validating meshed pods that are in the `Completed` or `Shutdown` state
 		// as they do not have a running proxy
-		if status == "Completed" {
+		if status == "Completed" || status == "Shutdown" {
 			continue
 		}
 
diff --git a/viz/charts/linkerd-viz/README.md b/viz/charts/linkerd-viz/README.md
index 36634c7a5..bc345e5fa 100644
--- a/viz/charts/linkerd-viz/README.md
+++ b/viz/charts/linkerd-viz/README.md
@@ -86,6 +86,7 @@ Kubernetes: `>=1.16.0-0`
 | dashboard.image.pullPolicy | string | defaultImagePullPolicy | Pull policy for the  web component |
 | dashboard.image.registry | string | defaultRegistry | Docker registry for the web instance |
 | dashboard.image.tag | string | linkerdVersion | Docker image tag for the web instance |
+| dashboard.logFormat | string | defaultLogFormat | log format of the dashboard component |
 | dashboard.logLevel | string | defaultLogLevel | log level of the dashboard component |
 | dashboard.proxy | string | `nil` |  |
 | dashboard.replicas | int | `1` | Number of replicas of dashboard |
@@ -95,6 +96,7 @@ Kubernetes: `>=1.16.0-0`
 | dashboard.resources.memory.request | string | `nil` | Amount of memory that the web container requests |
 | dashboard.restrictPrivileges | bool | `false` | Restrict the Linkerd Dashboard's default privileges to disallow Tap and Check |
 | defaultImagePullPolicy | string | `"IfNotPresent"` | Docker imagePullPolicy for all viz components |
+| defaultLogFormat | string | `"plain"` | Log format (`plain` or `json`) for all the viz components. |
 | defaultLogLevel | string | `"info"` | Log level for all the viz components |
 | defaultRegistry | string | `"cr.l5d.io/linkerd"` | Docker registry for all viz components |
 | defaultUID | int | `2103` | UID for all the viz components |
@@ -105,6 +107,8 @@ Kubernetes: `>=1.16.0-0`
 | grafana.image.pullPolicy | string | defaultImagePullPolicy | Pull policy for the grafana instance |
 | grafana.image.registry | string | defaultRegistry | Docker registry for the grafana instance |
 | grafana.image.tag | string | linkerdVersion | Docker image tag for the grafana instance |
+| grafana.logFormat | string | defaultLogFormat | log format (plain, json) of the grafana instance |
+| grafana.logLevel | string | defaultLogLevel | log level of the grafana instance |
 | grafana.nodeSelector | object | `{"beta.kubernetes.io/os":"linux"}` | NodeSelector section, See the [K8S documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) for more information |
 | grafana.proxy | string | `nil` |  |
 | grafana.resources.cpu.limit | string | `nil` | Maximum amount of CPU units that the grafana container can use |
@@ -124,6 +128,7 @@ Kubernetes: `>=1.16.0-0`
 | metricsAPI.image.pullPolicy | string | defaultImagePullPolicy | Pull policy for the metrics-api component |
 | metricsAPI.image.registry | string | defaultRegistry | Docker registry for the metrics-api component |
 | metricsAPI.image.tag | string | linkerdVersion | Docker image tag for the metrics-api component |
+| metricsAPI.logFormat | string | defaultLogFormat | log format of the metrics-api component |
 | metricsAPI.logLevel | string | defaultLogLevel | log level of the metrics-api component |
 | metricsAPI.nodeSelector | object | `{"beta.kubernetes.io/os":"linux"}` | NodeSelector section, See the [K8S documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) for more information |
 | metricsAPI.proxy | string | `nil` |  |
@@ -144,6 +149,7 @@ Kubernetes: `>=1.16.0-0`
 | prometheus.image.pullPolicy | string | defaultImagePullPolicy | Pull policy for the prometheus instance |
 | prometheus.image.registry | string | `"prom"` | Docker registry for the prometheus instance |
 | prometheus.image.tag | string | `"v2.19.3"` | Docker image tag for the prometheus instance |
+| prometheus.logFormat | string | defaultLogLevel | log format (plain, json) of the prometheus instance |
 | prometheus.logLevel | string | defaultLogLevel | log level of the prometheus instance |
 | prometheus.nodeSelector | object | `{"beta.kubernetes.io/os":"linux"}` | NodeSelector section, See the [K8S documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) for more information |
 | prometheus.proxy | string | `nil` |  |
@@ -166,6 +172,7 @@ Kubernetes: `>=1.16.0-0`
 | tap.image.registry | string | defaultRegistry | Docker registry for the tap instance |
 | tap.image.tag | string | linkerdVersion | Docker image tag for the tap instance |
 | tap.keyPEM | string | `""` | Certificate key for Tap component. If not provided then Helm will generate one. |
+| tap.logFormat | string | defaultLogFormat | log format of the tap component |
 | tap.logLevel | string | defaultLogLevel | log level of the tap component |
 | tap.proxy | string | `nil` |  |
 | tap.replicas | int | `1` | Number of tap component replicas |
@@ -183,6 +190,7 @@ Kubernetes: `>=1.16.0-0`
 | tapInjector.image.registry | string | defaultRegistry | Docker registry for the tapInjector instance |
 | tapInjector.image.tag | string | linkerdVersion | Docker image tag for the tapInjector instance |
 | tapInjector.keyPEM | string | `""` | Certificate key for the tapInjector. If not provided then Helm will generate one. |
+| tapInjector.logFormat | string | defaultLogFormat | log format of the tapInjector component |
 | tapInjector.logLevel | string | defaultLogLevel | log level of the tapInjector |
 | tapInjector.namespaceSelector | string | `nil` |  |
 | tapInjector.objectSelector | string | `nil` |  |
diff --git a/viz/charts/linkerd-viz/templates/grafana.yaml b/viz/charts/linkerd-viz/templates/grafana.yaml
index 4f901b158..9019e68be 100644
--- a/viz/charts/linkerd-viz/templates/grafana.yaml
+++ b/viz/charts/linkerd-viz/templates/grafana.yaml
@@ -30,6 +30,11 @@ data:
     check_for_updates = false
     [panels]
     disable_sanitize_html = true
+    [log]
+    mode = console
+    [log.console]
+    format = {{ .Values.grafana.logFormat | default .Values.defaultLogFormat | replace "plain" "text" }}
+    level = {{ .Values.grafana.logLevel | default .Values.defaultLogLevel }}
   datasources.yaml: |-
     apiVersion: 1
     datasources:
diff --git a/viz/charts/linkerd-viz/templates/metrics-api.yaml b/viz/charts/linkerd-viz/templates/metrics-api.yaml
index ca6aab7f5..4e1e3838d 100644
--- a/viz/charts/linkerd-viz/templates/metrics-api.yaml
+++ b/viz/charts/linkerd-viz/templates/metrics-api.yaml
@@ -69,6 +69,7 @@ spec:
       - args:
         - -controller-namespace={{.Values.linkerdNamespace}}
         - -log-level={{.Values.metricsAPI.logLevel | default .Values.defaultLogLevel}}
+        - -log-format={{.Values.metricsAPI.logFormat | default .Values.defaultLogFormat}}
         - -cluster-domain={{.Values.clusterDomain}}
         {{- if .Values.prometheusUrl }}
         - -prometheus-url={{.Values.prometheusUrl}}
diff --git a/viz/charts/linkerd-viz/templates/prometheus.yaml b/viz/charts/linkerd-viz/templates/prometheus.yaml
index 111b5863b..2de7000ec 100644
--- a/viz/charts/linkerd-viz/templates/prometheus.yaml
+++ b/viz/charts/linkerd-viz/templates/prometheus.yaml
@@ -245,6 +245,9 @@ spec:
         {{- if not (hasKey .Values.prometheus.args "log.level") }}
         - --log.level={{.Values.prometheus.logLevel | default .Values.defaultLogLevel}}
         {{- end }}
+        {{- if not (hasKey .Values.prometheus.args "log.format") }}
+        - --log.format={{.Values.prometheus.logFormat | default .Values.defaultLogFormat | replace "plain" "logfmt" }}
+        {{- end }}
         {{- range $key, $value := .Values.prometheus.args}}
         - --{{ $key }}{{ if $value }}={{ $value }}{{ end }}
         {{- end }}
diff --git a/viz/charts/linkerd-viz/templates/tap-injector.yaml b/viz/charts/linkerd-viz/templates/tap-injector.yaml
index ce5c7e0df..5de1426c6 100644
--- a/viz/charts/linkerd-viz/templates/tap-injector.yaml
+++ b/viz/charts/linkerd-viz/templates/tap-injector.yaml
@@ -73,6 +73,7 @@ spec:
         - injector
         - -tap-service-name=tap.{{.Values.namespace}}.serviceaccount.identity.{{.Values.linkerdNamespace}}.{{.Values.identityTrustDomain | default .Values.clusterDomain}}
         - -log-level={{.Values.tapInjector.logLevel | default .Values.defaultLogLevel}}
+        - -log-format={{.Values.tapInjector.logFormat | default .Values.defaultLogFormat}}
         image: {{.Values.tapInjector.image.registry | default .Values.defaultRegistry}}/{{.Values.tapInjector.image.name}}:{{.Values.tapInjector.image.tag | default .Values.linkerdVersion}}
         imagePullPolicy: {{.Values.tapInjector.image.pullPolicy | default .Values.defaultImagePullPolicy}}
         livenessProbe:
diff --git a/viz/charts/linkerd-viz/templates/tap.yaml b/viz/charts/linkerd-viz/templates/tap.yaml
index 725237b8e..6f19682c3 100644
--- a/viz/charts/linkerd-viz/templates/tap.yaml
+++ b/viz/charts/linkerd-viz/templates/tap.yaml
@@ -82,6 +82,7 @@ spec:
         - api
         - -api-namespace={{.Values.linkerdNamespace}}
         - -log-level={{.Values.tap.logLevel | default .Values.defaultLogLevel}}
+        - -log-format={{.Values.tap.logFormat | default .Values.defaultLogFormat}}
         - -identity-trust-domain={{.Values.identityTrustDomain | default .Values.clusterDomain}}
         image: {{.Values.tap.image.registry | default .Values.defaultRegistry}}/{{.Values.tap.image.name}}:{{.Values.tap.image.tag | default .Values.linkerdVersion}}
         imagePullPolicy: {{.Values.tap.image.pullPolicy | default .Values.defaultImagePullPolicy}}
diff --git a/viz/charts/linkerd-viz/templates/web.yaml b/viz/charts/linkerd-viz/templates/web.yaml
index 2517f6805..cf5d0c362 100644
--- a/viz/charts/linkerd-viz/templates/web.yaml
+++ b/viz/charts/linkerd-viz/templates/web.yaml
@@ -80,6 +80,7 @@ spec:
         - -controller-namespace={{.Values.linkerdNamespace}}
         - -viz-namespace={{.Values.namespace}}
         - -log-level={{.Values.dashboard.logLevel | default .Values.defaultLogLevel}}
+        - -log-format={{.Values.dashboard.logFormat | default .Values.defaultLogFormat}}
         {{- if .Values.dashboard.enforcedHostRegexp }}
         - -enforced-host={{.Values.dashboard.enforcedHostRegexp}}
         {{- else -}}
diff --git a/viz/charts/linkerd-viz/values.yaml b/viz/charts/linkerd-viz/values.yaml
index 0e7db7047..f4a0295e8 100644
--- a/viz/charts/linkerd-viz/values.yaml
+++ b/viz/charts/linkerd-viz/values.yaml
@@ -18,6 +18,8 @@ defaultRegistry: cr.l5d.io/linkerd
 defaultImagePullPolicy: IfNotPresent
 # -- Log level for all the viz components
 defaultLogLevel: info
+# -- Log format (`plain` or `json`) for all the viz components.
+defaultLogFormat: plain
 # -- UID for all the viz components
 defaultUID: 2103
 
@@ -71,6 +73,9 @@ metricsAPI:
   # -- log level of the metrics-api component
   # @default -- defaultLogLevel
   logLevel: ""
+  # -- log format of the metrics-api component
+  # @default -- defaultLogFormat
+  logFormat: ""
   image:
     # -- Docker registry for the metrics-api component
     # @default -- defaultRegistry
@@ -119,6 +124,9 @@ tap:
   # -- log level of the tap component
   # @default -- defaultLogLevel
   logLevel: ""
+  # -- log format of the tap component
+  # @default -- defaultLogFormat
+  logFormat: ""
   image:
     # -- Docker registry for the tap instance
     # @default -- defaultRegistry
@@ -175,6 +183,9 @@ tapInjector:
   # -- log level of the tapInjector
   # @default -- defaultLogLevel
   logLevel: ""
+  # -- log format of the tapInjector component
+  # @default -- defaultLogFormat
+  logFormat: ""
   image:
     # -- Docker registry for the tapInjector instance
     # @default -- defaultRegistry
@@ -239,6 +250,9 @@ dashboard:
   # -- log level of the dashboard component
   # @default -- defaultLogLevel
   logLevel: ""
+  # -- log format of the dashboard component
+  # @default -- defaultLogFormat
+  logFormat: ""
   image:
     # -- Docker registry for the web instance
     # @default -- defaultRegistry
@@ -282,6 +296,12 @@ dashboard:
 grafana:
   # -- toggle field to enable or disable grafana
   enabled: true
+  # -- log level of the grafana instance
+  # @default -- defaultLogLevel
+  logLevel: ""
+  # -- log format (plain, json) of the grafana instance
+  # @default -- defaultLogFormat
+  logFormat: ""  
   image:
     # -- Docker registry for the grafana instance
     # @default -- defaultRegistry
@@ -337,6 +357,9 @@ prometheus:
   # -- log level of the prometheus instance
   # @default -- defaultLogLevel
   logLevel: ""
+  # -- log format (plain, json) of the prometheus instance
+  # @default -- defaultLogLevel
+  logFormat: ""
   # -- Command line options for Prometheus binary
   args:
     storage.tsdb.path: /data


Test patch:
diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml
index 8f0051fb1..18e166d7a 100644
--- a/.github/workflows/integration_tests.yml
+++ b/.github/workflows/integration_tests.yml
@@ -61,6 +61,7 @@ jobs:
         - upgrade-edge
         - upgrade-stable
         - cni-calico-deep
+        - default-policy-deny
     needs: [docker_build]
     name: Integration tests (${{ matrix.integration_test }})
     runs-on: ubuntu-20.04
diff --git a/bin/test-cleanup b/bin/test-cleanup
index a615052f6..9b54b2f87 100755
--- a/bin/test-cleanup
+++ b/bin/test-cleanup
@@ -26,7 +26,7 @@ echo "cleaning up cluster-scoped resources labelled with test.linkerd.io/is-test
 kubectl --context="$k8s_context" delete clusterRole,clusterRoleBindings,mutatingwebhookconfiguration -l test.linkerd.io/is-test-data-plane
 
 echo "cleaning up linkerd resources [${k8s_context}]"
-"$linkerd_path" uninstall 2> /dev/null | kubectl --context="$k8s_context" delete -f -
+"$linkerd_path" uninstall | kubectl --context="$k8s_context" delete -f -
 
 # Helm cleanup. Just the entries in `helm ls` as the resources should have already been cleaned up by the code above.
 releases=$("$bindir/helm" ls -A -q)
diff --git a/pkg/healthcheck/healthcheck_test.go b/pkg/healthcheck/healthcheck_test.go
index 5bb1162f3..7a5223b4a 100644
--- a/pkg/healthcheck/healthcheck_test.go
+++ b/pkg/healthcheck/healthcheck_test.go
@@ -1590,6 +1590,23 @@ func TestValidateDataPlanePods(t *testing.T) {
 		}
 	})
 
+	t.Run("Does not return an error if the pod is in Shutdown state", func(t *testing.T) {
+		pods := []corev1.Pod{
+			{
+				ObjectMeta: metav1.ObjectMeta{Name: "emoji-d9c7866bb-7v74n"},
+				Status: corev1.PodStatus{
+					Phase:  "Failed",
+					Reason: "Shutdown",
+				},
+			},
+		}
+
+		err := validateDataPlanePods(pods, "emojivoto")
+		if err != nil {
+			t.Fatalf("Expected no error, got %s", err)
+		}
+	})
+
 	t.Run("Returns an error if the proxy container is not ready", func(t *testing.T) {
 		pods := []corev1.Pod{
 			{
diff --git a/test/integration/install_test.go b/test/integration/install_test.go
index 06234af55..85689d2a3 100644
--- a/test/integration/install_test.go
+++ b/test/integration/install_test.go
@@ -839,9 +839,10 @@ func TestOverridesSecret(t *testing.T) {
 		}
 
 		if policy := TestHelper.DefaultAllowPolicy(); policy != "" {
-			knownKeys["policyController"] = tree.Tree{
-				"defaultAllowPolicy": policy,
+			if _, ok := knownKeys["policyController"]; !ok {
+				knownKeys["policyController"] = tree.Tree{}
 			}
+			knownKeys["policyController"].(tree.Tree)["defaultAllowPolicy"] = policy
 		}
 
 		// Check if the keys in overridesTree match with knownKeys
diff --git a/test/integration/testdata/check.viz.external-prometheus.golden b/test/integration/testdata/check.viz.external-prometheus.golden
index 727dd2b66..ab06465f3 100644
--- a/test/integration/testdata/check.viz.external-prometheus.golden
+++ b/test/integration/testdata/check.viz.external-prometheus.golden
@@ -11,7 +11,7 @@ linkerd-viz
 √ viz extension proxies are healthy
 ‼ viz extension proxies are up-to-date
     {{.ProxyVersionErr}}
-    see https://linkerd.io/2/checks/#l5d-viz-proxy-cp-version for hints
+    see {{.HintURL}}l5d-viz-proxy-cp-version for hints
 √ viz extension proxies and cli versions match
 √ can initialize the client
 √ viz extension self-check
diff --git a/viz/cmd/testdata/install_default.golden b/viz/cmd/testdata/install_default.golden
index 89cf20d4c..43256650c 100644
--- a/viz/cmd/testdata/install_default.golden
+++ b/viz/cmd/testdata/install_default.golden
@@ -515,6 +515,7 @@ spec:
       - args:
         - -controller-namespace=linkerd
         - -log-level=info
+        - -log-format=plain
         - -cluster-domain=cluster.local
         - -prometheus-url=http://prometheus.linkerd-viz.svc.cluster.local:9090
         image: cr.l5d.io/linkerd/metrics-api:dev-undefined
@@ -607,6 +608,11 @@ data:
     check_for_updates = false
     [panels]
     disable_sanitize_html = true
+    [log]
+    mode = console
+    [log.console]
+    format = text
+    level = info
   datasources.yaml: |-
     apiVersion: 1
     datasources:
@@ -975,6 +981,7 @@ spec:
       containers:
       - args:
         - --log.level=info
+        - --log.format=logfmt
         - --config.file=/etc/prometheus/prometheus.yml
         - --storage.tsdb.path=/data
         - --storage.tsdb.retention.time=6h
@@ -1081,6 +1088,7 @@ spec:
         - api
         - -api-namespace=linkerd
         - -log-level=info
+        - -log-format=plain
         - -identity-trust-domain=cluster.local
         image: cr.l5d.io/linkerd/tap:dev-undefined
         imagePullPolicy: IfNotPresent
@@ -1279,6 +1287,7 @@ spec:
         - injector
         - -tap-service-name=tap.linkerd-viz.serviceaccount.identity.linkerd.cluster.local
         - -log-level=info
+        - -log-format=plain
         image: cr.l5d.io/linkerd/tap:dev-undefined
         imagePullPolicy: IfNotPresent
         livenessProbe:
@@ -1412,6 +1421,7 @@ spec:
         - -controller-namespace=linkerd
         - -viz-namespace=linkerd-viz
         - -log-level=info
+        - -log-format=plain
         - -enforced-host=^(localhost|127\.0\.0\.1|web\.linkerd-viz\.svc\.cluster\.local|web\.linkerd-viz\.svc|\[::1\])(:\d+)?$
         image: cr.l5d.io/linkerd/web:dev-undefined
         imagePullPolicy: IfNotPresent
diff --git a/viz/cmd/testdata/install_default_overrides.golden b/viz/cmd/testdata/install_default_overrides.golden
index 10f7103bc..b5b2e57dd 100644
--- a/viz/cmd/testdata/install_default_overrides.golden
+++ b/viz/cmd/testdata/install_default_overrides.golden
@@ -515,6 +515,7 @@ spec:
       - args:
         - -controller-namespace=linkerd
         - -log-level=debug
+        - -log-format=plain
         - -cluster-domain=cluster.local
         - -prometheus-url=http://prometheus.linkerd-viz.svc.cluster.local:9090
         image: gcr.io/linkerd/metrics-api:dev-undefined
@@ -607,6 +608,11 @@ data:
     check_for_updates = false
     [panels]
     disable_sanitize_html = true
+    [log]
+    mode = console
+    [log.console]
+    format = text
+    level = debug
   datasources.yaml: |-
     apiVersion: 1
     datasources:
@@ -975,6 +981,7 @@ spec:
       containers:
       - args:
         - --log.level=debug
+        - --log.format=logfmt
         - --config.file=/etc/prometheus/prometheus.yml
         - --storage.tsdb.path=/data
         - --storage.tsdb.retention.time=6h
@@ -1081,6 +1088,7 @@ spec:
         - api
         - -api-namespace=linkerd
         - -log-level=info
+        - -log-format=plain
         - -identity-trust-domain=cluster.local
         image: cr.l5d.io/linkerd/tap:stable-9.2
         imagePullPolicy: IfNotPresent
@@ -1279,6 +1287,7 @@ spec:
         - injector
         - -tap-service-name=tap.linkerd-viz.serviceaccount.identity.linkerd.cluster.local
         - -log-level=debug
+        - -log-format=plain
         image: gcr.io/linkerd/tap:dev-undefined
         imagePullPolicy: IfNotPresent
         livenessProbe:
@@ -1412,6 +1421,7 @@ spec:
         - -controller-namespace=linkerd
         - -viz-namespace=linkerd-viz
         - -log-level=debug
+        - -log-format=plain
         - -enforced-host=^(localhost|127\.0\.0\.1|web\.linkerd-viz\.svc\.cluster\.local|web\.linkerd-viz\.svc|\[::1\])(:\d+)?$
         image: gcr.io/linkerd/web:dev-undefined
         imagePullPolicy: IfNotPresent
diff --git a/viz/cmd/testdata/install_grafana_disabled.golden b/viz/cmd/testdata/install_grafana_disabled.golden
index 94ce61fae..58d0a94f9 100644
--- a/viz/cmd/testdata/install_grafana_disabled.golden
+++ b/viz/cmd/testdata/install_grafana_disabled.golden
@@ -502,6 +502,7 @@ spec:
       - args:
         - -controller-namespace=linkerd
         - -log-level=info
+        - -log-format=plain
         - -cluster-domain=cluster.local
         - -prometheus-url=http://prometheus.linkerd-viz.svc.cluster.local:9090
         image: cr.l5d.io/linkerd/metrics-api:dev-undefined
@@ -761,6 +762,7 @@ spec:
       containers:
       - args:
         - --log.level=info
+        - --log.format=logfmt
         - --config.file=/etc/prometheus/prometheus.yml
         - --storage.tsdb.path=/data
         - --storage.tsdb.retention.time=6h
@@ -867,6 +869,7 @@ spec:
         - api
         - -api-namespace=linkerd
         - -log-level=info
+        - -log-format=plain
         - -identity-trust-domain=cluster.local
         image: cr.l5d.io/linkerd/tap:dev-undefined
         imagePullPolicy: IfNotPresent
@@ -1065,6 +1068,7 @@ spec:
         - injector
         - -tap-service-name=tap.linkerd-viz.serviceaccount.identity.linkerd.cluster.local
         - -log-level=info
+        - -log-format=plain
         image: cr.l5d.io/linkerd/tap:dev-undefined
         imagePullPolicy: IfNotPresent
         livenessProbe:
@@ -1198,6 +1202,7 @@ spec:
         - -controller-namespace=linkerd
         - -viz-namespace=linkerd-viz
         - -log-level=info
+        - -log-format=plain
         - -enforced-host=^(localhost|127\.0\.0\.1|web\.linkerd-viz\.svc\.cluster\.local|web\.linkerd-viz\.svc|\[::1\])(:\d+)?$
         image: cr.l5d.io/linkerd/web:dev-undefined
         imagePullPolicy: IfNotPresent
diff --git a/viz/cmd/testdata/install_prometheus_disabled.golden b/viz/cmd/testdata/install_prometheus_disabled.golden
index e71bc7e31..21da1dd5d 100644
--- a/viz/cmd/testdata/install_prometheus_disabled.golden
+++ b/viz/cmd/testdata/install_prometheus_disabled.golden
@@ -475,6 +475,7 @@ spec:
       - args:
         - -controller-namespace=linkerd
         - -log-level=info
+        - -log-format=plain
         - -cluster-domain=cluster.local
         - -prometheus-url=external-prom.com
         image: cr.l5d.io/linkerd/metrics-api:dev-undefined
@@ -567,6 +568,11 @@ data:
     check_for_updates = false
     [panels]
     disable_sanitize_html = true
+    [log]
+    mode = console
+    [log.console]
+    format = text
+    level = info
   datasources.yaml: |-
     apiVersion: 1
     datasources:
@@ -794,6 +800,7 @@ spec:
         - api
         - -api-namespace=linkerd
         - -log-level=info
+        - -log-format=plain
         - -identity-trust-domain=cluster.local
         image: cr.l5d.io/linkerd/tap:dev-undefined
         imagePullPolicy: IfNotPresent
@@ -992,6 +999,7 @@ spec:
         - injector
         - -tap-service-name=tap.linkerd-viz.serviceaccount.identity.linkerd.cluster.local
         - -log-level=info
+        - -log-format=plain
         image: cr.l5d.io/linkerd/tap:dev-undefined
         imagePullPolicy: IfNotPresent
         livenessProbe:
@@ -1125,6 +1133,7 @@ spec:
         - -controller-namespace=linkerd
         - -viz-namespace=linkerd-viz
         - -log-level=info
+        - -log-format=plain
         - -enforced-host=^(localhost|127\.0\.0\.1|web\.linkerd-viz\.svc\.cluster\.local|web\.linkerd-viz\.svc|\[::1\])(:\d+)?$
         image: cr.l5d.io/linkerd/web:dev-undefined
         imagePullPolicy: IfNotPresent
diff --git a/viz/cmd/testdata/install_prometheus_loglevel_from_args.golden b/viz/cmd/testdata/install_prometheus_loglevel_from_args.golden
index 16730418f..8e1c57c26 100644
--- a/viz/cmd/testdata/install_prometheus_loglevel_from_args.golden
+++ b/viz/cmd/testdata/install_prometheus_loglevel_from_args.golden
@@ -515,6 +515,7 @@ spec:
       - args:
         - -controller-namespace=linkerd
         - -log-level=info
+        - -log-format=plain
         - -cluster-domain=cluster.local
         - -prometheus-url=http://prometheus.linkerd-viz.svc.cluster.local:9090
         image: cr.l5d.io/linkerd/metrics-api:dev-undefined
@@ -607,6 +608,11 @@ data:
     check_for_updates = false
     [panels]
     disable_sanitize_html = true
+    [log]
+    mode = console
+    [log.console]
+    format = text
+    level = info
   datasources.yaml: |-
     apiVersion: 1
     datasources:
@@ -974,6 +980,7 @@ spec:
         fsGroup: 65534
       containers:
       - args:
+        - --log.format=logfmt
         - --config.file=/etc/prometheus/prometheus.yml
         - --log.level=debug
         - --storage.tsdb.path=/data
@@ -1081,6 +1088,7 @@ spec:
         - api
         - -api-namespace=linkerd
         - -log-level=info
+        - -log-format=plain
         - -identity-trust-domain=cluster.local
         image: cr.l5d.io/linkerd/tap:dev-undefined
         imagePullPolicy: IfNotPresent
@@ -1279,6 +1287,7 @@ spec:
         - injector
         - -tap-service-name=tap.linkerd-viz.serviceaccount.identity.linkerd.cluster.local
         - -log-level=info
+        - -log-format=plain
         image: cr.l5d.io/linkerd/tap:dev-undefined
         imagePullPolicy: IfNotPresent
         livenessProbe:
@@ -1412,6 +1421,7 @@ spec:
         - -controller-namespace=linkerd
         - -viz-namespace=linkerd-viz
         - -log-level=info
+        - -log-format=plain
         - -enforced-host=^(localhost|127\.0\.0\.1|web\.linkerd-viz\.svc\.cluster\.local|web\.linkerd-viz\.svc|\[::1\])(:\d+)?$
         image: cr.l5d.io/linkerd/web:dev-undefined
         imagePullPolicy: IfNotPresent
diff --git a/viz/cmd/testdata/install_proxy_resources.golden b/viz/cmd/testdata/install_proxy_resources.golden
index 11cc6ba70..026a6be06 100644
--- a/viz/cmd/testdata/install_proxy_resources.golden
+++ b/viz/cmd/testdata/install_proxy_resources.golden
@@ -515,6 +515,7 @@ spec:
       - args:
         - -controller-namespace=linkerd
         - -log-level=info
+        - -log-format=plain
         - -cluster-domain=cluster.local
         - -prometheus-url=http://prometheus.linkerd-viz.svc.cluster.local:9090
         image: cr.l5d.io/linkerd/metrics-api:dev-undefined
@@ -607,6 +608,11 @@ data:
     check_for_updates = false
     [panels]
     disable_sanitize_html = true
+    [log]
+    mode = console
+    [log.console]
+    format = text
+    level = info
   datasources.yaml: |-
     apiVersion: 1
     datasources:
@@ -983,6 +989,7 @@ spec:
       containers:
       - args:
         - --log.level=info
+        - --log.format=logfmt
         - --config.file=/etc/prometheus/prometheus.yml
         - --storage.tsdb.path=/data
         - --storage.tsdb.retention.time=6h
@@ -1093,6 +1100,7 @@ spec:
         - api
         - -api-namespace=linkerd
         - -log-level=info
+        - -log-format=plain
         - -identity-trust-domain=cluster.local
         image: cr.l5d.io/linkerd/tap:dev-undefined
         imagePullPolicy: IfNotPresent
@@ -1291,6 +1299,7 @@ spec:
         - injector
         - -tap-service-name=tap.linkerd-viz.serviceaccount.identity.linkerd.cluster.local
         - -log-level=info
+        - -log-format=plain
         image: cr.l5d.io/linkerd/tap:dev-undefined
         imagePullPolicy: IfNotPresent
         livenessProbe:
@@ -1428,6 +1437,7 @@ spec:
         - -controller-namespace=linkerd
         - -viz-namespace=linkerd-viz
         - -log-level=info
+        - -log-format=plain
         - -enforced-host=^(localhost|127\.0\.0\.1|web\.linkerd-viz\.svc\.cluster\.local|web\.linkerd-viz\.svc|\[::1\])(:\d+)?$
         image: cr.l5d.io/linkerd/web:dev-undefined
         imagePullPolicy: IfNotPresent