Repository: linkerd/linkerd2
Pull request #4291 (2020-04-24 17:45:10)

Add Kubeconfig contex namespace to cli commands' options (#4197)
### Issue: #4197 
---

### What

According to the original issue, when using a `cli` command that operates on namespaced resources, the `-n` flag has to be used even when the resources are in the __default namespace of the Kubeconfig context__.  For example, if the currently used context by the Kubeconfig has the default namespace as `emojivoto`, doing `kubectl get pods` should list everything under the `emojivoto namespace`. Issue #4197 requested similar behaviour out of the `cli` commands. 
 

### How

* The `cli` has a set of options for each command. In implementing this feature, my first step was to compile a list of commands that act on namespaced resources and accept an `-n` flag. The command names are listed below:
```
(linkerd)
1. metrics
2. edges
3. get
4. profile
5. routes
6. top
7. tap
```

* I added a new function in `cli/cmd/root.go` called `getDefaultNamespace()` that infers the default namespace based on the currently active context. To do, it makes use of loading rules and and a `DeferredLoadingClient`. Once the loader is initialised with the loading rules, we can get access to the client configuration (i.e kubeconfig) and find the namespace associated with the currently active context (through the `Namespace()` function).
* For each command previously listed, in the `options` structure, instead of hardcoding the default namespace as `default` or `""`, I initialise it using the `getDefaultNamespace()` function.

* I thought in this case unit tests are trivial, since it would only test if a string = another string, and mostly test the functionality of `client-go`. Instead, I wrote a new function in the integration test helper that allows changing the default namespace of the currently used context. 
* I thought a full integration test might not be the best use of space, so I have instead added two new cases to the integration tests of `linkerd get` and `linkerd tap` respectively. My rationale is that if it works for these two, it will work for the rest since it's the same principle. I chose `get` and `tap` because they included more than one case each and it made the most sense (from a design perspective).

Looking forward to some feedback :) 

Signed-off-by: Matei David <matei.david.35@gmail.com>

<!--  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/master/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/master/CONTRIBUTING.md#committing
-->


grampelberg: The context is insanely helpful, thank you @Matei207 !
Matei207: > The context is insanely helpful, thank you @Matei207 !

Thank you for the encouragement! I seemed to have run into some issues with the integration tests, I will deal with it asap. Meanwhile, if there are any other changes that would benefit this PR let me know and I'll add them in.

Patch:
diff --git a/charts/linkerd2/README.md b/charts/linkerd2/README.md
index 24d158d3b..8ffa8a658 100644
--- a/charts/linkerd2/README.md
+++ b/charts/linkerd2/README.md
@@ -82,80 +82,83 @@ helm install \
 
 The following table lists the configurable parameters of the Linkerd2 chart and their default values.
 
-| Parameter                             | Description                                                                                                                                                                           | Default                              |
-|:--------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------|
-| `controllerImage`                     | Docker image for the controller, tap and identity components                                                                                                                          | `gcr.io/linkerd-io/controller`       |
-| `controllerImageVersion`              | Tag for the controller container docker image                                                                                                                                         | latest version                       |
-| `controllerLogLevel`                  | Log level for the control plane components                                                                                                                                            | `info`                               |
-| `controllerReplicas`                  | Number of replicas for each control plane pod                                                                                                                                         | `1`                                  |
-| `controllerUID`                       | User ID for the control plane components                                                                                                                                              | `2103`                               |
-| `dashboard.replicas`                  | Number of replicas of dashboard                                                                                                                                                       | `1`                                  |
-| `debugContainer.image.name`           | Docker image for the debug container                                                                                                                                                  | `gcr.io/linkerd-io/debug`            |
-| `debugContainer.image.pullPolicy`     | Pull policy for the debug container Docker image                                                                                                                                      | `IfNotPresent`                       |
-| `debugContainer.image.version`        | Tag for the debug container Docker image                                                                                                                                              | latest version                       |
-| `disableHeartBeat`                    | Set to true to not start the heartbeat cronjob                                                                                                                                        | `false`                              |
-| `enableH2Upgrade`                     | Allow proxies to perform transparent HTTP/2 upgrading                                                                                                                                 | `true`                               |
-| `global.clusterDomain`                       | Kubernetes DNS Domain name to use                                                                                                                                                     | `cluster.local`                      |
-| `global.cniEnabled`                          | Omit the NET_ADMIN capability in the PSP and the proxy-init container when injecting the proxy; requires the linkerd-cni plugin to already be installed                               | `false`                      |
-| `global.controllerComponentLabel`            | Control plane label. Do not edit                                                                                                                                                      | `linkerd.io/control-plane-component` |
-| `global.controllerNamespaceLabel`            | Control plane label. Do not edit                                                                                                                                                      | `linkerd.io/control-plane-component` |
-| `global.createdByAnnotation`                 | Annotation label for the proxy create. Do not edit.                                                                                                                                   | `linkerd.io/created-by`              |
-| `global.identityTrustAnchorsPEM`            | Trust root certificate (ECDSA). It must be provided during install.                                                                                                                                                         ||
+| Parameter                                   | Description                                                                                                                                                                           | Default                              |
+|:--------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------|
+| `controllerImage`                           | Docker image for the controller, tap and identity components                                                                                                                          | `gcr.io/linkerd-io/controller`       |
+| `controllerImageVersion`                    | Tag for the controller container docker image                                                                                                                                         | latest version                       |
+| `controllerLogLevel`                        | Log level for the control plane components                                                                                                                                            | `info`                               |
+| `controllerReplicas`                        | Number of replicas for each control plane pod                                                                                                                                         | `1`                                  |
+| `controllerUID`                             | User ID for the control plane components                                                                                                                                              | `2103`                               |
+| `dashboard.replicas`                        | Number of replicas of dashboard                                                                                                                                                       | `1`                                  |
+| `debugContainer.image.name`                 | Docker image for the debug container                                                                                                                                                  | `gcr.io/linkerd-io/debug`            |
+| `debugContainer.image.pullPolicy`           | Pull policy for the debug container Docker image                                                                                                                                      | `IfNotPresent`                       |
+| `debugContainer.image.version`              | Tag for the debug container Docker image                                                                                                                                              | latest version                       |
+| `disableHeartBeat`                          | Set to true to not start the heartbeat cronjob                                                                                                                                        | `false`                              |
+| `enableH2Upgrade`                           | Allow proxies to perform transparent HTTP/2 upgrading                                                                                                                                 | `true`                               |
+| `global.clusterDomain`                      | Kubernetes DNS Domain name to use                                                                                                                                                     | `cluster.local`                      |
+| `global.cniEnabled`                         | Omit the NET_ADMIN capability in the PSP and the proxy-init container when injecting the proxy; requires the linkerd-cni plugin to already be installed                               | `false`                              |
+| `global.controllerComponentLabel`           | Control plane label. Do not edit                                                                                                                                                      | `linkerd.io/control-plane-component` |
+| `global.controllerNamespaceLabel`           | Control plane label. Do not edit                                                                                                                                                      | `linkerd.io/control-plane-component` |
+| `global.createdByAnnotation`                | Annotation label for the proxy create. Do not edit.                                                                                                                                   | `linkerd.io/created-by`              |
+| `global.identityTrustAnchorsPEM`            | Trust root certificate (ECDSA). It must be provided during install.                                                                                                                   |                                      |
 | `global.identityTrustDomain`                | Trust domain used for identity                                                                                                                                                        | `cluster.local`                      |
-| `global.imagePullPolicy`                     | Docker image pull policy                                                                                                                                                              | `IfNotPresent`                       |
-| `global.linkerdNamespaceLabel`               | Control plane label. Do not edit                                                                                                                                                      | `linkerd.io/control-plane-component` |
-| `global.linkerdVersion`                      | Control plane version                                                                                                                                                                 | latest version                       |
-| `global.namespace`                           | Control plane namespace                                                                                                                                                               | `linkerd`                            |
-| `global.proxy.enableExternalProfiles`        | Enable service profiles for non-Kubernetes services                                                                                                                                   | `false`                              |
-| `global.proxy.image.name`                    | Docker image for the proxy                                                                                                                                                            | `gcr.io/linkerd-io/proxy`            |
-| `global.proxy.image.pullPolicy`              | Pull policy for the proxy container Docker image                                                                                                                                      | `IfNotPresent`                       |
-| `global.proxy.image.version`                 | Tag for the proxy container Docker image                                                                                                                                              | latest version                       |
-| `global.proxy.logLevel`                      | Log level for the proxy                                                                                                                                                               | `warn,linkerd=info`           |
-| `global.proxy.ports.admin`                   | Admin port for the proxy container                                                                                                                                                    | `4191`                               |
-| `global.proxy.ports.control`                 | Control port for the proxy container                                                                                                                                                  | `4190`                               |
-| `global.proxy.ports.inbound`                 | Inbound port for the proxy container                                                                                                                                                  | `4143`                               |
-| `global.proxy.ports.outbound`                | Outbound port for the proxy container                                                                                                                                                 | `4140`                               |
-| `global.proxy.resources.cpu.limit`           | Maximum amount of CPU units that the proxy can use                                                                                                                                                                          ||
-| `global.proxy.resources.cpu.request`         | Amount of CPU units that the proxy requests                                                                                                                                                                                 ||
-| `global.proxy.resources.memory.limit`        | Maximum amount of memory that the proxy can use                                                                                                                                                                             ||
-| `global.proxy.resources.memory.request`      | Amount of memory that the proxy requests                                                                                                                                                                                    ||
-| `global.proxy.trace.collectorSvcAccount`     | Service account associated with the Trace collector instance                                                                                                                                                                ||
-| `global.proxy.trace.collectorSvcAddr`        | Collector Service address for the proxies to send Trace Data                                                                                                                                                                ||
-| `global.proxy.uid`                           | User id under which the proxy runs                                                                                                                                                    | `2102`                               |
-| `global.proxy.waitBeforeExitSeconds`         | The proxy sidecar will stay alive for at least the given period before receiving SIGTERM signal from Kubernetes but no longer than pod's `terminationGracePeriodSeconds`.             | `0`                                  |
-| `global.proxyInit.ignoreInboundPorts`        | Inbound ports the proxy should ignore                                                                                                                                                                                       ||
-| `global.proxyInit.ignoreOutboundPorts`       | Outbound ports the proxy should ignore                                                                                                                                                                                      ||
-| `global.proxyInit.image.name`                | Docker image for the proxy-init container                                                                                                                                             | `gcr.io/linkerd-io/proxy-init`       |
-| `global.proxyInit.image.pullPolicy`          | Pull policy for the proxy-init container Docker image                                                                                                                                 | `IfNotPresent`                       |
-| `global.proxyInit.image.version`             | Tag for the proxy-init container Docker image                                                                                                                                         | latest version                       |
-| `global.proxyInit.resources.cpu.limit`       | Maximum amount of CPU units that the proxy-init container can use                                                                                                                     | `100m`                               |
-| `global.proxyInit.resources.cpu.request`     | Amount of CPU units that the proxy-init container requests                                                                                                                            | `10m`                                |
-| `global.ProxyInit.resources.memory.limit`    | Maximum amount of memory that the proxy-init container can use                                                                                                                        | `50Mi`                               |
-| `global.proxyInit.resources.memory.request`  | Amount of memory that the proxy-init container requests                                                                                                                               | `10Mi`                               |
-| `global.proxyInjectAnnotation`               | Annotation label to signal injection. Do not edit.                                                                                                                                                                          ||
-| `global.proxyInjectDisabled`                 | Annotation value to disable injection. Do not edit.                                                                                                                                   | `disabled`                           |
-| `grafanaImage`                        | Docker image for the Grafana container                                                                                                                                                | `gcr.io/linkerd-io/grafana`          |
-| `heartbeatSchedule`                   | Config for the heartbeat cronjob                                                                                                                                                      | `0 0 * * *`                          |
-| `identity.issuer.clockSkewAllowance`  | Amount of time to allow for clock skew within a Linkerd cluster                                                                                                                       | `20s`                                |
-| `identity.issuer.crtExpiry`           | Expiration timestamp for the issuer certificate. It must be provided during install                                                                                                                                         ||
-| `identity.issuer.crtExpiryAnnotation` | Annotation used to identity the issuer certificate expiration timestamp. Do not edit.                                                                                                 | `linkerd.io/identity-issuer-expiry`  |
-| `identity.issuer.issuanceLifetime`    | Amount of time for which the Identity issuer should certify identity                                                                                                                  | `86400s`                             |
-| `identity.issuer.scheme`              | Which scheme is used for the identity issuer secret format                                                                                                                            | `linkerd.io/tls`                     |
-| `identity.issuer.tls.crtPEM`          | Issuer certificate (ECDSA). It must be provided during install.                                                                                                                                                             ||
-| `identity.issuer.tls.keyPEM`          | Key for the issuer certificate (ECDSA). It must be provided during install.                                                                                                                                                 ||
-| `installNamespace`                    | Set to false when installing Linkerd in a custom namespace. See the [Linkerd documentation](https://linkerd.io/2/tasks/install-helm/#customizing-the-namespace) for more information. | `true`                               |
-| `omitWebhookSideEffects`              | Omit the `sideEffects` flag in the webhook manifests                                                                                                                                  | `false`                              |
-| `prometheusImage`                     | Docker image for the Prometheus container                                                                                                                                             | `prom/prometheus:v2.15.2`            |
-| `prometheusLogLevel`                  | Log level for Prometheus                                                                                                                                                              | `info`                               |
-| `proxyInjector.crtPEM`                | Certificate for the proxy injector. If not provided then Helm will generate one.                                                                                                                                            ||
-| `proxyInjector.keyPEM`                | Certificate key for the proxy injector. If not provided then Helm will generate one.                                                                                                                                        ||
-| `profileValidator.crtPEM`             | Certificate for the service profile validator. If not provided then Helm will generate one.                                                                                                                                 ||
-| `profileValidator.keyPEM`             | Certificate key for the service profile validator. If not provided then Helm will generate one.                                                                                                                             ||
-| `tap.crtPEM`                          | Certificate for the Tap component. If not provided then Helm will generate one.                                                                                                                                             ||
-| `tap.keyPEM`                          | Certificate key for Tap component. If not provided then Helm will generate one.                                                                                                                                             ||
-| `webhookFailurePolicy`                | Failure policy for the proxy injector                                                                                                                                                 | `Ignore`                             |
-| `webImage`                            | Docker image for the web container                                                                                                                                                    | `gcr.io/linkerd-io/web`              |
-| `enforcedHostRegexp`                  | Host header validation regex for the dashboard. See the [Linkerd documentation](https://linkerd.io/2/tasks/exposing-dashboard) for more information                                   | `""`              |
+| `global.imagePullPolicy`                    | Docker image pull policy                                                                                                                                                              | `IfNotPresent`                       |
+| `global.linkerdNamespaceLabel`              | Control plane label. Do not edit                                                                                                                                                      | `linkerd.io/control-plane-component` |
+| `global.linkerdVersion`                     | Control plane version                                                                                                                                                                 | latest version                       |
+| `global.namespace`                          | Control plane namespace                                                                                                                                                               | `linkerd`                            |
+| `global.proxy.enableExternalProfiles`       | Enable service profiles for non-Kubernetes services                                                                                                                                   | `false`                              |
+| `global.proxy.image.name`                   | Docker image for the proxy                                                                                                                                                            | `gcr.io/linkerd-io/proxy`            |
+| `global.proxy.image.pullPolicy`             | Pull policy for the proxy container Docker image                                                                                                                                      | `IfNotPresent`                       |
+| `global.proxy.image.version`                | Tag for the proxy container Docker image                                                                                                                                              | latest version                       |
+| `global.proxy.logLevel`                     | Log level for the proxy                                                                                                                                                               | `warn,linkerd=info`                  |
+| `global.proxy.ports.admin`                  | Admin port for the proxy container                                                                                                                                                    | `4191`                               |
+| `global.proxy.ports.control`                | Control port for the proxy container                                                                                                                                                  | `4190`                               |
+| `global.proxy.ports.inbound`                | Inbound port for the proxy container                                                                                                                                                  | `4143`                               |
+| `global.proxy.ports.outbound`               | Outbound port for the proxy container                                                                                                                                                 | `4140`                               |
+| `global.proxy.resources.cpu.limit`          | Maximum amount of CPU units that the proxy can use                                                                                                                                    |                                      |
+| `global.proxy.resources.cpu.request`        | Amount of CPU units that the proxy requests                                                                                                                                           |                                      |
+| `global.proxy.resources.memory.limit`       | Maximum amount of memory that the proxy can use                                                                                                                                       |                                      |
+| `global.proxy.resources.memory.request`     | Amount of memory that the proxy requests                                                                                                                                              |                                      |
+| `global.proxy.trace.collectorSvcAccount`    | Service account associated with the Trace collector instance                                                                                                                          |                                      |
+| `global.proxy.trace.collectorSvcAddr`       | Collector Service address for the proxies to send Trace Data                                                                                                                          |                                      |
+| `global.proxy.uid`                          | User id under which the proxy runs                                                                                                                                                    | `2102`                               |
+| `global.proxy.waitBeforeExitSeconds`        | The proxy sidecar will stay alive for at least the given period before receiving SIGTERM signal from Kubernetes but no longer than pod's `terminationGracePeriodSeconds`.             | `0`                                  |
+| `global.proxyInit.ignoreInboundPorts`       | Inbound ports the proxy should ignore                                                                                                                                                 |                                      |
+| `global.proxyInit.ignoreOutboundPorts`      | Outbound ports the proxy should ignore                                                                                                                                                |                                      |
+| `global.proxyInit.image.name`               | Docker image for the proxy-init container                                                                                                                                             | `gcr.io/linkerd-io/proxy-init`       |
+| `global.proxyInit.image.pullPolicy`         | Pull policy for the proxy-init container Docker image                                                                                                                                 | `IfNotPresent`                       |
+| `global.proxyInit.image.version`            | Tag for the proxy-init container Docker image                                                                                                                                         | latest version                       |
+| `global.proxyInit.resources.cpu.limit`      | Maximum amount of CPU units that the proxy-init container can use                                                                                                                     | `100m`                               |
+| `global.proxyInit.resources.cpu.request`    | Amount of CPU units that the proxy-init container requests                                                                                                                            | `10m`                                |
+| `global.ProxyInit.resources.memory.limit`   | Maximum amount of memory that the proxy-init container can use                                                                                                                        | `50Mi`                               |
+| `global.proxyInit.resources.memory.request` | Amount of memory that the proxy-init container requests                                                                                                                               | `10Mi`                               |
+| `global.proxyInjectAnnotation`              | Annotation label to signal injection. Do not edit.                                                                                                                                    |                                      |
+| `global.proxyInjectDisabled`                | Annotation value to disable injection. Do not edit.                                                                                                                                   | `disabled`                           |
+| `grafanaImage`                              | Docker image for the Grafana container                                                                                                                                                | `gcr.io/linkerd-io/grafana`          |
+| `heartbeatSchedule`                         | Config for the heartbeat cronjob                                                                                                                                                      | `0 0 * * *`                          |
+| `identity.issuer.clockSkewAllowance`        | Amount of time to allow for clock skew within a Linkerd cluster                                                                                                                       | `20s`                                |
+| `identity.issuer.crtExpiry`                 | Expiration timestamp for the issuer certificate. It must be provided during install                                                                                                   |                                      |
+| `identity.issuer.crtExpiryAnnotation`       | Annotation used to identity the issuer certificate expiration timestamp. Do not edit.                                                                                                 | `linkerd.io/identity-issuer-expiry`  |
+| `identity.issuer.issuanceLifetime`          | Amount of time for which the Identity issuer should certify identity                                                                                                                  | `86400s`                             |
+| `identity.issuer.scheme`                    | Which scheme is used for the identity issuer secret format                                                                                                                            | `linkerd.io/tls`                     |
+| `identity.issuer.tls.crtPEM`                | Issuer certificate (ECDSA). It must be provided during install.                                                                                                                       |                                      |
+| `identity.issuer.tls.keyPEM`                | Key for the issuer certificate (ECDSA). It must be provided during install.                                                                                                           |                                      |
+| `installNamespace`                          | Set to false when installing Linkerd in a custom namespace. See the [Linkerd documentation](https://linkerd.io/2/tasks/install-helm/#customizing-the-namespace) for more information. | `true`                               |
+| `omitWebhookSideEffects`                    | Omit the `sideEffects` flag in the webhook manifests                                                                                                                                  | `false`                              |
+| `prometheusAlertmanagers`                   | Alertmanager instances the Prometheus server sends alerts to configured via the static_configs parameter.                                                                             | `[]`                                 |
+| `prometheusExtraArgs`                       | Extra command line options for Prometheus                                                                                                                                             | `{}`                                 |
+| `prometheusImage`                           | Docker image for the Prometheus container                                                                                                                                             | `prom/prometheus:v2.15.2`            |
+| `prometheusLogLevel`                        | Log level for Prometheus                                                                                                                                                              | `info`                               |
+| `prometheusRuleConfigMapMounts`             | Alerting/recording rule ConfigMap mounts (sub-path names must end in `_rules.yml` or `_rules.yaml`)                                                                                   | `[]`                                 |
+| `proxyInjector.crtPEM`                      | Certificate for the proxy injector. If not provided then Helm will generate one.                                                                                                      |                                      |
+| `proxyInjector.keyPEM`                      | Certificate key for the proxy injector. If not provided then Helm will generate one.                                                                                                  |                                      |
+| `profileValidator.crtPEM`                   | Certificate for the service profile validator. If not provided then Helm will generate one.                                                                                           |                                      |
+| `profileValidator.keyPEM`                   | Certificate key for the service profile validator. If not provided then Helm will generate one.                                                                                       |                                      |
+| `tap.crtPEM`                                | Certificate for the Tap component. If not provided then Helm will generate one.                                                                                                       |                                      |
+| `tap.keyPEM`                                | Certificate key for Tap component. If not provided then Helm will generate one.                                                                                                       |                                      |
+| `webhookFailurePolicy`                      | Failure policy for the proxy injector                                                                                                                                                 | `Ignore`                             |
+| `webImage`                                  | Docker image for the web container                                                                                                                                                    | `gcr.io/linkerd-io/web`              |
+| `enforcedHostRegexp`                        | Host header validation regex for the dashboard. See the [Linkerd documentation](https://linkerd.io/2/tasks/exposing-dashboard) for more information                                   | `""`                                 |
 
 ## Add-Ons Configuration
 
@@ -163,21 +166,21 @@ The following table lists the configurable parameters of the Linkerd2 chart and
 
 The following table lists the configurable parameters for the Tracing Add-On.
 
-| Parameter                             | Description                                                                                                                                                                           | Default                              |
-|:--------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------|
-| `tracing.enabled`                     | Flag to enable tracing components to be installed                                                                                                                                                | `false`
-| `tracing.collector.name`                | Name of the trace collector Service                                                                                                                                                 | `linkerd-collector`                             |
-| `tracing.collector.image`                | Docker image for the trace collector                                                                                                                                                 | `omnition/opencensus-collector:0.1.10`                             |
-| `tracing.collector.resources.cpu.limit`       | Maximum amount of CPU units that the trace collector container can use                                                                                                                     | `1`                               |
-| `tracing.collector.resources.cpu.request`     | Amount of CPU units that the trace collector container requests                                                                                                                            | `200m`                                |
-| `tracing.collector.resources.memory.limit`    | Maximum amount of memory that the trace collector container can use                                                                                                                        | `2Gi`                               |
-| `tracing.collector.resources.memory.request`  | Amount of memory that the trace collector container requests                                                                                                                               | `400Mi`                               |
-| `tracing.jaeger.name`                | Name of the jaeger instance                                                                                                                                                 | `linkerd-jaeger`                             |
-| `tracing.jaeger.image`                | Docker image for the jaeger instance                                                                                                                                                 | `jaegertracing/all-in-one:1.8`                             |
-| `tracing.jaeger.resources.cpu.limit`       | Maximum amount of CPU units that the jaeger container can use                                                                                                                     ||
-| `tracing.jaeger.resources.cpu.request`     | Amount of CPU units that the jaeger container requests                                                                                                                            ||
-| `tracing.jaeger.resources.memory.limit`    | Maximum amount of memory that the jaeger container can use                                                                                                                        ||
-| `tracing.jaeger.resources.memory.request`  | Amount of memory that the jaeger container requests                                                                                                                               ||
+| Parameter                                    | Description                                                            | Default                                |
+|:---------------------------------------------|:-----------------------------------------------------------------------|:---------------------------------------|
+| `tracing.enabled`                            | Flag to enable tracing components to be installed                      | `false`                                |
+| `tracing.collector.name`                     | Name of the trace collector Service                                    | `linkerd-collector`                    |
+| `tracing.collector.image`                    | Docker image for the trace collector                                   | `omnition/opencensus-collector:0.1.10` |
+| `tracing.collector.resources.cpu.limit`      | Maximum amount of CPU units that the trace collector container can use | `1`                                    |
+| `tracing.collector.resources.cpu.request`    | Amount of CPU units that the trace collector container requests        | `200m`                                 |
+| `tracing.collector.resources.memory.limit`   | Maximum amount of memory that the trace collector container can use    | `2Gi`                                  |
+| `tracing.collector.resources.memory.request` | Amount of memory that the trace collector container requests           | `400Mi`                                |
+| `tracing.jaeger.name`                        | Name of the jaeger instance                                            | `linkerd-jaeger`                       |
+| `tracing.jaeger.image`                       | Docker image for the jaeger instance                                   | `jaegertracing/all-in-one:1.8`         |
+| `tracing.jaeger.resources.cpu.limit`         | Maximum amount of CPU units that the jaeger container can use          |                                        |
+| `tracing.jaeger.resources.cpu.request`       | Amount of CPU units that the jaeger container requests                 |                                        |
+| `tracing.jaeger.resources.memory.limit`      | Maximum amount of memory that the jaeger container can use             |                                        |
+| `tracing.jaeger.resources.memory.request`    | Amount of memory that the jaeger container requests                    |                                        |
 
 ## Get involved
 
diff --git a/charts/linkerd2/templates/prometheus.yaml b/charts/linkerd2/templates/prometheus.yaml
index 59176fe67..d190d62e1 100644
--- a/charts/linkerd2/templates/prometheus.yaml
+++ b/charts/linkerd2/templates/prometheus.yaml
@@ -15,6 +15,11 @@ metadata:
     {{.Values.global.createdByAnnotation}}: {{default (printf "linkerd/helm %s" .Values.global.linkerdVersion) .Values.global.cliVersion}}
 data:
   prometheus.yml: |-
+    {{- if .Values.prometheusAlertmanagers }}
+    alerting:
+      alertmanagers:
+        {{- toYaml .Values.prometheusAlertmanagers | trim | nindent 8 }}
+    {{- end }}
     global:
       scrape_interval: 10s
       scrape_timeout: 10s
@@ -22,6 +27,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -209,6 +215,9 @@ spec:
         - --storage.tsdb.retention.time=6h
         - --config.file=/etc/prometheus/prometheus.yml
         - --log.level={{lower .Values.prometheusLogLevel}}
+        {{- range $key, $value := .Values.prometheusExtraArgs}}
+        - --{{ $key }}{{ if $value }}={{ $value }}{{ end }}
+        {{- end }}
         image: {{.Values.prometheusImage}}
         imagePullPolicy: {{.Values.global.imagePullPolicy}}
         livenessProbe:
@@ -233,10 +242,17 @@ spec:
         securityContext:
           runAsUser: 65534
         volumeMounts:
+      {{- range .Values.prometheusRuleConfigMapMounts }}
+        - name: {{ .name }}
+          mountPath: /etc/prometheus/{{ .subPath }}
+          subPath: {{ .subPath }}
+          readOnly: true
+      {{- end }}
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - {{- include "partials.proxy" . | indent 8 | trimPrefix (repeat 7 " ") }}
       {{ if not .Values.global.cniEnabled -}}
@@ -245,6 +261,11 @@ spec:
       {{ end -}}
       serviceAccountName: linkerd-prometheus
       volumes:
+    {{- range .Values.prometheusRuleConfigMapMounts }}
+      - name: {{ .name }}
+        configMap:
+          name: {{ .configMap }}
+    {{- end }}
       - emptyDir: {}
         name: data
       - configMap:
diff --git a/charts/linkerd2/values.yaml b/charts/linkerd2/values.yaml
index ad6cb6c69..92cc7ffce 100644
--- a/charts/linkerd2/values.yaml
+++ b/charts/linkerd2/values.yaml
@@ -7,7 +7,7 @@ global:
   clusterDomain: &cluster_domain cluster.local
   imagePullPolicy: &image_pull_policy IfNotPresent
 
- # control plane trace configuration
+  # control plane trace configuration
   controlPlaneTracing: false
 
   # control plane version. See Proxy section for proxy version
@@ -133,6 +133,20 @@ heartbeatSchedule: "0 0 * * *"
 # prometheus configuration
 prometheusImage: prom/prometheus:v2.15.2
 prometheusLogLevel: *controller_log_level
+prometheusExtraArgs: {}
+  # log.format: json
+prometheusAlertmanagers: []
+  # - scheme: http
+  #   static_configs:
+  #   - targets:
+  #     - "alertmanager.linkerd.svc:9093"
+prometheusRuleConfigMapMounts: []
+  # - name: alerting-rules
+  #   subPath: alerting_rules.yml
+  #   configMap: linkerd-prometheus-rules
+  # - name: recording-rules
+  #   subPath: recording_rules.yml
+  #   configMap: linkerd-prometheus-rules
 
 # proxy injector configuration
 proxyInjector:
diff --git a/cli/cmd/edges.go b/cli/cmd/edges.go
index 2c0d7a6e4..922addeff 100644
--- a/cli/cmd/edges.go
+++ b/cli/cmd/edges.go
@@ -23,7 +23,7 @@ type edgesOptions struct {
 
 func newEdgesOptions() *edgesOptions {
 	return &edgesOptions{
-		namespace:     "",
+		namespace:     getDefaultNamespace(),
 		outputFormat:  tableOutput,
 		allNamespaces: false,
 	}
diff --git a/cli/cmd/get.go b/cli/cmd/get.go
index 9ec844da5..bf13c3283 100644
--- a/cli/cmd/get.go
+++ b/cli/cmd/get.go
@@ -18,7 +18,7 @@ type getOptions struct {
 
 func newGetOptions() *getOptions {
 	return &getOptions{
-		namespace:     "default",
+		namespace:     getDefaultNamespace(),
 		allNamespaces: false,
 	}
 }
diff --git a/cli/cmd/metrics.go b/cli/cmd/metrics.go
index b2236589d..95d1c5f12 100644
--- a/cli/cmd/metrics.go
+++ b/cli/cmd/metrics.go
@@ -22,7 +22,7 @@ type metricsOptions struct {
 
 func newMetricsOptions() *metricsOptions {
 	return &metricsOptions{
-		namespace: "default",
+		namespace: getDefaultNamespace(),
 		pod:       "",
 	}
 }
diff --git a/cli/cmd/profile.go b/cli/cmd/profile.go
index 098b7e6c5..a89ef87a2 100644
--- a/cli/cmd/profile.go
+++ b/cli/cmd/profile.go
@@ -27,7 +27,7 @@ type profileOptions struct {
 func newProfileOptions() *profileOptions {
 	return &profileOptions{
 		name:          "",
-		namespace:     "default",
+		namespace:     getDefaultNamespace(),
 		template:      false,
 		openAPI:       "",
 		proto:         "",
diff --git a/cli/cmd/root.go b/cli/cmd/root.go
index 3cdb33ce4..4f98d3997 100644
--- a/cli/cmd/root.go
+++ b/cli/cmd/root.go
@@ -9,6 +9,8 @@ import (
 	"time"
 
 	"github.com/spf13/pflag"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/client-go/tools/clientcmd"
 
 	"github.com/fatih/color"
 	log "github.com/sirupsen/logrus"
@@ -139,7 +141,7 @@ type statOptionsBase struct {
 
 func newStatOptionsBase() *statOptionsBase {
 	return &statOptionsBase{
-		namespace:    "default",
+		namespace:    getDefaultNamespace(),
 		timeWindow:   "1m",
 		outputFormat: tableOutput,
 	}
@@ -189,6 +191,27 @@ func getSuccessRate(success, failure uint64) float64 {
 	return float64(success) / float64(success+failure)
 }
 
+// getDefaultNamespace fetches the default namespace
+// used in the current KubeConfig context
+func getDefaultNamespace() string {
+	rules := clientcmd.NewDefaultClientConfigLoadingRules()
+
+	if kubeconfigPath != "" {
+		rules.ExplicitPath = kubeconfigPath
+	}
+
+	overrides := &clientcmd.ConfigOverrides{CurrentContext: kubeContext}
+	kubeCfg := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(rules, overrides)
+	ns, _, err := kubeCfg.Namespace()
+
+	if err != nil {
+		log.Errorf("failed to set namespace from config context:%v", err)
+		return corev1.NamespaceDefault
+	}
+
+	return ns
+}
+
 // proxyConfigOptions holds values for command line flags that apply to both the
 // install and inject commands. All fields in this struct should have
 // corresponding flags added in the addProxyConfigFlags func later in this file.
diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go
index 003c19d9a..8cff99dd4 100644
--- a/cli/cmd/tap.go
+++ b/cli/cmd/tap.go
@@ -103,7 +103,7 @@ type tapEvent struct {
 
 func newTapOptions() *tapOptions {
 	return &tapOptions{
-		namespace:     "default",
+		namespace:     getDefaultNamespace(),
 		toResource:    "",
 		toNamespace:   "",
 		maxRps:        maxRps,
diff --git a/cli/cmd/top.go b/cli/cmd/top.go
index f1532a7e8..2a35d4d49 100644
--- a/cli/cmd/top.go
+++ b/cli/cmd/top.go
@@ -259,7 +259,7 @@ const (
 
 func newTopOptions() *topOptions {
 	return &topOptions{
-		namespace:     "default",
+		namespace:     getDefaultNamespace(),
 		toResource:    "",
 		toNamespace:   "",
 		maxRps:        maxRps,
diff --git a/pkg/charts/linkerd2/values.go b/pkg/charts/linkerd2/values.go
index 01e9b119a..7ef3ed525 100644
--- a/pkg/charts/linkerd2/values.go
+++ b/pkg/charts/linkerd2/values.go
@@ -19,34 +19,37 @@ const (
 type (
 	// Values contains the top-level elements in the Helm charts
 	Values struct {
-		Stage                       string            `json:"stage"`
-		ControllerImage             string            `json:"controllerImage"`
-		ControllerImageVersion      string            `json:"controllerImageVersion"`
-		WebImage                    string            `json:"webImage"`
-		PrometheusImage             string            `json:"prometheusImage"`
-		GrafanaImage                string            `json:"grafanaImage"`
-		ControllerReplicas          uint              `json:"controllerReplicas"`
-		ControllerLogLevel          string            `json:"controllerLogLevel"`
-		PrometheusLogLevel          string            `json:"prometheusLogLevel"`
-		ControllerUID               int64             `json:"controllerUID"`
-		EnableH2Upgrade             bool              `json:"enableH2Upgrade"`
-		EnablePodAntiAffinity       bool              `json:"enablePodAntiAffinity"`
-		WebhookFailurePolicy        string            `json:"webhookFailurePolicy"`
-		OmitWebhookSideEffects      bool              `json:"omitWebhookSideEffects"`
-		RestrictDashboardPrivileges bool              `json:"restrictDashboardPrivileges"`
-		DisableHeartBeat            bool              `json:"disableHeartBeat"`
-		HeartbeatSchedule           string            `json:"heartbeatSchedule"`
-		InstallNamespace            bool              `json:"installNamespace"`
-		Configs                     ConfigJSONs       `json:"configs"`
-		Global                      *Global           `json:"global"`
-		Identity                    *Identity         `json:"identity"`
-		Dashboard                   *Dashboard        `json:"dashboard"`
-		DebugContainer              *DebugContainer   `json:"debugContainer"`
-		ProxyInjector               *ProxyInjector    `json:"proxyInjector"`
-		ProfileValidator            *ProfileValidator `json:"profileValidator"`
-		Tap                         *Tap              `json:"tap"`
-		NodeSelector                map[string]string `json:"nodeSelector"`
-		SMIMetrics                  *SMIMetrics       `json:"smiMetrics"`
+		Stage                         string                         `json:"stage"`
+		ControllerImage               string                         `json:"controllerImage"`
+		ControllerImageVersion        string                         `json:"controllerImageVersion"`
+		WebImage                      string                         `json:"webImage"`
+		PrometheusImage               string                         `json:"prometheusImage"`
+		GrafanaImage                  string                         `json:"grafanaImage"`
+		ControllerReplicas            uint                           `json:"controllerReplicas"`
+		ControllerLogLevel            string                         `json:"controllerLogLevel"`
+		PrometheusLogLevel            string                         `json:"prometheusLogLevel"`
+		PrometheusExtraArgs           map[string]string              `json:"prometheusExtraArgs"`
+		PrometheusAlertmanagers       []interface{}                  `json:"prometheusAlertmanagers"`
+		PrometheusRuleConfigMapMounts []PrometheusRuleConfigMapMount `json:"prometheusRuleConfigMapMounts"`
+		ControllerUID                 int64                          `json:"controllerUID"`
+		EnableH2Upgrade               bool                           `json:"enableH2Upgrade"`
+		EnablePodAntiAffinity         bool                           `json:"enablePodAntiAffinity"`
+		WebhookFailurePolicy          string                         `json:"webhookFailurePolicy"`
+		OmitWebhookSideEffects        bool                           `json:"omitWebhookSideEffects"`
+		RestrictDashboardPrivileges   bool                           `json:"restrictDashboardPrivileges"`
+		DisableHeartBeat              bool                           `json:"disableHeartBeat"`
+		HeartbeatSchedule             string                         `json:"heartbeatSchedule"`
+		InstallNamespace              bool                           `json:"installNamespace"`
+		Configs                       ConfigJSONs                    `json:"configs"`
+		Global                        *Global                        `json:"global"`
+		Identity                      *Identity                      `json:"identity"`
+		Dashboard                     *Dashboard                     `json:"dashboard"`
+		DebugContainer                *DebugContainer                `json:"debugContainer"`
+		ProxyInjector                 *ProxyInjector                 `json:"proxyInjector"`
+		ProfileValidator              *ProfileValidator              `json:"profileValidator"`
+		Tap                           *Tap                           `json:"tap"`
+		NodeSelector                  map[string]string              `json:"nodeSelector"`
+		SMIMetrics                    *SMIMetrics                    `json:"smiMetrics"`
 
 		DestinationResources   *Resources `json:"destinationResources"`
 		GrafanaResources       *Resources `json:"grafanaResources"`
@@ -188,6 +191,13 @@ type (
 		TLS                 *TLS      `json:"tls"`
 	}
 
+	// PrometheusRuleConfigMapMount is a user supplied prometheus rule config maps.
+	PrometheusRuleConfigMapMount struct {
+		Name      string `json:"name"`
+		SubPath   string `json:"subPath"`
+		ConfigMap string `json:"configMap"`
+	}
+
 	// ProxyInjector has all the proxy injector's Helm variables
 	ProxyInjector struct {
 		*TLS


Test patch:
diff --git a/cli/cmd/testdata/install_addon_control-plane.golden b/cli/cmd/testdata/install_addon_control-plane.golden
index 8e3792739..fd3f58a58 100644
--- a/cli/cmd/testdata/install_addon_control-plane.golden
+++ b/cli/cmd/testdata/install_addon_control-plane.golden
@@ -982,6 +982,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -1188,8 +1189,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_control-plane.golden b/cli/cmd/testdata/install_control-plane.golden
index 6bae28cb2..44930c42c 100644
--- a/cli/cmd/testdata/install_control-plane.golden
+++ b/cli/cmd/testdata/install_control-plane.golden
@@ -982,6 +982,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -1188,8 +1189,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_controlplane_tracing_output.golden b/cli/cmd/testdata/install_controlplane_tracing_output.golden
index db075eab6..98dc53854 100644
--- a/cli/cmd/testdata/install_controlplane_tracing_output.golden
+++ b/cli/cmd/testdata/install_controlplane_tracing_output.golden
@@ -1882,6 +1882,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2088,8 +2089,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_custom_registry.golden b/cli/cmd/testdata/install_custom_registry.golden
index c4ea1464d..8e1c1ea67 100644
--- a/cli/cmd/testdata/install_custom_registry.golden
+++ b/cli/cmd/testdata/install_custom_registry.golden
@@ -1822,6 +1822,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2028,8 +2029,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_default.golden b/cli/cmd/testdata/install_default.golden
index e84b34e0f..c5c19db03 100644
--- a/cli/cmd/testdata/install_default.golden
+++ b/cli/cmd/testdata/install_default.golden
@@ -1822,6 +1822,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2028,8 +2029,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_ha_output.golden b/cli/cmd/testdata/install_ha_output.golden
index f49bd513c..876d7f58b 100644
--- a/cli/cmd/testdata/install_ha_output.golden
+++ b/cli/cmd/testdata/install_ha_output.golden
@@ -1950,6 +1950,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2163,8 +2164,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_ha_with_overrides_output.golden b/cli/cmd/testdata/install_ha_with_overrides_output.golden
index f6cc45d27..01b85ad6c 100644
--- a/cli/cmd/testdata/install_ha_with_overrides_output.golden
+++ b/cli/cmd/testdata/install_ha_with_overrides_output.golden
@@ -1950,6 +1950,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2163,8 +2164,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_heartbeat_disabled_output.golden b/cli/cmd/testdata/install_heartbeat_disabled_output.golden
index 3f56776a4..87c82ac26 100644
--- a/cli/cmd/testdata/install_heartbeat_disabled_output.golden
+++ b/cli/cmd/testdata/install_heartbeat_disabled_output.golden
@@ -1733,6 +1733,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -1939,8 +1940,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_helm_output.golden b/cli/cmd/testdata/install_helm_output.golden
index 50d5b36cf..f7fd527ba 100644
--- a/cli/cmd/testdata/install_helm_output.golden
+++ b/cli/cmd/testdata/install_helm_output.golden
@@ -1888,6 +1888,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2094,8 +2095,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_helm_output_addons.golden b/cli/cmd/testdata/install_helm_output_addons.golden
index 42ee47dfb..7703a7b19 100644
--- a/cli/cmd/testdata/install_helm_output_addons.golden
+++ b/cli/cmd/testdata/install_helm_output_addons.golden
@@ -1888,6 +1888,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2094,8 +2095,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_helm_output_ha.golden b/cli/cmd/testdata/install_helm_output_ha.golden
index bef79fc42..0179cc6ec 100644
--- a/cli/cmd/testdata/install_helm_output_ha.golden
+++ b/cli/cmd/testdata/install_helm_output_ha.golden
@@ -2016,6 +2016,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2229,8 +2230,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_no_init_container.golden b/cli/cmd/testdata/install_no_init_container.golden
index 1c70b2af7..87db5d455 100644
--- a/cli/cmd/testdata/install_no_init_container.golden
+++ b/cli/cmd/testdata/install_no_init_container.golden
@@ -1687,6 +1687,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -1893,8 +1894,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_output.golden b/cli/cmd/testdata/install_output.golden
index 797c59fae..f9286fa2e 100644
--- a/cli/cmd/testdata/install_output.golden
+++ b/cli/cmd/testdata/install_output.golden
@@ -1818,6 +1818,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2024,8 +2025,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_proxy_ignores.golden b/cli/cmd/testdata/install_proxy_ignores.golden
index 23a2b5c0f..9442de79f 100644
--- a/cli/cmd/testdata/install_proxy_ignores.golden
+++ b/cli/cmd/testdata/install_proxy_ignores.golden
@@ -1822,6 +1822,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2028,8 +2029,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_restricted_dashboard.golden b/cli/cmd/testdata/install_restricted_dashboard.golden
index b387a4057..2c98a783d 100644
--- a/cli/cmd/testdata/install_restricted_dashboard.golden
+++ b/cli/cmd/testdata/install_restricted_dashboard.golden
@@ -1757,6 +1757,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -1963,8 +1964,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/install_tracing.golden b/cli/cmd/testdata/install_tracing.golden
index 04373e024..579532484 100644
--- a/cli/cmd/testdata/install_tracing.golden
+++ b/cli/cmd/testdata/install_tracing.golden
@@ -1822,6 +1822,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2028,8 +2029,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/upgrade_add-on_controlplane.golden b/cli/cmd/testdata/upgrade_add-on_controlplane.golden
index 690543ad0..1a927e0ba 100644
--- a/cli/cmd/testdata/upgrade_add-on_controlplane.golden
+++ b/cli/cmd/testdata/upgrade_add-on_controlplane.golden
@@ -990,6 +990,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -1196,8 +1197,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/upgrade_add-on_overwrite.golden b/cli/cmd/testdata/upgrade_add-on_overwrite.golden
index af4e14047..495bc419e 100644
--- a/cli/cmd/testdata/upgrade_add-on_overwrite.golden
+++ b/cli/cmd/testdata/upgrade_add-on_overwrite.golden
@@ -1830,6 +1830,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2036,8 +2037,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/upgrade_add_add-on.golden b/cli/cmd/testdata/upgrade_add_add-on.golden
index 86351d233..95bf1e3bd 100644
--- a/cli/cmd/testdata/upgrade_add_add-on.golden
+++ b/cli/cmd/testdata/upgrade_add_add-on.golden
@@ -1830,6 +1830,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2036,8 +2037,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/upgrade_default.golden b/cli/cmd/testdata/upgrade_default.golden
index 1ceba9206..9a349a398 100644
--- a/cli/cmd/testdata/upgrade_default.golden
+++ b/cli/cmd/testdata/upgrade_default.golden
@@ -1830,6 +1830,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2036,8 +2037,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/upgrade_external_issuer.golden b/cli/cmd/testdata/upgrade_external_issuer.golden
index b06b5a8e2..ff6e58684 100644
--- a/cli/cmd/testdata/upgrade_external_issuer.golden
+++ b/cli/cmd/testdata/upgrade_external_issuer.golden
@@ -1816,6 +1816,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2022,8 +2023,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/upgrade_ha.golden b/cli/cmd/testdata/upgrade_ha.golden
index f844525a5..23aa6e441 100644
--- a/cli/cmd/testdata/upgrade_ha.golden
+++ b/cli/cmd/testdata/upgrade_ha.golden
@@ -1958,6 +1958,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2171,8 +2172,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/upgrade_overwrite_issuer.golden b/cli/cmd/testdata/upgrade_overwrite_issuer.golden
index 3ec11fce8..d99c2cd70 100644
--- a/cli/cmd/testdata/upgrade_overwrite_issuer.golden
+++ b/cli/cmd/testdata/upgrade_overwrite_issuer.golden
@@ -1822,6 +1822,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2028,8 +2029,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/upgrade_overwrite_trust_anchors-external-issuer.golden b/cli/cmd/testdata/upgrade_overwrite_trust_anchors-external-issuer.golden
index 138cb8485..f2eda01b1 100644
--- a/cli/cmd/testdata/upgrade_overwrite_trust_anchors-external-issuer.golden
+++ b/cli/cmd/testdata/upgrade_overwrite_trust_anchors-external-issuer.golden
@@ -1808,6 +1808,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2014,8 +2015,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/cli/cmd/testdata/upgrade_overwrite_trust_anchors.golden b/cli/cmd/testdata/upgrade_overwrite_trust_anchors.golden
index 3ec11fce8..d99c2cd70 100644
--- a/cli/cmd/testdata/upgrade_overwrite_trust_anchors.golden
+++ b/cli/cmd/testdata/upgrade_overwrite_trust_anchors.golden
@@ -1822,6 +1822,7 @@ data:
 
     rule_files:
     - /etc/prometheus/*_rules.yml
+    - /etc/prometheus/*_rules.yaml
 
     scrape_configs:
     - job_name: 'prometheus'
@@ -2028,8 +2029,9 @@ spec:
         volumeMounts:
         - mountPath: /data
           name: data
-        - mountPath: /etc/prometheus
+        - mountPath: /etc/prometheus/prometheus.yml
           name: prometheus-config
+          subPath: prometheus.yml
           readOnly: true
       - env:
         - name: LINKERD2_PROXY_LOG
diff --git a/pkg/charts/linkerd2/values_test.go b/pkg/charts/linkerd2/values_test.go
index 2805270a1..0c65178e8 100644
--- a/pkg/charts/linkerd2/values_test.go
+++ b/pkg/charts/linkerd2/values_test.go
@@ -14,24 +14,27 @@ func TestNewValues(t *testing.T) {
 	testVersion := "linkerd-dev"
 
 	expected := &Values{
-		Stage:                       "",
-		ControllerImage:             "gcr.io/linkerd-io/controller",
-		ControllerImageVersion:      testVersion,
-		WebImage:                    "gcr.io/linkerd-io/web",
-		PrometheusImage:             "prom/prometheus:v2.15.2",
-		GrafanaImage:                "gcr.io/linkerd-io/grafana",
-		ControllerReplicas:          1,
-		ControllerLogLevel:          "info",
-		PrometheusLogLevel:          "info",
-		ControllerUID:               2103,
-		EnableH2Upgrade:             true,
-		EnablePodAntiAffinity:       false,
-		WebhookFailurePolicy:        "Ignore",
-		OmitWebhookSideEffects:      false,
-		RestrictDashboardPrivileges: false,
-		DisableHeartBeat:            false,
-		HeartbeatSchedule:           "0 0 * * *",
-		InstallNamespace:            true,
+		Stage:                         "",
+		ControllerImage:               "gcr.io/linkerd-io/controller",
+		ControllerImageVersion:        testVersion,
+		WebImage:                      "gcr.io/linkerd-io/web",
+		PrometheusImage:               "prom/prometheus:v2.15.2",
+		GrafanaImage:                  "gcr.io/linkerd-io/grafana",
+		ControllerReplicas:            1,
+		ControllerLogLevel:            "info",
+		PrometheusLogLevel:            "info",
+		PrometheusExtraArgs:           map[string]string{},
+		PrometheusAlertmanagers:       []interface{}{},
+		PrometheusRuleConfigMapMounts: []PrometheusRuleConfigMapMount{},
+		ControllerUID:                 2103,
+		EnableH2Upgrade:               true,
+		EnablePodAntiAffinity:         false,
+		WebhookFailurePolicy:          "Ignore",
+		OmitWebhookSideEffects:        false,
+		RestrictDashboardPrivileges:   false,
+		DisableHeartBeat:              false,
+		HeartbeatSchedule:             "0 0 * * *",
+		InstallNamespace:              true,
 		Global: &Global{
 			Namespace:                "linkerd",
 			ClusterDomain:            "cluster.local",
@@ -148,6 +151,12 @@ func TestNewValues(t *testing.T) {
 
 	t.Run("HA", func(t *testing.T) {
 		actual, err := NewValues(true)
+
+		// workaround for mergo, which resets these to []interface{}(nil)
+		// and []PrometheusRuleConfigMapMount(nil)
+		actual.PrometheusAlertmanagers = []interface{}{}
+		actual.PrometheusRuleConfigMapMounts = []PrometheusRuleConfigMapMount{}
+
 		if err != nil {
 			t.Fatalf("Unexpected error: %v\n", err)
 		}
diff --git a/test/get/get_test.go b/test/get/get_test.go
index 3450e6f24..1474d6a5f 100644
--- a/test/get/get_test.go
+++ b/test/get/get_test.go
@@ -105,6 +105,28 @@ func TestCliGet(t *testing.T) {
 			t.Fatalf("Pod output check failed:\n%s\nCommand output:\n%s", err, out)
 		}
 	})
+
+	t.Run("get pods from the default namespace of current context", func(t *testing.T) {
+		out, err := TestHelper.Kubectl("", "config", "set-context", "--namespace="+TestHelper.GetLinkerdNamespace(), "--current")
+		if err != nil {
+			t.Fatalf("Unexpected error: %v output:\n%s", err, out)
+		}
+
+		out, stderr, err = TestHelper.LinkerdRun("get", "pods")
+		if err != nil {
+			t.Fatalf("Unexpected error: %v output:\n%s\n%s", err, out, stderr)
+		}
+
+		err = checkPodOutput(out, linkerdPods, "linkerd-heartbeat", TestHelper.GetLinkerdNamespace())
+		if err != nil {
+			t.Fatalf("Pod output check failed:\n%s\nCommand output:\n%s", err, out)
+		}
+
+		out, err = TestHelper.Kubectl("", "config", "set-context", "--namespace=default", "--current")
+		if err != nil {
+			t.Fatalf("Unexpected error: %v output:\n%s", err, out)
+		}
+	})
 }
 
 func checkPodOutput(cmdOutput string, expectedPodCounts map[string]int, optionalPod string, namespace string) error {
diff --git a/test/tap/tap_test.go b/test/tap/tap_test.go
index 0e8c8f360..b2f697d2e 100644
--- a/test/tap/tap_test.go
+++ b/test/tap/tap_test.go
@@ -116,6 +116,28 @@ func TestCliTap(t *testing.T) {
 		}
 	})
 
+	t.Run("tap a deployment using context namespace", func(t *testing.T) {
+		out, err := TestHelper.Kubectl("", "config", "set-context", "--namespace="+prefixedNs, "--current")
+		if err != nil {
+			t.Fatalf("Unexpected error: %v output:\n%s", err, out)
+		}
+
+		events, err := tap("deploy/t1")
+		if err != nil {
+			t.Fatal(err.Error())
+		}
+
+		err = validateExpected(events, expectedT1)
+		if err != nil {
+			t.Fatal(err.Error())
+		}
+
+		out, err = TestHelper.Kubectl("", "config", "set-context", "--namespace=default", "--current")
+		if err != nil {
+			t.Fatalf("Unexpected error: %v output:\n%s", err, out)
+		}
+	})
+
 	t.Run("tap a disabled deployment", func(t *testing.T) {
 		out, stderr, err := TestHelper.LinkerdRun("tap", "deploy/t4", "--namespace", prefixedNs)
 		if out != "" {