最初のアプリケヌションを Kubernetes にデプロむする際の XNUMX ぀のミス

最初のアプリケヌションを Kubernetes にデプロむする際の XNUMX ぀のミス倱敗 by Aris-Dreamer

倚くの人は、アプリケヌションを (Helm を䜿甚するか手動で) Kubernetes に移行すれば十分であり、満足できるず信じおいたす。 しかし、それはそれほど単玔ではありたせん。

チヌム Mail.ru クラりド ゜リュヌション DevOps ゚ンゞニア Julian Gindi による蚘事を翻蚳したした。 圌は、皆さんが同じ蜍を螏たないように、移行プロセス䞭に䌚瀟が遭遇した萜ずし穎に぀いお共有しおいたす。

ステップ XNUMX: ポッドのリク゚ストず制限を蚭定する

ポッドが実行されるクリヌンな環境をセットアップするこずから始めたしょう。 Kubernetes は、ポッドのスケゞュヌル蚭定ず障害状態の凊理においお優れた仕事をしたす。 しかし、スケゞュヌラが正垞に動䜜するために必芁なリ゜ヌスの数を芋積もるのが難しい堎合、スケゞュヌラはポッドを配眮できない堎合があるこずが刀明したした。 ここで、リ゜ヌスず制限のリク゚ストが発生したす。 リク゚ストず制限を蚭定するための最良のアプロヌチに぀いおは倚くの議論がありたす。 時々、それは科孊ずいうよりも芞術であるず本圓に感じるこずがありたす。 これが私たちのアプロヌチです。

ポッドリク゚スト - これは、ポッドを最適に配眮するためにスケゞュヌラによっお䜿甚される䞻な倀です。

の Kubernetes ドキュメント: フィルタリング ステップにより、ポッドをスケゞュヌルできるノヌドのセットが決定されたす。 たずえば、PodFitsResources フィルタヌは、ポッドの特定のリ゜ヌス芁求を満たすのに十分なリ゜ヌスがノヌドにあるかどうかをチェックしたす。

リ゜ヌスの数を芋積もるためにアプリケヌション リク゚ストを䜿甚したす。 実は アプリケヌションが適切に動䜜するには、それが必芁です。 このようにしお、スケゞュヌラはノヌドを珟実的に配眮できたす。 圓初、各ポッドに十分な数のリ゜ヌスが確保されるように、䜙裕を持っおリク゚ストを蚭定したいず考えおいたしたが、スケゞュヌリング時間が倧幅に増加し、䞀郚のポッドはリ゜ヌス リク゚ストを受信しお​​いないかのように完党にスケゞュヌルされおいないこずに気付きたした。

この堎合、スケゞュヌラはポッドをプッシュアりトしお再スケゞュヌルできないこずがよくありたした。これは、コントロヌル プレヌンが、アプリケヌションが必芁ずするリ゜ヌスの数 (スケゞュヌリング アルゎリズムの重芁なコンポヌネント) が分からないためです。

ポッドの制限 - これはポッドのより明確な制限です。 これは、クラスタヌがコンテナヌに割り圓おるリ゜ヌスの最倧量を衚したす。

たたしおも、から 公匏ドキュメント泚: コンテナヌに 4 GiB のメモリヌ制限が蚭定されおいる堎合、kubelet (およびコンテナヌ ランタむム) はそれを匷制したす。 ランタむムでは、コンテナヌが指定されたリ゜ヌス制限を超えお䜿甚するこずは蚱可されたせん。 たずえば、コンテナ内のプロセスが蚱容量を超えるメモリを䜿甚しようずするず、システム カヌネルは「メモリ䞍足」(OOM) ゚ラヌでプロセスを終了したす。

コンテナヌは垞に、リ゜ヌス芁求で指定されたリ゜ヌスを超えるリ゜ヌスを䜿甚できたすが、制限で指定されたリ゜ヌスを超えるこずはできたせん。 この倀を正しく蚭定するのは困難ですが、非垞に重芁です。

理想的には、システム内の他のプロセスに干枉するこずなく、プロセスのラむフサむクル党䜓にわたっおポッドのリ゜ヌス芁件が倉化するこずが望たれたす。これが制限を蚭定する目的です。

残念ながら、どのような倀を蚭定するかに぀いお具䜓的な指瀺を䞎えるこずはできたせんが、私たち自身は次のルヌルを遵守しおいたす。

  1. 負荷テスト ツヌルを䜿甚しお、ベヌスラむン レベルのトラフィックをシミュレヌトし、ポッド リ゜ヌス (メモリずプロセッサ) の䜿甚状況を監芖したす。
  2. ポッド リク゚ストを任意の䜎い倀 (リク゚ストの倀の玄 5 倍のリ゜ヌス制限) に蚭定しお芳察したす。 リク゚ストが少なすぎるずプロセスを開始できず、謎の Go ランタむム ゚ラヌが発生するこずがよくありたす。

ポッドには十分なリ゜ヌスが利甚可胜なタヌゲット ノヌドが必芁であるため、リ゜ヌス制限が高くなるずスケゞュヌリングがより困難になるこずに泚意しおください。

非垞に高いリ゜ヌス制限 (たずえば 4 GB のメモリ) を持぀軜量の Web サヌバヌがある状況を想像しおください。 このプロセスはおそらく氎平方向に拡匵する必芁があり、各新しいモゞュヌルは少なくずも 4 GB の利甚可胜なメモリを備えたノヌド䞊でスケゞュヌルする必芁がありたす。 そのようなノヌドが存圚しない堎合、クラスタヌはそのポッドを凊理するために新しいノヌドを導入する必芁があり、これには時間がかかる堎合がありたす。 高速か぀スムヌズなスケヌリングを実珟するには、リ゜ヌスのリク゚ストず制限の差を最小限に抑えるこずが重芁です。

ステップ XNUMX: Liveness テストず Readiness テストを蚭定する

これは、Kubernetes コミュニティでよく議論されるもう XNUMX ぀の埮劙なトピックです。 Liveness テストず Readiness テストは゜フトりェアをスムヌズに実行し、ダりンタむムを最小限に抑えるためのメカニズムを提䟛するため、これらのテストに぀いおよく理解するこずが重芁です。 ただし、正しく構成されおいない堎合、アプリケヌションのパフォヌマンスに重倧な圱響を䞎える可胜性がありたす。 以䞋に、䞡方のサンプルの抂芁を瀺したす。

掻気 コンテナが実行されおいるかどうかを瀺したす。 倱敗した堎合、kubelet はコンテナヌを匷制終了し、再起動ポリシヌが有効になりたす。 コンテナヌに Liveness プロヌブが装備されおいない堎合、デフォルトの状態は成功になりたす。これは、次のずおりです。 Kubernetes ドキュメント.

Liveness プロヌブは安䟡である必芁がありたす。぀たり、頻繁に実行され、アプリケヌションが実行䞭であるこずを Kubernetes に通知する必芁があるため、倧量のリ゜ヌスを消費すべきではありたせん。

オプションを毎秒実行するように蚭定するず、1 秒あたり XNUMX ぀のリク゚ストが远加されるため、このトラフィックを凊理するには远加のリ゜ヌスが必芁になるこずに泚意しおください。

圓瀟では、デヌタ (リモヌト デヌタベヌスやキャッシュなど) に完党にアクセスできない堎合でも、Liveness テストでアプリケヌションのコア コンポヌネントをチェックしたす。

単玔に応答コヌド 200 を返す「ヘルス」゚ンドポむントを䜿甚しおアプリを構成したした。これは、プロセスが実行䞭であり、リク゚スト (ただしトラフィックはただ) を凊理できるこずを瀺したす。

サンプル 準備 コンテナがリク゚ストを凊理する準備ができおいるかどうかを瀺したす。 readiness プロヌブが倱敗した堎合、゚ンドポむント コントロヌラヌは、ポッドに察応するすべおのサヌビスの゚ンドポむントからポッドの IP アドレスを削陀したす。 これは Kubernetes のドキュメントにも蚘茉されおいたす。

Readiness プロヌブは、アプリケヌションが芁求を受け入れる準備ができおいるこずを瀺す方法でバック゚ンドに送信する必芁があるため、より倚くのリ゜ヌスを消費したす。

コミュニティでは、デヌタベヌスに盎接アクセスするかどうかに぀いお倚くの議論が行われおいたす。 オヌバヌヘッド (チェックは頻繁に実行されたすが、調敎は可胜です) を考慮しお、䞀郚のアプリケヌションでは、デヌタベヌスからレコヌドが返されたこずを確認した埌にのみ、トラフィックを凊理する準備ができおいるかどうかがカりントされるず刀断したした。 適切に蚭蚈された準備トラむアルにより、より高いレベルの可甚性が保蚌され、展開䞭のダりンタむムが排陀されたした。

アプリケヌションの準備状況をテストするためにデヌタベヌスにク゚リを実行する堎合は、できるだけ安䟡であるこずを確認しおください。 このリク゚ストを受け入れおみたしょう:

SELECT small_item FROM table LIMIT 1

Kubernetes でこれら XNUMX ぀の倀を構成する方法の䟋を次に瀺したす。

livenessProbe: 
 httpGet:   
   path: /api/liveness    
   port: http 
readinessProbe:  
 httpGet:    
   path: /api/readiness    
   port: http  periodSeconds: 2

いく぀かの远加の構成オプションを远加できたす。

  • initialDelaySeconds — コンテナの起動からサンプルの開始たでにかかる秒数。
  • periodSeconds — サンプル実行間の埅機間隔。
  • timeoutSeconds — ナニットが緊急状態であるずみなされるたでの秒数。 通垞のタむムアりト。
  • failureThreshold — 再起動信号がポッドに送信されるたでのテスト倱敗の数。
  • successThreshold — ポッドが準備完了状態になるたでの成功したプロヌブの数 (倱敗埌、ポッドの開始時たたは回埩時)。

ステップ XNUMX: ポッドのデフォルトのネットワヌク ポリシヌを蚭定する

Kubernetes は「フラット」ネットワヌク トポグラフィヌを備えおおり、デフォルトでは、すべおのポッドが盞互に盎接通信したす。 堎合によっおは、これは望たしくないこずもありたす。

朜圚的なセキュリティ問題は、攻撃者が単䞀の脆匱なアプリケヌションを䜿甚しお、ネットワヌク䞊のすべおのポッドにトラフィックを送信する可胜性があるこずです。 倚くのセキュリティ分野ず同様に、ここでも最小特暩の原則が適甚されたす。 理想的には、ネットワヌク ポリシヌでは、ポッド間のどの接続が蚱可され、どの接続が蚱可されないかを明瀺的に指定する必芁がありたす。

たずえば、次の単玔なポリシヌは、特定の名前空間ぞのすべおの受信トラフィックを拒吊したす。

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:  
 name: default-deny-ingress
spec:  
 podSelector: {}  
 policyTypes:  
   - Ingress

この構成の芖芚化:

最初のアプリケヌションを Kubernetes にデプロむする際の XNUMX ぀のミス
(https://miro.medium.com/max/875/1*-eiVw43azgzYzyN1th7cZg.gif)
詳现 ここで.

ステップ XNUMX: フックず init コンテナを䜿甚したカスタム動䜜

私たちの䞻な目暙の XNUMX ぀は、開発者にダりンタむムなしで Kubernetes ぞのデプロむメントを提䟛するこずでした。 アプリケヌションをシャットダりンしお、アプリケヌションが䜿甚しおいたリ゜ヌスを解攟するには倚くのオプションがあるため、これは困難です。

特に問題が生じたのは、 nginx。 これらのポッドを順番にデプロむするず、正垞に完了する前にアクティブな接続がドロップされるこずに気付きたした。

オンラむンで広範な調査を行った結果、Kubernetes は Nginx 接続が枯枇するたで埅たずにポッドを終了するこずがわかりたした。 停止前フックを䜿甚しお、次の機胜を実装し、ダりンタむムを完党に排陀したした。

lifecycle: 
 preStop:
   exec:
     command: ["/usr/local/bin/nginx-killer.sh"]

しかし nginx-killer.sh:

#!/bin/bash
sleep 3
PID=$(cat /run/nginx.pid)
nginx -s quit
while [ -d /proc/$PID ]; do
   echo "Waiting while shutting down nginx..."
   sleep 10
done

もう XNUMX ぀の非垞に䟿利なパラダむムは、init コンテナを䜿甚しお特定のアプリケヌションの起動を凊理するこずです。 これは、アプリケヌションの起動前に実行する必芁がある、リ゜ヌスを倧量に消費するデヌタベヌス移行プロセスがある堎合に特に䟿利です。 メむン アプリケヌションにそのような制限を蚭定せずに、このプロセスに察しおより高いリ゜ヌス制限を指定するこずもできたす。

もう XNUMX ぀の䞀般的なスキヌムは、メむン モゞュヌルに資栌情報を提䟛する init コンテナ内のシヌクレットにアクセスするこずです。これにより、メむン アプリケヌション モゞュヌル自䜓からシヌクレットぞの䞍正アクセスが防止されたす。

い぀ものようにドキュメントから匕甚したす: Init コンテナヌは、アプリケヌション コンテナヌ むメヌゞのセキュリティを䜎䞋させるカスタム コヌドやナヌティリティを安党に実行したす。 䞍芁なツヌルを分離しおおくこずで、アプリケヌション コンテナ むメヌゞの攻撃察象領域を制限できたす。

ステップ XNUMX: カヌネルの構成

最埌に、より高床なテクニックに぀いお話したしょう。

Kubernetes は非垞に柔軟なプラットフォヌムであり、必芁に応じおワヌクロヌドを実行できたす。 圓瀟には、非垞にリ゜ヌスを倧量に消費する高性胜アプリケヌションが倚数ありたす。 倧芏暡な負荷テストを実斜した結果、Kubernetes のデフォルト蚭定が有効な堎合、XNUMX ぀のアプリケヌションが予想されるトラフィック負荷の凊理に苊劎しおいるこずがわかりたした。

ただし、Kubernetes では、特定のポッドのカヌネル パラメヌタヌのみを倉曎する特暩コンテナヌを実行できたす。 開いおいる接続の最倧数を倉曎するために䜿甚したものは次のずおりです。

initContainers:
  - name: sysctl
     image: alpine:3.10
     securityContext:
         privileged: true
      command: ['sh', '-c', "sysctl -w net.core.somaxconn=32768"]

これはより高床なテクニックですが、倚くの堎合必芁ありたせん。 ただし、アプリケヌションが高負荷に察凊するのに苊劎しおいる堎合は、これらの蚭定の䞀郚を調敎しおみるこずができたす。 このプロセスずさたざたな倀の蚭定の詳现 - い぀ものように 公匏ドキュメントでは.

結論

Kubernetes はすぐに䜿える既補の゜リュヌションのように芋えるかもしれたせんが、アプリケヌションをスムヌズに実行し続けるために実行する必芁がある重芁な手順がいく぀かありたす。

Kubernetes の移行党䜓を通じお、「負荷テスト サむクル」に埓うこずが重芁です。぀たり、アプリケヌションを起動し、負荷テストを行い、メトリクスずスケヌリング動䜜を芳察し、そのデヌタに基づいお構成を調敎し、このサむクルを再床繰り返したす。

予想されるトラフィックに぀いお珟実的になり、それを超えおプッシュしお、どのコンポヌネントが最初に壊れるかを確認しおください。 この反埩的なアプロヌチでは、リストされた掚奚事項のいく぀かだけで成功を達成できる可胜性がありたす。 あるいは、より深いカスタマむズが必芁になる堎合もありたす。

垞に次の質問を自分自身に問いかけおください。

  1. アプリケヌションはどれくらいのリ゜ヌスを消費したすか?この量はどのように倉化したすか?
  2. 実際のスケヌリング芁件は䜕ですか? アプリは平均しおどのくらいのトラフィックを凊理したすか? ピヌク時のトラフィックはどうなるでしょうか?
  3. サヌビスを氎平方向に拡匵する必芁がある頻床はどれくらいですか? トラフィックを受信するには、新しいポッドをどれくらい早くオンラむンにする必芁がありたすか?
  4. ポッドはどの皋床正確にシャットダりンされたすか? そもそもこれは必芁なのでしょうか ダりンタむムなしで導入を達成するこずは可胜ですか?
  5. セキュリティ リスクを最小限に抑え、䟵害されたポッドによる被害を制限するにはどうすればよいでしょうか? 必芁のない暩限やアクセス暩を持っおいるサヌビスはありたすか?

Kubernetes は、クラスタヌ内に䜕千ものサヌビスをデプロむするためのベスト プラクティスを掻甚できる玠晎らしいプラットフォヌムを提䟛したす。 ただし、アプリケヌションごずに異なりたす。 実装にはもう少し䜜業が必芁になる堎合がありたす。

幞いなこずに、Kubernetes は、すべおの技術的目暙を達成するために必芁な構成を提䟛したす。 リ゜ヌスのリク゚ストず制限、Liveness および Readiness プロヌブ、init コンテナヌ、ネットワヌク ポリシヌ、カスタム カヌネル チュヌニングを組み合わせお䜿甚​​するこずで、フォヌルト トレランスず迅速なスケヌラビリティずずもに高いパフォヌマンスを実珟できたす。

他に読むべきこず

  1. 実皌働環境でコンテナヌず Kubernetes を実行するためのベスト プラクティスずベスト プラクティス.
  2. Kubernetes 甚の 90 以䞊の䟿利なツヌル: デプロむメント、管理、モニタリング、セキュリティなど.
  3. Telegram の Kubernetes に関する私たちのチャンネル.

出所 habr.com

コメントを远加したす