Google Cloudとコンテナの継続的なセキュリティ
本文の内容は、2020年1月21日にSysdigのCarlos Arillaが投稿したブログ(https://sysdig.com/blog/kubernetes-limits-requests/)を元に日本語に翻訳・再構成した内容となっております。
Kubernetesの制限とリクエストをどのように設定するかは、アプリケーションとクラスターのパフォーマンスを最適化するために不可欠です。
Kubernetesなど、アプリケーション間でリソースを共有するように設計されたすべての分散システムの課題の1つは、逆説的に、リソースを適切に共有する方法です。アプリケーションは通常、マシン上でスタンドアロンとして実行し、手元のすべてのリソースを使用するように設計されていいます。良いフェンスは良い隣人を作ると言われています。新しいランドスケープでは、同じスペースを他のユーザーと共有する必要があるため、リソースクォータがハード要件になります。
Kubernetesを使用すると、管理者はリソース使用量のハードリミットとして、ネームスペースでクォータを設定できます。これには追加の効果があります。 ネームスペースにCPUリクエストクォータを設定する場合、すべてのポッドは定義でCPUリクエストを設定する必要があります。設定しないと、スケジュールがなされません。
例を見ていきましょう。
apiVersion: v1 kind: ResourceQuota metadata: name: mem-cpu-example spec: hard: requests.cpu: 2 requests.memory: 2Gi limits.cpu: 3
limits.memory: 4Gi
このファイルをネームスペースに適用する場合、次の要件を設定します。
ポッドで割り当てられた1.9コアが既にあり、200mのCPU要求で新しいポッドを割り当てようとすると、ポッドはスケジュールされず、ペンディングの状態となります。
以下のデプロイメントの例で考えてみましょう。
kind: Deployment apiVersion: extensions/v1beta1 metadata: name: redis labels: name: redis-deployment app: example-voting-app spec: replicas: 1 selector: matchLabels: name: redis role: redisdb app: example-voting-app template: spec: containers: - name: redis image: redis:5.0.3-alpine resources: limits: memory: 600Mi cpu: 1 requests: memory: 300Mi cpu: 500m - name: busybox image: busybox:1.28 resources: limits: memory: 200Mi cpu: 300m requests: memory: 100Mi
cpu: 100m
たとえば、4つのコアと16GBのRAMノードでクラスターを実行しているとします。 多くの情報を抽出できます。
問題を検出するには、以下をモニタリングする必要があります。
ノードのCPUとメモリの使用量。ノードのメモリがいっぱいになると、すべてのコンテナが制限内にあるにもかかわらず、メモリのプレッシャーによりOOMで強制終了されます。CPUのプレッシャーはプロセスを抑制し、パフォーマンスに影響します。
Sysdig MonitorのダッシュボードにKubernetes → Resource usage → Kubernetes node healthにメトリクスがあります。
Sysdig MonitorのダッシュボードにKubernetes → Resource usage → Kubernetes node healthにメトリクスがあります。
ノードのディスク容量。ノードがディスクを使い果たすと、Podevictionでディスクスペースを解放する可能性があります。
Sysdig MonitorのダッシュボードにKubernetes → Resource usage → Kubernetes node healthにメトリクスがあります。
CPUクォータのパーセンテージは、コンテナ毎として使われます。ポッドのCPU使用率をモニタリングすると、誤認識となる場合があります。Kubernetesのリミットは、ポッドごとではなく、コンテナーごとに制限されることに注意してください。使用されるCPUシェアなどのその他のCPUメトリクスは、割り当てにのみ有効であるため、パフォーマンスの問題がある場合に時間を無駄にしないでください。
Sysdig MonitorのダッシュボードにHosts & containers → Container limitsにメトリクスがあります。
コンテナごとのメモリ使用量。この値を同じグラフのリミットに関連付けるか、使用されているメモリリミットの割合を分析を利用できます。ポッドのメモリ使用量を使用しないでください。この例のポッドは300MiBのRAMを使用でき、ポッドの有効制限(400MiB)を大幅に下回りますが、redisコンテナーが100MiBを使用し、busyboxコンテナーが200MiBを使用している場合、ポッドはフェイルします。
Sysdig MonitorのダッシュボードにHosts & containers → Container limitsにメトリクスがあります。
クラスターおよびノードにおけるリソース割り当ての割合。これは、使用可能なリソース全体から割り当てられたリソースの割合として表すことができます。適切な警告のしきい値は(n-1)/n*100です。ここでの、nはノードの数です。このしきい値を超えると、ノードに障害が発生した場合、残りのノードでワークロードを再割り当てできなくなります。
Sysdig MonitorのOverview機能 → clustersにメトリクスがあります。
オーバーコミットリミット(メモリおよびCPU)。これを明確に確認する最善の方法は、割り当て可能なリソース全体のリミットが表す割合です。通常のオペレーションでは、これは100%を超える可能性があります。
CPU使用量、キャパシティ、リミット、リクエストを示すカスタムグラフ。
Kubernetesの使用経験がある場合は、通常、リクエストとリミットを適切に設定することがアプリケーションとクラスターのパフォーマンスにとって最も重要であることを(難しい方法で)理解されているでしょう。
理想的な世界では、ポッドは、リクエストしたリソースの正確な量を継続的に使用する必要があります。しかし、現実の世界は寒くて気まぐれな場所であり、リソースの使用は定期的または予測可能ではありません。良い状況として、リクエスト値の上下に25%のマージンを考慮してください。 使用量がリクエストよりもはるかに少ない場合、お金を無駄にしています。 それよりも高い場合、ノードにおけるパフォーマンス問題となるリスクとなります。
リミットに関して良い設定を達成することは、試行錯誤が必要となるでしょう。アプリケーションの性質、需要モデル、エラーへの耐性、その他多くの要因にほとんど依存しないため、誰にとっても最適な値はありません。
考慮すべきもう1つのことは、ノードで許可するリミットのオーバーコミットです。
Kubernetesでは許可するオーバーコミットの量を通知する自動のメカニズムがないため、これらのリミットはユーザーが適切に使用する必要があります。
このことから学ぶべき教訓は次のとおりです。
リソースを適切に共有するには、クォータが必要です。共有サービスをリミットなしで使用できると誰かが言った場合、それらは嘘をついているか、システムが最終的に崩壊します。
Sysdig Monitorのような優れたモニタリングシステムは、クォータが適切に構成されていることを確認するのに役立ちます。 試されたい方は、https://sysdig.jp/ 内の無料お試しをクリックすると14日間のトライアルライセンスが発行されます。
Sysdig Secureも試されたい方は、http://www.scsk.jp/sp/sysdig/index.htmlからお問い合わせいただければと存じます。