Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable gvisor addon in minikube #3399

Merged
merged 27 commits into from
Dec 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
04c1215
Add integration test to make sure minikube starts and stops with cont…
Dec 3, 2018
01ad85e
Skip testing containerd if using none driver
Dec 3, 2018
8c7290f
add newline
Dec 3, 2018
e385449
Fixed imports
Dec 3, 2018
40ad9e7
Add skip message when using none driver and containerd
Dec 3, 2018
85a4b8b
Enable gvisor addon in minikube
Dec 4, 2018
f885f4b
Added doc for enabling gvisor in minikube
Dec 4, 2018
ac963e2
Code review comments
Dec 4, 2018
c894943
Simplify gvisor and check for containerd runtime
Dec 4, 2018
f9915ac
small improvements
Dec 4, 2018
81948f0
Merge branch 'integration' of github.com:priyawadhwa/minikube into gv…
Dec 5, 2018
4a8de41
Add gvisor integration test
Dec 5, 2018
fd1f375
Fixed merge conflict
Dec 5, 2018
7bee870
Show gvisor pod logs upon test failure
Dec 5, 2018
765cc93
Additional logs
Dec 5, 2018
6e6020f
Code review comments and added logs
Dec 5, 2018
1c01497
Remove default runsc debug as it's too verbose
Dec 5, 2018
830f8f8
change iso url
Dec 6, 2018
2ec2e53
More logs
Dec 6, 2018
a3cb54c
Code review comments and additional logs
Dec 6, 2018
420eb32
Merge branch 'master' of github.com:kubernetes/minikube into gvisoraddon
Dec 6, 2018
0e4a28c
delete minikube in test before starting with containerd
Dec 6, 2018
c976e11
delete after finishing up containerd
Dec 6, 2018
1073ea0
Add minikube User-Agent to requests for shim and runsc
Dec 6, 2018
af6d30b
Only delete minikube if there is already one running
Dec 6, 2018
fdfa42a
Merge branch 'master' of github.com:kubernetes/minikube into gvisoraddon
Dec 7, 2018
c7e5341
update gvisor url
Dec 7, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,18 @@ storage-provisioner-image: out/storage-provisioner
push-storage-provisioner-image: storage-provisioner-image
gcloud docker -- push $(REGISTRY)/storage-provisioner:$(STORAGE_PROVISIONER_TAG)

.PHONY: out/gvisor-addon
out/gvisor-addon:
GOOS=linux CGO_ENABLED=0 go build -o $@ cmd/gvisor/gvisor.go

.PHONY: gvisor-addon-image
gvisor-addon-image: out/gvisor-addon
docker build -t $(REGISTRY)/gvisor-addon:latest -f deploy/gvisor/Dockerfile .

.PHONY: push-gvisor-addon-image
push-gvisor-addon-image: gvisor-addon-image
gcloud docker -- push $(REGISTRY)/gvisor-addon:latest

.PHONY: release-iso
release-iso: minikube_iso checksum
gsutil cp out/minikube.iso gs://$(ISO_BUCKET)/minikube-$(ISO_VERSION).iso
Expand Down
31 changes: 31 additions & 0 deletions cmd/gvisor/gvisor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Copyright 2018 The Kubernetes Authors All rights reserved.

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.
*/

package main

import (
"log"
"os"

"k8s.io/minikube/pkg/gvisor"
)

func main() {
if err := gvisor.Enable(); err != nil {
log.Print(err)
os.Exit(1)
}
}
6 changes: 6 additions & 0 deletions cmd/minikube/cmd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@ var settings = []Setting{
validations: []setFn{IsValidAddon},
callbacks: []setFn{EnableOrDisableAddon},
},
{
name: "gvisor",
set: SetBool,
validations: []setFn{IsValidAddon, IsContainerdRuntime},
callbacks: []setFn{EnableOrDisableAddon},
},
{
name: "hyperv-virtual-switch",
set: SetString,
Expand Down
30 changes: 26 additions & 4 deletions cmd/minikube/cmd/config/validations.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ package config

import (
"fmt"
"github.com/docker/go-units"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/constants"
"net"
"net/url"
"os"
"strconv"
"strings"

"github.com/docker/go-units"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
)

func IsValidDriver(string, driver string) error {
Expand Down Expand Up @@ -125,3 +127,23 @@ func IsValidAddon(name string, val string) error {
}
return errors.Errorf("Cannot enable/disable invalid addon %s", name)
}

func IsContainerdRuntime(_, _ string) error {
config, err := config.Load()
if err != nil {
return fmt.Errorf("error getting cluster config: %v", err)
}
if config.KubernetesConfig.ContainerRuntime != constants.ContainerdRuntime {
return fmt.Errorf(`This addon can only be enabled with the containerd runtime backend.

To enable this backend, please first stop minikube with:

minikube stop

and then start minikube again with the following flags:

minikube start --container-runtime=containerd --docker-opt containerd=/var/run/containerd/containerd.sock --network-plugin=cni`)
}

return nil
}
71 changes: 71 additions & 0 deletions deploy/addons/gvisor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
## gVisor Addon
[gVisor](https://github.com/google/gvisor/blob/master/README.md), a sandboxed container runtime, allows users to securely run pods with untrusted workloads within Minikube.

### Starting Minikube
gVisor depends on the containerd runtime to run in Minikube.
When starting minikube, specify the following flags, along with any additional desired flags:

```shell
$ minikube start --container-runtime=containerd \
--docker-opt containerd=/var/run/containerd/containerd.sock \
--network-plugin=cni
```

### Enabling gVisor
To enable this addon, simply run:

```
$ minikube addons enable gvisor
```

Within one minute, the addon manager should pick up the change and you should see the `gvisor` pod:

```
$ kubectl get pod gvisor -n kube-system
NAME READY STATUS RESTARTS AGE
gvisor 1/1 Running 0 3m
```

Once the pod has status `Running`, gVisor is enabled in Minikube.

### Running pods in gVisor
To run a pod in gVisor, add this annotation to the Kubernetes yaml:

```
io.kubernetes.cri.untrusted-workload: "true"
priyawadhwa marked this conversation as resolved.
Show resolved Hide resolved
```

An example Pod is shown below:

```yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-untrusted
annotations:
io.kubernetes.cri.untrusted-workload: "true"
spec:
containers:
- name: nginx
image: nginx
```

_Note: this annotation will not be necessary once the RuntimeClass Kubernetes feature is available broadly._

### Disabling gVisor
To disable gVisor, run:

```
$ minikube addons disable gvisor
```

Within one minute, the addon manager should pick up the change.
Once the `gvisor` pod has status `Terminating`, or has been deleted, the gvisor addon should be disabled.

```
$ kubectl get pod gvisor -n kube-system
NAME READY STATUS RESTARTS AGE
gvisor 1/1 Terminating 0 5m
```

_Note: Once gVisor is disabled, any pod with the `io.kubernetes.cri.untrusted-workload` annotation will fail with a FailedCreatePodSandBox error._
priyawadhwa marked this conversation as resolved.
Show resolved Hide resolved
69 changes: 69 additions & 0 deletions deploy/addons/gvisor/gvisor-config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
root = "/var/lib/containerd"
state = "/run/containerd"
oom_score = 0

[grpc]
address = "/run/containerd/containerd.sock"
uid = 0
gid = 0
max_recv_message_size = 16777216
max_send_message_size = 16777216

[debug]
address = ""
uid = 0
gid = 0
level = ""

[metrics]
address = ""
grpc_histogram = false

[cgroup]
path = ""

[plugins]
[plugins.cgroups]
no_prometheus = false
[plugins.cri]
stream_server_address = ""
stream_server_port = "10010"
enable_selinux = false
sandbox_image = "k8s.gcr.io/pause:3.1"
stats_collect_period = 10
systemd_cgroup = false
enable_tls_streaming = false
max_container_log_line_size = 16384
[plugins.cri.containerd]
snapshotter = "overlayfs"
no_pivot = true
[plugins.cri.containerd.default_runtime]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = ""
runtime_root = ""
[plugins.cri.containerd.untrusted_workload_runtime]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = "/usr/local/bin/runsc"
runtime_root = "/run/containerd/runsc"
[plugins.cri.cni]
bin_dir = "/opt/cni/bin"
conf_dir = "/etc/cni/net.d"
conf_template = ""
[plugins.cri.registry]
[plugins.cri.registry.mirrors]
[plugins.cri.registry.mirrors."docker.io"]
endpoint = ["https://registry-1.docker.io"]
[plugins.diff-service]
default = ["walking"]
[plugins.linux]
shim = "gvisor-containerd-shim"
runtime = "runc"
runtime_root = ""
no_shim = false
shim_debug = true
[plugins.scheduler]
pause_threshold = 0.02
deletion_threshold = 0
mutation_threshold = 100
schedule_delay = "0s"
startup_delay = "100ms"
3 changes: 3 additions & 0 deletions deploy/addons/gvisor/gvisor-containerd-shim.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
runc_shim = "/bin/containerd-shim"
[runsc_config]
priyawadhwa marked this conversation as resolved.
Show resolved Hide resolved
user-log="/tmp/runsc/user-log-%ID%.log"
72 changes: 72 additions & 0 deletions deploy/addons/gvisor/gvisor-pod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Copyright 2018 The Kubernetes Authors All rights reserved.
#
# 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.

apiVersion: v1
kind: Pod
metadata:
name: gvisor
namespace: kube-system
labels:
addonmanager.kubernetes.io/mode: Reconcile
kubernetes.io/minikube-addons: gvisor
spec:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Consider setting terminationGracePeriodSeconds to something sane but less than 30s (an upper bound for what the preStop hook should take to run). AFAICT deleting the pod will take the full 30s since we are just sleeping for 1y

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up removing the prestop hook because it wasn't consistently running without errors; I've changed the code to intercept the SIGTERM kill signal and disable gvisor then.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. that should work

hostPID: true
containers:
- name: gvisor
image: gcr.io/k8s-minikube/gvisor-addon:latest
securityContext:
privileged: true
volumeMounts:
- mountPath: /node/
name: node
- mountPath: /usr/libexec/sudo
name: sudo
- mountPath: /var/run
name: varrun
- mountPath: /usr/bin
name: usrbin
- mountPath: /usr/lib
name: usrlib
- mountPath: /bin
name: bin
- mountPath: /tmp/gvisor
name: gvisor
env:
- name: PATH
value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/node/bin
- name: SYSTEMD_IGNORE_CHROOT
value: "yes"
volumes:
- name: node
hostPath:
path: /
- name: sudo
hostPath:
path: /usr/libexec/sudo
- name: varrun
hostPath:
path: /var/run
- name: usrlib
hostPath:
path: /usr/lib
- name: usrbin
hostPath:
path: /usr/bin
- name: bin
hostPath:
path: /bin
- name: gvisor
hostPath:
path: /tmp/gvisor
restartPolicy: Never
20 changes: 20 additions & 0 deletions deploy/gvisor/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2016 The Kubernetes Authors All rights reserved.
#
# 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.

FROM ubuntu:18.04
RUN apt-get update && \
apt-get install -y kmod gcc wget xz-utils libc6-dev bc libelf-dev bison flex openssl libssl-dev libidn2-0 sudo libcap2 && \
rm -rf /var/lib/apt/lists/*
COPY out/gvisor-addon /gvisor-addon
CMD ["/gvisor-addon"]
1 change: 1 addition & 0 deletions docs/addons.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ The currently supported addons include:
* [Freshpod](https://github.com/GoogleCloudPlatform/freshpod)
* [nvidia-driver-installer](https://github.com/GoogleCloudPlatform/container-engine-accelerators/tree/master/nvidia-driver-installer/minikube)
* [nvidia-gpu-device-plugin](https://github.com/GoogleCloudPlatform/container-engine-accelerators/tree/master/cmd/nvidia_gpu)
* [gvisor](../deploy/addons/gvisor/README.md)

If you would like to have minikube properly start/restart custom addons, place the addon(s) you wish to be launched with minikube in the `.minikube/addons` directory. Addons in this folder will be moved to the minikube VM and launched each time minikube is started/restarted.

Expand Down
Loading