mirror of
https://github.com/aljazceru/kata-containers.git
synced 2026-01-20 14:54:21 +01:00
This is a simplification of the host cgroup handling by partitioning the host cgroups into 2: A sandbox cgroup and an overhead cgroup. The sandbox cgroup is always created and initialized. The overhead cgroup is only available when sandbox_cgroup_only is unset, and is unconstrained on all controllers. The goal of having an overhead cgroup is to be more flexible on how we manage a pod overhead. Having such cgroup will allow for setting a fixed overhead per pod, for a subset of controllers, while at the same time not having the pod being accounted for those resources. When sandbox_cgroup_only is not set, we move all non vCPU threads to the overhead cgroup and let them run unconstrained. When it is set, all pod related processes and threads will run in the sandbox cgroup. Signed-off-by: Samuel Ortiz <samuel.e.ortiz@protonmail.com>
167 lines
3.9 KiB
Go
167 lines
3.9 KiB
Go
// Copyright (c) 2016 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package virtcontainers
|
|
|
|
import (
|
|
"context"
|
|
"runtime"
|
|
|
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils/katatrace"
|
|
deviceApi "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/api"
|
|
deviceConfig "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config"
|
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/cgroups"
|
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/compatoci"
|
|
vcTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// apiTracingTags defines tags for the trace span
|
|
var apiTracingTags = map[string]string{
|
|
"source": "runtime",
|
|
"packages": "virtcontainers",
|
|
"subsystem": "api",
|
|
}
|
|
|
|
func init() {
|
|
runtime.LockOSThread()
|
|
}
|
|
|
|
var virtLog = logrus.WithField("source", "virtcontainers")
|
|
|
|
// SetLogger sets the logger for virtcontainers package.
|
|
func SetLogger(ctx context.Context, logger *logrus.Entry) {
|
|
fields := virtLog.Data
|
|
virtLog = logger.WithFields(fields)
|
|
|
|
deviceApi.SetLogger(virtLog)
|
|
compatoci.SetLogger(virtLog)
|
|
deviceConfig.SetLogger(virtLog)
|
|
cgroups.SetLogger(virtLog)
|
|
}
|
|
|
|
// CreateSandbox is the virtcontainers sandbox creation entry point.
|
|
// CreateSandbox creates a sandbox and its containers. It does not start them.
|
|
func CreateSandbox(ctx context.Context, sandboxConfig SandboxConfig, factory Factory) (VCSandbox, error) {
|
|
span, ctx := katatrace.Trace(ctx, virtLog, "CreateSandbox", apiTracingTags)
|
|
defer span.End()
|
|
|
|
s, err := createSandboxFromConfig(ctx, sandboxConfig, factory)
|
|
|
|
return s, err
|
|
}
|
|
|
|
func createSandboxFromConfig(ctx context.Context, sandboxConfig SandboxConfig, factory Factory) (_ *Sandbox, err error) {
|
|
span, ctx := katatrace.Trace(ctx, virtLog, "createSandboxFromConfig", apiTracingTags)
|
|
defer span.End()
|
|
|
|
// Create the sandbox.
|
|
s, err := createSandbox(ctx, sandboxConfig, factory)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// cleanup sandbox resources in case of any failure
|
|
defer func() {
|
|
if err != nil {
|
|
s.Delete(ctx)
|
|
}
|
|
}()
|
|
|
|
// Create the sandbox network
|
|
if err = s.createNetwork(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// network rollback
|
|
defer func() {
|
|
if err != nil {
|
|
s.removeNetwork(ctx)
|
|
}
|
|
}()
|
|
|
|
// Set the sandbox host cgroups.
|
|
if err := s.setupCgroups(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Start the VM
|
|
if err = s.startVM(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// rollback to stop VM if error occurs
|
|
defer func() {
|
|
if err != nil {
|
|
s.stopVM(ctx)
|
|
}
|
|
}()
|
|
|
|
s.postCreatedNetwork(ctx)
|
|
|
|
if err = s.getAndStoreGuestDetails(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Create Containers
|
|
if err = s.createContainers(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s, nil
|
|
}
|
|
|
|
// CleanupContainer is used by shimv2 to stop and delete a container exclusively, once there is no container
|
|
// in the sandbox left, do stop the sandbox and delete it. Those serial operations will be done exclusively by
|
|
// locking the sandbox.
|
|
func CleanupContainer(ctx context.Context, sandboxID, containerID string, force bool) error {
|
|
span, ctx := katatrace.Trace(ctx, virtLog, "CleanupContainer", apiTracingTags)
|
|
defer span.End()
|
|
|
|
if sandboxID == "" {
|
|
return vcTypes.ErrNeedSandboxID
|
|
}
|
|
|
|
if containerID == "" {
|
|
return vcTypes.ErrNeedContainerID
|
|
}
|
|
|
|
unlock, err := rwLockSandbox(sandboxID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer unlock()
|
|
|
|
s, err := fetchSandbox(ctx, sandboxID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer s.Release(ctx)
|
|
|
|
_, err = s.StopContainer(ctx, containerID, force)
|
|
if err != nil && !force {
|
|
return err
|
|
}
|
|
|
|
_, err = s.DeleteContainer(ctx, containerID)
|
|
if err != nil && !force {
|
|
return err
|
|
}
|
|
|
|
if len(s.GetAllContainers()) > 0 {
|
|
return nil
|
|
}
|
|
|
|
if err = s.Stop(ctx, force); err != nil && !force {
|
|
return err
|
|
}
|
|
|
|
if err = s.Delete(ctx); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|