kubernetesのhostPathボリュームは、クラスタノードのディレクトリをコンテナにマウントする機能です。
k3sなど開発環境のローカルクラスタで、コンテナ内からワーキングディレクトリにアクセスしたいケースに使えます。
基本的な設定
volumes.[].hostPathにノードのディレクトリを指定します。
apiVersion: apps/v1
kind: StatefulSet
spec:
template:
spec:
volumes:
- name: working-dir
hostPath:
path: /opt
type: Directory
containers.[].volumeMountsに参照設定を記述します。
mountPathはコンテナ内のディレクトリです。
apiVersion: apps/v1
kind: StatefulSet
spec:
template:
spec:
containers:
- name: sample-container
volumeMounts:
- name: working-dir
mountPath: /root
パーミッションの考慮
ディレクトリの参照設定は、volumesとcontainers.[].volumeMountsで設定できます。
hostPathは、アクセスパーミッションの不整合によりコンテナ内でファイルが開けないといったトラブルが起きやすい環境でもあります。
コンテナ内ではrootまたはイメージ作成者が追加したユーザーが実行する一方、ホストはOSがセットアップした別体系のユーザーが実行しており、相互のパーミッション体系に関連がないためです。
containers.[].securityContextのrunAsUserやrunAsGroupを設定するとコンテナ内の実行ユーザーを変更できます。
ユーザーIDをホストのユーザーIDに合わせると、ファイルパーミッションをホスト環境に合わせられます。
apiVersion: apps/v1
kind: StatefulSet
spec:
template:
spec:
containers:
- name: sample-container
securityContext:
runAsUser: 5000
runAsGroup: 5000
ホストのユーザーID・グループIDはOS環境とセットアップにより異なるため、ホストのidコマンドや/etc/passwdなどで確認します。
runAsUserで指定したユーザーはコンテナ内に存在しないケースも多くありますが、存在しないユーザーでコンテナ実行できるケースが多々あります。
コンテナ内ユーザーの考慮
runAsUserとrunAsGroupを指定するとホストのファイルパーミッションに沿ったアクセスの問題は概ね解消するでしょう。
一方、非rootの独自ユーザーをセットアップしているイメージの場合、実行ユーザーが変わってしまうとコンテナ内のファイルにアクセスできなくなります。
このケースの緩和策としては、runAsUserを指定せずrunAsGroupのみ指定する手があります。
コンテナ内のファイルは、イメージ作成時のユーザーIDで概ねアクセスできます。
hostPathでマウントしたファイルについては、runAsGroupで指定したグループIDでアクセスする挙動になります。
775や664といった一般的なファイルパーミッションのリソースの場合、グループIDが一致すればアクセス可能です。
より込み入ったセットアップの場合、Unixアカウントとパーミッションの挙動を理解のうえ、さらに詳細な調整が必要になるでしょう。
ただし、そこまで複雑なセットアップとなると実用的とは言いにくい状況でもあります。