From 80c4977f58f2563a4602cba594f13c4a39cb5f9e Mon Sep 17 00:00:00 2001 From: Zexi Li Date: Mon, 7 Sep 2026 14:06:35 +0800 Subject: [PATCH] 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. --- pkg/apis/compute/pod.go | 4 ++ pkg/apis/container.go | 26 ++++--- pkg/apis/llm/llm_container.go | 9 +++ pkg/apis/llm/sku.go | 8 +++ pkg/hostman/guestman/pod.go | 35 ++++++--- pkg/llm/models/llm_deployment_gpu.go | 19 +++++ .../llm_deployment_gpu_explicit_util_test.go | 63 ++++++++++++++++ pkg/llm/models/llm_pod.go | 6 +- pkg/llm/models/llm_sku.go | 25 +++++++ pkg/llm/models/llm_sku_cgroup_test.go | 71 +++++++++++++++++++ pkg/llm/models/sku.go | 18 ++--- pkg/mcclient/options/compute/containers.go | 68 +++++++++--------- pkg/mcclient/options/llm/llm_sku_base.go | 19 +++-- 13 files changed, 303 insertions(+), 68 deletions(-) create mode 100644 pkg/llm/models/llm_deployment_gpu_explicit_util_test.go create mode 100644 pkg/llm/models/llm_sku_cgroup_test.go diff --git a/pkg/apis/compute/pod.go b/pkg/apis/compute/pod.go index 98e01a4583..42eeb3dec4 100644 --- a/pkg/apis/compute/pod.go +++ b/pkg/apis/compute/pod.go @@ -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 { diff --git a/pkg/apis/container.go b/pkg/apis/container.go index 478fbcaeff..6506774bc8 100644 --- a/pkg/apis/container.go +++ b/pkg/apis/container.go @@ -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. diff --git a/pkg/apis/llm/llm_container.go b/pkg/apis/llm/llm_container.go index 425f234bbf..cba23d2eb8 100644 --- a/pkg/apis/llm/llm_container.go +++ b/pkg/apis/llm/llm_container.go @@ -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 } diff --git a/pkg/apis/llm/sku.go b/pkg/apis/llm/sku.go index 7dc237ae2f..da717b2942 100644 --- a/pkg/apis/llm/sku.go +++ b/pkg/apis/llm/sku.go @@ -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"` diff --git a/pkg/hostman/guestman/pod.go b/pkg/hostman/guestman/pod.go index 8f2f58a335..3ce9a2d684 100644 --- a/pkg/hostman/guestman/pod.go +++ b/pkg/hostman/guestman/pod.go @@ -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, diff --git a/pkg/llm/models/llm_deployment_gpu.go b/pkg/llm/models/llm_deployment_gpu.go index 9a86e08812..5215a526de 100644 --- a/pkg/llm/models/llm_deployment_gpu.go +++ b/pkg/llm/models/llm_deployment_gpu.go @@ -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 } diff --git a/pkg/llm/models/llm_deployment_gpu_explicit_util_test.go b/pkg/llm/models/llm_deployment_gpu_explicit_util_test.go new file mode 100644 index 0000000000..ffed69f885 --- /dev/null +++ b/pkg/llm/models/llm_deployment_gpu_explicit_util_test.go @@ -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) + } +} diff --git a/pkg/llm/models/llm_pod.go b/pkg/llm/models/llm_pod.go index 7f0262816e..c06eff50ac 100644 --- a/pkg/llm/models/llm_pod.go +++ b/pkg/llm/models/llm_pod.go @@ -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 diff --git a/pkg/llm/models/llm_sku.go b/pkg/llm/models/llm_sku.go index d6ebaeb67d..c25ee319a0 100644 --- a/pkg/llm/models/llm_sku.go +++ b/pkg/llm/models/llm_sku.go @@ -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 { diff --git a/pkg/llm/models/llm_sku_cgroup_test.go b/pkg/llm/models/llm_sku_cgroup_test.go new file mode 100644 index 0000000000..f05cd1a72d --- /dev/null +++ b/pkg/llm/models/llm_sku_cgroup_test.go @@ -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") + } +} diff --git a/pkg/llm/models/sku.go b/pkg/llm/models/sku.go index 43abf743f4..7f4000711b 100644 --- a/pkg/llm/models/sku.go +++ b/pkg/llm/models/sku.go @@ -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"` } diff --git a/pkg/mcclient/options/compute/containers.go b/pkg/mcclient/options/compute/containers.go index 804e9bbc50..e645a06352 100644 --- a/pkg/mcclient/options/compute/containers.go +++ b/pkg/mcclient/options/compute/containers.go @@ -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: ="` - RootFs string `help:"Root filesystem of the container, e.g.: disk_index=,disk_id="` - VolumeMount []string `help:"Volume mount of the container and the format is: name=,mount_path=,readonly=,case_insensitive_paths=p1,p2,disk_index=,disk_id="` - Device []string `help:"Host device: ::, 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: ="` + RootFs string `help:"Root filesystem of the container, e.g.: disk_index=,disk_id="` + VolumeMount []string `help:"Volume mount of the container and the format is: name=,mount_path=,readonly=,case_insensitive_paths=p1,p2,disk_index=,disk_id="` + Device []string `help:"Host device: ::, 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, diff --git a/pkg/mcclient/options/llm/llm_sku_base.go b/pkg/mcclient/options/llm/llm_sku_base.go index 0a78908a9f..454ac235a6 100644 --- a/pkg/mcclient/options/llm/llm_sku_base.go +++ b/pkg/mcclient/options/llm/llm_sku_base.go @@ -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"`