我使用 alpine 映像创建了两个名为服务器和客户端的 docker 容器,并且我正在运行这两个容器。 然后我在两个容器中都安装了apk add openssh
和apk add openrc
。 使用rc-service sshd start
我已经启动了 ssh 服务。 现在,我想使用scp
复制文件。
从服务器容器中,我键入:
scp myfile.txt client@172.17.0.3:/location_of_the_folder
它要求客户端容器的密码。 我能做什么? 码头工人容器的默认密码是什么?
我尝试了以下 3 个选项:
- 将同一卷附加到两个容器。
- 使用从服务器容器到主机,然后主机到的
docker cp
客户端容器。 - 在服务器容器中使用
ssh-keygen
并复制id_rsa.pub
手动密钥到客户端容器/root/.ssh
目录,它可以工作。
我不想使用选项 1 和 2。 我应该如何使用 shell 脚本对选项 3 做什么?我想自动化这件事。 我可以手动完成,但是我们可以通过使用shell脚本自动完成,将一些文本从一个容器复制到另一个容器吗?
如果是本地 docker 容器,请使用docker cp,如下所述:
docker cp {container_name}:{file_path} {target_file_path OR target_dir_ended_with_slash}
但是,如果您确实需要ssh
(例如,当容器在远程主机中运行时(,请尝试以下步骤:
1.确保使用来自主机的 ssh 端口 22 重定向运行容器,例如docker run -p 8022:22 ...
然后在容器内:
2.
安装固态混合硬盘:sudo apt update && sudo apt install -y openssh-server
3.创建 sshd 目录:mkdir /var/run/sshd
4.
为当前用户添加密码("root"用户默认没有密码(:passwd
5.设置PermitRootLogin yes
sshd_config:sudo sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
6.您可能还需要:sudo sed 's@sessions*requireds*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
7.和:sudo sh -c 'echo "export VISIBLE=now" >> /etc/profile'
8.
重新启动 sshd服务:sudo service ssh restart
然后,您应该能够与SSH连接,并使用SCP传输文件。
如果收到">端口 22:连接被拒绝",请尝试以下任一解决方法:
- 使用特权访问权限运行容器:
docker exec --privileged -ti container_name bash
- 在容器内,打开带有 UFW 防火墙的端口 22:
sudo apt-get install -y ufw && sudo ufw allow 22
通常,Docker Linux 发行版基础映像会为所有用户禁用所有密码。 此外,您描述的设置有很多凭据需要管理(在每个图像中,本地用户的密码、远程用户的密码、您自己的 ssh 主机密钥、远程 ssh 主机密钥(,安全地执行此操作很棘手。 (例如,如果您在Dockerfile
中设置了密码,那么拥有该图像的任何人都可以从docker history
中读取它,或者尝试从图像的/etc/shadow
文件中破解散列密码。
我建议避免在 Docker 中使用 ssh。 它避免了上面显示的凭据问题,还避免了在容器中运行多个进程的固有困难。
这里最简单的方法是向可以生成文件内容的"服务器"添加一个端点,并让"客户端"在启动时或需要时请求它。
您还可以将相同命名的 Docker 卷或主机目录挂载到两个容器中,并且两者都对相同的文件具有读写访问权限,因此您可以通过这种方式传输文件。 这通常不是一个问题,但存在潜在的竞争条件(就像您在没有 Docker 的情况下在同一系统上运行两者一样(。 这种方法也不能很好地扩展到像Docker Swarm或Kubernetes这样的多主机安装。