在Kubernetes上部署OpenTelemetry收集器

10人将获赠CNCF商店$100美元礼券!

你填了吗?

image

问卷链接(https://www.wjx.cn/jq/9714648...


作者:Juraci Paixão Kröhling

OpenTelemetry 收集器是一个二进制程序,通常作为代理部署在运行业务应用程序的主机上,但是现在越来越多的应用程序运行在像 Kubernetes 这样的容器平台上。

在 Kubernetes 上运行 OpenTelemetry 收集器需要什么呢?

OpenTelemetry 收集器项目附带了一个示例文件以供 Kubernetes 使用,但是该示例文件的目的是作为一个指南,而不是作为一个可用于生产的解决方案。收集器是如此通用,以至于几乎不可能实现一刀切的部署配置。

部署模式

收集器的裸金属部署很容易规划和执行:它是作为主机上的守护进程运行的单个二进制文件。然而,对于 Kubernetes,我们有几个选择:

  • Deployment,多个副本可能在同一个节点上共存
  • DaemonSet,每个 Kubernetes 节点都有一个实例
  • StatefulSet,始终存在精确数量的副本,每个副本都有一个可预测的名称(collector-1, collector-2,…)
  • Sidecar,一个实例作为容器与运行你的业务应用程序的每个 pod 一起存在,扮演代理的角色

最常见的情况是,你可以混合使用 Deployment 和 Sidecar:Deployment 具有高度弹性,可以通过水平 Pod Autoscale 自动伸缩,而 Sidecar 允许你的应用程序将遥测数据卸载到运行在同一“主机”中的进程。Sidecar 更有可能拥有特定于业务应用程序的定制配置(即处理器),而 Deployment 通常是更通用的配置。

DaemonSet 最常用于单租户、多云部署,在这种情况下,需要确保来自应用程序的遥测数据在到达公共 internet 之前由同一个节点中的一个进程进行预处理。

当收集器实例的副本数量不会频繁更改,并且你正在使用可以从稳定的主机名列表(例如负载平衡导出器)中受益的处理器时,应该使用 StatefulSet。

开列清单

为部署设计好拓扑之后,就可以开始编制清单了!对于本例,我们将使用经典的 Deployment+Sidecar 模式。

无论采用哪种部署模式,你都可能需要为收集器提供一个配置文件。因为这必须是一个实际的文件,我们将为它创建一个 ConfigMap,像这样:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: collector-config
data:
  collector.yaml: |
    receivers:
      otlp:
        protocols:
          grpc:
    processors:
    exporters:
      logging:
    service:
      pipelines:
        traces:
          receivers: [otlp]
          processors: []
          exporters: [logging]
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: agent-config
data:
  agent.yaml: |
    receivers:
      otlp:
        protocols:
          grpc:
    processors:
    exporters:
      otlp:
        endpoint: "opentelemetrycollector.default.svc.cluster.local:4317"
        insecure: true
    service:
      pipelines:
        traces:
          receivers: [otlp]
          processors: []
          exporters: [otlp]

接下来,我们可以创建我们的 Deployment。最简单的解决方案是:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: opentelemetrycollector
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: opentelemetrycollector
  template:
    metadata:
      labels:
        app.kubernetes.io/name: opentelemetrycollector
    spec:
      containers:
      - name: otelcol
        args:
        - --config=/conf/collector.yaml
        image: otel/opentelemetry-collector:0.18.0
        volumeMounts:
        - mountPath: /conf
          name: collector-config
      volumes:
      - configMap:
          items:
          - key: collector.yaml
            path: collector.yaml
          name: collector-config
        name: collector-config

我们现在有了一个启动并运行的收集器实例,但是它仍然不能接收数据:为此,我们需要一个Service来暴露我们在配置中声明的 OTLP 端口。以下是满足该需求的服务定义:

apiVersion: v1
kind: Service
metadata:
  name: opentelemetrycollector
spec:
  ports:
  - name: grpc-otlp
    port: 4317
    protocol: TCP
    targetPort: 4317
  selector:
    app.kubernetes.io/name: opentelemetrycollector
  type: ClusterIP

测试

现在,我们已经为收集器准备好了所有部件,现在是时候启动一个生成跟踪并将其发送到收集器的应用程序了。为此,我们将创建一个 Deployment,其中包含一个应用程序,该应用程序为接收到的每个 HTTP 请求创建跟踪。这个应用程序被打包在一个名为quay.io/jpkroehling/generate-span-java:0.1.0的容器镜像中,我们可以使用如下 Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: myapp
  template:
    metadata:
      labels:
        app.kubernetes.io/name: myapp
    spec:
      containers:
      - name: myapp
        image: quay.io/jpkroehling/generate-span-java:0.1.0
      - name: agent
        image: otel/opentelemetry-collector:0.18.0
        args:
        - --config=/conf/agent.yaml
        volumeMounts:
        - mountPath: /conf
          name: agent-config
      volumes:
      - configMap:
          items:
          - key: agent.yaml
            path: agent.yaml
          name: agent-config
        name: agent-config

当 Deployment 就绪,我们就可以调用它的/orders 端点,它将为我们生成一些跨度。进行测试的最简单方法是执行端口转发,这样对 localhost:8080/orders 的调用就会落在 Kubernetes 集群中的应用程序上:

$ kubectl port-forward deployment/myapp 8080
Forwarding from 127.0.0.1:8080 -> 8080

现在让我们为我们的收集器跟踪日志:一旦我们调用了我们的服务,收集器中的 loggingexport 将确保在日志中记录这个事件。

$ kubectl logs deployments/opentelemetrycollector -f
...
2021-01-22T12:59:53.561Z info service/service.go:267 Everything is ready. Begin running and processing data.

最后,让我们生成一些跨度:

$ curl localhost:8080/order
Created

在收集器的日志中,我们现在应该看到如下内容:

2021-01-22T13:26:49.320Z INFO loggingexporter/logging_exporter.go:313 TracesExporter {"#spans": 2}
2021-01-22T13:26:49.430Z INFO loggingexporter/logging_exporter.go:313 TracesExporter {"#spans": 1}
2021-01-22T13:26:50.422Z INFO loggingexporter/logging_exporter.go:313 TracesExporter {"#spans": 4}
2021-01-22T13:26:50.571Z INFO loggingexporter/logging_exporter.go:313 TracesExporter {"#spans": 1}

这证实了在我们的应用程序中生成的跨已经通过 sidecar 代理转到收集器。在真实的设置中,我们将配置收集器以将我们的 span 导出到真实的后端,如 Jaeger 或 Zipkin。

其他选择

到目前为止,你可能已经意识到在 Kubernetes 上部署一个简单的 OpenTelemetry 收集器实例并不是那么困难。但第二天的问题该怎样,比如版本升级?或者如何使 Service 与 ConfigMap 保持同步,以便配置中定义的所有端口都通过服务自动暴露?自动将 sidecar 注入到业务部署中不是很好吗?这些都是OpenTelemetry Operator 可以完成的任务。

如果你更喜欢 Helm Charts,也有一个实验性的版本可以安装收集器。

总结

OpenTelemetry 收集器是一个非常灵活和轻量级的进程,使混合和匹配策略成为可能,允许根据你非常特定的需求构建收集器链。在 Kubernetes 中部署收集器的单个实例并不是一项复杂的任务,尽管维护这些实例可能会让你考虑使用像 Helm Charts 或 Operator 这样的工具。

感谢 Gary Brown。

点击阅读网站原文


CNCF (Cloud Native Computing Foundation)成立于2015年12月,隶属于Linux  Foundation,是非营利性组织。
CNCF(云原生计算基金会)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。扫描二维码关注CNCF微信公众号。
image

你可能感兴趣的:(在Kubernetes上部署OpenTelemetry收集器)