bump containerd/cgroups 5fbad35c2a7e855762d3c60f2e474ffcad0d470a

full diff: c4b9ac5c76...5fbad35c2a

- containerd/cgroups#82 Add go module support
- containerd/cgroups#96 Move metrics proto package to stats/v1
- containerd/cgroups#97 Allow overriding the default /proc folder in blkioController
- containerd/cgroups#98 Allows ignoring memory modules
- containerd/cgroups#99 Add Go 1.13 to Travis
- containerd/cgroups#100 stats/v1: export per-cgroup stats

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2019-10-30 13:06:34 +01:00
parent 7cb46617fc
commit 27552ceb15
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
17 changed files with 1527 additions and 407 deletions

View file

@ -16,7 +16,7 @@ import (
"strings"
"time"
containerd_cgroups "github.com/containerd/cgroups"
v1 "github.com/containerd/cgroups/stats/v1"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/blkiodev"
pblkiodev "github.com/docker/docker/api/types/blkiodev"
@ -1376,7 +1376,7 @@ func (daemon *Daemon) conditionalUnmountOnCleanup(container *container.Container
return daemon.Unmount(container)
}
func copyBlkioEntry(entries []*containerd_cgroups.BlkIOEntry) []types.BlkioStatEntry {
func copyBlkioEntry(entries []*v1.BlkIOEntry) []types.BlkioStatEntry {
out := make([]types.BlkioStatEntry, len(entries))
for i, re := range entries {
out[i] = types.BlkioStatEntry{

View file

@ -3,7 +3,7 @@ package types // import "github.com/docker/docker/libcontainerd/types"
import (
"time"
"github.com/containerd/cgroups"
v1 "github.com/containerd/cgroups/stats/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
@ -13,13 +13,13 @@ type Summary struct{}
// Stats holds metrics properties as returned by containerd
type Stats struct {
Read time.Time
Metrics *cgroups.Metrics
Metrics *v1.Metrics
}
// InterfaceToStats returns a stats object from the platform-specific interface.
func InterfaceToStats(read time.Time, v interface{}) *Stats {
return &Stats{
Metrics: v.(*cgroups.Metrics),
Metrics: v.(*v1.Metrics),
Read: read,
}
}

View file

@ -120,7 +120,7 @@ google.golang.org/genproto 694d95ba50e67b2e363f3483057d
github.com/containerd/containerd 36cf5b690dcc00ff0f34ff7799209050c3d0c59a # v1.3.0
github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
github.com/containerd/continuity f2a389ac0a02ce21c09edd7344677a601970f41c
github.com/containerd/cgroups c4b9ac5c7601384c965b9646fc515884e091ebb9
github.com/containerd/cgroups 5fbad35c2a7e855762d3c60f2e474ffcad0d470a
github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
github.com/containerd/go-runc e029b79d8cda8374981c64eba71f28ec38e5526f
github.com/containerd/typeurl 2a93cfde8c20b23de8eb84a5adbc234ddf7a9e8d

View file

@ -26,17 +26,33 @@ import (
"strconv"
"strings"
v1 "github.com/containerd/cgroups/stats/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
func NewBlkio(root string) *blkioController {
return &blkioController{
root: filepath.Join(root, string(Blkio)),
// NewBlkio returns a Blkio controller given the root folder of cgroups.
// It may optionally accept other configuration options, such as ProcRoot(path)
func NewBlkio(root string, options ...func(controller *blkioController)) *blkioController {
ctrl := &blkioController{
root: filepath.Join(root, string(Blkio)),
procRoot: "/proc",
}
for _, opt := range options {
opt(ctrl)
}
return ctrl
}
// ProcRoot overrides the default location of the "/proc" filesystem
func ProcRoot(path string) func(controller *blkioController) {
return func(c *blkioController) {
c.procRoot = path
}
}
type blkioController struct {
root string
root string
procRoot string
}
func (b *blkioController) Name() Name {
@ -72,8 +88,8 @@ func (b *blkioController) Update(path string, resources *specs.LinuxResources) e
return b.Create(path, resources)
}
func (b *blkioController) Stat(path string, stats *Metrics) error {
stats.Blkio = &BlkIOStat{}
func (b *blkioController) Stat(path string, stats *v1.Metrics) error {
stats.Blkio = &v1.BlkIOStat{}
settings := []blkioStatSettings{
{
name: "throttle.io_serviced",
@ -122,7 +138,7 @@ func (b *blkioController) Stat(path string, stats *Metrics) error {
},
)
}
f, err := os.Open("/proc/diskstats")
f, err := os.Open(filepath.Join(b.procRoot, "diskstats"))
if err != nil {
return err
}
@ -141,7 +157,7 @@ func (b *blkioController) Stat(path string, stats *Metrics) error {
return nil
}
func (b *blkioController) readEntry(devices map[deviceKey]string, path, name string, entry *[]*BlkIOEntry) error {
func (b *blkioController) readEntry(devices map[deviceKey]string, path, name string, entry *[]*v1.BlkIOEntry) error {
f, err := os.Open(filepath.Join(b.Path(path), fmt.Sprintf("blkio.%s", name)))
if err != nil {
return err
@ -180,7 +196,7 @@ func (b *blkioController) readEntry(devices map[deviceKey]string, path, name str
if err != nil {
return err
}
*entry = append(*entry, &BlkIOEntry{
*entry = append(*entry, &v1.BlkIOEntry{
Device: devices[deviceKey{major, minor}],
Major: major,
Minor: minor,
@ -268,7 +284,7 @@ type blkioSettings struct {
type blkioStatSettings struct {
name string
entry *[]*BlkIOEntry
entry *[]*v1.BlkIOEntry
}
func uintf(v interface{}) []byte {

View file

@ -25,6 +25,7 @@ import (
"strings"
"sync"
v1 "github.com/containerd/cgroups/stats/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
@ -246,7 +247,7 @@ func (c *cgroup) Delete() error {
}
// Stat returns the current metrics for the cgroup
func (c *cgroup) Stat(handlers ...ErrorHandler) (*Metrics, error) {
func (c *cgroup) Stat(handlers ...ErrorHandler) (*v1.Metrics, error) {
c.mu.Lock()
defer c.mu.Unlock()
if c.err != nil {
@ -256,10 +257,10 @@ func (c *cgroup) Stat(handlers ...ErrorHandler) (*Metrics, error) {
handlers = append(handlers, errPassthrough)
}
var (
stats = &Metrics{
CPU: &CPUStat{
Throttling: &Throttle{},
Usage: &CPUUsage{},
stats = &v1.Metrics{
CPU: &v1.CPUStat{
Throttling: &v1.Throttle{},
Usage: &v1.CPUUsage{},
},
}
wg = &sync.WaitGroup{}

View file

@ -19,6 +19,7 @@ package cgroups
import (
"os"
v1 "github.com/containerd/cgroups/stats/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
@ -68,7 +69,7 @@ type Cgroup interface {
// subsystems are moved one at a time
MoveTo(Cgroup) error
// Stat returns the stats for all subsystems in the cgroup
Stat(...ErrorHandler) (*Metrics, error)
Stat(...ErrorHandler) (*v1.Metrics, error)
// Update updates all the subsystems with the provided resource changes
Update(resources *specs.LinuxResources) error
// Processes returns all the processes in a select subsystem for the cgroup

View file

@ -24,6 +24,7 @@ import (
"path/filepath"
"strconv"
v1 "github.com/containerd/cgroups/stats/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
@ -100,7 +101,7 @@ func (c *cpuController) Update(path string, resources *specs.LinuxResources) err
return c.Create(path, resources)
}
func (c *cpuController) Stat(path string, stats *Metrics) error {
func (c *cpuController) Stat(path string, stats *v1.Metrics) error {
f, err := os.Open(filepath.Join(c.Path(path), "cpu.stat"))
if err != nil {
return err

View file

@ -22,6 +22,8 @@ import (
"path/filepath"
"strconv"
"strings"
v1 "github.com/containerd/cgroups/stats/v1"
)
const nanosecondsInSecond = 1000000000
@ -46,7 +48,7 @@ func (c *cpuacctController) Path(path string) string {
return filepath.Join(c.root, path)
}
func (c *cpuacctController) Stat(path string, stats *Metrics) error {
func (c *cpuacctController) Stat(path string, stats *v1.Metrics) error {
user, kernel, err := c.getUsage(path)
if err != nil {
return err

13
vendor/github.com/containerd/cgroups/go.mod generated vendored Normal file
View file

@ -0,0 +1,13 @@
module github.com/containerd/cgroups
go 1.12
require (
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e
github.com/docker/go-units v0.4.0
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e
github.com/gogo/protobuf v1.2.1
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700
github.com/pkg/errors v0.8.1
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f
)

View file

@ -23,6 +23,7 @@ import (
"strconv"
"strings"
v1 "github.com/containerd/cgroups/stats/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
@ -67,7 +68,7 @@ func (h *hugetlbController) Create(path string, resources *specs.LinuxResources)
return nil
}
func (h *hugetlbController) Stat(path string, stats *Metrics) error {
func (h *hugetlbController) Stat(path string, stats *v1.Metrics) error {
for _, size := range h.sizes {
s, err := h.readSizeStat(path, size)
if err != nil {
@ -78,8 +79,8 @@ func (h *hugetlbController) Stat(path string, stats *Metrics) error {
return nil
}
func (h *hugetlbController) readSizeStat(path, size string) (*HugetlbStat, error) {
s := HugetlbStat{
func (h *hugetlbController) readSizeStat(path, size string) (*v1.HugetlbStat, error) {
s := v1.HugetlbStat{
Pagesize: size,
}
for _, t := range []struct {

View file

@ -27,19 +27,48 @@ import (
"strings"
"syscall"
"golang.org/x/sys/unix"
v1 "github.com/containerd/cgroups/stats/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
"golang.org/x/sys/unix"
)
func NewMemory(root string) *memoryController {
return &memoryController{
root: filepath.Join(root, string(Memory)),
// NewMemory returns a Memory controller given the root folder of cgroups.
// It may optionally accept other configuration options, such as IgnoreModules(...)
func NewMemory(root string, options ...func(*memoryController)) *memoryController {
mc := &memoryController{
root: filepath.Join(root, string(Memory)),
ignored: map[string]struct{}{},
}
for _, opt := range options {
opt(mc)
}
return mc
}
// IgnoreModules configure the memory controller to not read memory metrics for some
// module names (e.g. passing "memsw" would avoid all the memory.memsw.* entries)
func IgnoreModules(names ...string) func(*memoryController) {
return func(mc *memoryController) {
for _, name := range names {
mc.ignored[name] = struct{}{}
}
}
}
// OptionalSwap allows the memory controller to not fail if cgroups is not accounting
// Swap memory (there are no memory.memsw.* entries)
func OptionalSwap() func(*memoryController) {
return func(mc *memoryController) {
_, err := os.Stat(filepath.Join(mc.root, "memory.memsw.usage_in_bytes"))
if os.IsNotExist(err) {
mc.ignored["memsw"] = struct{}{}
}
}
}
type memoryController struct {
root string
root string
ignored map[string]struct{}
}
func (m *memoryController) Name() Name {
@ -97,24 +126,24 @@ func (m *memoryController) Update(path string, resources *specs.LinuxResources)
return m.set(path, settings)
}
func (m *memoryController) Stat(path string, stats *Metrics) error {
func (m *memoryController) Stat(path string, stats *v1.Metrics) error {
f, err := os.Open(filepath.Join(m.Path(path), "memory.stat"))
if err != nil {
return err
}
defer f.Close()
stats.Memory = &MemoryStat{
Usage: &MemoryEntry{},
Swap: &MemoryEntry{},
Kernel: &MemoryEntry{},
KernelTCP: &MemoryEntry{},
stats.Memory = &v1.MemoryStat{
Usage: &v1.MemoryEntry{},
Swap: &v1.MemoryEntry{},
Kernel: &v1.MemoryEntry{},
KernelTCP: &v1.MemoryEntry{},
}
if err := m.parseStats(f, stats.Memory); err != nil {
return err
}
for _, t := range []struct {
module string
entry *MemoryEntry
entry *v1.MemoryEntry
}{
{
module: "",
@ -133,6 +162,9 @@ func (m *memoryController) Stat(path string, stats *Metrics) error {
entry: stats.Memory.KernelTCP,
},
} {
if _, ok := m.ignored[t.module]; ok {
continue
}
for _, tt := range []struct {
name string
value *uint64
@ -197,7 +229,7 @@ func writeEventFD(root string, cfd, efd uintptr) error {
return err
}
func (m *memoryController) parseStats(r io.Reader, stat *MemoryStat) error {
func (m *memoryController) parseStats(r io.Reader, stat *v1.MemoryStat) error {
var (
raw = make(map[string]uint64)
sc = bufio.NewScanner(r)
@ -282,7 +314,7 @@ func getMemorySettings(resources *specs.LinuxResources) []memorySettings {
value: mem.Limit,
},
{
name: "soft_limit_in_bytes",
name: "soft_limit_in_bytes",
value: mem.Reservation,
},
{

View file

@ -23,6 +23,7 @@ import (
"strconv"
"strings"
v1 "github.com/containerd/cgroups/stats/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
@ -62,7 +63,7 @@ func (p *pidsController) Update(path string, resources *specs.LinuxResources) er
return p.Create(path, resources)
}
func (p *pidsController) Stat(path string, stats *Metrics) error {
func (p *pidsController) Stat(path string, stats *v1.Metrics) error {
current, err := readUint(filepath.Join(p.Path(path), "pids.current"))
if err != nil {
return err
@ -77,7 +78,7 @@ func (p *pidsController) Stat(path string, stats *Metrics) error {
return err
}
}
stats.Pids = &PidsStat{
stats.Pids = &v1.PidsStat{
Current: current,
Limit: max,
}

View file

@ -24,6 +24,7 @@ import (
"strconv"
"strings"
v1 "github.com/containerd/cgroups/stats/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
@ -80,7 +81,7 @@ func (p *rdmaController) Update(path string, resources *specs.LinuxResources) er
return p.Create(path, resources)
}
func parseRdmaKV(raw string, entry *RdmaEntry) {
func parseRdmaKV(raw string, entry *v1.RdmaEntry) {
var value uint64
var err error
@ -103,13 +104,13 @@ func parseRdmaKV(raw string, entry *RdmaEntry) {
}
}
func toRdmaEntry(strEntries []string) []*RdmaEntry {
var rdmaEntries []*RdmaEntry
func toRdmaEntry(strEntries []string) []*v1.RdmaEntry {
var rdmaEntries []*v1.RdmaEntry
for i := range strEntries {
parts := strings.Fields(strEntries[i])
switch len(parts) {
case 3:
entry := new(RdmaEntry)
entry := new(v1.RdmaEntry)
entry.Device = parts[0]
parseRdmaKV(parts[1], entry)
parseRdmaKV(parts[2], entry)
@ -122,7 +123,7 @@ func toRdmaEntry(strEntries []string) []*RdmaEntry {
return rdmaEntries
}
func (p *rdmaController) Stat(path string, stats *Metrics) error {
func (p *rdmaController) Stat(path string, stats *v1.Metrics) error {
currentData, err := ioutil.ReadFile(filepath.Join(p.Path(path), "rdma.current"))
if err != nil {
@ -145,7 +146,7 @@ func (p *rdmaController) Stat(path string, stats *Metrics) error {
currentEntries := toRdmaEntry(currentPerDevices)
maxEntries := toRdmaEntry(maxPerDevices)
stats.Rdma = &RdmaStat{
stats.Rdma = &v1.RdmaStat{
Current: currentEntries,
Limit: maxEntries,
}

17
vendor/github.com/containerd/cgroups/stats/v1/doc.go generated vendored Normal file
View file

@ -0,0 +1,17 @@
/*
Copyright The containerd 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 v1

View file

@ -12,6 +12,7 @@ message Metrics {
BlkIOStat blkio = 5;
RdmaStat rdma = 6;
repeated NetworkStat network = 7;
CgroupStats cgroup_stats = 8;
}
message HugetlbStat {
@ -134,3 +135,17 @@ message NetworkStat {
uint64 tx_errors = 8;
uint64 tx_dropped = 9;
}
// CgroupStats exports per-cgroup statistics.
message CgroupStats {
// number of tasks sleeping
uint64 nr_sleeping = 1;
// number of tasks running
uint64 nr_running = 2;
// number of tasks in stopped state
uint64 nr_stopped = 3;
// number of tasks in uninterruptible state
uint64 nr_uninterruptible = 4;
// number of tasks waiting on IO
uint64 nr_io_wait = 5;
}

View file

@ -19,6 +19,7 @@ package cgroups
import (
"fmt"
v1 "github.com/containerd/cgroups/stats/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
@ -85,7 +86,7 @@ type deleter interface {
type stater interface {
Subsystem
Stat(path string, stats *Metrics) error
Stat(path string, stats *v1.Metrics) error
}
type updater interface {