Compare commits

...

1 Commits

Author SHA1 Message Date
f41gh7
fc8c62575e lib/promscrape: properly detect IPv6 address for docker discovery
Previously service discovery was not able to discover IP address at IPv6 only networks.

 This commit adds fall-back for GlobalIPv6Address field at container
network.

Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10965
2026-07-30 17:47:00 +02:00
3 changed files with 102 additions and 6 deletions

View File

@@ -45,6 +45,7 @@ See also [LTS releases](https://docs.victoriametrics.com/victoriametrics/lts-rel
* BUGFIX: [MetricsQL](https://docs.victoriametrics.com/victoriametrics/metricsql/): properly drop data points filtered out by an inner [comparison operation](https://prometheus.io/docs/prometheus/latest/querying/operators/#comparison-binary-operators) when its result is used on the right side of another comparison. Previously, queries like `foo != (bar > 100)` could return unexpected results because filtered-out data points are represented internally as `NaN`, and `value != NaN` evaluates to `true`. Comparisons against explicitly present `NaN` values keep the previous behavior. See [#10018](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10018). Thanks to @zasdaym for contribution.
* BUGFIX: [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/) and [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/): ignore HTTP proxy environment variables when scraping targets over Unix domain sockets. See [#11318](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/11318). Thanks to @lwmacct for contribution.
BUGFIX: [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/) and [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/): properly assign scrape target IP address at IPv6-only networks for [docker_sd_configs](https://docs.victoriametrics.com/victoriametrics/sd_configs/#docker_sd_configs). See [#10965](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10965).
* BUGFIX: [vmalert](https://docs.victoriametrics.com/victoriametrics/vmalert/): fixed the display of rule state badges on the `Groups` page in the web UI. See [#11160](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11160).
* BUGFIX: [vmbackupmanager](https://docs.victoriametrics.com/victoriametrics/vmbackupmanager/): previously, `vmbackupmanager` was crashing on startup when it failed to restore backup state from remote storage, causing a crash loop. Now it logs the error and continues running, retrying the state restore before each scheduled backup. Added `vm_backup_errors_total{type="restoreState"}` metric to track backup state restore failures. See [#11217](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11217).

View File

@@ -37,8 +37,9 @@ type containerNetworkSettings struct {
}
type containerNetwork struct {
IPAddress string
NetworkID string
GlobalIPv6Address string
IPAddress string
NetworkID string
}
func getContainersLabels(cfg *apiConfig) ([]*promutil.Labels, error) {
@@ -118,14 +119,18 @@ func addContainersLabels(containers []container, networkLabels map[string]*promu
networks = map[string]containerNetwork{firstNetworkMode: firstNetwork}
}
for _, n := range networks {
ipAddress := n.IPAddress
if len(ipAddress) == 0 {
ipAddress = n.GlobalIPv6Address
}
var added bool
for _, p := range c.Ports {
if p.Type != "tcp" {
continue
}
m := promutil.NewLabels(16)
m.Add("__address__", discoveryutil.JoinHostPort(n.IPAddress, p.PrivatePort))
m.Add("__meta_docker_network_ip", n.IPAddress)
m.Add("__address__", discoveryutil.JoinHostPort(ipAddress, p.PrivatePort))
m.Add("__meta_docker_network_ip", ipAddress)
m.Add("__meta_docker_port_private", strconv.Itoa(p.PrivatePort))
if p.PublicPort > 0 {
m.Add("__meta_docker_port_public", strconv.Itoa(p.PublicPort))
@@ -141,11 +146,11 @@ func addContainersLabels(containers []container, networkLabels map[string]*promu
// Use fallback port when no exposed ports are available or if all are non-TCP
addr := hostNetworkingHost
if c.HostConfig.NetworkMode != "host" {
addr = discoveryutil.JoinHostPort(n.IPAddress, defaultPort)
addr = discoveryutil.JoinHostPort(ipAddress, defaultPort)
}
m := promutil.NewLabels(16)
m.Add("__address__", addr)
m.Add("__meta_docker_network_ip", n.IPAddress)
m.Add("__meta_docker_network_ip", ipAddress)
addCommonLabels(m, c, networkLabels[n.NetworkID])
// Remove possible duplicate labels, which can appear after addCommonLabels() call
m.RemoveDuplicates()

View File

@@ -431,6 +431,96 @@ func TestAddContainerLabels(t *testing.T) {
}),
}
f(c, networkLabels, labelssExpected)
data = []byte(`[
{
"Name": "bridge",
"Id": "1dd8d1a8bef59943345c7231d7ce8268333ff5a8c5b3c94881e6b4742b447634",
"Created": "2021-03-18T14:36:04.290821903+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": true,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "fc00::/64",
"Gateway": "fc00::1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]`)
networks, err = parseNetworks(data)
if err != nil {
t.Fatalf("fail to parse networks: %v", err)
}
networkLabels = getNetworkLabelsByNetworkID(networks)
// NetworkMode != host
c = container{
ID: "90bc3b31aa13da5c0b11af2e228d54b38428a84e25d4e249ae9e9c95e51a0700",
Names: []string{"/crow-server"},
Labels: map[string]string{
"com.docker.compose.config-hash": "c9f0bd5bb31921f94cff367d819a30a0cc08d4399080897a6c5cd74b983156ec",
"com.docker.compose.container-number": "1",
"com.docker.compose.oneoff": "False",
"com.docker.compose.project": "crowserver",
"com.docker.compose.service": "crow-server",
"com.docker.compose.version": "1.11.2",
},
HostConfig: containerHostConfig{
NetworkMode: "bridge",
},
NetworkSettings: containerNetworkSettings{
Networks: map[string]containerNetwork{
"bridge": {
GlobalIPv6Address: "fc00::2",
NetworkID: "1dd8d1a8bef59943345c7231d7ce8268333ff5a8c5b3c94881e6b4742b447634",
},
},
},
}
labelssExpected = []*promutil.Labels{
promutil.NewLabelsFromMap(map[string]string{
"__address__": "[fc00::2]:8012",
"__meta_docker_container_id": "90bc3b31aa13da5c0b11af2e228d54b38428a84e25d4e249ae9e9c95e51a0700",
"__meta_docker_container_label_com_docker_compose_config_hash": "c9f0bd5bb31921f94cff367d819a30a0cc08d4399080897a6c5cd74b983156ec",
"__meta_docker_container_label_com_docker_compose_container_number": "1",
"__meta_docker_container_label_com_docker_compose_oneoff": "False",
"__meta_docker_container_label_com_docker_compose_project": "crowserver",
"__meta_docker_container_label_com_docker_compose_service": "crow-server",
"__meta_docker_container_label_com_docker_compose_version": "1.11.2",
"__meta_docker_container_name": "/crow-server",
"__meta_docker_container_network_mode": "bridge",
"__meta_docker_network_id": "1dd8d1a8bef59943345c7231d7ce8268333ff5a8c5b3c94881e6b4742b447634",
"__meta_docker_network_ingress": "false",
"__meta_docker_network_internal": "false",
"__meta_docker_network_ip": "fc00::2",
"__meta_docker_network_name": "bridge",
"__meta_docker_network_scope": "local",
}),
}
f(c, networkLabels, labelssExpected)
}
func TestDockerMultiNetworkLabels(t *testing.T) {