mirror of
https://github.com/fankes/komari-agent.git
synced 2025-10-18 18:49:23 +08:00
feat: 优化容器检测逻辑
This commit is contained in:
@@ -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"):
|
|
||||||
return "docker"
|
|
||||||
case strings.Contains(lower, "containerd"):
|
|
||||||
return "container"
|
|
||||||
case strings.Contains(lower, "kubepods") || strings.Contains(lower, "kubelet"):
|
|
||||||
return "kubernetes"
|
|
||||||
case strings.Contains(lower, "crio"):
|
|
||||||
return "container"
|
|
||||||
case strings.Contains(lower, "lxc"):
|
|
||||||
return "lxc"
|
|
||||||
case strings.Contains(lower, "podman"):
|
|
||||||
return "podman"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
lower := strings.ToLower(string(data))
|
||||||
|
|
||||||
|
// Precompile (once) regex patterns for common container runtimes.
|
||||||
|
// Patterns target leaf elements referencing container IDs instead of any occurrence of runtime name to reduce false positives.
|
||||||
|
var (
|
||||||
|
dockerIDPattern = regexp.MustCompile(`(?m)/(?:docker|cri-containerd)[/-]([0-9a-f]{12,64})(?:\.scope)?$`)
|
||||||
|
dockerScopePattern = regexp.MustCompile(`(?m)/docker-[0-9a-f]{12,64}\.scope$`)
|
||||||
|
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
|
||||||
|
podmanPattern = regexp.MustCompile(`(?m)/(?:libpod|podman)[-_]([0-9a-f]{12,64})(?:\.scope)?$`)
|
||||||
|
lxcPattern = regexp.MustCompile(`(?m)/lxc/[^/]+$`)
|
||||||
|
crioPattern = regexp.MustCompile(`(?m)/crio-[0-9a-f]{12,64}\.scope$`)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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 ""
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user