From cb6c1fce0370cf20cb08bbfeae2e903507f977fe Mon Sep 17 00:00:00 2001 From: Tarun Pothulapati Date: Fri, 12 Feb 2021 21:25:42 +0530 Subject: [PATCH] viz: make prom checks dynamic by using annotations (#5680) Fixes #5652 This PR adds new annotation that is added when a external Prometheus is used. Based on that annotations, The CLI can get to know if an external instance is being used and if the annotation is absent, that the the default instance is present. This updates the viz Checks to skip some checkers if the default Prometheus instances are absent. This PR also removes the grafana checks as they are not useful and add unnecessary complexity. This also cleans up some `grafanaUrl` stuff from the core control-plane chart. Signed-off-by: Tarun Pothulapati --- charts/linkerd2/README.md | 1 - charts/linkerd2/values.yaml | 2 - test/integration/testdata/check.viz.golden | 1 - .../testdata/check.viz.proxy.golden | 1 - viz/charts/linkerd-viz/README.md | 1 + .../linkerd-viz/templates/namespace.yaml | 3 + viz/charts/linkerd-viz/values.yaml | 3 + viz/cmd/install_test.go | 7 + .../testdata/install_grafana_disabled.golden | 1037 +++++++++++++++++ .../install_prometheus_disabled.golden | 1 + viz/pkg/healthcheck/healthcheck.go | 46 +- viz/pkg/labels/labels.go | 4 + 12 files changed, 1070 insertions(+), 37 deletions(-) create mode 100644 viz/cmd/testdata/install_grafana_disabled.golden diff --git a/charts/linkerd2/README.md b/charts/linkerd2/README.md index 09d77351a..48c45240e 100644 --- a/charts/linkerd2/README.md +++ b/charts/linkerd2/README.md @@ -145,7 +145,6 @@ Kubernetes: `>=1.13.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 | -| grafanaUrl | string | `""` | url of external grafana instance with reverse proxy configured. | | 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 | diff --git a/charts/linkerd2/values.yaml b/charts/linkerd2/values.yaml index 19ba8830c..8ad8a675c 100644 --- a/charts/linkerd2/values.yaml +++ b/charts/linkerd2/values.yaml @@ -37,8 +37,6 @@ cniEnabled: false identityTrustAnchorsPEM: | # -- Trust domain used for identity identityTrustDomain: *cluster_domain -# -- url of external grafana instance with reverse proxy configured. -grafanaUrl: "" # -- Additional annotations to add to all pods podAnnotations: {} # -- Additional labels to add to all pods diff --git a/test/integration/testdata/check.viz.golden b/test/integration/testdata/check.viz.golden index 8e696d5f6..964926474 100644 --- a/test/integration/testdata/check.viz.golden +++ b/test/integration/testdata/check.viz.golden @@ -9,7 +9,6 @@ linkerd-viz √ linkerd-viz pods are injected √ viz extension pods are running √ prometheus is installed and configured correctly -√ grafana is installed and configured correctly √ can initialize the client √ viz extension self-check diff --git a/test/integration/testdata/check.viz.proxy.golden b/test/integration/testdata/check.viz.proxy.golden index b36479467..243e8f3fa 100644 --- a/test/integration/testdata/check.viz.proxy.golden +++ b/test/integration/testdata/check.viz.proxy.golden @@ -9,7 +9,6 @@ linkerd-viz √ linkerd-viz pods are injected √ viz extension pods are running √ prometheus is installed and configured correctly -√ grafana is installed and configured correctly √ can initialize the client √ viz extension self-check diff --git a/viz/charts/linkerd-viz/README.md b/viz/charts/linkerd-viz/README.md index 1d8f48992..64aee39ba 100644 --- a/viz/charts/linkerd-viz/README.md +++ b/viz/charts/linkerd-viz/README.md @@ -100,6 +100,7 @@ Kubernetes: `>=1.13.0-0` | grafana.resources.cpu.request | string | `nil` | Amount of CPU units that the grafana container requests | | grafana.resources.memory.limit | string | `nil` | Maximum amount of memory that grafana container can use | | grafana.resources.memory.request | string | `nil` | Amount of memory that the grafana container requests | +| grafanaUrl | string | `""` | url of external grafana instance with reverse proxy configured. | | identityTrustDomain | string | `"cluster.local"` | Trust domain used for identity | | imagePullSecrets | list | `[]` | For Private docker registries, authentication is needed. Registry secrets are applied to the respective service accounts | | installNamespace | bool | `true` | Set to false when installing in a custom namespace. | diff --git a/viz/charts/linkerd-viz/templates/namespace.yaml b/viz/charts/linkerd-viz/templates/namespace.yaml index a296aaee5..7aa9a6655 100644 --- a/viz/charts/linkerd-viz/templates/namespace.yaml +++ b/viz/charts/linkerd-viz/templates/namespace.yaml @@ -10,5 +10,8 @@ metadata: labels: {{.Values.extensionAnnotation}}: linkerd-viz annotations: + {{- if .Values.prometheusUrl }} + viz.linkerd.io/external-prometheus: {{.Values.prometheusUrl}} + {{- end }} {{.Values.proxyInjectAnnotation}}: enabled {{ end -}} diff --git a/viz/charts/linkerd-viz/values.yaml b/viz/charts/linkerd-viz/values.yaml index 576e4e61f..a8b8eb99e 100644 --- a/viz/charts/linkerd-viz/values.yaml +++ b/viz/charts/linkerd-viz/values.yaml @@ -52,6 +52,9 @@ enablePodAntiAffinity: false # -- url of external prometheus instance prometheusUrl: "" +# -- url of external grafana instance with reverse proxy configured. +grafanaUrl: "" + # -- url of external jaeger instance # Set this to `jaeger.linkerd-jaeger.svc.` if you plan to use jaeger extension jaegerUrl: "" diff --git a/viz/cmd/install_test.go b/viz/cmd/install_test.go index 1c9848e91..aa6c3933c 100644 --- a/viz/cmd/install_test.go +++ b/viz/cmd/install_test.go @@ -63,6 +63,13 @@ func TestRender(t *testing.T) { }, "install_proxy_resources.golden", }, + { + map[string]interface{}{ + "grafana": map[string]interface{}{"enabled": false}, + "grafanaUrl": "external-grafana.com", + }, + "install_grafana_disabled.golden", + }, } for i, tc := range testCases { diff --git a/viz/cmd/testdata/install_grafana_disabled.golden b/viz/cmd/testdata/install_grafana_disabled.golden new file mode 100644 index 000000000..6731fd2a4 --- /dev/null +++ b/viz/cmd/testdata/install_grafana_disabled.golden @@ -0,0 +1,1037 @@ +--- +### +### Linkerd Viz Extension Namespace +### +kind: Namespace +apiVersion: v1 +metadata: + name: linkerd-viz + labels: + linkerd.io/extension: linkerd-viz + annotations: + linkerd.io/inject: enabled +--- +### +### Metrics API RBAC +### +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-linkerd-viz-metrics-api + labels: + linkerd.io/extension: linkerd-viz + component: metrics-api +rules: +- apiGroups: ["extensions", "apps"] + resources: ["daemonsets", "deployments", "replicasets", "statefulsets"] + verbs: ["list", "get", "watch"] +- apiGroups: ["extensions", "batch"] + resources: ["cronjobs", "jobs"] + verbs: ["list" , "get", "watch"] +- apiGroups: [""] + resources: ["pods", "endpoints", "services", "replicationcontrollers", "namespaces"] + verbs: ["list", "get", "watch"] +- apiGroups: ["linkerd.io"] + resources: ["serviceprofiles"] + verbs: ["list", "get", "watch"] +- apiGroups: ["split.smi-spec.io"] + resources: ["trafficsplits"] + verbs: ["list", "get", "watch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-linkerd-viz-metrics-api + labels: + linkerd.io/extension: linkerd-viz + component: metrics-api +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: linkerd-linkerd-viz-metrics-api +subjects: +- kind: ServiceAccount + name: linkerd-metrics-api + namespace: linkerd-viz +--- +kind: ServiceAccount +apiVersion: v1 +metadata: + name: linkerd-metrics-api + namespace: linkerd-viz + labels: + linkerd.io/extension: linkerd-viz + component: metrics-api +--- +### +### Prometheus RBAC +### +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-linkerd-viz-prometheus + labels: + linkerd.io/extension: linkerd-viz + component: prometheus +rules: +- apiGroups: [""] + resources: ["nodes", "nodes/proxy", "pods"] + verbs: ["get", "list", "watch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-linkerd-viz-prometheus + labels: + linkerd.io/extension: linkerd-viz + component: prometheus +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: linkerd-linkerd-viz-prometheus +subjects: +- kind: ServiceAccount + name: linkerd-prometheus + namespace: linkerd-viz +--- +kind: ServiceAccount +apiVersion: v1 +metadata: + name: linkerd-prometheus + namespace: linkerd-viz + labels: + linkerd.io/extension: linkerd-viz + component: prometheus + namespace: linkerd-viz +--- +### +### Tap RBAC +### +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-linkerd-viz-tap + labels: + linkerd.io/extension: linkerd-viz + component: tap +rules: +- apiGroups: [""] + resources: ["pods", "services", "replicationcontrollers", "namespaces", "nodes"] + verbs: ["list", "get", "watch"] +- apiGroups: ["extensions", "apps"] + resources: ["daemonsets", "deployments", "replicasets", "statefulsets"] + verbs: ["list", "get", "watch"] +- apiGroups: ["extensions", "batch"] + resources: ["cronjobs", "jobs"] + verbs: ["list" , "get", "watch"] +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-linkerd-viz-tap-admin + labels: + linkerd.io/extension: linkerd-viz + component: tap +rules: +- apiGroups: ["tap.linkerd.io"] + resources: ["*"] + verbs: ["watch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-linkerd-viz-tap + labels: + linkerd.io/extension: linkerd-viz + component: tap +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: linkerd-linkerd-viz-tap +subjects: +- kind: ServiceAccount + name: linkerd-tap + namespace: linkerd-viz +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: linkerd-linkerd-viz-tap-auth-delegator + labels: + linkerd.io/extension: linkerd-viz + component: tap +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: linkerd-tap + namespace: linkerd-viz +--- +kind: ServiceAccount +apiVersion: v1 +metadata: + name: linkerd-tap + namespace: linkerd-viz + labels: + linkerd.io/extension: linkerd-viz + component: tap + namespace: linkerd-viz +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: linkerd-linkerd-viz-tap-auth-reader + namespace: kube-system + labels: + linkerd.io/extension: linkerd-viz + component: tap + namespace: linkerd-viz +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: +- kind: ServiceAccount + name: linkerd-tap + namespace: linkerd-viz +--- +kind: Secret +apiVersion: v1 +metadata: + name: linkerd-tap-k8s-tls + namespace: linkerd-viz + labels: + linkerd.io/extension: linkerd-viz + component: tap + namespace: linkerd-viz + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined +type: kubernetes.io/tls +data: + tls.crt: dGVzdC10YXAtY3J0LXBlbQ== + tls.key: dGVzdC10YXAta2V5LXBlbQ== +--- +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + name: v1alpha1.tap.linkerd.io + labels: + linkerd.io/extension: linkerd-viz + component: tap +spec: + group: tap.linkerd.io + version: v1alpha1 + groupPriorityMinimum: 1000 + versionPriority: 100 + service: + name: linkerd-tap + namespace: linkerd-viz + caBundle: dGVzdC10YXAtY2EtYnVuZGxl +--- +### +### Web RBAC +### +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: linkerd-web + namespace: linkerd + labels: + linkerd.io/extension: linkerd-viz + component: web + namespace: linkerd +rules: +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["get"] + resourceNames: ["linkerd-config"] +- apiGroups: [""] + resources: ["namespaces", "configmaps"] + verbs: ["get"] +- apiGroups: [""] + resources: ["serviceaccounts", "pods"] + verbs: ["list"] +- apiGroups: ["apps"] + resources: ["replicasets"] + verbs: ["list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: linkerd-web + namespace: linkerd + labels: + linkerd.io/extension: linkerd-viz + component: web + namespace: linkerd +roleRef: + kind: Role + name: linkerd-web + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: linkerd-web + namespace: linkerd-viz +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: linkerd-linkerd-viz-web-check + labels: + linkerd.io/extension: linkerd-viz + component: web +rules: +- apiGroups: ["rbac.authorization.k8s.io"] + resources: ["clusterroles", "clusterrolebindings"] + verbs: ["list"] +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["list"] +- apiGroups: ["admissionregistration.k8s.io"] + resources: ["mutatingwebhookconfigurations", "validatingwebhookconfigurations"] + verbs: ["list"] +- apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + verbs: ["list"] +- apiGroups: ["linkerd.io"] + resources: ["serviceprofiles"] + verbs: ["list"] +- apiGroups: ["apiregistration.k8s.io"] + resources: ["apiservices"] + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: linkerd-linkerd-viz-web-check + labels: + linkerd.io/extension: linkerd-viz + component: web +roleRef: + kind: ClusterRole + name: linkerd-linkerd-viz-web-check + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: linkerd-web + namespace: linkerd-viz +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-linkerd-viz-web-admin + labels: + linkerd.io/extension: linkerd-viz + component: web +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: linkerd-linkerd-viz-tap-admin +subjects: +- kind: ServiceAccount + name: linkerd-web + namespace: linkerd-viz +--- +kind: ServiceAccount +apiVersion: v1 +metadata: + name: linkerd-web + namespace: linkerd-viz + labels: + linkerd.io/extension: linkerd-viz + component: web + namespace: linkerd-viz +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: linkerd-viz-psp + namespace: linkerd-viz + labels: + linkerd.io/extension: linkerd-viz + namespace: linkerd-viz +roleRef: + kind: Role + name: linkerd-psp + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: linkerd-tap + namespace: linkerd-viz +- kind: ServiceAccount + name: linkerd-web + namespace: linkerd-viz +- kind: ServiceAccount + name: linkerd-prometheus + namespace: linkerd-viz +--- +### +### Metrics API +### +kind: Service +apiVersion: v1 +metadata: + name: linkerd-metrics-api + namespace: linkerd-viz + labels: + linkerd.io/extension: linkerd-viz + component: metrics-api + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined +spec: + type: ClusterIP + selector: + linkerd.io/extension: linkerd-viz + component: metrics-api + ports: + - name: http + port: 8085 + targetPort: 8085 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined + labels: + linkerd.io/extension: linkerd-viz + app.kubernetes.io/name: metrics-api + app.kubernetes.io/part-of: Linkerd + app.kubernetes.io/version: dev-undefined + component: metrics-api + name: linkerd-metrics-api + namespace: linkerd-viz +spec: + replicas: 1 + selector: + matchLabels: + linkerd.io/extension: linkerd-viz + component: metrics-api + template: + metadata: + annotations: + checksum/config: 6827b2203b1cd90692d9dd6a973a2162e574dc9fd7b5b9e346ceac7e287204a6 + linkerd.io/created-by: linkerd/helm dev-undefined + labels: + linkerd.io/extension: linkerd-viz + component: metrics-api + spec: + nodeSelector: + beta.kubernetes.io/os: linux + containers: + - args: + - -controller-namespace=linkerd + - -log-level=info + - -cluster-domain=cluster.local + - -prometheus-url=http://linkerd-prometheus.linkerd-viz.svc.cluster.local:9090 + image: ghcr.io/linkerd/metrics-api:dev-undefined + imagePullPolicy: + livenessProbe: + httpGet: + path: /ping + port: 9995 + initialDelaySeconds: 10 + name: metrics-api + ports: + - containerPort: 8085 + name: http + - containerPort: 9995 + name: admin-http + readinessProbe: + failureThreshold: 7 + httpGet: + path: /ready + port: 9995 + resources: + securityContext: + runAsUser: 2103 + serviceAccountName: linkerd-metrics-api +--- +### +### Prometheus +### +kind: ConfigMap +apiVersion: v1 +metadata: + name: linkerd-prometheus-config + namespace: linkerd-viz + labels: + linkerd.io/extension: linkerd-viz + component: prometheus + namespace: linkerd-viz + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined +data: + prometheus.yml: |- + global: + evaluation_interval: 10s + scrape_interval: 10s + scrape_timeout: 10s + + rule_files: + - /etc/prometheus/*_rules.yml + - /etc/prometheus/*_rules.yaml + + scrape_configs: + - job_name: 'prometheus' + static_configs: + - targets: ['localhost:9090'] + + + + # Required for: https://grafana.com/grafana/dashboards/315 + - job_name: 'kubernetes-nodes-cadvisor' + scheme: https + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + kubernetes_sd_configs: + - role: node + relabel_configs: + - action: labelmap + regex: __meta_kubernetes_node_label_(.+) + - target_label: __address__ + replacement: kubernetes.default.svc:443 + - source_labels: [__meta_kubernetes_node_name] + regex: (.+) + target_label: __metrics_path__ + replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor + metric_relabel_configs: + - source_labels: [__name__] + regex: '(container|machine)_(cpu|memory|network|fs)_(.+)' + action: keep + - source_labels: [__name__] + regex: 'container_memory_failures_total' # unneeded large metric + action: drop + + - job_name: 'linkerd-controller' + kubernetes_sd_configs: + - role: pod + namespaces: + names: + - 'linkerd' + - 'linkerd-viz' + relabel_configs: + - source_labels: + - __meta_kubernetes_pod_container_port_name + action: keep + regex: admin-http + - source_labels: [__meta_kubernetes_pod_container_name] + action: replace + target_label: component + + - job_name: 'linkerd-service-mirror' + kubernetes_sd_configs: + - role: pod + relabel_configs: + - source_labels: + - __meta_kubernetes_pod_label_linkerd_io_control_plane_component + - __meta_kubernetes_pod_container_port_name + action: keep + regex: linkerd-service-mirror;admin-http$ + - source_labels: [__meta_kubernetes_pod_container_name] + action: replace + target_label: component + + - job_name: 'linkerd-proxy' + kubernetes_sd_configs: + - role: pod + relabel_configs: + - source_labels: + - __meta_kubernetes_pod_container_name + - __meta_kubernetes_pod_container_port_name + - __meta_kubernetes_pod_label_linkerd_io_control_plane_ns + action: keep + regex: ^linkerd-proxy;linkerd-admin;linkerd$ + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: namespace + - source_labels: [__meta_kubernetes_pod_name] + action: replace + target_label: pod + # special case k8s' "job" label, to not interfere with prometheus' "job" + # label + # __meta_kubernetes_pod_label_linkerd_io_proxy_job=foo => + # k8s_job=foo + - source_labels: [__meta_kubernetes_pod_label_linkerd_io_proxy_job] + action: replace + target_label: k8s_job + # drop __meta_kubernetes_pod_label_linkerd_io_proxy_job + - action: labeldrop + regex: __meta_kubernetes_pod_label_linkerd_io_proxy_job + # __meta_kubernetes_pod_label_linkerd_io_proxy_deployment=foo => + # deployment=foo + - action: labelmap + regex: __meta_kubernetes_pod_label_linkerd_io_proxy_(.+) + # drop all labels that we just made copies of in the previous labelmap + - action: labeldrop + regex: __meta_kubernetes_pod_label_linkerd_io_proxy_(.+) + # __meta_kubernetes_pod_label_linkerd_io_foo=bar => + # foo=bar + - action: labelmap + regex: __meta_kubernetes_pod_label_linkerd_io_(.+) + # Copy all pod labels to tmp labels + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + replacement: __tmp_pod_label_$1 + # Take `linkerd_io_` prefixed labels and copy them without the prefix + - action: labelmap + regex: __tmp_pod_label_linkerd_io_(.+) + replacement: __tmp_pod_label_$1 + # Drop the `linkerd_io_` originals + - action: labeldrop + regex: __tmp_pod_label_linkerd_io_(.+) + # Copy tmp labels into real labels + - action: labelmap + regex: __tmp_pod_label_(.+) +--- +kind: Service +apiVersion: v1 +metadata: + name: linkerd-prometheus + namespace: linkerd-viz + labels: + linkerd.io/extension: linkerd-viz + component: prometheus + namespace: linkerd-viz + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined +spec: + type: ClusterIP + selector: + linkerd.io/extension: linkerd-viz + component: prometheus + ports: + - name: admin-http + port: 9090 + targetPort: 9090 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined + labels: + linkerd.io/extension: linkerd-viz + app.kubernetes.io/name: prometheus + app.kubernetes.io/part-of: Linkerd + app.kubernetes.io/version: dev-undefined + component: prometheus + namespace: linkerd-viz + name: linkerd-prometheus + namespace: linkerd-viz +spec: + replicas: 1 + selector: + matchLabels: + linkerd.io/extension: linkerd-viz + component: prometheus + namespace: linkerd-viz + template: + metadata: + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined + labels: + linkerd.io/extension: linkerd-viz + component: prometheus + namespace: linkerd-viz + spec: + nodeSelector: + beta.kubernetes.io/os: linux + securityContext: + fsGroup: 65534 + containers: + - args: + - --config.file=/etc/prometheus/prometheus.yml + - --log.level=info + - --storage.tsdb.path=/data + - --storage.tsdb.retention.time=6h + image: prom/prometheus:v2.19.3 + imagePullPolicy: + livenessProbe: + httpGet: + path: /-/healthy + port: 9090 + initialDelaySeconds: 30 + timeoutSeconds: 30 + name: prometheus + ports: + - containerPort: 9090 + name: admin-http + readinessProbe: + httpGet: + path: /-/ready + port: 9090 + initialDelaySeconds: 30 + timeoutSeconds: 30 + resources: + securityContext: + runAsNonRoot: true + runAsUser: 65534 + runAsGroup: 65534 + volumeMounts: + - mountPath: /data + name: data + - mountPath: /etc/prometheus/prometheus.yml + name: prometheus-config + subPath: prometheus.yml + readOnly: true + serviceAccountName: linkerd-prometheus + volumes: + - name: data + emptyDir: {} + - configMap: + name: linkerd-prometheus-config + name: prometheus-config +--- +### +### Tap +### +kind: Service +apiVersion: v1 +metadata: + name: linkerd-tap + namespace: linkerd-viz + labels: + linkerd.io/extension: linkerd-viz + component: tap + namespace: linkerd-viz + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined +spec: + type: ClusterIP + selector: + linkerd.io/extension: linkerd-viz + component: tap + ports: + - name: grpc + port: 8088 + targetPort: 8088 + - name: apiserver + port: 443 + targetPort: apiserver +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined + labels: + linkerd.io/extension: linkerd-viz + app.kubernetes.io/name: tap + app.kubernetes.io/part-of: Linkerd + app.kubernetes.io/version: dev-undefined + component: tap + namespace: linkerd-viz + name: linkerd-tap + namespace: linkerd-viz +spec: + replicas: 1 + selector: + matchLabels: + linkerd.io/extension: linkerd-viz + component: tap + namespace: linkerd-viz + template: + metadata: + annotations: + checksum/config: bbc82b03e8c9fdc549e1ef5d3f795c07c21fb3b4c089351186f170b722689d86 + linkerd.io/created-by: linkerd/helm dev-undefined + labels: + linkerd.io/extension: linkerd-viz + component: tap + namespace: linkerd-viz + spec: + nodeSelector: + beta.kubernetes.io/os: linux + containers: + - args: + - api + - -api-namespace=linkerd + - -log-level=info + - -identity-trust-domain=cluster.local + image: ghcr.io/linkerd/tap:dev-undefined + imagePullPolicy: + livenessProbe: + httpGet: + path: /ping + port: 9998 + initialDelaySeconds: 10 + name: tap + ports: + - containerPort: 8088 + name: grpc + - containerPort: 8089 + name: apiserver + - containerPort: 9998 + name: admin-http + readinessProbe: + failureThreshold: 7 + httpGet: + path: /ready + port: 9998 + resources: + securityContext: + runAsUser: 2103 + volumeMounts: + - mountPath: /var/run/linkerd/tls + name: tls + readOnly: true + serviceAccountName: linkerd-tap + volumes: + - name: tls + secret: + secretName: linkerd-tap-k8s-tls + +--- +### +### Tap Injector RBAC +### +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-tap-injector + labels: + linkerd.io/extension: linkerd-viz +rules: +- apiGroups: [""] + resources: ["namespaces"] + verbs: ["get", "list", "watch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-tap-injector + labels: + linkerd.io/extension: linkerd-viz +subjects: +- kind: ServiceAccount + name: tap-injector + namespace: linkerd-viz +roleRef: + kind: ClusterRole + name: linkerd-tap-injector + apiGroup: rbac.authorization.k8s.io +--- +kind: ServiceAccount +apiVersion: v1 +metadata: + name: tap-injector + namespace: linkerd-viz +--- +kind: Secret +apiVersion: v1 +metadata: + name: tap-injector-k8s-tls + namespace: linkerd-viz + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined +type: kubernetes.io/tls +data: + tls.crt: dGVzdC10YXAtY3J0LXBlbQ== + tls.key: dGVzdC10YXAta2V5LXBlbQ== +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: linkerd-tap-injector-webhook-config + labels: + linkerd.io/extension: linkerd-viz +webhooks: +- name: tap-injector.linkerd.io + clientConfig: + service: + name: tap-injector + namespace: linkerd-viz + path: "/" + caBundle: dGVzdC10YXAtY2EtYnVuZGxl + failurePolicy: Ignore + admissionReviewVersions: ["v1", "v1beta1"] + reinvocationPolicy: IfNeeded + rules: + - operations: [ "CREATE" ] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] + sideEffects: None +--- +### +### Tap Injector +### +kind: Service +apiVersion: v1 +metadata: + name: tap-injector + namespace: linkerd-viz + labels: + linkerd.io/extension: linkerd-viz + component: tap-injector + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined +spec: + type: ClusterIP + selector: + component: tap-injector + ports: + - name: tap-injector + port: 443 + targetPort: tap-injector +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined + labels: + linkerd.io/extension: linkerd-viz + app.kubernetes.io/name: tap-injector + app.kubernetes.io/part-of: Linkerd + component: tap-injector + name: tap-injector + namespace: linkerd-viz +spec: + replicas: 1 + selector: + matchLabels: + component: tap-injector + template: + metadata: + annotations: + checksum/config: 0120b5feafdef04a057ab39fd63ed315ebbcc2bfc0b0657e3007fa34ffb8b7e2 + linkerd.io/created-by: linkerd/helm dev-undefined + labels: + linkerd.io/extension: linkerd-viz + component: tap-injector + spec: + nodeSelector: + beta.kubernetes.io/os: linux + containers: + - args: + - injector + - -tap-service-name=linkerd-tap.linkerd-viz.serviceaccount.identity.$(_l5d_ns).$(_l5d_trustdomain) + - -log-level=info + image: ghcr.io/linkerd/tap:dev-undefined + imagePullPolicy: + livenessProbe: + httpGet: + path: /ping + port: 9995 + initialDelaySeconds: 10 + name: tap-injector + ports: + - containerPort: 8443 + name: tap-injector + - containerPort: 9995 + name: admin-http + readinessProbe: + failureThreshold: 7 + httpGet: + path: /ready + port: 9995 + resources: + securityContext: + runAsUser: 2103 + volumeMounts: + - mountPath: /var/run/linkerd/tls + name: tls + readOnly: true + serviceAccountName: tap-injector + volumes: + - name: tls + secret: + secretName: tap-injector-k8s-tls +--- +### +### Web +### +kind: Service +apiVersion: v1 +metadata: + name: linkerd-web + namespace: linkerd-viz + labels: + linkerd.io/extension: linkerd-viz + component: web + namespace: linkerd-viz + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined +spec: + type: ClusterIP + selector: + linkerd.io/extension: linkerd-viz + component: web + ports: + - name: http + port: 8084 + targetPort: 8084 + - name: admin-http + port: 9994 + targetPort: 9994 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined + labels: + linkerd.io/extension: linkerd-viz + app.kubernetes.io/name: web + app.kubernetes.io/part-of: Linkerd + app.kubernetes.io/version: dev-undefined + component: web + namespace: linkerd-viz + name: linkerd-web + namespace: linkerd-viz +spec: + replicas: 1 + selector: + matchLabels: + linkerd.io/extension: linkerd-viz + component: web + namespace: linkerd-viz + template: + metadata: + annotations: + linkerd.io/created-by: linkerd/helm dev-undefined + labels: + linkerd.io/extension: linkerd-viz + component: web + namespace: linkerd-viz + spec: + nodeSelector: + beta.kubernetes.io/os: linux + containers: + - args: + - -linkerd-controller-api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085 + - -linkerd-metrics-api-addr=linkerd-metrics-api.linkerd-viz.svc.cluster.local:8085 + - -cluster-domain=cluster.local + - -grafana-addr=external-grafana.com + - -controller-namespace=linkerd + - -viz-namespace=linkerd-viz + - -log-level=info + - -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd-viz\.svc\.cluster\.local|linkerd-web\.linkerd-viz\.svc|\[::1\])(:\d+)?$ + image: ghcr.io/linkerd/web:dev-undefined + imagePullPolicy: + livenessProbe: + httpGet: + path: /ping + port: 9994 + initialDelaySeconds: 10 + name: web + ports: + - containerPort: 8084 + name: http + - containerPort: 9994 + name: admin-http + readinessProbe: + failureThreshold: 7 + httpGet: + path: /ready + port: 9994 + resources: + securityContext: + runAsUser: 2103 + serviceAccountName: linkerd-web diff --git a/viz/cmd/testdata/install_prometheus_disabled.golden b/viz/cmd/testdata/install_prometheus_disabled.golden index 3bf0b3850..571d36c50 100644 --- a/viz/cmd/testdata/install_prometheus_disabled.golden +++ b/viz/cmd/testdata/install_prometheus_disabled.golden @@ -9,6 +9,7 @@ metadata: labels: linkerd.io/extension: linkerd-viz annotations: + viz.linkerd.io/external-prometheus: external-prom.com linkerd.io/inject: enabled --- ### diff --git a/viz/pkg/healthcheck/healthcheck.go b/viz/pkg/healthcheck/healthcheck.go index 129875295..01ea74db0 100644 --- a/viz/pkg/healthcheck/healthcheck.go +++ b/viz/pkg/healthcheck/healthcheck.go @@ -12,6 +12,7 @@ import ( "github.com/linkerd/linkerd2/pkg/tls" "github.com/linkerd/linkerd2/viz/metrics-api/client" pb "github.com/linkerd/linkerd2/viz/metrics-api/gen/viz" + "github.com/linkerd/linkerd2/viz/pkg/labels" vizLabels "github.com/linkerd/linkerd2/viz/pkg/labels" corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" @@ -41,8 +42,9 @@ const ( // HealthChecker wraps Linkerd's main healthchecker, adding extra fields for Viz type HealthChecker struct { *healthcheck.HealthChecker - vizNamespace string - vizAPIClient pb.ApiClient + vizAPIClient pb.ApiClient + vizNamespace string + externalPrometheusURL string } // NewHealthChecker returns an initialized HealthChecker for Viz @@ -75,10 +77,13 @@ func (hc *HealthChecker) VizCategory() healthcheck.Category { Fatal(). WithCheck(func(ctx context.Context) error { vizNs, err := hc.KubeAPIClient().GetNamespaceWithExtensionLabel(ctx, "linkerd-viz") - if err == nil { - hc.vizNamespace = vizNs.Name + if err != nil { + return err } - return err + + hc.vizNamespace = vizNs.Name + hc.externalPrometheusURL = vizNs.Annotations[labels.VizExternalPrometheus] + return nil }), *healthcheck.NewChecker("linkerd-viz ClusterRoles exist"). WithHintAnchor("l5d-viz-cr-exists"). @@ -166,7 +171,10 @@ func (hc *HealthChecker) VizCategory() healthcheck.Category { WithHintAnchor("l5d-viz-prometheus"). Warning(). WithCheck(func(ctx context.Context) error { - // TODO: Skip if prometheus is disabled + if hc.externalPrometheusURL != "" { + return &healthcheck.SkipError{Reason: "linkerd-prometheus is disabled"} + } + // Check for ClusterRoles err := healthcheck.CheckClusterRoles(ctx, hc.KubeAPIClient(), true, []string{fmt.Sprintf("linkerd-%s-prometheus", hc.vizNamespace)}, "") if err != nil { @@ -196,30 +204,6 @@ func (hc *HealthChecker) VizCategory() healthcheck.Category { return err } - return nil - }), - *healthcheck.NewChecker("grafana is installed and configured correctly"). - WithHintAnchor("l5d-viz-grafana"). - Warning(). - WithCheck(func(ctx context.Context) error { - // TODO: Skip if grafana is disabled - // Check for ConfigMap - err := healthcheck.CheckConfigMaps(ctx, hc.KubeAPIClient(), hc.vizNamespace, true, []string{"linkerd-grafana-config"}, "") - if err != nil { - return err - } - - // Check for relevant pods to be present - pods, err := hc.KubeAPIClient().GetPodsByNamespace(ctx, hc.vizNamespace) - if err != nil { - return err - } - - err = healthcheck.CheckForPods(pods, []string{"linkerd-grafana"}) - if err != nil { - return err - } - return nil }), *healthcheck.NewChecker("can initialize the client"). @@ -287,8 +271,6 @@ func (hc *HealthChecker) VizDataPlaneCategory() healthcheck.Category { return err } - // TODO: Check if prometheus is present - return validateDataPlanePodReporting(pods) }), *healthcheck.NewChecker("data-plane pods have tap enabled"). diff --git a/viz/pkg/labels/labels.go b/viz/pkg/labels/labels.go index cb487c403..8ee739d70 100644 --- a/viz/pkg/labels/labels.go +++ b/viz/pkg/labels/labels.go @@ -16,6 +16,10 @@ const ( // VizTapDisabled can be used to disable tap on the injected proxy. VizTapDisabled = VizAnnotationsPrefix + "/disable-tap" + + // VizExternalPrometheus is only set on the namespace by the install + // when a external prometheus is being used + VizExternalPrometheus = VizAnnotationsPrefix + "/external-prometheus" ) // IsTapEnabled returns true if a pod has an annotation indicating that tap