文章目录
问题出现
- 使用
docker run
从镜像ubuntu:20.04
启动了一个容器
shell
docker run -p 8000:22 --name server -itd ubuntu:20.04
- 云服务的安全组已经放行的端口
8000
- 在宿主机使用
ssh
连接刚刚启动的容器server
shell
ssh root@xxx.xxx.xxx.xxx -p 8000
- 显示结果
shell
ssh: connect to host xxx.xxx.xxx.xxx port 8000: Connection refused
问题排查与解决
- 第一步检查云服务器是否真的放行了端口
8000
,经过核实的确放行了端口8000
- 第二检查容器是否开启了
ssh
服务,发现docker容器没有开启ssh
服务,经过查阅资料发现原始的ubuntu镜像并没有安装ssh
服务,需要手动安装
shell
docker exec -it server ps aux | grep ssh
- 进入docker容器,安装
openssh-server
shell
docker exec -it server /bin/bash
apt-get update & apt-get install -y openssh-server
- 配置
ssh
服务
shell
# 首先安装vim
apt-get install vim
# 配置ssh服务
vim /etc/ssh/sshd_config
# 开启以下服务
PermitRootLogin yes
PasswordAuthentication yes
- 重启
ssh
服务
shell
service ssh restart
重新登陆
- 首先安装
sudo
shell
apt-get install -y sudo
- 添加新用户,并将其加入到
sudo
组,使其拥有sudo
权限
shell
adduser username
usermod -aG sudo username
- 再次使用
ssh
登录
shell
ssh username@xxx.xxx.xxx.xxx -p 8000
显示登录成功,但是要输入密码,为了避免每次输入密码可以进行以下的配置
- 配置docker容器的信息
shell
vim .ssh/config
# 添加以下的信息
Host <容器别名>
HostName <宿主机IP地址>
User <登录的用户名>
Port <容器暴露的端口>
- 将宿主机上的ssh公钥
id_rsa.pub
拷贝到docker容器中的.ssh/authorized_keys
shell
# 在宿主机上生成密钥
ssh-keygen
# 可以通过命令将公钥传输到docker容器
ssh-copy-id <容器别名>
# 直接通过`ssh <容器别名>`即可登录到容器,无需输入密码
ssh server
+可以将我们刚刚配置好的容器提升为镜像,下次直接从镜像创建容器即可
shell
docker commit <容器名> <镜像名>:<tag>
# docker commit server myserver:1.0

- 在
root/.bashrc
文件中配置service ssh start
,可以登录容器时自动启动ssh
服务
深度剖析
- 之所以出现
port 8000: Connection refused
的本质原因,是因为容器内部没有服务正在监听22
端口。 - 建立连接需要先进行TCP三次握手,握手之前服务端必须处于
Listen
状态,并且监听相应的端口,具体的过程可见TCP三次握手 - 服务端没有监听相应的端口,请求连接的报文传输到服务端时,就会回应
rst
报文终止本次连接,详见服务端没有 listen,客户端发起连接建立,会发生什么?