Add methods for listing and fetching container stats
This uses the previously unusued lib/stats.go code to return data about container stats to the CRI API. As a shortcut for intial testing, I've made ListContainerStats an API composition of the ContainerStats and ListContainers APIs directly (calls the same server methods with the same context), but this should be refactored into an internal API. No data on filesystem layer usage is returned at this time. Fixes one-half of #1248 Signed-off-by: Yann Ramin <atrus@stackworks.net>
This commit is contained in:
parent
6f4d7c1ae0
commit
b4a469edfe
3 changed files with 65 additions and 7 deletions
|
@ -15,8 +15,8 @@ import (
|
||||||
type ContainerStats struct {
|
type ContainerStats struct {
|
||||||
Container string
|
Container string
|
||||||
CPU float64
|
CPU float64
|
||||||
cpuNano uint64
|
CPUNano uint64
|
||||||
systemNano uint64
|
SystemNano uint64
|
||||||
MemUsage uint64
|
MemUsage uint64
|
||||||
MemLimit uint64
|
MemLimit uint64
|
||||||
MemPerc float64
|
MemPerc float64
|
||||||
|
@ -29,8 +29,8 @@ type ContainerStats struct {
|
||||||
|
|
||||||
// GetContainerStats gets the running stats for a given container
|
// GetContainerStats gets the running stats for a given container
|
||||||
func (c *ContainerServer) GetContainerStats(ctr *oci.Container, previousStats *ContainerStats) (*ContainerStats, error) {
|
func (c *ContainerServer) GetContainerStats(ctr *oci.Container, previousStats *ContainerStats) (*ContainerStats, error) {
|
||||||
previousCPU := previousStats.cpuNano
|
previousCPU := previousStats.CPUNano
|
||||||
previousSystem := previousStats.systemNano
|
previousSystem := previousStats.SystemNano
|
||||||
libcontainerStats, err := c.LibcontainerStats(ctr)
|
libcontainerStats, err := c.LibcontainerStats(ctr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/kubernetes-incubator/cri-o/lib"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
||||||
)
|
)
|
||||||
|
@ -16,5 +17,35 @@ func (s *Server) ContainerStats(ctx context.Context, req *pb.ContainerStatsReque
|
||||||
recordOperation(operation, time.Now())
|
recordOperation(operation, time.Now())
|
||||||
recordError(operation, err)
|
recordError(operation, err)
|
||||||
}()
|
}()
|
||||||
return nil, fmt.Errorf("not implemented")
|
|
||||||
|
container := s.GetContainer(req.ContainerId)
|
||||||
|
if container == nil {
|
||||||
|
return nil, fmt.Errorf("invalid container")
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now().UnixNano()
|
||||||
|
stats, err := s.GetContainerStats(container, &lib.ContainerStats{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.ContainerStatsResponse{
|
||||||
|
&pb.ContainerStats{
|
||||||
|
Attributes: &pb.ContainerAttributes{
|
||||||
|
Id: req.ContainerId,
|
||||||
|
Metadata: container.Metadata(),
|
||||||
|
Labels: container.Labels(),
|
||||||
|
Annotations: container.Annotations(),
|
||||||
|
},
|
||||||
|
Cpu: &pb.CpuUsage{
|
||||||
|
Timestamp: now,
|
||||||
|
UsageCoreNanoSeconds: &pb.UInt64Value{stats.CPUNano + stats.SystemNano},
|
||||||
|
},
|
||||||
|
Memory: &pb.MemoryUsage{
|
||||||
|
Timestamp: now,
|
||||||
|
WorkingSetBytes: &pb.UInt64Value{stats.MemUsage},
|
||||||
|
},
|
||||||
|
WritableLayer: nil,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
||||||
)
|
)
|
||||||
|
@ -15,5 +15,32 @@ func (s *Server) ListContainerStats(ctx context.Context, req *pb.ListContainerSt
|
||||||
recordOperation(operation, time.Now())
|
recordOperation(operation, time.Now())
|
||||||
recordError(operation, err)
|
recordError(operation, err)
|
||||||
}()
|
}()
|
||||||
return nil, fmt.Errorf("not implemented")
|
|
||||||
|
// This is an inefficient method, since the container will be resolved twice,
|
||||||
|
// once by the container list code and once by the GetContainerStats call.
|
||||||
|
containers, err := s.ListContainers(ctx, &pb.ListContainersRequest{
|
||||||
|
&pb.ContainerFilter{
|
||||||
|
Id: req.Filter.Id,
|
||||||
|
PodSandboxId: req.Filter.PodSandboxId,
|
||||||
|
LabelSelector: req.Filter.LabelSelector,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var allStats []*pb.ContainerStats
|
||||||
|
|
||||||
|
for _, container := range containers.Containers {
|
||||||
|
stats, err := s.ContainerStats(ctx, &pb.ContainerStatsRequest{ContainerId: container.Id})
|
||||||
|
if err != nil {
|
||||||
|
logrus.Warn("unable to get stats for container %s", container.Id)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
allStats = append(allStats, stats.Stats)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.ListContainerStatsResponse{
|
||||||
|
Stats: allStats,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue