サブロウ丸

Sabrou-mal サブロウ丸

主にプログラミングと数学

マルチサーバ、マルチコンテナ(Docker)環境でのMPIプログラム実行

本稿ではホストネットワークを用いてマルチサーバーでマルチコンテナ環境でのMPI プログラムを実行する環境の作成を行います。

Docker Swarm ネットワークを用いた環境構築はこちら↓

コンテナの作成

準備

Dockerfile がある場所で次を実行し、鍵を生成する。

mkdir ssh
ssh-keygen -t rsa -N "" -f ./ssh/id_rsa

Dockerfile

FROM ubuntu:20.04

# using ssh port
ENV SSH_PORT=2222

RUN apt update && apt upgrade
RUN DEBIAN_FRONTEND=noninteractive TZ=Asia/Tokyo \
    apt install -y tzdata build-essential libopenmpi-dev openssh-server sshpass

RUN mkdir /var/run/sshd
RUN echo 'root:password' | chpasswd  # rootユーザのpasswordを設定
RUN echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
RUN echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config

COPY ./ssh /root/.ssh

# copy docker-entrypoint.sh
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh

EXPOSE ${SSH_PORT}

# --allow-run-as-root
ENV OMPI_ALLOW_RUN_AS_ROOT=1
ENV OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1

CMD ["/usr/local/bin/docker-entrypoint.sh"]

docker-entrypoint.sh

#!/bin/bash
echo "Port ${SSH_PORT}" >> /etc/ssh/sshd_config  # SSH_PORTのポートを利用
exec /usr/sbin/sshd -D

コンテナの起動

IMAGE_NAME, IMAGE_TAGは作成したimage に合わせて設定。 CONTAINER_NAMEはコンテナにつけたい名前を設定。

docker run -itd --rm --name $(CONTAINER_NAME) --network=host $(IMAGE_NAME):$(IMAGE_TAG)

SSH 鍵の共有

import subprocess
import yaml

with open("hosts.yaml", "r") as file:
    config = yaml.safe_load(file)
    hosts = [(entry["host"], entry["container"]) for entry in config["hosts"]]

for host, container in hosts:
    for other_host, _ in hosts:
        command = (
            f"docker exec -i {container} "
            f"sshpass -p 'password' ssh-copy-id "
            f"-p 2222 -o StrictHostKeyChecking=no root@{other_host}"
        )
        print(f"Running {command} on {host}")
        subprocess.run(["ssh", host, command])

hosts.yaml

$ cat hosts.yaml 
hosts:
  - host: serverA
    container: tmp_a
  - host: serverB
    container: tmp_b

実行

コンテナ間のSSH接続はDockerfileのSSH_PORTを用いて行われるため、これをMPIラウンチャーに教える必要がある。

  1. hostfile

hostfile を次のように作成。1行で1つのホスト情報。2222はSSH_PORTと同一の値。使用可能なプロセス数も指定する場合は slots=xxxx も記載する。

snail02 port=2222
snail03 port=2222

実行は

mpirun -n 2 --hostfile ./hostfile --allow-run-as-root BINARY
  1. コマンドライン

--mca plm_rsh_args "-p 2222" のオプションを追加する

mpirun -n 2 --mca plm_rsh_args "-p 2222" --allow-run-as-root BINARY

参考: OpenMPIを実装したDockerコンテナを複数ノードで実行する - akenji's lab
参考: Add support for specifying SSH port · Issue #2224 · open-mpi/ompi · GitHub