Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
d44e9b48
Commit
d44e9b48
authored
Apr 20, 2015
by
Victor Marmol
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7048 from yujuhong/para_cleanup
Kubelet: parallelize cleaning up containers in unwanted pods
parents
b37328a5
27500217
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
85 additions
and
38 deletions
+85
-38
manager.go
pkg/kubelet/dockertools/manager.go
+1
-1
kubelet.go
pkg/kubelet/kubelet.go
+84
-37
No files found.
pkg/kubelet/dockertools/manager.go
View file @
d44e9b48
...
@@ -375,7 +375,7 @@ func (dm *DockerManager) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) {
...
@@ -375,7 +375,7 @@ func (dm *DockerManager) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) {
}
}
func
(
dm
*
DockerManager
)
GetRunningContainers
(
ids
[]
string
)
([]
*
docker
.
Container
,
error
)
{
func
(
dm
*
DockerManager
)
GetRunningContainers
(
ids
[]
string
)
([]
*
docker
.
Container
,
error
)
{
result
:=
[]
*
docker
.
Container
{}
var
result
[]
*
docker
.
Container
if
dm
.
client
==
nil
{
if
dm
.
client
==
nil
{
return
nil
,
fmt
.
Errorf
(
"unexpected nil docker client."
)
return
nil
,
fmt
.
Errorf
(
"unexpected nil docker client."
)
}
}
...
...
pkg/kubelet/kubelet.go
View file @
d44e9b48
...
@@ -937,17 +937,27 @@ func (kl *Kubelet) pullImage(img string, ref *api.ObjectReference) error {
...
@@ -937,17 +937,27 @@ func (kl *Kubelet) pullImage(img string, ref *api.ObjectReference) error {
}
}
// Kill all running containers in a pod (includes the pod infra container).
// Kill all running containers in a pod (includes the pod infra container).
func
(
kl
*
Kubelet
)
killPod
(
runningP
od
kubecontainer
.
Pod
)
error
{
func
(
kl
*
Kubelet
)
killPod
(
p
od
kubecontainer
.
Pod
)
error
{
// Send the kills in parallel since they may take a long time.
// Send the kills in parallel since they may take a long time.
errs
:=
make
(
chan
error
,
len
(
runningP
od
.
Containers
))
errs
:=
make
(
chan
error
,
len
(
p
od
.
Containers
))
wg
:=
sync
.
WaitGroup
{}
wg
:=
sync
.
WaitGroup
{}
for
_
,
container
:=
range
runningP
od
.
Containers
{
for
_
,
container
:=
range
p
od
.
Containers
{
wg
.
Add
(
1
)
wg
.
Add
(
1
)
go
func
(
container
*
kubecontainer
.
Container
)
{
go
func
(
container
*
kubecontainer
.
Container
)
{
defer
util
.
HandleCrash
()
defer
util
.
HandleCrash
()
// Call the networking plugin for teardown.
// TODO: Handle this without signaling the pod infra container to
// adapt to the generic container runtime.
if
container
.
Name
==
dockertools
.
PodInfraContainerName
{
err
:=
kl
.
networkPlugin
.
TearDownPod
(
pod
.
Namespace
,
pod
.
Name
,
dockertools
.
DockerID
(
container
.
ID
))
if
err
!=
nil
{
glog
.
Errorf
(
"Failed tearing down the infra container: %v"
,
err
)
errs
<-
err
}
}
err
:=
kl
.
killContainer
(
container
)
err
:=
kl
.
killContainer
(
container
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
Errorf
(
"Failed to delete container: %v; Skipping pod %q"
,
err
,
runningP
od
.
ID
)
glog
.
Errorf
(
"Failed to delete container: %v; Skipping pod %q"
,
err
,
p
od
.
ID
)
errs
<-
err
errs
<-
err
}
}
wg
.
Done
()
wg
.
Done
()
...
@@ -1330,7 +1340,7 @@ func getDesiredVolumes(pods []*api.Pod) map[string]api.Volume {
...
@@ -1330,7 +1340,7 @@ func getDesiredVolumes(pods []*api.Pod) map[string]api.Volume {
return
desiredVolumes
return
desiredVolumes
}
}
func
(
kl
*
Kubelet
)
cleanupOrphanedPods
(
pods
[]
*
api
.
Pod
)
error
{
func
(
kl
*
Kubelet
)
cleanupOrphanedPod
Dir
s
(
pods
[]
*
api
.
Pod
)
error
{
desired
:=
util
.
NewStringSet
()
desired
:=
util
.
NewStringSet
()
for
_
,
pod
:=
range
pods
{
for
_
,
pod
:=
range
pods
{
desired
.
Insert
(
string
(
pod
.
UID
))
desired
.
Insert
(
string
(
pod
.
UID
))
...
@@ -1452,48 +1462,25 @@ func (kl *Kubelet) SyncPods(allPods []*api.Pod, podSyncTypes map[types.UID]metri
...
@@ -1452,48 +1462,25 @@ func (kl *Kubelet) SyncPods(allPods []*api.Pod, podSyncTypes map[types.UID]metri
return
nil
return
nil
}
}
// Kill any containers we don't need.
// Kill containers associated with unwanted pods and get a list of
killed
:=
[]
string
{}
// unwanted containers that are still running.
for
_
,
pod
:=
range
runningPods
{
running
,
err
:=
kl
.
killUnwantedPods
(
desiredPods
,
runningPods
)
if
_
,
found
:=
desiredPods
[
pod
.
ID
];
found
{
// syncPod() will handle this one.
continue
}
// Kill all the containers in the unidentified pod.
for
_
,
c
:=
range
pod
.
Containers
{
// call the networking plugin for teardown
if
c
.
Name
==
dockertools
.
PodInfraContainerName
{
err
:=
kl
.
networkPlugin
.
TearDownPod
(
pod
.
Namespace
,
pod
.
Name
,
dockertools
.
DockerID
(
c
.
ID
))
if
err
!=
nil
{
glog
.
Errorf
(
"Network plugin pre-delete method returned an error: %v"
,
err
)
}
}
glog
.
V
(
1
)
.
Infof
(
"Killing unwanted container %+v"
,
c
)
err
=
kl
.
killContainer
(
c
)
if
err
!=
nil
{
glog
.
Errorf
(
"Error killing container %+v: %v"
,
c
,
err
)
}
else
{
killed
=
append
(
killed
,
string
(
c
.
ID
))
}
}
}
running
,
err
:=
kl
.
containerManager
.
GetRunningContainers
(
killed
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
Errorf
(
"Failed
to poll container state
: %v"
,
err
)
glog
.
Errorf
(
"Failed
killing unwanted containers
: %v"
,
err
)
return
err
return
err
}
}
// Remove any orphaned volumes.
// Remove any orphaned volumes.
err
=
kl
.
cleanupOrphanedVolumes
(
pods
,
running
)
err
=
kl
.
cleanupOrphanedVolumes
(
pods
,
running
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
Errorf
(
"Failed cleaning up orphaned volumes: %v"
,
err
)
return
err
return
err
}
}
// Remove any orphaned pods.
// Remove any orphaned pod
directorie
s.
err
=
kl
.
cleanupOrphanedPods
(
pods
)
err
=
kl
.
cleanupOrphanedPod
Dir
s
(
pods
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
Errorf
(
"Failed cleaning up orphaned pod directories: %v"
,
err
)
return
err
return
err
}
}
...
@@ -1503,6 +1490,67 @@ func (kl *Kubelet) SyncPods(allPods []*api.Pod, podSyncTypes map[types.UID]metri
...
@@ -1503,6 +1490,67 @@ func (kl *Kubelet) SyncPods(allPods []*api.Pod, podSyncTypes map[types.UID]metri
return
err
return
err
}
}
// killUnwantedPods kills the unwanted, running pods in parallel, and returns
// containers in those pods that it failed to terminate.
func
(
kl
*
Kubelet
)
killUnwantedPods
(
desiredPods
map
[
types
.
UID
]
empty
,
runningPods
[]
*
kubecontainer
.
Pod
)
([]
*
docker
.
Container
,
error
)
{
type
result
struct
{
containers
[]
*
docker
.
Container
err
error
}
ch
:=
make
(
chan
result
,
len
(
runningPods
))
defer
close
(
ch
)
numWorkers
:=
0
for
_
,
pod
:=
range
runningPods
{
if
_
,
found
:=
desiredPods
[
pod
.
ID
];
found
{
// Per-pod workers will handle the desired pods.
continue
}
numWorkers
++
go
func
(
pod
*
kubecontainer
.
Pod
,
ch
chan
result
)
{
defer
func
()
{
// Send the IDs of the containers that we failed to killed.
containers
,
err
:=
kl
.
getRunningContainersByPod
(
pod
)
ch
<-
result
{
containers
:
containers
,
err
:
err
}
}()
glog
.
V
(
1
)
.
Infof
(
"Killing unwanted pod %q"
,
pod
.
Name
)
// Stop the containers.
err
:=
kl
.
killPod
(
*
pod
)
if
err
!=
nil
{
glog
.
Errorf
(
"Failed killing the pod %q: %v"
,
pod
.
Name
,
err
)
return
}
// Remove the pod directory.
err
=
os
.
RemoveAll
(
kl
.
getPodDir
(
pod
.
ID
))
if
err
!=
nil
{
glog
.
Errorf
(
"Failed removing pod directory for %q"
,
pod
.
Name
)
return
}
}(
pod
,
ch
)
}
// Aggregate results from the pod killing workers.
var
errs
[]
error
var
running
[]
*
docker
.
Container
for
i
:=
0
;
i
<
numWorkers
;
i
++
{
m
:=
<-
ch
if
m
.
err
!=
nil
{
errs
=
append
(
errs
,
m
.
err
)
continue
}
running
=
append
(
running
,
m
.
containers
...
)
}
return
running
,
utilErrors
.
NewAggregate
(
errs
)
}
func
(
kl
*
Kubelet
)
getRunningContainersByPod
(
pod
*
kubecontainer
.
Pod
)
([]
*
docker
.
Container
,
error
)
{
containerIDs
:=
make
([]
string
,
len
(
pod
.
Containers
))
for
i
,
c
:=
range
pod
.
Containers
{
containerIDs
[
i
]
=
string
(
c
.
ID
)
}
return
kl
.
containerManager
.
GetRunningContainers
(
containerIDs
)
}
type
podsByCreationTime
[]
*
api
.
Pod
type
podsByCreationTime
[]
*
api
.
Pod
func
(
s
podsByCreationTime
)
Len
()
int
{
func
(
s
podsByCreationTime
)
Len
()
int
{
...
@@ -1627,7 +1675,6 @@ func (kl *Kubelet) syncLoop(updates <-chan PodUpdate, handler SyncHandler) {
...
@@ -1627,7 +1675,6 @@ func (kl *Kubelet) syncLoop(updates <-chan PodUpdate, handler SyncHandler) {
unsyncedPod
=
false
unsyncedPod
=
false
}
}
}
}
pods
,
mirrorPods
:=
kl
.
podManager
.
GetPodsAndMirrorMap
()
pods
,
mirrorPods
:=
kl
.
podManager
.
GetPodsAndMirrorMap
()
if
err
:=
handler
.
SyncPods
(
pods
,
podSyncTypes
,
mirrorPods
,
start
);
err
!=
nil
{
if
err
:=
handler
.
SyncPods
(
pods
,
podSyncTypes
,
mirrorPods
,
start
);
err
!=
nil
{
glog
.
Errorf
(
"Couldn't sync containers: %v"
,
err
)
glog
.
Errorf
(
"Couldn't sync containers: %v"
,
err
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment