How to identify schedulable nodes in Kubernetes

12/27/2016

I'd like to (programatically) get a list of all schedulable nodes in my kubernetes cluster.

I'm fairly sure this used to be possible by looking at .spec.unschedulable in the full output of kubectl get nodes (using JSON or template output), but now it seems this info is inside the scheduler.alpha.kubernetes.io/taints key, which is much harder to parse and just doesn't feel like the right place.

Is there some other way to find this info? Am I missing something obvious? I'm using version 1.5.1 currently.

UPDATE: I can almost get there with some Go templating:

$ kubectl get nodes -o go-template='{{range .items}}{{with $x := index .metadata.annotations "scheduler.alpha.kubernetes.io/taints"}}{{.}}{{end}}{{end}}'
[{"key":"dedicated","value":"master","effect":"NoSchedule"}]

But that leaves me with a blob of JSON that I can't parse in the template, and I still have to invert the results and get the node name out.

UPDATE 2: Apparently unschedulable nodes should have .spec.unschedulable set. This doesn't seem to always be the case; not sure if it's due to a bug or a misunderstanding on my part.

-- Adrian Mouat
kubernetes

3 Answers

4/5/2018

Though quite late to the party, I needed something of the similar today to determine when the scheduling of pods would actually start succeeding:

kubectl get nodes -o jsonpath="{range .items[*]}{.metadata.name} {.spec.taints[?(@.effect=='NoSchedule')].effect}{\"\n\"}{end}" | awk 'NF==1 {print $0}'

this is essentially just a more compact template than the one the OP posted with the inversion done by filterung with awk.

Edit: after trying to use the command I had posted earlier, I realized that it would only work in the edge case of a single master. Thus I have extended the command to first print all node names along with NoSchedule taints (if present) and afterwards removing all lines with more than one column using awk (This is what NF==1 does).

-- Arne
Source: StackOverflow

10/7/2019

Here's a working go text/template that works now that spec.taints is GA:

{{/* scehdulable.gotmpl */}}
{{- range .items }}
  {{- $taints:="" }}
  {{- range .spec.taints }}
    {{- if eq .effect "NoSchedule" }}
      {{- $taints = print $taints .key "," }}
    {{- end }}
  {{- end }}
  {{- if not $taints }}
    {{- .metadata.name}}{{ "\n" }}
  {{- end }}
{{- end }}
kubectl get no -o go-template-file=./schedulable.gotmpl
kind-worker
kind-worker2

Compact version:

kubectl get no -o 'go-template={{range .items}}{{$taints:=""}}{{range .spec.taints}}{{if eq .effect "NoSchedule"}}{{$taints = print $taints .key ","}}{{end}}{{end}}{{if not $taints}}{{.metadata.name}}{{ "\n"}}{{end}}{{end}}'
-- stealthybox
Source: StackOverflow

12/30/2016

unschedulable defaults to false, so the value will not appear in the spec unless it is set to true. The value is implicit in the spec.

-- Bowei Du
Source: StackOverflow