Skip to content

Commit 0a97b7c

Browse files
authored
Add multitenant example for Tempo (#11)
* Add multitenant example #10 Signed-off-by: Israel Blancas <[email protected]> * Add missing namespace Signed-off-by: Israel Blancas <[email protected]> * Improve example documentation * Remove usage of minio. Add resources to allow the UI access the traces from the different tenants * Apply feedback requested in PR * Fix typos * Add feedback from code review --------- Signed-off-by: Israel Blancas <[email protected]>
1 parent 827e7f9 commit 0a97b7c

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed

tempo/auth/README.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Tempo authentication
2+
3+
This is an example about how to deploy a Tempo instance using the Tempo Operator. It receives traces from two tenants (`prod` and `dev`).
4+
5+
6+
The Tempo deployment accepts traces from two tenants: `dev` and `prod`. The way to identify the tenants is through the `X-Scope-OrgID` OTLP header. When the `X-Scope-OrgID` header is set to `dev` in the trace, the tenant is `dev`. When the `X-Scope-OrgID` header is set to `prod` in the trace, the tenant is `prod`.
7+
8+
It also enables the creation of the Jaeger UI `.spec.template.queryFrontend.jaegerQuery.enabled` and the gateway (`.spec.template.gateway.enabled`). You can get the URL to the UI for a given tenant with the following command:
9+
10+
```sh
11+
echo https://$(oc get routes tempo-authentication-example-gateway -o jsonpath='{.spec.host}')/<tenant name>
12+
```
13+
14+
For instance, for the `dev` tenant, it would be:
15+
```sh
16+
echo https://$(oc get routes tempo-authentication-example-gateway -o jsonpath='{.spec.host}')/dev
17+
```
18+
19+
The tenant needs permissions to the `tempo.grafana.com` API Group to write traces. You can follow this example to know
20+
how to provide write permissions to the `tenant-sa` `ServiceAccount` to write traces for the `dev` tenant:
21+
```yaml
22+
# Create the Service Account
23+
apiVersion: v1
24+
kind: ServiceAccount
25+
metadata:
26+
name: tenant-sa
27+
namespace: other-namespace
28+
---
29+
# ClusterRole needed to grant permissions to the service account to write traces
30+
# for the given tenant
31+
apiVersion: rbac.authorization.k8s.io/v1
32+
kind: ClusterRole
33+
metadata:
34+
name: tempostack-traces-write
35+
rules:
36+
- apiGroups:
37+
- 'tempo.grafana.com'
38+
# Tenant name set in X-Scope-OrgID
39+
resources:
40+
- dev
41+
resourceNames:
42+
- traces
43+
verbs:
44+
- 'create'
45+
---
46+
apiVersion: rbac.authorization.k8s.io/v1
47+
kind: ClusterRoleBinding
48+
metadata:
49+
name: tempostack-traces
50+
roleRef:
51+
apiGroup: rbac.authorization.k8s.io
52+
kind: ClusterRole
53+
name: tempostack-traces-write
54+
subjects:
55+
- kind: ServiceAccount
56+
name: tenant-sa
57+
namespace: other-namespace
58+
```
59+
Now, you can use the `tenant-sa` `ServiceAccount` in your application or `OpenTelemetry Collector` instance to write traces for the `dev` tenant.
60+
61+
To read the traces, you also need to create a `ClusterRoleBinding` to give `get` permissions to the `traces` resource from the `tempo.grafana.com` API group. In this example, we create a `ClusterRoleBinding` that gives read access to the traces from the `dev` and `prod` tenants to the authenticated users:
62+
```yaml
63+
# Allow the Jaeger UI to retrieve the data from the dev and prod tenants
64+
apiVersion: rbac.authorization.k8s.io/v1
65+
kind: ClusterRole
66+
metadata:
67+
name: tempostack-traces-reader
68+
rules:
69+
- apiGroups:
70+
- 'tempo.grafana.com'
71+
resources:
72+
- dev
73+
- prod
74+
resourceNames:
75+
- traces
76+
verbs:
77+
- 'get'
78+
---
79+
apiVersion: rbac.authorization.k8s.io/v1
80+
kind: ClusterRoleBinding
81+
metadata:
82+
name: tempostack-traces-reader
83+
roleRef:
84+
apiGroup: rbac.authorization.k8s.io
85+
kind: ClusterRole
86+
name: tempostack-traces-reader
87+
subjects:
88+
- kind: Group
89+
apiGroup: rbac.authorization.k8s.io
90+
name: system:authenticated
91+
```
92+
93+
## How to run
94+
1. Create an Object storage instance using [OpenShift Data Foundation](https://access.redhat.com/documentation/en-us/red_hat_openshift_data_foundation/).
95+
1. Create an Object Storage secret with keys as follows:
96+
```console
97+
kubectl create secret generic object-storage \
98+
--from-literal=bucket="<BUCKET_NAME>" \
99+
--from-literal=endpoint="https://s3.openshift-storage.svc" \
100+
--from-literal=access_key_id="<ACCESS_KEY_ID>" \
101+
--from-literal=access_key_secret="<ACCESS_KEY_SECRET>"
102+
```
103+
1. Deploy the Tempo instance in the `tempo-example` OpenShift Project:
104+
```sh
105+
kubectl create -f tempo.yaml
106+
```

tempo/auth/tempo.yaml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
apiVersion: project.openshift.io/v1
2+
kind: Project
3+
metadata:
4+
name: tempo-example
5+
---
6+
# Allow the Jaeger UI to retrieve the data from the dev and prod tenants
7+
apiVersion: rbac.authorization.k8s.io/v1
8+
kind: ClusterRole
9+
metadata:
10+
name: tempostack-traces-reader
11+
rules:
12+
- apiGroups:
13+
- 'tempo.grafana.com'
14+
resources:
15+
- dev
16+
- prod
17+
resourceNames:
18+
- traces
19+
verbs:
20+
- 'get'
21+
---
22+
apiVersion: rbac.authorization.k8s.io/v1
23+
kind: ClusterRoleBinding
24+
metadata:
25+
name: tempostack-traces-reader
26+
roleRef:
27+
apiGroup: rbac.authorization.k8s.io
28+
kind: ClusterRole
29+
name: tempostack-traces-reader
30+
subjects:
31+
- kind: Group
32+
apiGroup: rbac.authorization.k8s.io
33+
name: system:authenticated
34+
---
35+
apiVersion: tempo.grafana.com/v1alpha1
36+
kind: TempoStack
37+
metadata:
38+
name: authentication-example
39+
namespace: tempo-example
40+
spec:
41+
storage:
42+
secret:
43+
name: object-storage
44+
type: s3
45+
storageSize: 1Gi
46+
tenants:
47+
mode: openshift
48+
authentication:
49+
- tenantName: dev
50+
tenantId: "1610b0c3-c509-4592-a256-a1871353dbfa"
51+
- tenantName: prod
52+
tenantId: "1610b0c3-c509-4592-a256-a1871353dbfb"
53+
template:
54+
gateway:
55+
enabled: true
56+
queryFrontend:
57+
jaegerQuery:
58+
enabled: true

0 commit comments

Comments
 (0)