Commit d624c7de authored by feisky's avatar feisky

Pass the ContainerGCPolicy in Runtime.GarbageCollect

parent 69867fb5
...@@ -860,7 +860,7 @@ func CreateAndInitKubelet(kc *KubeletConfig) (k KubeletBootstrap, pc *config.Pod ...@@ -860,7 +860,7 @@ func CreateAndInitKubelet(kc *KubeletConfig) (k KubeletBootstrap, pc *config.Pod
kubeClient = kc.KubeClient kubeClient = kc.KubeClient
} }
gcPolicy := kubelet.ContainerGCPolicy{ gcPolicy := kubecontainer.ContainerGCPolicy{
MinAge: kc.MinimumGCAge, MinAge: kc.MinimumGCAge,
MaxPerPodContainer: kc.MaxPerPodContainerCount, MaxPerPodContainer: kc.MaxPerPodContainerCount,
MaxContainers: kc.MaxContainerCount, MaxContainers: kc.MaxContainerCount,
......
...@@ -14,13 +14,11 @@ See the License for the specific language governing permissions and ...@@ -14,13 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kubelet package container
import ( import (
"fmt" "fmt"
"time" "time"
"k8s.io/kubernetes/pkg/kubelet/container"
) )
// Specified a policy for garbage collecting containers. // Specified a policy for garbage collecting containers.
...@@ -39,7 +37,7 @@ type ContainerGCPolicy struct { ...@@ -39,7 +37,7 @@ type ContainerGCPolicy struct {
// Manages garbage collection of dead containers. // Manages garbage collection of dead containers.
// //
// Implementation is thread-compatible. // Implementation is thread-compatible.
type containerGC interface { type ContainerGC interface {
// Garbage collect containers. // Garbage collect containers.
GarbageCollect() error GarbageCollect() error
} }
...@@ -47,14 +45,14 @@ type containerGC interface { ...@@ -47,14 +45,14 @@ type containerGC interface {
// TODO(vmarmol): Preferentially remove pod infra containers. // TODO(vmarmol): Preferentially remove pod infra containers.
type realContainerGC struct { type realContainerGC struct {
// Container runtime // Container runtime
runtime container.Runtime runtime Runtime
// Policy for garbage collection. // Policy for garbage collection.
policy ContainerGCPolicy policy ContainerGCPolicy
} }
// New containerGC instance with the specified policy. // New ContainerGC instance with the specified policy.
func newContainerGC(runtime container.Runtime, policy ContainerGCPolicy) (containerGC, error) { func NewContainerGC(runtime Runtime, policy ContainerGCPolicy) (ContainerGC, error) {
if policy.MinAge < 0 { if policy.MinAge < 0 {
return nil, fmt.Errorf("invalid minimum garbage collection age: %v", policy.MinAge) return nil, fmt.Errorf("invalid minimum garbage collection age: %v", policy.MinAge)
} }
...@@ -66,5 +64,5 @@ func newContainerGC(runtime container.Runtime, policy ContainerGCPolicy) (contai ...@@ -66,5 +64,5 @@ func newContainerGC(runtime container.Runtime, policy ContainerGCPolicy) (contai
} }
func (cgc *realContainerGC) GarbageCollect() error { func (cgc *realContainerGC) GarbageCollect() error {
return cgc.runtime.GarbageCollect(cgc.policy.MaxPerPodContainer, cgc.policy.MaxContainers, cgc.policy.MinAge) return cgc.runtime.GarbageCollect(cgc.policy)
} }
...@@ -305,7 +305,7 @@ func (f *FakeRuntime) PortForward(pod *Pod, port uint16, stream io.ReadWriteClos ...@@ -305,7 +305,7 @@ func (f *FakeRuntime) PortForward(pod *Pod, port uint16, stream io.ReadWriteClos
return f.Err return f.Err
} }
func (f *FakeRuntime) GarbageCollect(maxPerPodContainer, maxContainers int, minAge time.Duration) error { func (f *FakeRuntime) GarbageCollect(gcPolicy ContainerGCPolicy) error {
f.Lock() f.Lock()
defer f.Unlock() defer f.Unlock()
......
...@@ -22,7 +22,6 @@ import ( ...@@ -22,7 +22,6 @@ import (
"io" "io"
"reflect" "reflect"
"strings" "strings"
"time"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
...@@ -75,8 +74,8 @@ type Runtime interface { ...@@ -75,8 +74,8 @@ type Runtime interface {
// specifies whether the runtime returns all containers including those already // specifies whether the runtime returns all containers including those already
// exited and dead containers (used for garbage collection). // exited and dead containers (used for garbage collection).
GetPods(all bool) ([]*Pod, error) GetPods(all bool) ([]*Pod, error)
// Garbage collection of dead containers // GarbageCollect removes dead containers using the specified container gc policy
GarbageCollect(maxPerPodContainer, maxContainers int, minAge time.Duration) error GarbageCollect(gcPolicy ContainerGCPolicy) error
// Syncs the running pod into the desired pod. // Syncs the running pod into the desired pod.
SyncPod(pod *api.Pod, runningPod Pod, podStatus api.PodStatus, pullSecrets []api.Secret, backOff *util.Backoff) error SyncPod(pod *api.Pod, runningPod Pod, podStatus api.PodStatus, pullSecrets []api.Secret, backOff *util.Backoff) error
// KillPod kills all the containers of a pod. Pod may be nil, running pod must not be. // KillPod kills all the containers of a pod. Pod may be nil, running pod must not be.
......
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
docker "github.com/fsouza/go-dockerclient" docker "github.com/fsouza/go-dockerclient"
"github.com/golang/glog" "github.com/golang/glog"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/types"
) )
...@@ -172,10 +173,10 @@ func (cgc *containerGC) evictableContainers(minAge time.Duration) (containersByE ...@@ -172,10 +173,10 @@ func (cgc *containerGC) evictableContainers(minAge time.Duration) (containersByE
return evictUnits, unidentifiedContainers, nil return evictUnits, unidentifiedContainers, nil
} }
// Garbage collection of dead containers // GarbageCollect removes dead containers using the specified container gc policy
func (cgc *containerGC) GarbageCollect(maxPerPodContainer, maxContainers int, minAge time.Duration) error { func (cgc *containerGC) GarbageCollect(gcPolicy kubecontainer.ContainerGCPolicy) error {
// Separate containers by evict units. // Separate containers by evict units.
evictUnits, unidentifiedContainers, err := cgc.evictableContainers(minAge) evictUnits, unidentifiedContainers, err := cgc.evictableContainers(gcPolicy.MinAge)
if err != nil { if err != nil {
return err return err
} }
...@@ -190,14 +191,14 @@ func (cgc *containerGC) GarbageCollect(maxPerPodContainer, maxContainers int, mi ...@@ -190,14 +191,14 @@ func (cgc *containerGC) GarbageCollect(maxPerPodContainer, maxContainers int, mi
} }
// Enforce max containers per evict unit. // Enforce max containers per evict unit.
if maxPerPodContainer >= 0 { if gcPolicy.MaxPerPodContainer >= 0 {
cgc.enforceMaxContainersPerEvictUnit(evictUnits, maxPerPodContainer) cgc.enforceMaxContainersPerEvictUnit(evictUnits, gcPolicy.MaxPerPodContainer)
} }
// Enforce max total number of containers. // Enforce max total number of containers.
if maxContainers >= 0 && evictUnits.NumContainers() > maxContainers { if gcPolicy.MaxContainers >= 0 && evictUnits.NumContainers() > gcPolicy.MaxContainers {
// Leave an equal number of containers per evict unit (min: 1). // Leave an equal number of containers per evict unit (min: 1).
numContainersPerEvictUnit := maxContainers / evictUnits.NumEvictUnits() numContainersPerEvictUnit := gcPolicy.MaxContainers / evictUnits.NumEvictUnits()
if numContainersPerEvictUnit < 1 { if numContainersPerEvictUnit < 1 {
numContainersPerEvictUnit = 1 numContainersPerEvictUnit = 1
} }
...@@ -205,14 +206,14 @@ func (cgc *containerGC) GarbageCollect(maxPerPodContainer, maxContainers int, mi ...@@ -205,14 +206,14 @@ func (cgc *containerGC) GarbageCollect(maxPerPodContainer, maxContainers int, mi
// If we still need to evict, evict oldest first. // If we still need to evict, evict oldest first.
numContainers := evictUnits.NumContainers() numContainers := evictUnits.NumContainers()
if numContainers > maxContainers { if numContainers > gcPolicy.MaxContainers {
flattened := make([]containerGCInfo, 0, numContainers) flattened := make([]containerGCInfo, 0, numContainers)
for uid := range evictUnits { for uid := range evictUnits {
flattened = append(flattened, evictUnits[uid]...) flattened = append(flattened, evictUnits[uid]...)
} }
sort.Sort(byCreated(flattened)) sort.Sort(byCreated(flattened))
cgc.removeOldestN(flattened, numContainers-maxContainers) cgc.removeOldestN(flattened, numContainers-gcPolicy.MaxContainers)
} }
} }
......
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
docker "github.com/fsouza/go-dockerclient" docker "github.com/fsouza/go-dockerclient"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
) )
func newTestContainerGC(t *testing.T) (*containerGC, *FakeDockerClient) { func newTestContainerGC(t *testing.T) (*containerGC, *FakeDockerClient) {
...@@ -92,7 +93,7 @@ func TestGarbageCollectZeroMaxContainers(t *testing.T) { ...@@ -92,7 +93,7 @@ func TestGarbageCollectZeroMaxContainers(t *testing.T) {
makeContainerDetail("1876", false, makeTime(0)), makeContainerDetail("1876", false, makeTime(0)),
) )
assert.Nil(t, gc.GarbageCollect(1, 0, time.Minute)) assert.Nil(t, gc.GarbageCollect(kubecontainer.ContainerGCPolicy{time.Minute, 1, 0}))
assert.Len(t, fakeDocker.Removed, 1) assert.Len(t, fakeDocker.Removed, 1)
} }
...@@ -113,7 +114,7 @@ func TestGarbageCollectNoMaxPerPodContainerLimit(t *testing.T) { ...@@ -113,7 +114,7 @@ func TestGarbageCollectNoMaxPerPodContainerLimit(t *testing.T) {
makeContainerDetail("5876", false, makeTime(4)), makeContainerDetail("5876", false, makeTime(4)),
) )
assert.Nil(t, gc.GarbageCollect(-1, 4, time.Minute)) assert.Nil(t, gc.GarbageCollect(kubecontainer.ContainerGCPolicy{time.Minute, -1, 4}))
assert.Len(t, fakeDocker.Removed, 1) assert.Len(t, fakeDocker.Removed, 1)
} }
...@@ -134,7 +135,7 @@ func TestGarbageCollectNoMaxLimit(t *testing.T) { ...@@ -134,7 +135,7 @@ func TestGarbageCollectNoMaxLimit(t *testing.T) {
makeContainerDetail("5876", false, makeTime(0)), makeContainerDetail("5876", false, makeTime(0)),
) )
assert.Nil(t, gc.GarbageCollect(1, -1, time.Minute)) assert.Nil(t, gc.GarbageCollect(kubecontainer.ContainerGCPolicy{time.Minute, 1, -1}))
assert.Len(t, fakeDocker.Removed, 0) assert.Len(t, fakeDocker.Removed, 0)
} }
...@@ -306,7 +307,7 @@ func TestGarbageCollect(t *testing.T) { ...@@ -306,7 +307,7 @@ func TestGarbageCollect(t *testing.T) {
gc, fakeDocker := newTestContainerGC(t) gc, fakeDocker := newTestContainerGC(t)
fakeDocker.ContainerList = test.containers fakeDocker.ContainerList = test.containers
fakeDocker.ContainerMap = test.containerDetails fakeDocker.ContainerMap = test.containerDetails
assert.Nil(t, gc.GarbageCollect(2, 6, time.Hour)) assert.Nil(t, gc.GarbageCollect(kubecontainer.ContainerGCPolicy{time.Hour, 2, 6}))
verifyStringArrayEqualsAnyOrder(t, fakeDocker.Removed, test.expectedRemoved) verifyStringArrayEqualsAnyOrder(t, fakeDocker.Removed, test.expectedRemoved)
} }
} }
...@@ -2025,6 +2025,6 @@ func (dm *DockerManager) GetNetNs(containerID kubecontainer.ContainerID) (string ...@@ -2025,6 +2025,6 @@ func (dm *DockerManager) GetNetNs(containerID kubecontainer.ContainerID) (string
} }
// Garbage collection of dead containers // Garbage collection of dead containers
func (dm *DockerManager) GarbageCollect(maxPerPodContainer, maxContainers int, minAge time.Duration) error { func (dm *DockerManager) GarbageCollect(gcPolicy kubecontainer.ContainerGCPolicy) error {
return dm.containerGC.GarbageCollect(maxPerPodContainer, maxContainers, minAge) return dm.containerGC.GarbageCollect(gcPolicy)
} }
...@@ -147,7 +147,7 @@ func NewMainKubelet( ...@@ -147,7 +147,7 @@ func NewMainKubelet(
pullBurst int, pullBurst int,
eventQPS float32, eventQPS float32,
eventBurst int, eventBurst int,
containerGCPolicy ContainerGCPolicy, containerGCPolicy kubecontainer.ContainerGCPolicy,
sourcesReady SourcesReadyFn, sourcesReady SourcesReadyFn,
registerNode bool, registerNode bool,
standaloneMode bool, standaloneMode bool,
...@@ -356,7 +356,7 @@ func NewMainKubelet( ...@@ -356,7 +356,7 @@ func NewMainKubelet(
} }
// setup containerGC // setup containerGC
containerGC, err := newContainerGC(klet.containerRuntime, containerGCPolicy) containerGC, err := kubecontainer.NewContainerGC(klet.containerRuntime, containerGCPolicy)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -511,7 +511,7 @@ type Kubelet struct { ...@@ -511,7 +511,7 @@ type Kubelet struct {
recorder record.EventRecorder recorder record.EventRecorder
// Policy for handling garbage collection of dead containers. // Policy for handling garbage collection of dead containers.
containerGC containerGC containerGC kubecontainer.ContainerGC
// Manager for images. // Manager for images.
imageManager imageManager imageManager imageManager
......
...@@ -1083,7 +1083,7 @@ func (r *Runtime) GetContainerLogs(pod *api.Pod, containerID kubecontainer.Conta ...@@ -1083,7 +1083,7 @@ func (r *Runtime) GetContainerLogs(pod *api.Pod, containerID kubecontainer.Conta
// GarbageCollect collects the pods/containers. // GarbageCollect collects the pods/containers.
// TODO(yifan): Enforce the gc policy, also, it would be better if we can // TODO(yifan): Enforce the gc policy, also, it would be better if we can
// just GC kubernetes pods. // just GC kubernetes pods.
func (r *runtime) GarbageCollect(maxPerPodContainer, maxContainers int, minAge time.Duration) error { func (r *runtime) GarbageCollect(gcPolicy kubecontainer.ContainerGCPolicy) error {
if err := exec.Command("systemctl", "reset-failed").Run(); err != nil { if err := exec.Command("systemctl", "reset-failed").Run(); err != nil {
glog.Errorf("rkt: Failed to reset failed systemd services: %v", err) glog.Errorf("rkt: Failed to reset failed systemd services: %v", err)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment