Skip to content

Commit 9f047ca

Browse files
committed
runtime/nodeinstaller: add insecure platform variants
1 parent 8968c98 commit 9f047ca

13 files changed

Lines changed: 381 additions & 29 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: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,30 +39,39 @@ func KataRuntimeConfig(
3939
) (*Config, error) {
4040
var customContrastAnnotations []string
4141
var config Config
42-
switch {
43-
case platforms.IsTDX(platform):
42+
switch platform {
43+
case platforms.MetalQEMUTDX, platforms.MetalQEMUTDXGPU:
4444
if err := toml.Unmarshal([]byte(kataBareMetalQEMUTDXBaseConfig), &config); err != nil {
4545
return nil, fmt.Errorf("failed to unmarshal kata runtime configuration: %w", err)
4646
}
4747
config.Hypervisor["qemu"]["firmware"] = filepath.Join(baseDir, "tdx", "share", "OVMF.fd")
4848
// We set up dm_verity in the system NixOS config.
4949
// Doing so again here prevents VM boots.
5050
config.Hypervisor["qemu"]["kernel_verity_params"] = ""
51-
case platforms.IsSNP(platform):
51+
case platforms.MetalQEMUSNP, platforms.MetalQEMUSNPGPU, platforms.MetalQEMUInsecure, platforms.MetalQEMUInsecureGPU:
5252
if err := toml.Unmarshal([]byte(kataBareMetalQEMUSNPBaseConfig), &config); err != nil {
5353
return nil, fmt.Errorf("failed to unmarshal kata runtime configuration: %w", err)
5454
}
5555

56-
for _, productLine := range []string{"_Milan", "_Genoa"} {
57-
for _, annotationType := range []string{"snp_id_block", "snp_id_auth", "snp_guest_policy"} {
58-
customContrastAnnotations = append(customContrastAnnotations, annotationType+productLine)
56+
if !platforms.IsInsecure(platform) {
57+
for _, productLine := range []string{"_Milan", "_Genoa"} {
58+
for _, annotationType := range []string{"snp_id_block", "snp_id_auth", "snp_guest_policy"} {
59+
customContrastAnnotations = append(customContrastAnnotations, annotationType+productLine)
60+
}
5961
}
6062
}
6163

6264
config.Hypervisor["qemu"]["firmware"] = filepath.Join(baseDir, "snp", "share", "OVMF.fd")
6365
default:
6466
return nil, fmt.Errorf("unsupported platform: %s", platform)
6567
}
68+
// Disable confidential computing features for insecure platforms.
69+
if platforms.IsInsecure(platform) {
70+
config.Hypervisor["qemu"]["confidential_guest"] = false
71+
if platforms.IsSNP(platform) || platform == platforms.MetalQEMUInsecure || platform == platforms.MetalQEMUInsecureGPU {
72+
config.Hypervisor["qemu"]["sev_snp_guest"] = false
73+
}
74+
}
6675
if debug {
6776
config.Agent["kata"]["enable_debug"] = true
6877
config.Agent["kata"]["debug_console_enabled"] = true

nodeinstaller/internal/kataconfig/config_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ var (
2222
expectedConfMetalQEMUSNPGPU []byte
2323
//go:embed testdata/expected-configuration-qemu-tdx-gpu.toml
2424
expectedConfMetalQEMUTDXGPU []byte
25+
//go:embed testdata/expected-configuration-qemu-insecure.toml
26+
expectedConfMetalQEMUInsecure []byte
27+
//go:embed testdata/expected-configuration-qemu-insecure-gpu.toml
28+
expectedConfMetalQEMUInsecureGPU []byte
2529
)
2630

2731
func TestKataRuntimeConfig(t *testing.T) {
@@ -45,6 +49,14 @@ func TestKataRuntimeConfig(t *testing.T) {
4549
changeSnpFields: false,
4650
want: string(expectedConfMetalQEMUTDXGPU),
4751
},
52+
platforms.MetalQEMUInsecure: {
53+
changeSnpFields: true,
54+
want: string(expectedConfMetalQEMUInsecure),
55+
},
56+
platforms.MetalQEMUInsecureGPU: {
57+
changeSnpFields: true,
58+
want: string(expectedConfMetalQEMUInsecureGPU),
59+
},
4860
}
4961
for platform, tc := range testCases {
5062
t.Run(platform.String(), func(t *testing.T) {
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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+
cold_plug_vfio = 'root-port'
9+
confidential_guest = false
10+
contrast_imagepuller_config = ''
11+
cpu_features = 'pmu=off'
12+
default_bridges = 1
13+
default_maxmemory = 0
14+
default_maxvcpus = 0
15+
default_memory = 1024
16+
default_vcpus = 1
17+
disable_block_device_use = true
18+
disable_guest_selinux = true
19+
disable_image_nvdimm = true
20+
disable_nesting_checks = true
21+
disable_selinux = false
22+
disable_vhost_net = false
23+
enable_annotations = ['cc_init_data']
24+
enable_debug = false
25+
enable_guest_swap = false
26+
enable_hugepages = false
27+
enable_iommu = false
28+
enable_iommu_platform = false
29+
enable_iothreads = false
30+
enable_mem_prealloc = false
31+
enable_numa = false
32+
enable_vhost_user_store = false
33+
enable_virtio_mem = false
34+
entropy_source = '/dev/urandom'
35+
file_mem_backend = ''
36+
firmware = '/snp/share/OVMF.fd'
37+
firmware_volume = ''
38+
guest_hook_path = ''
39+
guest_memory_dump_paging = false
40+
guest_memory_dump_path = ''
41+
image = '/share/kata-containers.img'
42+
indep_iothreads = 0
43+
initrd = '/share/kata-initrd.zst'
44+
kernel = '/share/kata-kernel'
45+
kernel_params = ''
46+
machine_accelerators = ''
47+
machine_type = 'q35'
48+
memory_offset = 0
49+
memory_slots = 10
50+
msize_9p = 8192
51+
numa_mapping = []
52+
path = '/bin/qemu-system-x86_64'
53+
pcie_root_port = 0
54+
pflashes = []
55+
reclaim_guest_freed_memory = false
56+
rootfs_type = 'erofs'
57+
rootless = false
58+
rx_rate_limiter_max_rate = 0
59+
seccompsandbox = ''
60+
sev_snp_guest = false
61+
shared_fs = 'none'
62+
snp_guest_policy = 196608
63+
snp_id_auth = ''
64+
snp_id_block = ''
65+
tx_rate_limiter_max_rate = 0
66+
use_legacy_serial = false
67+
valid_entropy_sources = ['/dev/urandom', '/dev/random', '']
68+
valid_file_mem_backends = ['']
69+
valid_hypervisor_paths = ['/bin/qemu-system-x86_64']
70+
valid_vhost_user_store_paths = ['/var/run/kata-containers/vhost-user']
71+
valid_virtio_fs_daemon_paths = ['/opt/kata/libexec/virtiofsd']
72+
vhost_user_reconnect_timeout_sec = 0
73+
vhost_user_store_path = '/var/run/kata-containers/vhost-user'
74+
virtio_fs_cache = 'auto'
75+
virtio_fs_cache_size = 0
76+
virtio_fs_daemon = '/opt/kata/libexec/virtiofsd'
77+
virtio_fs_extra_args = ['--thread-pool-size=1', '--announce-submounts']
78+
virtio_fs_queue_size = 1024
79+
80+
[Agent]
81+
[Agent.kata]
82+
debug_console_enabled = false
83+
dial_timeout = 600
84+
enable_debug = false
85+
enable_tracing = false
86+
kernel_modules = []
87+
88+
[Factory]
89+
enable_template = false
90+
template_path = '/run/vc/vm/template'
91+
vm_cache_endpoint = '/var/run/kata-containers/cache.sock'
92+
vm_cache_number = 0
93+
94+
[Runtime]
95+
create_container_timeout = 600
96+
dan_conf = '/run/kata-containers/dans'
97+
disable_guest_empty_dir = false
98+
disable_guest_seccomp = true
99+
disable_new_netns = false
100+
emptydir_mode = 'shared-fs'
101+
enable_debug = false
102+
enable_pprof = false
103+
enable_tracing = false
104+
enable_vcpus_pinning = false
105+
experimental = []
106+
experimental_force_guest_pull = true
107+
guest_selinux_label = ''
108+
internetworking_model = 'tcfilter'
109+
jaeger_endpoint = ''
110+
jaeger_password = ''
111+
jaeger_user = ''
112+
kubelet_root_dir = '/var/lib/kubelet'
113+
pod_resource_api_sock = '/var/lib/kubelet/pod-resources/kubelet.sock'
114+
sandbox_bind_mounts = []
115+
sandbox_cgroup_only = true
116+
static_sandbox_resource_mgmt = true
117+
vfio_mode = 'guest-kernel'

0 commit comments

Comments
 (0)