Fix #I4KI81 reason: modify kata-containers version and update it to 1.11.1 Signed-off-by: holyfei <yangfeiyu20092010@163.com>
319 lines
10 KiB
Diff
319 lines
10 KiB
Diff
From f4b899b933a3a30fc378ceb4d8855778cd783d9a Mon Sep 17 00:00:00 2001
|
||
From: holyfei <yangfeiyu20092010@163.com>
|
||
Date: Fri, 18 Sep 2020 16:54:11 +0800
|
||
Subject: [PATCH 4/5] kata_runtime: support the blkio in host cgroups
|
||
|
||
reason: support the blkio in host cgroups, run with paras
|
||
--annotation io.kubernetes.docker.type=podsandbox --annotation io.katacontainers.blkio_cgroup=
|
||
'{"blkiocgroup":[{"path":"/dev/sda","limits":[{"type":"throttle_read_bps","value":400}]}]}'
|
||
|
||
Signed-off-by: yangfeiyu <yangfeiyu2@huawei.com>
|
||
---
|
||
vendor/github.com/containerd/cgroups/blkio.go | 6 ++
|
||
virtcontainers/cgroups.go | 102 ++++++++++++++++++++++++++
|
||
virtcontainers/pkg/annotations/annotations.go | 3 +
|
||
virtcontainers/pkg/oci/utils.go | 50 ++++++++++++-
|
||
virtcontainers/sandbox.go | 6 ++
|
||
virtcontainers/utils/utils.go | 22 ++++++
|
||
6 files changed, 186 insertions(+), 3 deletions(-)
|
||
|
||
diff --git a/vendor/github.com/containerd/cgroups/blkio.go b/vendor/github.com/containerd/cgroups/blkio.go
|
||
index 7c498de..485ff7b 100644
|
||
--- a/vendor/github.com/containerd/cgroups/blkio.go
|
||
+++ b/vendor/github.com/containerd/cgroups/blkio.go
|
||
@@ -23,6 +23,7 @@ import (
|
||
"io/ioutil"
|
||
"os"
|
||
"path/filepath"
|
||
+ "reflect"
|
||
"strconv"
|
||
"strings"
|
||
|
||
@@ -55,6 +56,11 @@ func (b *blkioController) Create(path string, resources *specs.LinuxResources) e
|
||
return nil
|
||
}
|
||
for _, t := range createBlkioSettings(resources.BlockIO) {
|
||
+ ptr := reflect.ValueOf(t.value)
|
||
+ if ptr.Kind() == reflect.Ptr && ptr.IsNil() {
|
||
+ continue
|
||
+ }
|
||
+
|
||
if t.value != nil {
|
||
if err := ioutil.WriteFile(
|
||
filepath.Join(b.Path(path), fmt.Sprintf("blkio.%s", t.name)),
|
||
diff --git a/virtcontainers/cgroups.go b/virtcontainers/cgroups.go
|
||
index 65d2001..e8c5a7b 100644
|
||
--- a/virtcontainers/cgroups.go
|
||
+++ b/virtcontainers/cgroups.go
|
||
@@ -9,6 +9,7 @@ package virtcontainers
|
||
import (
|
||
"bufio"
|
||
"context"
|
||
+ "encoding/json"
|
||
"fmt"
|
||
"os"
|
||
"path/filepath"
|
||
@@ -16,6 +17,8 @@ import (
|
||
"strings"
|
||
|
||
"github.com/containerd/cgroups"
|
||
+ "github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
|
||
+ "github.com/kata-containers/runtime/virtcontainers/utils"
|
||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||
"github.com/sirupsen/logrus"
|
||
)
|
||
@@ -32,8 +35,46 @@ const (
|
||
cgroupKataPath = "/kata/"
|
||
vcpuCgroupName = "vcpu"
|
||
emulatorCgroupName = "emulator"
|
||
+
|
||
+ // BlkioThrottleReadBps is the key to fetch throttle_read_bps
|
||
+ BlkioThrottleReadBps = "throttle_read_bps"
|
||
+
|
||
+ // BlkioThrottleWriteBps is the key to fetch throttle_write_bps
|
||
+ BlkioThrottleWriteBps = "throttle_write_bps"
|
||
+
|
||
+ // BlkioThrottleReadIOPS is the key to fetch throttle_read_iops
|
||
+ BlkioThrottleReadIOPS = "throttle_read_iops"
|
||
+
|
||
+ // BlkioThrottleWriteIOPS is the key to fetch throttle_write_iops
|
||
+ BlkioThrottleWriteIOPS = "throttle_write_iops"
|
||
+
|
||
+ // BlkioWeight is the key to fetch blkio_weight
|
||
+ BlkioWeight = "blkio_weight"
|
||
+
|
||
+ // BlkioLeafWeight is the key to fetch blkio_leaf_weight
|
||
+ BlkioLeafWeight = "blkio_leaf_weight"
|
||
)
|
||
|
||
+// BlkioCgroup for Linux cgroup 'blkio' data exchange
|
||
+type BlkioCgroup struct {
|
||
+ // Items specifies per cgroup values
|
||
+ Items []BlockIOCgroupItem `json:"blkiocgroup,omitempty"`
|
||
+}
|
||
+
|
||
+type BlockIOCgroupItem struct {
|
||
+ // Path represent path of blkio device
|
||
+ Path string `json:"path,omitempty"`
|
||
+ // Limits specifies the blkio type and value
|
||
+ Limits []IOLimit `json:"limits,omitempty"`
|
||
+}
|
||
+
|
||
+type IOLimit struct {
|
||
+ // Type specifies IO type
|
||
+ Type string `json:"type,omitempty"`
|
||
+ // Value specifies rate or weight value
|
||
+ Value uint64 `json:"value,omitempty"`
|
||
+}
|
||
+
|
||
var cgroupsLoadFunc = cgroups.Load
|
||
var cgroupsNewFunc = cgroups.New
|
||
|
||
@@ -372,3 +413,64 @@ func isInSlice(i int, s []int) bool {
|
||
}
|
||
return false
|
||
}
|
||
+
|
||
+func (s *Sandbox) blockIOResource() *specs.LinuxBlockIO {
|
||
+ value, ok := s.config.Annotations[annotations.BlkioCgroupTypeKey]
|
||
+ if !ok {
|
||
+ return nil
|
||
+ }
|
||
+
|
||
+ var blkioCgroupParse BlkioCgroup
|
||
+ var linuxBlkio specs.LinuxBlockIO
|
||
+ if err := json.Unmarshal([]byte(value), &blkioCgroupParse); err != nil {
|
||
+ s.Logger().Errorf("blkio_cgroup Unmarshal error:%v", err)
|
||
+ return nil
|
||
+ }
|
||
+
|
||
+ for _, item := range blkioCgroupParse.Items {
|
||
+ if item.Limits == nil {
|
||
+ s.Logger().Errorf("%v:limits have none data", item)
|
||
+ return nil
|
||
+ }
|
||
+ for _, limit := range item.Limits {
|
||
+ if item.Path != "" {
|
||
+ major, minor, err := utils.GetDeviceByPath(item.Path)
|
||
+ if err != nil {
|
||
+ s.Logger().Errorf("failed to find major and minor of device %s: %v", item.Path, err)
|
||
+ return nil
|
||
+ }
|
||
+ td := specs.LinuxThrottleDevice{
|
||
+ Rate: limit.Value,
|
||
+ }
|
||
+ td.Major = major
|
||
+ td.Minor = minor
|
||
+ switch limit.Type {
|
||
+ case BlkioThrottleReadBps:
|
||
+ linuxBlkio.ThrottleReadBpsDevice = append(linuxBlkio.ThrottleReadBpsDevice, td)
|
||
+ case BlkioThrottleWriteBps:
|
||
+ linuxBlkio.ThrottleWriteBpsDevice = append(linuxBlkio.ThrottleWriteBpsDevice, td)
|
||
+ case BlkioThrottleReadIOPS:
|
||
+ linuxBlkio.ThrottleReadIOPSDevice = append(linuxBlkio.ThrottleReadIOPSDevice, td)
|
||
+ case BlkioThrottleWriteIOPS:
|
||
+ linuxBlkio.ThrottleWriteIOPSDevice = append(linuxBlkio.ThrottleWriteIOPSDevice, td)
|
||
+ default:
|
||
+ s.Logger().Errorf("the type of throtlle device:%s is not surpport", limit.Type)
|
||
+ return nil
|
||
+ }
|
||
+ } else {
|
||
+ switch limit.Type {
|
||
+ case BlkioWeight:
|
||
+ weightUint16 := uint16(limit.Value)
|
||
+ linuxBlkio.Weight = &weightUint16
|
||
+ case BlkioLeafWeight:
|
||
+ weightLeafUint16 := uint16(limit.Value)
|
||
+ linuxBlkio.LeafWeight = &weightLeafUint16
|
||
+ default:
|
||
+ s.Logger().Errorf("the type:%s is not one of the supported types of blkio_weight and blkio_leaf_weight", limit.Type)
|
||
+ return nil
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+ return &linuxBlkio
|
||
+}
|
||
diff --git a/virtcontainers/pkg/annotations/annotations.go b/virtcontainers/pkg/annotations/annotations.go
|
||
index 96c4ef2..c35993e 100644
|
||
--- a/virtcontainers/pkg/annotations/annotations.go
|
||
+++ b/virtcontainers/pkg/annotations/annotations.go
|
||
@@ -21,6 +21,9 @@ const (
|
||
ContainerTypeKey = kataAnnotationsPrefix + "pkg.oci.container_type"
|
||
|
||
SandboxConfigPathKey = kataAnnotationsPrefix + "config_path"
|
||
+
|
||
+ // BlkioCgroupTypeKey is the annotation key to fetch sandbox blkio cgroup values
|
||
+ BlkioCgroupTypeKey = kataAnnotationsPrefix + "blkio_cgroup"
|
||
)
|
||
|
||
// Annotations related to Hypervisor configuration
|
||
diff --git a/virtcontainers/pkg/oci/utils.go b/virtcontainers/pkg/oci/utils.go
|
||
index e8ef41b..643753b 100644
|
||
--- a/virtcontainers/pkg/oci/utils.go
|
||
+++ b/virtcontainers/pkg/oci/utils.go
|
||
@@ -38,9 +38,10 @@ type annotationContainerType struct {
|
||
type annotationHandler func(value string) error
|
||
|
||
var annotationHandlerList = map[string]annotationHandler{
|
||
- vcAnnotations.StaticCPUTypeKey: validateSandboxCPU,
|
||
- vcAnnotations.StaticMemTypeKey: validateSandboxMem,
|
||
- vcAnnotations.SandboxDNSTypeKey: validateSandboxDNS,
|
||
+ vcAnnotations.StaticCPUTypeKey: validateSandboxCPU,
|
||
+ vcAnnotations.StaticMemTypeKey: validateSandboxMem,
|
||
+ vcAnnotations.SandboxDNSTypeKey: validateSandboxDNS,
|
||
+ vcAnnotations.BlkioCgroupTypeKey: validateBlkioCgroup,
|
||
}
|
||
|
||
var (
|
||
@@ -1076,6 +1077,7 @@ func validateOtherSandboxAnnotations(annotation, value string) error {
|
||
// addOtherSandboxAnnotation add self defined annotation for sandbox
|
||
func addOtherSandboxAnnotation(ocispec specs.Spec, sbConfig *vc.SandboxConfig) error {
|
||
otherSandboxAnnotationsKey := []string{
|
||
+ vcAnnotations.BlkioCgroupTypeKey,
|
||
vcAnnotations.StaticCPUTypeKey,
|
||
vcAnnotations.StaticMemTypeKey,
|
||
}
|
||
@@ -1137,6 +1139,48 @@ func validateSandboxDNS(value string) error {
|
||
return nil
|
||
}
|
||
|
||
+func validateBlkioCgroup(value string) error {
|
||
+ var linuxBlkioCgroup vc.BlkioCgroup
|
||
+ if err := json.Unmarshal([]byte(value), &linuxBlkioCgroup); err != nil {
|
||
+ return fmt.Errorf("blkio_cgroup Unmarshal error:%v, value is %s", err, value)
|
||
+ }
|
||
+
|
||
+ if linuxBlkioCgroup.Items == nil {
|
||
+ return fmt.Errorf("BlkioCgroup:%v fetch none data", linuxBlkioCgroup)
|
||
+ }
|
||
+
|
||
+ // pathNull used to judge path for blkio.weight/blkio.leaf_weight only once
|
||
+ pathNull := false
|
||
+ for _, item := range linuxBlkioCgroup.Items {
|
||
+ if pathNull {
|
||
+ return fmt.Errorf("too many paths for blkio.weight/blkio.leaf_weight")
|
||
+ }
|
||
+ if item.Path == "" && !pathNull {
|
||
+ pathNull = true
|
||
+ if len(item.Limits) > 2 || len(item.Limits) == 0 {
|
||
+ return fmt.Errorf("the format of values for blkio.weight or blkio.leaf_weight is wrong")
|
||
+ }
|
||
+
|
||
+ for _, ioLimit := range item.Limits {
|
||
+ switch ioLimit.Type {
|
||
+ case vc.BlkioWeight:
|
||
+ // Blkio.weight, between 10 and 1000
|
||
+ if ioLimit.Value < 10 || ioLimit.Value > 1000 {
|
||
+ return fmt.Errorf("blkio.weight:%v must be between 10 and 1000", ioLimit.Value)
|
||
+ }
|
||
+ case vc.BlkioLeafWeight:
|
||
+ return fmt.Errorf("the blkio.leaf_weight is not supported now")
|
||
+ default:
|
||
+ return fmt.Errorf("the type of blkio device:%s is not surpport", ioLimit.Type)
|
||
+ }
|
||
+ }
|
||
+ } else if _, _, err := utils.GetDeviceByPath(item.Path); err != nil {
|
||
+ return fmt.Errorf("failed to find major and minor of device %s: %v", item.Path, err)
|
||
+ }
|
||
+ }
|
||
+ return nil
|
||
+}
|
||
+
|
||
func GetSandboxIDFromAnnotations(s *specs.Spec) (string, error) {
|
||
if s == nil {
|
||
return "", fmt.Errorf("spec is nil")
|
||
diff --git a/virtcontainers/sandbox.go b/virtcontainers/sandbox.go
|
||
index ca4e700..9284f99 100644
|
||
--- a/virtcontainers/sandbox.go
|
||
+++ b/virtcontainers/sandbox.go
|
||
@@ -2422,6 +2422,12 @@ func (s *Sandbox) setupHostCgroupsWithEmulator() error {
|
||
}
|
||
|
||
// limit blkio resource to "<path>"
|
||
+ blkioResources := specs.LinuxResources{
|
||
+ BlockIO: s.blockIOResource(),
|
||
+ }
|
||
+ if err := applyResourceLimit(&blkioResources, vcpuCgroupPath); err != nil {
|
||
+ return err
|
||
+ }
|
||
|
||
// limit files resource
|
||
|
||
diff --git a/virtcontainers/utils/utils.go b/virtcontainers/utils/utils.go
|
||
index 36ac67a..d4dad40 100644
|
||
--- a/virtcontainers/utils/utils.go
|
||
+++ b/virtcontainers/utils/utils.go
|
||
@@ -370,6 +370,28 @@ func GetPhysicalCPUNumber() int {
|
||
return cpuNum
|
||
}
|
||
|
||
+// GetDeviceByPath returns the device No.
|
||
+func GetDeviceByPath(path string) (int64, int64, error) {
|
||
+ if path == "" {
|
||
+ return -1, -1, fmt.Errorf("Path cannot be empty")
|
||
+ }
|
||
+
|
||
+ path, err := filepath.EvalSymlinks(path)
|
||
+ if err != nil {
|
||
+ return -1, -1, err
|
||
+ }
|
||
+
|
||
+ stat := syscall.Stat_t{}
|
||
+ err = syscall.Stat(path, &stat)
|
||
+ if err != nil {
|
||
+ return -1, -1, err
|
||
+ }
|
||
+
|
||
+ major := int64(stat.Rdev / 256)
|
||
+ minor := int64(stat.Rdev % 256)
|
||
+ return major, minor, nil
|
||
+}
|
||
+
|
||
func RoundVCPUNumber(value string) (int, error) {
|
||
cpuNum, err := strconv.ParseFloat(value, 64)
|
||
if err != nil || cpuNum < minCPUs {
|
||
--
|
||
1.8.3.1
|
||
|