feat(region,host): support container shm size (#20243)

This commit is contained in:
Zexi Li
2024-05-11 21:50:08 +08:00
committed by GitHub
parent 0ca0d8d559
commit d99c3fe990
5 changed files with 77 additions and 0 deletions
+1
View File
@@ -63,6 +63,7 @@ type ContainerSpec struct {
Lifecyle *ContainerLifecyle `json:"lifecyle"`
CgroupDevicesAllow []string `json:"cgroup_devices_allow"`
SimulateCpu bool `json:"simulate_cpu"`
ShmSizeMB int `json:"shm_size_mb"`
}
type ContainerCapability struct {
+4
View File
@@ -443,6 +443,10 @@ func (p *SPodDriver) RequestStartContainer(ctx context.Context, userCred mcclien
}
func (p *SPodDriver) RequestStopContainer(ctx context.Context, userCred mcclient.TokenCredential, task models.IContainerTask) error {
ctr := task.GetContainer()
params := task.GetParams()
params.Add(jsonutils.NewString(ctr.GetName()), "container_name")
params.Add(jsonutils.NewInt(int64(ctr.Spec.ShmSizeMB)), "shm_size_mb")
return p.performContainerAction(ctx, userCred, task, "stop", task.GetParams())
}
+4
View File
@@ -160,6 +160,10 @@ func (m *SContainerManager) ValidateSpec(ctx context.Context, userCred mcclient.
return errors.Wrap(err, "validate lifecycle")
}
if spec.ShmSizeMB < 64 {
return httperrors.NewInputParameterError("/dev/shm size is small than 64MB")
}
return nil
}
+64
View File
@@ -267,6 +267,14 @@ func (s *sPodGuestInstance) getPodLogDir() string {
return filepath.Join(s.HomeDir(), "logs")
}
func (s *sPodGuestInstance) getShmDir() string {
return filepath.Join(s.HomeDir(), "shm")
}
func (s *sPodGuestInstance) getContainerShmDir(containerName string) string {
return filepath.Join(s.getShmDir(), fmt.Sprintf("%s-shm", containerName))
}
func (s *sPodGuestInstance) GetDisks() []*desc.SGuestDisk {
return s.GetDesc().Disks
}
@@ -701,6 +709,18 @@ func (s *sPodGuestInstance) StopContainer(ctx context.Context, userCred mcclient
if body.Contains("timeout") {
timeout, _ = body.Int("timeout")
}
if body.Contains("shm_size_mb") {
shmSizeMB, _ := body.Int("shm_size_mb")
if shmSizeMB > 64 {
name, err := body.GetString("container_name")
if err != nil {
return nil, errors.Wrapf(err, "not found name from body: %s", body)
}
if err := s.unmountDevShm(name); err != nil {
return nil, errors.Wrapf(err, "unmount shm %s", name)
}
}
}
if err := s.getCRI().StopContainer(ctx, criId, timeout); err != nil {
return nil, errors.Wrap(err, "CRI.StopContainer")
}
@@ -923,6 +943,19 @@ func (s *sPodGuestInstance) createContainer(ctx context.Context, userCred mcclie
mounts = newMounts
}
// process shm size
if spec.ShmSizeMB > 64 {
// mount empty dir
shmPath, err := s.mountDevShm(input, spec.ShmSizeMB)
if err != nil {
return "", errors.Wrapf(err, "mount dev shm")
}
mounts = append(mounts, &runtimeapi.Mount{
ContainerPath: "/dev/shm",
HostPath: shmPath,
})
}
ctrCfg := &runtimeapi.ContainerConfig{
Metadata: &runtimeapi.ContainerMetadata{
Name: input.Name,
@@ -1301,3 +1334,34 @@ func (s *sPodGuestInstance) ExecContainer(ctx context.Context, userCred mcclient
}
return url.Parse(resp.Url)
}
func (s *sPodGuestInstance) mountDevShm(input *hostapi.ContainerCreateInput, mb int) (string, error) {
shmPath := s.getContainerShmDir(input.Name)
if !fileutils2.Exists(shmPath) {
out, err := procutils.NewRemoteCommandAsFarAsPossible("mkdir", "-p", shmPath).Output()
if err != nil {
return "", errors.Wrapf(err, "mkdir -p %s: %s", shmPath, out)
}
}
if err := procutils.NewRemoteCommandAsFarAsPossible("mountpoint", shmPath).Run(); err == nil {
log.Warningf("mountpoint %s is already mounted", shmPath)
return "", nil
}
out, err := procutils.NewRemoteCommandAsFarAsPossible("mount", "-t", "tmpfs", "-o", fmt.Sprintf("size=%dM", mb), "tmpfs", shmPath).Output()
if err != nil {
return "", errors.Wrapf(err, "mount tmpfs %s: %s", shmPath, out)
}
return shmPath, nil
}
func (s *sPodGuestInstance) unmountDevShm(containerName string) error {
shmPath := s.getContainerShmDir(containerName)
if err := procutils.NewRemoteCommandAsFarAsPossible("mountpoint", shmPath).Run(); err != nil {
return nil
}
out, err := procutils.NewRemoteCommandAsFarAsPossible("umount", shmPath).Output()
if err != nil {
return errors.Wrapf(err, "mount tmpfs %s: %s", shmPath, out)
}
return nil
}
@@ -58,6 +58,7 @@ type ContainerCreateCommonOptions struct {
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"`
}
func (o ContainerCreateCommonOptions) getCreateSpec() (*computeapi.ContainerSpec, error) {
@@ -74,6 +75,9 @@ func (o ContainerCreateCommonOptions) getCreateSpec() (*computeapi.ContainerSpec
SimulateCpu: o.SimulateCpu,
},
}
if o.ShmSizeMb > 0 {
req.ContainerSpec.ShmSizeMB = o.ShmSizeMb
}
if len(o.PostStartExec) != 0 {
req.Lifecyle = &apis.ContainerLifecyle{
PostStart: &apis.ContainerLifecyleHandler{