Skip to content

Commit d14bdbc

Browse files
committed
Update gvisor runsc version
- Updates the gvisor addon to use containerd shim v2 - Updates the version of runsc - Auto-installs a gvisor RuntimeClass Issue #4482
1 parent b37d1d2 commit d14bdbc

File tree

11 files changed

+154
-52
lines changed

11 files changed

+154
-52
lines changed

deploy/addons/gvisor/README.md

+17-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
## gVisor Addon
2-
[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.
2+
[gVisor](https://gvisor.dev/), a sandboxed container runtime, allows users to securely run pods with untrusted workloads within Minikube.
33

44
### Starting Minikube
55
gVisor depends on the containerd runtime to run in Minikube.
@@ -17,21 +17,27 @@ To enable this addon, simply run:
1717
$ minikube addons enable gvisor
1818
```
1919

20-
Within one minute, the addon manager should pick up the change and you should see the `gvisor` pod:
20+
Within one minute, the addon manager should pick up the change and you should
21+
see the `gvisor` pod and `gvisor` [Runtime Class](https://kubernetes.io/docs/concepts/containers/runtime-class/):
2122

2223
```
23-
$ kubectl get pod gvisor -n kube-system
24-
NAME READY STATUS RESTARTS AGE
25-
gvisor 1/1 Running 0 3m
24+
$ kubectl get pod,runtimeclass gvisor -n kube-system
25+
NAME READY STATUS RESTARTS AGE
26+
pod/gvisor 1/1 Running 0 2m52s
27+
28+
NAME CREATED AT
29+
runtimeclass.node.k8s.io/gvisor 2019-06-15T04:35:09Z
2630
```
2731

28-
Once the pod has status `Running`, gVisor is enabled in Minikube.
32+
Once the pod has status `Running`, gVisor is enabled in Minikube.
2933

3034
### Running pods in gVisor
31-
To run a pod in gVisor, add this annotation to the Kubernetes yaml:
35+
36+
To run a pod in gVisor, add the `gvisor` runtime class to the Pod spec in your
37+
Kubernetes yaml:
3238

3339
```
34-
io.kubernetes.cri.untrusted-workload: "true"
40+
runtimeClassName: gvisor
3541
```
3642

3743
An example Pod is shown below:
@@ -41,17 +47,15 @@ apiVersion: v1
4147
kind: Pod
4248
metadata:
4349
name: nginx-untrusted
44-
annotations:
45-
io.kubernetes.cri.untrusted-workload: "true"
4650
spec:
51+
runtimeClassName: gvisor
4752
containers:
4853
- name: nginx
4954
image: nginx
5055
```
5156
52-
_Note: this annotation will not be necessary once the RuntimeClass Kubernetes feature is available broadly._
53-
5457
### Disabling gVisor
58+
5559
To disable gVisor, run:
5660
5761
```
@@ -67,4 +71,4 @@ NAME READY STATUS RESTARTS AGE
6771
gvisor 1/1 Terminating 0 5m
6872
```
6973

70-
_Note: Once gVisor is disabled, any pod with the `io.kubernetes.cri.untrusted-workload` annotation will fail with a FailedCreatePodSandBox error._
74+
_Note: Once gVisor is disabled, any pod with the `gvisor` Runtime Class or `io.kubernetes.cri.untrusted-workload` annotation will fail with a FailedCreatePodSandBox error._

deploy/addons/gvisor/gvisor-config.toml

+5-6
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ oom_score = 0
4141
runtime_type = "io.containerd.runtime.v1.linux"
4242
runtime_engine = ""
4343
runtime_root = ""
44-
[plugins.cri.containerd.untrusted_workload_runtime]
45-
runtime_type = "io.containerd.runtime.v1.linux"
46-
runtime_engine = "/usr/local/bin/runsc"
47-
runtime_root = "/run/containerd/runsc"
44+
[plugins.cri.containerd.runtimes.untrusted]
45+
runtime_type = "io.containerd.runsc.v1"
46+
[plugins.cri.containerd.runtimes.runsc]
47+
runtime_type = "io.containerd.runsc.v1"
4848
[plugins.cri.cni]
4949
bin_dir = "/opt/cni/bin"
5050
conf_dir = "/etc/cni/net.d"
@@ -56,7 +56,6 @@ oom_score = 0
5656
[plugins.diff-service]
5757
default = ["walking"]
5858
[plugins.linux]
59-
shim = "gvisor-containerd-shim"
6059
runtime = "runc"
6160
runtime_root = ""
6261
no_shim = false
@@ -66,4 +65,4 @@ oom_score = 0
6665
deletion_threshold = 0
6766
mutation_threshold = 100
6867
schedule_delay = "0s"
69-
startup_delay = "100ms"
68+
startup_delay = "100ms"

deploy/addons/gvisor/gvisor-containerd-shim.toml

-3
This file was deleted.

deploy/addons/gvisor/gvisor-pod.yaml.tmpl

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@
1414

1515
apiVersion: v1
1616
kind: Pod
17-
metadata:
17+
metadata:
1818
name: gvisor
1919
namespace: kube-system
2020
labels:
2121
addonmanager.kubernetes.io/mode: Reconcile
2222
kubernetes.io/minikube-addons: gvisor
23-
spec:
23+
spec:
2424
hostPID: true
25-
containers:
25+
containers:
2626
- name: gvisor
2727
image: {{default "gcr.io/k8s-minikube" .ImageRepository}}/gvisor-addon:latest
2828
securityContext:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright 2018 The Kubernetes Authors All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
apiVersion: node.k8s.io/v1beta1
16+
kind: RuntimeClass
17+
metadata:
18+
name: gvisor
19+
labels:
20+
kubernetes.io/minikube-addons: gvisor
21+
addonmanager.kubernetes.io/mode: Reconcile
22+
handler: runsc

pkg/gvisor/enable.go

+2-12
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,6 @@ func makeGvisorDirs() error {
8080
return errors.Wrap(err, "creating runsc dir")
8181
}
8282

83-
// Make /usr/local/bin to store the runsc binary
84-
fp = filepath.Join(nodeDir, "usr/local/bin")
85-
if err := os.MkdirAll(fp, 0755); err != nil {
86-
return errors.Wrap(err, "creating usr/local/bin dir")
87-
}
88-
8983
// Make /tmp/runsc to also hold logs
9084
fp = filepath.Join(nodeDir, "tmp/runsc")
9185
if err := os.MkdirAll(fp, 0755); err != nil {
@@ -107,13 +101,13 @@ func downloadBinaries() error {
107101

108102
// downloads the gvisor-containerd-shim
109103
func gvisorContainerdShim() error {
110-
dest := filepath.Join(nodeDir, "usr/bin/gvisor-containerd-shim")
104+
dest := filepath.Join(nodeDir, "usr/bin/containerd-shim-runsc-v1")
111105
return downloadFileToDest(constants.GvisorContainerdShimURL, dest)
112106
}
113107

114108
// downloads the runsc binary and returns a path to the binary
115109
func runsc() error {
116-
dest := filepath.Join(nodeDir, "usr/local/bin/runsc")
110+
dest := filepath.Join(nodeDir, "usr/bin/runsc")
117111
return downloadFileToDest(constants.GvisorURL, dest)
118112
}
119113

@@ -159,10 +153,6 @@ func copyConfigFiles() error {
159153
if err := mcnutils.CopyFile(filepath.Join(nodeDir, constants.ContainerdConfigTomlPath), filepath.Join(nodeDir, constants.StoredContainerdConfigTomlPath)); err != nil {
160154
return errors.Wrap(err, "copying default config.toml")
161155
}
162-
log.Print("Copying gvisor-containerd-shim.toml...")
163-
if err := copyAssetToDest(constants.GvisorContainerdShimTargetName, filepath.Join(nodeDir, constants.GvisorContainerdShimTomlPath)); err != nil {
164-
return errors.Wrap(err, "copying gvisor-containerd-shim.toml")
165-
}
166156
log.Print("Copying containerd config.toml with gvisor...")
167157
if err := copyAssetToDest(constants.GvisorConfigTomlTargetName, filepath.Join(nodeDir, constants.ContainerdConfigTomlPath)); err != nil {
168158
return errors.Wrap(err, "copying gvisor version of config.toml")

pkg/minikube/assets/addons.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -314,18 +314,18 @@ var Addons = map[string]*Addon{
314314
"gvisor-pod.yaml",
315315
"0640",
316316
true),
317+
MustBinAsset(
318+
"deploy/addons/gvisor/gvisor-runtimeclass.yaml",
319+
constants.GuestAddonsDir,
320+
"gvisor-runtimeclass.yaml",
321+
"0640",
322+
false),
317323
MustBinAsset(
318324
"deploy/addons/gvisor/gvisor-config.toml",
319325
constants.GvisorFilesPath,
320326
constants.GvisorConfigTomlTargetName,
321327
"0640",
322328
true),
323-
MustBinAsset(
324-
"deploy/addons/gvisor/gvisor-containerd-shim.toml",
325-
constants.GvisorFilesPath,
326-
constants.GvisorContainerdShimTargetName,
327-
"0640",
328-
false),
329329
}, false, "gvisor"),
330330
}
331331

pkg/minikube/constants/constants.go

+2-6
Original file line numberDiff line numberDiff line change
@@ -384,20 +384,16 @@ const (
384384
GvisorFilesPath = "/tmp/gvisor"
385385
// ContainerdConfigTomlPath is the path to the containerd config.toml
386386
ContainerdConfigTomlPath = "/etc/containerd/config.toml"
387-
// GvisorContainerdShimTomlPath is the path to gvisor-containerd-shim.toml
388-
GvisorContainerdShimTomlPath = "/etc/containerd/gvisor-containerd-shim.toml"
389387
// StoredContainerdConfigTomlPath is the path where the default config.toml will be stored
390388
StoredContainerdConfigTomlPath = "/tmp/config.toml"
391389

392390
// GvisorConfigTomlTargetName is the go-bindata target name for the gvisor config.toml
393391
GvisorConfigTomlTargetName = "gvisor-config.toml"
394-
// GvisorContainerdShimTargetName is the go-bindata target name for gvisor-containerd-shim
395-
GvisorContainerdShimTargetName = "gvisor-containerd-shim.toml"
396392

397393
// GvisorContainerdShimURL is the url to download gvisor-containerd-shim
398-
GvisorContainerdShimURL = "https://github.com/google/gvisor-containerd-shim/releases/download/v0.0.1-rc.0/gvisor-containerd-shim-v0.0.1-rc.0.linux-amd64"
394+
GvisorContainerdShimURL = "https://github.com/google/gvisor-containerd-shim/releases/download/v0.0.3/containerd-shim-runsc-v1.linux-amd64"
399395
// GvisorURL is the url to download gvisor
400-
GvisorURL = "https://storage.googleapis.com/gvisor/releases/nightly/2018-12-07/runsc"
396+
GvisorURL = "https://storage.googleapis.com/gvisor/releases/nightly/2019-01-14/runsc"
401397
)
402398

403399
const (

test/integration/containerd_test.go

+84-3
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,57 @@ func TestContainerd(t *testing.T) {
3737
t.Parallel()
3838
}
3939

40+
t.Run("GvisorUntrustedWorkload", testGvisorUntrustedWorkload)
41+
t.Run("GvisorRuntimeClass", testGvisorRuntimeClass)
4042
t.Run("GvisorRestart", testGvisorRestart)
4143
}
4244

45+
func testGvisorUntrustedWorkload(t *testing.T) {
46+
p := profileName(t)
47+
if shouldRunInParallel(t) {
48+
t.Parallel()
49+
}
50+
mk := NewMinikubeRunner(t, p, "--wait=false")
51+
defer mk.TearDown(t)
52+
53+
mk.MustRun("addons enable gvisor", true)
54+
55+
t.Log("waiting for gvisor controller to come up")
56+
if err := waitForGvisorControllerRunning(p); err != nil {
57+
t.Fatalf("waiting for gvisor controller to be up: %v", err)
58+
}
59+
60+
createUntrustedWorkload(t, p)
61+
t.Log("making sure untrusted workload is Running")
62+
if err := waitForUntrustedNginxRunning(p); err != nil {
63+
t.Fatalf("waiting for nginx to be up: %v", err)
64+
}
65+
deleteUntrustedWorkload(t, p)
66+
}
67+
68+
func testGvisorRuntimeClass(t *testing.T) {
69+
p := profileName(t)
70+
if shouldRunInParallel(t) {
71+
t.Parallel()
72+
}
73+
mk := NewMinikubeRunner(t, p, "--wait=false")
74+
defer mk.TearDown(t)
75+
76+
mk.MustRun("addons enable gvisor", true)
77+
78+
t.Log("waiting for gvisor controller to come up")
79+
if err := waitForGvisorControllerRunning(p); err != nil {
80+
t.Fatalf("waiting for gvisor controller to be up: %v", err)
81+
}
82+
83+
createGvisorWorkload(t, p)
84+
t.Log("making sure gvisor workload is Running")
85+
if err := waitForGvisorNginxRunning(p); err != nil {
86+
t.Fatalf("waiting for nginx to be up: %v", err)
87+
}
88+
deleteGvisorWorkload(t, p)
89+
}
90+
4391
func testGvisorRestart(t *testing.T) {
4492
p := profileName(t)
4593
if shouldRunInParallel(t) {
@@ -98,7 +146,24 @@ func deleteUntrustedWorkload(t *testing.T, profile string) {
98146
}
99147
}
100148

101-
// waitForGvisorControllerRunning waits for the gvisor controller pod to be running
149+
func createGvisorWorkload(t *testing.T, profile string) {
150+
kr := util.NewKubectlRunner(t, profile)
151+
gvisorPath := filepath.Join(*testdataDir, "nginx-gvisor.yaml")
152+
t.Log("creating pod with gvisor workload annotation")
153+
if _, err := kr.RunCommand([]string{"replace", "-f", gvisorPath, "--force"}); err != nil {
154+
t.Fatalf("creating gvisor nginx resource: %v", err)
155+
}
156+
}
157+
158+
func deleteGvisorWorkload(t *testing.T, profile string) {
159+
kr := util.NewKubectlRunner(t, profile)
160+
gvisorPath := filepath.Join(*testdataDir, "nginx-gvisor.yaml")
161+
if _, err := kr.RunCommand([]string{"delete", "-f", gvisorPath}); err != nil {
162+
t.Logf("error deleting gvisor nginx resource: %v", err)
163+
}
164+
}
165+
166+
// waitForGvisorControllerRunning waits for the gvisor controller pod to be running.
102167
func waitForGvisorControllerRunning(p string) error {
103168
client, err := kapi.Client(p)
104169
if err != nil {
@@ -112,14 +177,30 @@ func waitForGvisorControllerRunning(p string) error {
112177
return nil
113178
}
114179

115-
// waitForUntrustedNginxRunning waits for the untrusted nginx pod to start running
180+
// waitForUntrustedNginxRunning waits for the untrusted nginx pod to start
181+
// running.
116182
func waitForUntrustedNginxRunning(miniProfile string) error {
117183
client, err := kapi.Client(miniProfile)
118184
if err != nil {
119185
return errors.Wrap(err, "getting kubernetes client")
120186
}
121187

122-
selector := labels.SelectorFromSet(labels.Set(map[string]string{"run": "nginx"}))
188+
selector := labels.SelectorFromSet(labels.Set(map[string]string{"run": "nginx", "untrusted": "true"}))
189+
if err := kapi.WaitForPodsWithLabelRunning(client, "default", selector); err != nil {
190+
return errors.Wrap(err, "waiting for nginx pods")
191+
}
192+
return nil
193+
}
194+
195+
// waitForGvisorNginxRunning waits for the nginx pod with gvisor runtime class
196+
// to start running.
197+
func waitForGvisorNginxRunning(miniProfile string) error {
198+
client, err := kapi.Client(miniProfile)
199+
if err != nil {
200+
return errors.Wrap(err, "getting kubernetes client")
201+
}
202+
203+
selector := labels.SelectorFromSet(labels.Set(map[string]string{"run": "nginx", "runtime": "gvisor"}))
123204
if err := kapi.WaitForPodsWithLabelRunning(client, "default", selector); err != nil {
124205
return errors.Wrap(err, "waiting for nginx pods")
125206
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: nginx-gvisor
5+
labels:
6+
run: nginx
7+
runtime: gvisor
8+
spec:
9+
runtimeClassName: gvisor
10+
containers:
11+
- name: nginx
12+
image: nginx

test/integration/testdata/nginx-untrusted.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ metadata:
44
name: nginx-untrusted
55
labels:
66
run: nginx
7+
untrusted: "true"
78
annotations:
89
io.kubernetes.cri.untrusted-workload: "true"
910
spec:

0 commit comments

Comments
 (0)