Skip to content

Container id extraction logic breaks on docker with cgroup2 #207

Closed
@HeavenVolkoff

Description

@HeavenVolkoff

Docker 20.10 gained support for cgroup v2.

However when running this caddy plugin in a container on Docker with cgroup2 the current logic for container ID extraction fails.

As far as I can tell the problem seems to be at this part of the code:

// GetCurrentContainerID returns the id of the container running this application
func (wrapper *dockerUtils) GetCurrentContainerID() (string, error) {
if runtime.GOOS == "windows" {
return os.Hostname()
}
bytes, err := ioutil.ReadFile("/proc/self/cgroup")
if err != nil {
return "", err
}
if len(bytes) == 0 {
return "", errors.New("Cannot read /proc/self/cgroup")
}
return wrapper.ExtractContainerID(string(bytes))
}
func (wrapper *dockerUtils) ExtractContainerID(cgroups string) (string, error) {
idRegex := regexp.MustCompile(`(?i):[^:]*\bcpu\b[^:]*:[^/]*/.*([[:alnum:]]{64}).*`)
matches := idRegex.FindStringSubmatch(cgroups)
if len(matches) == 0 {
return "", fmt.Errorf("Cannot find container id in cgroups: %v", cgroups)
}
return matches[len(matches)-1], nil
}

This seems to be based of a know hack for getting container information from within the container itself.

The problem is that with cgroup v2, the file /proc/self/cgroup doesn't contain the previously available information.

Below is the content of the file in a container running on a Docker with cgroup v2:

$> cat /proc/self/cgroup
0::/

Digging through the other files in /proc/self, there seems to be another (hacky) way for retrieving the container id.

The file /proc/self/mountinfo contains the id in the mount paths for the /etc/resolv.conf, /etc/hostname, /etc/hosts files:

$> cat /proc/self/mountinfo
1582 1433 0:29 /@/var/lib/docker/btrfs/subvolumes/3388737b99462f26ff76d17105b237d2c2f312338f3c6585af52d8745add9af1 / rw master:1 - btrfs /dev/sda2 rw,lazytime,compress=zstd:3,ssd,discard=async,space_cache,subvolid=4409,subvol=/@/var/lib/docker/btrfs/subvolumes/3388737b99462f26ff76d17105b237d2c2f312338f3c6585af52d8745add9af1
1583 1582 0:189 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
1584 1582 0:190 / /dev rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,inode64
1585 1584 0:191 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=666
1586 1582 0:192 / /sys ro,nosuid,nodev,noexec,relatime - sysfs sysfs ro
1587 1586 0:25 / /sys/fs/cgroup ro,nosuid,nodev,noexec,relatime - cgroup2 cgroup rw,nsdelegate,memory_recursiveprot
1588 1584 0:188 / /dev/mqueue rw,nosuid,nodev,noexec,relatime - mqueue mqueue rw
1589 1584 0:193 / /dev/shm rw,nosuid,nodev,noexec,relatime - tmpfs shm rw,size=65536k,inode64
1590 1582 0:29 /@/usr/bin/docker-init /sbin/docker-init ro master:1 - btrfs /dev/sda2 rw,lazytime,compress=zstd:3,ssd,discard=async,space_cache,subvolid=256,subvol=/@
1591 1582 0:187 / /tmp rw,nosuid,nodev,noexec,relatime master:645 - tmpfs tmpfs rw,size=262144k,mode=777,inode64
1592 1582 0:75 / /config rw,relatime master:666 - nfs4 :/caddy/config rw,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,soft,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.0.2,local_lock=none,addr=10.0.0.2
1593 1582 0:75 / /data rw,relatime master:673 - nfs4 :/caddy/data rw,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,soft,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.0.2,local_lock=none,addr=10.0.0.2
1594 1582 0:75 / /var/log rw,relatime master:659 - nfs4 :/logs/caddy rw,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,soft,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.0.2,local_lock=none,addr=10.0.0.2
1595 1582 0:29 /@/var/lib/docker/containers/fcc626d54fda7061cc76bbdb0a0d992bc7ea4864b88340336857c43fd37b3df0/resolv.conf /etc/resolv.conf rw - btrfs /dev/sda2 rw,lazytime,compress=zstd:3,ssd,discard=async,space_cache,subvolid=256,subvol=/@
1596 1582 0:29 /@/var/lib/docker/containers/fcc626d54fda7061cc76bbdb0a0d992bc7ea4864b88340336857c43fd37b3df0/hostname /etc/hostname rw - btrfs /dev/sda2 rw,lazytime,compress=zstd:3,ssd,discard=async,space_cache,subvolid=256,subvol=/@
1597 1582 0:29 /@/var/lib/docker/containers/fcc626d54fda7061cc76bbdb0a0d992bc7ea4864b88340336857c43fd37b3df0/hosts /etc/hosts rw - btrfs /dev/sda2 rw,lazytime,compress=zstd:3,ssd,discard=async,space_cache,subvolid=256,subvol=/@
1598 1582 0:75 / /usr/share/caddy rw,relatime master:652 - nfs4 :/caddy/static rw,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,soft,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.0.2,local_lock=none,addr=10.0.0.2
1434 1583 0:189 /bus /proc/bus ro,relatime - proc proc rw
1453 1583 0:189 /fs /proc/fs ro,relatime - proc proc rw
1496 1583 0:189 /irq /proc/irq ro,relatime - proc proc rw
1497 1583 0:189 /sys /proc/sys ro,relatime - proc proc rw
1498 1583 0:189 /sysrq-trigger /proc/sysrq-trigger ro,relatime - proc proc rw
1499 1583 0:194 / /proc/asound ro,relatime - tmpfs tmpfs ro,inode64
1500 1583 0:195 / /proc/acpi ro,relatime - tmpfs tmpfs ro,inode64
1501 1583 0:190 /null /proc/kcore rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,inode64
1502 1583 0:190 /null /proc/keys rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,inode64
1503 1583 0:190 /null /proc/latency_stats rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,inode64
1504 1583 0:190 /null /proc/timer_list rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,inode64
1505 1583 0:190 /null /proc/sched_debug rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,inode64
1506 1583 0:196 / /proc/scsi ro,relatime - tmpfs tmpfs ro,inode64
1507 1586 0:197 / /sys/firmware ro,relatime - tmpfs tmpfs ro,inode64

The logic for extracting the container id could be extended to parse this file in the case the information isn't available in /proc/self/cgroup. However, I don't how reliable this solution can be, as I didn't test enough to be certain this mount paths are always available no matter the options a container is run with.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions