runc icon indicating copy to clipboard operation
runc copied to clipboard

How to create a container with the same root fs as the host?

Open planetA opened this issue 7 years ago • 13 comments

Hello,

I'm trying to create a container that runs in its own namespaces (mount, net, uts, etc.). But the special thing I want to achieve is that it has the same view on the filesystem as the root, unless it tries to modify its own VFS.

For that I try to specify path to rootfs as "/", but the creation of the container does not work this way and fails with "invalid argument":

sudo ./test-runc hostname 2018/10/13 10:34:34 exec: "hostname": executable file not found in $PATH 2018/10/13 12:34:34 Failed to launch the container: container_linux.go:336: starting container process caused "exec: "hostname": executable file not found in $PATH"

Here is the full example I tried to run: test-runc

I still want to run the container in a separate mount namespace. For example, to be able to remount /proc, but I still want the rest of the host VFS be visible from the inside of the container.

planetA avatar Oct 13 '18 10:10 planetA

instead of changing your rootfs path... add a /host mount pointing to root in your config.json. Cheers.

mikebrow avatar Oct 13 '18 15:10 mikebrow

@mikebrow, thank you for the response, but could you be a bit more elaborate?

Do you mean creating a directory "/host" that is a bind mount to "/"? And then Rootfs parameter is "/host"?

planetA avatar Oct 13 '18 20:10 planetA

No. Instead of changing your rootfs parameter/path... add a mount who's source is root and who's destination is /host or some other path that is not used by your container. Put another way, no I do not believe you can set the rootfs of the container to the host root, but you can mount the host's root as a non root directory in the container. If you want to run ubuntu in a container.. you don't set your rootfs to the ubuntu host.. you run an ubuntu container in your ubuntu host.

mikebrow avatar Oct 14 '18 12:10 mikebrow

I too would like this capability. Is there a way to achieve this?

I have setup a series of bind mounts on the host but it is not that flexible.

sigmonsays avatar Nov 30 '18 21:11 sigmonsays

in your config.json.. add a new mount to "mounts": for example I added:

		{
			"destination": "/host",
			"type": "bind",
			"source": "/",
			"options": ["rbind","ro"]
		}

to the mounts list in a config.json in a local test directory that also has a rootfs/ with the extracted contents of the busybox container image and here are the results:

mike@mike-VirtualBox:~/go/src/busyboxtest$ sudo runc run test1
/ # ls
bin   dev   etc   home  host  proc  root  sys   tmp   usr   var
/ # ls host/home/mike/go/src/github.com/opencontainers
distribution-spec  go-digest          image-spec         runc               runtime-spec       runtime-tools      specs              tob

is this enough detail?

Cheers.,

mikebrow avatar Nov 30 '18 23:11 mikebrow

@planetA @sigmonsays any more help needed on this one?

Summary, you can't set a container's rootfs to the host's root. But you can mount the host root as a non root directory in the container.

mikebrow avatar Dec 04 '18 16:12 mikebrow

@mikebrow no

planetA avatar Dec 04 '18 16:12 planetA

@planetA Have you found the solution?

qbing avatar Dec 27 '18 08:12 qbing

@qbing Not really

planetA avatar Dec 30 '18 13:12 planetA

@planetA I also want to mount host "/" to contianer "/" , it can work but when i disable the mount namespace there will have some issues. you can refer to the following link: https://groups.google.com/a/opencontainers.org/forum/#!searchin/dev/mount$20namespace%7Csort:date/dev/p10bq-kXODk/obkqBRdxCQAJ

liudlong avatar Mar 28 '19 06:03 liudlong

If anyone still interested, I was able to achieve that by using mount namespace and rbind mount together. Also you need an empty initial rootfs, I've created a directory named empty-directory for that.

{
	"ociVersion": "1.0.2-dev",
	"process": {
		"terminal": true,
		"user": {
			"uid": 1031682,
			"gid": 100
		},
		"args": [
			"sh"
		],
		"env": [
			"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
			"TERM=xterm"
		],
		"cwd": "/",
		"rlimits": [
			{
				"type": "RLIMIT_NOFILE",
				"hard": 1024,
				"soft": 1024
			}
		],
		"noNewPrivileges": true
	},
	"root": {
		"path": "empty-directory",
		"readonly": false
	},
	"hostname": "runc",
	"mounts": [
		{
			"destination": "/",
			"type": "rbind",
			"source": "/",
			"options": [
				"rw",
				"rbind"
			]
		}
	],
	"linux": {
		"resources": {
			"devices": [
				{
					"allow": true,
					"access": "rwm"
				}
			]
		},
		"namespaces": [
			{
				"type": "pid"
			},
			{
				"type": "network"
			},
			{
				"type": "ipc"
			},
			{
				"type": "uts"
			},
			{
				"type": "mount"
			}
		]
	}
}

yozel avatar Nov 05 '21 08:11 yozel

yozel Thanks. It works but it has problems for example /dev/pts will have problem even after the container has been removed. Generically some resources are not designed to be shared - as kernel does not isolate these yet. Or do you have any workaround? maybe bind mount most host dirs to container's rootfs but not these problematic ones?

aeronwang avatar May 17 '24 15:05 aeronwang

I think this is better, but /proc cannot be bind mounted - anyone knows how to bind mount an empty host dir to container's /proc?

This works and no /dev/pts issue (and other potential similiar issues)

{ "ociVersion": "1.0.2-dev", "process": { "terminal": true, "user": { "uid": 1000, "gid": 1001 }, "args": [ "bash" ], "env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "TERM=xterm" ], "cwd": "/", "rlimits": [ { "type": "RLIMIT_NOFILE", "hard": 1024, "soft": 1024 } ], "noNewPrivileges": true }, "root": { "path": "rootfs", "readonly": false }, "hostname": "runc", "mounts": [ { "destination": "/", "type": "rbind", "source": "/", "options": [ "rw", "rbind" ] }, { "destination": "/run", "type": "rbind", "source": "/home/xxx/rootfs-bind/run", "options": [ "rw", "rbind" ] }, { "destination": "/tmp", "type": "rbind", "source": "/home/xxx/rootfs-bind/tmp", "options": [ "rw", "rbind" ] }, { "destination": "/proc", "type": "proc", "source": "proc" }, { "destination": "/dev", "type": "tmpfs", "source": "tmpfs", "options": [ "nosuid", "strictatime", "mode=755", "size=65536k" ] }, { "destination": "/dev/pts", "type": "devpts", "source": "devpts", "options": [ "nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5" ] }, { "destination": "/dev/shm", "type": "tmpfs", "source": "shm", "options": [ "nosuid", "noexec", "nodev", "mode=1777", "size=65536k" ] }, { "destination": "/dev/mqueue", "type": "mqueue", "source": "mqueue", "options": [ "nosuid", "noexec", "nodev" ] }, { "destination": "/sys", "type": "sysfs", "source": "sysfs", "options": [ "nosuid", "noexec", "nodev", "ro" ] }, { "destination": "/sys/fs/cgroup", "type": "cgroup", "source": "cgroup", "options": [ "nosuid", "noexec", "nodev", "relatime", "ro" ] } ], "linux": { "resources": { "devices": [ { "allow": true, "access": "rwm" } ] }, "namespaces": [ { "type": "pid" }, { "type": "network" }, { "type": "ipc" }, { "type": "uts" }, { "type": "mount" } ], "maskedPaths": [ "/proc/acpi", "/proc/asound", "/proc/kcore", "/proc/keys", "/proc/latency_stats", "/proc/timer_list", "/proc/timer_stats", "/proc/sched_debug", "/sys/firmware", "/proc/scsi" ], "readonlyPaths": [ "/proc/bus", "/proc/fs", "/proc/irq", "/proc/sys", "/proc/sysrq-trigger" ] } }

aeronwang avatar May 17 '24 18:05 aeronwang