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
0ba1b49b
Commit
0ba1b49b
authored
Jan 08, 2016
by
Matt Liggett
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
When a node becomes unreachable, do not evict DaemonSet-managed pods.
Part of the graduation requirement for DaemonSet spelled out in #15310.
parent
146a9e60
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
99 additions
and
0 deletions
+99
-0
nodecontroller.go
pkg/controller/node/nodecontroller.go
+23
-0
nodecontroller_test.go
pkg/controller/node/nodecontroller_test.go
+76
-0
No files found.
pkg/controller/node/nodecontroller.go
View file @
0ba1b49b
...
@@ -111,6 +111,9 @@ type NodeController struct {
...
@@ -111,6 +111,9 @@ type NodeController struct {
// Node framework and store
// Node framework and store
nodeController
*
framework
.
Controller
nodeController
*
framework
.
Controller
nodeStore
cache
.
StoreToNodeLister
nodeStore
cache
.
StoreToNodeLister
// DaemonSet framework and store
daemonSetController
*
framework
.
Controller
daemonSetStore
cache
.
StoreToDaemonSetLister
forcefullyDeletePod
func
(
*
api
.
Pod
)
forcefullyDeletePod
func
(
*
api
.
Pod
)
}
}
...
@@ -191,6 +194,19 @@ func NewNodeController(
...
@@ -191,6 +194,19 @@ func NewNodeController(
controller
.
NoResyncPeriodFunc
(),
controller
.
NoResyncPeriodFunc
(),
framework
.
ResourceEventHandlerFuncs
{},
framework
.
ResourceEventHandlerFuncs
{},
)
)
nc
.
daemonSetStore
.
Store
,
nc
.
daemonSetController
=
framework
.
NewInformer
(
&
cache
.
ListWatch
{
ListFunc
:
func
(
options
api
.
ListOptions
)
(
runtime
.
Object
,
error
)
{
return
nc
.
kubeClient
.
Extensions
()
.
DaemonSets
(
api
.
NamespaceAll
)
.
List
(
options
)
},
WatchFunc
:
func
(
options
api
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
return
nc
.
kubeClient
.
Extensions
()
.
DaemonSets
(
api
.
NamespaceAll
)
.
Watch
(
options
)
},
},
&
api
.
Node
{},
controller
.
NoResyncPeriodFunc
(),
framework
.
ResourceEventHandlerFuncs
{},
)
return
nc
return
nc
}
}
...
@@ -198,6 +214,8 @@ func NewNodeController(
...
@@ -198,6 +214,8 @@ func NewNodeController(
func
(
nc
*
NodeController
)
Run
(
period
time
.
Duration
)
{
func
(
nc
*
NodeController
)
Run
(
period
time
.
Duration
)
{
go
nc
.
nodeController
.
Run
(
util
.
NeverStop
)
go
nc
.
nodeController
.
Run
(
util
.
NeverStop
)
go
nc
.
podController
.
Run
(
util
.
NeverStop
)
go
nc
.
podController
.
Run
(
util
.
NeverStop
)
go
nc
.
daemonSetController
.
Run
(
util
.
NeverStop
)
// Incorporate the results of node status pushed from kubelet to master.
// Incorporate the results of node status pushed from kubelet to master.
go
util
.
Until
(
func
()
{
go
util
.
Until
(
func
()
{
if
err
:=
nc
.
monitorNodeStatus
();
err
!=
nil
{
if
err
:=
nc
.
monitorNodeStatus
();
err
!=
nil
{
...
@@ -752,6 +770,11 @@ func (nc *NodeController) deletePods(nodeName string) (bool, error) {
...
@@ -752,6 +770,11 @@ func (nc *NodeController) deletePods(nodeName string) (bool, error) {
if
pod
.
DeletionGracePeriodSeconds
!=
nil
{
if
pod
.
DeletionGracePeriodSeconds
!=
nil
{
continue
continue
}
}
// if the pod is managed by a daemonset, ignore it
_
,
err
:=
nc
.
daemonSetStore
.
GetPodDaemonSets
(
&
pod
)
if
err
==
nil
{
// No error means at least one daemonset was found
continue
}
glog
.
V
(
2
)
.
Infof
(
"Starting deletion of pod %v"
,
pod
.
Name
)
glog
.
V
(
2
)
.
Infof
(
"Starting deletion of pod %v"
,
pod
.
Name
)
nc
.
recorder
.
Eventf
(
&
pod
,
api
.
EventTypeNormal
,
"NodeControllerEviction"
,
"Marking for deletion Pod %s from Node %s"
,
pod
.
Name
,
nodeName
)
nc
.
recorder
.
Eventf
(
&
pod
,
api
.
EventTypeNormal
,
"NodeControllerEviction"
,
"Marking for deletion Pod %s from Node %s"
,
pod
.
Name
,
nodeName
)
...
...
pkg/controller/node/nodecontroller_test.go
View file @
0ba1b49b
...
@@ -26,6 +26,7 @@ import (
...
@@ -26,6 +26,7 @@ import (
apierrors
"k8s.io/kubernetes/pkg/api/errors"
apierrors
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/client/cache"
"k8s.io/kubernetes/pkg/client/cache"
client
"k8s.io/kubernetes/pkg/client/unversioned"
client
"k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/testclient"
"k8s.io/kubernetes/pkg/client/unversioned/testclient"
...
@@ -144,6 +145,7 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
...
@@ -144,6 +145,7 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
table
:=
[]
struct
{
table
:=
[]
struct
{
fakeNodeHandler
*
FakeNodeHandler
fakeNodeHandler
*
FakeNodeHandler
daemonSets
[]
extensions
.
DaemonSet
timeToPass
time
.
Duration
timeToPass
time
.
Duration
newNodeStatus
api
.
NodeStatus
newNodeStatus
api
.
NodeStatus
expectedEvictPods
bool
expectedEvictPods
bool
...
@@ -162,6 +164,7 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
...
@@ -162,6 +164,7 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
},
},
Fake
:
testclient
.
NewSimpleFake
(
&
api
.
PodList
{
Items
:
[]
api
.
Pod
{
*
newPod
(
"pod0"
,
"node0"
)}}),
Fake
:
testclient
.
NewSimpleFake
(
&
api
.
PodList
{
Items
:
[]
api
.
Pod
{
*
newPod
(
"pod0"
,
"node0"
)}}),
},
},
daemonSets
:
nil
,
timeToPass
:
0
,
timeToPass
:
0
,
newNodeStatus
:
api
.
NodeStatus
{},
newNodeStatus
:
api
.
NodeStatus
{},
expectedEvictPods
:
false
,
expectedEvictPods
:
false
,
...
@@ -190,6 +193,7 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
...
@@ -190,6 +193,7 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
},
},
Fake
:
testclient
.
NewSimpleFake
(
&
api
.
PodList
{
Items
:
[]
api
.
Pod
{
*
newPod
(
"pod0"
,
"node0"
)}}),
Fake
:
testclient
.
NewSimpleFake
(
&
api
.
PodList
{
Items
:
[]
api
.
Pod
{
*
newPod
(
"pod0"
,
"node0"
)}}),
},
},
daemonSets
:
nil
,
timeToPass
:
evictionTimeout
,
timeToPass
:
evictionTimeout
,
newNodeStatus
:
api
.
NodeStatus
{
newNodeStatus
:
api
.
NodeStatus
{
Conditions
:
[]
api
.
NodeCondition
{
Conditions
:
[]
api
.
NodeCondition
{
...
@@ -205,6 +209,72 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
...
@@ -205,6 +209,72 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
expectedEvictPods
:
false
,
expectedEvictPods
:
false
,
description
:
"Node created long time ago, and kubelet posted NotReady for a short period of time."
,
description
:
"Node created long time ago, and kubelet posted NotReady for a short period of time."
,
},
},
// Pod is ds-managed, and kubelet posted NotReady for a long period of time.
{
fakeNodeHandler
:
&
FakeNodeHandler
{
Existing
:
[]
*
api
.
Node
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"node0"
,
CreationTimestamp
:
unversioned
.
Date
(
2012
,
1
,
1
,
0
,
0
,
0
,
0
,
time
.
UTC
),
},
Status
:
api
.
NodeStatus
{
Conditions
:
[]
api
.
NodeCondition
{
{
Type
:
api
.
NodeReady
,
Status
:
api
.
ConditionFalse
,
LastHeartbeatTime
:
unversioned
.
Date
(
2015
,
1
,
1
,
12
,
0
,
0
,
0
,
time
.
UTC
),
LastTransitionTime
:
unversioned
.
Date
(
2015
,
1
,
1
,
12
,
0
,
0
,
0
,
time
.
UTC
),
},
},
},
},
},
Fake
:
testclient
.
NewSimpleFake
(
&
api
.
PodList
{
Items
:
[]
api
.
Pod
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"pod0"
,
Namespace
:
"default"
,
Labels
:
map
[
string
]
string
{
"daemon"
:
"yes"
},
},
Spec
:
api
.
PodSpec
{
NodeName
:
"node0"
,
},
},
},
},
),
},
daemonSets
:
[]
extensions
.
DaemonSet
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"ds0"
,
Namespace
:
"default"
,
},
Spec
:
extensions
.
DaemonSetSpec
{
Selector
:
&
extensions
.
LabelSelector
{
MatchLabels
:
map
[
string
]
string
{
"daemon"
:
"yes"
},
},
},
},
},
timeToPass
:
time
.
Hour
,
newNodeStatus
:
api
.
NodeStatus
{
Conditions
:
[]
api
.
NodeCondition
{
{
Type
:
api
.
NodeReady
,
Status
:
api
.
ConditionFalse
,
// Node status has just been updated, and is NotReady for 1hr.
LastHeartbeatTime
:
unversioned
.
Date
(
2015
,
1
,
1
,
12
,
59
,
0
,
0
,
time
.
UTC
),
LastTransitionTime
:
unversioned
.
Date
(
2015
,
1
,
1
,
12
,
0
,
0
,
0
,
time
.
UTC
),
},
},
},
expectedEvictPods
:
false
,
description
:
"Pod is ds-managed, and kubelet posted NotReady for a long period of time."
,
},
// Node created long time ago, and kubelet posted NotReady for a long period of time.
// Node created long time ago, and kubelet posted NotReady for a long period of time.
{
{
fakeNodeHandler
:
&
FakeNodeHandler
{
fakeNodeHandler
:
&
FakeNodeHandler
{
...
@@ -228,6 +298,7 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
...
@@ -228,6 +298,7 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
},
},
Fake
:
testclient
.
NewSimpleFake
(
&
api
.
PodList
{
Items
:
[]
api
.
Pod
{
*
newPod
(
"pod0"
,
"node0"
)}}),
Fake
:
testclient
.
NewSimpleFake
(
&
api
.
PodList
{
Items
:
[]
api
.
Pod
{
*
newPod
(
"pod0"
,
"node0"
)}}),
},
},
daemonSets
:
nil
,
timeToPass
:
time
.
Hour
,
timeToPass
:
time
.
Hour
,
newNodeStatus
:
api
.
NodeStatus
{
newNodeStatus
:
api
.
NodeStatus
{
Conditions
:
[]
api
.
NodeCondition
{
Conditions
:
[]
api
.
NodeCondition
{
...
@@ -266,6 +337,7 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
...
@@ -266,6 +337,7 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
},
},
Fake
:
testclient
.
NewSimpleFake
(
&
api
.
PodList
{
Items
:
[]
api
.
Pod
{
*
newPod
(
"pod0"
,
"node0"
)}}),
Fake
:
testclient
.
NewSimpleFake
(
&
api
.
PodList
{
Items
:
[]
api
.
Pod
{
*
newPod
(
"pod0"
,
"node0"
)}}),
},
},
daemonSets
:
nil
,
timeToPass
:
evictionTimeout
-
testNodeMonitorGracePeriod
,
timeToPass
:
evictionTimeout
-
testNodeMonitorGracePeriod
,
newNodeStatus
:
api
.
NodeStatus
{
newNodeStatus
:
api
.
NodeStatus
{
Conditions
:
[]
api
.
NodeCondition
{
Conditions
:
[]
api
.
NodeCondition
{
...
@@ -304,6 +376,7 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
...
@@ -304,6 +376,7 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
},
},
Fake
:
testclient
.
NewSimpleFake
(
&
api
.
PodList
{
Items
:
[]
api
.
Pod
{
*
newPod
(
"pod0"
,
"node0"
)}}),
Fake
:
testclient
.
NewSimpleFake
(
&
api
.
PodList
{
Items
:
[]
api
.
Pod
{
*
newPod
(
"pod0"
,
"node0"
)}}),
},
},
daemonSets
:
nil
,
timeToPass
:
60
*
time
.
Minute
,
timeToPass
:
60
*
time
.
Minute
,
newNodeStatus
:
api
.
NodeStatus
{
newNodeStatus
:
api
.
NodeStatus
{
Conditions
:
[]
api
.
NodeCondition
{
Conditions
:
[]
api
.
NodeCondition
{
...
@@ -326,6 +399,9 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
...
@@ -326,6 +399,9 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) {
evictionTimeout
,
util
.
NewFakeRateLimiter
(),
util
.
NewFakeRateLimiter
(),
testNodeMonitorGracePeriod
,
evictionTimeout
,
util
.
NewFakeRateLimiter
(),
util
.
NewFakeRateLimiter
(),
testNodeMonitorGracePeriod
,
testNodeStartupGracePeriod
,
testNodeMonitorPeriod
,
nil
,
false
)
testNodeStartupGracePeriod
,
testNodeMonitorPeriod
,
nil
,
false
)
nodeController
.
now
=
func
()
unversioned
.
Time
{
return
fakeNow
}
nodeController
.
now
=
func
()
unversioned
.
Time
{
return
fakeNow
}
for
_
,
ds
:=
range
item
.
daemonSets
{
nodeController
.
daemonSetStore
.
Add
(
&
ds
)
}
if
err
:=
nodeController
.
monitorNodeStatus
();
err
!=
nil
{
if
err
:=
nodeController
.
monitorNodeStatus
();
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
t
.
Errorf
(
"unexpected error: %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