Kubernetes API - pobiera pody na określonych węzłach

109

Patrząc na http://kubernetes.io/docs/user-guide/labels/#selecting-sets-of-nodes , wydaje się, że można wybrać określony zakres podów na podstawie etykiet. Ale w moim przypadku chcę wybrać wszystkie pody w jednym węźle, ale nie chcę oznaczać każdego poda w odpowiednim węźle.

Czy brakuje mi czegoś w dokumentacji, czy po prostu nie można wybrać według węzła? Jeśli zrobię:

kubectl --server="<SERVER>" --namespace=<NS> get pods -o wide | head
    NAME   READY     STATUS             RESTARTS   AGE       NODE

Czy którykolwiek z tych nagłówków może służyć jako selektor? Jeśli tak, to co najważniejsze w kubectl biust, jak to zrobić za pomocą API?

Z góry dziękuję

Regnoult
źródło
Rozważ zmianę zaakceptowanej odpowiedzi, ponieważ aktualnie zaakceptowana odpowiedź jest przestarzała.
deiga

Odpowiedzi:

187

Jak wspomniano w zaakceptowanej odpowiedzi, żądanie ściągania jest teraz scalane i można uzyskać pody według węzła w następujący sposób:

kubectl get pods --all-namespaces -o wide --field-selector spec.nodeName=<node>
Kristofer
źródło
9
To najbardziej eleganckie rozwiązanie.
Sergiu Marsavela
1
Mam wyjaśnienie: --all-namespacesnajpierw ściągnie wszystkie pody z całego klastra, a następnie przejdzie do filtrowania pod kątem węzła? czy może po prostu ściągnie wszystkie pody tylko z tego węzła bez nadmiernego ściągania wszystkich podów przestrzeni nazw z całego klastra?
AhmFM,
105

Przykładowe sortowanie podów według nodeName:

kubectl get pods -o wide --sort-by="{.spec.nodeName}"

Przykład pobierania podów na węzłach przy użyciu filtru etykiet:

for n in $(kubectl get nodes -l your_label_key=your_label_value --no-headers | cut -d " " -f1); do 
    kubectl get pods --all-namespaces  --no-headers --field-selector spec.nodeName=${n} 
done

lub według liczby ponownych uruchomień

kubectl get pods --sort-by="{.status.containerStatuses[:1].restartCount}"

Przykładowe filtrowanie według nodeName przy użyciu flagi --template:

$ kubectl get nodes

NAME                         STATUS                     AGE
ip-10-0-90-30.ec2.internal   Ready                      2d
ip-10-0-90-35.ec2.internal   Ready                      2d
ip-10-0-90-50.ec2.internal   Ready,SchedulingDisabled   2d
ip-10-0-91-60.ec2.internal   Ready                      2d
ip-10-0-91-65.ec2.internal   Ready                      2d


$kubectl get pods --template '{{range .items}}{{if eq .spec.nodeName "ip-10-0-90-30.ec2.internal"}}{{.metadata.name}}{{"\n"}}{{end}}}{{end}}'

filebeat-pezch
app-5xole
node-exporter-6kfs8
prometheus-0
sso-359976856-wu8zt
Camil
źródło
To interesujące, że można sortować według tych danych, ale jedyną rzeczą, którą można filtrować za pomocą selektora, jest to, co znajduje się na ".spec.selector".
Regnoult,
Filtry są wykonywane po stronie serwera, sortowanie po stronie klienta
Tim Hockin
19

Możesz również zapytać o wszystkie pody w węźle za pomocą następującego polecenia

kubectl get pods -o wide --all-namespaces | grep <YOUR-NODE>
Mal
źródło
1
użyj -a również z kubectl ----- kubectl get pods -a -o wide --all-namespaces | grep <YOUR-NODE>
Pawan Kumar
3
W rzeczywistości jest to zapytanie o wszystkie pody (a następnie filtrowanie w kliencie), co może być znacznie wolniejsze w dużych klastrach. Najlepszym rozwiązaniem byłaby odpowiedź @Kristofer.
Guilherme Garnier
14

kubectl describe node <node> pokaże wszystkie niezakończone pody działające w tym węźle

Matt Hamann
źródło
10

To, czego chcesz, jest obsługiwane po stronie serwera Kubernetes API w następujący sposób:

curl --cacert ca.crt --cert apiserver.crt --key apiserver.key  https://<server>:<port>/api/v1/namespaces/<namespace>/pods?fieldSelector=spec.nodeName%3Dsomenodename

Jednak ta opcja selektora pól nie jest jeszcze wbudowana kubectl: https://github.com/kubernetes/kubernetes/pull/50140

coreypobrien
źródło
3
FYI To zostało teraz połączone
deedubs
3

Przeszedłem przez ten sam proces z klientem Go i odkryłem kilka skrótów używanych przez CLI.

func doNodesHavePods(clientset *kubernetes.Clientset) error {
    nodeLabelSelector := "nodelabel=interesting_nodes"
    nodes, err := clientset.CoreV1().Nodes().List(metav1.ListOptions{LabelSelector: nodeLabelSelector})

    if err != nil {
        return err
    }

    nodeNames := []string{}
    for _, node := range nodes.Items {
        nodeNames = append(nodeNames, node.Name)
    }
    // --all-namespaces -> listing and looping on namespaces
    namespaces, err := clientset.CoreV1().Namespaces().List(metav1.ListOptions{})

    if err != nil {
        return err
    }
    for _, namespace := range namespaces.Items {
        for _, name := range nodeNames {
            // pods need a namespace to be listed.
            pods, err := clientset.CoreV1().Pods(namespace.Name).List(metav1.ListOptions{FieldSelector: "spec.nodeName=" + name})
            if err != nil {
                println("%v", err)
            }
            for _, pod := range pods.Items {
                fmt.Println(pod.Namespace, pod.Name)
            }
        }
    }
    return nil
}

Zacząłem odkrywać, że wiele pytań, które muszę zadać, staje się zbyt skomplikowanych dla CLI, który jest świetnym koniem roboczym, ale nauka korzystania z klienta Go może pomóc w uzyskaniu pierwszej odpowiedzi, której szukasz, ale zagłęb się także w pytania, które rodzą te odpowiedzi.

Breedly
źródło
2
Można użyć pustej przestrzeni nazw, aby uzyskać pody we wszystkich przestrzeniach nazw
dimm
To rozwiązanie pomogło mi, nie jestem pewien, dlaczego zostało odrzucone.
Ingytron