From c25530ac0b151e56012801cd2b57a081cf9c83ba Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Thu, 28 Sep 2017 10:52:56 +0200 Subject: [PATCH] server: implement update container resources Signed-off-by: Antonio Murdaca --- Dockerfile | 2 +- contrib/test/integration/build/cri-tools.yml | 2 +- oci/oci.go | 19 +++++++ server/container_update_resources.go | 31 +++++++++-- test/ctr.bats | 57 ++++++++++++++++++++ test/testdata/container_redis.json | 1 + 6 files changed, 107 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 607d5a86..86ea8d7b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -97,7 +97,7 @@ RUN set -x \ && rm -rf "$GOPATH" # Install crictl -ENV CRICTL_COMMIT 16e6fe4d7199c5689db4630a9330e6a8a12cecd1 +ENV CRICTL_COMMIT 9ff5e8f78a4182ab8d5ba9bcccdda5f338600eab RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/kubernetes-incubator/cri-tools.git "$GOPATH/src/github.com/kubernetes-incubator/cri-tools" \ diff --git a/contrib/test/integration/build/cri-tools.yml b/contrib/test/integration/build/cri-tools.yml index e314225e..9a117f3c 100644 --- a/contrib/test/integration/build/cri-tools.yml +++ b/contrib/test/integration/build/cri-tools.yml @@ -4,7 +4,7 @@ git: repo: "https://github.com/kubernetes-incubator/cri-tools.git" dest: "{{ ansible_env.GOPATH }}/src/github.com/kubernetes-incubator/cri-tools" - version: "16e6fe4d7199c5689db4630a9330e6a8a12cecd1" + version: "9ff5e8f78a4182ab8d5ba9bcccdda5f338600eab" - name: install crictl command: "/usr/bin/go install github.com/kubernetes-incubator/cri-tools/cmd/crictl" diff --git a/oci/oci.go b/oci/oci.go index 756be44b..1cf1964b 100644 --- a/oci/oci.go +++ b/oci/oci.go @@ -549,6 +549,25 @@ func (r *Runtime) ExecSync(c *Container, command []string, timeout int64) (resp }, nil } +// UpdateContainer updates container resources +func (r *Runtime) UpdateContainer(c *Container, res *rspec.LinuxResources) error { + cmd := exec.Command(r.Path(c), "update", "--resources", "-", c.id) + var stdout bytes.Buffer + var stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + jsonResources, err := json.Marshal(res) + if err != nil { + return err + } + cmd.Stdin = bytes.NewReader(jsonResources) + + if err := cmd.Run(); err != nil { + return fmt.Errorf("updating resources for container %q failed: %v %v (%v)", c.id, stderr.String(), stdout.String(), err) + } + return nil +} + func waitContainerStop(ctx context.Context, c *Container, timeout time.Duration) error { done := make(chan struct{}) // we could potentially re-use "done" channel to exit the loop on timeout diff --git a/server/container_update_resources.go b/server/container_update_resources.go index aa2c3734..e434e8a9 100644 --- a/server/container_update_resources.go +++ b/server/container_update_resources.go @@ -1,13 +1,38 @@ package server import ( - "fmt" - + "github.com/gogo/protobuf/proto" + rspec "github.com/opencontainers/runtime-spec/specs-go" "golang.org/x/net/context" pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" ) // UpdateContainerResources updates ContainerConfig of the container. func (s *Server) UpdateContainerResources(ctx context.Context, req *pb.UpdateContainerResourcesRequest) (*pb.UpdateContainerResourcesResponse, error) { - return nil, fmt.Errorf("not implemented") + c, err := s.GetContainerFromRequest(req.GetContainerId()) + if err != nil { + return nil, err + } + resources := toOCIResources(req.GetLinux()) + if err := s.Runtime().UpdateContainer(c, resources); err != nil { + return nil, err + } + return &pb.UpdateContainerResourcesResponse{}, nil +} + +// toOCIResources converts CRI resource constraints to OCI. +func toOCIResources(r *pb.LinuxContainerResources) *rspec.LinuxResources { + return &rspec.LinuxResources{ + CPU: &rspec.LinuxCPU{ + Shares: proto.Uint64(uint64(r.GetCpuShares())), + Quota: proto.Int64(r.GetCpuQuota()), + Period: proto.Uint64(uint64(r.GetCpuPeriod())), + Cpus: r.GetCpusetCpus(), + Mems: r.GetCpusetMems(), + }, + Memory: &rspec.LinuxMemory{ + Limit: proto.Int64(r.GetMemoryLimitInBytes()), + }, + // TODO(runcom): OOMScoreAdj is missing + } } diff --git a/test/ctr.bats b/test/ctr.bats index 90f42b68..88a47bc7 100644 --- a/test/ctr.bats +++ b/test/ctr.bats @@ -871,3 +871,60 @@ function teardown() { cleanup_pods stop_crio } + +@test "ctr update resources" { + start_crio + run crioctl pod run --config "$TESTDATA"/sandbox_config.json + echo "$output" + [ "$status" -eq 0 ] + pod_id="$output" + run crioctl ctr create --config "$TESTDATA"/container_redis.json --pod "$pod_id" + echo "$output" + [ "$status" -eq 0 ] + ctr_id="$output" + run crioctl ctr start --id "$ctr_id" + echo "$output" + [ "$status" -eq 0 ] + + run crioctl ctr execsync --id "$ctr_id" sh -c "cat /sys/fs/cgroup/memory/memory.limit_in_bytes" + echo "$output" + [ "$status" -eq 0 ] + [[ "$output" =~ "209715200" ]] + run crioctl ctr execsync --id "$ctr_id" sh -c "cat /sys/fs/cgroup/cpu/cpu.shares" + echo "$output" + [ "$status" -eq 0 ] + [[ "$output" =~ "512" ]] + run crioctl ctr execsync --id "$ctr_id" sh -c "cat /sys/fs/cgroup/cpu/cpu.cfs_period_us" + echo "$output" + [ "$status" -eq 0 ] + [[ "$output" =~ "10000" ]] + run crioctl ctr execsync --id "$ctr_id" sh -c "cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us" + echo "$output" + [ "$status" -eq 0 ] + [[ "$output" =~ "20000" ]] + + run crictl update --memory 524288000 --cpu-period 20000 --cpu-quota 10000 --cpu-share 256 "$ctr_id" + echo "$output" + [ "$status" -eq 0 ] + + run crioctl ctr execsync --id "$ctr_id" sh -c "cat /sys/fs/cgroup/memory/memory.limit_in_bytes" + echo "$output" + [ "$status" -eq 0 ] + [[ "$output" =~ "524288000" ]] + run crioctl ctr execsync --id "$ctr_id" sh -c "cat /sys/fs/cgroup/cpu/cpu.shares" + echo "$output" + [ "$status" -eq 0 ] + [[ "$output" =~ "256" ]] + run crioctl ctr execsync --id "$ctr_id" sh -c "cat /sys/fs/cgroup/cpu/cpu.cfs_period_us" + echo "$output" + [ "$status" -eq 0 ] + [[ "$output" =~ "20000" ]] + run crioctl ctr execsync --id "$ctr_id" sh -c "cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us" + echo "$output" + [ "$status" -eq 0 ] + [[ "$output" =~ "10000" ]] + + cleanup_ctrs + cleanup_pods + stop_crio +} diff --git a/test/testdata/container_redis.json b/test/testdata/container_redis.json index 638aba4f..20f1cbe5 100644 --- a/test/testdata/container_redis.json +++ b/test/testdata/container_redis.json @@ -45,6 +45,7 @@ "tty": false, "linux": { "resources": { + "memory_limit_in_bytes": 209715200, "cpu_period": 10000, "cpu_quota": 20000, "cpu_shares": 512,