创建可直接用 root 用户 ssh 登陆的 Docker 镜像
有时候我们在 Mac OS X 或 Windows 平台下需要开发以 Linux 为运行时的应用,IDE 或可直接使用 Docker 容器,或 SSH 远程连接。本地命令行下操作虽然可以用
注:
构建镜像
启动容器
SSH 登陆
第一次登陆会提示 Are you sure you want to continue connecting (yes/no/[fingerprint])?
回答 yes 后,再输入前面构建镜像时的密码(your_password)就登陆成功了。
就是下面的过程
fingerprint 记录在了本地的 ~/.ssh/known_hosts 文件中。如修改了镜像(重新构建了镜像),还是在相同的映射端口上启动容器后,比如重新构建了 demo-ssh 镜像,停掉了原来的容器,再次用
我们需要在 ~/.ssh/known_hosts 中把 [localhost]:2022 行删除掉才能重新回答
相同的镜像多次启动,或是用不同的映射端口启动容器都用不着从 ~/.ssh/known_hosts 中删除相应的条目。
首先在本地用
然后在构建 Docker 镜像是把本地的
相应的 Dockerfile 是
由于无需用户/密码登陆,所以关于启于 root 用户登陆相关的内容也用不着了。
构建命令
同样的方式启动容器,但 SSH 连接容器时不用输入密码了
另外还能配置默认的用户和端口号,在 ~/.ssh/config 文件中
这样的话,输入
而且配置了 ssh key 的话,ssh localhost 就直接登陆了。
只有第一次必须回答 yes 接受 fingerprint, 以后只需像上面那样输入
用 scp 命令在本地和 SSH 主机上搬运文件和 ssh 的验证方式是一样的,比如拷贝一个文件进到容器可以用命令
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
docker exec 连接正在运行的容器,但 IDE 远程连接的话 SSH 总是一种较为通用的连接方式,所以我们希望做一个能进行 SSH 连接的 Docker 容器。因为是本地运行的 Docker,我们想直接用 root 连接,以获得在容器中最大的运行权限。下面以 ubuntu:2004 基础镜像为例,看如何安装启用 ssh 服务以及允许 root 连接。创建允许 root + 密码登陆的镜像
我们创建一个基本的 Dockerfile 文件,内容为1FROM ubuntu:20.04
2
3RUN apt-get update && apt-get install -y openssh-server && \
4 mkdir /var/run/sshd && \
5 echo 'root:your_password' | chpasswd && \
6 sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
7
8CMD ["/usr/sbin/sshd", "-D"]注:
- mkdir /var/run/sshd: 在启动 /usr/sbin/sshd 需用到,否则无法启动
- sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config: 允许 root 用户登陆,安装 openssh-server 后,PermitRootLogin 行默认被注释掉了
- 如果登陆验证有问题,在构建镜像时加上
sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd试试
构建镜像
$ docker build -t demo-ssh .创建了一个 tag 为 demo-ssh:latest 的镜像
启动容器
$ docker run -d -p 2022:22 demo-ssh映射主机上的端口号 2022 容器的 22
895e8c689c44b806da82d87980a292f55fd316bbfcce2ac3a174d7710511f272
SSH 登陆
$ ssh root@localhost -p 2022由于使用了非默认的 22 端口号,所以需加上
-p 2022 指定连接端口号。第一次登陆会提示 Are you sure you want to continue connecting (yes/no/[fingerprint])?
回答 yes 后,再输入前面构建镜像时的密码(your_password)就登陆成功了。
就是下面的过程
1The authenticity of host '[localhost]:2022 ([::1]:2022)' can't be established.
2ED25519 key fingerprint is SHA256:PPAA8h/AKQS9n0myXjWn32i2Sr6d9bX+fZ9IynavXNg.
3This key is not known by any other names.
4Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
5Warning: Permanently added '[localhost]:2022' (ED25519) to the list of known hosts.
6root@localhost's password:
7Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 6.6.26-linuxkit x86_64)
8
9 * Documentation: https://help.ubuntu.com
10 * Management: https://landscape.canonical.com
11 * Support: https://ubuntu.com/pro
12
13This system has been minimized by removing packages and content that are
14not required on a system that users do not log into.
15
16To restore this content, you can run the 'unminimize' command.
17
18The programs included with the Ubuntu system are free software;
19the exact distribution terms for each program are described in the
20individual files in /usr/share/doc/*/copyright.
21
22Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
23applicable law.
24
25root@895e8c689c44:~#fingerprint 记录在了本地的 ~/.ssh/known_hosts 文件中。如修改了镜像(重新构建了镜像),还是在相同的映射端口上启动容器后,比如重新构建了 demo-ssh 镜像,停掉了原来的容器,再次用
$ docker run -d p 2022:22 demo-ssh在相同的 2022 端口上映射容器内的 22 端口号
$ ssh root@localhost -p 2022将会看到如下的信息
1ssh root@localhost -p 2022
2@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
3@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
4@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
5IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
6Someone could be eavesdropping on you right now (man-in-the-middle attack)!
7It is also possible that a host key has just been changed.
8The fingerprint for the ED25519 key sent by the remote host is
9SHA256:hKgsTk2QbpGoA3SS3qPGfbWKLZe3F5yTaYTBI4zBCck.
10Please contact your system administrator.
11Add correct host key in /Users/yanbin/.ssh/known_hosts to get rid of this message.
12Offending ECDSA key in /Users/yanbin/.ssh/known_hosts:38
13Host key for [localhost]:2022 has changed and you have requested strict checking.
14Host key verification failed.我们需要在 ~/.ssh/known_hosts 中把 [localhost]:2022 行删除掉才能重新回答
yes 来用密码登陆。相同的镜像多次启动,或是用不同的映射端口启动容器都用不着从 ~/.ssh/known_hosts 中删除相应的条目。
创建免密登陆的镜像
如果镜像不欲分享,那么参考 如何无需密码进行 SSH 连接[翻译],我们可以创建一个不用输入密码就能 SSH 登陆的 Docker 镜像。首先在本地用
ssh-keygen -t rsa 在目录 ~/.ssh 下生成 id_rsa 和 id_rds.pub 密钥文件,记住在询问 Enter passphrase 是直接回车过掉。然后在构建 Docker 镜像是把本地的
~/.ssh/id_rsa.pub 的内容放到镜像的 /root/.ssh/authorized_keys 文件中。相应的 Dockerfile 是
1FROM ubuntu:20.04
2
3ARG ssh_pub_key
4
5RUN apt-get update && apt-get install -y openssh-server && \
6 mkdir /var/run/sshd && \
7 mkdir /root/.ssh && \
8 echo "$ssh_pub_key" > /root/.ssh/authorized_keys
9
10CMD ["/usr/sbin/sshd", "-D"]由于无需用户/密码登陆,所以关于启于 root 用户登陆相关的内容也用不着了。
构建命令
$ docker build -t demo-ssh --build-arg ssh_pub_key="$(cat ~/.ssh/id_rsa.pub)" .这样本地的 ~/.ssh/id_rsa.pub 文件内容就会跑到镜像的 /root/.ssh/authorized_keys 中去
同样的方式启动容器,但 SSH 连接容器时不用输入密码了
$ ssh root@localhost -p 2022~/.ssh/known_hosts 的处理方式会是一样的,现在不需要输入密码就能登陆了。
另外还能配置默认的用户和端口号,在 ~/.ssh/config 文件中
1Host localhost
2 User root
3 Port 2022这样的话,输入
$ ssh localhost就相当于下面的全命令
$ ssh root@localhost -p 2022
而且配置了 ssh key 的话,ssh localhost 就直接登陆了。
1$ ssh localhost
2Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 6.6.26-linuxkit x86_64)
3
4 * Documentation: https://help.ubuntu.com
5 * Management: https://landscape.canonical.com
6 * Support: https://ubuntu.com/pro
7
8This system has been minimized by removing packages and content that are
9not required on a system that users do not log into.
10
11To restore this content, you can run the 'unminimize' command.
12Last login: Wed Jun 5 20:32:05 2024 from 192.168.65.1
13root@0474baf1a1ff:~#只有第一次必须回答 yes 接受 fingerprint, 以后只需像上面那样输入
ssh localhost 就非常顺滑进入到容器的终端。用 scp 命令在本地和 SSH 主机上搬运文件和 ssh 的验证方式是一样的,比如拷贝一个文件进到容器可以用命令
$ scp test.txt localhost:/因为是 Docker 容器,大可不必用 scp, 用 docker cp 就行,不依赖于 ssh, 只要写上可定位唯一容器的 ID 前缀
$ docker cp test.txt 89:/永久链接 https://yanbin.blog/create-root-ssh-docker-image/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。