我对 docker 有点陌生,并尝试用它模拟集群环境。我定义了一个容器共享的自定义 docker 网络,并将每个容器分配给不同的端口来模拟不同的网卡。
目前,我有一个工作的
Dockerfile
可以复制所需的 ssh 密钥,并且我会自动让它使用 ENTRYPOINT service ssh start && bash
启动 ssh 服务器。
现在,我的容器可以工作,但不便的是,当容器启动时,我必须手动运行
eval
ssh-agent && ssh-add /.ssh/docker_id_rsa,
,然后手动 ssh 到所有其他容器,然后我才能运行我的 MPI 程序。如果我不先执行这些步骤,我将无法跨容器运行程序。
所以我想做的是,当我附加到其中一个容器时,我想要(1)立即在所有容器上运行我的 MPI 程序,而不必运行我上面提到的所有步骤,或者(2 )甚至立即 ssh 到其他容器,然后运行我的程序。
这是我当前的示例
Dockerfile
:
FROM img_base AS img
COPY /keys/ /root/.ssh
COPY /keys/docker_id_rsa.pub /root/.ssh/authorized_keys
RUN sed -i 's/#PermitRootLogin no/PermitRootLogin yes/g' /etc/ssh/sshd_config
RUN sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
RUN sed -i "s+StrictHostKeyChecking .*+StrictHostKeyChecking allow-new+" /etc/ssh/sshd_config
RUN echo "localhost" >> hostfile
RUN echo "root@container2" >> hostfile
RUN echo "root@container3" >> hostfile
RUN echo "root@container4" >> hostfile
EXPOSE 22
ENTRYPOINT service ssh start && bash && eval `ssh-agent` && ssh-add /root/.ssh/docker_id_rsa
我使用以下 bash 脚本启动容器:
#!/bin/bash
docker run --rm -dit --name container1 --network=my-net --ip=172.18.0.2 -p 4022:22 --add-host container2:172.18.0.3 --add-host container3:172.18.0.4 --add-host container4:172.18.0.5 img
docker run --rm -dit --name container2 --network=my-net --ip=172.18.0.3 -p 3022:22 --add-host container1:172.18.0.2 --add-host container3:172.18.0.4 --add-host container4:172.18.0.5 img
docker run --rm -dit --name container3 --network=my-net --ip=172.18.0.4 -p 5022:22 --add-host container2:172.18.0.3 --add-host container1:172.18.0.2 --add-host container4:172.18.0.5 img
docker run --rm -dit --name container4 --network=my-net --ip=172.18.0.5 -p 6022:22 --add-host container2:172.18.0.3 --add-host container3:172.18.0.4 --add-host container1:172.18.0.2 img
docker attach container1
我尝试在
eval
命令中添加 ssh-add
和 ENTRYPOINT
命令。
我还尝试将这些命令添加到 bash 脚本中的
docker run
命令中。
我尝试使用 docker-compose 文件来执行此操作,但仍然不太了解如何使用 docker-compose 功能
非常感谢任何有关正确方法的建议或参考。
我不确定你的
img_base
是什么样子,但我只是假设它是一个 Ubuntu 映像(或衍生版本)。
您正在以
root
用户身份设置对容器的 SSH 访问。这并不理想,但 100% 可以正常运行。也许稍后更改为非特权用户?
🗎
Dockerfile
FROM ubuntu:22.04 AS img
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get install -y openssh-server && \
mkdir /var/run/sshd
RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
COPY keys/docker_id_rsa.pub /root/.ssh/authorized_keys
RUN chmod 700 /root/.ssh && chmod 600 /root/.ssh/authorized_keys
CMD ["/usr/sbin/sshd", "-D"]
测试图像。连接主机上的2022端口,以避免与主机上运行的SSHD冲突。
SSH 连接已确认。 ✅
现在让我们使用 Docker Compose 来实现这一点。
🗎
Dockerfile
FROM ubuntu:22.04 AS img
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get install -y openssh-server && \
mkdir /var/run/sshd
# SSH server configuration.
RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
# SSH client configuration.
RUN echo " StrictHostKeyChecking no" >> /etc/ssh/ssh_config
RUN echo " UserKnownHostsFile /dev/null" >> /etc/ssh/ssh_config
COPY keys /root/.ssh/
COPY keys/docker_id_rsa.pub /root/.ssh/authorized_keys
RUN chmod 700 /root/.ssh && chmod 600 /root/.ssh/authorized_keys
COPY setup.sh .
RUN chmod +x /setup.sh
CMD ["/usr/sbin/sshd", "-D"]
🗎
docker-compose.yml
version: '3.7'
x-common-service: &common-service-template
build:
context: .
dockerfile: Dockerfile
networks:
- my-net
services:
container1:
<<: *common-service-template
container_name: container1
ports:
- "4022:22"
command: /bin/bash -c "/setup.sh"
container2:
<<: *common-service-template
container_name: container2
ports:
- "3022:22"
container3:
<<: *common-service-template
container_name: container3
ports:
- "5022:22"
container4:
<<: *common-service-template
container_name: container4
ports:
- "6022:22"
networks:
my-net:
container1
服务略有不同,因为它运行 setup.sh
脚本。该脚本(见下文)将通过 SSH 在其他三个容器上运行代码。因此您可以使用它来设置所有容器。目前,它只是在每个容器上打印一条消息。
🗎
setup.sh
#!/bin/bash
echo "* Setting up cluster."
ssh -i ~/.ssh/docker_id_rsa root@container2 'echo "- Running code on container2! $(hostname)"'
ssh -i ~/.ssh/docker_id_rsa root@container3 'echo "- Running code on container3! $(hostname)"'
ssh -i ~/.ssh/docker_id_rsa root@container4 'echo "- Running code on container4! $(hostname)"'
echo "* Done!"
/usr/sbin/sshd -D
启动。
docker-compose build && docker-compose up
因此
container1
有效地充当主容器并在其他容器上进行设置。