更新–20200409

  • 退出docker后ssh connection refused.
  • 退出docker后,ssh会被关掉,先通过服务器docker exec进入container,然后输入以下指令启动ssh服务
/etc/init.d/ssh start


  • RSAAuthentication在CentoOS 7.4 中已经废除,通过密码登录的选项改为了PasswordAuthentication yes,如果是7.4以后的版本,这里需要修改一下.在CentOS7.4中其强行添加 RSAAuthentication 配置会触发系统对它的废除提示。
reprocess config line 38: Deprecated option RSAAuthentication

将sshd_config改为如下:

# PermitRootLogin prohibit-password # 默认打开 禁止root用户使用密码登陆,需要将其注释
# RSAAuthentication yes #启用 RSA 认证
PubkeyAuthentication yes #启用公钥私钥配对认证方式
PermitRootLogin yes #允许root用户使用ssh登录
PasswordAuthentication yes

  • 已解决:环境变量问题,用nvidia-smi的绝对路径可以执行,因此添加环境变量后可以解决:
# 查找nvidia-smi的绝对路径:
find -name nvidia-smi
# 返回:./usr/local/nvidia/bin/nvidia-smi
# 将nvidia-smi所在目录添加入环境变量
export PATH=/usr/local/nvidia/bin:$PATH

完美解决,感谢双朋。

写在前面

之前项目组每个人都独立地在各自docker内进行开发,这次做AutoML涉及到了很多个团队的成员,结果发现有些小伙伴在自己的docker下开发模块,merge以后因为别人的环境不一致结果频繁报错,也是项目管理没经验。这次整理一个简易版的VS code和Docker联调的方式,以后项目开发先搭建公共环境,引以为戒。

准备工具

安装了docker服务的远程服务器,有vscode的本地笔记本。开始。

创建docker

服务器上创建docker,这里我用的是被封装过的nvidia-docker:

$ nvidia-docker run -p 8022:22 -v /automl:/workspace/automl -it mydetnas:v1 /bin/bash

简单说下,-p 8022:22把docker的端口22映射到服务器的8022端口,这样之后通过 ssh root@<server ip> -p 8022就能访问到docker了
-v 挂载和同步目录,这样服务器和docker内就有一个文件夹会试中保持同步了。
-it 让docker后台交互运行
mydetnas:v1镜像名
最后是docker内要运行的指令。

添加ssh服务

这里各个博客写的五花八门,我就把自己配置的方式记录一下,亲测可用,以供后之来者。
进入docker

-$ nvidia-docker exec -it [容器ID] /bin/bash
# 用docker exec -it [容器ID] /bin/bash 也可以

在docker中输入以下内容,安装ssh服务

$ apt update
$ apt install -y openssh-server

然后输入passwd,修改root账户密码。
输入vim /etc/ssh/sshd_config,打开ssh配置文件,修改以下内容,以允许root账户通过密码登录:

# PermitRootLogin prohibit-password # 默认打开 禁止root用户使用密码登陆,需要将其注释
# RSAAuthentication yes #启用 RSA 认证
PubkeyAuthentication yes #启用公钥私钥配对认证方式
PermitRootLogin yes #允许root用户使用ssh登录
PasswordAuthentication yes

这里更新一下:RSAAuthentication在CentoOS 7.4 中已经废除,通过密码登录的选项改为了PasswordAuthentication yes,如果是7.4以后的版本,这里需要修改一下.在CentOS7.4中其强行添加 RSAAuthentication 配置会触发系统对它的废除提示。1

reprocess config line 38: Deprecated option RSAAuthentication

最后我们重启以下ssh,退出docker然后测试一下

root@container-$ /etc/init.d/ssh restart
root@container-$ exit
# 输入一下指令,验证端口映射无误
user@server-$ sudo docker port [容器ID] 22
# 如果设置正确,将输出:
#0.0.0.0:8022

在自己的笔记本上,打开cmd,输入ssh尝试连接

-> ssh username@server_IP -p 8022
# 回车后输入密码,就可以从本地登录远程服务器的docker了

配置VS Code

打开VS code,在扩展栏(或者按ctr+shift+X)查找安装Remote Development

docker 编码 进入mysql docker dmidecode_python


安装完成后需要reload一下,然后按ctr+shift+p,打开查找栏,输入remote-ssh,选择open Configuration file

docker 编码 进入mysql docker dmidecode_服务器_02


docker 编码 进入mysql docker dmidecode_服务器_03


Host随便起名字,这里我用AutoML_docker命名。在HostName的地方输入服务器的ip,注意端口Port是我们之前docker映射到服务器上的端口号。

配置成功后左边会多出一个远程浏览的标签,点开就可以看到刚才配置的远程连接了。点击之后要输入密码,即我们创建docker后修改的root密码。

docker 编码 进入mysql docker dmidecode_docker_04

配置vscode debugger

菜单查看-扩展或者Ctrl + Shift + X,在商店中搜索“Python”,找到“适Python extension for Visual Studio Code”安装在服务器docker中,然后重启VSCode。

之后,菜单查看-命令面板或者Ctrl + Shift + P,输入“python: select interpreter”,点击选择解析器,稍等几秒钟,就会列出在系统中找到的Python环境(Python环境要加入环境变量才能被找到),点击需要的python解析器即可。

打开debug选项卡,选择Add configuration

docker 编码 进入mysql docker dmidecode_服务器_05


编辑launch.json文件如下:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
    
    
        {
            "type": "python",
            "request": "launch",
            "name": "Python: Current File (Integrated Terminal)",
            "skipFiles": [
                "<node_internals>/**"
            ],
            "program": "${file}"
        }
    ]
}

launch.json常用的调试配置有:2

  • “Python: Current File (Integrated Terminal)”:该配置表示在VSCode内置的命令行中直接执行当前激活的Python文件。如果需要制定要执行的文件,可以修改"program": "${file}"中的${file}宏为需要的文件。
  • “Python: Current File (External Terminal)”:该配置功能和上面的相同,区别是不使用VSCode内置命令行,而新打开一个命令行。
  • “Python: Attach”:该配置是附件到另外一个进程的调试方式。

结束

Ok,至此配置VScode就结束了,可以选择刚才配置的解释器来逐行调试docker内的代码了。因为docker的代码是通过-v与服务器同步的,所以修改后也会直接改动服务器上存的代码,大家git的时候就只需要在服务器端设置,而不用在docker内再考虑这个问题了。