Vector Operator

repository·main·Indexed 41 days ago

https://github.com/kaasops/vector-operator

A Kubernetes operator that automates the deployment and configuration of Vector agents as a DaemonSet to collect and process container and application logs. It utilizes Custom Resources (CRs) such as Vector and VectorPipeline (API Group: observability.kaasops.io/v1alpha1) to manage data flows, provides support for Vector aggregators with native HPA autoscaling, and includes utilities like checkpoint_merger for log delivery consistency.

Tokens
21.4K
Snippets
45
Records
77
Agent score
51%

What's inside Vector Operator

  1. Overview of Vector Operator

    main

    Vector Operator is a Kubernetes operator that deploys and configures a Vector agent DaemonSet on every node. Its primary purpose is to collect container and application logs from the node's file system.

    Key features include:

    • Building Vector configurations from namespaced custom resources (kind: VectorPipeline).
    • Configuration validation.
    • Full support for Vector configuration options.
    • Namespace isolation.
    • Support for Vector aggregators.
  2. Compare spec.secret and Secure credentials

    main

    When configuring credentials, choose between spec.secret and the Vector CR's secure credentials based on your scoping needs:

    • spec.secret: Use this when each pipeline needs its own unique credentials, scoped to its own namespace, without requiring the owner of the Vector CR to be involved.
    • Secure credentials (env/envFrom): Use these on the Vector CR to inject credentials into every pipeline sharing that CR. These are managed by the owner of the Vector CR.
  3. Understand the Vector Operator CRD architecture

    main

    The Vector Operator manages Vector agent and aggregator installations using several Custom Resource Definitions (CRDs). The architecture is based on a separation of concerns between the installation of the Vector binary (the 'runtime') and the definition of data processing rules (the 'pipelines').

    Core Components

    • Vector: Deploys a Vector agent as a DaemonSet in a specific namespace. It is used for local log/metric collection.
    • VectorAggregator: Deploys a Vector aggregator as a Deployment in a specific namespace. It processes data from VectorPipeline resources in that same namespace.
    • ClusterVectorAggregator: A cluster-scoped version of the aggregator that processes data from ClusterVectorPipeline resources.
    • VectorPipeline: A namespace-scoped resource defining Sources, Transforms, and Sinks. It is automatically routed to either a Vector agent or a VectorAggregator based on its source types.
    • ClusterVectorPipeline: A cluster-scoped resource defining Sources, Transforms, and Sinks. It is automatically routed to either a Vector agent or a ClusterVectorAggregator based on its source types.
  4. Understand secret transition and bridge configs

    main

    Because the config Secret and the assets Secret cannot be updated atomically, the operator uses a staging process to prevent a pod from referencing a key that doesn't exist yet.

    The transition process:

    1. The assets Secret is staged first with the union of keys required by both the outgoing and incoming configurations.
    2. Keys no longer in use are pruned only after a grace period (currently 90 seconds) has passed since the config change.

    Handling overflow during transitions: If the union of keys (the "bridge" state) exceeds the 1 MiB limit, the operator publishes a bridge config containing only what fits alongside existing staged keys. The remaining pipelines will wait with a .status.reason indicating they are waiting for the transition to complete. This ensures no window exists where a config references a missing key, though it may cause a temporary pause in log collection for the waiting pipelines.

  5. Migration limitations and behaviors

    main

    When using --enable-checkpoint-migration, be aware of the following technical behaviors:

    • Per-pipeline opt-out: Toggling the per-(Cluster)VectorPipeline annotation does not trigger migration because it uses a live config reload instead of a pod restart. This results in a one-time re-read of the logs for that specific pipeline's namespace.
    • ignore_older_secs: If this setting is used on an agent source, any carried-over checkpoint older than the window will be dropped, causing the file to be re-read. To ensure migration works as intended, leave ignore_older_secs unset.
    • Per-source data_dir: Migration only covers the operator-managed global data directory (mounted at /vector-data-dir). If you manually configure a data_dir on a specific source (e.g., kubernetes_logs), that source's checkpoints will not be migrated and will be re-read upon a mode switch.
    • Rollback behavior: Rolling back to the legacy config restores per-source positions. However, checkpoint files may grow slightly because the consolidation process seeds target directories with the union of all node checkpoints.
  6. Handle flat-key collisions in pipeline secrets

    main

    The operator sanitizes secret references into a flat key shared by all pipelines on the same Vector/aggregator. Sanitization converts both - and the namespace/name separator into _. This can cause collisions where two different pipelines produce the same key (e.g., namespace team with pipeline a-x collides with namespace team-a with pipeline x).

    Behavior during collision:

    • The operator attributes the collision to the younger pipeline (based on metadata.creationTimestamp).
    • The younger pipeline's configCheckResult becomes false.
    • The .status.reason will name the colliding flat key and the surviving pipeline.
    • The older pipeline and the workload continue running; no secret values leak between them.
    • Recovery is automatic once a pipeline is renamed, deleted, or its alias/key is changed to resolve the collision.
  7. Manage aggregated Secret size limits

    main

    Every pipeline on a single Vector/aggregator shares one aggregated <workload>-secret-assets Secret. Kubernetes limits Secrets to 1 MiB (1,048,576 bytes) for resolved values.

    Exclusion logic:

    • The operator sums referenced values and processes pipelines from oldest to youngest.
    • If a pipeline's values would push the total over 1 MiB, that pipeline is skipped (excluded).
    • Skipping an oversized pipeline does not disqualify younger, smaller pipelines; they are still evaluated and kept if they fit.
    • An excluded pipeline's configCheckResult becomes false.
    • The .status.reason will specify the byte limit, the bytes already committed by older pipelines, and the pipeline's own would-be contribution.

    Note: A value referenced multiple times within the same pipeline is counted once. However, if two different pipelines reference the same underlying Secret key, each pipeline pays for its own copy in the aggregate.

  8. Understand Backpressure Isolation and Head-of-Line Blocking in Optimized Sources

    main

    When Config Optimization is enabled, pipelines that share a 'signature group' (identical settings except for namespace) share a single kubernetes_logs source.

    The Trade-off:

    • Without Optimization: Each pipeline has its own source. A stuck sink (e.g., using buffer.when_full: block) only stalls its own pipeline.
    • With Optimization: A single stuck sink in a group can cause head-of-line blocking, stalling the entire shared source and every pipeline in that group.

    Mitigation Strategies:

    1. Modify the Sink: Set buffer.when_full: drop_newest (or use a disk buffer with overflow) and/or set a bounded request.retry_max_duration_secs on the unreliable sink to break backpressure.
    2. Exclude the Pipeline: Use the vector-operator.kaasops.io/config-optimization: disabled annotation on the specific pipeline to give it a dedicated source and backpressure domain.
  9. How VectorPipeline routing works

    main

    A VectorPipeline (namespace-scoped) or ClusterVectorPipeline (cluster-scoped) does not explicitly state whether it is an 'agent' or an 'aggregator'. The Operator determines the role automatically based on the sources defined in the pipeline.

    VectorPipeline (Namespace-scoped)

    • Agent role: Triggered if the pipeline uses the kubernetes_logs source type. It is routed to the Vector DaemonSet in that namespace and is restricted to collecting logs from its own namespace.
    • Aggregator role: Triggered if the pipeline uses aggregator source types (e.g., kafka, http_server, amqp, socket, redis, nats). It is routed to the VectorAggregator in the same namespace.
    • Restriction: You cannot mix agent and aggregator source types in a single pipeline.

    ClusterVectorPipeline (Cluster-scoped)

    • Agent role: Triggered by agent source types (e.g., kubernetes_logs, file, journald, host_metrics, docker_logs). It is routed to the Vector DaemonSet and can collect logs from any namespace.
    • Aggregator role: Triggered by aggregator source types (e.g., kafka, http_server, etc.). It is routed to the ClusterVectorAggregator.
    • Restriction: You cannot mix agent and aggregator source types in a single pipeline.
  10. Define a Vector Pipeline

    main

    A VectorPipelineSpec (or ClusterVectorPipelineSpec) defines the data flow within Vector by specifying three main components:

    • sources: A list of data sources to ingest from.
    • transforms: A list of transformations to apply to the ingested data.
    • sinks: A list of destinations where the processed data should be sent.
  11. Understand limitations of SECRET[...] values

    main

    The SECRET[alias.key] mechanism replaces the placeholder with the content of the secret key. Because the operator publishes the configuration as JSON, the secret value must be valid within a JSON string.

    Unsupported Values

    The following values will cause the pipeline to be marked invalid:

    • Non-UTF-8: Must be valid UTF-8.
    • Double Quotes ("): These prematurely close the JSON string.
    • Backslashes (\): These can break parsing or create unintended escape sequences.
    • Raw Control Bytes: Any bytes in the range 0x00–0x1F.

    Best Practices

    • Use for single-line credentials: This feature is ideal for passwords, tokens, usernames, and connection strings.
    • Avoid for multi-line material: Do not use spec.secret for certificates or private keys. Instead, mount these as files using standard Kubernetes volumes and volumeMounts on the Vector CR, and use the file path options in your sink (e.g., ca_file, crt_file).

    Example: Using files for TLS and secrets for SASL

    sinks:
      out:
        type: kafka
        inputs: [logs]
        bootstrap_servers: "kafka.example.com:9093"
        auth:
          tls:
            enabled: true
            # Mounted via standard volumes/volumeMounts on the Vector CR
            ca_file: /etc/vector/tls/ca.crt
          sasl:
            enabled: true
            mechanism: SCRAM-SHA-512
            username: "SECRET[kafka.username]"
            password: "SECRET[kafka.password]"