Commit ef56dca6 authored by gmarek's avatar gmarek

Remove ConditionSchedulable

parent d6851729
...@@ -38,24 +38,17 @@ must have appropriate conditions, see below. ...@@ -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 ...@@ -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 ( ...@@ -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 ( ...@@ -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 ...@@ -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 { ...@@ -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 ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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 { ...@@ -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 { ...@@ -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) { ...@@ -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,11 +249,9 @@ func (factory *ConfigFactory) pollMinions() (cache.Enumerator, error) { ...@@ -249,11 +249,9 @@ 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 {
nodes.Items = append(nodes.Items, node) nodes.Items = append(nodes.Items, node)
......
...@@ -148,10 +148,8 @@ func TestPollMinions(t *testing.T) { ...@@ -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) { ...@@ -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) { ...@@ -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},
},
}, },
}, },
}, },
......
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