Delete containers when pod is deleted
This commit is contained in:
		
				
					committed by
					
						
						bindata-mockuser
					
				
			
			
				
	
			
			
			
						parent
						
							2ae16a2e60
						
					
				
				
					commit
					8bc4444f16
				
			@@ -695,3 +695,7 @@ func buildResourceToRankFunc(withImageFs bool) map[api.ResourceName]rankFunc {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return resourceToRankFunc
 | 
						return resourceToRankFunc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func PodIsEvicted(podStatus api.PodStatus) bool {
 | 
				
			||||||
 | 
						return podStatus.Phase == api.PodFailed && podStatus.Reason == reason
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2188,11 +2188,10 @@ func (kl *Kubelet) syncLoopIteration(configCh <-chan kubetypes.PodUpdate, handle
 | 
				
			|||||||
			glog.V(2).Infof("SyncLoop (PLEG): %q, event: %#v", format.Pod(pod), e)
 | 
								glog.V(2).Infof("SyncLoop (PLEG): %q, event: %#v", format.Pod(pod), e)
 | 
				
			||||||
			handler.HandlePodSyncs([]*api.Pod{pod})
 | 
								handler.HandlePodSyncs([]*api.Pod{pod})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if e.Type == pleg.ContainerDied {
 | 
							if e.Type == pleg.ContainerDied {
 | 
				
			||||||
			if podStatus, err := kl.podCache.Get(e.ID); err == nil {
 | 
					 | 
				
			||||||
			if containerID, ok := e.Data.(string); ok {
 | 
								if containerID, ok := e.Data.(string); ok {
 | 
				
			||||||
					kl.containerDeletor.deleteContainersInPod(containerID, podStatus)
 | 
									kl.cleanUpContainersInPod(e.ID, containerID)
 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	case <-syncCh:
 | 
						case <-syncCh:
 | 
				
			||||||
@@ -2922,6 +2921,16 @@ func (kl *Kubelet) ListenAndServeReadOnly(address net.IP, port uint) {
 | 
				
			|||||||
	server.ListenAndServeKubeletReadOnlyServer(kl, kl.resourceAnalyzer, address, port, kl.containerRuntime)
 | 
						server.ListenAndServeKubeletReadOnlyServer(kl, kl.resourceAnalyzer, address, port, kl.containerRuntime)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Delete the eligible dead container instances in a pod. Depending on the configuration, the latest dead containers may be kept around.
 | 
				
			||||||
 | 
					func (kl *Kubelet) cleanUpContainersInPod(podId types.UID, exitedContainerID string) {
 | 
				
			||||||
 | 
						if podStatus, err := kl.podCache.Get(podId); err == nil {
 | 
				
			||||||
 | 
							if status, ok := kl.statusManager.GetPodStatus(podId); ok {
 | 
				
			||||||
 | 
								// If a pod is evicted, we can delete all the dead containers.
 | 
				
			||||||
 | 
								kl.containerDeletor.deleteContainersInPod(exitedContainerID, podStatus, eviction.PodIsEvicted(status))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// isSyncPodWorthy filters out events that are not worthy of pod syncing
 | 
					// isSyncPodWorthy filters out events that are not worthy of pod syncing
 | 
				
			||||||
func isSyncPodWorthy(event *pleg.PodLifecycleEvent) bool {
 | 
					func isSyncPodWorthy(event *pleg.PodLifecycleEvent) bool {
 | 
				
			||||||
	// ContatnerRemoved doesn't affect pod state
 | 
						// ContatnerRemoved doesn't affect pod state
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,7 +59,7 @@ func newPodContainerDeletor(runtime kubecontainer.Runtime, containersToKeep int)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// getContainersToDeleteInPod returns the exited containers in a pod whose name matches the name inferred from exitedContainerID, ordered by the creation time from the latest to the earliest.
 | 
					// getContainersToDeleteInPod returns the exited containers in a pod whose name matches the name inferred from exitedContainerID, ordered by the creation time from the latest to the earliest.
 | 
				
			||||||
func (p *podContainerDeletor) getContainersToDeleteInPod(exitedContainerID string, podStatus *kubecontainer.PodStatus) containerStatusbyCreatedList {
 | 
					func getContainersToDeleteInPod(exitedContainerID string, podStatus *kubecontainer.PodStatus, containersToKeep int) containerStatusbyCreatedList {
 | 
				
			||||||
	var matchedContainer *kubecontainer.ContainerStatus
 | 
						var matchedContainer *kubecontainer.ContainerStatus
 | 
				
			||||||
	var exitedContainers []*kubecontainer.ContainerStatus
 | 
						var exitedContainers []*kubecontainer.ContainerStatus
 | 
				
			||||||
	// Find all exited containers in the pod
 | 
						// Find all exited containers in the pod
 | 
				
			||||||
@@ -84,17 +84,21 @@ func (p *podContainerDeletor) getContainersToDeleteInPod(exitedContainerID strin
 | 
				
			|||||||
			candidates = append(candidates, containerStatus)
 | 
								candidates = append(candidates, containerStatus)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(candidates) <= p.containersToKeep {
 | 
					
 | 
				
			||||||
 | 
						if len(candidates) <= containersToKeep {
 | 
				
			||||||
		return containerStatusbyCreatedList{}
 | 
							return containerStatusbyCreatedList{}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	sort.Sort(candidates)
 | 
						sort.Sort(candidates)
 | 
				
			||||||
	return candidates[p.containersToKeep:]
 | 
						return candidates[containersToKeep:]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// deleteContainersInPod issues container deletion requests for containers selected by getContainersToDeleteInPod.
 | 
					// deleteContainersInPod issues container deletion requests for containers selected by getContainersToDeleteInPod.
 | 
				
			||||||
func (p *podContainerDeletor) deleteContainersInPod(exitedContainerID string, podStatus *kubecontainer.PodStatus) {
 | 
					func (p *podContainerDeletor) deleteContainersInPod(exitedContainerID string, podStatus *kubecontainer.PodStatus, removeAll bool) {
 | 
				
			||||||
	for _, candidate := range p.getContainersToDeleteInPod(exitedContainerID, podStatus) {
 | 
						containersToKeep := p.containersToKeep
 | 
				
			||||||
 | 
						if removeAll {
 | 
				
			||||||
 | 
							containersToKeep = 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, candidate := range getContainersToDeleteInPod(exitedContainerID, podStatus, containersToKeep) {
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
		case p.worker <- candidate.ID:
 | 
							case p.worker <- candidate.ID:
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,6 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 | 
						kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 | 
				
			||||||
	containertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func testGetContainersToDeleteInPod(t *testing.T) {
 | 
					func testGetContainersToDeleteInPod(t *testing.T) {
 | 
				
			||||||
@@ -61,9 +60,28 @@ func testGetContainersToDeleteInPod(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	expectedCandidates := []*kubecontainer.ContainerStatus{pod.ContainerStatuses[2], pod.ContainerStatuses[1]}
 | 
						testCases := []struct {
 | 
				
			||||||
	candidates := newPodContainerDeletor(&containertest.FakeRuntime{}, 1).getContainersToDeleteInPod("2", &pod)
 | 
							containersToKeep           int
 | 
				
			||||||
	if !reflect.DeepEqual(candidates, expectedCandidates) {
 | 
							expectedContainersToDelete []*kubecontainer.ContainerStatus
 | 
				
			||||||
		t.Errorf("expected %v got %v", expectedCandidates, candidates)
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								0,
 | 
				
			||||||
 | 
								[]*kubecontainer.ContainerStatus{pod.ContainerStatuses[3], pod.ContainerStatuses[2], pod.ContainerStatuses[1]},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								1,
 | 
				
			||||||
 | 
								[]*kubecontainer.ContainerStatus{pod.ContainerStatuses[2], pod.ContainerStatuses[1]},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								2,
 | 
				
			||||||
 | 
								[]*kubecontainer.ContainerStatus{pod.ContainerStatuses[1]},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, test := range testCases {
 | 
				
			||||||
 | 
							candidates := getContainersToDeleteInPod("4", &pod, test.containersToKeep)
 | 
				
			||||||
 | 
							if !reflect.DeepEqual(getContainersToDeleteInPod("4", &pod, test.containersToKeep), test.expectedContainersToDelete) {
 | 
				
			||||||
 | 
								t.Errorf("expected %v got %v", test.expectedContainersToDelete, candidates)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user