使用 Tanka 在 Kubernetes 上部署
通过本部署指南,您可以使用 Jsonnet 库和 Grafana Tanka 将 Tempo 部署到 Kubernetes,创建开发集群或沙盒环境。此过程使用 MinIO 提供对象存储,无论您使用何种云平台或本地存储。在生产环境中,您可以使用您的云提供商的对象存储服务,以避免在生产环境中运行对象存储带来的运维开销。
要使用 Tanka 在 Kubernetes 上设置 Tempo,您需要
- 配置 Kubernetes 并安装 Tanka
- 设置 Tanka 环境
- 安装库
- 部署 MinIO 对象存储
- 可选:启用 metrics-generator
- 使用 Tanka 命令部署 Tempo
注意
此配置不适合生产环境,但可作为学习 Tempo 的有用方法。
开始之前
使用 Tanka 将 Tempo 部署到 Kubernetes,您需要
- 一个 Kubernetes 集群,默认配置至少需要 40 个 CPU 和 46GB 内存。较小的摄入或查询量可以使用远小于此的配置。
kubectl
(版本取决于您集群中 Kubernetes 的 API 版本)
配置 Kubernetes 并安装 Tanka
按照以下步骤配置 Kubernetes 并安装 Tanka。
为安装创建一个新目录,并将其设置为当前工作目录
mkdir tempo cd tempo
创建一个 Kubernetes 命名空间。您可以将本例中的命名空间
tempo
替换为您选择的名称。kubectl create namespace tempo
安装 Grafana Tanka;请参阅 安装 Tanka。
安装
jsonnet-bundler
;请参阅jsonnet-bundler
README。
设置 Tanka 环境
Tanka 需要您 Kubernetes 环境的当前上下文。
检查您的 Kubernetes 集群的当前上下文并确保其正确
kubectl config current-context
初始化 Tanka。这将使用当前的 Kubernetes 上下文
tk init --k8s=false tk env add environments/tempo tk env set environments/tempo \ --namespace=tempo \ --server-from-context=$(kubectl config current-context)
安装库
安装 k.libsonnet
、Jsonnet 和 Memcached 库。
为您版本的 Kubernetes 安装
k.libsonnet
mkdir -p lib export K8S_VERSION=1.25 jb install github.com/jsonnet-libs/k8s-libsonnet/${K8S_VERSION}@main cat <<EOF > lib/k.libsonnet import 'github.com/jsonnet-libs/k8s-libsonnet/${K8S_VERSION}/main.libsonnet' EOF
安装 Tempo Jsonnet 库及其依赖项。
jb install github.com/grafana/tempo/operations/jsonnet/microservices@main
安装 Memcached 库及其依赖项。
jb install github.com/grafana/jsonnet-libs/memcached@master
部署 MinIO 对象存储
MinIO 是一种开源的 Amazon S3 兼容对象存储服务,可免费获取且易于在 Kubernetes 上运行。
创建一个名为
minio.yaml
的文件,并将以下 YAML 配置复制到其中。您可能需要根据您的 Kubernetes 平台删除/修改storageClassName
。例如,GKE 可能不支持local-path
名称,但可能支持standard
等其他选项。apiVersion: v1 kind: PersistentVolumeClaim metadata: # This name uniquely identifies the PVC. Will be used in deployment below. name: minio-pv-claim labels: app: minio-storage-claim spec: # Read more about access modes here: https://kubernetes.ac.cn/docs/user-guide/persistent-volumes/#access-modes accessModes: - ReadWriteOnce storageClassName: local-path resources: # This is the request for storage. Should be available in the cluster. requests: storage: 50Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: minio spec: selector: matchLabels: app: minio strategy: type: Recreate template: metadata: labels: # Label is used as selector in the service. app: minio spec: # Refer to the PVC created earlier volumes: - name: storage persistentVolumeClaim: # Name of the PVC created earlier claimName: minio-pv-claim initContainers: - name: create-buckets image: busybox:1.28 command: - "sh" - "-c" - "mkdir -p /storage/tempo-data" volumeMounts: - name: storage # must match the volume name, above mountPath: "/storage" containers: - name: minio # Pulls the default Minio image from Docker Hub image: minio/minio:latest args: - server - /storage - --console-address - ":9001" env: # Minio access key and secret key - name: MINIO_ACCESS_KEY value: "minio" - name: MINIO_SECRET_KEY value: "minio123" ports: - containerPort: 9000 - containerPort: 9001 volumeMounts: - name: storage # must match the volume name, above mountPath: "/storage" --- apiVersion: v1 kind: Service metadata: name: minio spec: type: ClusterIP ports: - port: 9000 targetPort: 9000 protocol: TCP name: api - port: 9001 targetPort: 9001 protocol: TCP name: console selector: app: minio
运行以下命令应用 minio.yaml 文件
kubectl apply --namespace tempo -f minio.yaml
要检查 MinIO 是否已正确配置,请登录 MinIO 并验证是否已创建一个 bucket。如果没有这些 bucket,将不会存储数据。
将 MinIO 端口转发到 9001
kubectl port-forward --namespace tempo service/minio 9001:9001
使用浏览器导航到 MinIO 管理界面:
https://:9001
。登录凭据是用户名minio
,密码minio123
。验证 Buckets 页面是否列出
tempo-data
。
通过运行以下命令更新
environments/tempo/main.jsonnet
文件的内容,使用 MinIO 对象存储配置 Tempo 集群cat <<EOF > environments/tempo/main.jsonnet // The jsonnet file used to generate the Kubernetes manifests. local tempo = import 'microservices/tempo.libsonnet'; local k = import 'ksonnet-util/kausal.libsonnet'; local container = k.core.v1.container; local containerPort = k.core.v1.containerPort; tempo { _images+:: { tempo: 'grafana/tempo:latest', tempo_query: 'grafana/tempo-query:latest', }, tempo_distributor_container+:: container.withPorts([ containerPort.new('jaeger-grpc', 14250), containerPort.new('otlp-grpc', 4317), ]), _config+:: { namespace: 'tempo', compactor+: { replicas: 1, }, query_frontend+: { replicas: 2, }, querier+: { replicas: 3, }, ingester+: { replicas: 3, pvc_size: '10Gi', pvc_storage_class: 'standard', }, distributor+: { replicas: 3, receivers: { jaeger: { protocols: { grpc: { endpoint: '0.0.0.0:14250', }, }, }, otlp: { protocols: { grpc: { endpoint: '0.0.0.0:4317', }, }, }, }, }, metrics_generator+: { replicas: 1, ephemeral_storage_request_size: '10Gi', ephemeral_storage_limit_size: '11Gi', pvc_size: '10Gi', pvc_storage_class: 'standard', }, memcached+: { replicas: 3, }, bucket: 'tempo-data', backend: 's3', }, tempo_config+:: { storage+: { trace+: { s3: { bucket: $._config.bucket, access_key: 'minio', secret_key: 'minio123', endpoint: 'minio:9000', insecure: true, }, }, }, metrics_generator+: { processor: { span_metrics: {}, service_graphs: {}, }, registry+: { external_labels: { source: 'tempo', }, }, }, overrides+: { metrics_generator_processors: ['service-graphs', 'span-metrics'], }, }, tempo_ingester_container+:: { securityContext+: { runAsUser: 0, }, }, local statefulSet = $.apps.v1.statefulSet, tempo_ingester_statefulset+: statefulSet.mixin.spec.withPodManagementPolicy('Parallel'), } EOF
可选:启用 metrics-generator
在前面的配置中,已启用指标生成。但是,您仍然需要指定将生成的指标数据发送到何处。如果您想将这些指标远程写入到 Prometheus 兼容实例(例如 Grafana Cloud metrics 或 Mimir 实例),您需要在上面的 tempo_config
块的 metrics_generator
部分包含以下配置块(这假定需要基本身份验证,如果不需要,则移除 basic_auth
部分)。您可以通过云门户找到您的 Grafana Cloud 账户的 Grafana Cloud metrics 实例的详细信息。
storage+: {
remote_write: [
{
url: 'https://<urlForPrometheusCompatibleStore>/api/v1/write',
send_exemplars: true,
basic_auth: {
username: '<username>',
password: '<password>',
},
}
],
},
注意:启用指标生成并将其远程写入 Grafana Cloud Metrics 将产生额外的活跃序列,这可能会影响您的账单。有关账单的更多信息,请参阅账单和使用情况。有关指标生成的更多信息,请参阅 Tempo 文档中的Metrics-generator。
可选:降低组件系统要求
较小的摄入和查询量允许使用较少的资源。如果您希望降低分配给组件的资源,可以通过容器配置来完成。例如,更改 ingester 的 CPU 和内存资源分配。
要更改资源要求,请按照以下步骤操作
- 打开
environments/tempo/main.jsonnet
文件。 - 为相应的组件(在本例中是 ingester)添加一个新的配置块
tempo_ingester_container+:: { resources+: { limits+: { cpu: '3', memory: '5Gi', }, requests+: { cpu: '200m', memory: '2Gi', }, }, },
- 保存对文件的更改。
注意
降低这些要求可能会影响整体性能。
使用 Tanka 部署 Tempo
- 使用 Tanka 命令部署 Tempo
tk apply environments/tempo/main.jsonnet
注意
如果在部署 Tempo 后 ingester 未启动,这可能与为预写日志 (Write Ahead Logs) 选择的存储类有关。如果是这种情况,请在 ingester 配置中添加一个适当的存储类。例如,要添加 standard 而不是 fast 存储类,请在上一步的
config
(不是tempo_config
)部分中添加以下内容ingester+: { pvc_storage_class: 'standard', },
后续步骤
Tempo 实例现在将通过 distributor 服务在相关端口 distributor.tempo.svc.cluster.local
接受两个已配置的追踪协议(OTLP gRPC 和 Jaeger gRPC)
- OTLP gRPC:
4317
- Jaeger gRPC:
14250
您可以使用 query-frontend.tempo.svc.cluster.local
服务在端口 3200
上查询 Tempo,或者在端口 16686
或 16687
上进行 Jaeger 类型查询。
现在您已经配置了一个 Tempo 集群,您需要将数据发送到其中。阅读设置测试应用程序获取说明。