Karpenter v1.0+BottlerocketでEKSノードコスト40%削減を実現する実装パターン
この記事でわかること
- Karpenter v1.0のNodePool / EC2NodeClassを使ったノード自動プロビジョニングの設計と実装方法
- Bottlerocket OSを採用するメリットとKarpenterとの組み合わせによるセキュリティ・コスト効果
- Spot Instanceの活用戦略とDisruption Budgetsによる可用性制御の具体的な設定
- Cluster Autoscalerからの移行判断基準と実運用でのトラブルシューティング
- 実際の企業事例に基づくコスト削減・運用効率化の数値根拠
対象読者
- 想定読者: EKS上でワークロードを運用しているインフラエンジニア・SRE・MLEで、ノードスケーリングやコスト最適化に課題を感じている方
-
必要な前提知識:
- Kubernetesの基本概念(Pod、Node、Deployment、PodDisruptionBudget)
- AWSの基本操作(EC2、IAM、VPC)
-
kubectlコマンドの基本的な使い方 - YAML形式のマニフェスト記述経験
結論・成果
Karpenter v1.0とBottlerocketを組み合わせたEKSノードプロビジョニング構成により、以下の効果が報告されています。
- コンピュートコスト40%削減: Bottlerocketの軽量OSとKarpenterのbin-packing最適化による効率化(KubeFM事例)
- ノードプロビジョニング速度30〜60秒: Cluster Autoscalerの3〜5分から大幅に短縮(ScaleOps比較レポート)
- 運用オーバーヘッド80%削減: 静的なAuto Scaling Group管理が不要に(Salesforce 1,000+クラスタ移行事例)
ここからは、この構成を実装するための具体的な手順とノウハウを解説していきます。
Karpenterの基本アーキテクチャを理解する
Karpenterは、Kubernetesクラスタのノードライフサイクルを自動管理するオープンソースのオートスケーラーです。従来のCluster Autoscaler(以下CA)がAuto Scaling Group(ASG)を介してノードを追加・削除するのに対し、KarpenterはEC2 Fleet APIを直接呼び出してノードをプロビジョニングします。
この設計の違いが、スケーリング速度とコスト効率の差を生みます。CAではASGごとに固定のインスタンスタイプを定義する必要がありましたが、Karpenterはペンディング中のPodのリソース要求を見て、最適なインスタンスタイプ・AZ・購入オプション(On-Demand / Spot)をリアルタイムに選択します。
Karpenter v1.0の主要な変更点
Karpenter v1.0は2024年8月にGA(一般提供)となり、2026年4月時点の最新安定版はv1.11.1です(AWS Karpenter Provider リリースページ)。v1.0以降、APIの後方互換性が保証されており、安心して本番採用できます。
v1.0で導入された主要機能は以下の3つです。
| 機能 | 説明 | ユースケース |
|---|---|---|
| Disruption Budgets |
underutilized、empty、driftなど、中断理由ごとに予算を設定可能 |
ワークロードの種類に応じた細やかな中断制御 |
| Forceful Disruption Mode | アプリケーション可用性とセキュリティ要件のバランスを取る強制中断モード | セキュリティパッチ適用の強制実行 |
| consolidateAfter拡張 | 統合処理の待機時間を細かく調整可能 | バッチ処理終了後の素早いノード回収 |
また、v1.0ではDrift機能が安定版となり、NodePoolやEC2NodeClassの設定変更時に自動的にノードを置き換える動作がデフォルトで有効化されました。
Cluster Autoscalerとの違い
移行を検討する上で、CAとの違いを正しく理解しておきましょう。
| 比較項目 | Cluster Autoscaler | Karpenter v1.0+ |
|---|---|---|
| ノード追加速度 | 3〜5分(ASG経由) | 30〜60秒(EC2 Fleet API直接) |
| インスタンス選択 | ASGで事前定義 | Podの要求から動的選択 |
| bin-packing | 限定的 | 高度な最適化(25〜40%のコスト削減効果) |
| Spot対応 | ASGのMixed Instance Policy | ネイティブ対応、リアルタイムSpotスコア考慮 |
| メモリ使用量(2,000ノード) | 1GiB超 | 軽量 |
| マルチクラウド | 対応 | AWS / Azure(AKS)で対応、GKE未対応 |
| 対応プロバイダ | 全Kubernetesディストリビューション | AWS EKS、Azure AKS |
注意点: KarpenterとCAを同じクラスタで併用してはいけません。両者はノードスケーリングの同じ問題を解決するため、競合が発生します。
Karpenterは単一プロバイダー(主にAWS EKS)のクラスタで特に効果を発揮します。マルチクラウドやオンプレミスのKubernetesクラスタでは、CAが依然として有効な選択肢です。
NodePoolとEC2NodeClassを設計・実装する
Karpenterの設定は、NodePool(どのようなノードをプロビジョニングするかのポリシー)とEC2NodeClass(AWSリソースの具体的な設定)の2つのCRD(Custom Resource Definition)で構成されます。実際の設定例を見ていきましょう。
EC2NodeClassでBottlerocketを指定する
まず、ノードのAWSリソース設定を定義するEC2NodeClassを作成します。ここでBottlerocket OSを指定します。
# ec2nodeclass-bottlerocket.yaml
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
name: bottlerocket-default
spec:
# Bottlerocketを指定(AL2023も選択可能)
amiSelectorTerms:
- alias: bottlerocket@latest
role: "KarpenterNodeRole-${CLUSTER_NAME}"
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: "${CLUSTER_NAME}"
securityGroupSelectorTerms:
- tags:
karpenter.sh/discovery: "${CLUSTER_NAME}"
blockDeviceMappings:
# Bottlerocketのルートボリューム
- deviceName: /dev/xvda
ebs:
volumeSize: 4Gi
volumeType: gp3
encrypted: true
# コンテナデータボリューム
- deviceName: /dev/xvdb
ebs:
volumeSize: 50Gi
volumeType: gp3
encrypted: true
iops: 3000
throughput: 125
# Bottlerocket固有のTOML形式userData
userData: |
[settings.kubernetes.eviction-hard]
"memory.available" = "10%"
"nodefs.available" = "10%"
[settings.kubernetes]
device-ownership-from-security-context = true
なぜBottlerocketを選ぶのか:
Bottlerocketはコンテナ実行に特化した軽量OSです。通常のAmazon Linuxと比較して以下のメリットがあります。
- セキュリティ: read-onlyルートファイルシステム、SELinux強制、最小限のパッケージ構成で攻撃面を縮小
- 起動速度: 軽量なため、ノードの起動からReady状態までの時間がAL2と比較して約40秒短縮(Snowflake事例)
- 更新の安全性: ロールバック可能なアトミック更新(更新失敗時に自動で前のバージョンに戻る)
- 運用コスト: SSHなし、パッケージマネージャなしで構成ドリフトを防止
注意: Bottlerocketはカーネルモジュールのロードが制限されています。EDR(Endpoint Detection and Response)などのセキュリティエージェントがカーネルモジュールを必要とする場合、eBPFベースのツールへの移行を検討してください(KubeFM事例)。
NodePoolで自動プロビジョニングポリシーを定義する
次に、ノードのプロビジョニングポリシーを定義するNodePoolを作成します。本番環境では、ワークロードの特性に応じて複数のNodePoolを使い分けるのが効果的です。
# nodepool-general.yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: general-workload
spec:
template:
metadata:
labels:
workload-type: general
spec:
requirements:
# Spot優先、On-Demand fallback
- key: karpenter.sh/capacity-type
operator: In
values: ["spot", "on-demand"]
# 幅広いインスタンスファミリー指定
- key: karpenter.k8s.aws/instance-category
operator: In
values: ["c", "m", "r"]
# 第5世代以降を指定
- key: karpenter.k8s.aws/instance-generation
operator: Gt
values: ["4"]
# x86_64アーキテクチャ
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
nodeClassRef:
group: karpenter.k8s.aws
kind: EC2NodeClass
name: bottlerocket-default
# ノードの最大生存期間(セキュリティパッチ適用のため)
expireAfter: 72h
# クラスタ全体のリソース上限
limits:
cpu: "1000"
memory: 2000Gi
# 中断(Disruption)ポリシー
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 60s
budgets:
- nodes: "20%"
- nodes: "0"
schedule: "0 9-17 * * MON-FRI"
duration: 8h
reasons:
- Underutilized
# NodePool選択の重み(数字が大きいほど優先)
weight: 50
この設定のポイントを解説します。
インスタンスファミリーは広く指定する: c(コンピュート最適化)、m(汎用)、r(メモリ最適化)の3ファミリーを指定しています。Karpenterが広い候補プールからコスト・可用性の両方を最適化するためです。Tinybird社の事例では、インスタンスタイプを限定しすぎるとKarpenterの最適化能力が制限されると報告されています(Tinybird事例)。
expireAfter: 72hの意味: ノードの最大生存期間を72時間に設定しています。Karpenterは有効期限を過ぎたノードを自動的にdrainして置き換えます。これにより、最新のBottlerocket AMIが定期的に適用されてセキュリティパッチが自動的に当たります。
Disruption Budgetsの活用: 平日のビジネスアワー(9〜17時)にはUnderutilized理由でのノード統合を停止しています。これにより、日中のトラフィック変動でノードが頻繁に入れ替わることを防ぎます。
ステートフルワークロード用のNodePoolを分離する
ML学習ジョブやデータベースなど、中断に弱いワークロードには専用のNodePoolを作成します。
# nodepool-stateful.yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: stateful-workload
spec:
template:
metadata:
labels:
workload-type: stateful
spec:
requirements:
# On-Demandのみ(Spotは使わない)
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand"]
- key: karpenter.k8s.aws/instance-category
operator: In
values: ["m", "r"]
- key: karpenter.k8s.aws/instance-generation
operator: Gt
values: ["4"]
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
nodeClassRef:
group: karpenter.k8s.aws
kind: EC2NodeClass
name: bottlerocket-default
expireAfter: 168h
# Taintでステートフルワークロード専用にする
taints:
- key: workload-type
value: stateful
effect: NoSchedule
limits:
cpu: "200"
memory: 800Gi
disruption:
consolidationPolicy: WhenEmpty
consolidateAfter: 5m
budgets:
- nodes: "10%"
weight: 10
なぜNodePoolを分離するのか:
Karpenterのbin-packing最適化は、ステートレスなワークロードでは大きな効果を発揮しますが、ステートフルワークロードでは頻繁なノード統合がサービス中断を引き起こすリスクがあります。Salesforce社の事例では、シングルレプリカのアプリケーションがbin-packing最適化で意図せず中断される問題が報告されています(Salesforce移行事例)。
NodePoolを分離し、ステートフルワークロードにはconsolidationPolicy: WhenEmpty(空になった場合のみ統合)を設定することで、この問題を回避できます。
Spotインスタンスでコストを最適化する
Spot Instanceは、On-Demandと比較して最大90%の割引価格で利用できるEC2インスタンスです。ただし、AWSが2分前の通知でインスタンスを中断(回収)する可能性があるため、適切な戦略が必要です。
Karpenterは、リアルタイムのSpot配置スコアとインスタンスライフサイクルコストを考慮して、最適なSpotインスタンスを選択します。
Spot活用の基本戦略
Spotインスタンスを安全に活用するために、以下の3つの原則を守ります。
1. ワークロードのステートレス性を確保する
Spot中断時にPodが安全に別ノードへ移動できるよう、以下をDeploymentに設定します。
# deployment-spot-ready.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-api
spec:
replicas: 3
template:
spec:
# Pod分散配置(AZとノードをまたぐ)
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: web-api
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app: web-api
# Graceful shutdown
terminationGracePeriodSeconds: 60
containers:
- name: web-api
image: myapp:latest
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 10"]
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
memory: "512Mi"
2. PodDisruptionBudgetを設定する
# pdb.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-api-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: web-api
3. インスタンスタイプを多様化する
特定のインスタンスタイプに依存すると、そのタイプのSpotキャパシティが枯渇した際にスケーリングが停止します。NodePoolのrequirementsで複数のファミリー・世代を許可することで、Karpenterが自動的に利用可能なSpotインスタンスを探索します。
Spot中断への対応
Karpenter v1.0以降では、AWS Node Termination Handler(NTH)は不要です。Karpenterが以下のイベントを自動的にハンドリングします。
- Spot中断通知(2分前通知)
- スケジュールされたメンテナンスイベント
- インスタンスのヘルスステータス変更
Karpenterはこれらのイベントを検知すると、対象ノード上のPodをcordon→drainし、新しいノードをプロビジョニングします。
よくある間違い: Karpenter導入後もNTHを残してしまうケースがあります。両者が同時に動作すると、同じ中断イベントに対して二重にdrain処理が走り、予期しない挙動になることがあります。Karpenter導入時にはNTHを削除してください。
コスト削減効果の実例
企業各社が報告しているコスト削減効果を整理します。
| 企業 | 構成 | コスト削減効果 | 出典 |
|---|---|---|---|
| Tinybird | Karpenter + Spot + On-Demand fallback | 全体20%、CI/CDは90%削減 | Tinybird Blog |
| Salesforce | Karpenter移行(1,000+クラスタ) | FY2026で5%、FY2027見込み10-15% | InfoQ |
| 匿名事例(ZeonEdge) | Karpenter + Spot + VPA | $50K→$22K/月(56%削減) | ZeonEdge Blog |
| 匿名事例(KubeFM) | Karpenter + Bottlerocket | コンピュートキャパシティ40%削減 | KubeFM |
コスト削減効果はワークロードの特性に大きく依存します。Tinybird社のように短時間のCI/CDジョブが多い場合はSpotの効果が顕著に出る一方、Salesforce社のように大規模で安定したワークロードではbin-packing改善がメインの効果となっています。
Karpenter自体のデプロイと運用を設計する
Karpenter自身のデプロイ方法も重要な設計判断です。Karpenterが管理するノード上にKarpenter自身をデプロイすると、循環依存が発生します。
Karpenterのデプロイ先
Karpenterのデプロイには以下の3つの選択肢があります。
| 方式 | メリット | デメリット |
|---|---|---|
| マネージドノードグループ | 設定がシンプル、既存環境との親和性 | ノードグループの管理コストが残る |
| AWS Fargate | ノード管理不要、完全サーバーレス | Fargateの起動時間(30〜60秒) |
| EKS Auto Mode | AWS管理のKarpenter、設定不要 | カスタマイズ性が制限される |
Tinybird社やKubeFM事例ではFargate上にKarpenterをデプロイする方式を推奨しています。この方式では、Karpenterコントローラーの可用性がノードの状態に依存しないため、障害時の回復力が向上します。
# karpenter-fargate-profile.yaml(Terraformの場合)
# Fargateプロファイルを作成し、karpenterネームスペースの
# PodをFargateで実行
resource "aws_eks_fargate_profile" "karpenter" {
cluster_name = aws_eks_cluster.main.name
fargate_profile_name = "karpenter"
pod_execution_role_arn = aws_iam_role.fargate.arn
selector {
namespace = "karpenter"
}
subnet_ids = var.private_subnet_ids
}
Helmによるインストール
Karpenterの最新安定版(2026年4月時点でv1.11.1)をHelmでインストールします。
# Helmリポジトリ追加
helm registry logout public.ecr.aws
helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter \
--version "1.11.1" \
--namespace karpenter \
--create-namespace \
--set "settings.clusterName=${CLUSTER_NAME}" \
--set "settings.interruptionQueue=${CLUSTER_NAME}" \
--set controller.resources.requests.cpu=1 \
--set controller.resources.requests.memory=1Gi \
--set controller.resources.limits.cpu=1 \
--set controller.resources.limits.memory=1Gi \
--wait
interruptionQueueの設定: Spot中断通知を受け取るSQSキュー名を指定します。このキューはKarpenterのインストール前にTerraform等で作成しておく必要があります。
モニタリングとアラート
Karpenterは/metricsエンドポイントからPrometheus形式のメトリクスを公開しています。重要なメトリクスを監視しましょう。
# prometheus-rules.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: karpenter-alerts
namespace: monitoring
spec:
groups:
- name: karpenter
rules:
# NodePool上限に近づいたら警告
- alert: KarpenterNodePoolNearLimit
expr: |
karpenter_nodepools_usage{resource_type="cpu"}
/ karpenter_nodepools_limit{resource_type="cpu"}
> 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "NodePool CPU使用率が80%超過"
# プロビジョニング失敗の検知
- alert: KarpenterProvisioningErrors
expr: |
increase(
karpenter_provisioner_scheduling_duration_seconds_count{result="error"}[5m]
) > 0
for: 1m
labels:
severity: critical
annotations:
summary: "Karpenterのノードプロビジョニングが失敗"
Cluster Autoscalerからの移行手順を実践する
既存のCluster Autoscaler環境からKarpenterへ移行する場合、段階的なアプローチが安全です。Salesforce社の1,000+クラスタ移行事例から得られた知見をもとに、移行手順を解説します。
移行のフェーズ
Phase 1: 準備(IAMロール・SQS・NodePool作成)
Karpenterに必要なIAMロールとSQSキューを作成します。
# IAMロール作成(Terraform推奨、ここではAWS CLIの例)
# KarpenterNodeRoleにはEC2、SSM、ECRの権限が必要
# SQSキュー作成(Spot中断通知受信用)
aws sqs create-queue \
--queue-name "${CLUSTER_NAME}" \
--attributes '{"SqsManagedSseEnabled":"true"}'
# EventBridgeルール作成(Spot中断イベントをSQSに送信)
aws events put-rule \
--name "KarpenterInterruptionRule" \
--event-pattern '{
"source": ["aws.ec2"],
"detail-type": [
"EC2 Spot Instance Interruption Warning",
"EC2 Instance Rebalance Recommendation",
"EC2 Instance State-change Notification"
]
}'
Phase 2: 並行稼働(新規ワークロードをKarpenterへ)
既存のASGノードはそのまま維持し、新規のワークロードだけをKarpenterに振り向けます。NodePoolにweightを設定し、新規Podが優先的にKarpenterノードにスケジュールされるようにします。
# Karpenterをインストール(前述のHelmコマンド)
# NodePool / EC2NodeClassを適用
kubectl apply -f ec2nodeclass-bottlerocket.yaml
kubectl apply -f nodepool-general.yaml
# 動作確認:テスト用Podを作成
kubectl run test-karpenter --image=nginx --restart=Never \
--overrides='{
"spec": {
"nodeSelector": {"workload-type": "general"}
}
}'
# ノードのプロビジョニングを確認
kubectl get nodes -l karpenter.sh/registered=true
kubectl get nodeclaims
Phase 3〜4: 既存ノードのdrain → CA停止
問題がなければ、既存のASGノードからワークロードを段階的にdrainし、最終的にCluster Autoscalerを停止します。
# CAのレプリカを0にして停止
kubectl scale deployment cluster-autoscaler \
-n kube-system --replicas=0
# 既存ASGノードを段階的にdrain
for node in $(kubectl get nodes -l eks.amazonaws.com/nodegroup -o name); do
kubectl cordon "$node"
kubectl drain "$node" --ignore-daemonsets --delete-emptydir-data
done
# ASGの最小サイズを0に設定
aws autoscaling update-auto-scaling-group \
--auto-scaling-group-name "${ASG_NAME}" \
--min-size 0 --desired-capacity 0
ハマりポイント: Salesforce社の事例では、PodDisruptionBudget(PDB)の設定ミスによりノードのdrain処理がブロックされるケースが報告されています。移行前に全PDBの
minAvailable/maxUnavailable設定を確認し、drain処理を許可する余裕があることを確認してください。
Phase 5: 最適化
移行完了後、consolidateAfterの値を調整してコスト効率を最大化します。
# Karpenterメトリクスでノード使用率を確認
kubectl get nodeclaims -o custom-columns=\
NAME:.metadata.name,\
TYPE:.spec.requirements[0].values[0],\
INSTANCE:.status.instanceType,\
ZONE:.status.zone,\
CAPACITY:.status.capacity.cpu,\
AGE:.metadata.creationTimestamp
よくある問題と解決方法
Karpenter運用で遭遇しやすい問題とその対処法をまとめます。
| 問題 | 原因 | 解決方法 |
|---|---|---|
| Podが永続的にPending | NodePoolのlimitsに到達 |
limitsの引き上げ、または不要なNodeClaimの確認 |
| ノードが頻繁に入れ替わる |
consolidateAfterが短すぎる |
値を60s→5m等に延長 |
| Spot中断後にスケーリングが遅い | インスタンスタイプが限定的 |
instance-categoryを["c","m","r"]に拡大 |
| Bottlerocketでセキュリティエージェントが動かない | カーネルモジュール制限 | eBPFベースのエージェントに変更 |
| PDB違反でdrainがブロックされる |
minAvailableが高すぎる |
PDB設定を見直し、maxUnavailable: 1を使用 |
| Drift検出で全ノードが同時に置き換わる | Disruption Budgetが未設定 |
budgetsで同時置き換えノード数を制限 |
トレードオフの理解:
Karpenter + Bottlerocket構成は、スケーリング速度とコスト効率で大きなメリットがありますが、以下の制約も存在します。
- 学習曲線: CAからの移行にはNodePool / EC2NodeClassの設計知識が必要
- AWS依存: Karpenter AWS Providerを使う場合、AWS EKSに強くロックインされる
-
Bottlerocketの制約: パッケージマネージャがないため、ノード上でのデバッグはAPI経由(
apiclientコマンド)に限定される - Spot依存のリスク: Spotキャパシティが逼迫する時期(年末年始、re:Inventなど)にはOn-Demand fallbackのコストが増加する
まとめと次のステップ
まとめ:
- Karpenter v1.0はEC2 Fleet APIを直接呼び出し、30〜60秒でノードをプロビジョニングする(CAの3〜5分から大幅短縮)
- BottlerocketのRead-Onlyルートファイルシステムと最小限のパッケージ構成が、セキュリティとノード起動速度を向上させる
- NodePoolの分離(ステートレス用 / ステートフル用)とDisruption Budgetsの活用が、コスト最適化と可用性のバランスを取る鍵
- 実際の企業事例では、コンピュートコスト20〜56%削減、運用オーバーヘッド80%削減が報告されている
- AL2のAMI配信は2025年11月に停止済みのため、Bottlerocket / AL2023への移行は計画的に進める必要がある
次にやるべきこと:
- 開発環境でKarpenter + Bottlerocketの構成を作成し、ノードプロビジョニングの速度と動作を検証する
- 既存ワークロードのSpot耐性を評価する(ステートレス性、PDB設定、graceful shutdown対応)
- AWS EKS Best Practices - Karpenterを参照し、自組織のセキュリティ要件に合わせたIAMポリシーを設計する
参考
- AWS公式 - Karpenter Best Practices
- Karpenter公式ドキュメント - NodeClasses
- Karpenter公式ドキュメント - Disruption
- Karpenter公式ドキュメント - NodePools
- AWS Bottlerocket公式
- Snowflake Bottlerocket + Karpenter事例 - AWS Open Source Blog
- Salesforce 1,000+ EKS Clusters Karpenter移行 - AWS Architecture Blog
- Tinybird AWS Cost 20%削減事例
- KubeFM - 40% Compute Capacity削減事例
- Karpenter vs Cluster Autoscaler比較 - ScaleOps
- Karpenter AWS Provider Releases - GitHub
- ZeonEdge $50K→$22K/月コスト削減事例
- Salesforce Karpenter移行 - InfoQ
注意: この記事はAI(Claude Code)により自動生成されました。内容の正確性については複数の情報源で検証していますが、実際の利用時は公式ドキュメントもご確認ください。