From 63a9488c8c29fd2a9893b996a20d9d2c2102cb59 Mon Sep 17 00:00:00 2001 From: Evan Bradley Date: Thu, 13 Apr 2023 13:55:25 -0400 Subject: [PATCH] Add specification document converted from Markdown --- cmd/opampsupervisor/README.md | 4 +- cmd/opampsupervisor/specification/README.md | 468 ++++++++++++++++++ .../specification/extension-diagram.png | Bin 0 -> 12635 bytes .../specification/supervisor-diagram.png | Bin 0 -> 29815 bytes 4 files changed, 470 insertions(+), 2 deletions(-) create mode 100644 cmd/opampsupervisor/specification/README.md create mode 100644 cmd/opampsupervisor/specification/extension-diagram.png create mode 100644 cmd/opampsupervisor/specification/supervisor-diagram.png diff --git a/cmd/opampsupervisor/README.md b/cmd/opampsupervisor/README.md index 2c8bdbafaece..3601a0732bcd 100644 --- a/cmd/opampsupervisor/README.md +++ b/cmd/opampsupervisor/README.md @@ -1,7 +1,7 @@ # OpAMP Supervisor for the OpenTelemetry Collector This is an implementation of an OpAMP Supervisor that runs a Collector instance using configuration provided from an OpAMP server. This implementation -is following a design specified in this [Google Doc](https://docs.google.com/document/d/1KtH5atZQUs9Achbce6LiOaJxLbksNJenvgvyKLsJrkc/edit). +is following a design specified [here](./specification/README.md). The design is still undergoing changes, and as such this implementation may change as well. ## Experimenting with the supervisor @@ -21,4 +21,4 @@ The supervisor is currently undergoing heavy development and is not ready for an go run . --config testdata/supervisor_.yaml ``` -4. The supervisor should connect to the OpAMP server and start a Collector instance. \ No newline at end of file +4. The supervisor should connect to the OpAMP server and start a Collector instance. diff --git a/cmd/opampsupervisor/specification/README.md b/cmd/opampsupervisor/specification/README.md new file mode 100644 index 000000000000..0d1b766f8976 --- /dev/null +++ b/cmd/opampsupervisor/specification/README.md @@ -0,0 +1,468 @@ +# OpAMP for OpenTelemetry Collector + +Author: Tigran Najaryan + +## Introduction + +[OpAMP](https://github.com/open-telemetry/opamp-spec) has been one of +the most requested capabilities at Kubecon 2022. We can implement OpAMP +for the Collector in 2 different ways: + +- As a Collector extension, with limited functionality, +- As an external Supervisor, that implements all or most of OpAMP + capabilities. + +In discussions with users and Collector contributors we found that both +of these approaches are wanted. This document describes how to implement +both while minimizing duplicate work. + +The main idea is to implement a Collector extension with a limited set +of OpAMP capabilities, where the extension can be used on its own, then +additionally create an external Supervisor that uses the exact same +extension as a helper and implements the remaining OpAMP capabilities on +top of what the extension implements. This way most of OpAMP-related +functionality is implemented once only, there is virtually no code +duplication. + +## Supervised Operation + +This section describes a specialized Supervisor made for OpenTelemetry +Collector. The Supervisor will have the benefit of knowing for example +how to inject desirable values into the Collector's configuration file. + +Here is how a Supervisor-based management works: + +![Supervisor architecture diagram](supervisor-diagram.png) + +The Supervisor process does the following: + +- Implements the client-side of OpAMP protocol and communicates with + the OpAMP Backend. +- Starts/stops the Collector process as necessary. +- Receives configuration from the OpAMP Backend and pushes it to the + Collector, using the Collector config.yaml file as an intermediary, + restarting the Collector process as necessary. +- Serves as a watchdog, restarts the Collector process if the + Collector crashes. +- Accepts an OpAMP connection from Collectors' [*opamp + extension*](#collectors-opamp-extension), receives the Collector's + AgentDescription, HealthStatus and EffectiveConfig messages and + forwards them to the OpAMP Backend. +- Optionally: downloads Collector executable packages offered by the + Backend and performs the Collector updates. +- Optionally: configures Collector to collect Collector's own metrics + and report the metrics to the OTLP telemetry backend requested by + OpAMP Backend. +- Optionally: collects Collector logs and sends them to the Telemetry + Backend via OTLP. + +Supervisor is implemented as a Go library that may be customized and +rebuilt by vendors with useful default configurations, such as the OpAMP +Backend endpoint to connect to, in order to minimize the manual +configuration required. + +*Important: the Supervisor needs to be highly stable, so we need to keep +its complexity and functionality to minimum. The features listed in this +section need a critical review and may be removed (responsibility moved +elsewhere, e.g. to the Collector itself).* + +### Supervisor Configuration + +The Supervisor is configured via a yaml config file: + +```yaml +# OpAMP backend server settings. +server: + # endpoint is a URL and is mandatory. + # ws,wss,http,https schemes are supported. + # Other connection settings, e.g. TLS cert, etc. + endpoint: wss://example.com/opamp + +# Keys with boolean true/false values that enable a particular +# OpAMP capability. +# The Supervisor will accept remote configuration from the Server. +# If enabled the Supervisor will also report RemoteConfig status +# to the Server. +capabilities: + AcceptsRemoteConfig: # false if unspecified + + # The Supervisor will report EffectiveConfig to the Server. + ReportsEffectiveConfig: # true if unspecified + + # The Supervisor can accept Collector executable package updates. + # If enabled the Supervisor will also report package status to the + # Server. + AcceptsPackages: # false if unspecified + + # The Collector will report own metrics to the destination specified by + # the Server. + ReportsOwnMetrics: # true if unspecified + + # The Collector will report own logs to the destination specified by + # the Server. + ReportsOwnLogs: # true if unspecified + + # The Collector will accept connections settings for exporters + # from the Server. + AcceptsOtherConnectionSettings: # false if unspecified + + # The Supervisor will accept restart requests. + AcceptsRestartCommand: # true if unspecified + + # The Collector will report Health. + ReportsHealth: # true if unspecified + +storage: + # A writable directory where the Supervisor can store data + # (e.g. cached remote config). + # defaults to /var/lib/otelcol/supervisor on posix systems + # and %ProgramData%/Otelcol/Supervisor on Windows. + directory: /path/to/dir + +collector: + # Path to Collector executable. Required. + executable: /opt/otelcol/bin/otelcol + + # extra command line flags to pass to the Collector executable. + args: + + # extra environment variables to set when executing the Collector + # Optional user name to drop the privileges to when running the + # Collector process. + env: + run_as: myuser + # Path to optional local Collector config file to be merged with the + # config provided by the OpAMP server. + config_file: /etc/otelcol/config.yaml + # Optional directories that are allowed to be read/written by the + # Collector. + # If unspecified then NO access to the filesystem is allowed. + access_dirs: + read: + allow: \[/var/log\] + deny: \[/var/log/secret_logs\] + write: + allow: \[/var/otelcol\] +``` + +### Executing Collector + +The Supervisor starts and stops the Collector process as necessary. When +run_as setting is provided, the Supervisor will execute the Collector +process as the specified user. This is highly recommended in situations +when the Supervisor itself is running as root and it is desirable to +drop the root privileges and run the Collector as a more restricted +user. + +#### Stopping Collector + +To stop the Collector the Supervisor will issue a SIGTERM signal first, +wait for the process to exit, then force exit via SIGKILL if necessary. + +### Collector Config + +The Supervisor creates a Collector config file in a temp directory and +passes to the Collector via --config command line option. The config +file is created by merging the local config file (optional) and the +remote config received from OpAMP backend (also optional). The +configuration file merging rules match the merging rules that are +already in place in the Collector codebase (key-by-key, recursively). + +#### Remote Configuration + +Note: this capability must be manually enabled by the user via a +AcceptsRemoteConfig setting in the supervisor config file and is +disabled by default. + +The Supervisor receives [*Remote +Configuration*](https://github.com/open-telemetry/opamp-spec/blob/main/specification.md#configuration) +from the OpAMP Backend, merges it with an optional local config file and +writes it to the Collector's config file, then restarts the Collector. + +In the future once config file watching is implemented the Collector can +reload the config without the need for the Supervisor to restart the +Collector process. + +The Supervisor will report to the OpAMP Backend the status of all these +operations via RemoteConfigStatus message. + +#### Sanitizing Configuration + +The Supervisor will sanitize the configuration of the components that +access the local filesystem according to the access_dirs config setting +to only allow specified directories and their subdirectories. This +applies for example to \`include\` setting of the \`filelog\` receiver +or to \`directory\` setting of the \`file_storage\` extension. + +The Supervisor will locate all such entries while building the Collector +config file and will delete the ones which are prohibited by the access +control settings. + +*Open Question: if after sanitizing the component's directory setting +the configuration becomes invalid what do we do?* + +*The sanitizing logic is hard-coded in the Supervisor and works for +specific components only. In the future we will consider implementing a +more generic safety mechanism that does not depend on the knowledge +about specific component behavior.* + +#### Bootstrapping + +In order to obtain the remote configuration from the OpAMP Backend the +Supervisor must send an AgentDescription to the Backend. Initially the +Supervisor doesn't have this information. The AgentDescription becomes +available only after the Collector process is started and the +AgentDescription is sent from the opamp extension to the Supervisor. +However, it is impossible to start the Collector without a +configuration. + +To overcome this problem the Supervisor starts the Collector with an +"noop" configuration that collects nothing but allows the opamp +extension to be started. The "noop" configuration is a single pipeline +with a filelog receiver that points to a non-existing file and a logging +exporter and the opamp extension. The purpose of the "noop" +configuration is to make sure the Collector starts and the opamp +extension communicates with the Supervisor. + +Once the initial Collector launch is successful and the remote +configuration is received by the Supervisor the Supervisor restarts the +Collector with the new config. The new config is also cached by the +Supervisor in a local file, so that subsequent restarts no longer need +to start the Collector using the "noop" configuration. Caching of the +last config also allows the Supervisor to subsequently start the +Collector without waiting for the OpAMP Backend to provide the remote +config and mitigates OpAMP Backend unavailability. + +#### Reverting + +One of the challenges when the Supervisor updates the configuration is +knowing whether the configuration is successfully applied or not. There +may not exist a definite signal that indicates that all of the +configuration is good and applied by the Collector. One possible +approach is to set a certain period after which the Collector is +expected to be up and running in "healthy" status and if that does not +happen (i.e. the Collector crashes or "healthy" status is not seen) then +the configuration is reverted to the last one. + +The reverting likely needs to be an optional feature that the user can +enable. TODO: add a Supervisor config setting for this option. + +### Watchdog + +The Supervisor will monitor the Collector process it started. If the +Collector process terminates unexpectedly the Supervisor will restart +the Collector (with a backoff). The Supervisor can also report restart +or crash-related metrics along with other telemetry it reports for the +Collector. + +### Collector Instance UID + +The Supervisor maintains a Collector instance_uid (a +[ULID](https://github.com/open-telemetry/opamp-spec/blob/main/specification.md#agenttoserverinstance_uid)). +The instance_uid is generated by the Supervisor on the first run or +during the Supervisor installation and remains unchanged thereafter. The +instance_uid will be used in OpAMP communication. + +The value is injected into the Collector config in [opamp +extension's](#collectors-opamp-extension) instance_uid setting and as +service.instance.id attribute under the service.telemetry.resource +setting. + +Note: if [Make generated service.instance.id available to +extensions](https://github.com/open-telemetry/opentelemetry-collector/issues/6599) +is implemented then the instance_uid setting in the opamp extension is +no longer necessary. + +### Collector's Own Telemetry + +#### Own Metrics + +Supervisor will configure Collector to report its own metrics to the +OTLP destination requested by the OpAMP Backend. See how it is done in +[this example +here](https://github.com/open-telemetry/opamp-go/blob/efddaa260895e7ebb2431deeefef3a3380d8d902/internal/examples/supervisor/supervisor/supervisor.go#L277). + +Eventually, when the Collector's internal metrics are migrated to Otel +SDK we should be able to configure the SDK to send to this destination +without configuring a Collector pipeline. + +#### Own Logs + +The Supervisor will collect Collector's logs (the stdout and stderr) and +send them to the log collection endpoint offered by the OpAMP Backend. + +The Supervisor will configure the Collector output logs in json format +(e.g. [like +this](https://github.com/open-telemetry/opamp-go/blob/efddaa260895e7ebb2431deeefef3a3380d8d902/internal/examples/supervisor/supervisor/supervisor.go#LL220C21-L220C21)) +and will parse them, then send to the OTLP destination requested by the +OpAMP Backend. The Supervisor will enrich the logs using the attributes +it received previously in AgentDescription message from the [opamp +extension](#collectors-opamp-extension). + +Note that for logs we are not using the same approach as we do for +Collector's own metrics. The reason is that collecting logs may produce +logs and that may result in catastrophic amplification of generated +logs. To safeguard from that we collect logs using the Supervisor. + +The additional benefit of using Supervisor for log collection is that if +the Collector crashes the Supervisor will still be able to collect all +log output up until the process termination, which can be crucial for +understanding the cause of crash (using Collector to collect its logs +won't guarantee this). + +The Supervisor will also write the Collector's log to a local log file. +The path to the Collector log files will be printed in the Supervisor +output. + +*Open Question: instead of writing to a local log file do we want to +pipe Collector logs to Supervisor's log output?* + +### Collector Executable Updates + +Note: this capability must be manually enabled by the user via the +AcceptsPackages setting in the supervisor config file and is disabled by +default. + +This capability should be only implemented after we introduce the code +signing process for the Collector and all released Collector executables +are signed, the Supervisor is capable of verifying the signature of +executables and other OpAMP security recommendations are followed. + +The Supervisor will download Collector package updates when offered so +by the Backend. The Supervisor will verify the integrity of the packages +and will install them. This requires stopping the Collector, overwriting +the Collector executable file with the newly downloaded version and +starting the Collector. Before overwriting the executable the Supervisor +will save it in case it is necessary for reverting. + +If after the restart the Collector does not become healthy the +Supervisor will revert the update, by stopping the Collector, reverting +the Collector executable file and starting the Collector again. The +failed update attempt will be reported to the Backend and the failed +Collector package version will be marked as "bad" to avoid trying it +again even if offered by the Backend. + +Note: cached local config must be invalidated after executable updates +to make sure a fresh AgentDescription is obtained by the Supervisor on +the next Collector start (at the minimum the version number to be +included in AgentDescription is expected to change after the executable +is updated). + +### Addons Management + +The Collector currently does not have a concept of addons so this OpAMP +capability is not implemented by the Supervisor. + +### Exporter Connection Settings + +The Supervisor will populate the connection settings for exporters in +the Collector configuration file based on the "other_connections" named +settings it receives from the OpAMP Backend. Each named connection +setting corresponds to the exporter with the same name. The Supervisor +will populate exporter settings from OpAMP ConnectionSettings message +the following way: + +| **ConnectionSettings** | **Exporter setting** | +|---------------------------|----------------------| +| destination_endpoint | endpoint | +| headers | headers | +| certificate.public_key | tls.cert_file | +| certificate.private_key | tls.key_file | +| certificate.ca_public_key | tls.ca_file | + +The received certificate will be written to local files and the paths to +the files containing the keys will be populated in the corresponding +sections under the \`tls\` setting. + +## Collector's opamp Extension + +The Supervisor automatically injects the opamp extension in the +Collector's configuration. The opamp extension implements an OpAMP +client with a small subset of OpAMP agent capabilities: + +- ReportsStatus. The extension reports agent description and status. + This is the first message from the client to the server in the OpAMP + protocol that is essential for beginning OpAMP message exchange. +- ReportsEffectiveConfig. The extension reports the Collector's + effective config on startup and any time the config changes. In + order to do this the opamp extension needs [access to the effective + config](https://github.com/open-telemetry/opentelemetry-collector/issues/6596). +- ReportsHealth. The extension reports Collector's health on startup + and any time the health changes. In order to do this the opamp + extension needs access to the health of the Collector. The very + basic health capability can be replicated by mirroring the + functionality of the healthcheck extension, a more advanced + capability depends on the [component status + reporting](https://github.com/open-telemetry/opentelemetry-collector/pull/6560). + +The messages received from the opamp extension are forwarded by the +Supervisor to the destination OpAMP Backend and replies to these +messages that the Supervisor receives from the OpAMP Backend are +forwarded in the opposite direction to the opamp extension. The +Supervisor also peeks into AgentDescription and keeps it for its own use +as necessary (e.g. to use as [log attributes](#own-logs)). + +The opamp extension in the Collector will accept the following +configuration: + +```yaml +extensions: + opamp: + # OpAMP server URL. Supports WS or plain http transport, + # based on the scheme of the URL (ws,wss,http,https). + # Any other settings defined in HTTPClientSettings, squashed. This + # includes ability to specify an "auth" setting that refers + # to an extension that implements the Authentication interface. + endpoint: + + # ULID formatted as a 26 character string in canonical + # representation. Auto-generated on start if missing. + # Injected by Supervisor. + # Note: can be deprecated after Collector issue #6599 + # is implemented. + instance_uid: +``` + +The extension uses an OpAMP connection to the Supervisor when used with +the Supervisor model. + +The extensions' configuration cannot be overridden by the remote +configuration. + +The same extension can be used to connect directly to the OpAMP Server, +without the Supervisor: + +![OpAMP extension architecture diagram](extension-diagram.png) + +This is the simplified operation model where only status reporting is +required. Only the 3 capabilities that the extension implements work. No +other OpAMP capabilities are available in this operation model. + +When the opamp extension is used without the Supervisor it will need to +know what service.instance.id the Collector's telemetry is using. There +is an [open +issue](https://github.com/open-telemetry/opentelemetry-collector/issues/6599) +to allow this. + +*Open Question: when used with Supervisor do we want the Supervisor to +actively periodically query the health of the Collector or we can rely +on opamp extension to report the health when it changes?* + +## Future Work + +- Decide if we want to have Supervisor-less AcceptsRemoteConfig + capability in the Collector. This currently can't be done by using + just an extension. At the minimum it requires a config Provider. +- Consider extending the Supervisor to be able to manage multiple + Collector instances. + +## References + +- OpAMP Specification: + [https://github.com/open-telemetry/opamp-spec/blob/main/specification.md](https://github.com/open-telemetry/opamp-spec/blob/main/specification.md) +- OpAMP client and server implementation in Go: + [https://github.com/open-telemetry/opamp-go](https://github.com/open-telemetry/opamp-go) +- Example Supervisor implementation: + [https://github.com/open-telemetry/opamp-go/tree/main/internal/examples/supervisor](https://github.com/open-telemetry/opamp-go/tree/main/internal/examples/supervisor) +- OpAMP Milestone in the Collector: + [https://github.com/open-telemetry/opentelemetry-collector/milestone/29](https://github.com/open-telemetry/opentelemetry-collector/milestone/29) diff --git a/cmd/opampsupervisor/specification/extension-diagram.png b/cmd/opampsupervisor/specification/extension-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..9f754812a8a6afd19ba9d979c1f5c49755d1cb85 GIT binary patch literal 12635 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 literal 0 HcmV?d00001 diff --git a/cmd/opampsupervisor/specification/supervisor-diagram.png b/cmd/opampsupervisor/specification/supervisor-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..cb10dd2eb0d8adc460ab71328a5f570491bb24bf GIT binary patch literal 29815 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 literal 0 HcmV?d00001