hostPath ボリュームは、これにより、Pod はノードのファイルシステムを読み書きできるようになり、ノードレベルのログへのアクセス、特定の設定ファイルの読み取り、開発環境での迅速なデータ共有などのシナリオで役立ちます。
仕組み
プロセスの概要
Pod がノードにスケジュールされると、そのノード上の kubelet は、コンテナーを起動する前に hostPath マウント操作を実行します。kubelet は、定義された type に基づいて、hostPath フィールドで指定された path を検証して準備します。
DirectoryOrCreate: ホストにpathが存在するかどうかを確認します。存在しない場合は、パーミッション0755で空のディレクトリが自動的に作成されます。所有者とグループは kubelet と同一になります。Directory: ホストにpathが存在し、それがディレクトリであるかどうかを確認します。そうでない場合、Pod の起動は失敗します。FileOrCreate: ホストのpathが存在するかどうかを確認します。存在しない場合は、パーミッション0644で空のファイルが自動的に作成されます。所有者とグループは kubelet と同一になります。File: ホストにpathが存在し、それがファイルであるかどうかを確認します。そうでない場合、Pod の起動は失敗します。
検証後、kubelet はホストの path をコンテナーにバインドマウントします。コンテナーからマウントポイントへの読み書き操作は、ホストのファイルシステムに直接影響します。
使用方法
Pod で hostPath ボリュームを直接マウントする: この方法は、Pod の
volumesセクションでhostPathを定義することで簡単に設定できます。ただし、アプリケーションとノードのストレージ間に密結合が生まれるため、長期的なメンテナンスや将来のストレージ変更が必要な本番アプリケーションには推奨されません。PV と PVC を使用して hostPath ボリュームをマウントする: この方法は、ストレージをアプリケーションから分離します。
hostPathは別の永続ボリューム (PV) で定義され、Pod は 永続ボリューム要求 (PVC) を使用してそれを要求します。これにより、アプリケーションの Pod 定義を変更することなく、基盤となるストレージを独立して管理できます。
方法 1: Pod で hostPath を直接マウントする
pod-hostpath-direct.yamlという名前のファイルを作成します。この例では、ノードの
/dataディレクトリを Pod の/testディレクトリにマウントします。apiVersion: v1 kind: Pod metadata: name: test-pod spec: containers: - image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 name: test-container volumeMounts: - mountPath: /test name: test-volume volumes: - name: test-volume hostPath: # ホストノード上のパスを指定します path: /data # マウントモードを指定します type: DirectoryOrCreatePod をデプロイします。
kubectl apply -f pod-hostpath-direct.yamlPod 内にファイルを作成し、そのファイルがホストノードに存在するかどうかを確認して、マウントを検証します。
Pod にファイルを作成します。
Pod の
/testディレクトリ (マウントポイント) にtest.txtという名前のファイルを作成します。kubectl exec test-pod -- sh -c 'echo "This file was created from within the Pod." > /test/test.txt'Pod が実行されているノードの名前を取得します。
NODE_NAME=$(kubectl get pod test-pod -o jsonpath='{.spec.nodeName}') echo "Pod is running on node: $NODE_NAME"ノード上のファイルを確認します。
ノードにログインし、
ls /dataコマンドを実行して、ホストの/dataディレクトリにファイルがあるかを確認します。test.txtファイルが存在する場合、hostPath ボリュームは正常にマウントされています。
方法 2: PV と PVC を使用して hostPath をマウントする
pv-pvc-hostpath.yamlという名前のファイルを作成します。この例では、ホストの
/dataディレクトリを指す PV、このストレージを要求する PVC、およびこの PVC を使用する Pod を作成します。# --- PV の定義 --- apiVersion: v1 kind: PersistentVolume metadata: name: hostpath-pv labels: type: local spec: capacity: storage: 10Gi accessModes: - ReadWriteOnce hostPath: path: "/data" --- # --- PVC の定義 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: hostpath-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi # セレクターは、この PVC が上記で作成した PV にバインドされるようにします selector: matchLabels: type: local --- # --- Pod の定義 --- apiVersion: v1 kind: Pod metadata: name: test-pod-pvc spec: containers: - name: test-container image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 ports: - containerPort: 80 volumeMounts: - mountPath: "/usr/share/nginx/html" name: storage volumes: - name: storage persistentVolumeClaim: # 上記で定義された PVC を参照します claimName: hostpath-pvcPV、PVC、および Pod を作成します。
kubectl apply -f pv-pvc-hostpath.yamlPod 内にファイルを作成し、そのファイルがノードに存在するかどうかを確認して、マウントを検証します。
Pod にファイルを作成します。
Pod の
/usr/share/nginx/htmlディレクトリ (マウントポイント) にtest.txtという名前のファイルを作成します。kubectl exec test-pod-pvc -- sh -c 'echo "File from PV/PVC Pod." > /usr/share/nginx/html/test.txt'Pod が実行されているノード名を取得します。
NODE_NAME=$(kubectl get pod test-pod-pvc -o jsonpath='{.spec.nodeName}') echo "Pod is running on node: $NODE_NAME"ノード上のファイルを確認します。
ノードにログインし、
ls /dataコマンドを実行して、ホストの/dataディレクトリにファイルがあるかを確認します。test.txtファイルが存在する場合、PV と PVC を使用してマウントされた hostPath ボリュームは正常に機能しています。
本番運用時の注意点
セキュリティ
読み取り専用マウントの使用: アプリケーションがノードからデータを読み取るだけでよい場合は、ボリュームを読み取り専用 (
ReadOnlyMany) に設定して、ホストファイルへの意図しない変更を防ぎます。最小権限の原則に従う: ホストのルートディレクトリ (
/) や、/etcや/varなどの機密性の高いシステムディレクトリをマウントしないでください。hostPath ボリュームには、常に専用の隔離されたディレクトリを使用してください。
ノードリソース
データの永続性とポータビリティ
説明hostPath ボリュームは Pod のデータを特定のノードの物理ストレージに密結合させるため、データはそのノードに限定され、ノード間での永続性はありません。
データベースやキャッシュなど、高可用性と永続ストレージを必要とするステートフルアプリケーションには hostPath を使用しないでください。障害や更新により Pod が別のノードに再スケジュールされると、元のデータへのアクセスが失われます。
hostPath はコンテナーの隔離を破壊します。 Pod にホストファイルシステムへのアクセスを許可すると、重大なセキュリティリスクが生じます。コンテナー化されたアプリケーションの脆弱性が悪用され、ノード全体が侵害される可能性があります。ContainerOS のような読み取り専用のルートファイルシステムを持つノードでは hostPath を使用しないでください。
よくある質問
Pod が削除されて再作成された場合、hostPath ボリューム内のデータは残りますか?
それは、新しい Pod がどこにスケジュールされるかによって異なります。
同じノードにスケジュールされた場合: はい。新しい Pod はノード上のまったく同じディレクトリをマウントし、以前のすべてのデータにアクセスできます。
別のノードにスケジュールされた場合: いいえ。新しい Pod は新しいノードに空のディレクトリをマウントします。元のデータは元のノードに残りますが、新しい Pod からはアクセスできません。
=