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