Kubernetesの健康診断とサービス依存処理

39029 ワード

【編集者の話】オンライン業務にとって、サービスの正常な安定を保証することは重要であり、故障サービスのタイムリーな処理が業務に影響を及ぼさないこと、迅速な回復を避けることは、開発運営維持の難点である.Kubernetesは健康診断サービスを提供し、障害が検出されたサービスに対して直ちに自動的にオフラインになり、サービスを再起動することでサービスを自動的に回復させる.一方、サービス依存性については、リソース記述ファイルがpod,rcまたはdeploymentであっても、対応するyamlファイルの記述はContainerのサービス起動順序ではなくcontainer起動順序のみであり、Kubernetesが提供するInit Containerは、サービス間依存性を処理することができる.
簡単な例は、健康診断とサービス依存性とは何かを説明します.例えば、1つのアプリケーションにはそれぞれA、B、Cの3つのサービスがあり、健康診断はどのようにA、BとCがあるContainerが運行状態にあり、サービスが正常であることを確定するかです.一方、サービス依存性については、サービスAは、サービスBが正常に起動する前に起動しなければならず、サービスBは、サービスCが正常に起動する前に起動しなければならないと仮定し、すなわち、起動順序はA−>B−>Cである.
健康診断
LivenessプローブおよびReadnessプローブの使用
ここでLivenessプローブは主にContainerが稼働しているかどうかを判断するために用いられ、例えばサービスcrashやデッドロックなどの状況が発生した場合、kubeletはContainerをkillして落ちる.その後、設定したrestart policyに従って対応する操作を行います(本機でContainerを再起動するか、Kubernetes QoSを設定するため、本機にリソースがない場合に配布される他の機器で再起動する可能性があります).
Readnessプローブは、主にサービスが正常に動作しているかどうかを判断するために使用され、サービスがロード完了または動作異常がない場合、サービスが存在するPodのIPアドレスは、サービスのendpointsから削除され、すなわち、サービスがreadyを持たない場合、サービスのload balancerから削除され、要求を受け入れたり応答したりしない.
プローブ処理Handlerタイプ
ReadnessプローブまたはLivenessプローブの場合、Handlerは、ExecAction、TCPSocketAction、HTTPGetActionの3種類をサポートします.各タイプの説明と例を次に示します.
  • ExecAction:Container内部で特定のコマンド、例を実行します.
  • TCPSocketAction:containerのIP、portでtcpを実行してチェックします.例です.
  • HTTPGetAction:containerのIP,port,pathを介してHTTP Getリクエストでチェックを行う例.

  • プローブ検査結果
    プローブ検査結果は3つの状況に分けられる.
  • 成功(Success):検査に合格しました.
  • 失敗(Failure):チェックに失敗しました.
  • 未知(Unknown):未知をチェックし、人工的な介入が必要です.

  • 健康診断のまとめ
                                                                                
    ExecAction         container    shell                              shell    0
    TCPSocketAction      container IPport  tcp                     port    
    HTTPGetAction        container IPportpathHTTP Get         200<=   <400

    サービスの可用性と自動リカバリ
  • サービスの健康診断(readines)に失敗した場合、障害のあるサービスインスタンスがサービスendpointからオフラインになり、外部リクエストはこのサービスに転送されず、提供されているサービスの正確性がある程度保証され、サービスが自己回復した場合(ネットワークの問題など)、自動的にサービスendpointに再加入して対外的にサービスを提供します.
  • また、Container(liveness)のプローブが設定されている場合、障害サービスのContainer(liveness)のプローブも失敗し、containerはkillによって落とされ、元のcontainer再起動ポリシーに従って、システムは元のマシンでcontainerを再起動したり、他のマシンでpodを再作成したりする傾向があります.
  • 上記のメカニズムにより、サービス全体が自己利用可能および自動リカバリを実現した.

  • 推奨事項の使用
  • すべてのサービスに対して同時にサービス(readines)とContainer(liveness)の健康診断
  • を設定することを提案する
  • TCPによるポートチェック形式(TCPSocketAction)は、ポートがクローズされた場合やプロセスが停止した場合にのみ適用されます.サービスが異常であっても、ポートが開いている限り、健康診断は通過します.
  • 第2の点に基づいて、一般的にはExecActionを使用して健康診断ロジックをカスタマイズするか、HTTP Getリクエストを使用して検査(HTTPGetAction)を行うことを推奨する.
  • どの種類のプローブを採用しても、一般的には、検査サービス(readines)を設定する時間がContainer(liveness)を検査する時間よりも短く、検査サービス(readines)のプローブをContainer(liveness)のプローブと一致させることを推奨する.障害サービスは、一時的に自動的にリカバリできない場合は、再起動ポリシーに基づいてcontainerを再起動するか、他のマシンでpodリカバリ障害サービスを再作成することを目的としています.

  •  
    サービス依存
    Init Containerの理解
    1つのpodに1つ以上のInit Containerを含めることができます.Podの複数のInit Containerの起動順序はyamlファイルの記述順序であり、シリアル方式で起動し、次のInit/app Containerは前のInit Containerが完了するのを待たなければ起動できない.たとえば、Init Container 1->...->Init Container->app Container[1-n]です.Init Container 1が正常に起動し、完了すると、後続のInit Containerとapp Containerが起動できます.例えば、Init Containerの起動や関連するチェックの実行に失敗した場合、後続のinit ContainerとアプリケーションContainerは起動コマンドを実行しません.
    したがって、Init Containerを利用して、app Containerで依存するサービスが正常に起動したかどうかを判断することができる.依存するapp Containerサービスの起動に失敗した場合、Init Containerの起動に失敗すると、後続のapp Containerサービスの起動を阻止することができる.
    Init Containerはpod状態がReadyになる前に完了しなければならないのでreadinesプローブは必要ありません.またリソースのrequestsとlimitsでは通常Containerとわずかな差があり,詳細はResourcesを参照し,以上の2点を除きInit Containerと通常Containerには明らかな差はなかった.
    Init Containers用途
  • では前述したように、Init Containerはapp Containersの起動前に完了しなければならないため、その特性を利用してサービス依存処理として使用することができる.例えば、あるサービスAがdbやmemcachedに依存する必要がある場合、サービスA podのInit Containerを利用してdb/memcachedが正常にサービスを提供しているかどうかを判断することができ、サービス起動に失敗したり、動作が異常になったりして、Init Containerの起動に失敗した場合、podのサービスAは起動されません.
  • セキュリティ上の理由でインストールまたは実行できないツールを適用し、Init Containerで実行できます.また、Init Containerは業務サービスとは独立しており、sed,awk,python,digなどの業務に関係のないツールも必要に応じてInit Containerに入れることができる.最後に、Init Containerは、アプリケーションContainerがアクセスできないコンテンツへのアクセスを許可することもできる.

  • Init Container処理サービス依存アプリケーションの例
    サービスAサービスはサービスBに依存するが、サービスBはReadnessプローブについて上述したHTTPGetActionHandlerを使用する.
    spec:
      initContainers:
      - name: init-serviceA
        image: registry.docker.dev.fwmrm.net/busybox:latest
        command: ['sh', '-c', "curl --connect-timeout 3 --max-time 5 --retry 10 --retry-delay 5 --retry-max-time 60 serviceB:portB/pathB/"]
      containers:

    サービスA Podを起動すると、サービスBはまだreadyがなく、kubectl get po-o wideでpodがInit状態であることを確認します
    NAME                        READY     STATUS    RESTARTS   AGE       IP          .l  NODE
    serviceA-3071943788-8x27q            0/1       Init:0/1   0          20s       10.244.1.172   bjo-ep-svc-017.dev.fwmrm.net

    kubectl describe po serviceA-3071943788-g 03 wtで見ると、app Containerの起動時にinit Containerが起動し、正常に完了した後:
    Events:
    FirstSeen LastSeen    Count   From                    SubObjectPath               Type        Reason  Message
    --------- --------    -----   ----                    -------------               --------    ------  -------
    25s       25s     1   default-scheduler                               Normal      ScheduledSuccessfully assigned serviceA-3071943788-g03wt to bjo-ep-dep-040.dev.fwmrm.net
    25s       25s     1   kubelet, bjo-ep-dep-040.dev.fwmrm.net                       Normal      SuccessfulMountVolume   MountVolume.SetUp succeeded for volume "serviceA-config-volume"
    25s       25s     1   kubelet, bjo-ep-dep-040.dev.fwmrm.net                       Normal      SuccessfulMountVolume   MountVolume.SetUp succeeded for volume "default-token-2c9j1"
    24s       24s     1   kubelet, bjo-ep-dep-040.dev.fwmrm.net   spec.initContainers{init-myservice} Normal      Pulling pulling image "registry.docker.dev.fwmrm.net/ui-search-solr-data:latest"
    24s       24s     1   kubelet, bjo-ep-dep-040.dev.fwmrm.net   spec.initContainers{init-myservice} Normal      Pulled  Successfully pulled image "registry.docker.dev.fwmrm.net/busybox:latest"
    24s       24s     1   kubelet, bjo-ep-dep-040.dev.fwmrm.net   spec.initContainers{init-myservice} Normal      Created Created container
    24s       24s     1   kubelet, bjo-ep-dep-040.dev.fwmrm.net   spec.initContainers{init-myservice} Normal      Started Started container
    20s       20s     1   kubelet, bjo-ep-dep-040.dev.fwmrm.net   spec.containers{is}         Normal      Pulling pulling image "registry.docker.dev.fwmrm.net/infra/is:latest"
    20s       20s     1   kubelet, bjo-ep-dep-040.dev.fwmrm.net   spec.containers{is}         Normal      Pulled  Successfully pulled image "registry.docker.dev.fwmrm.net/infra/is:latest"
    20s       20s     1   kubelet, bjo-ep-dep-040.dev.fwmrm.net   spec.containers{is}         Normal      Created Created container
    19s       19s     1   kubelet, bjo-ep-dep-040.dev.fwmrm.net   spec.containers{is}         Normal      Started Started container

    docker Container logを表示します.init Containerは事前の設定に従って、3秒ごとにサービスB健康診断ポイントサービスB:portB/pathB/をポーリングしています.
    docker logs 4fd58bf54f76
    waiting for serviceB service
    waiting for serviceB service
    ... ...

    しばらく待ってから、再びkubectl get po-o wideでpodがRunning状態であることを確認します.
    NAME                        READY     STATUS    RESTARTS   AGE       IP          .l  NODE
    serviceA-3071943788-g03wt   1/1       Running   0          1m        10.244.2.68   bjo-ep-dep-040.dev.fwmrm.net

    podが再起動された場合、すべてのinit Containerが再実行されます.KubernetesはInit Containerのreadinesプローブの使用を禁止し、Pod定義activeDeadlineSecondsとContainerのlivenessProbeを使用してinit containersの繰り返し失敗を防止することができる.ActiveDeadlineSecondsにはinit containerの起動時間が含まれています.
    参考資料
  • Container Lifecycle Hooks: https://kubernetes.io/docs/con … ooks/
  • Attach Handlers to Container Lifecycle Events: https://kubernetes.io/docs/tas … vent/
  • Init Containers: https://kubernetes.io/docs/con … ners/
  • Init Container and Probe: https://blog.giantswarm.io/wai … etes/
  • Configure Pod Initialisation: https://kubernetes.io/docs/tas … ainer
  • Debug Init Containers: https://kubernetes.io/docs/tas … ners/
  • Delaying the deployment of our stubborn service: https://blog.giantswarm.io/wai … etes/

  • 転載を歓迎して、作者の出所を明記してください:張夏、FreeWheel Lead Engineer、Kubernetes中国語コミュニティ
    Kubernetesの健康診断とサービス依存処理