Remove ConditionSchedulable
This commit is contained in:
parent
d6851729d2
commit
ef56dca6b6
17
docs/node.md
17
docs/node.md
@ -38,24 +38,17 @@ must have appropriate conditions, see below.
|
|||||||
|
|
||||||
### Node Condition
|
### Node Condition
|
||||||
Node Condition describes the conditions of `Running` nodes. Current valid
|
Node Condition describes the conditions of `Running` nodes. Current valid
|
||||||
conditions are `NodeReady` and `NodeSchedulable`. In the future, we plan to
|
condition is `NodeReady`. In the future, we plan to add more.
|
||||||
add more. `NodeReady` means kubelet is healthy and ready to accept pods
|
`NodeReady` means kubelet is healthy and ready to accept pods. Different
|
||||||
`NodeSchedulable` means node is allowed to schedule any new pods and is
|
condition provides different level of understanding for node health.
|
||||||
controlled by 'unschedulable' field in node spec. Different condition provides
|
Node condition is represented as a json object. For example,
|
||||||
different level of understanding for node health. Kubernetes will make a
|
the following conditions mean the node is in sane state:
|
||||||
comprehensive scheduling decision based on the information. Node condition
|
|
||||||
is represented as a json object. For example, the following conditions mean
|
|
||||||
the node is in sane state but not allowed to accept new pods:
|
|
||||||
```json
|
```json
|
||||||
"conditions": [
|
"conditions": [
|
||||||
{
|
{
|
||||||
"kind": "Ready",
|
"kind": "Ready",
|
||||||
"status": "True",
|
"status": "True",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"kind": "Schedulable",
|
|
||||||
"status": "False",
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1087,12 +1087,10 @@ type NodeConditionType string
|
|||||||
|
|
||||||
// These are valid conditions of node. Currently, we don't have enough information to decide
|
// These are valid conditions of node. Currently, we don't have enough information to decide
|
||||||
// node condition. In the future, we will add more. The proposed set of conditions are:
|
// node condition. In the future, we will add more. The proposed set of conditions are:
|
||||||
// NodeReachable, NodeLive, NodeReady, NodeSchedulable, NodeRunnable.
|
// NodeReady, NodeReachable
|
||||||
const (
|
const (
|
||||||
// NodeReady means kubelet is healthy and ready to accept pods.
|
// NodeReady means kubelet is healthy and ready to accept pods.
|
||||||
NodeReady NodeConditionType = "Ready"
|
NodeReady NodeConditionType = "Ready"
|
||||||
// NodeSchedulable means the node is ready to accept new pods.
|
|
||||||
NodeSchedulable NodeConditionType = "Schedulable"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type NodeCondition struct {
|
type NodeCondition struct {
|
||||||
|
@ -945,6 +945,7 @@ const (
|
|||||||
// NodeReady means kubelet is healthy and ready to accept pods.
|
// NodeReady means kubelet is healthy and ready to accept pods.
|
||||||
NodeReady NodeConditionKind = "Ready"
|
NodeReady NodeConditionKind = "Ready"
|
||||||
// NodeSchedulable means the node is ready to accept new pods.
|
// NodeSchedulable means the node is ready to accept new pods.
|
||||||
|
// DEPRECATED: this kind of condition is unused and has no effect even if present.
|
||||||
NodeSchedulable NodeConditionKind = "Schedulable"
|
NodeSchedulable NodeConditionKind = "Schedulable"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -954,6 +954,7 @@ const (
|
|||||||
// NodeReady means kubelet is healthy and ready to accept pods.
|
// NodeReady means kubelet is healthy and ready to accept pods.
|
||||||
NodeReady NodeConditionKind = "Ready"
|
NodeReady NodeConditionKind = "Ready"
|
||||||
// NodeSchedulable means the node is ready to accept new pods.
|
// NodeSchedulable means the node is ready to accept new pods.
|
||||||
|
// DEPRECATED: this kind of condition is unused and has no effect even if present.
|
||||||
NodeSchedulable NodeConditionKind = "Schedulable"
|
NodeSchedulable NodeConditionKind = "Schedulable"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1088,8 +1088,6 @@ type NodeConditionType string
|
|||||||
const (
|
const (
|
||||||
// NodeReady means kubelet is healthy and ready to accept pods.
|
// NodeReady means kubelet is healthy and ready to accept pods.
|
||||||
NodeReady NodeConditionType = "Ready"
|
NodeReady NodeConditionType = "Ready"
|
||||||
// NodeSchedulable means the node is ready to accept new pods.
|
|
||||||
NodeSchedulable NodeConditionType = "Schedulable"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type NodeCondition struct {
|
type NodeCondition struct {
|
||||||
|
@ -339,12 +339,6 @@ func (nc *NodeController) DoCheck(node *api.Node) []api.NodeCondition {
|
|||||||
}
|
}
|
||||||
conditions = append(conditions, *newReadyCondition)
|
conditions = append(conditions, *newReadyCondition)
|
||||||
|
|
||||||
// Check Condition: NodeSchedulable
|
|
||||||
oldSchedulableCondition := nc.getCondition(&node.Status, api.NodeSchedulable)
|
|
||||||
newSchedulableCondition := nc.checkNodeSchedulable(node)
|
|
||||||
nc.updateLastTransitionTime(oldSchedulableCondition, newSchedulableCondition)
|
|
||||||
conditions = append(conditions, *newSchedulableCondition)
|
|
||||||
|
|
||||||
return conditions
|
return conditions
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,25 +354,6 @@ func (nc *NodeController) updateLastTransitionTime(oldCondition, newCondition *a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkNodeSchedulable checks node schedulable condition, without transition timestamp set.
|
|
||||||
func (nc *NodeController) checkNodeSchedulable(node *api.Node) *api.NodeCondition {
|
|
||||||
if node.Spec.Unschedulable {
|
|
||||||
return &api.NodeCondition{
|
|
||||||
Type: api.NodeSchedulable,
|
|
||||||
Status: api.ConditionFalse,
|
|
||||||
Reason: "User marked unschedulable during node create/update",
|
|
||||||
LastProbeTime: nc.now(),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return &api.NodeCondition{
|
|
||||||
Type: api.NodeSchedulable,
|
|
||||||
Status: api.ConditionTrue,
|
|
||||||
Reason: "Node is schedulable by default",
|
|
||||||
LastProbeTime: nc.now(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkNodeReady checks raw node ready condition, without transition timestamp set.
|
// checkNodeReady checks raw node ready condition, without transition timestamp set.
|
||||||
func (nc *NodeController) checkNodeReady(node *api.Node) *api.NodeCondition {
|
func (nc *NodeController) checkNodeReady(node *api.Node) *api.NodeCondition {
|
||||||
switch status, err := nc.kubeletClient.HealthCheck(node.Name); {
|
switch status, err := nc.kubeletClient.HealthCheck(node.Name); {
|
||||||
|
@ -625,13 +625,6 @@ func TestNodeConditionsCheck(t *testing.T) {
|
|||||||
LastProbeTime: fakeNow,
|
LastProbeTime: fakeNow,
|
||||||
LastTransitionTime: fakeNow,
|
LastTransitionTime: fakeNow,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Type: api.NodeSchedulable,
|
|
||||||
Status: api.ConditionTrue,
|
|
||||||
Reason: "Node is schedulable by default",
|
|
||||||
LastProbeTime: fakeNow,
|
|
||||||
LastTransitionTime: fakeNow,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -650,18 +643,10 @@ func TestNodeConditionsCheck(t *testing.T) {
|
|||||||
LastProbeTime: fakeNow,
|
LastProbeTime: fakeNow,
|
||||||
LastTransitionTime: fakeNow,
|
LastTransitionTime: fakeNow,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Type: api.NodeSchedulable,
|
|
||||||
Status: api.ConditionTrue,
|
|
||||||
Reason: "Node is schedulable by default",
|
|
||||||
LastProbeTime: fakeNow,
|
|
||||||
LastTransitionTime: fakeNow,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// User specified node as unschedulable and kubelet /healthz probe returns failure with some error.
|
// Expected node condition to be not ready as marking Node Unschedulable does not impact Readiness.
|
||||||
// Expected node condition to be not ready and marked unschedulable.
|
|
||||||
node: &api.Node{ObjectMeta: api.ObjectMeta{Name: "node0"}, Spec: api.NodeSpec{Unschedulable: true}},
|
node: &api.Node{ObjectMeta: api.ObjectMeta{Name: "node0"}, Spec: api.NodeSpec{Unschedulable: true}},
|
||||||
fakeKubeletClient: &FakeKubeletClient{
|
fakeKubeletClient: &FakeKubeletClient{
|
||||||
Status: probe.Failure,
|
Status: probe.Failure,
|
||||||
@ -675,13 +660,6 @@ func TestNodeConditionsCheck(t *testing.T) {
|
|||||||
LastProbeTime: fakeNow,
|
LastProbeTime: fakeNow,
|
||||||
LastTransitionTime: fakeNow,
|
LastTransitionTime: fakeNow,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Type: api.NodeSchedulable,
|
|
||||||
Status: api.ConditionFalse,
|
|
||||||
Reason: "User marked unschedulable during node create/update",
|
|
||||||
LastProbeTime: fakeNow,
|
|
||||||
LastTransitionTime: fakeNow,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -764,13 +742,6 @@ func TestSyncProbedNodeStatus(t *testing.T) {
|
|||||||
LastProbeTime: fakeNow,
|
LastProbeTime: fakeNow,
|
||||||
LastTransitionTime: fakeNow,
|
LastTransitionTime: fakeNow,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Type: api.NodeSchedulable,
|
|
||||||
Status: api.ConditionTrue,
|
|
||||||
Reason: "Node is schedulable by default",
|
|
||||||
LastProbeTime: fakeNow,
|
|
||||||
LastTransitionTime: fakeNow,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Addresses: []api.NodeAddress{
|
Addresses: []api.NodeAddress{
|
||||||
{Type: api.NodeLegacyHostIP, Address: "1.2.3.4"},
|
{Type: api.NodeLegacyHostIP, Address: "1.2.3.4"},
|
||||||
@ -795,13 +766,6 @@ func TestSyncProbedNodeStatus(t *testing.T) {
|
|||||||
LastProbeTime: fakeNow,
|
LastProbeTime: fakeNow,
|
||||||
LastTransitionTime: fakeNow,
|
LastTransitionTime: fakeNow,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Type: api.NodeSchedulable,
|
|
||||||
Status: api.ConditionTrue,
|
|
||||||
Reason: "Node is schedulable by default",
|
|
||||||
LastProbeTime: fakeNow,
|
|
||||||
LastTransitionTime: fakeNow,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Addresses: []api.NodeAddress{
|
Addresses: []api.NodeAddress{
|
||||||
{Type: api.NodeLegacyHostIP, Address: "1.2.3.4"},
|
{Type: api.NodeLegacyHostIP, Address: "1.2.3.4"},
|
||||||
@ -868,12 +832,6 @@ func TestSyncProbedNodeStatusTransitionTime(t *testing.T) {
|
|||||||
Reason: "Node health check succeeded: kubelet /healthz endpoint returns ok",
|
Reason: "Node health check succeeded: kubelet /healthz endpoint returns ok",
|
||||||
LastTransitionTime: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
|
LastTransitionTime: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Type: api.NodeSchedulable,
|
|
||||||
Status: api.ConditionTrue,
|
|
||||||
Reason: "Node is schedulable by default",
|
|
||||||
LastTransitionTime: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -903,12 +861,6 @@ func TestSyncProbedNodeStatusTransitionTime(t *testing.T) {
|
|||||||
Reason: "Node health check succeeded: kubelet /healthz endpoint returns ok",
|
Reason: "Node health check succeeded: kubelet /healthz endpoint returns ok",
|
||||||
LastTransitionTime: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
|
LastTransitionTime: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Type: api.NodeSchedulable,
|
|
||||||
Status: api.ConditionTrue,
|
|
||||||
Reason: "Node is schedulable by default",
|
|
||||||
LastTransitionTime: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -482,11 +482,17 @@ func printSecretList(list *api.SecretList, w io.Writer) error {
|
|||||||
|
|
||||||
func printNode(node *api.Node, w io.Writer) error {
|
func printNode(node *api.Node, w io.Writer) error {
|
||||||
conditionMap := make(map[api.NodeConditionType]*api.NodeCondition)
|
conditionMap := make(map[api.NodeConditionType]*api.NodeCondition)
|
||||||
NodeAllConditions := []api.NodeConditionType{api.NodeSchedulable, api.NodeReady}
|
NodeAllConditions := []api.NodeConditionType{api.NodeReady}
|
||||||
for i := range node.Status.Conditions {
|
for i := range node.Status.Conditions {
|
||||||
cond := node.Status.Conditions[i]
|
cond := node.Status.Conditions[i]
|
||||||
conditionMap[cond.Type] = &cond
|
conditionMap[cond.Type] = &cond
|
||||||
}
|
}
|
||||||
|
var schedulable string
|
||||||
|
if node.Spec.Unschedulable {
|
||||||
|
schedulable = "Unschedulable"
|
||||||
|
} else {
|
||||||
|
schedulable = "Schedulable"
|
||||||
|
}
|
||||||
var status []string
|
var status []string
|
||||||
for _, validCondition := range NodeAllConditions {
|
for _, validCondition := range NodeAllConditions {
|
||||||
if condition, ok := conditionMap[validCondition]; ok {
|
if condition, ok := conditionMap[validCondition]; ok {
|
||||||
@ -500,7 +506,7 @@ func printNode(node *api.Node, w io.Writer) error {
|
|||||||
if len(status) == 0 {
|
if len(status) == 0 {
|
||||||
status = append(status, "Unknown")
|
status = append(status, "Unknown")
|
||||||
}
|
}
|
||||||
_, err := fmt.Fprintf(w, "%s\t%s\t%s\n", node.Name, formatLabels(node.Labels), strings.Join(status, ","))
|
_, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", node.Name, schedulable, formatLabels(node.Labels), strings.Join(status, ","))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,24 +579,6 @@ func TestPrintMinionStatus(t *testing.T) {
|
|||||||
},
|
},
|
||||||
status: "Unknown",
|
status: "Unknown",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
minion: api.Node{
|
|
||||||
ObjectMeta: api.ObjectMeta{Name: "foo7"},
|
|
||||||
Status: api.NodeStatus{Conditions: []api.NodeCondition{
|
|
||||||
{Type: api.NodeSchedulable, Status: api.ConditionTrue},
|
|
||||||
{Type: api.NodeReady, Status: api.ConditionTrue}}},
|
|
||||||
},
|
|
||||||
status: "Schedulable,Ready",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
minion: api.Node{
|
|
||||||
ObjectMeta: api.ObjectMeta{Name: "foo8"},
|
|
||||||
Status: api.NodeStatus{Conditions: []api.NodeCondition{
|
|
||||||
{Type: api.NodeSchedulable, Status: api.ConditionFalse},
|
|
||||||
{Type: api.NodeReady, Status: api.ConditionFalse}}},
|
|
||||||
},
|
|
||||||
status: "NotSchedulable,NotReady",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range table {
|
for _, test := range table {
|
||||||
|
@ -249,10 +249,8 @@ func (factory *ConfigFactory) pollMinions() (cache.Enumerator, error) {
|
|||||||
cond := node.Status.Conditions[i]
|
cond := node.Status.Conditions[i]
|
||||||
conditionMap[cond.Type] = &cond
|
conditionMap[cond.Type] = &cond
|
||||||
}
|
}
|
||||||
if condition, ok := conditionMap[api.NodeSchedulable]; ok {
|
if node.Spec.Unschedulable {
|
||||||
if condition.Status != api.ConditionTrue {
|
continue
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if condition, ok := conditionMap[api.NodeReady]; ok {
|
if condition, ok := conditionMap[api.NodeReady]; ok {
|
||||||
if condition.Status == api.ConditionTrue {
|
if condition.Status == api.ConditionTrue {
|
||||||
|
@ -148,10 +148,8 @@ func TestPollMinions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
ObjectMeta: api.ObjectMeta{Name: "fiz"},
|
ObjectMeta: api.ObjectMeta{Name: "fiz"},
|
||||||
Status: api.NodeStatus{
|
Spec: api.NodeSpec{
|
||||||
Conditions: []api.NodeCondition{
|
Unschedulable: false,
|
||||||
{Type: api.NodeSchedulable, Status: api.ConditionTrue},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -167,28 +165,34 @@ func TestPollMinions(t *testing.T) {
|
|||||||
ObjectMeta: api.ObjectMeta{Name: "fuz"},
|
ObjectMeta: api.ObjectMeta{Name: "fuz"},
|
||||||
Status: api.NodeStatus{
|
Status: api.NodeStatus{
|
||||||
Conditions: []api.NodeCondition{
|
Conditions: []api.NodeCondition{
|
||||||
{Type: api.NodeSchedulable, Status: api.ConditionTrue},
|
|
||||||
{Type: api.NodeReady, Status: api.ConditionTrue},
|
{Type: api.NodeReady, Status: api.ConditionTrue},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Spec: api.NodeSpec{
|
||||||
|
Unschedulable: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ObjectMeta: api.ObjectMeta{Name: "buz"},
|
ObjectMeta: api.ObjectMeta{Name: "buz"},
|
||||||
Status: api.NodeStatus{
|
Status: api.NodeStatus{
|
||||||
Conditions: []api.NodeCondition{
|
Conditions: []api.NodeCondition{
|
||||||
{Type: api.NodeSchedulable, Status: api.ConditionFalse},
|
|
||||||
{Type: api.NodeReady, Status: api.ConditionTrue},
|
{Type: api.NodeReady, Status: api.ConditionTrue},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Spec: api.NodeSpec{
|
||||||
|
Unschedulable: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ObjectMeta: api.ObjectMeta{Name: "foobar"},
|
ObjectMeta: api.ObjectMeta{Name: "foobar"},
|
||||||
Status: api.NodeStatus{
|
Status: api.NodeStatus{
|
||||||
Conditions: []api.NodeCondition{
|
Conditions: []api.NodeCondition{
|
||||||
{Type: api.NodeSchedulable, Status: api.ConditionTrue},
|
|
||||||
{Type: api.NodeReady, Status: api.ConditionFalse},
|
{Type: api.NodeReady, Status: api.ConditionFalse},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Spec: api.NodeSpec{
|
||||||
|
Unschedulable: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCount: 3,
|
expectedCount: 3,
|
||||||
@ -218,18 +222,14 @@ func TestPollMinions(t *testing.T) {
|
|||||||
minions: []api.Node{
|
minions: []api.Node{
|
||||||
{
|
{
|
||||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||||
Status: api.NodeStatus{
|
Spec: api.NodeSpec{
|
||||||
Conditions: []api.NodeCondition{
|
Unschedulable: false,
|
||||||
{Type: api.NodeSchedulable, Status: api.ConditionTrue},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ObjectMeta: api.ObjectMeta{Name: "bar"},
|
ObjectMeta: api.ObjectMeta{Name: "bar"},
|
||||||
Status: api.NodeStatus{
|
Spec: api.NodeSpec{
|
||||||
Conditions: []api.NodeCondition{
|
Unschedulable: true,
|
||||||
{Type: api.NodeSchedulable, Status: api.ConditionFalse},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user