新しい歴史

待つ:あなたがマスターすべき微妙な芸術

Nicolas Fränkel6m2025/04/25
Read on Terminal Reader

長すぎる; 読むには

最近、GKE と GitHub Actions で Kubernetes で Pull Request をテストするというワークショップで働いていたとき、私は同じ問題に二度直面しました:サービス A にはサービス B が必要ですが、サービス A はサービス B より速く開始し、システムは失敗します。
featured image - 待つ:あなたがマスターすべき微妙な芸術
Nicolas Fränkel HackerNoon profile picture

最近、タイトルは「WORKSHOP」Kubernetes で Pull Request を GKE および GitHub アクションでテストする, I faced the same problem twice: service A needs service B, but service A starts faster than service B, and the system fails. In this post, I want to describe the context of these issues and how I solved them both with the same tool. サービスAはサービスBを必要としているが、サービスAはサービスBよりも速く開始し、システムが失敗する。

Kubernetesで待つ

Kubernetes で待つのは不思議かもしれません。Kubernetes プラットフォームの自癒性は最大の利点のひとつです。Python アプリケーションと PostgreSQL データベースの 2 つの pods を考えてみましょう。


アプリケーションは非常に迅速に起動し、熱心にデータベースへの接続を確立しようとします。その間に、データベースは提供されたデータと自らを初期化しています。Failed


しばらくすると、Kubernetes はアプリケーション ポッドの状態を要求します. 失敗したため、それを終了し、新しいポッドを起動します. この時点で、2つのことが起こりうる: データベース ポッドはまだ準備ができていません。

プロセスを加速させるために、Kubernetesは提供します。スタートアップテスト: :


startupProbe:
  httpGet:
    path: /health
    port: 8080
  failureThreshold: 30
  periodSeconds: 10


上記のサンドでは、Kubernetes は最初の 10 秒間、ポッドの状態を要求する前に待機します. 失敗した場合、さらに 10 秒間待機します. 洗浄し、絶対に失敗する前に 30 回繰り返します.


HTTPに気づいたのかもしれない。/healthKubernetes は 2 つのエンドポイントを提供します。テスト設定設定:httpGetまたはexec. 前者はウェブアプリケーションに適しているが、後者は他のアプリケーションに適している. それは pod が含むコンテナの種類を知る必要があることを意味し、それが可能である限り、その状態をチェックする方法を示す。Bitnami Helm Chart適用された時には以下のようになります。


startupProbe:
  exec:
    command:
      - /bin/sh
      - -c
      - -e
      - exec pg_isready -U $PG_USER -h $PG_HOST -p $PG_PORT

上記は、データベース名とSSL証明書を無視するため、単純化であることに注意してください。


スタートアップ ソンドは、正しく設定した場合、デフォルトの状況に比べ物事を加速させます. 長い初期遅延を設定し、その後より短い増加を設定できます. しかし、コンテナが多様化するほど、コンテナの構成が難しくなります。


代替案を探すのは有利だろう。

ワイ4x

Alternatives are tools whose focus is on waiting. Long ago, I found the待合せアイデアはシンプルだ!アイデアはシンプルだ。


./wait-for は docker コンテナなどのサービスを同期するように設計されたスクリプトです。

./wait-for は docker コンテナなどのサービスを同期するように設計されたスクリプトです。


以下は、HTTP API を待つ方法です。


sh -c './wait-for http://my.api/health -- echo "The api is up! Let's use it"'


それは仕事を完了しましたが、その時点で、あなたはスクリプトをコピーし、手動で更新をチェックしなければなりませんでした. I have checked, and the project now provides a regular container.


ワイ4x同じ役割を果たしているが、バージョン化されたコンテナとして利用可能で、HTTP、DNS、データベース、メッセージの列を待つためのより多くのサービスを提供している。


どんなツールを使おうと、あなたはそれを内部で使用することができます。initコンテナ: :


Pod には、アプリケーションを実行する複数のコンテナがありますが、アプリケーションのコンテナが起動する前に実行される 1 つまたは複数の init コンテナもあります。

Initコンテナは、以下を除く通常のコンテナである。


    各 init コンテナは、次のコンテナが始まる前に完了しなければなりません。

Pod には、アプリケーションを実行する複数のコンテナがありますが、アプリケーションのコンテナが起動する前に実行される 1 つまたは複数の init コンテナもあります。

Initコンテナは、以下を除く通常のコンテナである。


  • Initコンテナは常に完成まで走ります。
  • それぞれの init コンテナは、次のコンテナが始まる前に完了しなければなりません。


次のことを想像してPodこれは PostgreSQL に依存します。Deployment: :


apiVersion: v1
kind: Pod
metadata:
  labels:
    type: app
    app: recommandations
spec:
  containers:
    - name: recommandations
      image: recommandations:latest
      envFrom:
        - configMapRef:
            name: postgres-config


アプリケーションはPythonで、かなり速く起動します。それはPostgreSQLデータベースに接続しようとします。残念ながら、データベースは初期化を完了していないので、接続が失敗し、KubernetesはPodを再起動します。


我々はそれを一つのinitContainer待機コンテナ:


apiVersion: v1
kind: Pod
metadata:
  labels:
    type: app
    app: recommandations
spec:
  initContainers:
    - name: wait-for-postgres
      image: atkrad/wait4x:3.1
      command:
        - wait4x
        - postgresql
        - postgres://$(DATABASE_URL)?sslmode=disable
      envFrom:
        - configMapRef:
            name: postgres-config
  containers:
    - name: recommandations
      image: recommandations:latest
      envFrom:
        - configMapRef:
            name: postgres-config


上記の設定では、TheinitContainerデータベースが接続を受け入れるまで停止しません. When it does, it terminates, and therecommandationsコンテナを起動できます Kubernetes は、終了する必要はありません。Pod前回の設定と同様に、ログ数が少なくなり、潜在的に警告数が少なくなります。

待つことが義務化されたとき

上記はわずかな改善ですが、それなしではできます。他のケースでは、待つことが義務化されます。私は前述のワークショップの準備中に最近それを経験しました。


  • パイプラインはKubernetes側に宣言を適用する
  • 次のステップでは、テストを実行します。
  • アプリケーションが読まれる前にテストが始まると、失敗します。


私たちはテストする前にバックエンドが準備が整うまで待つ必要があります。wait4xを待つためにPodテストを開始する前に要求を受け入れるために:


      - name: Wait until the application has started
        uses: addnab/docker-run-action@v3                                       #1
        with:
          image: atkrad/wait4x:latest
          run: wait4x http ${{ env.BASE_URL }}/health --expect-status-code 200  #2
  1. GitHub Action はコンテナを実行することを可能にします. I could have downloaded the Go binary instead.
  2. /health エンドポイントが 200 応答コードを返すまで待つ。

結論

Kubernetes スタートダッシュは、相互に依存するサービスを起動する際に不要な再起動を避けるのに最適な方法です。initContainerで。wait4x他の文脈で使用できるツールです それは今、私のツールベルトの一部です。


To go further:


  • ワイ4x
  • それでは、いくつかのKubernetesのリソースを待つ必要がありますか?



オリジナルの投稿 A Java Geek on April 20th, 2025

・Java Geek

Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks