web-dev-qa-db-de.com

Kubernetes: Ist es möglich, mehrere Pods mit einer einzigen Anforderung im Kubernetes-Cluster zu treffen

Ich möchte den Cache in allen Pods in meinem Kubernetes-Namespace löschen. Ich möchte eine Anfrage an den Endpunkt senden, die dann einen HTTP-Aufruf an alle Pods im Namespace sendet, um den Cache zu löschen. Derzeit kann ich mit Kubernetes nur einen Pod schlagen und habe keine Kontrolle darüber, welcher Pod getroffen werden würde.

Obwohl der Load-Balancer auf RR eingestellt ist, hilft das ständige Auftreffen der Pods (n Anzahl von Malen, wobei n die Gesamtanzahl der Pods ist) nicht, da sich einige andere Anforderungen einschleichen können.

Das gleiche Problem wurde hier diskutiert, aber ich konnte keine Lösung für die Implementierung finden: https://github.com/kubernetes/kubernetes/issues/18755

Ich versuche, den Clearing-Cache-Teil mit Hazelcast zu implementieren, wobei ich den gesamten Cache speichern werde und Hazelcast sich automatisch um die Cache-Aktualisierung kümmert.

Wenn es einen alternativen Ansatz für dieses Problem gibt oder eine Möglichkeit, Kubernetze so zu konfigurieren, dass sie für bestimmte Anforderungen alle Endpunkte erreicht, wäre das Teilen hier eine große Hilfe.

13

Vorausgesetzt, Sie haben kubectl in Ihrem Pod und haben Zugriff auf den API-Server, können Sie alle Endpunktadressen erhalten und an curl übergeben:

kubectl get endpoints <servicename> \
        -o jsonpath="{.subsets[*].addresses[*].ip}" | xargs curl

Alternative ohne kubectl in pod:

der empfohlene Weg für den Zugriff auf den API-Server von einem Pod aus ist die Verwendung von kubectl proxy: https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#accessing-the-api-from- a-pod Dies würde natürlich mindestens den gleichen Overhead hinzufügen. Alternativ können Sie auch direkt die API REST aufrufen. Sie müssen das Token manuell bereitstellen.

APISERVER=$(kubectl config view --minify | grep server | cut -f 2- -d ":" | tr -d " ")
TOKEN=$(kubectl describe secret $(kubectl get secrets \
     | grep ^default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d " ")

wenn Sie die Variablen APISERVER und TOKEN angeben, benötigen Sie kein kubectl in Ihrem Pod. Auf diese Weise benötigen Sie nur curl, um auf den API-Server zuzugreifen, und "jq", um die Json-Ausgabe zu parsen:

curl $APISERVER/api/v1/namespaces/default/endpoints --silent \
     --header "Authorization: Bearer $TOKEN" --insecure \
     | jq -rM ".items[].subsets[].addresses[].ip" | xargs curl

UPDATE (endgültige Version)

APISERVER kann normalerweise auf kubernetes.default.svc gesetzt werden, und das Token sollte im Pod unter /var/run/secrets/kubernetes.io/serviceaccount/token verfügbar sein.

TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token); \
curl https://kubernetes.default.svc/api/v1/namespaces/default/endpoints --silent \
     --header "Authorization: Bearer $TOKEN" --insecure \
     | jq -rM ".items[].subsets[].addresses[].ip" | xargs curl

jq ist hier verfügbar: https://stedolan.github.io/jq/download/ (<4 MiB, lohnt sich aber für das einfache Analysieren von JSON)

5
Markus Dresch

Für diejenigen, die eine Alternative suchen, habe ich Hazelcast als Listener für verteilte Ereignisse verwendet. Ein ähnlicher POC wurde auf github hinzugefügt: https://github.com/vinrar/HazelcastAsEventListener

1

Ich habe dieses Problem mit dieses Skript behoben. Sie müssen nur den entsprechenden Befehl schreiben, um den API-Aufruf durchzuführen. Ich habe curl benutzt, um das zu tun.

Es folgt die Verwendung des Skripts:

function usage {
    echo "usage: $PROGNAME [-n NAMESPACE] [-m MAX-PODS] -s SERVICE -- COMMAND"
    echo "  -s SERVICE   K8s service, i.e. a pod selector (required)"
    echo "     COMMAND   Command to execute on the pods"
    echo "  -n NAMESPACE K8s namespace (optional)"
    echo "  -m MAX-PODS  Max number of pods to run on (optional; default=all)"
    echo "  -q           Quiet mode"
    echo "  -d           Dry run (don't actually exec)"
}

Um beispielsweise den Befehl curl http://google.com Auf allen Pods eines Dienstes mit dem Namen s1 Und dem Namespace n1 Auszuführen, müssen Sie ./kcdo -s s1 -n n1 -- curl http://google.com Ausführen.

0
Lokesh