gvisor icon indicating copy to clipboard operation
gvisor copied to clipboard

Unable to mount unix socket to container

Open capnspacehook opened this issue 1 year ago • 3 comments

Description

Whenever I try to mount a unix socket to a container by creating a bind volume, runsc fails with a fatal error when creating the container: Error response from daemon: OCI runtime start failed: starting container: starting root container: starting sandbox: failed to setupFS: mounting submounts: mount submount "/var/run/docker.sock": failed to mount "/var/run/docker.sock" (type: bind): input/output error, opts: &{{false false false false} false {trans=fd,rfdno=9,wfdno=9,cache=remote_revalidating {/var/run/docker.sock false false}} true}: unknown.

Steps to reproduce

Using this docker compose file:

version: "3"
services:
  watchtower:
    image: containrrr/watchtower
    runtime: runsc
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

Run docker compose up and observe the error.

runsc version

runsc version release-20220815.0
spec: 1.0.2-dev

docker version (if using docker)

Client: Docker Engine - Community
 Version:           20.10.17
 API version:       1.41
 Go version:        go1.17.11
 Git commit:        100c701
 Built:             Mon Jun  6 23:02:46 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.17
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.17.11
  Git commit:       a89b842
  Built:            Mon Jun  6 23:00:51 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.8
  GitCommit:        9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
 runc:
  Version:          1.1.4
  GitCommit:        v1.1.4-0-g5fd4c4d
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

uname

Linux pop-os 5.19.0-76051900-generic #202207312230~1660780566~22.04~9d60db1 SMP PREEMPT_DYNAMIC Thu A x86_64 x86_64 x86_64 GNU/Linux

kubectl (if using Kubernetes)

No response

repo state (if built from source)

No response

runsc debug logs (if available)

runsc-logs.zip

capnspacehook avatar Sep 09 '22 12:09 capnspacehook

I believe runsc blocks unix domain sockets by default. So you need to pass the --fsgofer-host-uds=true flag to runsc if memory serves. Also, by passing a docker socket, it looks to me like you'd be bypassing the runtime protections runsc offers.

https://github.com/google/gvisor/blob/master/runsc/config/config.go#L74-L76

knisbet avatar Sep 10 '22 02:09 knisbet

Thanks for the info, I'll try using that flag. I see via the docs that I can set flags for gvisor globally by modifying /etc/docker/daemon.json, but is it possible to only pass a flag when starting a specific container?

I'm actually not planning on using watchtower, I just used that as a succinct example. What I plan to do is mount the docker socket in an isolated container that will filter and proxy requests going to it. The application that needs access to the docker socket to function only needs read only access, so I'm planning on using another container to enforce that.

I understand that the proxy container can use the docker socket to gain root access on the host if it's compromised, but I figured wrapping it with gvisor couldn't hurt.

capnspacehook avatar Sep 10 '22 03:09 capnspacehook

but is it possible to only pass a flag when starting a specific container?

I think you'd need to setup a second runtime in the docker daemon.json, and then use that runtime from kubernetes. So runtime: runsc -> runtime: runsc-uds type of idea for containers that need unix domain sockets, and will then invoke runsc with that additional flag.

knisbet avatar Sep 11 '22 17:09 knisbet

Correct, you can configure a second runtime with docker/K8s and use it for the container you need socket access. You could also set OCI annotations to set flags to individual containers, but there is no way to set annotations with docker AFAIK. This can be done with K8s or calling runsc manually.

The annotation format is like this: dev.gvisor.flag.<flag-name>: <value>

Here is an example in K8s to enable debug in a single pod:

metadata:
  annotations:
    dev.gvisor.flag.debug-log: "/tmp/runsc/sandbox-%ID/"
    dev.gvisor.flag.debug: "true"
    dev.gvisor.flag.strace: "true"

Note: it requires the runtime to be configured with --allow-flag-override.

fvoznika avatar Oct 05 '22 23:10 fvoznika