Docker の --shm-size オプションから始めましょう
Docker コマンドの --shm-size パラメータは、コンテナ内の共有メモリ領域のサイズを指定するために使用されます。このオプションは、特に機械学習や高性能コンピューティングのワークロードで頻繁に利用されます。このコンテナを Kubernetes 環境にデプロイする際、同様の共有メモリ設定をどのように実現するかが課題となります。本記事では、Kubernetes で共有メモリを効率的に設定する方法を解説します。
Linux における /dev/shm
Linux システムには /dev/shm という特別なディレクトリが存在します。これは「共有メモリ (Shared Memory)」を表す一時ファイルシステム(tmpfs)であり、ディスクではなくメモリ上にファイルを保存します。つまり、/dev/shm/a.txt のようなファイルを通常のディスクファイルと同じように読み書きできますが、実際にはメモリ上に存在するため、非常に高速なアクセスが可能です。
この /dev/shm を利用することで、プロセス間でデータを高速に共有したり、一時ファイルを効率的に処理したりすることができます。ソケットや RPC などのネットワークベースのプロセス間通信(IPC)と比較して、共有メモリは明らかに高いパフォーマンスを発揮します。
Docker による共有メモリのサポート
Docker はコンテナの /dev/shm サイズを制御するための2つの主要な方法を提供しています。
- docker run コマンドの --shm-size フラグ: 個々のコンテナの起動時に
--shm-size=1gのようにサイズを指定できます。 - Docker デーモンの設定:
daemon.json設定ファイル内で"shared-memory-size": "1G"を指定し、すべてのコンテナに対するデフォルトサイズを設定できます。
--shm-size フラグの設定が daemon.json のデフォルト設定より優先されます。Docker コンテナはデフォルトで 64MB の /dev/shm を使用します。
Kubernetes での /dev/shm サイズ設定
Kubernetes には /dev/shm サイズを直接設定するための専用のフィールドはありません。しかし、Pod の仕様内で共有メモリを適切に設定するためのいくつかの方法が存在します。
4.1 方案一:ノードの Docker 設定を変更する
ノード上の Docker デーモン設定(daemon.json)を変更し、グローバルに shared-memory-size を設定することで、そのノード上で実行されるすべての Pod に影響を与えることができます。この方法は全体的な設定変更には有効ですが、特定の Pod に対して柔軟にサイズを調整できないという欠点があります。
4.2 方案二:ボリュームをマウントしてディスク上の領域を利用する
Pod の /dev/shm に大きなディレクトリをボリュームとしてマウントする方法です。以下は emptyDir を使用した例です。
apiVersion: v1
kind: Pod
metadata:
name: disk-based-shm-pod
spec:
containers:
- name: app-container
image: your-image
volumeMounts:
- name: shm-volume
mountPath: /dev/shm
volumes:
- name: shm-volume
emptyDir: {}
この方法は機能的には動作しますが、emptyDir は通常ディスク上に作成されるため、共有メモリの高速性という利点を活かすことができません。パフォーマンス要件が厳しい場合は不適切です。
4.3 方案三:Kubernetes の本来の方法でメモリ上に共有メモリを確保する
Kubernetes には、Pod 専用のメモリ上の一時ファイルシステムを自動的に作成する、より適切な方法が存在します。それは emptyDir ボリュームに medium: Memory を指定するものです。これにより、指定されたサイズのメモリ上の tmpfs が Pod 内の /dev/shm として利用可能になります。
apiVersion: v1
kind: Pod
metadata:
name: memory-based-shm-pod
spec:
volumes:
- name: shm-memory-volume
emptyDir:
medium: Memory
sizeLimit: "512Mi"
containers:
- name: app-container
image: your-image
volumeMounts:
- name: shm-memory-volume
mountPath: /dev/shm
この設定により、Pod は高速な共有メモリ領域を確保し、Docker の --shm-size オプションと同等の機能を Kubernetes 環境内で実現できます。