Skip to content

K8s + Sysbox: mount sysfs fails (EPERM) during pod creation #67

Description

@rodnymolina

I ran into this one while trying to scope the level of effort required to launch K8s PODs through Sysbox runtime.

I initially stumbled into issue #66, which hasn't been properly fixed yet, and then reproduced the problem described herein. Notice that even though the symptoms are identical (i.e, unable to mount sysfs), the cause seems to be different in this case, and that's why we are tracking this issue separately.

After multiple attempts at bysecting the container's OCI spec, i was able to identify the spec instruction causing this problem; however, the low-level root-cause has not been found yet.

Problem is reproduced whenever a sandbox container (e.g. "pause") is instantiated by K8s master. There's nothing specially relevant in the spec of this container, except for the fact that a "path" element is passed as part of the network-namespace element:

        "namespaces": [
            {
                "type": "pid"
            },
            {
                "type": "ipc"
            },
            {
                "type": "uts"
            },
            {
                "type": "mount"
            },
            {
                "path": "/var/run/netns/cni-ca69f110-38f9-4be8-dca4-10cbb16f8695",
                "type": "network"
            }
        ],

As per OCI's specification, a compliant runtime is expected to place the to-be-created container in the network namespace indicated by this file (which in turn, represents a bind-mount of a "/proc/pid/ns/net").

path (string, OPTIONAL) - namespace file. This value MUST be an absolute path in the runtime mount namespace. The runtime MUST place the container process in the namespace associated with that path. The runtime MUST generate an error if path is not associated with a namespace of type type. If path is not specified, the runtime MUST create a new container namespace of type type.

We can re-create the observed behavior by following the steps indicated below ...

Let's start by creating the shared network namespace that our POD will be part of:

rmolina@heavy-vm-bionic:~/wsp$ sudo ip netns add test-ns-1

rmolina@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu$ ls -li /run/netns/
total 0
4026532321 -r--r--r-- 1 root root 0 May 13 02:31 test-ns-1
rmolina@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu$

rmolina@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu$ findmnt
...
├─/run                                tmpfs                  tmpfs       rw,nosuid,noexec,relatime,size=815200k,mode=755
│ ├─/run/lock                         tmpfs                  tmpfs       rw,nosuid,nodev,noexec,relatime,size=5120k
│ ├─/run/user/1000                    tmpfs                  tmpfs       rw,nosuid,nodev,relatime,size=815196k,mode=700,uid=1000,gid=1000
│ ├─/run/user/1001                    tmpfs                  tmpfs       rw,nosuid,nodev,relatime,size=815196k,mode=700,uid=1001,gid=1001
│ ├─/run/netns/test-ns-1              nsfs[net:[4026532321]] nsfs        rw
│ └─/run/netns                        tmpfs[/netns]          tmpfs       rw,nosuid,noexec,relatime,size=815200k,mode=755
│   └─/run/netns/test-ns-1            nsfs[net:[4026532321]] nsfs        rw
├─/boot                               /dev/sda1              ext4        rw,relatime
...

Let's now add this network-ns file to our own baked spec:

		"namespaces": [
			{
				"type": "pid"
			},
		        {
			        "path": "/var/run/netns/test-ns-1",
				"type": "network"
			},
			{
				"type": "ipc"
			},
			{
				"type": "uts"
			},
			{
				"type": "mount"
			},
			{
				"type": "cgroup"
			}
		],

Problem is right away reproduced:

rmolina@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu$ sudo sysbox-runc run ubuntu-1
container_linux.go:364: starting container process caused "process_linux.go:533: container init caused \"rootfs_linux.go:58: setting up rootfs mounts caused \\\"rootfs_linux.go:928: mounting \\\\\\\"sysfs\\\\\\\" to rootfs \\\\\\\"/home/rmolina/wsp/05-12-2020/sysbox/ubuntu/rootfs\\\\\\\" at \\\\\\\"sys\\\\\\\" caused \\\\\\\"operation not permitted\\\\\\\"\\\"\""
rmolina@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu$

As expected, problem is not reproduced with upstream runc in the default configuration (no user-ns), as this would also fail in all K8s deployments. However, the same exact issue is reproduced the moment that we request user-ns creation.

See no issue with runc when relying on the above spec:

rmolina@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu$ sudo runc run ubuntu-1
#

Let's modify the spec to explicitly activate user-ns creation:

root@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu# cat /etc/subuid
lxd:100000:65536
root:100000:65536
vagrant:165536:65536
rmolina:231072:65536
sysbox:296608:268435456

root@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu# cat config.json
...
        "linux": {
        "uidMappings": [
            {
                "hostID": 296608,
                "containerID": 0,
                "size": 268435456
            }
        ],
        "gidMappings": [
            {
                "hostID": 296608,
                "containerID": 0,
                "size": 268435456
            }
        ],
            "namespaces": [
                        {
                                "type": "pid"
                        },
                        {
                                "path": "/var/run/netns/test-ns-1",
                                "type": "network"
                        },
                        {
                                "type": "ipc"
                        },
                        {
                                "type": "uts"
                        },
                        {
                                "type": "mount"
                        },
                        {
                                "type": "user"
                        },
                        {
                                "type": "cgroup"
                        }
                ],
...

Trying runc once again shows the same problem reported by sysbox-runc:

rmolina@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu$ sudo runc run ubuntu-1
WARN[0000] exit status 1
ERRO[0000] container_linux.go:349: starting container process caused "process_linux.go:449: container init caused \"rootfs_linux.go:58: mounting \\\"sysfs\\\" to rootfs \\\"/home/rmolina/wsp/05-12-2020/sysbox/ubuntu/rootfs\\\" at \\\"/sys\\\" caused \\\"operation not permitted\\\"\""
container_linux.go:349: starting container process caused "process_linux.go:449: container init caused \"rootfs_linux.go:58: mounting \\\"sysfs\\\" to rootfs \\\"/home/rmolina/wsp/05-12-2020/sysbox/ubuntu/rootfs\\\" at \\\"/sys\\\" caused \\\"operation not permitted\\\"\""
rmolina@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu$

Problem seems to be caused by some sort of kernel limitation or requirement imposed on user-namespaces and their relationship with network-namespaces. See that issue is also reproduced when leaving runtimes out of the equation:


<-- With network-ns:

rmolina@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu$ sudo unshare -m -u -i -n -p -U -f -r bash -c "mkdir /root/sys && mount -t sysfs sysfs /root/sys"
rmolina@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu$ echo $?
0

rmolina@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu$ sudo rm -rf /root/sys

<-- No network-ns:

rmolina@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu$ sudo unshare -m -u -i -p -U -f -r bash -c "mkdir /root/sys && mount -t sysfs sysfs /root/sys"
mount: /root/sys: permission denied.
rmolina@heavy-vm-bionic:~/wsp/05-12-2020/sysbox/ubuntu$

More details to come ...

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions