From b34c4274f240931e724bb4012b04bafc7346e46e Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Wed, 24 Apr 2024 18:48:09 -0400 Subject: [PATCH 01/30] New blog post: OTel Operator Q&A --- .../blog/2024/otel-operator-q-and-a/index.md | 182 ++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 content/en/blog/2024/otel-operator-q-and-a/index.md diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md new file mode 100644 index 000000000000..7f43928f86d8 --- /dev/null +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -0,0 +1,182 @@ +--- +title: OTel Operator Q&A +linkTitle: OTel Operator Q&A +date: 2024-04-24 +author: >- + [Adriana Villela](https://github.com/avillela) (ServiceNow), +# canonical_url: http://somewhere.else/ +--- + +The [OpenTelemetry (OTel) Operator](https://github.com/open-telemetry/opentelemetry-operator) is a [Kubernetes Operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) that manages OTel things for you in your Kubernetes cluster to make life a little easier. It does the following: + +* Manages deployment of the [OpenTelemetry Collector](http://localhost:1313/docs/collector/), supported by the [`OpenTelemetryCollector`](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#getting-started) [custom resource (CR)](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) +* Manages the configuration of a fleet of OpenTelemetry Collectors via [OpAMP](/docs/specs/opamp/) integration, supported by the [`OpAMPBridge`](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opampbridge) custom resource +* Injects and configures [auto-instrumentation](https://www.honeycomb.io/blog/what-is-auto-instrumentation) into your pods, supported by the [`Instrumentation`](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#opentelemetry-auto-instrumentation-injection) custom resource + +I've had a chance to use the Operator in the last year, and learned some pretty cool things, so I thought it might be helpful to share some little OTel Operator goodies that I’ve picked up along the way, in the form of a Q&A. + +Please note that this post assumes that you have some familiarity with OpenTelemetry, the [OpenTelemetry Collector](http://localhost:1313/docs/collector/), the [OpenTelemetry Operator](https://github.com/open-telemetry/opentelemetry-operator) (including the [Target Allocator](https://adri-v.medium.com/prometheus-opentelemetry-better-together-41dc637f2292)), and [Kubernetes](https://kubernetes.io). + +## Q&A + +### Q1: Does the Operator support multiple Collector configuration sources? + +Short answer: no. + +Longer answer: OTel Collector can be fed more than one Collector config YAML file. That way, you can keep your base configurations in say, `otelcol-config.yaml`, and overrides or additions to the base configuration can go in say, `otelcol-config-extras.yaml`. You can see an example of this in the [OTel Demo’s Docker compose file](https://github.com/open-telemetry/opentelemetry-demo/blob/06f020c97f78ae9625d3a4a5d1107c55045c567f/docker-compose.yml#L665-L668). + +Unfortunately, while the OTel Collector supports multiple Collector configuration files, the Collector managed by the OTel Operator does not. + +To get around this, you could merge the multiple Collector configs through some external tool beforehand. For example, if you [were deploying the Operator via Helm](https://github.com/open-telemetry/opentelemetry-helm-charts/tree/main/charts/opentelemetry-operator), you could technically [pass it multiple Collector config files using multiple --values flags](https://stackoverflow.com/a/56653384) and let [Helm](https://helm.sh) do the merging for you. + +For reference, [check out this thread in the #otel-operator CNCF Slack channel](https://cloud-native.slack.com/archives/C033BJ8BASU/p1709321896612279). + + +### Q2: How can I securely reference access tokens in the OpenTelemetryCollector’s configuration? + +In order to send OpenTelemetry data to an observability backend, you must define at least one [exporter](/docs/collector/configuration/#exporters). Whether you use [OTLP](/docs/specs/otel/protocol/) or [some proprietary vendor format](/docs/specs/otel/protocol/), most exporters typically require that you specify an endpoint and an access token when sending data to a vendor backend. + +When using the OpenTelemetry Operator to manage the OTel Collector, the OTel Collector config YAML is defined in the [OpenTelemetryCollector](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#getting-started) CR. This file should be version-controlled and therefore shouldn’t contain any sensitive data, including access tokens stored as plain text. + +Fortunately, the `OpenTelemetryCollector` CR gives us a way to reference that value as a secret. Here’s how you do it: + +1. Create a Kubernetes secret for your access token. Remember to [base-64 encode](https://www.base64encode.org/) the secret. + +2. [Expose the secret as an environment variable](https://kubernetes.io/docs/concepts/configuration/secret/#using-a-secret) by adding it to the `OpenTelemetryCollector` CR’s [`env` section](https://github.com/avillela/otel-target-allocator-talk/blob/21e9643e28165e39bd79f3beec7f2b1f989d87e9/src/resources/02-otel-collector-ls.yml#L16-L21). For example: + + ```yaml + env: + - name: LS_TOKEN + valueFrom: + secretKeyRef: + key: LS_TOKEN + name: otel-collector-secret + ``` + +3. Reference the _environment variable_ in your [exporter definition](https://github.com/avillela/otel-target-allocator-talk/blob/21e9643e28165e39bd79f3beec7f2b1f989d87e9/src/resources/02-otel-collector-ls.yml#L43-L47): + + + ```yaml + exporters: + otlp/ls: + endpoint: "ingest.lightstep.com:443" + headers: + "lightstep-access-token": "${LS_TOKEN}" + ``` + + +For more info, check out my full example [here](https://github.com/avillela/otel-target-allocator-talk/blob/main/src/resources/02-otel-collector-ls.yml), along with full instructions [here](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). + + +### Q3: Is the Operator version at parity with the Collector version? + +The default version of the Collector used by the Operator is typically behind by one version at most. For example, at the time of this writing, the latest Operator version is 0.98.0, and the latest Collector version is 0.99.0. In addition, the default image of the Collector used by the Operator is the [core distribution](/blog/2024/otel-collector-anti-patterns/#3--not-using-the-right-collector-distribution-or-not-building-your-own-distribution) (as opposed to the contrib distribution). + + +### Q4: Can I override the base OTel Collector image? + +Yes! In fact, [you probably should](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579)! + +As we saw earlier, the [core distribution](https://github.cm/open-telemetry/open-telemetry-collector) is the default Collector distribution used by the `OpenTelemetryCollector` CR. The Core distribution is a bare-bones distribution of the Collector for OTel developers to develop and test. It contains a base set of components–i.e. [extensions](/docs/collector/configuration/#service-extensions), [connectors](/docs/collector/configuration/#connectors), [receivers](/docs/collector/configuration/#receivers), [processors](/docs/collector/configuration/#processors), and [exporters](/docs/collector/configuration/#exporters). + +If you want access to more components than the ones offered by core, you can use the contrib distribution instead. The contrib distribution extends the core distribution, and includes components created by third-parties (including vendors and individual community members), that are useful to the OpenTelemetry community at large. + +Or better yet, if you want to use specific Collector components, you can build your own distribution using the [OpenTelemetry Collector Builder](/docs/collector/custom-collector/) (OCB), and include only the components that you need. + +Either way, the OpenTelemetryCollector CR allows you to override the default Collector image with one that better suits your needs by `adding spec.image` to your `OpenTelemetryCollector` YAML. In addition, you can also specify the number of Collector replicas by adding `spec.replicas`. This is totally independent of whether or not you override the Collector image. + +Your code would look something like this: + +```yaml +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: otelcol + namespace: mynamespace +spec: + mode: statefulset + image: + replicas: +... +``` + +Where: + +* `` is the name of a valid Collector image from a container repository +* `` is the number of pod instances for the underlying OpenTelemetry Collector + +Keep in mind that if you're pulling a Collector image from a private container registry, you'll need to use [`imagePullSecrets`](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). Since private container registries require authentication, this will enable you to authenticate against that private registry. For more info on how to use `imagePullSecrets` for your Collector image, check out the instructions [here](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#using-imagepullsecrets). + +For more info, check out the [OpenTelemetryCollector CR API docs](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opentelemetrycollector). + + +### Q4: Does the Target Allocator work for all deployment types? + +No. The Target Allocator only works for [Deloyment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/), [StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/), and [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) ([newly-introduced](https://github.com/open-telemetry/opentelemetry-operator/pull/2430#discussion_r1420495631)). For reference, check out [this discussion](https://cloud-native.slack.com/archives/C033BJ8BASU/p1709935402250859). + + +### Q5: If I’m using Operator’s Target Allocator for Prometheus service discovery, do I need `PodMonitor` and `ServiceMonitor` CRs installed in my Kubernetes cluster? + +Yes, you do. These CRs are bundled with the [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator); however, they can be installed standalone, which means that you don’t need to install the Prometheus Operator just to use these two CRs with the Target Allocator. + +The easiest way to install the [`PodMonitor`](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.PodMonitor) and [`ServiceMonitor`](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.ServiceMonitor) CRs is to grab a copy of the individual [PodMonitor YAML](https://github.com/prometheus-community/helm-charts/blob/main/charts/kube-prometheus-stack/charts/crds/crds/crd-podmonitors.yaml) and [ServiceMonitor YAML](https://github.com/prometheus-community/helm-charts/blob/main/charts/kube-prometheus-stack/charts/crds/crds/crd-servicemonitors.yaml) [custom resource definitions (CRDs)](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/), like this: + + +```shell +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.2/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml + +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.2/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +``` + +Check out my example of the OpenTelemetry Operator’s Target Allocator with `ServiceMonitor` [here](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). + +### Q6: Do I need to create a service account to use the Target Allocator? + +No, but you do need to do a bit of extra work. So, here’s the deal…although you need a [service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) to use the Target Allocator, you don’t have to create your own. + +If you enable the Target Allocator and don’t create a service account, one is automagically created for you. This service account’s default name is a concatenation of the Collector name (`metadata.name` in the `OpenTelemetryCollector` CR) and `-collector`. For example, if your Collector is called `mycollector`, then your service account would be called `mycollector-collector`. + +By default, this service account has no defined policy. This means that you’ll still need to create your own [`ClusterRole`](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole) and [`ClusterRoleBinding`](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding), and associate the `ClusterRole` to the `ServiceAccount` via `ClusterRoleBinding`. + +See the [Target Allocator readme](https://github.com/open-telemetry/opentelemetry-operator/tree/main/cmd/otel-allocator#rbac) for more on Target Allocator RBAC configuration. + +### Q7: Can I override the Target Allocator base image? + +Just like you can override the Collector base image in the `OpenTelemetryCollector` CR, you can also override the Target Allocator base image. + +Please keep in mind that [it’s usually best to keep the Target Allocator and OTel operator versions the same](https://cloud-native.slack.com/archives/C033BJ8BASU/p1709128862949249?thread_ts=1709081221.484429&cid=C033BJ8BASU), to avoid any compatibility issues. If do you choose to override the Target Allocator’s base image, you can do so by adding `spec.targetAllocator.image` in the `OpenTelemetryCollector` CR. You can also specify the number of replicas by adding `spec.targetAllocator.replicas`. This is totally independent of whether or not you override the TA image. + +Your code would look something like this: + +```yaml +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: otelcol + namespace: mynamespace +spec: + mode: statefulset + targetAllocator: + image: + replicas: +... +``` + +Where: + +* `` is a valid Target Allocator image from a container repository. +* `` is the number of pod instances for the underlying Target Allocator + +### Q8: If it’s not recommended that you override the Target Allocator base image, then why would you want to? + +One use case might be [if you need to host a mirror of the Target Allocator image in your own private container registry for security purposes](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579). + +If you do need to reference a Target Allocator image from a private registry, you’ll need to use `imagePullSecrets`. To use `imagePullSecrets` with the OTel Operator, check out the instructions [here](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#using-imagepullsecrets). Note that you don’t need to create a `serviceAccount` for the Target Allocator, since once is already created for you automagically if you don’t create one yourself (see [Q6](#q6-do-i-need-to-create-a-service-account-to-use-the-target-allocator)). + +For more info, check out the [Target Allocator API docs](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opentelemetrycollectorspectargetallocator). + +## Final Thoughts + +Hopefully this has helped to demystify the OTel Operator a bit more. There’s definitely a lot going on, and the OTel Operator can certainly be a bit scary at first, but understanding some of the basics will get you well on your way to mastering this powerful tool. + +If you have any questions about the OTel Operator, I highly recommend that you post questions on the [#otel-operator](https://cloud-native.slack.com/archives/C033BJ8BASU) channel on the [CNCF Slack](https://communityinviter.com/apps/cloud-native/cncf). Maintainers and contributors are super friendly, and have always been more than willing to answer my questions! You can also [hit me up](https://bento.me/adrianamvillela), and I'll try my best to answer your questions, or to direct you to folks who have the answers! \ No newline at end of file From 3299aabe8969724b407a6dbe8f3b3bd2063e1f2b Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Wed, 24 Apr 2024 18:50:56 -0400 Subject: [PATCH 02/30] Add image --- .../blog/2024/otel-operator-q-and-a/index.md | 2 ++ .../otel-operator-q-and-a/mount-rainier.jpg | Bin 0 -> 222532 bytes 2 files changed, 2 insertions(+) create mode 100644 content/en/blog/2024/otel-operator-q-and-a/mount-rainier.jpg diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 7f43928f86d8..2d81efee027f 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -7,6 +7,8 @@ author: >- # canonical_url: http://somewhere.else/ --- +![Seattle's Mount Rainier rising about the clouds, as seen from an airplane. Photo by Adriana Villela](mount-rainier.jpg) + The [OpenTelemetry (OTel) Operator](https://github.com/open-telemetry/opentelemetry-operator) is a [Kubernetes Operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) that manages OTel things for you in your Kubernetes cluster to make life a little easier. It does the following: * Manages deployment of the [OpenTelemetry Collector](http://localhost:1313/docs/collector/), supported by the [`OpenTelemetryCollector`](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#getting-started) [custom resource (CR)](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) diff --git a/content/en/blog/2024/otel-operator-q-and-a/mount-rainier.jpg b/content/en/blog/2024/otel-operator-q-and-a/mount-rainier.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8230b5ce09f6f9d34b56ec1f740d4dd201bce91c GIT binary patch literal 222532 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 G|M|ZcG>^{! literal 0 HcmV?d00001 From 10bb133d2836307f954b23e440d59e07294a1272 Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Wed, 24 Apr 2024 18:56:20 -0400 Subject: [PATCH 03/30] Added one more question --- content/en/blog/2024/otel-operator-q-and-a/index.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 2d81efee027f..bf2f27582702 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -177,6 +177,10 @@ If you do need to reference a Target Allocator image from a private registry, yo For more info, check out the [Target Allocator API docs](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opentelemetrycollectorspectargetallocator). +### Q9: Is there a version lag between the OTel Operator auto-instrumentation and auto-instrumentation of supported languages? + +If there is a lag, it's minimal, as maintainers try to keep these up to date for each release cycle. Keep in mind that there are breaking changes in some semconvs and the team is trying to avoid breaking users' code. More info [here](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579). + ## Final Thoughts Hopefully this has helped to demystify the OTel Operator a bit more. There’s definitely a lot going on, and the OTel Operator can certainly be a bit scary at first, but understanding some of the basics will get you well on your way to mastering this powerful tool. From cc40f6bbc6603c843f32d87a4bee3347e66a289d Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Wed, 24 Apr 2024 21:10:28 -0400 Subject: [PATCH 04/30] Fix linting issues --- .../blog/2024/otel-operator-q-and-a/index.md | 317 +++++++++++++----- 1 file changed, 233 insertions(+), 84 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index bf2f27582702..dd317502e66e 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -4,20 +4,45 @@ linkTitle: OTel Operator Q&A date: 2024-04-24 author: >- [Adriana Villela](https://github.com/avillela) (ServiceNow), -# canonical_url: http://somewhere.else/ + +# canonical_url: http://somewhere.else/ --- ![Seattle's Mount Rainier rising about the clouds, as seen from an airplane. Photo by Adriana Villela](mount-rainier.jpg) -The [OpenTelemetry (OTel) Operator](https://github.com/open-telemetry/opentelemetry-operator) is a [Kubernetes Operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) that manages OTel things for you in your Kubernetes cluster to make life a little easier. It does the following: - -* Manages deployment of the [OpenTelemetry Collector](http://localhost:1313/docs/collector/), supported by the [`OpenTelemetryCollector`](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#getting-started) [custom resource (CR)](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) -* Manages the configuration of a fleet of OpenTelemetry Collectors via [OpAMP](/docs/specs/opamp/) integration, supported by the [`OpAMPBridge`](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opampbridge) custom resource -* Injects and configures [auto-instrumentation](https://www.honeycomb.io/blog/what-is-auto-instrumentation) into your pods, supported by the [`Instrumentation`](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#opentelemetry-auto-instrumentation-injection) custom resource - -I've had a chance to use the Operator in the last year, and learned some pretty cool things, so I thought it might be helpful to share some little OTel Operator goodies that I’ve picked up along the way, in the form of a Q&A. - -Please note that this post assumes that you have some familiarity with OpenTelemetry, the [OpenTelemetry Collector](http://localhost:1313/docs/collector/), the [OpenTelemetry Operator](https://github.com/open-telemetry/opentelemetry-operator) (including the [Target Allocator](https://adri-v.medium.com/prometheus-opentelemetry-better-together-41dc637f2292)), and [Kubernetes](https://kubernetes.io). +The +[OpenTelemetry (OTel) Operator](https://github.com/open-telemetry/opentelemetry-operator) +is a +[Kubernetes Operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) +that manages OTel things for you in your Kubernetes cluster to make life a +little easier. It does the following: + +- Manages deployment of the + [OpenTelemetry Collector](http://localhost:1313/docs/collector/), supported by + the + [`OpenTelemetryCollector`](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#getting-started) + [custom resource (CR)](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) +- Manages the configuration of a fleet of OpenTelemetry Collectors via + [OpAMP](/docs/specs/opamp/) integration, supported by the + [`OpAMPBridge`](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opampbridge) + custom resource +- Injects and configures + [auto-instrumentation](https://www.honeycomb.io/blog/what-is-auto-instrumentation) + into your pods, supported by the + [`Instrumentation`](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#opentelemetry-auto-instrumentation-injection) + custom resource + +I've had a chance to use the Operator in the last year, and learned some pretty +cool things, so I thought it might be helpful to share some little OTel Operator +goodies that I’ve picked up along the way, in the form of a Q&A. + +Please note that this post assumes that you have some familiarity with +OpenTelemetry, the +[OpenTelemetry Collector](http://localhost:1313/docs/collector/), the +[OpenTelemetry Operator](https://github.com/open-telemetry/opentelemetry-operator) +(including the +[Target Allocator](https://adri-v.medium.com/prometheus-opentelemetry-better-together-41dc637f2292)), +and [Kubernetes](https://kubernetes.io). ## Q&A @@ -25,67 +50,117 @@ Please note that this post assumes that you have some familiarity with OpenTelem Short answer: no. -Longer answer: OTel Collector can be fed more than one Collector config YAML file. That way, you can keep your base configurations in say, `otelcol-config.yaml`, and overrides or additions to the base configuration can go in say, `otelcol-config-extras.yaml`. You can see an example of this in the [OTel Demo’s Docker compose file](https://github.com/open-telemetry/opentelemetry-demo/blob/06f020c97f78ae9625d3a4a5d1107c55045c567f/docker-compose.yml#L665-L668). +Longer answer: OTel Collector can be fed more than one Collector config YAML +file. That way, you can keep your base configurations in say, +`otelcol-config.yaml`, and overrides or additions to the base configuration can +go in say, `otelcol-config-extras.yaml`. You can see an example of this in the +[OTel Demo’s Docker compose file](https://github.com/open-telemetry/opentelemetry-demo/blob/06f020c97f78ae9625d3a4a5d1107c55045c567f/docker-compose.yml#L665-L668). -Unfortunately, while the OTel Collector supports multiple Collector configuration files, the Collector managed by the OTel Operator does not. +Unfortunately, while the OTel Collector supports multiple Collector +configuration files, the Collector managed by the OTel Operator does not. -To get around this, you could merge the multiple Collector configs through some external tool beforehand. For example, if you [were deploying the Operator via Helm](https://github.com/open-telemetry/opentelemetry-helm-charts/tree/main/charts/opentelemetry-operator), you could technically [pass it multiple Collector config files using multiple --values flags](https://stackoverflow.com/a/56653384) and let [Helm](https://helm.sh) do the merging for you. - -For reference, [check out this thread in the #otel-operator CNCF Slack channel](https://cloud-native.slack.com/archives/C033BJ8BASU/p1709321896612279). +To get around this, you could merge the multiple Collector configs through some +external tool beforehand. For example, if you +[were deploying the Operator via Helm](https://github.com/open-telemetry/opentelemetry-helm-charts/tree/main/charts/opentelemetry-operator), +you could technically +[pass it multiple Collector config files using multiple --values flags](https://stackoverflow.com/a/56653384) +and let [Helm](https://helm.sh) do the merging for you. +For reference, +[check out this thread in the #otel-operator CNCF Slack channel](https://cloud-native.slack.com/archives/C033BJ8BASU/p1709321896612279). ### Q2: How can I securely reference access tokens in the OpenTelemetryCollector’s configuration? -In order to send OpenTelemetry data to an observability backend, you must define at least one [exporter](/docs/collector/configuration/#exporters). Whether you use [OTLP](/docs/specs/otel/protocol/) or [some proprietary vendor format](/docs/specs/otel/protocol/), most exporters typically require that you specify an endpoint and an access token when sending data to a vendor backend. - -When using the OpenTelemetry Operator to manage the OTel Collector, the OTel Collector config YAML is defined in the [OpenTelemetryCollector](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#getting-started) CR. This file should be version-controlled and therefore shouldn’t contain any sensitive data, including access tokens stored as plain text. - -Fortunately, the `OpenTelemetryCollector` CR gives us a way to reference that value as a secret. Here’s how you do it: +In order to send OpenTelemetry data to an observability backend, you must define +at least one [exporter](/docs/collector/configuration/#exporters). Whether you +use [OTLP](/docs/specs/otel/protocol/) or +[some proprietary vendor format](/docs/specs/otel/protocol/), most exporters +typically require that you specify an endpoint and an access token when sending +data to a vendor backend. -1. Create a Kubernetes secret for your access token. Remember to [base-64 encode](https://www.base64encode.org/) the secret. +When using the OpenTelemetry Operator to manage the OTel Collector, the OTel +Collector config YAML is defined in the +[OpenTelemetryCollector](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#getting-started) +CR. This file should be version-controlled and therefore shouldn’t contain any +sensitive data, including access tokens stored as plain text. -2. [Expose the secret as an environment variable](https://kubernetes.io/docs/concepts/configuration/secret/#using-a-secret) by adding it to the `OpenTelemetryCollector` CR’s [`env` section](https://github.com/avillela/otel-target-allocator-talk/blob/21e9643e28165e39bd79f3beec7f2b1f989d87e9/src/resources/02-otel-collector-ls.yml#L16-L21). For example: +Fortunately, the `OpenTelemetryCollector` CR gives us a way to reference that +value as a secret. Here’s how you do it: - ```yaml - env: - - name: LS_TOKEN - valueFrom: - secretKeyRef: - key: LS_TOKEN - name: otel-collector-secret - ``` +1. Create a Kubernetes secret for your access token. Remember to + [base-64 encode](https://www.base64encode.org/) the secret. -3. Reference the _environment variable_ in your [exporter definition](https://github.com/avillela/otel-target-allocator-talk/blob/21e9643e28165e39bd79f3beec7f2b1f989d87e9/src/resources/02-otel-collector-ls.yml#L43-L47): +2. [Expose the secret as an environment variable](https://kubernetes.io/docs/concepts/configuration/secret/#using-a-secret) + by adding it to the `OpenTelemetryCollector` CR’s + [`env` section](https://github.com/avillela/otel-target-allocator-talk/blob/21e9643e28165e39bd79f3beec7f2b1f989d87e9/src/resources/02-otel-collector-ls.yml#L16-L21). + For example: +```yaml +env: + - name: LS_TOKEN + valueFrom: + secretKeyRef: + key: LS_TOKEN + name: otel-collector-secret +``` - ```yaml - exporters: - otlp/ls: - endpoint: "ingest.lightstep.com:443" - headers: - "lightstep-access-token": "${LS_TOKEN}" - ``` - +3. Reference the _environment variable_ in your + [exporter definition](https://github.com/avillela/otel-target-allocator-talk/blob/21e9643e28165e39bd79f3beec7f2b1f989d87e9/src/resources/02-otel-collector-ls.yml#L43-L47): -For more info, check out my full example [here](https://github.com/avillela/otel-target-allocator-talk/blob/main/src/resources/02-otel-collector-ls.yml), along with full instructions [here](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). +```yaml +exporters: + otlp/ls: + endpoint: 'ingest.lightstep.com:443' + headers: + 'lightstep-access-token': '${LS_TOKEN}' +``` +For more info, check out my full example +[here](https://github.com/avillela/otel-target-allocator-talk/blob/main/src/resources/02-otel-collector-ls.yml), +along with full instructions +[here](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). ### Q3: Is the Operator version at parity with the Collector version? -The default version of the Collector used by the Operator is typically behind by one version at most. For example, at the time of this writing, the latest Operator version is 0.98.0, and the latest Collector version is 0.99.0. In addition, the default image of the Collector used by the Operator is the [core distribution](/blog/2024/otel-collector-anti-patterns/#3--not-using-the-right-collector-distribution-or-not-building-your-own-distribution) (as opposed to the contrib distribution). - +The default version of the Collector used by the Operator is typically behind by +one version at most. For example, at the time of this writing, the latest +Operator version is 0.98.0, and the latest Collector version is 0.99.0. In +addition, the default image of the Collector used by the Operator is the +[core distribution](/blog/2024/otel-collector-anti-patterns/#3--not-using-the-right-collector-distribution-or-not-building-your-own-distribution) +(as opposed to the contrib distribution). ### Q4: Can I override the base OTel Collector image? -Yes! In fact, [you probably should](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579)! - -As we saw earlier, the [core distribution](https://github.cm/open-telemetry/open-telemetry-collector) is the default Collector distribution used by the `OpenTelemetryCollector` CR. The Core distribution is a bare-bones distribution of the Collector for OTel developers to develop and test. It contains a base set of components–i.e. [extensions](/docs/collector/configuration/#service-extensions), [connectors](/docs/collector/configuration/#connectors), [receivers](/docs/collector/configuration/#receivers), [processors](/docs/collector/configuration/#processors), and [exporters](/docs/collector/configuration/#exporters). - -If you want access to more components than the ones offered by core, you can use the contrib distribution instead. The contrib distribution extends the core distribution, and includes components created by third-parties (including vendors and individual community members), that are useful to the OpenTelemetry community at large. - -Or better yet, if you want to use specific Collector components, you can build your own distribution using the [OpenTelemetry Collector Builder](/docs/collector/custom-collector/) (OCB), and include only the components that you need. - -Either way, the OpenTelemetryCollector CR allows you to override the default Collector image with one that better suits your needs by `adding spec.image` to your `OpenTelemetryCollector` YAML. In addition, you can also specify the number of Collector replicas by adding `spec.replicas`. This is totally independent of whether or not you override the Collector image. +Yes! In fact, +[you probably should](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579)! + +As we saw earlier, the +[core distribution](https://github.cm/open-telemetry/open-telemetry-collector) +is the default Collector distribution used by the `OpenTelemetryCollector` CR. +The Core distribution is a bare-bones distribution of the Collector for OTel +developers to develop and test. It contains a base set of components–i.e. +[extensions](/docs/collector/configuration/#service-extensions), +[connectors](/docs/collector/configuration/#connectors), +[receivers](/docs/collector/configuration/#receivers), +[processors](/docs/collector/configuration/#processors), and +[exporters](/docs/collector/configuration/#exporters). + +If you want access to more components than the ones offered by core, you can use +the contrib distribution instead. The contrib distribution extends the core +distribution, and includes components created by third-parties (including +vendors and individual community members), that are useful to the OpenTelemetry +community at large. + +Or better yet, if you want to use specific Collector components, you can build +your own distribution using the +[OpenTelemetry Collector Builder](/docs/collector/custom-collector/) (OCB), and +include only the components that you need. + +Either way, the OpenTelemetryCollector CR allows you to override the default +Collector image with one that better suits your needs by `adding spec.image` to +your `OpenTelemetryCollector` YAML. In addition, you can also specify the number +of Collector replicas by adding `spec.replicas`. This is totally independent of +whether or not you override the Collector image. Your code would look something like this: @@ -99,30 +174,55 @@ spec: mode: statefulset image: replicas: -... ``` Where: -* `` is the name of a valid Collector image from a container repository -* `` is the number of pod instances for the underlying OpenTelemetry Collector - -Keep in mind that if you're pulling a Collector image from a private container registry, you'll need to use [`imagePullSecrets`](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). Since private container registries require authentication, this will enable you to authenticate against that private registry. For more info on how to use `imagePullSecrets` for your Collector image, check out the instructions [here](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#using-imagepullsecrets). +- `` is the name of a valid Collector image from a container + repository +- `` is the number of pod instances for the underlying + OpenTelemetry Collector -For more info, check out the [OpenTelemetryCollector CR API docs](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opentelemetrycollector). +Keep in mind that if you're pulling a Collector image from a private container +registry, you'll need to use +[`imagePullSecrets`](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). +Since private container registries require authentication, this will enable you +to authenticate against that private registry. For more info on how to use +`imagePullSecrets` for your Collector image, check out the instructions +[here](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#using-imagepullsecrets). +For more info, check out the +[OpenTelemetryCollector CR API docs](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opentelemetrycollector). ### Q4: Does the Target Allocator work for all deployment types? -No. The Target Allocator only works for [Deloyment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/), [StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/), and [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) ([newly-introduced](https://github.com/open-telemetry/opentelemetry-operator/pull/2430#discussion_r1420495631)). For reference, check out [this discussion](https://cloud-native.slack.com/archives/C033BJ8BASU/p1709935402250859). - +No. The Target Allocator only works for +[Deloyment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/), +[StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/), +and +[DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) +([newly-introduced](https://github.com/open-telemetry/opentelemetry-operator/pull/2430#discussion_r1420495631)). +For reference, check out +[this discussion](https://cloud-native.slack.com/archives/C033BJ8BASU/p1709935402250859). ### Q5: If I’m using Operator’s Target Allocator for Prometheus service discovery, do I need `PodMonitor` and `ServiceMonitor` CRs installed in my Kubernetes cluster? -Yes, you do. These CRs are bundled with the [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator); however, they can be installed standalone, which means that you don’t need to install the Prometheus Operator just to use these two CRs with the Target Allocator. - -The easiest way to install the [`PodMonitor`](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.PodMonitor) and [`ServiceMonitor`](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.ServiceMonitor) CRs is to grab a copy of the individual [PodMonitor YAML](https://github.com/prometheus-community/helm-charts/blob/main/charts/kube-prometheus-stack/charts/crds/crds/crd-podmonitors.yaml) and [ServiceMonitor YAML](https://github.com/prometheus-community/helm-charts/blob/main/charts/kube-prometheus-stack/charts/crds/crds/crd-servicemonitors.yaml) [custom resource definitions (CRDs)](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/), like this: - +Yes, you do. These CRs are bundled with the +[Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator); +however, they can be installed standalone, which means that you don’t need to +install the Prometheus Operator just to use these two CRs with the Target +Allocator. + +The easiest way to install the +[`PodMonitor`](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.PodMonitor) +and +[`ServiceMonitor`](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.ServiceMonitor) +CRs is to grab a copy of the individual +[PodMonitor YAML](https://github.com/prometheus-community/helm-charts/blob/main/charts/kube-prometheus-stack/charts/crds/crds/crd-podmonitors.yaml) +and +[ServiceMonitor YAML](https://github.com/prometheus-community/helm-charts/blob/main/charts/kube-prometheus-stack/charts/crds/crds/crd-servicemonitors.yaml) +[custom resource definitions (CRDs)](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/), +like this: ```shell kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.2/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml @@ -130,23 +230,49 @@ kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheu kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.2/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml ``` -Check out my example of the OpenTelemetry Operator’s Target Allocator with `ServiceMonitor` [here](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). +Check out my example of the OpenTelemetry Operator’s Target Allocator with +`ServiceMonitor` +[here](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). ### Q6: Do I need to create a service account to use the Target Allocator? -No, but you do need to do a bit of extra work. So, here’s the deal…although you need a [service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) to use the Target Allocator, you don’t have to create your own. - -If you enable the Target Allocator and don’t create a service account, one is automagically created for you. This service account’s default name is a concatenation of the Collector name (`metadata.name` in the `OpenTelemetryCollector` CR) and `-collector`. For example, if your Collector is called `mycollector`, then your service account would be called `mycollector-collector`. - -By default, this service account has no defined policy. This means that you’ll still need to create your own [`ClusterRole`](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole) and [`ClusterRoleBinding`](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding), and associate the `ClusterRole` to the `ServiceAccount` via `ClusterRoleBinding`. - -See the [Target Allocator readme](https://github.com/open-telemetry/opentelemetry-operator/tree/main/cmd/otel-allocator#rbac) for more on Target Allocator RBAC configuration. +No, but you do need to do a bit of extra work. So, here’s the deal…although you +need a +[service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) +to use the Target Allocator, you don’t have to create your own. + +If you enable the Target Allocator and don’t create a service account, one is +automagically created for you. This service account’s default name is a +concatenation of the Collector name (`metadata.name` in the +`OpenTelemetryCollector` CR) and `-collector`. For example, if your Collector is +called `mycollector`, then your service account would be called +`mycollector-collector`. + +By default, this service account has no defined policy. This means that you’ll +still need to create your own +[`ClusterRole`](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole) +and +[`ClusterRoleBinding`](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding), +and associate the `ClusterRole` to the `ServiceAccount` via +`ClusterRoleBinding`. + +See the +[Target Allocator readme](https://github.com/open-telemetry/opentelemetry-operator/tree/main/cmd/otel-allocator#rbac) +for more on Target Allocator RBAC configuration. ### Q7: Can I override the Target Allocator base image? -Just like you can override the Collector base image in the `OpenTelemetryCollector` CR, you can also override the Target Allocator base image. +Just like you can override the Collector base image in the +`OpenTelemetryCollector` CR, you can also override the Target Allocator base +image. -Please keep in mind that [it’s usually best to keep the Target Allocator and OTel operator versions the same](https://cloud-native.slack.com/archives/C033BJ8BASU/p1709128862949249?thread_ts=1709081221.484429&cid=C033BJ8BASU), to avoid any compatibility issues. If do you choose to override the Target Allocator’s base image, you can do so by adding `spec.targetAllocator.image` in the `OpenTelemetryCollector` CR. You can also specify the number of replicas by adding `spec.targetAllocator.replicas`. This is totally independent of whether or not you override the TA image. +Please keep in mind that +[it’s usually best to keep the Target Allocator and OTel operator versions the same](https://cloud-native.slack.com/archives/C033BJ8BASU/p1709128862949249?thread_ts=1709081221.484429&cid=C033BJ8BASU), +to avoid any compatibility issues. If do you choose to override the Target +Allocator’s base image, you can do so by adding `spec.targetAllocator.image` in +the `OpenTelemetryCollector` CR. You can also specify the number of replicas by +adding `spec.targetAllocator.replicas`. This is totally independent of whether +or not you override the TA image. Your code would look something like this: @@ -161,28 +287,51 @@ spec: targetAllocator: image: replicas: -... ``` Where: -* `` is a valid Target Allocator image from a container repository. -* `` is the number of pod instances for the underlying Target Allocator +- `` is a valid Target Allocator image from a container + repository. +- `` is the number of pod instances for the underlying + Target Allocator -### Q8: If it’s not recommended that you override the Target Allocator base image, then why would you want to? +### Q8: If it’s not recommended that you override the Target Allocator base image, then why would you want to? -One use case might be [if you need to host a mirror of the Target Allocator image in your own private container registry for security purposes](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579). +One use case might be +[if you need to host a mirror of the Target Allocator image in your own private container registry for security purposes](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579). -If you do need to reference a Target Allocator image from a private registry, you’ll need to use `imagePullSecrets`. To use `imagePullSecrets` with the OTel Operator, check out the instructions [here](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#using-imagepullsecrets). Note that you don’t need to create a `serviceAccount` for the Target Allocator, since once is already created for you automagically if you don’t create one yourself (see [Q6](#q6-do-i-need-to-create-a-service-account-to-use-the-target-allocator)). +If you do need to reference a Target Allocator image from a private registry, +you’ll need to use `imagePullSecrets`. To use `imagePullSecrets` with the OTel +Operator, check out the instructions +[here](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#using-imagepullsecrets). +Note that you don’t need to create a `serviceAccount` for the Target Allocator, +since once is already created for you automagically if you don’t create one +yourself (see +[Q6](#q6-do-i-need-to-create-a-service-account-to-use-the-target-allocator)). -For more info, check out the [Target Allocator API docs](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opentelemetrycollectorspectargetallocator). +For more info, check out the +[Target Allocator API docs](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opentelemetrycollectorspectargetallocator). ### Q9: Is there a version lag between the OTel Operator auto-instrumentation and auto-instrumentation of supported languages? -If there is a lag, it's minimal, as maintainers try to keep these up to date for each release cycle. Keep in mind that there are breaking changes in some semconvs and the team is trying to avoid breaking users' code. More info [here](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579). +If there is a lag, it's minimal, as maintainers try to keep these up to date for +each release cycle. Keep in mind that there are breaking changes in some +semconvs and the team is trying to avoid breaking users' code. More info +[here](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579). ## Final Thoughts -Hopefully this has helped to demystify the OTel Operator a bit more. There’s definitely a lot going on, and the OTel Operator can certainly be a bit scary at first, but understanding some of the basics will get you well on your way to mastering this powerful tool. - -If you have any questions about the OTel Operator, I highly recommend that you post questions on the [#otel-operator](https://cloud-native.slack.com/archives/C033BJ8BASU) channel on the [CNCF Slack](https://communityinviter.com/apps/cloud-native/cncf). Maintainers and contributors are super friendly, and have always been more than willing to answer my questions! You can also [hit me up](https://bento.me/adrianamvillela), and I'll try my best to answer your questions, or to direct you to folks who have the answers! \ No newline at end of file +Hopefully this has helped to demystify the OTel Operator a bit more. There’s +definitely a lot going on, and the OTel Operator can certainly be a bit scary at +first, but understanding some of the basics will get you well on your way to +mastering this powerful tool. + +If you have any questions about the OTel Operator, I highly recommend that you +post questions on the +[#otel-operator](https://cloud-native.slack.com/archives/C033BJ8BASU) channel on +the [CNCF Slack](https://communityinviter.com/apps/cloud-native/cncf). +Maintainers and contributors are super friendly, and have always been more than +willing to answer my questions! You can also +[hit me up](https://bento.me/adrianamvillela), and I'll try my best to answer +your questions, or to direct you to folks who have the answers! From 0b5d2ec16cfa306765e7d150dc7fa7909125e7e2 Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Wed, 24 Apr 2024 21:12:56 -0400 Subject: [PATCH 05/30] Fix linting issues --- content/en/blog/2024/otel-operator-q-and-a/index.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index dd317502e66e..676dc4515c44 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -6,6 +6,7 @@ author: >- [Adriana Villela](https://github.com/avillela) (ServiceNow), # canonical_url: http://somewhere.else/ +cSpell:ignore: automagically mycollector Deloyment --- ![Seattle's Mount Rainier rising about the clouds, as seen from an airplane. Photo by Adriana Villela](mount-rainier.jpg) @@ -317,7 +318,8 @@ For more info, check out the If there is a lag, it's minimal, as maintainers try to keep these up to date for each release cycle. Keep in mind that there are breaking changes in some -semconvs and the team is trying to avoid breaking users' code. More info +semantic conventions and the team is trying to avoid breaking users' code. More +info [here](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579). ## Final Thoughts From a67e3edbe95d5d8d9fb9126d8f90204fb6abe7a8 Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Wed, 24 Apr 2024 23:41:19 -0400 Subject: [PATCH 06/30] Fix linting issues --- .../blog/2024/otel-operator-q-and-a/index.md | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 676dc4515c44..dc109cbc13dc 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -6,7 +6,7 @@ author: >- [Adriana Villela](https://github.com/avillela) (ServiceNow), # canonical_url: http://somewhere.else/ -cSpell:ignore: automagically mycollector Deloyment +cSpell:ignore: automagically mycollector --- ![Seattle's Mount Rainier rising about the clouds, as seen from an airplane. Photo by Adriana Villela](mount-rainier.jpg) @@ -96,25 +96,25 @@ value as a secret. Here’s how you do it: [`env` section](https://github.com/avillela/otel-target-allocator-talk/blob/21e9643e28165e39bd79f3beec7f2b1f989d87e9/src/resources/02-otel-collector-ls.yml#L16-L21). For example: -```yaml -env: - - name: LS_TOKEN - valueFrom: - secretKeyRef: - key: LS_TOKEN - name: otel-collector-secret -``` + ```yaml + env: + - name: LS_TOKEN + valueFrom: + secretKeyRef: + key: LS_TOKEN + name: otel-collector-secret + ``` -3. Reference the _environment variable_ in your +3. Reference the environment variable in your [exporter definition](https://github.com/avillela/otel-target-allocator-talk/blob/21e9643e28165e39bd79f3beec7f2b1f989d87e9/src/resources/02-otel-collector-ls.yml#L43-L47): -```yaml -exporters: - otlp/ls: - endpoint: 'ingest.lightstep.com:443' - headers: - 'lightstep-access-token': '${LS_TOKEN}' -``` + ```yaml + exporters: + otlp/ls: + endpoint: 'ingest.lightstep.com:443' + headers: + 'lightstep-access-token': '${LS_TOKEN}' + ``` For more info, check out my full example [here](https://github.com/avillela/otel-target-allocator-talk/blob/main/src/resources/02-otel-collector-ls.yml), @@ -198,7 +198,7 @@ For more info, check out the ### Q4: Does the Target Allocator work for all deployment types? No. The Target Allocator only works for -[Deloyment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/), +[Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/), [StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/), and [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) From 9ee7e2dd9819e463634f025ed9f3b4818ebc37b8 Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Wed, 24 Apr 2024 23:42:32 -0400 Subject: [PATCH 07/30] Fix linting issues --- .../blog/2024/otel-operator-q-and-a/index.md | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index dc109cbc13dc..b8f01fdc29b1 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -96,25 +96,25 @@ value as a secret. Here’s how you do it: [`env` section](https://github.com/avillela/otel-target-allocator-talk/blob/21e9643e28165e39bd79f3beec7f2b1f989d87e9/src/resources/02-otel-collector-ls.yml#L16-L21). For example: - ```yaml - env: - - name: LS_TOKEN - valueFrom: - secretKeyRef: - key: LS_TOKEN - name: otel-collector-secret - ``` +```yaml +env: + - name: LS_TOKEN + valueFrom: + secretKeyRef: + key: LS_TOKEN + name: otel-collector-secret +``` 3. Reference the environment variable in your [exporter definition](https://github.com/avillela/otel-target-allocator-talk/blob/21e9643e28165e39bd79f3beec7f2b1f989d87e9/src/resources/02-otel-collector-ls.yml#L43-L47): - ```yaml - exporters: - otlp/ls: - endpoint: 'ingest.lightstep.com:443' - headers: - 'lightstep-access-token': '${LS_TOKEN}' - ``` +```yaml +exporters: + otlp/ls: + endpoint: 'ingest.lightstep.com:443' + headers: + 'lightstep-access-token': '${LS_TOKEN}' +``` For more info, check out my full example [here](https://github.com/avillela/otel-target-allocator-talk/blob/main/src/resources/02-otel-collector-ls.yml), From 50dc3193e1df60f43f840966c43033973de68fe3 Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Thu, 25 Apr 2024 00:01:46 -0400 Subject: [PATCH 08/30] Fix linting issues --- .../blog/2024/otel-operator-q-and-a/index.md | 19 ++--- static/refcache.json | 80 +++++++++++++++++++ 2 files changed, 90 insertions(+), 9 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index b8f01fdc29b1..63a3cbcc013a 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -5,7 +5,7 @@ date: 2024-04-24 author: >- [Adriana Villela](https://github.com/avillela) (ServiceNow), -# canonical_url: http://somewhere.else/ +canonical_url: https://adri-v.medium.com/81d63addbf92? cSpell:ignore: automagically mycollector --- @@ -88,13 +88,14 @@ sensitive data, including access tokens stored as plain text. Fortunately, the `OpenTelemetryCollector` CR gives us a way to reference that value as a secret. Here’s how you do it: -1. Create a Kubernetes secret for your access token. Remember to - [base-64 encode](https://www.base64encode.org/) the secret. +1- Create a Kubernetes secret for your access token. Remember to +[base-64 encode](https://www.base64encode.org/) the secret. -2. [Expose the secret as an environment variable](https://kubernetes.io/docs/concepts/configuration/secret/#using-a-secret) - by adding it to the `OpenTelemetryCollector` CR’s - [`env` section](https://github.com/avillela/otel-target-allocator-talk/blob/21e9643e28165e39bd79f3beec7f2b1f989d87e9/src/resources/02-otel-collector-ls.yml#L16-L21). - For example: +2- +[Expose the secret as an environment variable](https://kubernetes.io/docs/concepts/configuration/secret/#using-a-secret) +by adding it to the `OpenTelemetryCollector` CR’s +[`env` section](https://github.com/avillela/otel-target-allocator-talk/blob/21e9643e28165e39bd79f3beec7f2b1f989d87e9/src/resources/02-otel-collector-ls.yml#L16-L21). +For example: ```yaml env: @@ -105,8 +106,8 @@ env: name: otel-collector-secret ``` -3. Reference the environment variable in your - [exporter definition](https://github.com/avillela/otel-target-allocator-talk/blob/21e9643e28165e39bd79f3beec7f2b1f989d87e9/src/resources/02-otel-collector-ls.yml#L43-L47): +3- Reference the environment variable in your +[exporter definition](https://github.com/avillela/otel-target-allocator-talk/blob/21e9643e28165e39bd79f3beec7f2b1f989d87e9/src/resources/02-otel-collector-ls.yml#L43-L47): ```yaml exporters: diff --git a/static/refcache.json b/static/refcache.json index 5ce0ab8939a6..b1834a242ad8 100644 --- a/static/refcache.json +++ b/static/refcache.json @@ -47,6 +47,14 @@ "StatusCode": 200, "LastSeen": "2024-02-23T23:30:53.006527-05:00" }, + "https://adri-v.medium.com/81d63addbf92": { + "StatusCode": 200, + "LastSeen": "2024-04-25T00:01:01.348993-04:00" + }, + "https://adri-v.medium.com/prometheus-opentelemetry-better-together-41dc637f2292": { + "StatusCode": 200, + "LastSeen": "2024-04-25T00:01:03.277893-04:00" + }, "https://agilecoffee.com/leancoffee/": { "StatusCode": 200, "LastSeen": "2024-01-18T08:05:43.542109-05:00" @@ -183,6 +191,10 @@ "StatusCode": 200, "LastSeen": "2024-01-18T08:05:49.179762-05:00" }, + "https://bento.me/adrianamvillela": { + "StatusCode": 206, + "LastSeen": "2024-04-25T00:01:12.426363-04:00" + }, "https://betterstack.com/docs/logs/open-telemetry/#2-setup": { "StatusCode": 200, "LastSeen": "2024-01-30T16:14:47.668996-05:00" @@ -355,6 +367,22 @@ "StatusCode": 200, "LastSeen": "2024-01-30T06:07:21.044023-05:00" }, + "https://cloud-native.slack.com/archives/C033BJ8BASU/p1709128862949249": { + "StatusCode": 200, + "LastSeen": "2024-04-25T00:01:12.168228-04:00" + }, + "https://cloud-native.slack.com/archives/C033BJ8BASU/p1709321896612279": { + "StatusCode": 200, + "LastSeen": "2024-04-25T00:01:04.608233-04:00" + }, + "https://cloud-native.slack.com/archives/C033BJ8BASU/p1709935402250859": { + "StatusCode": 200, + "LastSeen": "2024-04-25T00:01:09.586175-04:00" + }, + "https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579": { + "StatusCode": 200, + "LastSeen": "2024-04-25T00:01:06.117078-04:00" + }, "https://cloud-native.slack.com/archives/C03B4CWV4DA": { "StatusCode": 200, "LastSeen": "2024-01-18T08:53:40.157677-05:00" @@ -2079,6 +2107,10 @@ "StatusCode": 200, "LastSeen": "2024-01-30T06:01:12.059909-05:00" }, + "https://github.cm/open-telemetry/open-telemetry-collector": { + "StatusCode": 200, + "LastSeen": "2024-04-25T00:01:07.022619-04:00" + }, "https://github.com": { "StatusCode": 200, "LastSeen": "2024-01-18T19:55:56.862973-05:00" @@ -3707,6 +3739,10 @@ "StatusCode": 200, "LastSeen": "2024-01-18T20:05:35.482435-05:00" }, + "https://github.com/open-telemetry/opentelemetry-operator/pull/2430#discussion_r1420495631": { + "StatusCode": 200, + "LastSeen": "2024-04-25T00:01:09.014347-04:00" + }, "https://github.com/open-telemetry/opentelemetry-operator/pull/832": { "StatusCode": 200, "LastSeen": "2024-01-18T20:05:30.899318-05:00" @@ -4867,6 +4903,10 @@ "StatusCode": 206, "LastSeen": "2024-01-18T19:02:39.056387-05:00" }, + "https://kubernetes.io": { + "StatusCode": 206, + "LastSeen": "2024-04-25T00:01:03.727092-04:00" + }, "https://kubernetes.io/": { "StatusCode": 206, "LastSeen": "2024-01-18T08:52:44.68263-05:00" @@ -4879,6 +4919,14 @@ "StatusCode": 206, "LastSeen": "2024-01-18T08:53:40.07228-05:00" }, + "https://kubernetes.io/docs/concepts/configuration/secret/#using-a-secret": { + "StatusCode": 206, + "LastSeen": "2024-04-25T00:01:05.630302-04:00" + }, + "https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/": { + "StatusCode": 206, + "LastSeen": "2024-04-25T00:01:01.910218-04:00" + }, "https://kubernetes.io/docs/concepts/extend-kubernetes/operator/": { "StatusCode": 206, "LastSeen": "2024-01-18T19:02:12.432637-05:00" @@ -4939,14 +4987,34 @@ "StatusCode": 206, "LastSeen": "2024-01-30T16:14:53.147946-05:00" }, + "https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole": { + "StatusCode": 206, + "LastSeen": "2024-04-25T00:01:11.20031-04:00" + }, + "https://kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding": { + "StatusCode": 206, + "LastSeen": "2024-04-25T00:01:11.609121-04:00" + }, "https://kubernetes.io/docs/reference/kubectl/": { "StatusCode": 206, "LastSeen": "2024-01-30T06:02:57.628168-05:00" }, + "https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/": { + "StatusCode": 206, + "LastSeen": "2024-04-25T00:01:10.691008-04:00" + }, + "https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/": { + "StatusCode": 206, + "LastSeen": "2024-04-25T00:01:07.571021-04:00" + }, "https://kubernetes.io/docs/tasks/debug/debug-cluster/resource-usage-monitoring/": { "StatusCode": 206, "LastSeen": "2024-01-30T06:01:40.735077-05:00" }, + "https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/": { + "StatusCode": 206, + "LastSeen": "2024-04-25T00:01:10.120654-04:00" + }, "https://kyverno.io/": { "StatusCode": 206, "LastSeen": "2024-01-30T16:06:10.681585-05:00" @@ -7655,6 +7723,10 @@ "StatusCode": 206, "LastSeen": "2024-02-26T10:53:38.643051+01:00" }, + "https://stackoverflow.com/a/56653384": { + "StatusCode": 200, + "LastSeen": "2024-04-25T00:01:04.058944-04:00" + }, "https://stackoverflow.com/questions/5626193/what-is-monkey-patching": { "StatusCode": 200, "LastSeen": "2024-01-18T19:07:28.672979-05:00" @@ -7991,6 +8063,10 @@ "StatusCode": 200, "LastSeen": "2024-01-18T19:56:02.154722-05:00" }, + "https://www.base64encode.org/": { + "StatusCode": 200, + "LastSeen": "2024-04-25T00:01:05.091534-04:00" + }, "https://www.bmc.com/blogs/opentracing-opencensus-openmetrics/": { "StatusCode": 200, "LastSeen": "2024-01-18T19:10:51.674944-05:00" @@ -8171,6 +8247,10 @@ "StatusCode": 206, "LastSeen": "2024-01-30T06:01:04.885071-05:00" }, + "https://www.honeycomb.io/blog/what-is-auto-instrumentation": { + "StatusCode": 206, + "LastSeen": "2024-04-25T00:01:02.263794-04:00" + }, "https://www.hyperdx.io/docs/install/opentelemetry": { "StatusCode": 206, "LastSeen": "2024-01-30T16:14:16.496047-05:00" From 2b3431b84c843b0508ac8267107f059f7470efd1 Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Thu, 25 Apr 2024 13:32:35 -0400 Subject: [PATCH 09/30] Make token example more generic --- content/en/blog/2024/otel-operator-q-and-a/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 63a3cbcc013a..a0c529ee0ebe 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -99,10 +99,10 @@ For example: ```yaml env: - - name: LS_TOKEN + - name: TOKEN_VALUE valueFrom: secretKeyRef: - key: LS_TOKEN + key: TOKEN_VALUE name: otel-collector-secret ``` @@ -112,9 +112,9 @@ env: ```yaml exporters: otlp/ls: - endpoint: 'ingest.lightstep.com:443' + endpoint: '' headers: - 'lightstep-access-token': '${LS_TOKEN}' + '': '${TOKEN_VALUE}' ``` For more info, check out my full example From c7f5466f5b03940dc0e1f7df3df4753ae464315a Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Thu, 25 Apr 2024 13:33:33 -0400 Subject: [PATCH 10/30] Make token example more generic --- content/en/blog/2024/otel-operator-q-and-a/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index a0c529ee0ebe..26c325a7fb45 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -111,8 +111,8 @@ env: ```yaml exporters: - otlp/ls: - endpoint: '' + otlp: + endpoint: '' headers: '': '${TOKEN_VALUE}' ``` From df926d0a38dddb81297f8c76ce98b318bbdb5a73 Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Thu, 25 Apr 2024 13:41:52 -0400 Subject: [PATCH 11/30] Incorporate suggestions --- .../blog/2024/otel-operator-q-and-a/index.md | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 26c325a7fb45..9884fac2f1ca 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -15,23 +15,23 @@ The [OpenTelemetry (OTel) Operator](https://github.com/open-telemetry/opentelemetry-operator) is a [Kubernetes Operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) -that manages OTel things for you in your Kubernetes cluster to make life a +that manages OTel for you in your Kubernetes cluster to make life a little easier. It does the following: - Manages deployment of the [OpenTelemetry Collector](http://localhost:1313/docs/collector/), supported by the [`OpenTelemetryCollector`](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#getting-started) - [custom resource (CR)](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) + [custom resource (CR)](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/). - Manages the configuration of a fleet of OpenTelemetry Collectors via [OpAMP](/docs/specs/opamp/) integration, supported by the [`OpAMPBridge`](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opampbridge) - custom resource + custom resource. - Injects and configures [auto-instrumentation](https://www.honeycomb.io/blog/what-is-auto-instrumentation) into your pods, supported by the [`Instrumentation`](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#opentelemetry-auto-instrumentation-injection) - custom resource + custom resource. I've had a chance to use the Operator in the last year, and learned some pretty cool things, so I thought it might be helpful to share some little OTel Operator @@ -49,12 +49,12 @@ and [Kubernetes](https://kubernetes.io). ### Q1: Does the Operator support multiple Collector configuration sources? -Short answer: no. +Short answer: No. Longer answer: OTel Collector can be fed more than one Collector config YAML -file. That way, you can keep your base configurations in say, +file. That way, you can keep your base configurations in, say, `otelcol-config.yaml`, and overrides or additions to the base configuration can -go in say, `otelcol-config-extras.yaml`. You can see an example of this in the +go in, for example, `otelcol-config-extras.yaml`. See an example of this in the [OTel Demo’s Docker compose file](https://github.com/open-telemetry/opentelemetry-demo/blob/06f020c97f78ae9625d3a4a5d1107c55045c567f/docker-compose.yml#L665-L668). Unfortunately, while the OTel Collector supports multiple Collector @@ -70,7 +70,7 @@ and let [Helm](https://helm.sh) do the merging for you. For reference, [check out this thread in the #otel-operator CNCF Slack channel](https://cloud-native.slack.com/archives/C033BJ8BASU/p1709321896612279). -### Q2: How can I securely reference access tokens in the OpenTelemetryCollector’s configuration? +### Q2: How can I securely reference access tokens in the Collector's configuration? In order to send OpenTelemetry data to an observability backend, you must define at least one [exporter](/docs/collector/configuration/#exporters). Whether you @@ -124,10 +124,8 @@ along with full instructions ### Q3: Is the Operator version at parity with the Collector version? -The default version of the Collector used by the Operator is typically behind by -one version at most. For example, at the time of this writing, the latest -Operator version is 0.98.0, and the latest Collector version is 0.99.0. In -addition, the default image of the Collector used by the Operator is the +For every Collector release, there is an Operator release which provides support for that Collector version. For example, at the time of this writing, the latest +Operator version is 0.98.0. Thus, the the default image of the Collector used by the Operator is version 0.98.0 of the [core distribution](/blog/2024/otel-collector-anti-patterns/#3--not-using-the-right-collector-distribution-or-not-building-your-own-distribution) (as opposed to the contrib distribution). @@ -199,13 +197,12 @@ For more info, check out the ### Q4: Does the Target Allocator work for all deployment types? No. The Target Allocator only works for -[Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/), [StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/), and [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) ([newly-introduced](https://github.com/open-telemetry/opentelemetry-operator/pull/2430#discussion_r1420495631)). -For reference, check out -[this discussion](https://cloud-native.slack.com/archives/C033BJ8BASU/p1709935402250859). +More info +[here](https://github.com/open-telemetry/opentelemetry-operator/blob/aed905c2c3c0aa3fb608a79c2e4d0e7b73dff980/apis/v1beta1/collector_webhook.go#L328). ### Q5: If I’m using Operator’s Target Allocator for Prometheus service discovery, do I need `PodMonitor` and `ServiceMonitor` CRs installed in my Kubernetes cluster? @@ -323,7 +320,7 @@ semantic conventions and the team is trying to avoid breaking users' code. More info [here](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579). -## Final Thoughts +## Final thoughts Hopefully this has helped to demystify the OTel Operator a bit more. There’s definitely a lot going on, and the OTel Operator can certainly be a bit scary at From cc88653c5b05e9262adb18fdf2ed0776a75cde4d Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Thu, 25 Apr 2024 13:46:34 -0400 Subject: [PATCH 12/30] Prettify --- content/en/blog/2024/otel-operator-q-and-a/index.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 9884fac2f1ca..a4a2d0e7d032 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -15,8 +15,8 @@ The [OpenTelemetry (OTel) Operator](https://github.com/open-telemetry/opentelemetry-operator) is a [Kubernetes Operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) -that manages OTel for you in your Kubernetes cluster to make life a -little easier. It does the following: +that manages OTel for you in your Kubernetes cluster to make life a little +easier. It does the following: - Manages deployment of the [OpenTelemetry Collector](http://localhost:1313/docs/collector/), supported by @@ -124,8 +124,10 @@ along with full instructions ### Q3: Is the Operator version at parity with the Collector version? -For every Collector release, there is an Operator release which provides support for that Collector version. For example, at the time of this writing, the latest -Operator version is 0.98.0. Thus, the the default image of the Collector used by the Operator is version 0.98.0 of the +For every Collector release, there is an Operator release which provides support +for that Collector version. For example, at the time of this writing, the latest +Operator version is 0.98.0. Thus, the the default image of the Collector used by +the Operator is version 0.98.0 of the [core distribution](/blog/2024/otel-collector-anti-patterns/#3--not-using-the-right-collector-distribution-or-not-building-your-own-distribution) (as opposed to the contrib distribution). From 90e0601594578c921ee5e905b452638baa933300 Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Thu, 25 Apr 2024 14:01:21 -0400 Subject: [PATCH 13/30] Updates from PR comments --- content/en/blog/2024/otel-operator-q-and-a/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index a4a2d0e7d032..335cadb5e329 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -27,6 +27,8 @@ easier. It does the following: [OpAMP](/docs/specs/opamp/) integration, supported by the [`OpAMPBridge`](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opampbridge) custom resource. +- Provides + [integration with the Prometheus Operator's `PodMonitor` and `ServiceMonintor` CRs](https://github.com/open-telemetry/opentelemetry-operator/tree/main/cmd/otel-allocator). - Injects and configures [auto-instrumentation](https://www.honeycomb.io/blog/what-is-auto-instrumentation) into your pods, supported by the From dbd280e86435f085d04f74e98b78ddb827f5d6bd Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Thu, 25 Apr 2024 14:10:55 -0400 Subject: [PATCH 14/30] Fix typo --- content/en/blog/2024/otel-operator-q-and-a/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 335cadb5e329..ae55dffdc356 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -28,7 +28,7 @@ easier. It does the following: [`OpAMPBridge`](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opampbridge) custom resource. - Provides - [integration with the Prometheus Operator's `PodMonitor` and `ServiceMonintor` CRs](https://github.com/open-telemetry/opentelemetry-operator/tree/main/cmd/otel-allocator). + [integration with the Prometheus Operator's `PodMonitor` and `ServiceMonitor` CRs](https://github.com/open-telemetry/opentelemetry-operator/tree/main/cmd/otel-allocator). - Injects and configures [auto-instrumentation](https://www.honeycomb.io/blog/what-is-auto-instrumentation) into your pods, supported by the From 1c07a7fd2e031fd72531c0e0554907629f786739 Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Thu, 25 Apr 2024 14:15:13 -0400 Subject: [PATCH 15/30] Update section on collector distros --- content/en/blog/2024/otel-operator-q-and-a/index.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index ae55dffdc356..f3e3f8da8d25 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -149,13 +149,9 @@ developers to develop and test. It contains a base set of components–i.e. [processors](/docs/collector/configuration/#processors), and [exporters](/docs/collector/configuration/#exporters). -If you want access to more components than the ones offered by core, you can use -the contrib distribution instead. The contrib distribution extends the core -distribution, and includes components created by third-parties (including -vendors and individual community members), that are useful to the OpenTelemetry -community at large. +If you want access to more components than the ones offered by core, you can use the Collector's [Kubernetes Distribution](https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-k8s) instead. This distribution is made specifically to be used in a Kubernetes cluster to monitor Kubernetes and services running in Kubernetes. It contains a subset of components from [OpenTelemetry Collector Core](https://github.com/open-telemetry/opentelemetry-collector) and [OpenTelemetry Collector Contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib). -Or better yet, if you want to use specific Collector components, you can build +If you want to use your own specific Collector components, you can build your own distribution using the [OpenTelemetry Collector Builder](/docs/collector/custom-collector/) (OCB), and include only the components that you need. From d4d91e6174d7eb558b6c799f12546dc01f585062 Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Thu, 25 Apr 2024 14:20:18 -0400 Subject: [PATCH 16/30] Prettify --- .../en/blog/2024/otel-operator-q-and-a/index.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index f3e3f8da8d25..dca481267b83 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -149,10 +149,18 @@ developers to develop and test. It contains a base set of components–i.e. [processors](/docs/collector/configuration/#processors), and [exporters](/docs/collector/configuration/#exporters). -If you want access to more components than the ones offered by core, you can use the Collector's [Kubernetes Distribution](https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-k8s) instead. This distribution is made specifically to be used in a Kubernetes cluster to monitor Kubernetes and services running in Kubernetes. It contains a subset of components from [OpenTelemetry Collector Core](https://github.com/open-telemetry/opentelemetry-collector) and [OpenTelemetry Collector Contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib). +If you want access to more components than the ones offered by core, you can use +the Collector's +[Kubernetes Distribution](https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-k8s) +instead. This distribution is made specifically to be used in a Kubernetes +cluster to monitor Kubernetes and services running in Kubernetes. It contains a +subset of components from +[OpenTelemetry Collector Core](https://github.com/open-telemetry/opentelemetry-collector) +and +[OpenTelemetry Collector Contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib). -If you want to use your own specific Collector components, you can build -your own distribution using the +If you want to use your own specific Collector components, you can build your +own distribution using the [OpenTelemetry Collector Builder](/docs/collector/custom-collector/) (OCB), and include only the components that you need. From 9316d9e517f883a85f0729400833f30eb4da2fcc Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Fri, 26 Apr 2024 18:19:53 -0400 Subject: [PATCH 17/30] Fix quesiton numbering --- .../en/blog/2024/otel-operator-q-and-a/index.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index dca481267b83..dc42fd006358 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -202,7 +202,7 @@ to authenticate against that private registry. For more info on how to use For more info, check out the [OpenTelemetryCollector CR API docs](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opentelemetrycollector). -### Q4: Does the Target Allocator work for all deployment types? +### Q5: Does the Target Allocator work for all deployment types? No. The Target Allocator only works for [StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/), @@ -212,7 +212,7 @@ and More info [here](https://github.com/open-telemetry/opentelemetry-operator/blob/aed905c2c3c0aa3fb608a79c2e4d0e7b73dff980/apis/v1beta1/collector_webhook.go#L328). -### Q5: If I’m using Operator’s Target Allocator for Prometheus service discovery, do I need `PodMonitor` and `ServiceMonitor` CRs installed in my Kubernetes cluster? +### Q6: If I’m using Operator’s Target Allocator for Prometheus service discovery, do I need `PodMonitor` and `ServiceMonitor` CRs installed in my Kubernetes cluster? Yes, you do. These CRs are bundled with the [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator); @@ -241,7 +241,7 @@ Check out my example of the OpenTelemetry Operator’s Target Allocator with `ServiceMonitor` [here](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). -### Q6: Do I need to create a service account to use the Target Allocator? +### Q7: Do I need to create a service account to use the Target Allocator? No, but you do need to do a bit of extra work. So, here’s the deal…although you need a @@ -267,7 +267,7 @@ See the [Target Allocator readme](https://github.com/open-telemetry/opentelemetry-operator/tree/main/cmd/otel-allocator#rbac) for more on Target Allocator RBAC configuration. -### Q7: Can I override the Target Allocator base image? +### Q8: Can I override the Target Allocator base image? Just like you can override the Collector base image in the `OpenTelemetryCollector` CR, you can also override the Target Allocator base @@ -303,7 +303,7 @@ Where: - `` is the number of pod instances for the underlying Target Allocator -### Q8: If it’s not recommended that you override the Target Allocator base image, then why would you want to? +### Q9: If it’s not recommended that you override the Target Allocator base image, then why would you want to? One use case might be [if you need to host a mirror of the Target Allocator image in your own private container registry for security purposes](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579). @@ -315,12 +315,12 @@ Operator, check out the instructions Note that you don’t need to create a `serviceAccount` for the Target Allocator, since once is already created for you automagically if you don’t create one yourself (see -[Q6](#q6-do-i-need-to-create-a-service-account-to-use-the-target-allocator)). +[Q7](#q7-do-i-need-to-create-a-service-account-to-use-the-target-allocator)). For more info, check out the [Target Allocator API docs](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opentelemetrycollectorspectargetallocator). -### Q9: Is there a version lag between the OTel Operator auto-instrumentation and auto-instrumentation of supported languages? +### Q10: Is there a version lag between the OTel Operator auto-instrumentation and auto-instrumentation of supported languages? If there is a lag, it's minimal, as maintainers try to keep these up to date for each release cycle. Keep in mind that there are breaking changes in some From e07f53927e948bfb9fe80889899093fa0debd82d Mon Sep 17 00:00:00 2001 From: Adriana Villela <50256412+avillela@users.noreply.github.com> Date: Mon, 6 May 2024 11:39:36 -0400 Subject: [PATCH 18/30] Update content/en/blog/2024/otel-operator-q-and-a/index.md Co-authored-by: Patrice Chalin --- content/en/blog/2024/otel-operator-q-and-a/index.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index dc42fd006358..623928e07ac3 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -237,9 +237,8 @@ kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheu kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.2/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml ``` -Check out my example of the OpenTelemetry Operator’s Target Allocator with -`ServiceMonitor` -[here](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). +See my [example of the OpenTelemetry Operator’s Target Allocator with +`ServiceMonitor`](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). ### Q7: Do I need to create a service account to use the Target Allocator? From 6743b582bea6d4eca2a8bd9be896f5722a3e9a3a Mon Sep 17 00:00:00 2001 From: Adriana Villela <50256412+avillela@users.noreply.github.com> Date: Mon, 6 May 2024 11:40:30 -0400 Subject: [PATCH 19/30] Update content/en/blog/2024/otel-operator-q-and-a/index.md Co-authored-by: Patrice Chalin --- content/en/blog/2024/otel-operator-q-and-a/index.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 623928e07ac3..ff92d82ee0d0 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -308,9 +308,7 @@ One use case might be [if you need to host a mirror of the Target Allocator image in your own private container registry for security purposes](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579). If you do need to reference a Target Allocator image from a private registry, -you’ll need to use `imagePullSecrets`. To use `imagePullSecrets` with the OTel -Operator, check out the instructions -[here](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#using-imagepullsecrets). +you’ll need to use `imagePullSecrets`. For details, see [the instructions](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#using-imagepullsecrets). Note that you don’t need to create a `serviceAccount` for the Target Allocator, since once is already created for you automagically if you don’t create one yourself (see From f6bd948234438e5c0b7074030e43ea7fbd5a54d0 Mon Sep 17 00:00:00 2001 From: Adriana Villela <50256412+avillela@users.noreply.github.com> Date: Mon, 6 May 2024 11:40:43 -0400 Subject: [PATCH 20/30] Update content/en/blog/2024/otel-operator-q-and-a/index.md Co-authored-by: Patrice Chalin --- content/en/blog/2024/otel-operator-q-and-a/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index ff92d82ee0d0..378eaf5f837c 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -209,8 +209,8 @@ No. The Target Allocator only works for and [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) ([newly-introduced](https://github.com/open-telemetry/opentelemetry-operator/pull/2430#discussion_r1420495631)). -More info -[here](https://github.com/open-telemetry/opentelemetry-operator/blob/aed905c2c3c0aa3fb608a79c2e4d0e7b73dff980/apis/v1beta1/collector_webhook.go#L328). +For more info, see +[`collector_webhook.go`](https://github.com/open-telemetry/opentelemetry-operator/blob/aed905c2c3c0aa3fb608a79c2e4d0e7b73dff980/apis/v1beta1/collector_webhook.go#L328). ### Q6: If I’m using Operator’s Target Allocator for Prometheus service discovery, do I need `PodMonitor` and `ServiceMonitor` CRs installed in my Kubernetes cluster? From 356140f5977cf15ae3cb520e0a4d5e45aa9a2b47 Mon Sep 17 00:00:00 2001 From: Adriana Villela <50256412+avillela@users.noreply.github.com> Date: Mon, 6 May 2024 11:41:01 -0400 Subject: [PATCH 21/30] Update content/en/blog/2024/otel-operator-q-and-a/index.md Co-authored-by: Patrice Chalin --- content/en/blog/2024/otel-operator-q-and-a/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 378eaf5f837c..31448da382ca 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -196,8 +196,7 @@ registry, you'll need to use [`imagePullSecrets`](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). Since private container registries require authentication, this will enable you to authenticate against that private registry. For more info on how to use -`imagePullSecrets` for your Collector image, check out the instructions -[here](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#using-imagepullsecrets). +`imagePullSecrets` for your Collector image, see [the instructions](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#using-imagepullsecrets). For more info, check out the [OpenTelemetryCollector CR API docs](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opentelemetrycollector). From ff76b4a3798a1dc193af3e8fb6cbb2a261287a85 Mon Sep 17 00:00:00 2001 From: Adriana Villela <50256412+avillela@users.noreply.github.com> Date: Mon, 6 May 2024 11:41:14 -0400 Subject: [PATCH 22/30] Update content/en/blog/2024/otel-operator-q-and-a/index.md Co-authored-by: Patrice Chalin --- content/en/blog/2024/otel-operator-q-and-a/index.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 31448da382ca..9f8426238398 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -320,9 +320,8 @@ For more info, check out the If there is a lag, it's minimal, as maintainers try to keep these up to date for each release cycle. Keep in mind that there are breaking changes in some -semantic conventions and the team is trying to avoid breaking users' code. More -info -[here](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579). +semantic conventions and the team is trying to avoid breaking users' code. For details, see this +[`#otel-operator` thread](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579). ## Final thoughts From 43d8d5e0e057e3569f98727593056a62f2f5f41e Mon Sep 17 00:00:00 2001 From: Adriana Villela <50256412+avillela@users.noreply.github.com> Date: Mon, 6 May 2024 11:44:39 -0400 Subject: [PATCH 23/30] Update content/en/blog/2024/otel-operator-q-and-a/index.md Co-authored-by: Patrice Chalin --- content/en/blog/2024/otel-operator-q-and-a/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 9f8426238398..048e4d6b1da3 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -119,8 +119,7 @@ exporters: '': '${TOKEN_VALUE}' ``` -For more info, check out my full example -[here](https://github.com/avillela/otel-target-allocator-talk/blob/main/src/resources/02-otel-collector-ls.yml), +For more info, see the [full example](https://github.com/avillela/otel-target-allocator-talk/blob/main/src/resources/02-otel-collector-ls.yml), along with full instructions [here](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). From 29c2c85849fe7d4f574dd13c4c0f9f825af25897 Mon Sep 17 00:00:00 2001 From: Adriana Villela <50256412+avillela@users.noreply.github.com> Date: Mon, 6 May 2024 11:44:56 -0400 Subject: [PATCH 24/30] Update content/en/blog/2024/otel-operator-q-and-a/index.md Co-authored-by: Patrice Chalin --- content/en/blog/2024/otel-operator-q-and-a/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 048e4d6b1da3..192990d3415e 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -120,8 +120,7 @@ exporters: ``` For more info, see the [full example](https://github.com/avillela/otel-target-allocator-talk/blob/main/src/resources/02-otel-collector-ls.yml), -along with full instructions -[here](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). +along with the [instructions](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). ### Q3: Is the Operator version at parity with the Collector version? From c352767de1eb0818e7e5907c02df2cc05a41fde8 Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Mon, 6 May 2024 16:32:37 -0400 Subject: [PATCH 25/30] Update per feedback from @swiatekm-sumo --- .../blog/2024/otel-operator-q-and-a/index.md | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 192990d3415e..f034ab0a8899 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -69,6 +69,10 @@ you could technically [pass it multiple Collector config files using multiple --values flags](https://stackoverflow.com/a/56653384) and let [Helm](https://helm.sh) do the merging for you. +> **NOTE:** There are plans to offer higher-level constructs for sepcifying +> configurations in the future, as per +> [this PR](https://github.com/open-telemetry/opentelemetry-operator/issues/1906). + For reference, [check out this thread in the #otel-operator CNCF Slack channel](https://cloud-native.slack.com/archives/C033BJ8BASU/p1709321896612279). @@ -119,8 +123,10 @@ exporters: '': '${TOKEN_VALUE}' ``` -For more info, see the [full example](https://github.com/avillela/otel-target-allocator-talk/blob/main/src/resources/02-otel-collector-ls.yml), -along with the [instructions](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). +For more info, see the +[full example](https://github.com/avillela/otel-target-allocator-talk/blob/main/src/resources/02-otel-collector-ls.yml), +along with the +[instructions](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). ### Q3: Is the Operator version at parity with the Collector version? @@ -194,7 +200,8 @@ registry, you'll need to use [`imagePullSecrets`](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). Since private container registries require authentication, this will enable you to authenticate against that private registry. For more info on how to use -`imagePullSecrets` for your Collector image, see [the instructions](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#using-imagepullsecrets). +`imagePullSecrets` for your Collector image, see +[the instructions](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#using-imagepullsecrets). For more info, check out the [OpenTelemetryCollector CR API docs](https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#opentelemetrycollector). @@ -206,10 +213,10 @@ No. The Target Allocator only works for and [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) ([newly-introduced](https://github.com/open-telemetry/opentelemetry-operator/pull/2430#discussion_r1420495631)). -For more info, see +For more info, see [`collector_webhook.go`](https://github.com/open-telemetry/opentelemetry-operator/blob/aed905c2c3c0aa3fb608a79c2e4d0e7b73dff980/apis/v1beta1/collector_webhook.go#L328). -### Q6: If I’m using Operator’s Target Allocator for Prometheus service discovery, do I need `PodMonitor` and `ServiceMonitor` CRs installed in my Kubernetes cluster? +### Q6: If I enable `prometheusCR` in the Target Allocator, do I need the `PodMonitor` and `ServiceMonitor` CRs installed in my Kubernetes cluster? Yes, you do. These CRs are bundled with the [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator); @@ -229,13 +236,13 @@ and like this: ```shell -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.2/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl --context kind-otel-target-allocator-talk apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/main/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.2/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl --context kind-otel-target-allocator-talk apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/main/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml ``` -See my [example of the OpenTelemetry Operator’s Target Allocator with -`ServiceMonitor`](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). +See my +[example of the OpenTelemetry Operator’s Target Allocator with `ServiceMonitor`](https://github.com/avillela/otel-target-allocator-talk/tree/main?tab=readme-ov-file#3b--kubernetes-deployment-servicenow-cloud-observability-backend). ### Q7: Do I need to create a service account to use the Target Allocator? @@ -263,6 +270,8 @@ See the [Target Allocator readme](https://github.com/open-telemetry/opentelemetry-operator/tree/main/cmd/otel-allocator#rbac) for more on Target Allocator RBAC configuration. +> **NOTE:** There are plans to automate this fully in the near future. + ### Q8: Can I override the Target Allocator base image? Just like you can override the Collector base image in the @@ -305,7 +314,8 @@ One use case might be [if you need to host a mirror of the Target Allocator image in your own private container registry for security purposes](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579). If you do need to reference a Target Allocator image from a private registry, -you’ll need to use `imagePullSecrets`. For details, see [the instructions](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#using-imagepullsecrets). +you’ll need to use `imagePullSecrets`. For details, see +[the instructions](https://github.com/open-telemetry/opentelemetry-operator?tab=readme-ov-file#using-imagepullsecrets). Note that you don’t need to create a `serviceAccount` for the Target Allocator, since once is already created for you automagically if you don’t create one yourself (see @@ -318,7 +328,8 @@ For more info, check out the If there is a lag, it's minimal, as maintainers try to keep these up to date for each release cycle. Keep in mind that there are breaking changes in some -semantic conventions and the team is trying to avoid breaking users' code. For details, see this +semantic conventions and the team is trying to avoid breaking users' code. For +details, see this [`#otel-operator` thread](https://cloud-native.slack.com/archives/C033BJ8BASU/p1713894678225579). ## Final thoughts From 554aab0b0178d441d61e2effa939e4014f58e5f9 Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Thu, 9 May 2024 12:05:23 -0400 Subject: [PATCH 26/30] Update per feedback from @swiatekm-sumo + update blog post title --- content/en/blog/2024/otel-operator-q-and-a/index.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index f034ab0a8899..431eb420a676 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -1,5 +1,7 @@ --- -title: OTel Operator Q&A +title: + Things You Might Not Have Known About the OpenTelemetry Operator - An OTel + Operator Q&A linkTitle: OTel Operator Q&A date: 2024-04-24 author: >- @@ -270,7 +272,9 @@ See the [Target Allocator readme](https://github.com/open-telemetry/opentelemetry-operator/tree/main/cmd/otel-allocator#rbac) for more on Target Allocator RBAC configuration. -> **NOTE:** There are plans to automate this fully in the near future. +> **NOTE:** This will be automated fully in the near future (see accompanying +> [PR](https://github.com/open-telemetry/opentelemetry-operator/pull/2787)), and +> will be released as part of version `0.100.0`. ### Q8: Can I override the Target Allocator base image? From 214da5669ea488f42304cd752e7d7ef6725eb783 Mon Sep 17 00:00:00 2001 From: Adriana Villela Date: Thu, 9 May 2024 12:13:59 -0400 Subject: [PATCH 27/30] minor updates and prettify --- content/en/blog/2024/otel-operator-q-and-a/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 431eb420a676..53954e1fd642 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -273,8 +273,8 @@ See the for more on Target Allocator RBAC configuration. > **NOTE:** This will be automated fully in the near future (see accompanying -> [PR](https://github.com/open-telemetry/opentelemetry-operator/pull/2787)), and -> will be released as part of version `0.100.0`. +> [PR](https://github.com/open-telemetry/opentelemetry-operator/pull/2787)), as +> part of version `0.100.0`. ### Q8: Can I override the Target Allocator base image? From 72a7ae3ce07152001b93fa5a0f21f6b916ae3682 Mon Sep 17 00:00:00 2001 From: Severin Neumann Date: Mon, 13 May 2024 09:17:16 +0200 Subject: [PATCH 28/30] Update content/en/blog/2024/otel-operator-q-and-a/index.md --- content/en/blog/2024/otel-operator-q-and-a/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 53954e1fd642..1052207f1b5f 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -3,7 +3,7 @@ title: Things You Might Not Have Known About the OpenTelemetry Operator - An OTel Operator Q&A linkTitle: OTel Operator Q&A -date: 2024-04-24 +date: 2024-05-13 author: >- [Adriana Villela](https://github.com/avillela) (ServiceNow), From 1866a4842d0861fced2724668696ecae0b08809e Mon Sep 17 00:00:00 2001 From: Severin Neumann Date: Mon, 13 May 2024 09:19:37 +0200 Subject: [PATCH 29/30] Update content/en/blog/2024/otel-operator-q-and-a/index.md --- content/en/blog/2024/otel-operator-q-and-a/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/blog/2024/otel-operator-q-and-a/index.md b/content/en/blog/2024/otel-operator-q-and-a/index.md index 1052207f1b5f..209b21a4d6fc 100644 --- a/content/en/blog/2024/otel-operator-q-and-a/index.md +++ b/content/en/blog/2024/otel-operator-q-and-a/index.md @@ -71,7 +71,7 @@ you could technically [pass it multiple Collector config files using multiple --values flags](https://stackoverflow.com/a/56653384) and let [Helm](https://helm.sh) do the merging for you. -> **NOTE:** There are plans to offer higher-level constructs for sepcifying +> **NOTE:** There are plans to offer higher-level constructs for specifying > configurations in the future, as per > [this PR](https://github.com/open-telemetry/opentelemetry-operator/issues/1906). From e2ab3cd1e18b2ed053213c0694f9490aea3c7105 Mon Sep 17 00:00:00 2001 From: opentelemetrybot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 13 May 2024 07:25:21 +0000 Subject: [PATCH 30/30] Results from /fix:refcache --- static/refcache.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/static/refcache.json b/static/refcache.json index c645de11216f..66727ad99250 100644 --- a/static/refcache.json +++ b/static/refcache.json @@ -3775,6 +3775,10 @@ "StatusCode": 200, "LastSeen": "2024-01-18T19:37:11.461365-05:00" }, + "https://github.com/open-telemetry/opentelemetry-operator/issues/1906": { + "StatusCode": 200, + "LastSeen": "2024-05-13T07:25:18.846726619Z" + }, "https://github.com/open-telemetry/opentelemetry-operator/issues/902": { "StatusCode": 200, "LastSeen": "2024-01-18T20:05:35.482435-05:00" @@ -3783,6 +3787,10 @@ "StatusCode": 200, "LastSeen": "2024-04-25T00:01:09.014347-04:00" }, + "https://github.com/open-telemetry/opentelemetry-operator/pull/2787": { + "StatusCode": 200, + "LastSeen": "2024-05-13T07:25:20.170057644Z" + }, "https://github.com/open-telemetry/opentelemetry-operator/pull/832": { "StatusCode": 200, "LastSeen": "2024-01-18T20:05:30.899318-05:00"