feat(llm): allow disabling pod/container cgroup CPU and memory limits (#25577)

Inference SKUs default to off; SKU and CLI expose enable flags so hosts can skip CFS quota and memory hard limits when needed.
This commit is contained in:
Zexi Li
2026-09-07 14:06:35 +08:00
committed by GitHub
parent d76698cfa1
commit 80c4977f58
13 changed files with 303 additions and 68 deletions

View File

@@ -84,6 +84,10 @@ type PodCreateInput struct {
HostIPC bool `json:"host_ipc"`
//PortMappings []*PodPortMapping `json:"port_mappings"`
SecurityContext *PodSecurityContext `json:"security_context,omitempty"`
// DisableCgroupCpuLimit skips setting CPU CFS quota on the pod sandbox and containers.
DisableCgroupCpuLimit bool `json:"disable_cgroup_cpu_limit"`
// DisableCgroupMemoryLimit skips setting memory hard limit on the pod sandbox and containers.
DisableCgroupMemoryLimit bool `json:"disable_cgroup_memory_limit"`
}
type PodStartResponse struct {

View File

@@ -136,17 +136,21 @@ type ContainerSpec struct {
// List of environment variable to set in the container.
Envs []*ContainerKeyValue `json:"envs"`
// Enable lxcfs
EnableLxcfs bool `json:"enable_lxcfs"`
Capabilities *ContainerCapability `json:"capabilities"`
Privileged bool `json:"privileged"`
DisableNoNewPrivs bool `json:"disable_no_new_privs"`
Lifecyle *ContainerLifecyle `json:"lifecyle"`
CgroupDevicesAllow []string `json:"cgroup_devices_allow"`
CgroupPidsMax int `json:"cgroup_pids_max"`
ResourcesLimit *ContainerResources `json:"resources_limit"`
SimulateCpu bool `json:"simulate_cpu"`
ShmSizeMB int `json:"shm_size_mb"`
SecurityContext *ContainerSecurityContext `json:"security_context,omitempty"`
EnableLxcfs bool `json:"enable_lxcfs"`
Capabilities *ContainerCapability `json:"capabilities"`
Privileged bool `json:"privileged"`
DisableNoNewPrivs bool `json:"disable_no_new_privs"`
Lifecyle *ContainerLifecyle `json:"lifecyle"`
CgroupDevicesAllow []string `json:"cgroup_devices_allow"`
CgroupPidsMax int `json:"cgroup_pids_max"`
ResourcesLimit *ContainerResources `json:"resources_limit"`
// DisableCgroupCpuLimit skips setting CPU CFS quota for this container.
DisableCgroupCpuLimit bool `json:"disable_cgroup_cpu_limit"`
// DisableCgroupMemoryLimit skips setting memory hard limit for this container.
DisableCgroupMemoryLimit bool `json:"disable_cgroup_memory_limit"`
SimulateCpu bool `json:"simulate_cpu"`
ShmSizeMB int `json:"shm_size_mb"`
SecurityContext *ContainerSecurityContext `json:"security_context,omitempty"`
// Periodic probe of container liveness.
// Container will be restarted if the probe fails.
// Cannot be updated.

View File

@@ -37,6 +37,11 @@ var (
string(LLM_CONTAINER_COMFYUI),
string(LLM_CONTAINER_OPENCLAW),
)
LLM_INFERENCE_TYPES = sets.NewString(
string(LLM_CONTAINER_OLLAMA),
string(LLM_CONTAINER_VLLM),
string(LLM_CONTAINER_SGLANG),
)
)
func IsLLMContainerType(t string) bool {
@@ -47,6 +52,10 @@ func IsLLMInstantModelType(t string) bool {
return LLM_INSTANT_MODEL_TYPES.Has(t)
}
func IsLLMInferenceType(t string) bool {
return LLM_INFERENCE_TYPES.Has(t)
}
func GetLLMInstantModelContainerType(t LLMContainerType) LLMContainerType {
return t
}

View File

@@ -162,6 +162,11 @@ type LLMSKuBaseCreateInput struct {
Memory int `json:"memory"`
Bandwidth int `json:"bandwidth"`
// EnableCgroupCpu enables CPU CFS quota on the pod/container. Inference SKUs default to false.
EnableCgroupCpu *bool `json:"enable_cgroup_cpu"`
// EnableCgroupMemory enables memory hard limit on the pod/container. Inference SKUs default to false.
EnableCgroupMemory *bool `json:"enable_cgroup_memory"`
Volumes *Volumes `json:"volumes"`
HostPaths *HostPaths `json:"host_paths"`
PortMappings *PortMappings `json:"port_mappings"`
@@ -176,6 +181,9 @@ type LLMSkuBaseUpdateInput struct {
Cpu *int `json:"cpu"`
Memory *int `json:"memory"`
EnableCgroupCpu *bool `json:"enable_cgroup_cpu"`
EnableCgroupMemory *bool `json:"enable_cgroup_memory"`
// RequstSyncImage *bool `json:"request_sync_image"`
DiskSize *int `json:"disk_size" yunion-deprecated-by:"disk_size_mb"`

View File

@@ -1170,7 +1170,7 @@ func (s *sPodGuestInstance) _startPod(ctx context.Context, userCred mcclient.Tok
return nil, errors.Wrap(err, "setCRIId")
}
// set pod cgroup resources
if err := s.setPodCgroupResources(criId, s.GetDesc().Mem, s.GetDesc().Cpu); err != nil {
if err := s.setPodCgroupResources(criId, s.GetDesc().Mem, s.GetDesc().Cpu, podInput); err != nil {
return nil, errors.Wrapf(err, "set pod %s cgroup memMB %d, cpu %d", criId, s.GetDesc().Mem, s.GetDesc().Cpu)
}
@@ -1184,12 +1184,16 @@ func (s *sPodGuestInstance) _startPod(ctx context.Context, userCred mcclient.Tok
}, nil
}
func (s *sPodGuestInstance) setPodCgroupResources(criId string, memMB int64, cpuCnt int64) error {
if err := s.getCGUtil().SetMemoryLimitBytes(criId, memMB*1024*1024); err != nil {
return errors.Wrap(err, "set cgroup memory limit")
func (s *sPodGuestInstance) setPodCgroupResources(criId string, memMB int64, cpuCnt int64, podInput *computeapi.PodCreateInput) error {
if podInput == nil || !podInput.DisableCgroupMemoryLimit {
if err := s.getCGUtil().SetMemoryLimitBytes(criId, memMB*1024*1024); err != nil {
return errors.Wrap(err, "set cgroup memory limit")
}
}
if err := s.getCGUtil().SetCPUCfs(criId, cpuCnt*s.getDefaultCPUPeriod(), s.getDefaultCPUPeriod()); err != nil {
return errors.Wrap(err, "set cgroup cfs")
if podInput == nil || !podInput.DisableCgroupCpuLimit {
if err := s.getCGUtil().SetCPUCfs(criId, cpuCnt*s.getDefaultCPUPeriod(), s.getDefaultCPUPeriod()); err != nil {
return errors.Wrap(err, "set cgroup cfs")
}
}
return nil
}
@@ -2051,6 +2055,21 @@ func (s *sPodGuestInstance) createContainer(ctx context.Context, userCred mcclie
procMountType = apis.ContainerUnmaskedProcMount
}
cpuQuota := (s.GetDesc().Cpu + int64(extraCpuCount)) * s.getDefaultCPUPeriod()
memoryLimitInBytes := s.GetDesc().Mem * 1024 * 1024
disableCgroupCpuLimit := spec.DisableCgroupCpuLimit
disableCgroupMemoryLimit := spec.DisableCgroupMemoryLimit
if podCreateInput, err := s.getPodCreateParams(); err == nil && podCreateInput != nil {
disableCgroupCpuLimit = disableCgroupCpuLimit || podCreateInput.DisableCgroupCpuLimit
disableCgroupMemoryLimit = disableCgroupMemoryLimit || podCreateInput.DisableCgroupMemoryLimit
}
if disableCgroupCpuLimit {
cpuQuota = 0
}
if disableCgroupMemoryLimit {
memoryLimitInBytes = 0
}
ctrCfg := &runtimeapi.ContainerConfig{
Metadata: &runtimeapi.ContainerMetadata{
Name: input.Name,
@@ -2072,9 +2091,9 @@ func (s *sPodGuestInstance) createContainer(ctx context.Context, userCred mcclie
Resources: &runtimeapi.LinuxContainerResources{
// REF: https://docs.docker.com/config/containers/resource_constraints/#configure-the-default-cfs-scheduler
CpuPeriod: s.getDefaultCPUPeriod(),
CpuQuota: (s.GetDesc().Cpu + int64(extraCpuCount)) * s.getDefaultCPUPeriod(),
CpuQuota: cpuQuota,
//CpuShares: defaultCPUPeriod,
MemoryLimitInBytes: s.GetDesc().Mem * 1024 * 1024,
MemoryLimitInBytes: memoryLimitInBytes,
OomScoreAdj: 0,
CpusetCpus: cpuSetCpus,
CpusetMems: cpuSetMems,

View File

@@ -154,6 +154,20 @@ func runtimeHasExplicitTokenLimit(sku *SLLMSku) bool {
}
}
// skuHasExplicitGpuMemoryUtilization reports whether the SKU already sets the
// backend GPU memory fraction (vLLM gpu-memory-utilization / SGLang mem-fraction-static)
// via backend_parameters or type-specific customized args.
func skuHasExplicitGpuMemoryUtilization(sku *SLLMSku) bool {
if sku == nil {
return false
}
key, ok := gpuMemoryUtilizationRuntimeArgKey(sku.LLMType)
if !ok {
return false
}
return runtimeHasExplicitArg(sku, []string{key})
}
func runtimeHasExplicitArg(sku *SLLMSku, keys []string) bool {
if sku == nil {
return false
@@ -563,6 +577,11 @@ func BuildDeploymentResolvedGpuMemoryLLMSpec(ctx context.Context, userCred mccli
if deploy.GpuMemoryUtilization != nil {
return buildDeploymentGpuMemoryLLMSpec(deploy, sku)
}
if skuHasExplicitGpuMemoryUtilization(sku) {
key, _ := gpuMemoryUtilizationRuntimeArgKey(sku.LLMType)
log.Infof("skip auto gpu_memory_utilization: sku=%s already has explicit %s", sku.Id, key)
return nil, nil
}
if !skuCanAutoGpuMemoryUtilization(sku) {
return nil, nil
}

View File

@@ -0,0 +1,63 @@
package models
import (
"context"
"testing"
api "yunion.io/x/onecloud/pkg/apis/llm"
)
func TestSkuHasExplicitGpuMemoryUtilization(t *testing.T) {
if skuHasExplicitGpuMemoryUtilization(nil) {
t.Fatal("nil sku should not have explicit GPU util")
}
plain := &SLLMSku{LLMType: string(api.LLM_CONTAINER_VLLM)}
if skuHasExplicitGpuMemoryUtilization(plain) {
t.Fatal("SKU without backend args should not have explicit GPU util")
}
byBackend := &SLLMSku{
LLMType: string(api.LLM_CONTAINER_VLLM),
BackendParameters: []string{"--max-model-len=4096", "--gpu-memory-utilization=0.9"},
}
if !skuHasExplicitGpuMemoryUtilization(byBackend) {
t.Fatal("backend_parameters gpu-memory-utilization should count as explicit")
}
bySpec := &SLLMSku{
LLMType: string(api.LLM_CONTAINER_VLLM),
LLMSpec: &api.LLMSpec{
Vllm: &api.LLMSpecVllm{
CustomizedArgs: []*api.VllmCustomizedArg{{Key: "gpu-memory-utilization", Value: "0.85"}},
},
},
}
if !skuHasExplicitGpuMemoryUtilization(bySpec) {
t.Fatal("vllm customized_args gpu-memory-utilization should count as explicit")
}
sglang := &SLLMSku{
LLMType: string(api.LLM_CONTAINER_SGLANG),
BackendParameters: []string{"--mem-fraction-static=0.8"},
}
if !skuHasExplicitGpuMemoryUtilization(sglang) {
t.Fatal("sglang mem-fraction-static should count as explicit")
}
}
func TestBuildDeploymentResolvedGpuMemoryLLMSpecSkipsExplicitSkuArg(t *testing.T) {
auto := true
deploy := &SLLMDeployment{AutoGpuMemoryUtilization: &auto}
sku := &SLLMSku{
LLMType: string(api.LLM_CONTAINER_VLLM),
BackendParameters: []string{"--gpu-memory-utilization=0.9"},
}
spec, err := BuildDeploymentResolvedGpuMemoryLLMSpec(context.Background(), nil, deploy, sku)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if spec != nil {
t.Fatalf("expected nil spec when SKU already sets gpu-memory-utilization, got %#v", spec)
}
}

View File

@@ -40,8 +40,10 @@ func GetLLMPodCreateInput(
containers := GetDriverPodContainers(ctx, lcd, llm, llmImage, sku, nil, nil, "")
data.Pod = &computeapi.PodCreateInput{
HostIPC: true,
Containers: containers,
HostIPC: true,
Containers: containers,
DisableCgroupCpuLimit: sku == nil || !skuCgroupLimitEnabled(sku.EnableCgroupCpu),
DisableCgroupMemoryLimit: sku == nil || !skuCgroupLimitEnabled(sku.EnableCgroupMemory),
}
return data, nil

View File

@@ -230,6 +230,30 @@ func (manager *SLLMSkuManager) FetchCustomizeColumns(
return res
}
func boolPtr(v bool) *bool {
return &v
}
func skuCgroupLimitEnabled(enabled *bool) bool {
if enabled == nil {
return true
}
return *enabled
}
func applySkuCgroupLimitDefaults(input *api.LLMSkuCreateInput) {
if input == nil {
return
}
def := !api.IsLLMInferenceType(input.LLMType)
if input.EnableCgroupCpu == nil {
input.EnableCgroupCpu = boolPtr(def)
}
if input.EnableCgroupMemory == nil {
input.EnableCgroupMemory = boolPtr(def)
}
}
func (man *SLLMSkuManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input *api.LLMSkuCreateInput) (*api.LLMSkuCreateInput, error) {
var err error
input.LLMSKuBaseCreateInput, err = man.SLLMSkuBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.LLMSKuBaseCreateInput)
@@ -239,6 +263,7 @@ func (man *SLLMSkuManager) ValidateCreateData(ctx context.Context, userCred mccl
if !api.IsLLMContainerType(input.LLMType) && input.LLMType != string(api.LLM_CONTAINER_DIFY) {
return input, errors.Wrap(httperrors.ErrInputParameter, "llm_type must be one of "+strings.Join(api.LLM_CONTAINER_TYPES.List(), ","))
}
applySkuCgroupLimitDefaults(input)
drv, err := GetLLMContainerDriverWithError(api.LLMContainerType(input.LLMType))
if err != nil {

View File

@@ -0,0 +1,71 @@
package models
import (
"testing"
api "yunion.io/x/onecloud/pkg/apis/llm"
)
func TestApplySkuCgroupLimitDefaultsInference(t *testing.T) {
for _, llmType := range []string{
string(api.LLM_CONTAINER_VLLM),
string(api.LLM_CONTAINER_SGLANG),
string(api.LLM_CONTAINER_OLLAMA),
} {
input := &api.LLMSkuCreateInput{LLMType: llmType}
applySkuCgroupLimitDefaults(input)
if input.EnableCgroupCpu == nil || *input.EnableCgroupCpu {
t.Fatalf("%s: expected enable_cgroup_cpu=false, got %v", llmType, input.EnableCgroupCpu)
}
if input.EnableCgroupMemory == nil || *input.EnableCgroupMemory {
t.Fatalf("%s: expected enable_cgroup_memory=false, got %v", llmType, input.EnableCgroupMemory)
}
}
}
func TestApplySkuCgroupLimitDefaultsInferenceExplicitTrue(t *testing.T) {
enabled := true
input := &api.LLMSkuCreateInput{
LLMType: string(api.LLM_CONTAINER_VLLM),
LLMSKuBaseCreateInput: api.LLMSKuBaseCreateInput{
EnableCgroupCpu: &enabled,
EnableCgroupMemory: &enabled,
},
}
applySkuCgroupLimitDefaults(input)
if input.EnableCgroupCpu == nil || !*input.EnableCgroupCpu {
t.Fatalf("expected explicit enable_cgroup_cpu=true, got %v", input.EnableCgroupCpu)
}
if input.EnableCgroupMemory == nil || !*input.EnableCgroupMemory {
t.Fatalf("expected explicit enable_cgroup_memory=true, got %v", input.EnableCgroupMemory)
}
}
func TestApplySkuCgroupLimitDefaultsNonInference(t *testing.T) {
for _, llmType := range []string{
string(api.LLM_CONTAINER_DIFY),
string(api.LLM_CONTAINER_DESKTOP),
string(api.LLM_CONTAINER_COMFYUI),
} {
input := &api.LLMSkuCreateInput{LLMType: llmType}
applySkuCgroupLimitDefaults(input)
if input.EnableCgroupCpu == nil || !*input.EnableCgroupCpu {
t.Fatalf("%s: expected enable_cgroup_cpu=true, got %v", llmType, input.EnableCgroupCpu)
}
if input.EnableCgroupMemory == nil || !*input.EnableCgroupMemory {
t.Fatalf("%s: expected enable_cgroup_memory=true, got %v", llmType, input.EnableCgroupMemory)
}
}
}
func TestSkuCgroupLimitEnabled(t *testing.T) {
if !skuCgroupLimitEnabled(nil) {
t.Fatal("nil should default to enabled (legacy SKU behavior)")
}
if !skuCgroupLimitEnabled(boolPtr(true)) {
t.Fatal("true should be enabled")
}
if skuCgroupLimitEnabled(boolPtr(false)) {
t.Fatal("false should be disabled")
}
}

View File

@@ -34,14 +34,16 @@ type SLLMSkuBaseManager struct {
type SLLMSkuBase struct {
db.SSharableVirtualResourceBase
Bandwidth int `nullable:"false" default:"0" create:"optional" list:"user" update:"user"`
Cpu int `nullable:"false" default:"1" create:"optional" list:"user" update:"user"`
Memory int `nullable:"false" default:"512" create:"optional" list:"user" update:"user"`
Volumes *api.Volumes `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
HostPaths *api.HostPaths `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
PortMappings *api.PortMappings `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
Devices *api.Devices `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
Envs *api.Envs `charset:"utf8" nullable:"true" list:"user" update:"user" create:"optional"`
Bandwidth int `nullable:"false" default:"0" create:"optional" list:"user" update:"user"`
Cpu int `nullable:"false" default:"1" create:"optional" list:"user" update:"user"`
Memory int `nullable:"false" default:"512" create:"optional" list:"user" update:"user"`
EnableCgroupCpu *bool `default:"true" create:"optional" list:"user" update:"user"`
EnableCgroupMemory *bool `default:"true" create:"optional" list:"user" update:"user"`
Volumes *api.Volumes `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
HostPaths *api.HostPaths `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
PortMappings *api.PortMappings `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
Devices *api.Devices `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
Envs *api.Envs `charset:"utf8" nullable:"true" list:"user" update:"user" create:"optional"`
// Properties
Properties map[string]string `charset:"utf8" nullable:"true" list:"user" update:"user" create:"optional"`
}

View File

@@ -48,43 +48,47 @@ type ContainerDeleteOptions struct {
}
type ContainerCreateCommonOptions struct {
IMAGE string `help:"Image of container" json:"image"`
ImageCredentialId string `help:"Image credential id" json:"image_credential_id"`
Command []string `help:"Command to execute (i.e., entrypoint for docker)" json:"command"`
Args []string `help:"Args for the Command (i.e. command for docker)" json:"args"`
WorkingDir string `help:"Current working directory of the command" json:"working_dir"`
Env []string `help:"List of environment variable to set in the container and the format is: <key>=<value>"`
RootFs string `help:"Root filesystem of the container, e.g.: disk_index=<disk_number>,disk_id=<disk_id>"`
VolumeMount []string `help:"Volume mount of the container and the format is: name=<val>,mount_path=<container_path>,readonly=<true_or_false>,case_insensitive_paths=p1,p2,disk_index=<disk_number>,disk_id=<disk_id>"`
Device []string `help:"Host device: <host_path>:<container_path>:<permissions>, e.g.: /dev/snd:/dev/snd:rwm"`
Privileged bool `help:"Privileged mode"`
Caps string `help:"Container capabilities, e.g.: SETPCAP,AUDIT_WRITE,SYS_CHROOT,CHOWN,DAC_OVERRIDE,FOWNER,SETGID,SETUID,SYSLOG,SYS_ADMIN,WAKE_ALARM,SYS_PTRACE,BLOCK_SUSPEND,MKNOD,KILL,SYS_RESOURCE,NET_RAW,NET_ADMIN,NET_BIND_SERVICE,SYS_NICE"`
DropCaps string `help:"Container dropped capabilities, split by ','"`
EnableLxcfs bool `help:"Enable lxcfs"`
PostStartExec string `help:"Post started execution command"`
CgroupDeviceAllow []string `help:"Cgroup devices.allow, e.g.: 'c 13:* rwm'"`
SimulateCpu bool `help:"Simulating /sys/devices/system/cpu files"`
ShmSizeMb int `help:"Shm size MB"`
Uid int64 `help:"UID of container" default:"0"`
Gid int64 `help:"GID of container" default:"0"`
DisableNoNewPrivs bool `help:"Disable no_new_privs flag of the container"`
Apparmor string `help:"Apparmor profile for container"`
IMAGE string `help:"Image of container" json:"image"`
ImageCredentialId string `help:"Image credential id" json:"image_credential_id"`
Command []string `help:"Command to execute (i.e., entrypoint for docker)" json:"command"`
Args []string `help:"Args for the Command (i.e. command for docker)" json:"args"`
WorkingDir string `help:"Current working directory of the command" json:"working_dir"`
Env []string `help:"List of environment variable to set in the container and the format is: <key>=<value>"`
RootFs string `help:"Root filesystem of the container, e.g.: disk_index=<disk_number>,disk_id=<disk_id>"`
VolumeMount []string `help:"Volume mount of the container and the format is: name=<val>,mount_path=<container_path>,readonly=<true_or_false>,case_insensitive_paths=p1,p2,disk_index=<disk_number>,disk_id=<disk_id>"`
Device []string `help:"Host device: <host_path>:<container_path>:<permissions>, e.g.: /dev/snd:/dev/snd:rwm"`
Privileged bool `help:"Privileged mode"`
Caps string `help:"Container capabilities, e.g.: SETPCAP,AUDIT_WRITE,SYS_CHROOT,CHOWN,DAC_OVERRIDE,FOWNER,SETGID,SETUID,SYSLOG,SYS_ADMIN,WAKE_ALARM,SYS_PTRACE,BLOCK_SUSPEND,MKNOD,KILL,SYS_RESOURCE,NET_RAW,NET_ADMIN,NET_BIND_SERVICE,SYS_NICE"`
DropCaps string `help:"Container dropped capabilities, split by ','"`
EnableLxcfs bool `help:"Enable lxcfs"`
PostStartExec string `help:"Post started execution command"`
CgroupDeviceAllow []string `help:"Cgroup devices.allow, e.g.: 'c 13:* rwm'"`
DisableCgroupCpuLimit bool `help:"Do not set CPU cgroup CFS quota"`
DisableCgroupMemoryLimit bool `help:"Do not set memory cgroup hard limit"`
SimulateCpu bool `help:"Simulating /sys/devices/system/cpu files"`
ShmSizeMb int `help:"Shm size MB"`
Uid int64 `help:"UID of container" default:"0"`
Gid int64 `help:"GID of container" default:"0"`
DisableNoNewPrivs bool `help:"Disable no_new_privs flag of the container"`
Apparmor string `help:"Apparmor profile for container"`
}
func (o ContainerCreateCommonOptions) getCreateSpec() (*computeapi.ContainerSpec, error) {
req := &computeapi.ContainerSpec{
ContainerSpec: apis.ContainerSpec{
Image: o.IMAGE,
ImageCredentialId: o.ImageCredentialId,
Command: o.Command,
Args: o.Args,
WorkingDir: o.WorkingDir,
EnableLxcfs: o.EnableLxcfs,
Privileged: o.Privileged,
Capabilities: &apis.ContainerCapability{},
CgroupDevicesAllow: o.CgroupDeviceAllow,
SimulateCpu: o.SimulateCpu,
DisableNoNewPrivs: o.DisableNoNewPrivs,
Image: o.IMAGE,
ImageCredentialId: o.ImageCredentialId,
Command: o.Command,
Args: o.Args,
WorkingDir: o.WorkingDir,
EnableLxcfs: o.EnableLxcfs,
Privileged: o.Privileged,
Capabilities: &apis.ContainerCapability{},
CgroupDevicesAllow: o.CgroupDeviceAllow,
DisableCgroupCpuLimit: o.DisableCgroupCpuLimit,
DisableCgroupMemoryLimit: o.DisableCgroupMemoryLimit,
SimulateCpu: o.SimulateCpu,
DisableNoNewPrivs: o.DisableNoNewPrivs,
SecurityContext: &apis.ContainerSecurityContext{
RunAsUser: nil,
RunAsGroup: nil,

View File

@@ -19,6 +19,9 @@ type LLMSkuBaseCreateOptions struct {
MEMORY int `help:"memory size MB"`
DISK_SIZE int `help:"disk size MB"`
EnableCgroupCpu *bool `help:"enable CPU cgroup CFS quota; inference SKUs default false" json:"enable_cgroup_cpu" token:"enable-cgroup-cpu"`
EnableCgroupMemory *bool `help:"enable memory cgroup hard limit; inference SKUs default false" json:"enable_cgroup_memory" token:"enable-cgroup-memory"`
Bandwidth int
StorageType string
// DiskOverlay string `help:"disk overlay, e.g. /opt/steam-data/base:/opt/steam-data/games"`
@@ -59,13 +62,15 @@ type LLMSkuBaseUpdateOptions struct {
ID string
Cpu *int
Memory *int `help:"memory size MB"`
DiskSize *int `help:"disk size MB"`
StorageType string
TemplateId string
NoTemplate bool `json:"-" help:"remove template"`
Bandwidth *int
Cpu *int
Memory *int `help:"memory size MB"`
EnableCgroupCpu *bool `help:"enable CPU cgroup CFS quota" json:"enable_cgroup_cpu" token:"enable-cgroup-cpu"`
EnableCgroupMemory *bool `help:"enable memory cgroup hard limit" json:"enable_cgroup_memory" token:"enable-cgroup-memory"`
DiskSize *int `help:"disk size MB"`
StorageType string
TemplateId string
NoTemplate bool `json:"-" help:"remove template"`
Bandwidth *int
// Dpi *int
// Fps *int
PortMappings []string `help:"port mapping in the format of protocol:port[:prefix][:first_port_offset], e.g. tcp:5555:192.168.0.0/16,10.10.0.0/16:1000"`