Repository: linkerd/linkerd2
Pull request #7627 (2022-01-17 14:37:30)

Helm add resource block linkerd-jaeger chart
<!--  Thanks for sending a pull request!

If you already have a well-structured git commit message, chances are GitHub
set the title and description of this PR to the git commit message subject and
body, respectively. If so, you may delete these instructions and submit your PR.

If this is your first time, please read our contributor guide:
https://github.com/linkerd/linkerd2/blob/main/CONTRIBUTING.md

The title and description of your Pull Request should match the git commit
subject and body, respectively. Git commit messages are structured as follows:

```
Subject

Problem

Solution

Validation

Fixes #[GitHub issue ID]

DCO Sign off
```

Example git commit message:

```
Introduce Pull Request Template

GitHub's community guidelines recommend a pull request template, the repo was
lacking one.

Introduce a `PULL_REQUEST_TEMPLATE.md` file.

Once merged, the
[Community profile checklist](https://github.com/linkerd/linkerd2/community)
should indicate the repo now provides a pull request template.

Fixes #3321

Signed-off-by: Jane Smith <jane.smith@example.com>
```

Note the git commit message subject becomes the pull request title.

For more details around git commits, see the section on Committing in our
contributor guide:
https://github.com/linkerd/linkerd2/blob/main/CONTRIBUTING.md#committing
-->
Subject

Problem
jaeger-injector deployment doesn't have resource block. 

Solution
Added into values and deployment resources block


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 96b25b048..42abecf3a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,17 @@
 # It is not intended for manual editing.
 version = 3
 
+[[package]]
+name = "ahash"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
+dependencies = [
+ "getrandom",
+ "once_cell",
+ "version_check",
+]
+
 [[package]]
 name = "aho-corasick"
 version = "0.7.18"
@@ -55,6 +66,17 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
 
+[[package]]
+name = "backoff"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1"
+dependencies = [
+ "getrandom",
+ "instant",
+ "rand",
+]
+
 [[package]]
 name = "base64"
 version = "0.13.0"
@@ -116,9 +138,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "3.0.7"
+version = "3.0.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12e8611f9ae4e068fa3e56931fded356ff745e70987ff76924a6e0ab1c8ef2e3"
+checksum = "8c506244a13c87262f84bf16369740d0b7c3850901b6a642aa41b031a710c473"
 dependencies = [
  "bitflags",
  "clap_derive",
@@ -725,9 +747,9 @@ dependencies = [
 
 [[package]]
 name = "kube"
-version = "0.65.0"
+version = "0.66.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ec231e9ec9e84789f9eb414d1ac40ce6c90d0517fb272a335b4233f2e272b1e"
+checksum = "f4b96944d327b752df4f62f3a31d8694892af06fb585747c0b5e664927823d1a"
 dependencies = [
  "k8s-openapi",
  "kube-client",
@@ -738,9 +760,9 @@ dependencies = [
 
 [[package]]
 name = "kube-client"
-version = "0.65.0"
+version = "0.66.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95dddb1fcced906d79cdae530ff39079c2d3772b2d623088fdbebe610bfa8217"
+checksum = "232db1af3d3680f9289cf0b4db51b2b9fee22550fc65d25869e39b23e0aaa696"
 dependencies = [
  "base64",
  "bytes",
@@ -762,6 +784,7 @@ dependencies = [
  "pin-project",
  "rustls 0.20.2",
  "rustls-pemfile",
+ "secrecy",
  "serde",
  "serde_json",
  "serde_yaml",
@@ -776,9 +799,9 @@ dependencies = [
 
 [[package]]
 name = "kube-core"
-version = "0.65.0"
+version = "0.66.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c52b6ab05d160691083430f6f431707a4e05b64903f2ffa0095ee5efde759117"
+checksum = "de491f8c9ee97117e0b47a629753e939c2392d5d0a40f6928e582a5fba328098"
 dependencies = [
  "chrono",
  "form_urlencoded",
@@ -786,6 +809,7 @@ dependencies = [
  "json-patch",
  "k8s-openapi",
  "once_cell",
+ "schemars",
  "serde",
  "serde_json",
  "thiserror",
@@ -793,9 +817,9 @@ dependencies = [
 
 [[package]]
 name = "kube-derive"
-version = "0.65.0"
+version = "0.66.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b98ff3d647085c6c025083efad0435890867f4bea042fc62d408ab3aeb1cdf66"
+checksum = "fcbb86bb3607245a67c8ad3a52aff41108f36b0d1e9e3e82ffb5760bfd84b965"
 dependencies = [
  "darling",
  "proc-macro2",
@@ -806,10 +830,11 @@ dependencies = [
 
 [[package]]
 name = "kube-runtime"
-version = "0.65.0"
+version = "0.66.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "406280d56304bc79b37af7f78e0d9719a4eebc3f46e5e79663154874b7696a48"
+checksum = "710729592eb30219b4e84898e91dc991fe09ccafe2c17fec4e45c3426c61abe0"
 dependencies = [
+ "backoff",
  "dashmap",
  "derivative",
  "futures",
@@ -870,6 +895,7 @@ dependencies = [
 name = "linkerd-policy-controller-core"
 version = "0.1.0"
 dependencies = [
+ "ahash",
  "anyhow",
  "async-trait",
  "futures",
@@ -910,6 +936,7 @@ dependencies = [
 name = "linkerd-policy-controller-k8s-index"
 version = "0.1.0"
 dependencies = [
+ "ahash",
  "anyhow",
  "async-stream",
  "async-trait",
@@ -1555,6 +1582,16 @@ dependencies = [
  "untrusted",
 ]
 
+[[package]]
+name = "secrecy"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e"
+dependencies = [
+ "serde",
+ "zeroize",
+]
+
 [[package]]
 name = "security-framework"
 version = "2.4.2"
@@ -1621,9 +1658,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.74"
+version = "1.0.75"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142"
+checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79"
 dependencies = [
  "indexmap",
  "itoa 1.0.1",
@@ -2051,9 +2088,9 @@ dependencies = [
 
 [[package]]
 name = "tracing-subscriber"
-version = "0.3.5"
+version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d81bfa81424cc98cb034b837c985b7a290f592e5b4322f353f94a0ab0f9f594"
+checksum = "77be66445c4eeebb934a7340f227bfe7b338173d3f8c00a60a5a58005c9faecf"
 dependencies = [
  "lazy_static",
  "matchers",
@@ -2299,3 +2336,9 @@ checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
 dependencies = [
  "linked-hash-map",
 ]
+
+[[package]]
+name = "zeroize"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc222aec311c323c717f56060324f32b82da1ce1dd81d9a09aa6a9030bfe08db"
diff --git a/jaeger/charts/linkerd-jaeger/README.md b/jaeger/charts/linkerd-jaeger/README.md
index 60e6f7086..df17b73e0 100644
--- a/jaeger/charts/linkerd-jaeger/README.md
+++ b/jaeger/charts/linkerd-jaeger/README.md
@@ -121,6 +121,10 @@ Kubernetes: `>=1.20.0-0`
 | webhook.namespaceSelector | string | `nil` |  |
 | webhook.nodeSelector | object | `{"kubernetes.io/os":"linux"}` | NodeSelector section, See the [K8S documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) for more information |
 | webhook.objectSelector | string | `nil` |  |
+| webhook.resources.cpu.limit | string | `nil` | Maximum amount of CPU units that the jaeger-injector container can use |
+| webhook.resources.cpu.request | string | `nil` | Amount of CPU units that the jaeger-injector container requests |
+| webhook.resources.memory.limit | string | `nil` | Maximum amount of memory that jaeger-injector container can use |
+| webhook.resources.memory.request | string | `nil` | Amount of memory that the jaeger-injector container requests |
 | webhook.tolerations | string | `nil` | Tolerations section, See the [K8S documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) for more information |
 
 ----------------------------------------------
diff --git a/jaeger/charts/linkerd-jaeger/templates/jaeger-injector.yaml b/jaeger/charts/linkerd-jaeger/templates/jaeger-injector.yaml
index ac2dd6ec7..88fc9716b 100644
--- a/jaeger/charts/linkerd-jaeger/templates/jaeger-injector.yaml
+++ b/jaeger/charts/linkerd-jaeger/templates/jaeger-injector.yaml
@@ -62,6 +62,9 @@ spec:
         - mountPath: /var/run/linkerd/tls
           name: tls
           readOnly: true
+        {{- if .Values.webhook.resources -}}
+        {{- include "partials.resources" .Values.webhook.resources | nindent 8 }}
+        {{- end }}
       serviceAccountName: jaeger-injector
       volumes:
       - name: tls
diff --git a/jaeger/charts/linkerd-jaeger/values.yaml b/jaeger/charts/linkerd-jaeger/values.yaml
index 14e39a2df..36a569bd1 100644
--- a/jaeger/charts/linkerd-jaeger/values.yaml
+++ b/jaeger/charts/linkerd-jaeger/values.yaml
@@ -19,7 +19,6 @@ enablePSP: false
 
 # -- Kubernetes DNS Domain name to use
 clusterDomain: cluster.local
-
 collector:
   # -- Set to false to exclude collector installation
   enabled: true
@@ -184,6 +183,18 @@ webhook:
     #matchLabels:
     #  foo: bar
 
+  resources:
+    cpu:
+      # -- Maximum amount of CPU units that the jaeger-injector container can use
+      limit:
+      # -- Amount of CPU units that the jaeger-injector container requests
+      request:
+    memory:
+      # -- Maximum amount of memory that jaeger-injector container can use
+      limit:
+      # -- Amount of memory that the jaeger-injector container requests
+      request:
+
   # -- NodeSelector section, See the
   # [K8S documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) for more information
   nodeSelector: *default_node_selector
diff --git a/policy-controller/Cargo.toml b/policy-controller/Cargo.toml
index d169ea2ee..fa9c9404b 100644
--- a/policy-controller/Cargo.toml
+++ b/policy-controller/Cargo.toml
@@ -16,7 +16,7 @@ clap = { version = "3", default-features = false, features = ["derive", "env", "
 drain = "0.1"
 futures = { version = "0.3", default-features = false }
 hyper = { version = "0.14", features = ["http1", "http2", "runtime", "server"] }
-kube = { version = "0.65", default-features = false, features = ["admission", "client"] }
+kube = { version = "0.66", default-features = false, features = ["admission", "client"] }
 linkerd-policy-controller-core = { path = "./core" }
 linkerd-policy-controller-grpc = { path = "./grpc" }
 linkerd-policy-controller-k8s-index = { path = "./k8s/index" }
diff --git a/policy-controller/core/Cargo.toml b/policy-controller/core/Cargo.toml
index 677c51f53..1c1d6eb80 100644
--- a/policy-controller/core/Cargo.toml
+++ b/policy-controller/core/Cargo.toml
@@ -6,6 +6,7 @@ license = "Apache-2.0"
 publish = false
 
 [dependencies]
+ahash = "0.7"
 anyhow = "1"
 async-trait = "0.1"
 futures = { version = "0.3", default-features = false, features = ["std"] }
diff --git a/policy-controller/core/src/lib.rs b/policy-controller/core/src/lib.rs
index 774365993..1a3e77ebe 100644
--- a/policy-controller/core/src/lib.rs
+++ b/policy-controller/core/src/lib.rs
@@ -5,10 +5,11 @@ mod identity_match;
 mod network_match;
 
 pub use self::{identity_match::IdentityMatch, network_match::NetworkMatch};
+use ahash::AHashMap as HashMap;
 use anyhow::Result;
 use futures::prelude::*;
 pub use ipnet::{IpNet, Ipv4Net, Ipv6Net};
-use std::{collections::HashMap, hash::Hash, pin::Pin, time::Duration};
+use std::{hash::Hash, pin::Pin, time::Duration};
 
 /// Models inbound server configuration discovery.
 #[async_trait::async_trait]
diff --git a/policy-controller/k8s/api/Cargo.toml b/policy-controller/k8s/api/Cargo.toml
index 8c787756c..c0072629d 100644
--- a/policy-controller/k8s/api/Cargo.toml
+++ b/policy-controller/k8s/api/Cargo.toml
@@ -8,7 +8,7 @@ publish = false
 [dependencies]
 futures = { version = "0.3", default-features = false }
 k8s-openapi = { version = "0.13", default-features = false, features = ["v1_20"] }
-kube = { version = "0.65", default-features = false, features = ["client", "derive", "runtime"] }
+kube = { version = "0.66", default-features = false, features = ["client", "derive", "runtime"] }
 schemars = "0.8"
 serde = { version = "1", features = ["derive"] }
 serde_json = "1"
diff --git a/policy-controller/k8s/index/Cargo.toml b/policy-controller/k8s/index/Cargo.toml
index bf62ddd07..f61068004 100644
--- a/policy-controller/k8s/index/Cargo.toml
+++ b/policy-controller/k8s/index/Cargo.toml
@@ -6,6 +6,7 @@ license = "Apache-2.0"
 publish = false
 
 [dependencies]
+ahash = "0.7"
 anyhow = "1"
 async-stream = "0.3"
 async-trait = "0.1"
diff --git a/policy-controller/k8s/index/src/authz.rs b/policy-controller/k8s/index/src/authz.rs
index 9ef9ba5f4..636f21f5d 100644
--- a/policy-controller/k8s/index/src/authz.rs
+++ b/policy-controller/k8s/index/src/authz.rs
@@ -1,4 +1,5 @@
 use crate::{server::ServerSelector, ClusterInfo, Errors, Index, SrvIndex};
+use ahash::{AHashMap as HashMap, AHashSet as HashSet};
 use anyhow::{anyhow, bail, Result};
 use linkerd_policy_controller_core::{
     ClientAuthentication, ClientAuthorization, IdentityMatch, IpNet, NetworkMatch,
@@ -8,7 +9,7 @@ use linkerd_policy_controller_k8s_api::{
     policy::{self, authz::MeshTls},
     ResourceExt,
 };
-use std::collections::{hash_map::Entry as HashEntry, HashMap, HashSet};
+use std::collections::hash_map::Entry;
 use tracing::{debug, instrument, trace};
 
 /// Indexes `ServerAuthorization` resources within a namespace.
@@ -142,12 +143,12 @@ impl AuthzIndex {
         let authz = mk_authz(authz, cluster)?;
 
         match self.index.entry(name) {
-            HashEntry::Vacant(entry) => {
+            Entry::Vacant(entry) => {
                 servers.add_authz(entry.key(), &authz.servers, authz.clients.clone());
                 entry.insert(authz);
             }
 
-            HashEntry::Occupied(mut entry) => {
+            Entry::Occupied(mut entry) => {
                 // If the authorization changed materially, then update it in all servers.
                 if entry.get() != &authz {
                     servers.add_authz(entry.key(), &authz.servers, authz.clients.clone());
diff --git a/policy-controller/k8s/index/src/defaults.rs b/policy-controller/k8s/index/src/defaults.rs
index b820dd942..5f2838159 100644
--- a/policy-controller/k8s/index/src/defaults.rs
+++ b/policy-controller/k8s/index/src/defaults.rs
@@ -1,11 +1,12 @@
 use crate::{ServerRx, ServerTx};
+use ahash::AHashMap as HashMap;
 use anyhow::{anyhow, Error, Result};
 use linkerd_policy_controller_core::{
     ClientAuthentication, ClientAuthorization, IdentityMatch, InboundServer, IpNet, NetworkMatch,
     ProxyProtocol,
 };
 use linkerd_policy_controller_k8s_api as k8s;
-use std::{collections::HashMap, hash::Hash};
+use std::hash::Hash;
 use tokio::{sync::watch, time};
 
 /// Indicates the default behavior to apply when no Server is found for a port.
diff --git a/policy-controller/k8s/index/src/lookup.rs b/policy-controller/k8s/index/src/lookup.rs
index 19df8323e..e2207d92a 100644
--- a/policy-controller/k8s/index/src/lookup.rs
+++ b/policy-controller/k8s/index/src/lookup.rs
@@ -1,11 +1,9 @@
 use crate::PodServerRx;
+use ahash::AHashMap as HashMap;
 use anyhow::{anyhow, Result};
 use linkerd_policy_controller_core::{DiscoverInboundServer, InboundServer, InboundServerStream};
 use parking_lot::RwLock;
-use std::{
-    collections::hash_map::{Entry, HashMap},
-    sync::Arc,
-};
+use std::{collections::hash_map::Entry, sync::Arc};
 
 #[derive(Debug, Default)]
 pub(crate) struct Writer(ByNs);
diff --git a/policy-controller/k8s/index/src/namespace.rs b/policy-controller/k8s/index/src/namespace.rs
index be1013ce1..a121ec767 100644
--- a/policy-controller/k8s/index/src/namespace.rs
+++ b/policy-controller/k8s/index/src/namespace.rs
@@ -1,5 +1,5 @@
 use crate::{authz::AuthzIndex, pod::PodIndex, server::SrvIndex, DefaultPolicy};
-use std::collections::HashMap;
+use ahash::AHashMap as HashMap;
 
 #[derive(Debug)]
 pub(crate) struct NamespaceIndex {
diff --git a/policy-controller/k8s/index/src/pod.rs b/policy-controller/k8s/index/src/pod.rs
index 2d10ba1d8..74f56e01a 100644
--- a/policy-controller/k8s/index/src/pod.rs
+++ b/policy-controller/k8s/index/src/pod.rs
@@ -2,9 +2,10 @@ use crate::{
     defaults::PortDefaults, lookup, DefaultPolicy, DefaultPolicyWatches, Errors, Index, Namespace,
     PodServerTx, ServerRx, SrvIndex,
 };
+use ahash::{AHashMap as HashMap, AHashSet as HashSet};
 use anyhow::{anyhow, bail, Context, Result};
 use linkerd_policy_controller_k8s_api::{self as k8s, policy, ResourceExt};
-use std::collections::{hash_map::Entry as HashEntry, HashMap, HashSet};
+use std::collections::hash_map::Entry;
 use tokio::sync::watch;
 use tracing::{debug, instrument, trace};
 
@@ -193,7 +194,7 @@ impl PodIndex {
         let ns_name = pod.namespace().expect("pod must have a namespace");
         let pod_name = pod.name();
         match self.index.entry(pod_name) {
-            HashEntry::Vacant(pod_entry) => {
+            Entry::Vacant(pod_entry) => {
                 let spec = pod.spec.ok_or_else(|| anyhow!("pod missing spec"))?;
 
                 // Check the pod for a default-allow annotation. If it's set, use it; otherwise use
@@ -239,7 +240,7 @@ impl PodIndex {
                 Ok(())
             }
 
-            HashEntry::Occupied(mut entry) => {
+            Entry::Occupied(mut entry) => {
                 debug_assert!(
                     lookups.contains(&ns_name, entry.key()),
                     "pod must exist in lookups"
diff --git a/policy-controller/k8s/index/src/server.rs b/policy-controller/k8s/index/src/server.rs
index ae10ef6eb..c9b0c5336 100644
--- a/policy-controller/k8s/index/src/server.rs
+++ b/policy-controller/k8s/index/src/server.rs
@@ -1,11 +1,9 @@
 use crate::{authz::AuthzIndex, Errors, Index, Namespace, ServerRx, ServerTx};
+use ahash::{AHashMap as HashMap, AHashSet as HashSet};
 use anyhow::{anyhow, bail, Result};
 use linkerd_policy_controller_core::{ClientAuthorization, InboundServer, ProxyProtocol};
 use linkerd_policy_controller_k8s_api::{self as k8s, policy, ResourceExt};
-use std::{
-    collections::{hash_map::Entry as HashEntry, HashMap, HashSet},
-    sync::Arc,
-};
+use std::{collections::hash_map::Entry, sync::Arc};
 use tokio::{sync::watch, time};
 use tracing::{debug, instrument, trace};
 
@@ -184,7 +182,7 @@ impl SrvIndex {
         let protocol = Self::mk_protocol(srv.spec.proxy_protocol.as_ref());
 
         match self.index.entry(srv_name) {
-            HashEntry::Vacant(entry) => {
+            Entry::Vacant(entry) => {
                 let labels = k8s::Labels::from(srv.metadata.labels);
                 let authzs = ns_authzs
                     .filter_for_server(entry.key(), labels.clone())
@@ -209,7 +207,7 @@ impl SrvIndex {
                 });
             }
 
-            HashEntry::Occupied(mut entry) => {
+            Entry::Occupied(mut entry) => {
                 trace!(srv = ?entry.get(), "Updating existing server");
 
                 // If something about the server changed, we need to update the config to reflect
diff --git a/web/app/package.json b/web/app/package.json
index f833068ed..68ee4bbdd 100644
--- a/web/app/package.json
+++ b/web/app/package.json
@@ -16,7 +16,7 @@
     "@material-ui/icons": "4.11.2",
     "@material-ui/lab": "^4.0.0-alpha.60",
     "classnames": "2.3.1",
-    "core-js": "^3.20.2",
+    "core-js": "^3.20.3",
     "css-mediaquery": "^0.1.2",
     "d3-drag": "3.0.0",
     "d3-force": "3.0.0",
diff --git a/web/app/yarn.lock b/web/app/yarn.lock
index 57fceb03f..1e2d76788 100644
--- a/web/app/yarn.lock
+++ b/web/app/yarn.lock
@@ -2953,10 +2953,10 @@ core-js-pure@^3.16.0:
   resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.18.0.tgz#e5187347bae66448c9e2d67c01c34c4df3261dc5"
   integrity sha512-ZnK+9vyuMhKulIGqT/7RHGRok8RtkHMEX/BGPHkHx+ouDkq+MUvf9mfIgdqhpmPDu8+V5UtRn/CbCRc9I4lX4w==
 
-core-js@^3.20.2:
-  version "3.20.2"
-  resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.20.2.tgz#46468d8601eafc8b266bd2dd6bf9dee622779581"
-  integrity sha512-nuqhq11DcOAbFBV4zCbKeGbKQsUDRqTX0oqx7AttUBuqe3h20ixsE039QHelbL6P4h+9kytVqyEtyZ6gsiwEYw==
+core-js@^3.20.3:
+  version "3.20.3"
+  resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.20.3.tgz#c710d0a676e684522f3db4ee84e5e18a9d11d69a"
+  integrity sha512-vVl8j8ph6tRS3B8qir40H7yw7voy17xL0piAjlbBUsH7WIfzoedL/ZOr1OV9FyZQLWXsayOJyV4tnRyXR85/ag==
 
 core-util-is@~1.0.0:
   version "1.0.3"


Test patch:
diff --git a/jaeger/cmd/testdata/install_collector_disabled.golden b/jaeger/cmd/testdata/install_collector_disabled.golden
index 79c15986b..961fc43a0 100644
--- a/jaeger/cmd/testdata/install_collector_disabled.golden
+++ b/jaeger/cmd/testdata/install_collector_disabled.golden
@@ -100,6 +100,7 @@ spec:
         - mountPath: /var/run/linkerd/tls
           name: tls
           readOnly: true
+        resources:
       serviceAccountName: jaeger-injector
       volumes:
       - name: tls
diff --git a/jaeger/cmd/testdata/install_default.golden b/jaeger/cmd/testdata/install_default.golden
index d3947ca68..61dd375ec 100644
--- a/jaeger/cmd/testdata/install_default.golden
+++ b/jaeger/cmd/testdata/install_default.golden
@@ -100,6 +100,7 @@ spec:
         - mountPath: /var/run/linkerd/tls
           name: tls
           readOnly: true
+        resources:
       serviceAccountName: jaeger-injector
       volumes:
       - name: tls
diff --git a/jaeger/cmd/testdata/install_jaeger_disabled.golden b/jaeger/cmd/testdata/install_jaeger_disabled.golden
index c57c549b1..c1778d183 100644
--- a/jaeger/cmd/testdata/install_jaeger_disabled.golden
+++ b/jaeger/cmd/testdata/install_jaeger_disabled.golden
@@ -100,6 +100,7 @@ spec:
         - mountPath: /var/run/linkerd/tls
           name: tls
           readOnly: true
+        resources:
       serviceAccountName: jaeger-injector
       volumes:
       - name: tls
diff --git a/policy-controller/k8s/index/src/tests.rs b/policy-controller/k8s/index/src/tests.rs
index e997bad1e..e9d1620cc 100644
--- a/policy-controller/k8s/index/src/tests.rs
+++ b/policy-controller/k8s/index/src/tests.rs
@@ -1,11 +1,12 @@
 use super::*;
+use ahash::AHashMap as HashMap;
 use futures::prelude::*;
 use linkerd_policy_controller_core::{
     ClientAuthentication, ClientAuthorization, IdentityMatch, IpNet, Ipv4Net, Ipv6Net,
     NetworkMatch, ProxyProtocol,
 };
 use linkerd_policy_controller_k8s_api::{policy::server::Port, ResourceExt};
-use std::{collections::HashMap, net::IpAddr, str::FromStr};
+use std::{net::IpAddr, str::FromStr};
 use tokio::time;
 
 /// Creates a pod, then a server, then an authorization--then deletes these resources in the reverse
diff --git a/test/integration/tracing/testdata/emojivoto.yaml b/test/integration/tracing/testdata/emojivoto.yaml
index 347787375..1f1c77bb1 100644
--- a/test/integration/tracing/testdata/emojivoto.yaml
+++ b/test/integration/tracing/testdata/emojivoto.yaml
@@ -1,193 +1,221 @@
----
-kind: ServiceAccount
 apiVersion: v1
+kind: ServiceAccount
 metadata:
   name: emoji
 ---
-kind: ServiceAccount
 apiVersion: v1
+kind: ServiceAccount
 metadata:
   name: voting
 ---
-kind: ServiceAccount
 apiVersion: v1
+kind: ServiceAccount
 metadata:
   name: web
 ---
+apiVersion: v1
+kind: Service
+metadata:
+  name: emoji-svc
+spec:
+  ports:
+  - name: grpc
+    port: 8080
+    targetPort: 8080
+  - name: prom
+    port: 8801
+    targetPort: 8801
+  selector:
+    app: emoji-svc
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: voting-svc
+spec:
+  ports:
+  - name: grpc
+    port: 8080
+    targetPort: 8080
+  - name: prom
+    port: 8801
+    targetPort: 8801
+  selector:
+    app: voting-svc
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: web-svc
+spec:
+  ports:
+  - name: http
+    port: 80
+    targetPort: 8080
+  selector:
+    app: web-svc
+  type: ClusterIP
+---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
-  creationTimestamp: null
+  labels:
+    app.kubernetes.io/name: emoji
+    app.kubernetes.io/part-of: emojivoto
+    app.kubernetes.io/version: v11
   name: emoji
 spec:
   replicas: 1
   selector:
     matchLabels:
       app: emoji-svc
-  strategy: {}
+      version: v11
   template:
     metadata:
-      creationTimestamp: null
       labels:
         app: emoji-svc
+        version: v11
+      annotations:
+        linkerd.io/inject: enabled
     spec:
-      serviceAccountName: emoji
       containers:
       - env:
         - name: GRPC_PORT
           value: "8080"
+        - name: PROM_PORT
+          value: "8801"
         - name: OC_AGENT_HOST
-          value: "collector.___TRACING_NS___:55678"
-        image: buoyantio/emojivoto-emoji-svc:v8-tracing
+          value: "collector.linkerd-jaeger:55678"
+        image: docker.l5d.io/buoyantio/emojivoto-emoji-svc:v11
         name: emoji-svc
         ports:
         - containerPort: 8080
           name: grpc
+        - containerPort: 8801
+          name: prom
         resources:
           requests:
             cpu: 100m
-status: {}
+      serviceAccountName: emoji
 ---
-apiVersion: v1
-kind: Service
+apiVersion: apps/v1
+kind: Deployment
 metadata:
-  name: emoji-svc
+  labels:
+    app.kubernetes.io/name: vote-bot
+    app.kubernetes.io/part-of: emojivoto
+    app.kubernetes.io/version: v11
+  name: vote-bot
 spec:
+  replicas: 1
   selector:
-    app: emoji-svc
-  clusterIP: None
-  ports:
-  - name: grpc
-    port: 8080
-    targetPort: 8080
+    matchLabels:
+      app: vote-bot
+      version: v11
+  template:
+    metadata:
+      labels:
+        app: vote-bot
+        version: v11
+      annotations:
+        linkerd.io/inject: enabled
+    spec:
+      containers:
+      - command:
+        - emojivoto-vote-bot
+        env:
+        - name: WEB_HOST
+          value: web-svc:80
+        - name: OC_AGENT_HOST
+          value: "collector.linkerd-jaeger:55678"
+        image: docker.l5d.io/buoyantio/emojivoto-web:v11
+        name: vote-bot
+        resources:
+          requests:
+            cpu: 10m
 ---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
-  creationTimestamp: null
+  labels:
+    app.kubernetes.io/name: voting
+    app.kubernetes.io/part-of: emojivoto
+    app.kubernetes.io/version: v11
   name: voting
 spec:
   replicas: 1
   selector:
     matchLabels:
       app: voting-svc
-  strategy: {}
+      version: v11
   template:
     metadata:
-      creationTimestamp: null
       labels:
         app: voting-svc
+        version: v11
+      annotations:
+        linkerd.io/inject: enabled
     spec:
-      serviceAccountName: voting
       containers:
       - env:
         - name: GRPC_PORT
           value: "8080"
+        - name: PROM_PORT
+          value: "8801"
         - name: OC_AGENT_HOST
-          value: "collector.___TRACING_NS___:55678"
-        image: buoyantio/emojivoto-voting-svc:v8-tracing
+          value: "collector.linkerd-jaeger:55678"
+        image: docker.l5d.io/buoyantio/emojivoto-voting-svc:v11
         name: voting-svc
         ports:
         - containerPort: 8080
           name: grpc
+        - containerPort: 8801
+          name: prom
         resources:
           requests:
             cpu: 100m
-status: {}
----
-apiVersion: v1
-kind: Service
-metadata:
-  name: voting-svc
-spec:
-  selector:
-    app: voting-svc
-  clusterIP: None
-  ports:
-  - name: grpc
-    port: 8080
-    targetPort: 8080
+      serviceAccountName: voting
 ---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
-  creationTimestamp: null
+  labels:
+    app.kubernetes.io/name: web
+    app.kubernetes.io/part-of: emojivoto
+    app.kubernetes.io/version: v11
   name: web
 spec:
   replicas: 1
   selector:
     matchLabels:
       app: web-svc
-  strategy: {}
+      version: v11
   template:
     metadata:
-      creationTimestamp: null
       labels:
         app: web-svc
+        version: v11
+      annotations:
+        linkerd.io/inject: enabled
     spec:
-      serviceAccountName: web
       containers:
       - env:
         - name: WEB_PORT
-          value: "80"
-        - name: OC_AGENT_HOST
-          value: "collector.___TRACING_NS___:55678"
+          value: "8080"
         - name: EMOJISVC_HOST
           value: emoji-svc:8080
         - name: VOTINGSVC_HOST
           value: voting-svc:8080
         - name: INDEX_BUNDLE
           value: dist/index_bundle.js
-        image: buoyantio/emojivoto-web:v8-tracing
+        - name: OC_AGENT_HOST
+          value: "collector.linkerd-jaeger:55678"
+        image: docker.l5d.io/buoyantio/emojivoto-web:v11
         name: web-svc
         ports:
-        - containerPort: 80
+        - containerPort: 8080
           name: http
         resources:
           requests:
             cpu: 100m
-status: {}
----
-apiVersion: v1
-kind: Service
-metadata:
-  name: web-svc
-spec:
-  type: LoadBalancer
-  selector:
-    app: web-svc
-  ports:
-  - name: http
-    port: 80
-    targetPort: 80
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  creationTimestamp: null
-  name: vote-bot
-spec:
-  replicas: 1
-  selector:
-    matchLabels:
-      app: vote-bot
-  strategy: {}
-  template:
-    metadata:
-      creationTimestamp: null
-      labels:
-        app: vote-bot
-    spec:
-      containers:
-      - command:
-        - emojivoto-vote-bot
-        env:
-        - name: WEB_HOST
-          value: nginx-ingress:80
-        image: buoyantio/emojivoto-web:v10
-        name: vote-bot
-        resources:
-          requests:
-            cpu: 10m
-status: {}
----
+      serviceAccountName: web
diff --git a/test/integration/tracing/testdata/ingress.yaml b/test/integration/tracing/testdata/ingress.yaml
deleted file mode 100644
index 0df572e9b..000000000
--- a/test/integration/tracing/testdata/ingress.yaml
+++ /dev/null
@@ -1,195 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
-  name: nginx-ingress
-  labels:
-    app: nginx-ingress
-rules:
-- apiGroups:
-  - ""
-  resources:
-  - configmaps
-  - endpoints
-  - nodes
-  - pods
-  - secrets
-  verbs:
-  - create
-  - update
-  - list
-  - watch
-  - get
-- apiGroups:
-  - ""
-  resources:
-  - nodes
-  verbs:
-  - get
-- apiGroups:
-  - ""
-  resources:
-  - services
-  verbs:
-  - get
-  - list
-  - update
-  - watch
-- apiGroups:
-  - extensions
-  resources:
-  - ingresses
-  verbs:
-  - get
-  - list
-  - watch
-- apiGroups:
-  - ""
-  resources:
-  - events
-  verbs:
-  - create
-  - patch
-- apiGroups:
-  - extensions
-  resources:
-  - ingresses/status
-  verbs:
-  - update
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
-  name: nginx-ingress
-  labels:
-    app: nginx-ingress
-roleRef:
-  apiGroup: rbac.authorization.k8s.io
-  kind: ClusterRole
-  name: nginx-ingress
-subjects:
-- kind: ServiceAccount
-  name: default
-  namespace: ___INGRESS_NAMESPACE___
----
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
-  name: web-nginx
-  annotations:
-    nginx.ingress.kubernetes.io/configuration-snippet: |
-      proxy_set_header l5d-dst-override $service_name.$namespace.svc.cluster.local:80;
-spec:
-  ingressClassName: nginx
-  rules:
-  - http:
-      paths:
-      - path: /
-        pathType: Prefix
-        backend:
-          service:
-            name: web-svc
-            port:
-              number: 80
----
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: nginx-ingress-controller
-  labels:
-    app: nginx-ingress
-data:
-  ssl-redirect: "false"
-  enable-opentracing: "true"
-  enable-vts-status: "false"
-  zipkin-collector-host: collector.___TRACING_NS___
-  zipkin-sample-rate: "0.5"
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  labels:
-    app: nginx-ingress
-  name: nginx-ingress
-spec:
-  replicas: 1
-  selector:
-    matchLabels:
-      app: nginx-ingress
-  template:
-    metadata:
-      labels:
-        app: nginx-ingress
-    spec:
-      containers:
-      - args:
-        - /nginx-ingress-controller
-        - --default-backend-service=
-        - --ingress-class=nginx
-        - --configmap=___INGRESS_NAMESPACE___/nginx-ingress-controller
-        env:
-        - name: POD_NAME
-          valueFrom:
-            fieldRef:
-              apiVersion: v1
-              fieldPath: metadata.name
-        - name: POD_NAMESPACE
-          valueFrom:
-            fieldRef:
-              apiVersion: v1
-              fieldPath: metadata.namespace
-        image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.22.0
-        imagePullPolicy: IfNotPresent
-        livenessProbe:
-          failureThreshold: 3
-          httpGet:
-            path: /healthz
-            port: 10254
-            scheme: HTTP
-          initialDelaySeconds: 10
-          periodSeconds: 10
-          successThreshold: 1
-          timeoutSeconds: 1
-        name: nginx-ingress-controller
-        ports:
-        - containerPort: 80
-          name: http
-          protocol: TCP
-        - containerPort: 443
-          name: https
-          protocol: TCP
-        readinessProbe:
-          failureThreshold: 3
-          httpGet:
-            path: /healthz
-            port: 10254
-            scheme: HTTP
-          initialDelaySeconds: 10
-          periodSeconds: 10
-          successThreshold: 1
-          timeoutSeconds: 1
-        resources: {}
-        securityContext:
-          capabilities:
-            add:
-            - NET_BIND_SERVICE
-            drop:
-            - ALL
-          procMount: Default
-          runAsUser: 33
-        terminationMessagePath: /dev/termination-log
-        terminationMessagePolicy: File
----
-apiVersion: v1
-kind: Service
-metadata:
-  name: nginx-ingress
-  labels:
-    app: nginx-ingress
-spec:
-  ports:
-  - name: http
-    port: 80
-    protocol: TCP
-    targetPort: http
-  selector:
-    app: nginx-ingress
diff --git a/test/integration/tracing/tracing_test.go b/test/integration/tracing/tracing_test.go
index 91773cd66..207b45b07 100644
--- a/test/integration/tracing/tracing_test.go
+++ b/test/integration/tracing/tracing_test.go
@@ -7,7 +7,6 @@ import (
 	"fmt"
 	"html/template"
 	"os"
-	"strings"
 	"testing"
 	"time"
 
@@ -51,11 +50,6 @@ func TestTracing(t *testing.T) {
 		t.Skip("Skipped. Jaeger & Open Census images does not support ARM yet")
 	}
 
-	// Require an environment variable to be set for this test to be run.
-	if os.Getenv("RUN_FLAKEY_TEST") == "" {
-		t.Skip("Skipping due to flakiness. See linkerd/linkerd2#7538")
-	}
-
 	// linkerd-jaeger extension
 	tracingNs := "linkerd-jaeger"
 	out, err := TestHelper.LinkerdRun("jaeger", "install")
@@ -113,130 +107,78 @@ func TestTracing(t *testing.T) {
 		testutil.AnnotatedFatal(t, fmt.Sprintf("'linkerd jaeger check' command timed-out (%s)", timeout), err)
 	}
 
-	// Emojivoto components
-	emojivotoNs := TestHelper.GetTestNamespace("emojivoto")
-	err = TestHelper.CreateDataPlaneNamespaceIfNotExists(ctx, emojivotoNs, nil)
-	if err != nil {
-		testutil.AnnotatedFatalf(t, fmt.Sprintf("failed to create %s namespace", emojivotoNs),
-			"failed to create %s namespace: %s", emojivotoNs, err)
-	}
-
-	emojivotoYaml, err := testutil.ReadFile("testdata/emojivoto.yaml")
-	if err != nil {
-		testutil.AnnotatedFatalf(t, "failed to read emojivoto yaml",
-			"failed to read emojivoto yaml\n%s\n", err)
-	}
-	emojivotoYaml = strings.ReplaceAll(emojivotoYaml, "___TRACING_NS___", tracingNs)
-	out, stderr, err := TestHelper.PipeToLinkerdRun(emojivotoYaml, "inject", "-")
-	if err != nil {
-		testutil.AnnotatedFatalf(t, "'linkerd inject' command failed",
-			"'linkerd inject' command failed\n%s\n%s", out, stderr)
-	}
-
-	out, err = TestHelper.KubectlApply(out, emojivotoNs)
-	if err != nil {
-		testutil.AnnotatedFatalf(t, "'kubectl apply' command failed",
-			"'kubectl apply' command failed\n%s", out)
-	}
-
-	// Ingress components
-	// Ingress must run in the same namespace as the service it routes to (web)
-	ingressNs := emojivotoNs
-	err = TestHelper.CreateDataPlaneNamespaceIfNotExists(ctx, ingressNs, nil)
-	if err != nil {
-		testutil.AnnotatedFatalf(t, fmt.Sprintf("failed to create %s namespace", ingressNs),
-			"failed to create %s namespace: %s", ingressNs, err)
-	}
-
-	ingressYaml, err := testutil.ReadFile("testdata/ingress.yaml")
-	if err != nil {
-		testutil.AnnotatedFatalf(t, "failed to read ingress yaml",
-			"failed to read ingress yaml\n%s\n", err)
-	}
-	ingressYaml = strings.ReplaceAll(ingressYaml, "___INGRESS_NAMESPACE___", ingressNs)
-	ingressYaml = strings.ReplaceAll(ingressYaml, "___TRACING_NS___", tracingNs)
-	out, stderr, err = TestHelper.PipeToLinkerdRun(ingressYaml, "inject", "-")
-	if err != nil {
-		testutil.AnnotatedFatalf(t, "'linkerd inject' command failed",
-			"'linkerd inject' command failed\n%s\n%s", out, stderr)
-	}
-
-	out, err = TestHelper.KubectlApply(out, ingressNs)
-	if err != nil {
-		testutil.AnnotatedFatalf(t, "'kubectl apply' command failed",
-			"'kubectl apply' command failed\n%s", out)
-	}
-
-	// wait for deployments to start
-	for _, deploy := range []struct {
-		ns   string
-		name string
-	}{
-		{ns: emojivotoNs, name: "vote-bot"},
-		{ns: emojivotoNs, name: "web"},
-		{ns: emojivotoNs, name: "emoji"},
-		{ns: emojivotoNs, name: "voting"},
-		{ns: ingressNs, name: "nginx-ingress"},
-		{ns: tracingNs, name: "collector"},
-		{ns: tracingNs, name: "jaeger"},
-	} {
-		if err := TestHelper.CheckPods(ctx, deploy.ns, deploy.name, 1); err != nil {
-			if rce, ok := err.(*testutil.RestartCountError); ok {
-				testutil.AnnotatedWarn(t, "CheckPods timed-out", rce)
-			} else {
-				testutil.AnnotatedError(t, "CheckPods timed-out", err)
-			}
+	TestHelper.WithDataPlaneNamespace(ctx, "tracing-test", map[string]string{}, t, func(t *testing.T, namespace string) {
+		emojivotoYaml, err := testutil.ReadFile("testdata/emojivoto.yaml")
+		if err != nil {
+			testutil.AnnotatedFatalf(t, "failed to read emojivoto yaml",
+				"failed to read emojivoto yaml\n%s\n", err)
 		}
-	}
-
-	t.Run("expect full trace", func(t *testing.T) {
 
-		timeout := 120 * time.Second
-		err = TestHelper.RetryFor(timeout, func() error {
-			url, err := TestHelper.URLFor(ctx, tracingNs, "jaeger", 16686)
-			if err != nil {
-				return err
-			}
+		out, err = TestHelper.KubectlApply(emojivotoYaml, namespace)
+		if err != nil {
+			testutil.AnnotatedFatalf(t, "'kubectl apply' command failed",
+				"'kubectl apply' command failed\n%s", out)
+		}
 
-			tracesJSON, err := TestHelper.HTTPGetURL(url + "/jaeger/api/traces?lookback=1h&service=nginx")
-			if err != nil {
-				return err
+		// wait for deployments to start
+		for _, deploy := range []struct {
+			ns   string
+			name string
+		}{
+			{ns: namespace, name: "vote-bot"},
+			{ns: namespace, name: "web"},
+			{ns: namespace, name: "emoji"},
+			{ns: namespace, name: "voting"},
+			{ns: tracingNs, name: "collector"},
+			{ns: tracingNs, name: "jaeger"},
+		} {
+			if err := TestHelper.CheckPods(ctx, deploy.ns, deploy.name, 1); err != nil {
+				if rce, ok := err.(*testutil.RestartCountError); ok {
+					testutil.AnnotatedWarn(t, "CheckPods timed-out", rce)
+				} else {
+					testutil.AnnotatedError(t, "CheckPods timed-out", err)
+				}
 			}
-			traces := traces{}
+		}
 
-			err = json.Unmarshal([]byte(tracesJSON), &traces)
+		t.Run("expect full trace", func(t *testing.T) {
+			timeout := 3 * time.Minute
+			err = TestHelper.RetryFor(timeout, func() error {
+				url, err := TestHelper.URLFor(ctx, tracingNs, "jaeger", 16686)
+				if err != nil {
+					return err
+				}
+
+				tracesJSON, err := TestHelper.HTTPGetURL(url + "/jaeger/api/traces?lookback=1h&service=linkerd-proxy")
+				if err != nil {
+					return err
+				}
+				traces := traces{}
+
+				err = json.Unmarshal([]byte(tracesJSON), &traces)
+				if err != nil {
+					return err
+				}
+
+				if !hasTraceWithProcess(&traces, "linkerd-proxy") {
+					return fmt.Errorf("No trace found with processes: linkerd-proxy")
+				}
+				return nil
+			})
 			if err != nil {
-				return err
+				testutil.AnnotatedFatal(t, fmt.Sprintf("timed-out checking trace (%s)", timeout), err)
 			}
-
-			processes := []string{"nginx", "web", "emoji", "voting", "linkerd-proxy"}
-			if !hasTraceWithProcesses(&traces, processes) {
-				return fmt.Errorf("No trace found with processes: %s", processes)
-			}
-			return nil
 		})
-		if err != nil {
-			testutil.AnnotatedFatal(t, fmt.Sprintf("timed-out checking trace (%s)", timeout), err)
-		}
 	})
 }
 
-func hasTraceWithProcesses(traces *traces, ps []string) bool {
+func hasTraceWithProcess(traces *traces, ps string) bool {
 	for _, trace := range traces.Data {
-		if containsProcesses(trace, ps) {
-			return true
+		for _, process := range trace.Processes {
+			if process.ServiceName == ps {
+				return true
+			}
 		}
 	}
 	return false
 }
-
-func containsProcesses(trace trace, ps []string) bool {
-	toFind := make(map[string]struct{})
-	for _, p := range ps {
-		toFind[p] = struct{}{}
-	}
-	for _, p := range trace.Processes {
-		delete(toFind, p.ServiceName)
-	}
-	return len(toFind) == 0
-}