web-dev-qa-db-ja.com

Kubernetes:Kubernetesクラスターで単一のリクエストで複数のポッドをヒットすることは可能ですか?

Kubernetes名前空間のすべてのポッドのキャッシュをクリアしたい。 1つのリクエストをエンドポイントに送信し、エンドポイントはネームスペース内のすべてのポッドにHTTP呼び出しを送信してキャッシュをクリアします。現在、Kubernetesを使用して1つのポッドのみをヒットでき、どのポッドがヒットするかを制御することはできません。

ロードバランサーがRRに設定されていても、ポッドに連続的にヒットする(n回、nはポッドの総数)と、他のリクエストが忍び寄ることがあります。

同じ問題がここで説明されましたが、実装の解決策が見つかりませんでした: https://github.com/kubernetes/kubernetes/issues/18755

Hazelcastを使用してキャッシュのクリア部分を実装しようとしています。すべてのキャッシュを保存し、Hazelcastがキャッシュの更新を自動的に処理します。

この問題に別のアプローチがある場合、または特定のリクエストのすべてのエンドポイントにヒットするようにkubernetesを構成する方法がある場合、ここで共有すると非常に役立ちます。

24

ポッドでkubectlを取得し、api-serverにアクセスできる場合は、すべてのエンドポイントアドレスを取得してcurlに渡すことができます。

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

ポッドでkubectlを使用しない代替:

ポッドからAPIサーバーにアクセスする推奨方法は、kubectlプロキシを使用することです。 https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#accessing-the-api- from-a-pod これはもちろん、少なくとも同じオーバーヘッドを追加します。または、REST apiを直接呼び出して、トークンを手動で提供する必要があります。

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 " ")

aPISERVERおよびTOKEN変数を提供する場合、ポッドでkubectlは必要ありません。この方法では、APIサーバーにアクセスするためにcurlとjson出力を解析するために「jq」のみが必要です。

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

UPDATE(最終バージョン)

通常、APISERVERはkubernetes.default.svcに設定でき、トークンはポッドの/var/run/secrets/kubernetes.io/serviceaccount/tokenで利用できる必要があるため、手動で何も提供する必要はありません。

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はここにあります: https://stedolan.github.io/jq/download/ (<4 MiB、しかしJSONを簡単に解析するためには価値があります)

14
Markus Dresch

別の方法を見つけようとしている皆さんのために、分散イベントリスナーとしてhazelcastを使用しました。 githubに同様のPOCを追加しました: https://github.com/vinrar/HazelcastAsEventListener

1

このスクリプト を使用してこの問題を修正しました。 API呼び出しを行うには、同等のコマンドを記述する必要があります。そのためにcurlを使用しました。

スクリプトの使用方法は次のとおりです。

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)"
}

たとえば、名前curl http://google.comおよび名前空間s1を持つサービスのすべてのポッドでコマンドn1を実行するには、./kcdo -s s1 -n n1 -- curl http://google.comを実行する必要があります。

0
Lokesh