Refresh gVisor tests and docs to tell that privilege container is not needed.

Docker container and privileged container can be started w/ a limited
number of capabilities from our experiment.

PiperOrigin-RevId: 704601261
This commit is contained in:
Jing Chen
2024-12-10 01:26:21 -08:00
committed by gVisor bot
parent 95ca82d872
commit 0a0f202662
6 changed files with 67 additions and 51 deletions
@@ -9,13 +9,13 @@ network driver and the bridge network driver are tested and supported.
## How to run Docker in a GKE Sandbox
First, install a GKE cluster (1.29.0 or higher) and deploy a node pool with
gVisor enabled. You can view the full documentation [here][gke-sandbox-docs].
gVisor enabled. You can view the full documentation
[here](https://cloud.google.com/kubernetes-engine/docs/how-to/sandbox-pods#enabling).
Prepare a container image with pre-installed Docker:
```shell
$ cd g3doc/user_guide/tutorials/docker-in-gke-sandbox/
$ docker build -t {registry_url}/docker-in-gvisor:latest .
$ docker build -t docker-in-gvisor images/basic/docker
$ docker push {registry_url}/docker-in-gvisor:latest
```
@@ -1,8 +0,0 @@
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND="noninteractive"
RUN apt-get update && apt-get install -y docker.io
COPY docker-run.sh /usr/local/bin/docker-run.sh
CMD /usr/local/bin/docker-run.sh
@@ -1,25 +0,0 @@
#!/bin/bash
# Copyright 2024 The gVisor Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -xe
test -f /sys/fs/cgroup/devices/tasks || {
mount -t tmpfs cgroups /sys/fs/cgroup
mkdir /sys/fs/cgroup/devices
mount -t cgroup -o devices devices /sys/fs/cgroup/devices
}
exec /usr/bin/dockerd --bridge=none --iptables=false --ip6tables=false "$@"
@@ -6,7 +6,7 @@ spec:
runtimeClassName: gvisor
containers:
- name: docker-in-gvisor
image: avagin/docker-in-gvisor:0.1
image: us-central1-docker.pkg.dev/gvisor-presubmit/gvisor-presubmit-images/basic/docker_x86_64:latest
securityContext:
capabilities:
add: ["all"]
+10 -5
View File
@@ -31,15 +31,17 @@ entry.
First, prepare a container image with pre-installed Docker:
```shell
$ cd images/basic/docker/
$ docker build -t docker-in-gvisor .
$ docker build -t docker-in-gvisor images/basic/docker
```
Since Docker requires root privileges and a full set of capabilities, a gVisor
sandbox needs to be started in privileged mode:
In a gVisor sandbox, Docker containers can be started with a set of capabilities
as `audit_write`, `chown`, `dac_override`, `fowner`, `fsetid`, `kill`, `mknod`,
`net_bind_service`, `net_admin`, `net_raw`, `setfcap`, `setgid`, `setpcap`,
`setuid`, `sys_admin`, `sys_chroot`, `sys_ptrace`. For the simplicity, let's
start the sandbox with all capabilities:
```shell
$ docker run --runtime runsc -d --rm --privileged --name docker-in-gvisor docker-in-gvisor
$ docker run --runtime runsc -d --rm --cap-add all --name docker-in-gvisor docker-in-gvisor
```
Now, we can build and run Docker containers.
@@ -78,3 +80,6 @@ $ docker run -it --rm whalesay "Containers do not contain, but gVisor-s do!"
\____\______/
```
> In the sandbox, we can also run privileged containers by `docker run -it
> --privileged --rm whalesay "Containers do not contain, but gVisor-s do!"`
+53 -9
View File
@@ -339,25 +339,65 @@ func TestStdio(t *testing.T) {
}
}
func dockerInGvisorCapabilities() []string {
return []string{
"audit_write",
"chown",
"dac_override",
"fowner",
"fsetid",
"kill",
"mknod",
"net_admin",
"net_bind_service",
"net_raw",
"setfcap",
"setgid",
"setpcap",
"setuid",
"sys_admin",
"sys_chroot",
"sys_ptrace",
}
}
func TestDockerOverlayWithHostNetwork(t *testing.T) {
testDocker(t, true, true)
testDocker(t, true, true, false)
}
func TestPrivilegedDockerOverlayWithHostNetwork(t *testing.T) {
testDocker(t, true, true, true)
}
func TestDockerOverlay(t *testing.T) {
testDocker(t, true, false)
testDocker(t, true, false, false)
}
func TestPrivilegedDockerOverlay(t *testing.T) {
testDocker(t, true, false, true)
}
func TestDockerWithHostNetwork(t *testing.T) {
testDocker(t, false, true)
testDocker(t, false, true, false)
}
func TestPrivilegedDockerWithHostNetwork(t *testing.T) {
testDocker(t, false, true, true)
}
func TestDocker(t *testing.T) {
// Overlayfs can't be built on top of another overlayfs, so docket has
// to fall back to the vfs driver.
testDocker(t, false, false)
testDocker(t, false, false, false)
}
func testDocker(t *testing.T, overlay, hostNetwork bool) {
func TestPrivilegedDocker(t *testing.T) {
// Overlayfs can't be built on top of another overlayfs, so docket has
// to fall back to the vfs driver.
testDocker(t, false, false, true)
}
func testDocker(t *testing.T, overlay, hostNetwork, startPrivilegedContainer bool) {
if testutil.IsRunningWithHostNet() {
t.Skip("docker doesn't work with hostinet")
}
@@ -367,8 +407,8 @@ func testDocker(t *testing.T, overlay, hostNetwork bool) {
// Start the container.
opts := dockerutil.RunOpts{
Image: "basic/docker",
Privileged: true,
Image: "basic/docker",
CapAdd: dockerInGvisorCapabilities(),
}
if overlay {
opts.Mounts = []mount.Mount{
@@ -403,10 +443,14 @@ func testDocker(t *testing.T, overlay, hostNetwork bool) {
}
break
}
cmd := []string{"docker", "run", "--rm", "alpine", "sh", "-c", "apk add curl && curl -h"}
cmd := []string{"docker", "run", "--rm"}
if hostNetwork {
cmd = []string{"docker", "run", "--network", "host", "--rm", "alpine", "sh", "-c", "apk add curl && curl -h"}
cmd = append(cmd, "--network", "host")
}
if startPrivilegedContainer {
cmd = append(cmd, "--privileged")
}
cmd = append(cmd, "alpine", "sh", "-c", "apk add curl && curl -h")
_, err := d.ExecProcess(ctx, dockerutil.ExecOpts{}, cmd...)
if err != nil {
t.Fatalf("docker exec failed: %v", err)