feat: 优化容器检测逻辑

This commit is contained in:
Akizon77
2025-08-28 12:31:15 +08:00
parent 3453aecbec
commit b20e972c96

View File

@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"regexp"
"runtime" "runtime"
"strings" "strings"
@@ -70,37 +71,23 @@ func detectByCPUID() string {
// detectContainer attempts to detect common Linux container environments when systemd isn't available. // detectContainer attempts to detect common Linux container environments when systemd isn't available.
// Returns a systemd-detect-virt-like string such as "docker", "podman", "lxc", "container" or empty if not detected. // Returns a systemd-detect-virt-like string such as "docker", "podman", "lxc", "container" or empty if not detected.
func detectContainer() string { func detectContainer() string {
// Quick file markers used by Docker/Podman/CRI-O // Definite file markers first.
if fileExists("/.dockerenv") { if fileExists("/.dockerenv") {
return "docker" return "docker"
} }
if fileExists("/run/.containerenv") { if fileExists("/run/.containerenv") { // podman / CRI-O
// podman/cri-o often drop this file
// Try to refine using cgroup content.
if s := parseCgroupForContainer(); s != "" { if s := parseCgroupForContainer(); s != "" {
return s return s
} }
return "container" return "container"
} }
// Check cgroup info for container keywords. // cgroup based detection (safer & more specific than broad substring checks)
if s := parseCgroupForContainer(); s != "" { if s := parseCgroupForContainer(); s != "" {
return s return s
} }
// Check mounts for overlay/containers hints. // (Removed mountinfo heuristics which caused host false positives when Docker/Kube tools are installed.)
if data, err := os.ReadFile("/proc/self/mountinfo"); err == nil {
lower := strings.ToLower(string(data))
switch {
case strings.Contains(lower, "/docker/"):
return "docker"
case strings.Contains(lower, "/containers/overlay-containers/") || strings.Contains(lower, "/lib/containers/"):
return "podman"
case strings.Contains(lower, "/kubelet/"):
return "kubernetes"
}
}
return "" return ""
} }
@@ -112,23 +99,39 @@ func fileExists(p string) bool {
} }
func parseCgroupForContainer() string { func parseCgroupForContainer() string {
// cgroup v1 & v2 paths can contain docker, kubepods, containerd, crio, lxc, podman data, err := os.ReadFile("/proc/self/cgroup")
if data, err := os.ReadFile("/proc/self/cgroup"); err == nil { if err != nil {
lower := strings.ToLower(string(data)) return ""
switch { }
case strings.Contains(lower, "docker"): lower := strings.ToLower(string(data))
return "docker"
case strings.Contains(lower, "containerd"): // Precompile (once) regex patterns for common container runtimes.
return "container" // Patterns target leaf elements referencing container IDs instead of any occurrence of runtime name to reduce false positives.
case strings.Contains(lower, "kubepods") || strings.Contains(lower, "kubelet"): var (
return "kubernetes" dockerIDPattern = regexp.MustCompile(`(?m)/(?:docker|cri-containerd)[/-]([0-9a-f]{12,64})(?:\.scope)?$`)
case strings.Contains(lower, "crio"): dockerScopePattern = regexp.MustCompile(`(?m)/docker-[0-9a-f]{12,64}\.scope$`)
return "container" kubePattern = regexp.MustCompile(`(?m)/kubepods[/.].*([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}).*`) // pod UID
case strings.Contains(lower, "lxc"): podmanPattern = regexp.MustCompile(`(?m)/(?:libpod|podman)[-_]([0-9a-f]{12,64})(?:\.scope)?$`)
return "lxc" lxcPattern = regexp.MustCompile(`(?m)/lxc/[^/]+$`)
case strings.Contains(lower, "podman"): crioPattern = regexp.MustCompile(`(?m)/crio-[0-9a-f]{12,64}\.scope$`)
return "podman" )
}
} // Order: specific runtime before generic container.
if dockerIDPattern.FindStringIndex(lower) != nil || dockerScopePattern.FindStringIndex(lower) != nil {
return "docker"
}
if podmanPattern.FindStringIndex(lower) != nil {
return "podman"
}
if crioPattern.FindStringIndex(lower) != nil {
return "container" // CRI-O generic
}
if kubePattern.FindStringIndex(lower) != nil {
return "kubernetes"
}
if lxcPattern.FindStringIndex(lower) != nil {
return "lxc"
}
return "" return ""
} }