Skip to content

Commit 5fa6e62

Browse files
committed
runtime/nodeinstaller: add insecure platform variants
1 parent 51d7176 commit 5fa6e62

17 files changed

Lines changed: 630 additions & 27 deletions

File tree

internal/kuberesource/parts.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ func ContrastRuntimeClass(platform platforms.Platform) (*RuntimeClassConfig, err
2828

2929
// Consists of the default VM memory, 70MiB for the Kata shim and 100MiB for qemu overhead.
3030
memoryOverhead := platforms.DefaultMemoryInMebiBytes(platform) + 170
31+
if platforms.IsInsecure(platform) && platforms.IsGPU(platform) {
32+
// On insecure (non-CC) GPU platforms, iommufd VFIO passthrough pins guest
33+
// memory and allocates IOMMU page tables that are charged to the pod's
34+
// cgroup. On CC platforms, TDX manages this memory outside the cgroup.
35+
// (in the kernel / TDX module memory)
36+
// Add extra headroom to avoid OOM kills. 512MB should suffice for VMs up
37+
// to ~256GB of memory, which is our current limit on TDX as well.
38+
memoryOverhead += 512
39+
}
3140

3241
r := RuntimeClass(runtimeHandler).
3342
WithHandler(runtimeHandler).

internal/manifest/runtimehandler.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,28 @@ func RuntimeHandler(platform platforms.Platform) (string, error) {
3333
// PlatformFromHandler extracts the platform from the runtime handler name.
3434
func PlatformFromHandler(handler string) (platforms.Platform, error) {
3535
rest, found := strings.CutPrefix(handler, "contrast-cc-")
36+
isInsecure := false
37+
if !found {
38+
rest, found = strings.CutPrefix(handler, "contrast-insecure-")
39+
isInsecure = true
40+
}
3641
if !found {
3742
return platforms.Unknown, fmt.Errorf("invalid handler name: %s", handler)
3843
}
3944

4045
parts := strings.Split(rest, "-")
41-
if len(parts) != 4 && len(parts) != 5 {
46+
if len(parts) < 3 || len(parts) > 5 {
4247
return platforms.Unknown, fmt.Errorf("invalid handler name: %s", handler)
4348
}
4449

4550
rawPlatform := strings.Join(parts[:len(parts)-1], "-")
51+
if isInsecure {
52+
if before, ok := strings.CutSuffix(rawPlatform, "-gpu"); ok {
53+
rawPlatform = before + "-insecure-gpu"
54+
} else {
55+
rawPlatform += "-insecure"
56+
}
57+
}
4658

4759
platform, err := platforms.FromString(rawPlatform)
4860
if err != nil {

internal/platforms/platforms.go

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,18 @@ const (
2424
MetalQEMUSNPGPU
2525
// MetalQEMUTDXGPU is the generic platform for bare-metal TDX deployments with GPU passthrough.
2626
MetalQEMUTDXGPU
27+
// MetalQEMUInsecure is the platform for bare-metal deployments with a non-CC runtime class.
28+
MetalQEMUInsecure
29+
// MetalQEMUInsecureGPU is the platform for bare-metal deployments with GPU passthrough and a non-CC runtime class.
30+
MetalQEMUInsecureGPU
2731
)
2832

2933
// All returns a list of all available platforms.
3034
func All() []Platform {
31-
return []Platform{MetalQEMUSNP, MetalQEMUTDX, MetalQEMUSNPGPU, MetalQEMUTDXGPU}
35+
return []Platform{
36+
MetalQEMUSNP, MetalQEMUTDX, MetalQEMUSNPGPU, MetalQEMUTDXGPU,
37+
MetalQEMUInsecure, MetalQEMUInsecureGPU,
38+
}
3239
}
3340

3441
// AllStrings returns a list of all available platforms as strings.
@@ -51,11 +58,28 @@ func (p Platform) String() string {
5158
return "Metal-QEMU-TDX"
5259
case MetalQEMUTDXGPU:
5360
return "Metal-QEMU-TDX-GPU"
61+
case MetalQEMUInsecure:
62+
return "Metal-QEMU-Insecure"
63+
case MetalQEMUInsecureGPU:
64+
return "Metal-QEMU-Insecure-GPU"
5465
default:
5566
return "Unknown"
5667
}
5768
}
5869

70+
// InsecureVariant returns the insecure (non-CC) variant of the
71+
// platform, or Unknown if there is no such variant.
72+
func (p Platform) InsecureVariant() Platform {
73+
switch p {
74+
case MetalQEMUSNP, MetalQEMUTDX:
75+
return MetalQEMUInsecure
76+
case MetalQEMUSNPGPU, MetalQEMUTDXGPU:
77+
return MetalQEMUInsecureGPU
78+
default:
79+
return Unknown
80+
}
81+
}
82+
5983
// MarshalJSON marshals a Platform type to a JSON string.
6084
func (p Platform) MarshalJSON() ([]byte, error) {
6185
return fmt.Appendf(nil, `"%s"`, p.String()), nil
@@ -99,6 +123,10 @@ func FromString(s string) (Platform, error) {
99123
return MetalQEMUTDX, nil
100124
case "metal-qemu-tdx-gpu":
101125
return MetalQEMUTDXGPU, nil
126+
case "metal-qemu-insecure":
127+
return MetalQEMUInsecure, nil
128+
case "metal-qemu-insecure-gpu":
129+
return MetalQEMUInsecureGPU, nil
102130
default:
103131
return Unknown, fmt.Errorf("unknown platform: %s", s)
104132
}
@@ -125,6 +153,10 @@ func FromRuntimeClassString(s string) (Platform, error) {
125153
return MetalQEMUTDXGPU, nil
126154
case strings.HasPrefix(s, "contrast-cc-metal-qemu-tdx"):
127155
return MetalQEMUTDX, nil
156+
case strings.HasPrefix(s, "contrast-insecure-metal-qemu-gpu"):
157+
return MetalQEMUInsecureGPU, nil
158+
case strings.HasPrefix(s, "contrast-insecure-metal-qemu"):
159+
return MetalQEMUInsecure, nil
128160
default:
129161
return Unknown, fmt.Errorf("unknown platform: %s", s)
130162
}
@@ -133,7 +165,7 @@ func FromRuntimeClassString(s string) (Platform, error) {
133165
// DefaultMemoryInMebiBytes returns the desired VM overhead for the given platform.
134166
func DefaultMemoryInMebiBytes(p Platform) int {
135167
switch p {
136-
case MetalQEMUSNPGPU, MetalQEMUTDXGPU:
168+
case MetalQEMUSNPGPU, MetalQEMUTDXGPU, MetalQEMUInsecureGPU:
137169
// Guest components contribute around 600MiB with GPU enabled.
138170
return 1024
139171
default:
@@ -144,6 +176,16 @@ func DefaultMemoryInMebiBytes(p Platform) int {
144176
}
145177
}
146178

179+
// IsInsecure returns true if the platform is an insecure (non-CC) platform.
180+
func IsInsecure(p Platform) bool {
181+
switch p {
182+
case MetalQEMUInsecure, MetalQEMUInsecureGPU:
183+
return true
184+
default:
185+
return false
186+
}
187+
}
188+
147189
// IsSNP returns true if the platform is a SEV-SNP platform.
148190
func IsSNP(p Platform) bool {
149191
switch p {
@@ -167,7 +209,7 @@ func IsTDX(p Platform) bool {
167209
// IsGPU returns true if the platform supports GPUs.
168210
func IsGPU(p Platform) bool {
169211
switch p {
170-
case MetalQEMUSNPGPU, MetalQEMUTDXGPU:
212+
case MetalQEMUSNPGPU, MetalQEMUTDXGPU, MetalQEMUInsecureGPU:
171213
return true
172214
default:
173215
return false
@@ -177,7 +219,8 @@ func IsGPU(p Platform) bool {
177219
// IsQEMU returns true if the platform uses QEMU as the hypervisor.
178220
func IsQEMU(p Platform) bool {
179221
switch p {
180-
case MetalQEMUSNP, MetalQEMUSNPGPU, MetalQEMUTDX, MetalQEMUTDXGPU:
222+
case MetalQEMUSNP, MetalQEMUSNPGPU, MetalQEMUTDX, MetalQEMUTDXGPU,
223+
MetalQEMUInsecure, MetalQEMUInsecureGPU:
181224
return true
182225
default:
183226
return false
@@ -191,6 +234,8 @@ func (p Platform) WithGPU() Platform {
191234
return MetalQEMUSNPGPU
192235
case MetalQEMUTDX, MetalQEMUTDXGPU:
193236
return MetalQEMUTDXGPU
237+
case MetalQEMUInsecure, MetalQEMUInsecureGPU:
238+
return MetalQEMUInsecureGPU
194239
default:
195240
return Unknown
196241
}

justfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ node-installer platform=default_platform:
5858
#!/usr/bin/env bash
5959
set -euo pipefail
6060
case {{ platform }} in
61-
"Metal-QEMU-SNP"|"Metal-QEMU-TDX")
61+
"Metal-QEMU-SNP"|"Metal-QEMU-TDX"|"Metal-QEMU-Insecure")
6262
just push "node-installer-kata"
6363
;;
64-
"Metal-QEMU-SNP-GPU"|"Metal-QEMU-TDX-GPU")
64+
"Metal-QEMU-SNP-GPU"|"Metal-QEMU-TDX-GPU"|"Metal-QEMU-Insecure-GPU")
6565
just push "node-installer-kata-gpu"
6666
;;
6767
*)

nodeinstaller/internal/containerdconfig/config.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,12 @@ func ContrastRuntime(baseDir string, platform platforms.Platform) (Runtime, erro
144144
PrivilegedWithoutHostDevices: true,
145145
}
146146

147-
switch {
148-
case platforms.IsTDX(platform):
147+
switch platform {
148+
case platforms.MetalQEMUTDX, platforms.MetalQEMUTDXGPU:
149149
cfg.Options = map[string]any{
150150
"ConfigPath": filepath.Join(baseDir, "etc", "configuration-qemu-tdx.toml"),
151151
}
152-
case platforms.IsSNP(platform):
152+
case platforms.MetalQEMUSNP, platforms.MetalQEMUSNPGPU, platforms.MetalQEMUInsecure, platforms.MetalQEMUInsecureGPU:
153153
cfg.Options = map[string]any{
154154
"ConfigPath": filepath.Join(baseDir, "etc", "configuration-qemu-snp.toml"),
155155
}

nodeinstaller/internal/kataconfig/config.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,28 @@ func KataRuntimeConfig(
3030
return nil, fmt.Errorf("failed to unmarshal kata runtime configuration: %w", err)
3131
}
3232
config.Hypervisor["qemu"]["firmware"] = filepath.Join(baseDir, "tdx", "share", "OVMF.fd")
33-
case platforms.IsSNP(platform):
33+
case platforms.IsSNP(platform) || platforms.IsInsecure(platform):
3434
if err := toml.Unmarshal([]byte(kataBareMetalQEMUSNPBaseConfig), &config); err != nil {
3535
return nil, fmt.Errorf("failed to unmarshal kata runtime configuration: %w", err)
3636
}
3737

38-
for _, productLine := range []string{"_Milan", "_Genoa"} {
39-
for _, annotationType := range []string{"snp_id_block", "snp_id_auth", "snp_guest_policy"} {
40-
customContrastAnnotations = append(customContrastAnnotations, annotationType+productLine)
38+
if !platforms.IsInsecure(platform) {
39+
for _, productLine := range []string{"_Milan", "_Genoa"} {
40+
for _, annotationType := range []string{"snp_id_block", "snp_id_auth", "snp_guest_policy"} {
41+
customContrastAnnotations = append(customContrastAnnotations, annotationType+productLine)
42+
}
4143
}
4244
}
4345

4446
config.Hypervisor["qemu"]["firmware"] = filepath.Join(baseDir, "snp", "share", "OVMF.fd")
4547
default:
4648
return nil, fmt.Errorf("unsupported platform: %s", platform)
4749
}
50+
// Disable confidential computing features for insecure platforms.
51+
if platforms.IsInsecure(platform) {
52+
config.Hypervisor["qemu"]["confidential_guest"] = false
53+
config.Hypervisor["qemu"]["sev_snp_guest"] = false
54+
}
4855
if debug {
4956
config.Agent["kata"]["enable_debug"] = true
5057
config.Agent["kata"]["debug_console_enabled"] = true

nodeinstaller/internal/kataconfig/config_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ func TestKataRuntimeConfig(t *testing.T) {
3434
changeSnpFields: false,
3535
want: string(expectedConfMetalQEMUTDXGPU),
3636
},
37+
platforms.MetalQEMUInsecure: {
38+
changeSnpFields: true,
39+
want: string(expectedConfMetalQEMUInsecure),
40+
},
41+
platforms.MetalQEMUInsecureGPU: {
42+
changeSnpFields: true,
43+
want: string(expectedConfMetalQEMUInsecureGPU),
44+
},
3745
}
3846
for platform, tc := range testCases {
3947
t.Run(platform.String(), func(t *testing.T) {

nodeinstaller/internal/kataconfig/runtime_go_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,8 @@ var (
1616
expectedConfMetalQEMUSNPGPU []byte
1717
//go:embed testdata/runtime-go/expected-configuration-qemu-tdx-gpu.toml
1818
expectedConfMetalQEMUTDXGPU []byte
19+
//go:embed testdata/runtime-go/expected-configuration-qemu-insecure.toml
20+
expectedConfMetalQEMUInsecure []byte
21+
//go:embed testdata/runtime-go/expected-configuration-qemu-insecure-gpu.toml
22+
expectedConfMetalQEMUInsecureGPU []byte
1923
)

nodeinstaller/internal/kataconfig/runtime_rs_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,8 @@ var (
1616
expectedConfMetalQEMUSNPGPU []byte
1717
//go:embed testdata/runtime-rs/expected-configuration-qemu-tdx-gpu.toml
1818
expectedConfMetalQEMUTDXGPU []byte
19+
//go:embed testdata/runtime-rs/expected-configuration-qemu-insecure.toml
20+
expectedConfMetalQEMUInsecure []byte
21+
//go:embed testdata/runtime-rs/expected-configuration-qemu-insecure-gpu.toml
22+
expectedConfMetalQEMUInsecureGPU []byte
1923
)
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
[hypervisor]
2+
[hypervisor.qemu]
3+
block_device_aio = 'threads'
4+
block_device_cache_direct = false
5+
block_device_cache_noflush = false
6+
block_device_cache_set = false
7+
block_device_driver = 'virtio-scsi'
8+
block_device_logical_sector_size = 0
9+
block_device_physical_sector_size = 0
10+
cold_plug_vfio = 'root-port'
11+
confidential_guest = false
12+
contrast_imagepuller_config = ''
13+
cpu_features = 'pmu=off'
14+
default_bridges = 1
15+
default_maxmemory = 0
16+
default_maxvcpus = 0
17+
default_memory = 1024
18+
default_vcpus = 1
19+
disable_block_device_use = true
20+
disable_guest_selinux = true
21+
disable_image_nvdimm = true
22+
disable_nesting_checks = true
23+
disable_selinux = false
24+
disable_vhost_net = false
25+
enable_annotations = ['cc_init_data']
26+
enable_debug = false
27+
enable_guest_swap = false
28+
enable_hugepages = false
29+
enable_iommu = false
30+
enable_iommu_platform = false
31+
enable_iothreads = false
32+
enable_mem_prealloc = false
33+
enable_numa = false
34+
enable_vhost_user_store = false
35+
enable_virtio_mem = false
36+
entropy_source = '/dev/urandom'
37+
file_mem_backend = ''
38+
firmware = '/snp/share/OVMF.fd'
39+
firmware_volume = ''
40+
guest_hook_path = ''
41+
guest_memory_dump_paging = false
42+
guest_memory_dump_path = ''
43+
image = '/share/kata-containers.img'
44+
indep_iothreads = 0
45+
initrd = '/share/kata-initrd.zst'
46+
kernel = '/share/kata-kernel'
47+
kernel_params = ''
48+
kernel_verity_params = ''
49+
machine_accelerators = ''
50+
machine_type = 'q35'
51+
memory_offset = 0
52+
memory_slots = 10
53+
msize_9p = 8192
54+
numa_mapping = []
55+
path = '/bin/qemu-system-x86_64'
56+
pcie_root_port = 0
57+
pflashes = []
58+
reclaim_guest_freed_memory = false
59+
rootfs_type = 'erofs'
60+
rootless = false
61+
rx_rate_limiter_max_rate = 0
62+
seccompsandbox = ''
63+
sev_snp_guest = false
64+
shared_fs = 'none'
65+
snp_guest_policy = 196608
66+
snp_id_auth = ''
67+
snp_id_block = ''
68+
tx_rate_limiter_max_rate = 0
69+
use_legacy_serial = false
70+
valid_entropy_sources = ['/dev/urandom', '/dev/random', '']
71+
valid_file_mem_backends = ['']
72+
valid_hypervisor_paths = ['/bin/qemu-system-x86_64']
73+
valid_vhost_user_store_paths = ['/var/run/kata-containers/vhost-user']
74+
valid_virtio_fs_daemon_paths = ['/opt/kata/libexec/virtiofsd']
75+
vhost_user_reconnect_timeout_sec = 0
76+
vhost_user_store_path = '/var/run/kata-containers/vhost-user'
77+
virtio_fs_cache = 'auto'
78+
virtio_fs_cache_size = 0
79+
virtio_fs_daemon = '/opt/kata/libexec/virtiofsd'
80+
virtio_fs_extra_args = ['--thread-pool-size=1', '--announce-submounts']
81+
virtio_fs_queue_size = 1024
82+
83+
[agent]
84+
[agent.kata]
85+
debug_console_enabled = false
86+
dial_timeout = 600
87+
enable_debug = false
88+
enable_tracing = false
89+
kernel_modules = []
90+
launch_process_timeout = 6
91+
92+
[factory]
93+
enable_template = false
94+
template_path = '/run/vc/vm/template'
95+
vm_cache_endpoint = '/var/run/kata-containers/cache.sock'
96+
vm_cache_number = 0
97+
98+
[runtime]
99+
create_container_timeout = 600
100+
dan_conf = '/run/kata-containers/dans'
101+
disable_guest_empty_dir = false
102+
disable_guest_seccomp = true
103+
disable_new_netns = false
104+
emptydir_mode = 'shared-fs'
105+
enable_debug = false
106+
enable_pprof = false
107+
enable_tracing = false
108+
enable_vcpus_pinning = false
109+
experimental = []
110+
experimental_force_guest_pull = true
111+
guest_selinux_label = ''
112+
internetworking_model = 'tcfilter'
113+
jaeger_endpoint = ''
114+
jaeger_password = ''
115+
jaeger_user = ''
116+
kubelet_root_dir = '/var/lib/kubelet'
117+
pod_resource_api_sock = '/var/lib/kubelet/pod-resources/kubelet.sock'
118+
sandbox_bind_mounts = []
119+
sandbox_cgroup_only = true
120+
static_sandbox_resource_mgmt = true
121+
vfio_mode = 'guest-kernel'

0 commit comments

Comments
 (0)