基于docker的MPI安装
一、制作MPI镜像
1.下载centos7镜像并安装mpi
拉去centos7的镜像,并查看其镜像ID
docker pull centos:7
docker images
# 取前几位imageID即可
docker run -it eeb6 /bin/bash
进入容器后,首先下载必要的库
yum -y update
yum -y install openssh-clients
yum -y install openssh-server
yum -y install nano
yum -y install net-tools
yum -y install gcc
yum -y install gcc-c++
yum -y install gcc-gfortran
yum -y install sudo
yum -y install passwd
yum -y install make
yum -y install nfs-utils
这里先回到window,下载mpich-3.3.1.tar.gz,并保存至docker的宿主机 下载地址
在docker宿主机另窗口执行,将mpich压缩文件传递给容器
docker cp ./下载/mpich-3.3.1.tar.gz ${container id}:/mpi
到容器内部有压缩包的文件夹,对其进行解压
tar -xzvf mpich-3.3.1.tar.gz
解压完后进入文件夹中,进行安装
./configure
make
make install
在configure过程中,如果出现报错说没安装什么包,重新安装后再次./configure
即可
安装完成后配置环境变量
vi ~/.bashrc
进入此文件后,添加下属三个环境变量
export MPI_ROOT=/home/mpi/mpich-3.3.1
export PATH=$MPI_ROOT/bin:$PATH
export MANPATH=$MPI_ROOT/man:$MANPATH
添加完退出后,再输入source ~/.bashrc
使其生效
最后可以利用mpi自带的example进行测试
mpirun -n 6 /home/mpi/mpich-3.3.1/examples/cpi
成功的运行结果如下
2.配置ssh
1.依次执行
mkdir -p /var/run/sshd
ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N ''
ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N ''
ssh-keygen -t dsa -f /etc/ssh/ssh_host_ed25519_key -N ''
#一直Enter即可
2.修改 /etc/ssh/sshd_config 配置信息:
UsePAM yes 改为 UsePAM no
UsePrivilegeSeparation sandbox 改为 UsePrivilegeSeparation no
sed -i "s/UsePAM.*/UsePAM no/g" /etc/ssh/sshd_config
sed -i "s/#UsePrivilegeSeparation.*/UsePrivilegeSeparation no/g" /etc/ssh/sshd_config
#启动ssh
/usr/sbin/sshd -D &
#检测是否启动成功
netstat -apn | grep ssh
#修改密码
passwd
改成123456,方便记忆
3.提交容器变为镜像
docker commit -m "description" -a "author information" [containterid] name:tag
二、创建节点
1. 制作一个docker网段
docker network create --subnet=192.168.10.0/16 network_mpi
docker network ls
2. 创建三个容器
创建容器,容器都与主机的目录挂载,为他们设定名字,设定ip
#node4节点
docker run -it --name node4 -h node4 --net network_my --ip 192.168.10.20 --add-host node5:192.168.10.21 --add-host node6:192.168.10.22 -v /home/mpi/work:/home/mpi/work 3c2e /bin/bash
exit
#node5节点
docker run -it --name node5 -h node5 --net network_my --ip 192.168.10.21 --add-host node4:192.168.10.20 --add-host node6:192.168.10.22 -v /home/mpi/work:/home/mpi/work 3c2e /bin/bash
exit
#node6节点
docker run -it --name node6 -h node6 --net network_my --ip 192.168.10.22 --add-host node4:192.168.10.20 --add-host node5:192.168.10.21 -v /home/mpi/work:/home/mpi/work 3c2e /bin/bash
exit
现在已经可以在宿主机的对应目录/home/mpi/work
添加文件并自动挂载进三台节点机了
3. 配置ssh无密码登陆
1.重新启动一下ssh
#启动ssh
/usr/sbin/sshd -D &
#检测是否启动成功
netstat -apn | grep ssh
- 在每个节点依次进行ssh登录
#node4
ssh node4
cd ~/.ssh
#显示出known_hosts后,继续执行
ssh-keygen -t rsa
#一直Enter,再次ls,会出现三个文件
ls
#node5
ssh node5
cd ~/.ssh
#显示出known_hosts后,继续执行
ssh-keygen -t rsa
#一直Enter,再次ls,会出现三个文件
ls
#node6
ssh node6
cd ~/.ssh
#显示出known_hosts后,继续执行
ssh-keygen -t rsa
#一直Enter,再次ls,会出现三个文件
ls
- 先将所有节点的公钥发到一个节点中
#把node5的公钥发给node4
#node5
scp ~/.ssh/id_rsa.pub root@node4:~/.ssh/5.pub
#把node6的公钥发给node4
#node6
scp ~/.ssh/id_rsa.pub root@node4:~/.ssh/6.pub
- 在这个节点将所有公钥写进一个文件
#node4
#自己
cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
#写node5
cat ~/.ssh/5.pub >> ~/.ssh/authorized_keys
#写node6
cat ~/.ssh/6.pub >> ~/.ssh/authorized_keys
5.再将这个文件发给其他节点
#node4
#发给node5
scp ~/.ssh/authorized_keys root@node5:~/.ssh/
#发给node6
scp ~/.ssh/authorized_keys root@node6:~/.ssh/
此时三台节点已实现相互免密码登录了,可以通过ssh node【】
登录进行尝试
三、编写文件
由于三台机器已经把/home/mpi/work
挂载到宿主机的对应目录下,我只需要把hello.c文件传到宿主机的对应目录即可
hello.c
#include <stdio.h>
#include "mpi.h"
int main(int argc, char *argv[])
{
int myrank, size;
char processor_name[MPI_MAX_PROCESSOR_NAME];
int namelen;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Get_processor_name(processor_name, &namelen);
printf("Processor %d of %d on %s: Hello World!\n", myrank, size, processor_name);
MPI_Finalize();
return 0;
}
还可以编写一个控制由哪个节点来运行的文件machinefile
node4
node5
node6
当其放在对应目录下后,三个节点已有此文件,在其中一个节点对hello.c进行编译
mpicc -o hello hello.c
此时三个节点均已有编译好的hello文件
在其中一个节点按照编写好的machinefile运行程序,如下所示
#-f表示使用哪个控制文件 -n表示进程数量
mpiexec -f machinefile -n 6 ./hello
结果如下: