hostPath

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

パーミッションの考慮

ディレクトリの参照設定は、volumescontainers.[].volumeMountsで設定できます。

hostPathは、アクセスパーミッションの不整合によりコンテナ内でファイルが開けないといったトラブルが起きやすい環境でもあります。
コンテナ内ではrootまたはイメージ作成者が追加したユーザーが実行する一方、ホストはOSがセットアップした別体系のユーザーが実行しており、相互のパーミッション体系に関連がないためです。

containers.[].securityContextrunAsUserrunAsGroupを設定するとコンテナ内の実行ユーザーを変更できます。
ユーザー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で指定したユーザーはコンテナ内に存在しないケースも多くありますが、存在しないユーザーでコンテナ実行できるケースが多々あります。

コンテナ内ユーザーの考慮

runAsUserrunAsGroupを指定するとホストのファイルパーミッションに沿ったアクセスの問題は概ね解消するでしょう。

一方、非rootの独自ユーザーをセットアップしているイメージの場合、実行ユーザーが変わってしまうとコンテナ内のファイルにアクセスできなくなります。
このケースの緩和策としては、runAsUserを指定せずrunAsGroupのみ指定する手があります。

コンテナ内のファイルは、イメージ作成時のユーザーIDで概ねアクセスできます。
hostPathでマウントしたファイルについては、runAsGroupで指定したグループIDでアクセスする挙動になります。
775664といった一般的なファイルパーミッションのリソースの場合、グループIDが一致すればアクセス可能です。

より込み入ったセットアップの場合、Unixアカウントとパーミッションの挙動を理解のうえ、さらに詳細な調整が必要になるでしょう。
ただし、そこまで複雑なセットアップとなると実用的とは言いにくい状況でもあります。

⁋ 2024/01/23↻ 2024/11/07
中馬崇尋
Chuma Takahiro