# The VictoriaMetrics operator is a Prometheus operator clone with its own CRDs

> VictoriaMetrics/operator is a Go Kubernetes operator that manages VictoriaMetrics deployments and their scrape and rule configuration, modelled on prometheus-operator and offering both the familiar ServiceMonitor, PodMonitor, PrometheusRule and Probe objects and VictoriaMetrics specific VMServiceScrape, VMPodScrape, VMRule, VMProbe and VMScrapeConfig resources. Its most interesting feature is delegating monitoring configuration to application teams through the API.

**VictoriaMetrics/operator** — Kubernetes operator for Victoria Metrics

- Repository: https://github.com/VictoriaMetrics/operator
- Stars: 595 · Forks: 242
- Language: Go
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/victoriametrics-operator

## Two CRD vocabularies, and the reason for both

The operator is described as a design and implementation inspired by prometheus-operator, and the first thing that makes that concrete is that it accepts two sets of custom resource definitions.

The familiar set is the Prometheus Operator one: ServiceMonitor, PodMonitor, PrometheusRule and Probe. A team migrating from prometheus-operator can keep its existing objects.

The VictoriaMetrics set is VMServiceScrape, which defines scraping metrics configuration from pods backed by services, VMPodScrape for pods, VMRule for alerting or recording rules, VMProbe for probing configuration for targets with blackbox exporter, and VMScrapeConfig which defines a scrape config using any of the service discovery options supported in VictoriaMetrics.

The VM variants are not a rename. The last one in particular is the interesting case, because VMScrapeConfig is explicitly a way to express any discovery mechanism the product supports, which is broader than what the Prometheus Operator model allows. The operator code confirms the split in its dependencies, since it pulls in prometheus-operator/pkg/apis/monitoring for the upstream types and the api/ directory of its own module for the VM ones, with the api module versioned in step with the operator at v0.75.0.

Everything else follows from those types being separate Go API packages with their own CRD schemas, their own validation and their own version compatibility rules.

## Delegating monitoring config to the people who own the code

The use cases section describes two audiences, and the second one contains the feature that distinguishes this operator from a packaging convenience.

For Kubernetes cluster administrators, the operator simplifies installation, configuration and management for a VictoriaMetrics application.

For application developers, it is a possibility for managing observability of applications: you define metrics scraping and alerting configuration for your application and manage it with your application deployment process. The concrete workflow given is to define app_deployment.yaml, app_vmpodscrape.yaml and app_vmrule.yaml and apply them to the cluster. The stated main feature of the operator is the ability to delegate applications monitoring configuration to the end-users.

That word, delegate, is the point. The alternative model is that a platform team maintains one central Prometheus configuration with a ConfigMap and a set of scrape jobs, and every application team files a request when they want a new scrape target. The operator model replaces that with an API: application teams create their own VMServiceScrape and VMRule objects, and the operator reconciles them into the running VictoriaMetrics configuration.

The price of delegation is the API surface itself, and that is why the operator has an api capability with it, and why the documentation has a page for external access to cluster resources and one for security. If application teams can create scrape configurations, they can also point scrapes at arbitrary targets, so authentication, authorisation and resource validation are part of the product rather than an afterthought. The project links dedicated documents for both.

## The operator manages the whole VictoriaMetrics application set

Beyond the scrape and rule objects, the operator manages VictoriaMetrics applications inside a Kubernetes cluster, and it simplifies cluster installation, upgrading and managing.

The documentation links point at the resources this covers, and they give a good picture of the scope. There is a VMSingle resource, with its own page covering backup automation. There is a VMCluster resource, also with backup automation. There is a vmalert resource, whose page includes a high availability section, and a vmagent resource with a relabeling configuration page. There is a resources page that covers managing versions of VM resources, and a page for external access to cluster resources under the auth heading.

The vmagent relabeling page is a good indicator of the level of detail expected. Relabeling is where a scrape configuration gets its power, dropping and rewriting metrics as they arrive, and having a dedicated page for it means the operator is expected to configure agents properly rather than just run them.

The backup integration is the part with real state behind it. The operator integrates with vmbackupmanager, described as advanced tools for making backups, and the documentation points at backup automation sections for both VMSingle and VMCluster. That is a meaningful piece of integration, because a metrics deployment without a tested backup path is a deployment whose history disappears on the next node failure.

The relationship to Helm is stated directly in a short section. VictoriaMetrics provides helm charts, and the operator makes the same, simplifies it and provides advanced features. The chart is the imperative one shot installation; the operator is the reconciling one.

## Configuration is environment variables, and validation is in the CRD schema

The operator is configured by environment variables, with the full list at a documentation link, and it defines default configuration options such as images for components, timeouts and features.

The dependency on github.com/caarlos0/env/v11 in go.mod is what implements that. It is a small library that maps environment variables onto a Go struct, and it is the reason the operator's configuration surface is a flat set of environment variables rather than a configuration file or a flag set. The consequence for a cluster administrator is that configuring the operator means editing the operator's Deployment, which is the normal pattern for an operator and the reason the documentation lists it as a separate topic.

The other configuration surface is the CRD schema itself, and there is a dedicated document on resource validation. That is the important one for anyone writing manifests. A CRD with a structural schema validates on apply, so a manifest with a bad field or a wrong type is rejected by the API server rather than silently accepted and then failing later inside the operator's reconcile loop. The trade is that the schemas have to be maintained as the product changes, and the project has a separate document on managing CRD object versions for exactly that reason.

The remaining configuration topics are labelled in the documentation list: relabeling configuration, high availability, external access to cluster resources, and security. The presence of a security document at all is a sign of the delegation model described earlier.

## Building the operator and running its tests

The development section lists the dependencies: kubebuilder v4, golang 1.23+, kubectl and docker. The go.mod is more specific than the README, declaring go 1.27.2, and the Dockerfile builds from golang:1.27.2.

There are three make targets, and the third one is commented out in the documentation:

```bash
make run
```

```bash
make test
```

```bash
# make test-e2e
```

The first starts the operator against the current cluster configuration, the second runs the unit tests, and the third is the end to end suite on an automatically configured Kind cluster, which is present but commented out in the README, presumably because it needs to be enabled deliberately.

The repository layout confirms the controller-runtime structure. There is an api directory for the CRD types, an internal directory for the reconciliation logic, a cmd directory that is the ROOT of the build, a config directory that holds the manifests, and a hack directory for the usual scaffolding scripts. The PROJECT file is the kubebuilder project descriptor, and the presence of a separate api module, api/go.mod referenced in the Dockerfile copy step, means the CRD types are versioned as their own Go module, which is how a project keeps API compatibility separate from operator release cadence.

The test stack is ginkgo and gomega, with testify also present, and the Makefile pins ENVTEST_K8S_VERSION to 1.37.1, which is the version of the Kubernetes control plane binaries the envtest harness downloads. The k8s.io libraries are all on 0.37.1 to match.

## The container is a static binary on scratch

The Dockerfile is worth a look because it shows how little runtime the operator needs.

The build stage starts from golang:1.27.2, sets CARGO_NET_GIT_FETCH_WITH_CLI, and installs the usual build prerequisites including libssl-dev and libclang-dev. The go module download is done in its own layer with cache mounts, deliberately before the source is copied, so that a source change does not invalidate the downloaded dependency layer.

The build itself sets CGO_ENABLED=0, so the binary is fully static. It also honours a FIPS_VERSION build argument through GOFIPS140, and a GODEBUG_ARGS argument, and stamps the version into the binary with a linker flag pointing at the buildinfo package of the VictoriaMetrics module.

The runtime stage uses scratch as the base image, which means no shell, no package manager and no libc in the image. It copies the LICENSE to /licenses/apache2.txt, copies the binary to the root, and runs as user 65532:65532 rather than root. The entrypoint is the binary itself.

That choice is well matched to an operator. An operator is a long running process that watches the API server and reconciles, and it does not need a shell to do that. Shipping it on scratch removes a shell from every cluster that runs it, and the non-root user is a meaningful detail in a component that has permission to read and write cluster objects.

The Makefile adds the operational details around that image. REGISTRY and PUBLISH_REGISTRIES default to docker.io, and the publish list includes quay.io as well. The TAG is derived from git describe, and it is marked dirty when the working tree has changes outside the config and docs directories, so a locally built image is distinguishable from a released one. The base image can be swapped, and a UBI base is offered for Red Hat environments. There is also a separate config-reloader image built from the same repository, and a .trivyignore and a .golangci.yml for the security scanner and the linter.

## Where the VictoriaMetrics operator is the wrong choice

Four situations rule it out.

The first is a cluster that has not chosen VictoriaMetrics. The entire CRD surface, the API and the reconciliation logic exist to manage one product. If the monitoring stack is Prometheus, or Grafana Cloud, or a managed offering, this operator gives you nothing, and a helm chart would be less work.

The second is a team that wants the full Prometheus Operator feature set. The README says the design and implementation are inspired by prometheus-operator, and the dependency on prometheus-operator/pkg/apis/monitoring gives it the upstream API types. It does not say it is a complete replacement for every feature of that project. Anything the upstream operator does that this one does not is a gap, and the documentation lists the operator's own features rather than enumerating the differences.

The third is an environment without a Kubernetes API to reconcile against. The operator is a controller, and its entire value depends on running inside a cluster with RBAC and CRDs. Testing it outside a cluster means a Kind cluster, which the development section reflects with the commented out test-e2e target and a kind.yaml file in the repository root.

The fourth is a team that wants monitoring configuration as code in one place, reviewed together. The delegation model that makes the operator valuable for a large organisation has the opposite effect on a small one. With a handful of services, a single ConfigMap with a scrape configuration is simpler, easier to review in a pull request, and does not need an API in front of it. The operator earns its complexity when there are many teams with independent services, and it is overhead when there are few.

The alternative worth naming is the Helm chart that the README itself points at. The chart installs the same VictoriaMetrics components declaratively and in one step, and you manage configuration by editing values and re-running a diff. The operator replaces that workflow with a reconciliation loop, which is the right trade when configuration changes often and comes from many authors, and the wrong one when it changes rarely and comes from one team.

## Conclusion

VictoriaMetrics operator fits a Kubernetes organisation that has standardised on VictoriaMetrics and wants the operator pattern, or that wants application teams to own their own scrape configuration without cluster admin editing a shared config map. It is the wrong choice for a cluster that has not settled on VictoriaMetrics, since the whole CRD surface and the API exist to manage that one product, and it is the wrong choice if you want the full Prometheus operator feature set, because this operator is described as inspired by prometheus-operator rather than a complete replacement. Before adopting it, check three things: that the CRD versions you write against are the ones this operator ships, since the project has a dedicated document on managing CRD object versions, that the resource validation rules in the CRD schema match your manifests rather than being rejected, and that the backup automation you rely on works with vmbackupmanager as documented for VMSingle and VMCluster, since that integration is the part of the operator with real state behind it.

## FAQ

### What is the VictoriaMetrics operator and what does it do?

It is a Go Kubernetes operator, designed and implemented inspired by prometheus-operator, that manages VictoriaMetrics applications inside a cluster and simplifies installation, upgrading and managing. It also has an API capability so that monitoring configuration can be delegated to end users.

### What custom resource definitions does the VictoriaMetrics operator support?

Both the familiar Prometheus Operator objects, ServiceMonitor, PodMonitor, PrometheusRule and Probe, and the VictoriaMetrics ones, VMServiceScrape, VMPodScrape, VMRule, VMProbe and VMScrapeConfig, where VMScrapeConfig can use any of the service discovery options supported in VictoriaMetrics.

### How is the VictoriaMetrics operator configured?

By environment variables, with the list at a documentation link. It defines default configuration options such as images for components, timeouts and features, and the environment variable mapping is implemented with the caarlos0/env library.

### How do I run the VictoriaMetrics operator locally?

The development dependencies are kubebuilder v4, golang 1.23+, kubectl and docker. make run starts the operator, make test runs the unit tests, and there is a make test-e2e target for an end to end run on an automatically configured Kind cluster, which is shown commented out in the documentation.

### What is the difference between the VictoriaMetrics operator and its Helm charts?

The README states that VictoriaMetrics provides helm charts, and that the operator makes the same, simplifies it and provides advanced features. The chart is a one shot declarative installation, while the operator reconciles continuously and adds the API for delegating configuration to application teams.

## Sources

- [Issues](https://github.com/VictoriaMetrics/operator/issues)
- [License: Apache-2.0](https://github.com/VictoriaMetrics/operator/blob/master/LICENSE)
- [README](https://github.com/VictoriaMetrics/operator/blob/master/README.md)
- [Releases](https://github.com/VictoriaMetrics/operator/releases)
- [VictoriaMetrics/operator on GitHub](https://github.com/VictoriaMetrics/operator)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/victoriametrics-operator
