Sitelet https://github.com/kubernetes/kops/commit/7c5a8e883e0bd695b98aace0cc770232729208ca
Skip to content

Commit 7c5a8e8

Browse files
committed
feat: add gVisor RuntimeClass support for containerd
Add support for running workloads under gVisor (runsc) as a containerd runtime handler, following the existing NVIDIA GPU runtime pattern. gVisor is gated to Debian-family distributions only. The runsc apt package provides both runsc and containerd-shim-runsc-v1. Assisted by Opus 4.6 Signed-off-by: Arnaud Meukam <ameukam@gmail.com>
1 parent d768817 commit 7c5a8e8

17 files changed

Lines changed: 467 additions & 0 deletions

File tree

‎nodeup/pkg/model/containerd.go‎

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ func (b *ContainerdBuilder) Build(c *fi.NodeupModelBuilderContext) error {
9393
return err
9494
}
9595

96+
// If gVisor is enabled, emit the runsc shim config file
97+
if b.InstallGVisorRuntime() {
98+
b.buildGVisorShimConfig(c)
99+
}
100+
96101
if installContainerd {
97102
if err := b.installContainerd(c); err != nil {
98103
return err
@@ -564,6 +569,12 @@ func (b *ContainerdBuilder) buildContainerdConfigV2() (string, error) {
564569
}
565570
}
566571

572+
if b.InstallGVisorRuntime() {
573+
if err := appendGVisorRuntimeConfig(config, []string{"plugins", "io.containerd.grpc.v1.cri", "containerd", "runtimes"}); err != nil {
574+
return "", fmt.Errorf("appending gvisor runtime to v2 containerd config: %w", err)
575+
}
576+
}
577+
567578
if err := applyConfigAdditions(config, containerd.ConfigAdditions); err != nil {
568579
return "", fmt.Errorf("applying ConfigAdditions to v2 containerd config: %w", err)
569580
}
@@ -617,6 +628,12 @@ func (b *ContainerdBuilder) buildContainerdConfigV3() (string, error) {
617628
}
618629
}
619630

631+
if b.InstallGVisorRuntime() {
632+
if err := appendGVisorRuntimeConfig(config, []string{"plugins", "io.containerd.cri.v1.runtime", "containerd", "runtimes"}); err != nil {
633+
return "", fmt.Errorf("appending gvisor runtime to v3 containerd config: %w", err)
634+
}
635+
}
636+
620637
if err := applyConfigAdditions(config, containerd.ConfigAdditions); err != nil {
621638
return "", fmt.Errorf("applying ConfigAdditions to v3 containerd config: %w", err)
622639
}
@@ -691,6 +708,45 @@ func appendNvidiaGPURuntimeConfig(config *toml.Tree, runtimesPath []string) erro
691708
return nil
692709
}
693710

711+
// appendGVisorRuntimeConfig adds the "runsc" runtime entry under runtimesPath.
712+
// runtimesPath is schema-specific so the same helper can serve both v2 and v3 builders.
713+
func appendGVisorRuntimeConfig(config *toml.Tree, runtimesPath []string) error {
714+
gvisorConfig, err := toml.TreeFromMap(
715+
map[string]interface{}{
716+
"runtime_type": "io.containerd.runsc.v1",
717+
},
718+
)
719+
if err != nil {
720+
return err
721+
}
722+
723+
path := make([]string, len(runtimesPath)+1)
724+
copy(path, runtimesPath)
725+
path[len(runtimesPath)] = "runsc"
726+
config.SetPath(path, gvisorConfig)
727+
728+
return nil
729+
}
730+
731+
// buildGVisorShimConfig emits /etc/containerd/runsc.toml, the shim-level
732+
// configuration consumed by containerd-shim-runsc-v1 at container creation.
733+
// See https://gvisor.dev/docs/user_guide/containerd/configuration/
734+
func (b *ContainerdBuilder) buildGVisorShimConfig(c *fi.NodeupModelBuilderContext) {
735+
platform := b.NodeupConfig.GVisor.Platform
736+
if platform == "" {
737+
platform = "systrap"
738+
}
739+
740+
shimConfig, _ := toml.Load("")
741+
shimConfig.SetPath([]string{"runsc_config", "platform"}, platform)
742+
743+
c.AddTask(&nodetasks.File{
744+
Path: "/etc/containerd/runsc.toml",
745+
Contents: fi.NewStringResource(shimConfig.String()),
746+
Type: nodetasks.FileType_File,
747+
})
748+
}
749+
694750
// buildRegistryHosts emits one hosts.toml per RegistryMirrors entry under containerdRegistryDirPath.
695751
// The directory is referenced by registry.config_path in the main containerd config; the
696752
// emit-files-iff-mirrors-non-empty condition here must stay in sync with the registry.config_path

‎nodeup/pkg/model/context.go‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,14 @@ func (c *NodeupModelContext) InstallNvidiaRuntime() bool {
563563
c.GPUVendor == architectures.GPUVendorNvidia
564564
}
565565

566+
// InstallGVisorRuntime returns true if the gVisor (runsc) runtime should be installed.
567+
// gVisor is only supported on Debian-family distributions (Debian, Ubuntu).
568+
func (c *NodeupModelContext) InstallGVisorRuntime() bool {
569+
return c.NodeupConfig.GVisor != nil &&
570+
fi.ValueOf(c.NodeupConfig.GVisor.Enabled) &&
571+
c.Distribution.IsDebianFamily()
572+
}
573+
566574
// CloudProvider returns the cloud provider we are running on
567575
func (c *NodeupModelContext) CloudProvider() kops.CloudProviderID {
568576
return c.BootConfig.CloudProvider

‎nodeup/pkg/model/gvisor.go‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
Copyright The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package model
18+
19+
import (
20+
"k8s.io/kops/upup/pkg/fi"
21+
"k8s.io/kops/upup/pkg/fi/nodeup/nodetasks"
22+
)
23+
24+
// GVisorBuilder installs the gVisor (runsc) sandboxed runtime.
25+
// Only supported on Debian-family distributions.
26+
type GVisorBuilder struct {
27+
*NodeupModelContext
28+
}
29+
30+
var _ fi.NodeupModelBuilder = &GVisorBuilder{}
31+
32+
// Build installs gVisor packages via the upstream apt repository.
33+
func (b *GVisorBuilder) Build(c *fi.NodeupModelBuilderContext) error {
34+
if !b.InstallGVisorRuntime() {
35+
return nil
36+
}
37+
38+
c.AddTask(&nodetasks.AptSource{
39+
Name: "gvisor",
40+
Keyring: "https://gvisor.dev/archive.key",
41+
Sources: []string{
42+
"deb [arch=$(dpkg --print-architecture)] https://storage.googleapis.com/gvisor/releases release main",
43+
},
44+
})
45+
// The runsc package bundles both runsc and containerd-shim-runsc-v1.
46+
c.AddTask(&nodetasks.Package{Name: "runsc"})
47+
48+
return nil
49+
}

‎pkg/apis/kops/containerdconfig.go‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ const (
2626
NvidiaDefaultDriverPackage = "nvidia-driver-535-server"
2727
// NvidiaDevicePluginImage is the Nvidia K8s device plugin container image
2828
NvidiaDevicePluginImage = "nvcr.io/nvidia/k8s-device-plugin:v0.17.3"
29+
// GVisorDefaultPlatform is the default gVisor execution platform.
30+
// systrap uses SECCOMP_RET_TRAP/SIGSYS and works in all environments including VMs.
31+
GVisorDefaultPlatform = "systrap"
2932
)
3033

3134
// ContainerdConfig is the configuration for containerd
@@ -55,6 +58,8 @@ type ContainerdConfig struct {
5558
Version *string `json:"version,omitempty"`
5659
// NvidiaGPU configures the Nvidia GPU runtime.
5760
NvidiaGPU *NvidiaGPUConfig `json:"nvidiaGPU,omitempty"`
61+
// GVisor configures the gVisor (runsc) sandboxed runtime.
62+
GVisor *GVisorConfig `json:"gvisor,omitempty"`
5863
// Runc configures the runc runtime.
5964
Runc *Runc `json:"runc,omitempty"`
6065
// SelinuxEnabled enables SELinux support
@@ -106,3 +111,17 @@ type Runc struct {
106111
// Packages overrides the URL and hash for the packages.
107112
Packages *PackagesConfig `json:"packages,omitempty"`
108113
}
114+
115+
// GVisorConfig configures the gVisor sandboxed container runtime.
116+
// When enabled, kOps installs runsc and containerd-shim-runsc-v1,
117+
// registers the "runsc" runtime handler in containerd, and deploys
118+
// a Kubernetes RuntimeClass named "gvisor".
119+
type GVisorConfig struct {
120+
// Enabled determines if kOps will install the gVisor runtime.
121+
Enabled *bool `json:"enabled,omitempty"`
122+
// Platform is the gVisor execution platform: "systrap" (default, works
123+
// everywhere including VMs) or "kvm" (bare-metal with KVM support).
124+
Platform string `json:"platform,omitempty"`
125+
// Packages overrides the URL and hash for the gVisor packages.
126+
Packages *PackagesConfig `json:"packages,omitempty"`
127+
}

‎pkg/apis/kops/v1alpha2/containerdconfig.go‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ type ContainerdConfig struct {
4848
Version *string `json:"version,omitempty"`
4949
// NvidiaGPU configures the Nvidia GPU runtime.
5050
NvidiaGPU *NvidiaGPUConfig `json:"nvidiaGPU,omitempty"`
51+
// GVisor configures the gVisor (runsc) sandboxed runtime.
52+
GVisor *GVisorConfig `json:"gvisor,omitempty"`
5153
// Runc configures the runc runtime.
5254
Runc *Runc `json:"runc,omitempty"`
5355
// SelinuxEnabled enables SELinux support
@@ -99,3 +101,17 @@ type Runc struct {
99101
// Packages overrides the URL and hash for the packages.
100102
Packages *PackagesConfig `json:"packages,omitempty"`
101103
}
104+
105+
// GVisorConfig configures the gVisor sandboxed container runtime.
106+
// When enabled, kOps installs runsc and containerd-shim-runsc-v1,
107+
// registers the "runsc" runtime handler in containerd, and deploys
108+
// a Kubernetes RuntimeClass named "gvisor".
109+
type GVisorConfig struct {
110+
// Enabled determines if kOps will install the gVisor runtime.
111+
Enabled *bool `json:"enabled,omitempty"`
112+
// Platform is the gVisor execution platform: "systrap" (default, works
113+
// everywhere including VMs) or "kvm" (bare-metal with KVM support).
114+
Platform string `json:"platform,omitempty"`
115+
// Packages overrides the URL and hash for the gVisor packages.
116+
Packages *PackagesConfig `json:"packages,omitempty"`
117+
}

‎pkg/apis/kops/v1alpha2/zz_generated.conversion.go‎

Lines changed: 68 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go‎

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎pkg/apis/kops/v1alpha3/containerdconfig.go‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ type ContainerdConfig struct {
4848
Version *string `json:"version,omitempty"`
4949
// NvidiaGPU configures the Nvidia GPU runtime.
5050
NvidiaGPU *NvidiaGPUConfig `json:"nvidiaGPU,omitempty"`
51+
// GVisor configures the gVisor (runsc) sandboxed runtime.
52+
GVisor *GVisorConfig `json:"gvisor,omitempty"`
5153
// Runc configures the runc runtime.
5254
Runc *Runc `json:"runc,omitempty"`
5355
// SelinuxEnabled enables SELinux support
@@ -99,3 +101,17 @@ type Runc struct {
99101
// Packages overrides the URL and hash for the packages.
100102
Packages *PackagesConfig `json:"packages,omitempty"`
101103
}
104+
105+
// GVisorConfig configures the gVisor sandboxed container runtime.
106+
// When enabled, kOps installs runsc and containerd-shim-runsc-v1,
107+
// registers the "runsc" runtime handler in containerd, and deploys
108+
// a Kubernetes RuntimeClass named "gvisor".
109+
type GVisorConfig struct {
110+
// Enabled determines if kOps will install the gVisor runtime.
111+
Enabled *bool `json:"enabled,omitempty"`
112+
// Platform is the gVisor execution platform: "systrap" (default, works
113+
// everywhere including VMs) or "kvm" (bare-metal with KVM support).
114+
Platform string `json:"platform,omitempty"`
115+
// Packages overrides the URL and hash for the gVisor packages.
116+
Packages *PackagesConfig `json:"packages,omitempty"`
117+
}

0 commit comments

Comments
 (0)