本文の内容は、2024年2月12日にNIGEL DOUGLAS が投稿したブログ(https://sysdig.com/blog/resource-constraints-in-kubernetes-and-security/)を元に日本語に翻訳・再構成した内容となっております。
Sysdig 2024 クラウドネイティブ セキュリティおよび利用状況レポートは、進化する脅威の状況を浮き彫りにしていますが、さらに重要なのは、コンテナや Kubernetes などのクラウドネイティブ テクノロジーの採用が増加し続けているため、すべての組織がベストプラクティスに従っているわけではないことです。これにより、Kubernetes などの運用でコンテナを悪用してリソースを利用する際に、最終的に攻撃者が有利になることになります。
リソース管理とセキュリティのバランスをとることは、技術的な課題であるだけでなく、戦略的な義務でもあります。驚くべきことに、Sysdig の最新の調査レポートでは、CPU とメモリの使用量に関するアラートを備えている Kubernetes 環境は半数未満であり、大多数にはこれらのリソースに対する最大制限がないことが判明しました。この傾向は、セキュリティ慣行の見落としだけではありません。これは、潜在的なセキュリティリスクよりも可用性と開発の機敏性を優先していることを反映しています。
未チェックのリソースのセキュリティリスク
Kubernetes ポッドでの無制限のリソース割り当ては、攻撃者にとって絶好の機会となります。制約がなければ、悪意のあるエンティティが環境を悪用し、クリプトジャッキング攻撃を開始したり、ネットワーク内の他のシステムを標的とする横方向の動きを開始したりする可能性があります。リソース制限がない場合、セキュリティ リスクが増大するだけでなく、攻撃者によるチェックされていないリソースの消費により、多大な経済的損失が発生する可能性もあります。
費用対効果の高いセキュリティ戦略
一銭一銭が重要な現在の経済状況では、リソースの使用状況を把握して管理することは、セキュリティ戦略であると同時に財務戦略でもあります。不必要なリソース消費を特定して削減することで、組織は大幅なコスト削減を達成できます。これは、クラウド環境とコンテナ環境の両方において重要な側面です。
Kubernetes でのリソース制約の強制
Kubernetesでリソース制約を実装するのは簡単ですが、インパクトがあります。Kubernetesの atomicred
ツールのデプロイメント例にリソース制約を適用するには、ユーザーは単純にデプロイメントマニフェストを変更して、 resources
のリクエストとリミットを含めることができます。
Kubernetesプロジェクトが推奨する変更の実施方法は以下の通りです:
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: atomicred
namespace: atomic-red
labels:
app: atomicred
spec:
replicas: 1
selector:
matchLabels:
app: atomicred
template:
metadata:
labels:
app: atomicred
spec:
containers:
- name: atomicred
image: issif/atomic-red:latest
imagePullPolicy: "IfNotPresent"
command: ["sleep", "3560d"]
securityContext:
privileged: true
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
nodeSelector:
kubernetes.io/os: linux
EOF
Code language: JavaScript (javascript)
このマニフェストでは、次のように CPU とメモリのリクエストとリミットの両方を設定します。
requests
: Kubernetes がコンテナに対して保証する CPU とメモリの量です。この場合、64Mi のメモリと 250m CPU (1000m は 1 CPU コアに相当します)。limits
: コンテナが使用できる CPU とメモリの最大量です。コンテナがこれらのリミットを超えようとすると、スロットルされるか (CPU)、強制終了され、場合によっては再起動されます (メモリ)。ここでは、メモリ 128Mi、CPU 500m に設定しています。
この設定により、Atomicred ツールが効率的に機能するのに十分なリソースが割り当てられると同時に、Kubernetes クラスター内の他のプロセスに影響を与える可能性のある過剰なリソースの消費を防ぐことができます。これらのリクエストの制約により、コンテナが少なくとも指定されたリソースを取得することが保証され、リミットにより、定義された上限を超えないことが保証されます。この設定は、リソースの使用率を最適化するだけでなく、リソース枯渇攻撃からも保護します。
Kubernetes でのリソース制約のモニタリング
Kubernetesで実行中のポッドのリソース制約を確認するには、kubectl describeコマンドを使用します。このコマンドは、app=atomicredというラベルを持つatomic-redネームスペースの最初のPodを自動的に記述します。
kubectl describe pod -n atomic-red $(kubectl get pods -n atomic-red -l app=atomicred -o jsonpath="{.items[0].metadata.name}")
Code language: JavaScript (javascript)
これらのリミットを乱用するとどうなるでしょうか?
CPU とメモリのリミットをテストするには、そのリミットで許可されている以上のリソースを意図的に消費しようとするコンテナを実行できます。ただし、これは少し複雑になる可能性があります。
- CPU : コンテナがその制限を超える CPU リソースを使用しようとすると、Kubernetes はコンテナの CPU 使用率を調整します。これは、コンテナは終了されませんが、実行速度が遅くなることを意味します。
- メモリ: コンテナがリミットを超えるメモリを使用しようとした場合、リミットを超えると Kubernetes によって終了されます。これは、メモリ不足 (OOM) キルとして知られています。
ストレス テストコンテナの作成
意図的にリソースに負荷をかける新しいデプロイメントを作成できます。
たとえば、Stress などのツールを使用して、CPU とメモリを意図的に消費できます。
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: resource-stress-test
namespace: atomic-red
spec:
replicas: 1
selector:
matchLabels:
app: resource-stress-test
template:
metadata:
labels:
app: resource-stress-test
spec:
containers:
- name: stress
image: polinux/stress
resources:
limits:
memory: "128Mi"
cpu: "500m"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
EOF
Code language: JavaScript (javascript)
デプロイメント仕様では、イメージpolinux/stressを使用して単一のコンテナを定義します。これは、ワークロードとストレステストの生成に一般的に使用されるイメージです。リソースセクションでは、コンテナのリソースのリスエストとリミットを定義します。150Mi のメモリをリクエストしていますが、メモリの最大しきい値は 128Mi のリミットに固定されています。
コンテナ内でコマンドが実行され、K8s に 150 MB の仮想ワークロードを作成し、1 秒間ハングするように指示されます。これは、このコンテナイメージを使用してストレステストを実行する一般的な方法です。
以下のスクリーンショットからわかるように、OOMKilled 出力が表示されます。これは、メモリ不足によりコンテナが強制終了されることを意味します。OOMKilled アクションの時点で攻撃者がポッド内でクリプトマイニングバイナリを実行していた場合、攻撃者は追い出され、ポッドは元の状態に戻り (マイニング バイナリのインスタンスがすべて削除され、事実上)、ポッドが再作成されます。 。
リソースの制約なしでデプロイされたポッドに関するアラート
適切なリソース制約が設定されていることを確認するために、すべてのポッドを説明する必要があるかどうか疑問に思うかもしれません。それを行うこともできますが、厳密にはスケーラブルではありません。もちろん、Kubernetes ログ データを Prometheus に取り込み、それに応じてレポートすることもできます。あるいは、Kubernetes クラスターに Falco がすでにインストールされている場合は、以下の Falco ルールを適用して、リソースのリミットなしでポッドが正常にデプロイされているインスタンスを検出できます。
- rule: Create Pod Without Resource Limits
desc: Detect pod created without defined CPU and memory limits
condition: kevt and pod and kcreate
and not ka.target.subresource in (resourcelimits)
output: Pod started without CPU or memory limits (user=%ka.user.name pod=%ka.resp.name resource=%ka.target.resource ns=%ka.target.namespace images=%ka.req.pod.containers.image)
priority: WARNING
source: k8s_audit
tags: [k8s, resource_limits]
- list: resourcelimits
items: ["limits"]
Code language: JavaScript (javascript)
注: Kubernetes ワークロードの設定方法によっては、このルールにより、リソースリミットなしで意図的にデプロイされた正規のポッドに対してFalse/Positiveアラート検出が生成される可能性があります。このような場合でも、誤検知を最小限に抑えるために、このルールを微調整するか、いくつかのエクセプションを実装する必要がある場合があります。ただし、このようなルールを実装すると、監視機能が大幅に強化され、Kubernetes でのリソース割り当てのベスト プラクティスが確実に遵守されるようになります。
Sysdig のオープンソースへの取り組み
多くの組織で Kubernetes にリソース制約が強制されていないことは、現在のセキュリティ フレームワークに重大なギャップがあることを浮き彫りにしており、認識を高めることが緊急に必要であることを浮き彫りにしています。これに応えて、私たちは調査結果を Kubernetes の OWASP Top 10 フレームワークに提供し、間違いなく安全でないワークロード構成の一例に対処しました。私たちのコントリビューションはその価値が認められ、正式にフレームワークに組み込まれました。OWASP フレームワークの本質的にオープン ソースの性質を利用して、この新しい機能強化を提案するプル リクエスト(PR) を GitHub に送信しました。確立されたセキュリティ意識フレームワークに貢献するこの行為は、クラウドネイティブ セキュリティを強化するだけでなく、その透明性も強化し、より安全で意識的なクラウドネイティブ エコシステムに向けた極めて重要な一歩となります。
セキュリティとスケーラビリティの橋渡し
リソース制約の維持、監視、および変更が複雑であると認識されると、多くの場合、組織はこれらの重要なセキュリティ対策の実装を妨げる可能性があります。アプリケーションのニーズが需要、機能のロールアウト、スケーラビリティの要件に基づいて変動する可能性がある開発環境の動的な性質を考慮すると、チームがリソースの制限を俊敏性に対する潜在的な障壁とみなす理由は理解できます。ただし、この観点では、Kubernetes のリソース管理機能に本来備わっている柔軟性、そしてさらに重要なことに、セキュリティとパフォーマンスの両方の設定を最適化する際の部門を超えたコミュニケーションの重要な役割が見落とされています。
柔軟な制約の技
Kubernetes は、アプリケーションの成長や運用の柔軟性を本質的に妨げることのない、リソース制約を管理するための洗練されたモデルを提供します。Kubernetes では、リクエストとリミットを使用することで、コンテナに対して保証される最小リソース (リクエスト) と、コンテナが超えることができない最大キャップ (リミット) を指定できます。このモデルは、アプリケーションが効率的に動作し、パフォーマンスを損なうことなくセキュリティを確保する事前定義された範囲内でスケーリングできるフレームワークを提供します。
このモデルを効果的に活用する鍵は、継続的な評価と調整のアプローチを採用することにあります。リソース使用率のメトリクスを定期的に確認すると、割り当てられたリソースに対してアプリケーションがどのように実行されているかに関する貴重な洞察が得られ、実際のニーズに合わせて制約を調整する機会を特定できます。この反復的なプロセスにより、リソース制限が適切な状態に保たれ、アプリケーションの要求をサポートし、セキュリティの脆弱性から保護されることが保証されます。
オープンなコミュニケーションラインの育成
柔軟なリソース制約を適切に実装するための核となるのは、開発、運用、セキュリティの各チーム間のコラボレーションです。オープンなコミュニケーションラインは、アプリケーションの要件を理解し、構成変更による潜在的なセキュリティへの影響に関する洞察を共有し、リソース割り当てについて情報に基づいた意思決定を行うために不可欠です。
透明性とコラボレーションの文化を奨励すると、リソース制限を調整するプロセスがわかりやすくなり、困難な作業ではなく、開発ライフサイクルの日常的な部分になります。定期的な部門横断的な会議、リソース使用率とパフォーマンス指標の共有ダッシュボード、およびインシデント対応への統一されたアプローチにより、より統合されたチームのダイナミクスを促進できます。
メンテナンス、監視、変更の簡素化
適切なツールと実践方法を導入すると、リソース管理を合理化し、既存の開発ワークフローに統合できます。自動化ツールを使用すると、リソース制約の導入と更新を簡素化でき、監視ソリューションではリソースの使用率とパフォーマンスをリアルタイムで可視化できます。
トレーニングと権限付与を、明確なガイドラインと使いやすいツールと組み合わせることで、セキュリティ体制と運用の機敏性の両方をサポートする簡単なタスクでリソースの制約を調整できます。
まとめ
Kubernetes でのリソース制限の設定は、単なるセキュリティ対策ではありません。これは、運用効率と堅牢なセキュリティのバランスを調和させる極めて重要な戦略です。この手法は、進化するクラウドネイティブの脅威、特にクリプトマイニング攻撃の観点からさらに重要性を増しています。クリプトマイニング攻撃は、労力が少なく報酬が高いという性質から、攻撃者にとってますます好まれる手法になりつつあります。
2022 年のクラウドネイティブ脅威レポートを振り返ると、注目すべき傾向が観察されます。Sysdig 脅威リサーチチームは、主に仮想通貨マイニングを目的として、クラウド環境とコンテナ環境の両方を標的にすることで知られる悪名高いクラウドネイティブの脅威アクターである TeamTNT をプロファイリングしました。彼らのリサーチは、驚くべき経済的不均衡を示しています。クリプトジャッキングでは、攻撃者が盗まれたリソースから得る 1 ドルごとに、被害者に驚くべき事に 53 ドルの費用がかかります。この差異は、明らかなセキュリティ侵害を超えて、このような攻撃による経済的影響を浮き彫りにしています。
TeamTNT のアプローチは、攻撃者がコンテナのリソース制限が未定義または監視されていない環境を悪用することを選択する理由を繰り返し示しています。コンテナ内のリソース使用量に対する制約や監視が欠如しているため、攻撃者がクリプトジャッキング マルウェアを展開し、被害者を犠牲にして金銭的利益を得るために監視されていないリソースを利用するための野蛮な環境が生まれます。
これらの洞察を踏まえると、Kubernetes でのリソース制約の実装と Kubernetes でのリソース使用状況の監視は、セキュリティと運用効率の単なるベストプラクティスではないことが明らかになります。これらは、経済的に浪費するクリプトマイニング攻撃の増加傾向に対する重要な防御策です。Kubernetes が進化し続けるにつれて、これらのプラクティスの重要性は高まるばかりです。組織は、適切なリソース制限を設定し、慎重な監視システムを確立することで積極的に適応し、このような潜行的な脅威に直面しても安全で効率的で財務的に健全な環境を確保する必要があります。