Kubernetesクラスター内の各ノードで、不要になったDockerイメージを定期的に自動削除するためのCronJob設定について解説します。このソリューションは、ノードのディスク容量を効率的に管理することを目的としており、毎日午前3時に実行されます。
前提条件:
- Kubernetesバージョン v1.20以降 (
kubectl debug機能を利用するため) - コンテナランタイムとしてDockerを使用しているノード (containerdやCRI-Oは直接サポートされていません)
ClusterRoleおよびClusterRoleBindingを作成するための権限docker:28.0.1およびbitnami/kubectl:latestイメージをプルできるネットワーク環境- ノードで稼働しているDockerバージョンと互換性のあるDockerイメージバージョンを使用することを推奨します。
互換性:
- コンテナランタイム: Dockerのみ直接サポート。containerdやCRI-Oを使用する場合は、
crictlコマンドへの適応が必要です。 - Kubernetesバージョン: v1.20以降では
kubectl debugが利用可能。v1.15からv1.19ではkubectl runによる代替策が必要になる場合があります。v1.15未満はサポート対象外です。
機能概要:
- 実行スケジュール: 毎日午前3時
- 対象範囲: クラスター内の全ノード
- クリーンアップポリシー:
- 過去24時間以上使用されていないイメージを削除
- 未使用の(dangling)イメージを削除
- タイムアウト設定: 各ノードでの操作は120秒以内に完了する必要があります。
- 履歴管理: 成功したジョブは3件、失敗したジョブは1件保持されます。
CronJob YAML設定例:
apiVersion: batch/v1
kind: CronJob
metadata:
name: node-image-cleaner
namespace: kube-system # または任意の管理用ネームスペース
spec:
schedule: "0 3 * * *"
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
ttlSecondsAfterFinished: 3600 # ジョブ完了後1時間で自動削除
template:
spec:
serviceAccountName: node-cleaner-sa
containers:
- name: image-purger
image: bitnami/kubectl:latest
command: ["/bin/bash", "-c"]
args:
- |
echo "Starting Docker image cleanup across all nodes..."
NODE_OPERATION_TIMEOUT=120 # seconds
kubectl get nodes -o name | while read node_ref; do
NODE_NAME=$(basename $node_ref)
echo "Processing node: $NODE_NAME"
# Use kubectl debug to execute cleanup commands on the node
timeout $NODE_OPERATION_TIMEOUT kubectl debug $NODE_NAME \
--image=docker:28.0.1 \
--quiet \
-- sh -c "
echo 'Running cleanup on node ${NODE_NAME}...'
# Prune images older than 24 hours
chroot /host docker image prune -a -f --filter 'until=24h' >/dev/null 2>&1
# Prune dangling images
chroot /host docker image prune -f >/dev/null 2>&1
echo 'Cleanup completed on node ${NODE_NAME}.'
" || echo "Node $NODE_NAME cleanup timed out or failed."
echo "$NODE_NAME processing finished."
echo "--------------------"
done
echo "All nodes image cleanup finished."
restartPolicy: Never
デプロイ手順:
- Namespaceの作成 (まだ存在しない場合):
kubectl create namespace image-cleanup-ns - ServiceAccountの作成:
kubectl create serviceaccount node-cleaner-sa -n image-cleanup-ns - ClusterRoleの作成: ノード情報の取得とデバッグPodの作成・削除権限を付与します。
kubectl apply -f - <<EOF apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: node-image-cleaner-role rules: - apiGroups: [""] resources: ["nodes"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["pods"] verbs: ["create", "delete", "get", "list", "watch"] EOF - ClusterRoleBindingの作成: ServiceAccountにClusterRoleを紐付けます。
kubectl apply -f - <<EOF apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: node-image-cleaner-binding subjects: - kind: ServiceAccount name: node-cleaner-sa namespace: image-cleanup-ns roleRef: kind: ClusterRole name: node-image-cleaner-role apiGroup: rbac.authorization.k8s.io EOF - CronJobの適用: 上記のYAML設定をファイルに保存し、適用します。
kubectl apply -f your-cronjob-file.yaml -n image-cleanup-ns
設定詳細:
schedule: "0 3 * * *": UTC午前3時にジョブを実行します。successfulJobsHistoryLimit: 3,failedJobsHistoryLimit: 1: 過去のジョブ実行履歴の保持数を指定します。ttlSecondsAfterFinished: 3600: 完了したジョブは1時間後に自動的に削除されます。--image=docker:28.0.1: ノード上でDockerコマンドを実行するために使用される一時的なコンテナイメージです。ノードのDockerバージョンとの互換性を考慮して、適切なバージョンを指定することが重要です。timeout $NODE_OPERATION_TIMEOUT: 各ノードでのDockerコマンド実行にタイムアウトを設定します。chroot /host docker image prune ...: ノードのルートファイルシステムにchrootしてからDockerコマンドを実行し、ホストOSのDockerデーモンにアクセスします。--filter 'until=24h': 24時間以上使用されていないイメージを対象とします。
注意事項:
- RBAC権限:
ClusterRoleおよびClusterRoleBindingの設定が正しく行われていることを確認してください。 - リソースへの影響: イメージクリーンアップは一時的にノードのCPUやI/Oに負荷をかける可能性があります。
- 監視: CronJobの実行状況、ノードのディスク使用率を監視し、問題発生時にはログを確認してください。
- Dockerバージョンの整合性:
--image=docker:X.Y.Zで使用するDockerイメージのバージョンは、ノードにインストールされているDockerエンジンのバージョンと互換性があることを確認してください。バージョンが大きく異なると、コマンドが失敗したり、予期せぬ動作を引き起こしたりする可能性があります。
トラブルシューティング:
- 権限エラー:
kubectl auth can-i ...コマンドでServiceAccountの権限を確認します。 - イメージプル失敗: ネットワーク設定や、プライベートレジストリを使用している場合は認証情報を確認します。
- ノードでのコマンド失敗:
kubectl logsでジョブのログを確認し、Dockerコマンドのエラーメッセージを調査します。kubectl debugコマンドを直接ノードで実行してテストすることも有効です。