Repository: linkerd/linkerd2
Pull request #5610 (2021-01-26 10:10:19)

tests: include viz extension in upgrade-* integration tests
Currently, The source version of viz is installed even for
upgrade integration tests. Instead, Just like the core
control-plane, the viz extension should be started with stable/edge
version and then upgraded to the source version.

This helps discover any issues between upgrades for viz extension.

Currently, This is useful only for `upgrade-edge` CLI integration tests
as the viz extension is not present in stable yet and there is no
`helm-upgrade-edge` test.

Signed-off-by: Tarun Pothulapati <tarunpothulapati@outlook.com>


kleimkuhler: In `linkerd-viz` healthcheck, it looks like the order of `linkerd-viz pods are injected` and `viz extension pods are running` are flipped.
Pothulapati: @kleimkuhler I am guessing it was failing because we are doing a viz check on the edge and comparing it with `viz.golden` in source which has the order change and hence it was failing.

Now, That we have a new edge with the ordering change, My guess is that this should work.
Pothulapati: DO NOT MERGE this yet, as there is one last thing to fix in this.
adleong: @Pothulapati this has been open for a while, what's the status of it?
Pothulapati: @alpeb Updated

Also, We do install viz with Helm integration tests [already](https://github.com/linkerd/linkerd2/blob/tarun/integration-viz/test/integration/install_test.go#L528) right?

Patch:
diff --git a/charts/linkerd2/README.md b/charts/linkerd2/README.md
index b7708abe0..d00d84d5d 100644
--- a/charts/linkerd2/README.md
+++ b/charts/linkerd2/README.md
@@ -142,7 +142,6 @@ Kubernetes: `>=1.16.0-0`
 | disableHeartBeat | bool | `false` | Set to true to not start the heartbeat cronjob |
 | enableEndpointSlices | bool | `false` | enables the use of EndpointSlice informers for the destination service; enableEndpointSlices should be set to true only if EndpointSlice K8s feature gate is on; the feature is still experimental. |
 | enableH2Upgrade | bool | `true` | Allow proxies to perform transparent HTTP/2 upgrading |
-| heartbeatSchedule | string | `"0 0 * * *"` | Config for the heartbeat cronjob |
 | identity.issuer.clockSkewAllowance | string | `"20s"` | Amount of time to allow for clock skew within a Linkerd cluster |
 | identity.issuer.crtExpiry | string | `nil` | Expiration timestamp for the issuer certificate. It must be provided during install. Must match the expiry date in crtPEM |
 | identity.issuer.issuanceLifetime | string | `"24h0m0s"` | Amount of time for which the Identity issuer should certify identity |
diff --git a/charts/linkerd2/templates/heartbeat.yaml b/charts/linkerd2/templates/heartbeat.yaml
index ee5a4fe7e..28327696b 100644
--- a/charts/linkerd2/templates/heartbeat.yaml
+++ b/charts/linkerd2/templates/heartbeat.yaml
@@ -17,7 +17,12 @@ metadata:
   annotations:
     {{ include "partials.annotations.created-by" . }}
 spec:
+  concurrencyPolicy: Replace
+  {{ if .Values.heartbeatSchedule -}}
   schedule: "{{.Values.heartbeatSchedule}}"
+  {{ else -}}
+  schedule: "{{ dateInZone "04 15 * * *" (now | mustDateModify "+10m") "UTC"}}"
+  {{ end -}}
   successfulJobsHistoryLimit: 0
   jobTemplate:
     spec:
diff --git a/charts/linkerd2/values.yaml b/charts/linkerd2/values.yaml
index a220d4d21..78b8f4363 100644
--- a/charts/linkerd2/values.yaml
+++ b/charts/linkerd2/values.yaml
@@ -211,7 +211,7 @@ identity:
 # disableHeartBeat -- Set to true to not start the heartbeat cronjob
 disableHeartBeat: false
 # -- Config for the heartbeat cronjob
-heartbeatSchedule: "0 0 * * *"
+# heartbeatSchedule: "0 0 * * *"
 
 # proxy injector configuration
 proxyInjector:
diff --git a/cli/cmd/install.go b/cli/cmd/install.go
index 429c738d2..9180d7209 100644
--- a/cli/cmd/install.go
+++ b/cli/cmd/install.go
@@ -307,9 +307,6 @@ func install(ctx context.Context, w io.Writer, values *l5dcharts.Values, flags [
 		return err
 	}
 
-	t := time.Now().Add(10 * time.Minute).UTC()
-	values.HeartbeatSchedule = fmt.Sprintf("%d %d * * * ", t.Minute(), t.Hour())
-
 	return render(w, values, stage, options)
 }
 
diff --git a/controller/heartbeat/heartbeat.go b/controller/heartbeat/heartbeat.go
index 96cec1741..78b2420e6 100644
--- a/controller/heartbeat/heartbeat.go
+++ b/controller/heartbeat/heartbeat.go
@@ -240,6 +240,9 @@ func send(client *http.Client, baseURL string, v url.Values) error {
 	if err != nil {
 		return fmt.Errorf("failed to read response body: %s", err)
 	}
+	if resp.StatusCode != http.StatusOK {
+		return fmt.Errorf("request failed with code %d; response body: %s", resp.StatusCode, string(body))
+	}
 
 	log.Infof("Successfully sent heartbeat: %s", string(body))
 


Test patch:
diff --git a/bin/_test-helpers.sh b/bin/_test-helpers.sh
index f26accdef..efac6d36b 100644
--- a/bin/_test-helpers.sh
+++ b/bin/_test-helpers.sh
@@ -413,6 +413,15 @@ upgrade_test() {
   fi
 
   install_version "$install_url" "$upgrade_version"
+
+  # Install viz extension
+  local tmp_linkerd_path=$tmp/.linkerd2/bin/linkerd
+  (
+      set -x
+      "$tmp_linkerd_path" viz install | kubectl --context="$context" apply -f - 2>&1
+  )
+  exit_on_err "upgrade_test() - installing viz extension in $upgrade_version failed"
+
   run_test "$test_directory/install_test.go" --upgrade-from-version="$upgrade_version"
 }
 
diff --git a/cli/cmd/install_helm_test.go b/cli/cmd/install_helm_test.go
index 9756bf3bd..41577322d 100644
--- a/cli/cmd/install_helm_test.go
+++ b/cli/cmd/install_helm_test.go
@@ -279,6 +279,7 @@ func readTestValues(ha bool, ignoreOutboundPorts string, ignoreInboundPorts stri
 	}
 	values.ProxyInit.IgnoreOutboundPorts = ignoreOutboundPorts
 	values.ProxyInit.IgnoreInboundPorts = ignoreInboundPorts
+	values.HeartbeatSchedule = "1 2 3 4 5"
 
 	return values, nil
 }
diff --git a/cli/cmd/install_test.go b/cli/cmd/install_test.go
index 5ee4f0978..d3d59983b 100644
--- a/cli/cmd/install_test.go
+++ b/cli/cmd/install_test.go
@@ -36,6 +36,7 @@ func TestRender(t *testing.T) {
 		EnableH2Upgrade:         true,
 		WebhookFailurePolicy:    "WebhookFailurePolicy",
 		OmitWebhookSideEffects:  false,
+		HeartbeatSchedule:       "1 2 3 4 5",
 		InstallNamespace:        true,
 		Identity:                defaultValues.Identity,
 		NodeSelector:            defaultValues.NodeSelector,
diff --git a/cli/cmd/testdata/install_controlplane_tracing_output.golden b/cli/cmd/testdata/install_controlplane_tracing_output.golden
index deb04f448..5218b9e60 100644
--- a/cli/cmd/testdata/install_controlplane_tracing_output.golden
+++ b/cli/cmd/testdata/install_controlplane_tracing_output.golden
@@ -1803,6 +1803,7 @@ metadata:
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
 spec:
+  concurrencyPolicy: Replace
   schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
diff --git a/cli/cmd/testdata/install_custom_domain.golden b/cli/cmd/testdata/install_custom_domain.golden
index 18524aa90..5cf2c142b 100644
--- a/cli/cmd/testdata/install_custom_domain.golden
+++ b/cli/cmd/testdata/install_custom_domain.golden
@@ -1800,6 +1800,7 @@ metadata:
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
 spec:
+  concurrencyPolicy: Replace
   schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
diff --git a/cli/cmd/testdata/install_custom_registry.golden b/cli/cmd/testdata/install_custom_registry.golden
index 104711aa4..b94b8b1ee 100644
--- a/cli/cmd/testdata/install_custom_registry.golden
+++ b/cli/cmd/testdata/install_custom_registry.golden
@@ -1800,6 +1800,7 @@ metadata:
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
 spec:
+  concurrencyPolicy: Replace
   schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
diff --git a/cli/cmd/testdata/install_default.golden b/cli/cmd/testdata/install_default.golden
index 94649d6d9..92cd24c8c 100644
--- a/cli/cmd/testdata/install_default.golden
+++ b/cli/cmd/testdata/install_default.golden
@@ -1800,6 +1800,7 @@ metadata:
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
 spec:
+  concurrencyPolicy: Replace
   schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
diff --git a/cli/cmd/testdata/install_default_override_dst_get_nets.golden b/cli/cmd/testdata/install_default_override_dst_get_nets.golden
index 93d971b1b..d7681d43d 100644
--- a/cli/cmd/testdata/install_default_override_dst_get_nets.golden
+++ b/cli/cmd/testdata/install_default_override_dst_get_nets.golden
@@ -1800,6 +1800,7 @@ metadata:
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
 spec:
+  concurrencyPolicy: Replace
   schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
diff --git a/cli/cmd/testdata/install_ha_output.golden b/cli/cmd/testdata/install_ha_output.golden
index 6ea3bd78a..8fa067da9 100644
--- a/cli/cmd/testdata/install_ha_output.golden
+++ b/cli/cmd/testdata/install_ha_output.golden
@@ -1986,6 +1986,7 @@ metadata:
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
 spec:
+  concurrencyPolicy: Replace
   schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
diff --git a/cli/cmd/testdata/install_ha_with_overrides_output.golden b/cli/cmd/testdata/install_ha_with_overrides_output.golden
index e457b3ce5..7f7063ec4 100644
--- a/cli/cmd/testdata/install_ha_with_overrides_output.golden
+++ b/cli/cmd/testdata/install_ha_with_overrides_output.golden
@@ -1986,6 +1986,7 @@ metadata:
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
 spec:
+  concurrencyPolicy: Replace
   schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
diff --git a/cli/cmd/testdata/install_helm_output.golden b/cli/cmd/testdata/install_helm_output.golden
index 4c3c01cc6..46f7acb0a 100644
--- a/cli/cmd/testdata/install_helm_output.golden
+++ b/cli/cmd/testdata/install_helm_output.golden
@@ -916,7 +916,7 @@ data:
     enablePodAntiAffinity: false
     grafanaUrl: ""
     heartbeatResources: null
-    heartbeatSchedule: 0 0 * * *
+    heartbeatSchedule: 1 2 3 4 5
     highAvailability: false
     identity:
       issuer:
@@ -1777,7 +1777,8 @@ metadata:
   annotations:
     linkerd.io/created-by: linkerd/helm linkerd-version
 spec:
-  schedule: "0 0 * * *"
+  concurrencyPolicy: Replace
+  schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
     spec:
diff --git a/cli/cmd/testdata/install_helm_output_ha.golden b/cli/cmd/testdata/install_helm_output_ha.golden
index dcd81da22..46264dfd0 100644
--- a/cli/cmd/testdata/install_helm_output_ha.golden
+++ b/cli/cmd/testdata/install_helm_output_ha.golden
@@ -928,7 +928,7 @@ data:
       memory:
         limit: 250Mi
         request: 50Mi
-    heartbeatSchedule: 0 0 * * *
+    heartbeatSchedule: 1 2 3 4 5
     highAvailability: false
     identity:
       issuer:
@@ -1963,7 +1963,8 @@ metadata:
   annotations:
     linkerd.io/created-by: linkerd/helm linkerd-version
 spec:
-  schedule: "0 0 * * *"
+  concurrencyPolicy: Replace
+  schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
     spec:
diff --git a/cli/cmd/testdata/install_helm_output_ha_labels.golden b/cli/cmd/testdata/install_helm_output_ha_labels.golden
index 75cc3ead9..83019a553 100644
--- a/cli/cmd/testdata/install_helm_output_ha_labels.golden
+++ b/cli/cmd/testdata/install_helm_output_ha_labels.golden
@@ -928,7 +928,7 @@ data:
       memory:
         limit: 250Mi
         request: 50Mi
-    heartbeatSchedule: 0 0 * * *
+    heartbeatSchedule: 1 2 3 4 5
     highAvailability: false
     identity:
       issuer:
@@ -1979,7 +1979,8 @@ metadata:
   annotations:
     linkerd.io/created-by: linkerd/helm linkerd-version
 spec:
-  schedule: "0 0 * * *"
+  concurrencyPolicy: Replace
+  schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
     spec:
diff --git a/cli/cmd/testdata/install_helm_output_ha_namespace_selector.golden b/cli/cmd/testdata/install_helm_output_ha_namespace_selector.golden
index 47dd4fc3c..dceb98881 100644
--- a/cli/cmd/testdata/install_helm_output_ha_namespace_selector.golden
+++ b/cli/cmd/testdata/install_helm_output_ha_namespace_selector.golden
@@ -928,7 +928,7 @@ data:
       memory:
         limit: 250Mi
         request: 50Mi
-    heartbeatSchedule: 0 0 * * *
+    heartbeatSchedule: 1 2 3 4 5
     highAvailability: false
     identity:
       issuer:
@@ -1963,7 +1963,8 @@ metadata:
   annotations:
     linkerd.io/created-by: linkerd/helm linkerd-version
 spec:
-  schedule: "0 0 * * *"
+  concurrencyPolicy: Replace
+  schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
     spec:
diff --git a/cli/cmd/testdata/install_no_init_container.golden b/cli/cmd/testdata/install_no_init_container.golden
index 95bb08791..c64586889 100644
--- a/cli/cmd/testdata/install_no_init_container.golden
+++ b/cli/cmd/testdata/install_no_init_container.golden
@@ -1683,6 +1683,7 @@ metadata:
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
 spec:
+  concurrencyPolicy: Replace
   schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
diff --git a/cli/cmd/testdata/install_output.golden b/cli/cmd/testdata/install_output.golden
index e79feddbb..e53179665 100644
--- a/cli/cmd/testdata/install_output.golden
+++ b/cli/cmd/testdata/install_output.golden
@@ -894,7 +894,7 @@ data:
     enablePodAntiAffinity: false
     grafanaUrl: ""
     heartbeatResources: null
-    heartbeatSchedule: ""
+    heartbeatSchedule: 1 2 3 4 5
     highAvailability: false
     identity:
       issuer:
@@ -1806,7 +1806,8 @@ metadata:
   annotations:
     linkerd.io/created-by: CliVersion
 spec:
-  schedule: ""
+  concurrencyPolicy: Replace
+  schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
     spec:
@@ -2313,7 +2314,7 @@ spec:
 ---
 apiVersion: v1
 data:
-  linkerd-config-overrides: Y2xpVmVyc2lvbjogQ2xpVmVyc2lvbgpjbHVzdGVyTmV0d29ya3M6IENsdXN0ZXJOZXR3b3Jrcwpjb250cm9sUGxhbmVUcmFjaW5nTmFtZXNwYWNlOiAiIgpjb250cm9sbGVySW1hZ2U6IENvbnRyb2xsZXJJbWFnZQpjb250cm9sbGVySW1hZ2VWZXJzaW9uOiBDb250cm9sbGVySW1hZ2VWZXJzaW9uCmNvbnRyb2xsZXJMb2dGb3JtYXQ6IENvbnRyb2xsZXJMb2dGb3JtYXQKY29udHJvbGxlckxvZ0xldmVsOiBDb250cm9sbGVyTG9nTGV2ZWwKZGVidWdDb250YWluZXI6CiAgaW1hZ2U6CiAgICBuYW1lOiBEZWJ1Z0ltYWdlTmFtZQogICAgcHVsbFBvbGljeTogRGVidWdJbWFnZVB1bGxQb2xpY3kKICAgIHZlcnNpb246IERlYnVnVmVyc2lvbgpoZWFydGJlYXRTY2hlZHVsZTogIiIKaWRlbnRpdHk6CiAgaXNzdWVyOgogICAgY3J0RXhwaXJ5OiAiMjAzMC0wOC0yNlQwNzoxMzo0N1oiCiAgICB0bHM6CiAgICAgIGNydFBFTTogfAogICAgICAgIC0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQogICAgICAgIE1JSUJ3RENDQVdlZ0F3SUJBZ0lSQUpSSWdaOFJ0TzhFd2cxWGVwZjhUNDR3Q2dZSUtvWkl6ajBFQXdJd0tURW4KICAgICAgICBNQ1VHQTFVRUF4TWVhV1JsYm5ScGRIa3ViR2x1YTJWeVpDNWpiSFZ6ZEdWeUxteHZZMkZzTUI0WERUSXdNRGd5CiAgICAgICAgT0RBM01UTTBOMW9YRFRNd01EZ3lOakEzTVRNME4xb3dLVEVuTUNVR0ExVUVBeE1lYVdSbGJuUnBkSGt1YkdsdQogICAgICAgIGEyVnlaQzVqYkhWemRHVnlMbXh2WTJGc01Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRTEvRnAKICAgICAgICBmY1JuRGNlZEw2QWpVYVhZUHY0RElNQmFKdWZPSTVOV3R5K1hTWDdKalhnWnRNNzJkUXZSYVlhbnV4RDM2RHQxCiAgICAgICAgMi9KeHlpU2d4S1dSZG9heSthTndNRzR3RGdZRFZSMFBBUUgvQkFRREFnRUdNQklHQTFVZEV3RUIvd1FJTUFZQgogICAgICAgIEFmOENBUUF3SFFZRFZSME9CQllFRkkxV25ycU1ZS2FISE9vK3pweWlpRHEycE8wS01Da0dBMVVkRVFRaU1DQ0MKICAgICAgICBIbWxrWlc1MGFYUjVMbXhwYm10bGNtUXVZMngxYzNSbGNpNXNiMk5oYkRBS0JnZ3Foa2pPUFFRREFnTkhBREJFCiAgICAgICAgQWlBdHVvSTVYdUN0ckdWUnpTbVJUbDJyYTI4YVY5TXlUVTdkNXFuVEFGSEtTZ0lnUktDdmx1T1NnQTVPMjFwNQogICAgICAgIDUxdGRybWtIRVpScjBxbExTSmRIWWdFZk16az0KICAgICAgICAtLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCiAgICAgIGtleVBFTTogfAogICAgICAgIC0tLS0tQkVHSU4gRUMgUFJJVkFURSBLRVktLS0tLQogICAgICAgIE1IY0NBUUVFSUFBZThuZmJ6WnU5Yy9PQjIrOHhKTTBGejdOVXdUUWF6dWxrRk5zNFRJNStvQW9HQ0NxR1NNNDkKICAgICAgICBBd0VIb1VRRFFnQUUxL0ZwZmNSbkRjZWRMNkFqVWFYWVB2NERJTUJhSnVmT0k1Tld0eStYU1g3SmpYZ1p0TTcyCiAgICAgICAgZFF2UmFZYW51eEQzNkR0MTIvSnh5aVNneEtXUmRvYXkrUT09CiAgICAgICAgLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQppZGVudGl0eVRydXN0QW5jaG9yc1BFTTogfAogIC0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQogIE1JSUJ3VENDQVdhZ0F3SUJBZ0lRZURacDVsRGFJeWdRNVVmTUtackZBVEFLQmdncWhrak9QUVFEQWpBcE1TY3cKICBKUVlEVlFRREV4NXBaR1Z1ZEdsMGVTNXNhVzVyWlhKa0xtTnNkWE4wWlhJdWJHOWpZV3d3SGhjTk1qQXdPREk0CiAgTURjeE1qUTNXaGNOTXpBd09ESTJNRGN4TWpRM1dqQXBNU2N3SlFZRFZRUURFeDVwWkdWdWRHbDBlUzVzYVc1cgogIFpYSmtMbU5zZFhOMFpYSXViRzlqWVd3d1dUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFScWM3MFoKICBsMXZndzc5cmpCNXVTSVRJQ1VBNkd5ZnZTRmZjdUlpczdCL1hGU2trd0FIVTVTL3MxQUFQK1IwVFg3SEJXVUM0CiAgdWFHNFdXc2l3SktObjdtZ28zQXdiakFPQmdOVkhROEJBZjhFQkFNQ0FRWXdFZ1lEVlIwVEFRSC9CQWd3QmdFQgogIC93SUJBVEFkQmdOVkhRNEVGZ1FVNVl0alZWUGZkN0k3TkxIc24yQzI2RUJ5R1Ywd0tRWURWUjBSQkNJd0lJSWUKICBhV1JsYm5ScGRIa3ViR2x1YTJWeVpDNWpiSFZ6ZEdWeUxteHZZMkZzTUFvR0NDcUdTTTQ5QkFNQ0Ewa0FNRVlDCiAgSVFDTjdsQkZMRER2ang2VjArWGtqcEtFUlJzSllmNWFkTXZubG9GbDQ4aWxKZ0loQU50eGhuZGNyK1FKUHVDOAogIHZnVUMwZDIvOUZNdWVJVk1iKzQ2V1RDT2pzcXIKICAtLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCmltYWdlUHVsbFBvbGljeTogSW1hZ2VQdWxsUG9saWN5CmltYWdlUHVsbFNlY3JldHM6IG51bGwKbGlua2VyZFZlcnNpb246ICIiCnByb2ZpbGVWYWxpZGF0b3I6CiAgY2FCdW5kbGU6IHByb2ZpbGUgdmFsaWRhdG9yIENBIGJ1bmRsZQogIGNydFBFTTogcHJvZmlsZSB2YWxpZGF0b3IgY3J0CiAga2V5UEVNOiBwcm9maWxlIHZhbGlkYXRvciBrZXkKcHJveHk6CiAgaW1hZ2U6CiAgICBuYW1lOiBQcm94eUltYWdlTmFtZQogICAgcHVsbFBvbGljeTogSW1hZ2VQdWxsUG9saWN5CiAgICB2ZXJzaW9uOiBQcm94eVZlcnNpb24KICBpbmJvdW5kQ29ubmVjdFRpbWVvdXQ6ICIiCiAgb3V0Ym91bmRDb25uZWN0VGltZW91dDogIiIKICByZXNvdXJjZXM6CiAgICBjcHU6CiAgICAgIGxpbWl0OiBjcHUtbGltaXQKICAgICAgcmVxdWVzdDogY3B1LXJlcXVlc3QKICAgIG1lbW9yeToKICAgICAgbGltaXQ6IG1lbW9yeS1saW1pdAogICAgICByZXF1ZXN0OiBtZW1vcnktcmVxdWVzdApwcm94eUNvbnRhaW5lck5hbWU6IFByb3h5Q29udGFpbmVyTmFtZQpwcm94eUluaXQ6CiAgaWdub3JlT3V0Ym91bmRQb3J0czogIjQ0MyIKICBpbWFnZToKICAgIG5hbWU6IFByb3h5SW5pdEltYWdlTmFtZQogICAgcHVsbFBvbGljeTogSW1hZ2VQdWxsUG9saWN5CiAgICB2ZXJzaW9uOiBQcm94eUluaXRWZXJzaW9uCnByb3h5SW5qZWN0b3I6CiAgY2FCdW5kbGU6IHByb3h5IGluamVjdG9yIENBIGJ1bmRsZQogIGNydFBFTTogcHJveHkgaW5qZWN0b3IgY3J0CiAga2V5UEVNOiBwcm94eSBpbmplY3RvciBrZXkKd2ViaG9va0ZhaWx1cmVQb2xpY3k6IFdlYmhvb2tGYWlsdXJlUG9saWN5Cg==
+  linkerd-config-overrides: Y2xpVmVyc2lvbjogQ2xpVmVyc2lvbgpjbHVzdGVyTmV0d29ya3M6IENsdXN0ZXJOZXR3b3Jrcwpjb250cm9sUGxhbmVUcmFjaW5nTmFtZXNwYWNlOiAiIgpjb250cm9sbGVySW1hZ2U6IENvbnRyb2xsZXJJbWFnZQpjb250cm9sbGVySW1hZ2VWZXJzaW9uOiBDb250cm9sbGVySW1hZ2VWZXJzaW9uCmNvbnRyb2xsZXJMb2dGb3JtYXQ6IENvbnRyb2xsZXJMb2dGb3JtYXQKY29udHJvbGxlckxvZ0xldmVsOiBDb250cm9sbGVyTG9nTGV2ZWwKZGVidWdDb250YWluZXI6CiAgaW1hZ2U6CiAgICBuYW1lOiBEZWJ1Z0ltYWdlTmFtZQogICAgcHVsbFBvbGljeTogRGVidWdJbWFnZVB1bGxQb2xpY3kKICAgIHZlcnNpb246IERlYnVnVmVyc2lvbgpoZWFydGJlYXRTY2hlZHVsZTogMSAyIDMgNCA1CmlkZW50aXR5OgogIGlzc3VlcjoKICAgIGNydEV4cGlyeTogIjIwMzAtMDgtMjZUMDc6MTM6NDdaIgogICAgdGxzOgogICAgICBjcnRQRU06IHwKICAgICAgICAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KICAgICAgICBNSUlCd0RDQ0FXZWdBd0lCQWdJUkFKUklnWjhSdE84RXdnMVhlcGY4VDQ0d0NnWUlLb1pJemowRUF3SXdLVEVuCiAgICAgICAgTUNVR0ExVUVBeE1lYVdSbGJuUnBkSGt1YkdsdWEyVnlaQzVqYkhWemRHVnlMbXh2WTJGc01CNFhEVEl3TURneQogICAgICAgIE9EQTNNVE0wTjFvWERUTXdNRGd5TmpBM01UTTBOMW93S1RFbk1DVUdBMVVFQXhNZWFXUmxiblJwZEhrdWJHbHUKICAgICAgICBhMlZ5WkM1amJIVnpkR1Z5TG14dlkyRnNNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUxL0ZwCiAgICAgICAgZmNSbkRjZWRMNkFqVWFYWVB2NERJTUJhSnVmT0k1Tld0eStYU1g3SmpYZ1p0TTcyZFF2UmFZYW51eEQzNkR0MQogICAgICAgIDIvSnh5aVNneEtXUmRvYXkrYU53TUc0d0RnWURWUjBQQVFIL0JBUURBZ0VHTUJJR0ExVWRFd0VCL3dRSU1BWUIKICAgICAgICBBZjhDQVFBd0hRWURWUjBPQkJZRUZJMVducnFNWUthSEhPbyt6cHlpaURxMnBPMEtNQ2tHQTFVZEVRUWlNQ0NDCiAgICAgICAgSG1sa1pXNTBhWFI1TG14cGJtdGxjbVF1WTJ4MWMzUmxjaTVzYjJOaGJEQUtCZ2dxaGtqT1BRUURBZ05IQURCRQogICAgICAgIEFpQXR1b0k1WHVDdHJHVlJ6U21SVGwycmEyOGFWOU15VFU3ZDVxblRBRkhLU2dJZ1JLQ3ZsdU9TZ0E1TzIxcDUKICAgICAgICA1MXRkcm1rSEVaUnIwcWxMU0pkSFlnRWZNems9CiAgICAgICAgLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQogICAgICBrZXlQRU06IHwKICAgICAgICAtLS0tLUJFR0lOIEVDIFBSSVZBVEUgS0VZLS0tLS0KICAgICAgICBNSGNDQVFFRUlBQWU4bmZielp1OWMvT0IyKzh4Sk0wRno3TlV3VFFhenVsa0ZOczRUSTUrb0FvR0NDcUdTTTQ5CiAgICAgICAgQXdFSG9VUURRZ0FFMS9GcGZjUm5EY2VkTDZBalVhWFlQdjRESU1CYUp1Zk9JNU5XdHkrWFNYN0pqWGdadE03MgogICAgICAgIGRRdlJhWWFudXhEMzZEdDEyL0p4eWlTZ3hLV1Jkb2F5K1E9PQogICAgICAgIC0tLS0tRU5EIEVDIFBSSVZBVEUgS0VZLS0tLS0KaWRlbnRpdHlUcnVzdEFuY2hvcnNQRU06IHwKICAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KICBNSUlCd1RDQ0FXYWdBd0lCQWdJUWVEWnA1bERhSXlnUTVVZk1LWnJGQVRBS0JnZ3Foa2pPUFFRREFqQXBNU2N3CiAgSlFZRFZRUURFeDVwWkdWdWRHbDBlUzVzYVc1clpYSmtMbU5zZFhOMFpYSXViRzlqWVd3d0hoY05NakF3T0RJNAogIE1EY3hNalEzV2hjTk16QXdPREkyTURjeE1qUTNXakFwTVNjd0pRWURWUVFERXg1cFpHVnVkR2wwZVM1c2FXNXIKICBaWEprTG1Oc2RYTjBaWEl1Ykc5allXd3dXVEFUQmdjcWhrak9QUUlCQmdncWhrak9QUU1CQndOQ0FBUnFjNzBaCiAgbDF2Z3c3OXJqQjV1U0lUSUNVQTZHeWZ2U0ZmY3VJaXM3Qi9YRlNra3dBSFU1Uy9zMUFBUCtSMFRYN0hCV1VDNAogIHVhRzRXV3Npd0pLTm43bWdvM0F3YmpBT0JnTlZIUThCQWY4RUJBTUNBUVl3RWdZRFZSMFRBUUgvQkFnd0JnRUIKICAvd0lCQVRBZEJnTlZIUTRFRmdRVTVZdGpWVlBmZDdJN05MSHNuMkMyNkVCeUdWMHdLUVlEVlIwUkJDSXdJSUllCiAgYVdSbGJuUnBkSGt1YkdsdWEyVnlaQzVqYkhWemRHVnlMbXh2WTJGc01Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQwogIElRQ043bEJGTEREdmp4NlYwK1hranBLRVJSc0pZZjVhZE12bmxvRmw0OGlsSmdJaEFOdHhobmRjcitRSlB1QzgKICB2Z1VDMGQyLzlGTXVlSVZNYis0NldUQ09qc3FyCiAgLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQppbWFnZVB1bGxQb2xpY3k6IEltYWdlUHVsbFBvbGljeQppbWFnZVB1bGxTZWNyZXRzOiBudWxsCmxpbmtlcmRWZXJzaW9uOiAiIgpwcm9maWxlVmFsaWRhdG9yOgogIGNhQnVuZGxlOiBwcm9maWxlIHZhbGlkYXRvciBDQSBidW5kbGUKICBjcnRQRU06IHByb2ZpbGUgdmFsaWRhdG9yIGNydAogIGtleVBFTTogcHJvZmlsZSB2YWxpZGF0b3Iga2V5CnByb3h5OgogIGltYWdlOgogICAgbmFtZTogUHJveHlJbWFnZU5hbWUKICAgIHB1bGxQb2xpY3k6IEltYWdlUHVsbFBvbGljeQogICAgdmVyc2lvbjogUHJveHlWZXJzaW9uCiAgaW5ib3VuZENvbm5lY3RUaW1lb3V0OiAiIgogIG91dGJvdW5kQ29ubmVjdFRpbWVvdXQ6ICIiCiAgcmVzb3VyY2VzOgogICAgY3B1OgogICAgICBsaW1pdDogY3B1LWxpbWl0CiAgICAgIHJlcXVlc3Q6IGNwdS1yZXF1ZXN0CiAgICBtZW1vcnk6CiAgICAgIGxpbWl0OiBtZW1vcnktbGltaXQKICAgICAgcmVxdWVzdDogbWVtb3J5LXJlcXVlc3QKcHJveHlDb250YWluZXJOYW1lOiBQcm94eUNvbnRhaW5lck5hbWUKcHJveHlJbml0OgogIGlnbm9yZU91dGJvdW5kUG9ydHM6ICI0NDMiCiAgaW1hZ2U6CiAgICBuYW1lOiBQcm94eUluaXRJbWFnZU5hbWUKICAgIHB1bGxQb2xpY3k6IEltYWdlUHVsbFBvbGljeQogICAgdmVyc2lvbjogUHJveHlJbml0VmVyc2lvbgpwcm94eUluamVjdG9yOgogIGNhQnVuZGxlOiBwcm94eSBpbmplY3RvciBDQSBidW5kbGUKICBjcnRQRU06IHByb3h5IGluamVjdG9yIGNydAogIGtleVBFTTogcHJveHkgaW5qZWN0b3Iga2V5CndlYmhvb2tGYWlsdXJlUG9saWN5OiBXZWJob29rRmFpbHVyZVBvbGljeQo=
 kind: Secret
 metadata:
   creationTimestamp: null
diff --git a/cli/cmd/testdata/install_proxy_ignores.golden b/cli/cmd/testdata/install_proxy_ignores.golden
index 787e1eeb0..1fc16ce77 100644
--- a/cli/cmd/testdata/install_proxy_ignores.golden
+++ b/cli/cmd/testdata/install_proxy_ignores.golden
@@ -1800,6 +1800,7 @@ metadata:
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
 spec:
+  concurrencyPolicy: Replace
   schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
diff --git a/cli/cmd/testdata/install_values_file.golden b/cli/cmd/testdata/install_values_file.golden
index 128ceb248..13dd36062 100644
--- a/cli/cmd/testdata/install_values_file.golden
+++ b/cli/cmd/testdata/install_values_file.golden
@@ -1786,6 +1786,7 @@ metadata:
   annotations:
     linkerd.io/created-by: linkerd/cli dev-undefined
 spec:
+  concurrencyPolicy: Replace
   schedule: "1 2 3 4 5"
   successfulJobsHistoryLimit: 0
   jobTemplate:
diff --git a/pkg/charts/linkerd2/values_test.go b/pkg/charts/linkerd2/values_test.go
index e9102e7a9..e45eecaa3 100644
--- a/pkg/charts/linkerd2/values_test.go
+++ b/pkg/charts/linkerd2/values_test.go
@@ -36,7 +36,7 @@ func TestNewValues(t *testing.T) {
 		WebhookFailurePolicy:         "Ignore",
 		OmitWebhookSideEffects:       false,
 		DisableHeartBeat:             false,
-		HeartbeatSchedule:            "0 0 * * *",
+		HeartbeatSchedule:            "",
 		InstallNamespace:             true,
 		Namespace:                    "linkerd",
 		ClusterDomain:                "cluster.local",
diff --git a/test/integration/install_test.go b/test/integration/install_test.go
index cdd6faded..3311f09ba 100644
--- a/test/integration/install_test.go
+++ b/test/integration/install_test.go
@@ -253,6 +253,7 @@ func TestInstallOrUpgradeCli(t *testing.T) {
 			"--controller-log-level", "debug",
 			"--proxy-version", TestHelper.GetVersion(),
 			"--skip-inbound-ports", skippedInboundPorts,
+			"--set", "heartbeatSchedule=1 2 3 4 5",
 		}
 		vizCmd  = []string{"viz", "install"}
 		vizArgs = []string{
@@ -730,7 +731,7 @@ func TestOverridesSecret(t *testing.T) {
 	t.Run("Check if any unknown fields sneaked in", func(t *testing.T) {
 		knownKeys := tree.Tree{
 			"controllerLogLevel": "debug",
-			"heartbeatSchedule":  extractValue(t, "heartbeatSchedule"),
+			"heartbeatSchedule":  "1 2 3 4 5",
 			"identity": map[string]interface{}{
 				"issuer": map[string]interface{}{},
 			},