Skip to content
This repository was archived by the owner on Mar 9, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions integration/container_update_resources_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
Copyright 2017 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package integration

import (
"testing"

"github.com/containerd/cgroups"
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
"k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
)

func checkMemoryLimit(t *testing.T, spec *runtimespec.Spec, memLimit int64) {
require.NotNil(t, spec)
require.NotNil(t, spec.Linux)
require.NotNil(t, spec.Linux.Resources)
require.NotNil(t, spec.Linux.Resources.Memory)
require.NotNil(t, spec.Linux.Resources.Memory.Limit)
assert.Equal(t, memLimit, *spec.Linux.Resources.Memory.Limit)
}

func TestUpdateContainerResources(t *testing.T) {
t.Logf("Create a sandbox")
sbConfig := PodSandboxConfig("sandbox", "update-container-resources")
sb, err := runtimeService.RunPodSandbox(sbConfig)
require.NoError(t, err)
defer func() {
assert.NoError(t, runtimeService.StopPodSandbox(sb))
assert.NoError(t, runtimeService.RemovePodSandbox(sb))
}()

t.Logf("Create a container with memory limit")
cnConfig := ContainerConfig(
"container",
pauseImage,
WithResources(&runtime.LinuxContainerResources{
MemoryLimitInBytes: 2 * 1024 * 1024,
}),
)
cn, err := runtimeService.CreateContainer(sb, cnConfig, sbConfig)
require.NoError(t, err)

t.Logf("Check memory limit in container OCI spec")
container, err := containerdClient.LoadContainer(context.Background(), cn)
require.NoError(t, err)
spec, err := container.Spec()
require.NoError(t, err)
checkMemoryLimit(t, spec, 2*1024*1024)

t.Logf("Update container memory limit after created")
err = runtimeService.UpdateContainerResources(cn, &runtime.LinuxContainerResources{
MemoryLimitInBytes: 4 * 1024 * 1024,
})
require.NoError(t, err)

t.Logf("Check memory limit in container OCI spec")
container, err = containerdClient.LoadContainer(context.Background(), cn)
require.NoError(t, err)
spec, err = container.Spec()
require.NoError(t, err)
checkMemoryLimit(t, spec, 4*1024*1024)

t.Logf("Start the container")
require.NoError(t, runtimeService.StartContainer(cn))
task, err := container.Task(context.Background(), nil)
require.NoError(t, err)

t.Logf("Check memory limit in cgroup")
cgroup, err := cgroups.Load(cgroups.V1, cgroups.PidPath(int(task.Pid())))
require.NoError(t, err)
stat, err := cgroup.Stat(cgroups.IgnoreNotExist)
require.NoError(t, err)
assert.Equal(t, uint64(4*1024*1024), stat.Memory.Usage.Limit)

t.Logf("Update container memory limit after started")
err = runtimeService.UpdateContainerResources(cn, &runtime.LinuxContainerResources{
MemoryLimitInBytes: 8 * 1024 * 1024,
})
require.NoError(t, err)

t.Logf("Check memory limit in container OCI spec")
container, err = containerdClient.LoadContainer(context.Background(), cn)
require.NoError(t, err)
spec, err = container.Spec()
require.NoError(t, err)
checkMemoryLimit(t, spec, 8*1024*1024)

t.Logf("Check memory limit in cgroup")
stat, err = cgroup.Stat(cgroups.IgnoreNotExist)
require.NoError(t, err)
assert.Equal(t, uint64(8*1024*1024), stat.Memory.Usage.Limit)
}
28 changes: 23 additions & 5 deletions integration/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"errors"
"time"

"github.com/containerd/containerd"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/kubelet/apis/cri"
"k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
Expand All @@ -29,14 +30,17 @@ import (
)

const (
sock = "/var/run/cri-containerd.sock"
timeout = 1 * time.Minute
pauseImage = "gcr.io/google_containers/pause:3.0"
sock = "/var/run/cri-containerd.sock"
timeout = 1 * time.Minute
pauseImage = "gcr.io/google_containers/pause:3.0" // This is the same with default sandbox image.
k8sNamespace = "k8s.io" // This is the same with server.k8sContainerdNamespace.
containerdEndpoint = "/run/containerd/containerd.sock"
)

var (
runtimeService cri.RuntimeService
imageService cri.ImageManagerService
runtimeService cri.RuntimeService
imageService cri.ImageManagerService
containerdClient *containerd.Client
)

func init() {
Expand All @@ -49,6 +53,10 @@ func init() {
if err != nil {
glog.Exitf("Failed to create image service: %v", err)
}
containerdClient, err = containerd.New(containerdEndpoint, containerd.WithDefaultNamespace(k8sNamespace))
if err != nil {
glog.Exitf("Failed to connect containerd: %v", err)
}
}

// Opts sets specific information in pod sandbox config.
Expand Down Expand Up @@ -88,6 +96,16 @@ func WithTestAnnotations() ContainerOpts {
}
}

// Add container resource limits.
func WithResources(r *runtime.LinuxContainerResources) ContainerOpts {
return func(cf *runtime.ContainerConfig) {
if cf.Linux == nil {
cf.Linux = &runtime.LinuxContainerConfig{}
}
cf.Linux.Resources = r
}
}

// ContainerConfig creates a container config given a name and image name
// and additional container config options
func ContainerConfig(name, image string, opts ...ContainerOpts) *runtime.ContainerConfig {
Expand Down
2 changes: 1 addition & 1 deletion pkg/server/container_attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (c *criContainerdService) attachContainer(ctx context.Context, id string, s
return fmt.Errorf("container is in %s state", criContainerStateToString(state))
}

task, err := cntr.Container.Task(ctx, nil)
task, err := cntr.Container.Get().Task(ctx, nil)
if err != nil {
return fmt.Errorf("failed to load task: %v", err)
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/server/container_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,8 @@ func setOCILinuxResource(g *generate.Generator, resources *runtime.LinuxContaine
g.SetLinuxResourcesCPUShares(uint64(resources.GetCpuShares()))
g.SetLinuxResourcesMemoryLimit(resources.GetMemoryLimitInBytes())
g.SetProcessOOMScoreAdj(int(resources.GetOomScoreAdj()))
g.SetLinuxResourcesCPUCpus(resources.GetCpusetCpus())
g.SetLinuxResourcesCPUMems(resources.GetCpusetMems())
}

// getOCICapabilitiesList returns a list of all available capabilities.
Expand Down
4 changes: 4 additions & 0 deletions pkg/server/container_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ func getCreateContainerTestData() (*runtime.ContainerConfig, *runtime.PodSandbox
CpuShares: 300,
MemoryLimitInBytes: 400,
OomScoreAdj: 500,
CpusetCpus: "0-1",
CpusetMems: "2-3",
},
SecurityContext: &runtime.LinuxContainerSecurityContext{
SupplementalGroups: []int64{1111, 2222},
Expand Down Expand Up @@ -138,6 +140,8 @@ func getCreateContainerTestData() (*runtime.ContainerConfig, *runtime.PodSandbox
assert.EqualValues(t, *spec.Linux.Resources.CPU.Period, 100)
assert.EqualValues(t, *spec.Linux.Resources.CPU.Quota, 200)
assert.EqualValues(t, *spec.Linux.Resources.CPU.Shares, 300)
assert.EqualValues(t, spec.Linux.Resources.CPU.Cpus, "0-1")
assert.EqualValues(t, spec.Linux.Resources.CPU.Mems, "2-3")
assert.EqualValues(t, *spec.Linux.Resources.Memory.Limit, 400)
assert.EqualValues(t, *spec.Process.OOMScoreAdj, 500)

Expand Down
2 changes: 1 addition & 1 deletion pkg/server/container_execsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (c *criContainerdService) execInContainer(ctx context.Context, id string, o
return nil, fmt.Errorf("container is in %s state", criContainerStateToString(state))
}

container := cntr.Container
container := cntr.Container.Get()
spec, err := container.Spec()
if err != nil {
return nil, fmt.Errorf("failed to get container spec: %v", err)
Expand Down
2 changes: 1 addition & 1 deletion pkg/server/container_remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (c *criContainerdService) RemoveContainer(ctx context.Context, r *runtime.R
}

// Delete containerd container.
if err := container.Container.Delete(ctx, containerd.WithSnapshotCleanup); err != nil {
if err := container.Container.Get().Delete(ctx, containerd.WithSnapshotCleanup); err != nil {
if !errdefs.IsNotFound(err) {
return nil, fmt.Errorf("failed to delete containerd container %q: %v", id, err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/server/container_start.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (c *criContainerdService) startContainer(ctx context.Context,
status *containerstore.Status) (retErr error) {
id := cntr.ID
meta := cntr.Metadata
container := cntr.Container
container := cntr.Container.Get()
config := meta.Config

// Return error if container is not in created state.
Expand Down
4 changes: 2 additions & 2 deletions pkg/server/container_stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func (c *criContainerdService) stopContainer(ctx context.Context, container cont
}
}
glog.V(2).Infof("Stop container %q with signal %v", id, stopSignal)
task, err := container.Container.Task(ctx, nil)
task, err := container.Container.Get().Task(ctx, nil)
if err != nil {
if !errdefs.IsNotFound(err) {
return fmt.Errorf("failed to stop container, task not found for container %q: %v", id, err)
Expand All @@ -111,7 +111,7 @@ func (c *criContainerdService) stopContainer(ctx context.Context, container cont
glog.Errorf("Stop container %q timed out: %v", id, err)
}

task, err := container.Container.Task(ctx, nil)
task, err := container.Container.Get().Task(ctx, nil)
if err != nil {
if !errdefs.IsNotFound(err) {
return fmt.Errorf("failed to stop container, task not found for container %q: %v", id, err)
Expand Down
Loading