Updated code snippets to match PoC branch.

This commit is contained in:
Connor Doyle 2017-07-12 10:54:31 -07:00
parent b961e4eee9
commit a6afac8372
1 changed files with 49 additions and 89 deletions

View File

@ -87,43 +87,39 @@ system yields two cores on the same socket.
contains code to build a ThreadSet from the output of `lscpu -p`. contains code to build a ThreadSet from the output of `lscpu -p`.
1. Execute a mature external topology program like [`mpi-hwloc`][hwloc] -- 1. Execute a mature external topology program like [`mpi-hwloc`][hwloc] --
potentially adding support for the hwloc file format to the Kubelet. potentially adding support for the hwloc file format to the Kubelet.
1. Re-use existing discovery functionality from cAdvisor. **(preferred initial
solution)**
#### CPU Manager interfaces (sketch) #### CPU Manager interfaces (sketch)
```go ```go
type CPUManagerPolicy interface { type State interface {
Init(driver CPUDriver, topo CPUTopo) GetCPUSet(containerID string) (cpuset.CPUSet, bool)
Add(c v1.Container, qos QoS) error GetDefaultCPUSet() cpuset.CPUSet
Remove(c v1.Container, qos QoS) error GetCPUSetOrDefault(containerID string) cpuset.CPUSet
SetCPUSet(containerID string, cpuset CPUSet)
SetDefaultCPUSet(cpuset CPUSet)
Delete(containerID string)
} }
type CPUDriver { type Manager interface {
GetPods() []v1.Pod Start()
GetCPUs(containerID string) CPUList Policy() Policy
SetCPUs(containerID string, clist CPUList) error RegisterContainer(p *Pod, c *Container, containerID string) error
// Future: RDT L3 and L2 cache masks, etc. UnregisterContainer(containerID string) error
State() state.Reader
} }
type CPUTopo TBD type Policy interface {
Name() string
Start(s state.State)
RegisterContainer(s State, pod *Pod, container *Container, containerID string) error
UnregisterContainer(s State, containerID string) error
}
type CPUList string type CPUSet map[int]struct{} // set operations and parsing/formatting helpers
func (c CPUList) Size() int {} type CPUTopology TBD
// Returns a CPU list with size n and the remainder or
// an error if the request cannot be satisfied, taking
// into account the supplied topology.
//
// @post: c = set_union(taken, remaining),
// empty_set = set_intersection(taken, remainder)
func (c CPUList) Take(n int, topo CPUTopo) (taken CPUList,
remainder CPUList,
err error) {}
// Returns a CPU list that includes all CPUs in c and d and no others.
//
// @post: result = set_union(c, d)
func (c CPUList) Add(d CPUList) (result CPUList) {}
``` ```
Kubernetes will ship with three CPU manager policies. Only one policy is Kubernetes will ship with three CPU manager policies. Only one policy is
@ -154,69 +150,36 @@ becomes terminal.)
##### Implementation sketch ##### Implementation sketch
```go ```go
// Implements CPUManagerPolicy func (p *staticPolicy) Start(s State) {
type staticManager struct { // Iteration starts at index `1` here because CPU `0` is reserved
driver CPUDriver // for infrastructure processes.
topo CPUTopo // TODO(CD): Improve this to align with kube/system reserved resources.
// CPU list assigned to non-exclusive containers. shared := NewCPUSet()
shared CPUList for cpuid := 1; cpuid < p.topology.NumCPUs; cpuid++ {
shared.Add(cpuid)
}
s.SetDefaultCPUSet(shared)
} }
func (m *staticManager) Init(driver CPUDriver, topo CPUTopo) { func (p *staticPolicy) RegisterContainer(s State, pod *Pod, container *Container, containerID string) error {
m.driver = driver if numCPUs := numGuaranteedCPUs(pod, container); numCPUs != 0 {
m.topo = topo // container should get some exclusively allocated CPUs
} cpuset, err := p.allocateCPUs(s, numCPUs)
func (m *staticManager) Add(c v1.Container, qos QoS) error {
if p.QoS == GUARANTEED && numExclusive(c) > 0 {
excl, err := allocate(numExclusive(c))
if err != nil { if err != nil {
return err return err
} }
m.driver.SetCPUs(c.ID, excl) s.SetCPUSet(containerID, cpuset)
return nil
} }
// container belongs in the shared pool (nothing to do; use default cpuset)
// Default case: assign the shared set.
m.driver.SetCPUs(c.ID, m.shared)
return nil return nil
} }
func (m *staticManager) Remove(c v1.Container, qos QoS) error { func (p *staticPolicy) UnregisterContainer(s State, containerID string) error {
m.free(m.driver.GetCPUs(c.ID)) if toRelease, ok := s.GetCPUSet(containerID); ok {
} s.Delete(containerID)
p.releaseCPUs(s, toRelease)
func (m *staticManager) allocate(n int) (CPUList, err) {
excl, remaining, err := m.shared.Take(n, m.topo)
if err != nil {
return "", err
} }
m.setShared(remaining) return nil
return excl, nil
}
func (m *staticManager) free(c CPUList) {
m.setShared(m.shared.add(c))
}
func (m *staticManager) setShared(c CPUList) {
prev := m.shared
m.shared = c
for _, pod := range m.driver.GetPods() {
for _, container := range p.Containers {
if driver.GetCPUs(container.ID) == prev {
driver.SetCPUs(m.shared)
}
}
}
}
// @pre: container_qos = guaranteed
func numExclusive(c v1.Container) int {
if c.resources.requests["cpu"] % 1000 == 0 {
return c.resources.requests["cpu"] / 1000
}
return 0
} }
``` ```
@ -238,19 +201,16 @@ _TODO: Describe the policy._
##### Implementation sketch ##### Implementation sketch
```go ```go
// Implements CPUManagerPolicy. func (p *dynamicPolicy) Start(s State) {
type dynamicManager struct {} // TODO
func (m *dynamicManager) Init(driver CPUDriver, topo CPUTopo) {
// TODO
} }
func (m *dynamicManager) Add(c v1.Container, qos QoS) error { func (p *dynamicPolicy) RegisterContainer(s State, pod *Pod, container *Container, containerID string) error {
// TODO // TODO
} }
func (m *dynamicManager) Remove(c v1.Container, qos QoS) error { func (p *dynamicPolicy) UnregisterContainer(s State, containerID string) error {
// TODO // TODO
} }
``` ```