nvidia-smi
Tue Aug 9 11:13:42 2022
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 515.65.01 Driver Version: 515.65.01 CUDA Version: 11.7 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 NVIDIA GeForce ... Off | 00000000:01:00.0 On | N/A |
| N/A 47C P5 25W / N/A | 570MiB / 8192MiB | 22% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| 0 N/A N/A 1238 G /usr/lib/xorg/Xorg 286MiB |
| 0 N/A N/A 2020 G /usr/bin/kwin_x11 115MiB |
| 0 N/A N/A 2074 G /usr/bin/plasmashell 99MiB |
| 0 N/A N/A 6161 G ...159984077981301337,131072 63MiB |
+-----------------------------------------------------------------------------+
docker version
Client: Docker Engine - Community
Version: 20.10.17
API version: 1.41
Go version: go1.17.11
Git commit: 100c701
Built: Mon Jun 6 23:02:46 2022
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.17
API version: 1.41 (minimum version 1.12)
Go version: go1.17.11
Git commit: a89b842
Built: Mon Jun 6 23:00:51 2022
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.6
GitCommit: 10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1
runc:
Version: 1.1.2
GitCommit: v1.1.2-0-ga916309
docker-init:
Version: 0.19.0
GitCommit: de40ad0
同样是zsh及其相关插件,安装教程见ZSH、oh-my-zsh安装教程及插件和主题推荐
sudo snap changes #查看ID
sudo snap abort [ID] #将 [ID] 替换为实际安装qv2ray的ID,例如 sudo snap abort 49
https://github.com/v2 | fly/v2 | ray-core/releases |
---|
https://github.com/Qv2 | ray/QvPlugin-SS | R/releases/tag/v2.0.3 |
---|
第一次打开软件一,会提示有2.7.0版本,不升级,点击忽略。打开左上角首选项
在内核设置中点击“检查核心设置”,若已按照步骤2.解压并移动到指定位置,则会有以下提示
在入站设置中将监听地址改为“0.0.0.0”
连接设置如图所示
最后点右下角的“OK”完成设置
在软件首页点击插件,“打开本地插件目录”
把步骤3.中下载好的插件放到该目录,然后重启程序,再次打开插件,若显示如上图所示,则说明安装成功
点击程序首页下方的分组,再点击“组列表”下方垃圾桶图标左边的图标,添加一个分组,在“订阅设置”中勾选“此分组是一个订阅”,输入订阅地址,点击下方“更新订阅”中,然后点ok完成设置
回到程序首页,就可以在分组中选择服务器使用了
使用的如果是bash,则修改~/.bashrc,添加如下两行,zsh同理修改~/.zshrc
export http_proxy="http://127.0.0.1:8889"
export https_proxy="http://127.0.0.1:8889"
若是脚本,则在脚本开头加入这两行即可
若apt安装还是速度慢,见Ubuntu设置apt代理(使用Synaptic Package Manager 新立得软件包管理器、修改 /etc/apt/apt.conf.d/proxy.conf 文件、修改 .bashrc)
Chrome使用的是系统的代理设置,所以需要修改系统代理
该图为Ubuntu的设置
该图为Kubuntu的设置
见Ubuntu Snap商店代理设置方法的方法二
对于不同的使用情景,需要在不同地方设置,建议一次全设置上,若没有安装Docker Desktop for Linux,则不需要针对run命令使用方法三
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf
以下为示例内容
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:8889"
Environment="HTTPS_PROXY=http://127.0.0.1:8889"
Environment="NO_PROXY=localhost,127.0.0.1"
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl show --property=Environment docker
方法一
为docker pull设置代理
方法三
方法二
使用Electron的好处是不需要再去Ubuntu的设置里面手动修改地址和端口,选择任意一项,软件都会自动修改Ubuntu的配置,弊端是不像软件一可以修改监听地址,使用软件二无法设置docker build命令的代理,因为docker build的代理地址是本机的局域网ip地址,监听地址不改为0.0.0.0,无法通过局域网代理
参照软件一的配置教程即可,凡是代理地址为127.0.0.1的设置都能生效
若想局域网共享代理,则须使用软件一,将监听地址设置为0.0.0.0,然后其他设备中代理地址填写本机的ip和开放的端口即可(本教程中为8889端口)
适用于有Nvidia独显的主机并希望能在容器中使用独显
需要在主机中安装nvidia显卡驱动(建议安装最新版本,使用系统自带的驱动管理程序安装)并安装 NVIDIA Container Runtime,安装教程见Ubuntu下 NVIDIA Container Runtime 安装与使用
之前尝试过写Dockerfile,然后手动安装cuda和cudnn,很麻烦,因此直接使用nvidia的cuda镜像,在它的基础上定制自己的镜像
使用 docker run 运行容器的时候,需要加很多参数,相比之下docker-compose.yml简化了run后跟的参数,将运行时的参数全部写到yml文件里面,只需执行 docker compose up -d 就可以启动,达到和 docker run 一样的效果
docker-compose.yml原本是为一次管理多个容器而设计的(见Docker官方文档学习笔记(二):入门),在这里管理一个容器同样方便
# 这个version指的是compose文档的官方版本,不同版本号所含的功能不同
# 具体见 https://docs.docker.com/compose/compose-file/compose-versioning/
# 编写本教程时的最新版本为3.8
version: '3.8'
# 项目名称
name: my_dev
# 所有的容器的定义都要在services这个顶级元素下定义
services:
# 服务名称,可以与项目名称保持一致
my_dev:
# 设置为true,则容器内PID为1的进程就会是docker提供的一个init程序
# 这样可以使容器能够回收内部的僵尸进程,避免占用资源
init: true
# 容器名称,可以与服务名称保持一致
container_name: my_dev
# 网络模式设置为host,就可以与主机使用同一个网络,而不是使用docker虚拟网卡的桥接网络,方便设置代理和ssh连接
network_mode: "host"
# 设置为true,则容器内的root用户与主机的root用户具有相同的权限
privileged: true
# 使用nvidia官方镜像:cuda11.6.2,cudnn8,ubuntu18.04
# 更多镜像见 https://hub.docker.com/r/nvidia/cuda/tags?page=1&ordering=last_updated
image: nvidia/cuda:11.6.2-cudnn8-devel-ubuntu18.04
# 设置容器启动后自动执行的命令,不能为空
# 容器内PID为1的进程退出后,容器就会关闭,为了防止容器自动关闭,就需要让容器一直运行程序
# 这个命令可以防止容器启动后自动退出
command: tail -f /dev/null
# 设置要挂载的目录,可以理解为共享文件夹
volumes:
# 使容器和主机共用一套ssh密钥,但主机内该文件夹的config文件(如果存在的话)不能被容器内的root用户使用,
# 可能会报错(Bad owner or permissions on /root/.ssh/config)。
# 这个config文件是vscode保存ssh连接的,权限为600
# 解决办法是将主机的这个config文件改名,例如改为config.back
# 但推荐方法是重新设置vscode保存ssh连接的文件的路径,下文会介绍
# - "~/.ssh:/root/.ssh:rw" # 本来是为了省事,现在不推荐挂载,因为会导致一些报错,处理起来比较麻烦。
# 显示GUI所必须的
- "/tmp/.X11-unix:/tmp/.X11-unix:rw"
# 使容器可以读取到外接设备
# 比如主机上插了一个USB相机,挂载/dev后,容器内就也可以使用该相机了
- "/dev:/dev:rw"
# 将docker-compose.yml所在目录下的ENVIRONMENTS文件夹(如果不存在则会自动创建一个)共享到容器中
# 目的是方便在容器和主机间共享数据
- "./ENVIRONMENTS:/root/ENVIRONMENTS:rw"
# 将docker-compose.yml所在目录下的SHARE文件夹(如果不存在则会自动创建一个)共享到容器中
# 目的是方便在容器和主机间共享数据
- "./SHARE:/root/SHARE:rw"
# 与主机共用git配置
# - "~/.gitconfig:/root/.gitconfig:rw" # 这个也就不推荐挂载了
# 设置容器的默认工作目录
working_dir: /root
# 设置环境变量
environment:
# 显示GUI所必须的
- DISPLAY=$DISPLAY
- QT_X11_NO_MITSHM=1
# 将语言设置成简体中文
- LC_ALL=zh_CN.UTF-8
# 启用GPU驱动的所有功能
- NVIDIA_DRIVER_CAPABILITIES=all
# 启用GPU
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
关于GPU的更多配置,见Ubuntu下 NVIDIA Container Runtime 安装与使用
在主机的nvidia显卡设置中(即nvidia-settings),找到PRIME Profiles,选择NVIDIA(Performance Mode),然后重启电脑
使用docker compose命令创建容器
在docker-compose.yml所在文件夹执行
docker compose up -d
该命令执行一次即可,重复执行会导致之前使用该命令创建的容器被删除,然后创建新的容器,数据会丢失
容器关闭后,正确的启动方法是使用docker start命令,下文会介绍
在前面的docker-compose.yml中,使用container_name将容器名称定义为了my_dev,因此会在主机中创建一个名为my_dev的容器
使用docker exec命令进入容器
docker exec -it my_dev bash
在哪个终端执行这个命令,那么之后在这个终端输入的命令就会在容器中执行
为容器换中科大源
sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list && sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
apt update && apt upgrade -y
为主机和容器安装中文语言包
主机终端执行
sudo apt install language-pack-zh*
容器终端执行(因为容器默认用户为root,并且未安装sudo,所以命令里不需要加上sudo)
apt install language-pack-zh*
在步骤1.中打开的容器终端输入 exit ,退出容器终端
exit
在主机的终端中使用docker restart命令重启容器
docker restart my_dev
重复步骤1.,然后在这个终端中为容器配置自己需要的环境就可以了
若想打开更多容器内终端,同样重复步骤1.即可
开发的时候会用到ssh连接容器,所以需要给容器安装openssh-server
apt install openssh-server
然后修改容器内的/etc/ssh/sshd_config文件:
修改容器root用户的密码
passwd
配完容器的环境后,需要将容器保存为镜像,这样才能复用
使用docker stop命令关闭容器
docker stop my_dev
使用docker export命令将容器导出为tar包
docker export -o=my_dev.tar my_dev
-o=my_dev.tar指定了tar包的生成路径为当前文件夹且生成的包的名称为my_dev.tar,最后的参数my_dev是容器名称
使用docker import命令将tar包导入为镜像
docker import my_dev.tar my_dev:latest
这样就成功导入了镜像,可以通过docker image命令查看自己导入的镜像
docker image ls -a
# 另一种写法
# docker images -a
my_dev是镜像名称,latest是标签,可以理解为镜像的分支或版本,就像git中的master一样,镜像的默认标签为latest,标签可以自定义,比如my_dev:v1
将镜像推送到远程仓库
推送到Docker Hub:Docker官方文档学习笔记(二):入门、Docker官方文档学习笔记(三):总结与补充
推送到阿里云:使用阿里云管理Docker镜像
简单来说就是注册账户->创建远程仓库->使用docker login本地终端登陆账户->使用docker tag修改本地镜像名称->使用docker push推送到远程仓库
在步骤编写docker-compose.yml中,使用的镜像是nvidia的镜像,现在要更换为自己的镜像,所以将image修改为
image: my_dev:latest
需要ssh连接容器,所以在容器启动的时候就要启动ssh服务,将command修改为
command: bash -c "service ssh start && tail -f /dev/null"
然后重新创建容器
docker compose up -d
以后每次开机后,启动自己配好的容器时,都只需要使用docker start命令
docker start my_dev
要运行GUI程序,见Docker容器运行GUI程序的方法(直接进入Docker容器运行或通过SSH连接Docker容器运行)
使用vscode在容器内写代码
安装好Remote插件后,点击左侧的远程资源管理器图标
点击右上角的齿轮图标
点击“Settings”
自己新建好一个空文件用于保存SSH配置
touch ~/vscode_Remote_config
然后在这里指定好路径
点击右上角的“+”
输入命令,按回车,选择保存在刚才新建的配置文件中
ssh -p 2222 root@localhost -Y
保存成功后配置文件如图所示,远程资源管理器中也出现了添加的连接
右键选择连接
如图所示连接成功
点击左侧的扩展图标,进入扩展界面,会显示主机和容器安装的扩展,点击下载图标即可同步扩展到容器中
这样就设置完成了,可以在容器中写代码了
连接容器
ssh -p 2222 root@localhost -Y
docker exec -it my_dev bash
适用于无Nvidia独显的主机
# 使用的是ubuntu18.04镜像,是Docker Hub上的Ubuntu官方镜像
FROM ubuntu:18.04
# 每一个RUN命令都会在镜像中构建一个“层”
# 从DEBIAN_FRONTEND开始往下的都是安装命令,仅为示例,非必须
RUN /bin/bash -c "sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list \
&& sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list \
&& apt update && apt upgrade -y && \
DEBIAN_FRONTEND=noninteractive apt install tzdata git openssh-server vim zsh libgoogle-glog-dev libgflags-dev libatlas-base-dev \
libeigen3-dev libsuitesparse-dev \
build-essential libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev \
qt5-default qtcreator libssl-dev openssl sudo python-dev libgtest-dev net-tools inetutils-ping \
usbutils x11-apps language-pack-zh* iproute2 ninja-build -y"
写好后,使用docker build命令构建镜像
docker build -t=my_dev:latest .
-t=my_dev是将构建的镜像名称指定为my_dev,版本/标签为latest,后面的“.”是指Dockerfile的路径为当前目录下
执行该命令后,Docker会从Docker Hub下载ubuntu:18.04镜像,然后在这个镜像中执行RUN所给的命令,最后构建出一个名为my_dev的镜像
# 这个version指的是compose文档的官方版本,不同版本号所含的功能不同
# 具体见 https://docs.docker.com/compose/compose-file/compose-versioning/
# 编写本教程时的最新版本为3.8
version: '3.8'
# 项目名称
name: my_dev
# 所有的容器的定义都要在services这个顶级元素下定义
services:
# 服务名称,可以与项目名称保持一致
my_dev:
# 设置为true,则容器内PID为1的进程就会是docker提供的一个init程序
# 这样可以使容器能够回收内部的僵尸进程,避免占用资源
init: true
# 容器名称,可以与服务名称保持一致
container_name: my_dev
# 网络模式设置为host,就可以与主机使用同一个网络,而不是使用docker虚拟网卡的桥接网络,方便设置代理和ssh连接
network_mode: "host"
# 设置为true,则容器内的root用户与主机的root用户具有相同的权限
privileged: true
image: my_dev:latest
# 设置容器启动后自动执行的命令,不能为空
# 容器内PID为1的进程退出后,容器就会关闭,为了防止容器自动关闭,就需要让容器一直运行程序
# 这个命令可以防止容器启动后自动退出
command: tail -f /dev/null
# 设置要挂载的目录,可以理解为共享文件夹
volumes:
# 使容器和主机共用一套ssh密钥,但主机内该文件夹的config文件(如果存在的话)不能被容器内的root用户使用,
# 可能会报错(Bad owner or permissions on /root/.ssh/config)。
# 这个config文件是vscode保存ssh连接的,权限为600
# 解决办法是将主机的这个config文件改名,例如改为config.back
# 但推荐方法是重新设置vscode保存ssh连接的文件的路径,下文会介绍
# - "~/.ssh:/root/.ssh:rw" # 本来是为了省事,现在不推荐挂载,因为会导致一些报错,处理起来比较麻烦。
# 显示GUI所必须的
- "/tmp/.X11-unix:/tmp/.X11-unix:rw"
# 使容器可以读取到外接设备
# 比如主机上插了一个USB相机,挂载/dev后,容器内就也可以使用该相机了
- "/dev:/dev:rw"
# 将docker-compose.yml所在目录下的ENVIRONMENTS文件夹(如果不存在则会自动创建一个)共享到容器中
# 目的是方便在容器和主机间共享数据
- "./ENVIRONMENTS:/root/ENVIRONMENTS:rw"
# 将docker-compose.yml所在目录下的SHARE文件夹(如果不存在则会自动创建一个)共享到容器中
# 目的是方便在容器和主机间共享数据
- "./SHARE:/root/SHARE:rw"
# 与主机共用git配置
# - "~/.gitconfig:/root/.gitconfig:rw" # 这个也就不推荐挂载了
# 设置容器的默认工作目录
working_dir: /root
# 设置环境变量
environment:
# 显示GUI所必须的
- DISPLAY=$DISPLAY
- QT_X11_NO_MITSHM=1
# 将语言设置成简体中文
- LC_ALL=zh_CN.UTF-8
和上文中的docker-compose.yml大部分内容一样,只是少了GPU设置,使用的镜像不同而已
使用docker compose命令创建容器
在docker-compose.yml所在文件夹执行
docker compose up -d
该命令执行一次即可,重复执行会导致之前使用该命令创建的容器被删除,然后创建新的容器,数据会丢失
容器关闭后,正确的启动方法是使用docker start命令,下文会介绍
在前面的docker-compose.yml中,使用container_name将容器名称定义为了my_dev,因此会在主机中创建一个名为my_dev的容器
使用docker exec命令进入容器
docker exec -it my_dev bash
在哪个终端执行这个命令,那么之后在这个终端输入的命令就会在容器中执行
为容器换中科大源
sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list && sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
apt update && apt upgrade -y
为主机和容器安装中文语言包
主机终端执行
sudo apt install language-pack-zh*
容器终端执行(因为容器默认用户为root,并且未安装sudo,所以命令里不需要加上sudo)
apt install language-pack-zh*
在步骤1.中打开的容器终端输入 exit ,退出容器终端
exit
在主机的终端中使用docker restart命令重启容器
docker restart my_dev
重复步骤1.,然后在这个终端中为容器配置自己需要的环境就可以了
若想打开更多容器内终端,同样重复步骤1.即可
开发的时候会用到ssh连接容器,所以需要给容器安装openssh-server
apt install openssh-server
然后修改容器内的/etc/ssh/sshd_config文件:
修改容器root用户的密码
passwd
配完容器的环境后,需要将容器保存为镜像,这样才能复用
使用docker stop命令关闭容器
docker stop my_dev
使用docker export命令将容器导出为tar包
docker export -o=my_dev.tar my_dev
-o=my_dev.tar指定了tar包的生成路径为当前文件夹且生成的包的名称为my_dev.tar,最后的参数my_dev是容器名称
使用docker import命令将tar包导入为镜像
docker import my_dev.tar my_dev:latest
这样就成功导入了镜像,可以通过docker image命令查看自己导入的镜像
docker image ls -a
# 另一种写法
# docker images -a
my_dev是镜像名称,latest是标签,可以理解为镜像的分支或版本,就像git中的master一样,镜像的默认标签为latest,标签可以自定义,比如my_dev:v1
将镜像推送到远程仓库
推送到Docker Hub:Docker官方文档学习笔记(二):入门、Docker官方文档学习笔记(三):总结与补充
推送到阿里云:使用阿里云管理Docker镜像
简单来说就是注册账户->创建远程仓库->使用docker login本地终端登陆账户->使用docker tag修改本地镜像名称->使用docker push推送到远程仓库
在步骤编写docker-compose.yml中,使用的镜像是nvidia的镜像,现在要更换为自己的镜像,所以将image修改为
image: my_dev:latest
需要ssh连接容器,所以在容器启动的时候就要启动ssh服务,将command修改为
command: bash -c "service ssh start && tail -f /dev/null"
然后重新创建容器
docker compose up -d
以后每次开机后,启动自己配好的容器时,都只需要使用docker start命令
docker start my_dev
要运行GUI程序,见Docker容器运行GUI程序的方法(直接进入Docker容器运行或通过SSH连接Docker容器运行)
使用vscode在容器内写代码
安装好Remote插件后,点击左侧的远程资源管理器图标
点击右上角的齿轮图标
点击“Settings”
自己新建好一个空文件用于保存SSH配置
touch ~/vscode_Remote_config
然后在这里指定好路径
点击右上角的“+”
输入命令,按回车,选择保存在刚才新建的配置文件中
ssh -p 2222 root@localhost -Y
保存成功后配置文件如图所示,远程资源管理器中也出现了添加的连接
右键选择连接
如图所示连接成功
点击左侧的扩展图标,进入扩展界面,会显示主机和容器安装的扩展,点击下载图标即可同步扩展到容器中
这样就设置完成了,可以在容器中写代码了
连接容器
ssh -p 2222 root@localhost -Y
docker exec -it my_dev bash
可能是因为使用vscode连接容器时没有修改SSH配置文件的存储位置,使用了默认位置,然后容器启动后将该文件挂载到了容器中
首先在容器内尝试修改权限
chmod 600 ~/.ssh/config
如果还不行,则删除该文件,按照上文教程,在vscode中指定SSH配置文件的存储位置
这是权限问题导致的,容器内是root用户,主机使用非root权限用户当然无法访问,修改权限和所有者即可
命令前面加不加sudo取决于是使用容器中的root用户还是使用主机中的非root用户
sudo chmod -R [所有者][用户组][其他]
4:可读sudo chmod -R 777 SHARE
chown -R [所有者]:[用户组]
例如chown -R root:root
要运行GUI程序,见Docker容器运行GUI程序的方法(直接进入Docker容器运行或通过SSH连接Docker容器运行)
先删除崩了的容器
在docker-compose.yml所在目录执行
docker compose down
创建新容器
在docker-compose.yml所在目录执行
docker compose up -d
这个需要实现用户映射,见ROS官方文档中的login as yourself和The isolated way