自学内容网 自学内容网

Docker 安装和使用

#Docker 安装和使用

1. 安装

# Ubuntu
sudo apt install docker.io
# Manjaro
sudo pacman -S docker

Windows 下安装直接下载安装包进行安装即可。前提是 BIOS 中已经开启虚拟化(可以在“任务个管理器”的 CPU 信息中查看到“虚拟化”是否已启用),Windows 安装有:“Hyper-V”、“Windows 虚拟机监控程序平台”和“适用于 Linux 的 Windows 子系统”。

如果没有安装,可以到:控制面板->程序->启用或关闭 Windows 功能 中进行安装。Windows 家庭版系统在该页面下可能没有 Hyper-V 选项,此时需要手动安装,复制下面内容到 bat 文件中,然后右击以管理员身份运行:

pushd "%~dp0"
dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hyper-v.txt
for /f %%i in ('findstr /i . hyper-v.txt 2^>nul') do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages\%%i"
del hyper-v.txt
Dism /online /enable-feature /featurename:Microsoft-Hyper-V-All /LimitAccess /ALL

最后到管理员模式的 PowerShell 中执行:

bcdedit /set hypervisorlaunchtype auto

将 Hyper-V 设置为自动运行。再执行:

wsl --update

确保“适用于 Linux 的 Windows 子系统”为最新版本。

2. 干掉讨厌的 sudo

# 如果还没有 docker group 就添加一个
sudo groupadd docker
# 将自己的登录名(${USER} )加入该 group 内。然后退出并重新登录就生效啦
sudo gpasswd -a ${USER} docker
# 重启 docker 服务
sudo systemctl restart docker
# 切换当前会话到新 group 或者重启 X 会话
# 注意,这一步是必须的,否则因为 groups 命令获取到的是缓存的组信息,刚添加的组信息未能生效,所以 docker images 执行时同样有错。
newgrp docker
# 或者
pkill X

3. 使用镜像源

以 USTC 镜像源为例。

3.1. 使用 upstart 的系统

在配置文件 /etc/default/docker 中的 DOCKER_OPTS 中配置 Hub 地址:

DOCKER_OPTS="--registry-mirror=https://docker.mirrors.ustc.edu.cn/"

重新启动服务:

sudo service docker restart

3.2. 使用 systemd 的系统

在 /etc/docker 下创建 daemon.json 文件,修改其内容并重启启动 docker 相关服务:

cd /etc/docker
sudo touch daemon.json
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

4. 基本使用

Docker 的主要管理对象是镜像和容器,镜像是静态对象,保存了分层的用户数据;而容器是动态对象,可以看作镜像的运行状态,容器主要包容了 root fs。二者的关系如同程序文件与进程的关系。必须使用镜像来创建容器,一旦 Docker 加载并运行了某镜像,就为之创建一个与之对应的容器,容器至少有 stop 和 run 两个状态。使用 run 命令通过镜像创建容器后,该容器处于 run 状态,使用 exit 命令脱离容器后,容器处于 stop 状态。可以使用 start 命令将处于 stop 状态的容器再次运行起来。

如果每次都使用 run 命令从同一个镜像创建容器,会发现两个容器是完全一样的,因为他们都有相同的起始点。容器使用后,会保存当前的使用状态,但如果希望将其当前状态保存成镜像,可以使用 commit 命令。

注意:以下 image name 为 <repository>:<tag> 这种形式。

建议先配置使用镜像源。

以下是使用 Docker 的一些基础命令:

# 从 docker hub 上搜索镜像
docker search [option] <keyword>
# 从 https://hub.docker.com 拉取镜像
docker pull <name>[:tag]
# 运行某镜像并为之创建容器
docker run <image name/id>
# 运行某镜像,为之创建容器,将宿主机端口影射到容器端口,并将宿主机的某目录挂载到容器的对应目录下
docker run -it -p <host ip:port>:<container port> -v <host dir>:<container dir> <image name/id> /bin/bash
# 运行某镜像,为之创建容器,随机映射主机端口和容器端口,指定容器名称,赋予 privileged 权限,并将宿主机的某目录挂载到容器的对应目录下
docker run -it -P --name=<a container name> --privileged -v <host dir>:<container dir> <image name/id> /bin/bash
# 运行某镜像,为之创建容器,设置网络参数,并将宿主机的某目录挂载到容器的对应目录下
docker run -it --net=<bridge/host/container:container name or id/none> -v <host dir>:<container dir> <image name/id> /bin/bash
# 允许容器访问 usb 总线,允许容器通过 adb 连接 android 设备
docker run -it -P --name=<a container name> --privileged -v /dev/bus/usb:/dev/bus/usb <image name/id> /bin/bash
# 映射 Nvidia GPU
docker run -it -P --name=<a container name> --privileged --device /dev/nvidia0:/dev/nvidia0 <image name/id> /bin/bash
# 退出并关闭容器:在容器的 shell 中直接
exit
# 查看正在运行的容器
docker ps
# 提交针对某容器的修改,将其保存为镜像
docker commit <container name/id> <repository>:<tag>
# 运行某已存在的容器
docker start <container name/id>
# 连接到已运行的容器上
docker attach <container name/id>
# 运行并连接到已存在的容器上
docker start -a <container name/id>
# 在某已运行的容器中执行命令
docker exec -it <container name/id> <cmd and args>
# 迁移镜像
docker save -o <tar file> <image name/id>
docker load -i <tar file>
# 迁移容器
docker export -o <tar file> <container name/id>
docker import <tar file> <repository>:<tag>

想要退出但不关闭容器,在容器中按下 Ctrl + P + Q 组合健即可.

4.1. 容器操作

# 获得容器信息
docker container ls -a
# 获得容器id
docker container ls -a  -p
# 停止容器
docker container stop <container name/id>
# 删除容器
docker container rm  <container name/id>
# 重命名容器
docker container rename <current name> <new name>
# 更新容器的环境变量
docker container update --env <MY_VAR>=<value> <container name/id>
# 更新容器的端口映射
docker container update --publish <host port>:<container port> <container name/id>
# 更新容器的内存限制
docker container update --memory 512m <container name/id>
# 更新容器的 CPU 共享限制
docker container update --cpu-shares 512 <container name/id>

4.2. 镜像操作

# 获得镜像信息
docker image ls -a
# 获得镜像id
docker image ls -a  -p
# 重命名镜像
docker tag <image name/id> <repository>:<tag>
# 删除镜像
docker image rm  <image name/id>

5. 网络模式说明

5.1. bridge 模式

Docker 容器默认使用 bridge 模式的网络。其特点如下:

  • 使用一个 linux bridge,默认为 docker0
  • 使用 veth 对,一头在容器的网络 namespace 中,一头在 docker0 上
  • 该模式下 Docker Container 不具有一个公有 IP,因为宿主机的IP地址与 veth pair 的 IP 地址不在同一个网段内
  • Docker 采用 NAT 方式,将容器内部的服务监听的端口与宿主机的某一个端口 port 进行“绑定”,使得宿主机以外的世界可以主动将网络报文发送至容器内部
  • 外界访问容器内的服务时,需要访问宿主机的 IP 以及宿主机的端口 port
  • NAT 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率。
  • 容器拥有独立、隔离的网络栈;让容器和宿主机以外的世界通过 NAT 建立通信。

5.2. host 模式

Host 模式并没有为容器创建一个隔离的网络环境。而之所以称之为 host 模式,是因为该模式下的 Docker 容器会和 host 宿主机共享同一个网络 namespace,故 Docker Container 可以和宿主机一样,使用宿主机的 eth0,实现和外界的通信。换言之,Docker Container 的 IP 地址即为宿主机 eth0 的 IP 地址。其特点包括:

  • 这种模式下的容器没有隔离的 network namespace
  • 容器的 IP 地址同 Docker host 的 IP 地址
  • 需要注意容器中服务的端口号不能与 Docker host 上已经使用的端口号相冲突
  • host 模式能够和其它模式共存

5.3. container 模式

Container 网络模式是 Docker 中一种较为特别的网络的模式。处于这个模式下的 Docker 容器会共享其他容器的网络环境,因此,至少这两个容器之间不存在网络隔离,而这两个容器又与宿主机以及除此之外其他的容器存在网络隔离。

5.4. none 模式

网络模式为 none,即不为 Docker 容器构造任何网络环境。一旦 Docker 容器采用了none 网络模式,那么容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。Docker Container 的 none 网络模式意味着不给该容器创建任何网络环境,容器只能使用 127.0.0.1 的本机网络。

6. 查看 Docker run 启动参数

pip install runlike
runlike -p <container name/id>

7. 设置容器自启动

  1. 使用 docker run 命令运行时增加 --restart=always 参数即可;

  2. 使用 docker-compose 命令运行时在 yml 文件中,需要自启动的 service 下增加 restart: always 项目即可;

  3. 已运行的容器修改其自启动策略,执行命令:

    docker container update --restart=<no|on-failure|always> <container name/id>
    

8. SSH X11Forwarding

8.1. Windows 下实现

在启动容器时需要使用 -p 参数将 ssh 端口映射到主机。

参照 Linux SSH 服务的安装和使用 中的方式配置并启动(使用非 systemd 方式) ssh 服务,并确保 /etc/ssh/sshd_config 中的以下变量为:

PermitRootLogin yes
X11Forwarding yes
X11DisplayOffset 10
X11UseLocalhost no

启动 MobaXterm 创建 SSH 连接到 127.0.0.1:<主机映射的容器 SSH 端口>,注意需要使能 X11-Forwarding 功能。之后通过 SSH 连接容器,注意 MobaXterm 打印的连接信息:

               • MobaXterm Professional Edition v22.0 • 
                (SSH client, X server and network tools)

➤ SSH session to root@127.0.0.1
  • Direct SSH      :  ✔ 
  • SSH compression :  ✔ 
  • SSH-browser     :  ✔
  • X11-forwarding  :(remote display is forwarded through SSH)
➤ For more info, ctrl+click on help or visit our website. 

注意 X11-forwarding 一项后面是否为“✔”,如果为“x”说明容器没有正确开启 X11-forwarding。

本次配置 X11Forwarding 时总是出现“cannot open display”错误,原因是旧的 sshd_config 配置文件中一些变量不被支持,SSH 服务忽略这些变量时出现问题,导致 SSH X11-forwarding 功能没有正确开启,注释掉这些不支持的变量后工作正常。

9. 解决 Windows 下容器占用空间过大问题

9.1. 压缩 .vhdx 文件

Windows 下 Docker 依赖 WSL,而 WSL 依赖 HDX(Virtual Hard Disk v2) 提供虚拟硬盘,单文件的最高容量是 64TB。。总之,Windows 下需要使用 .vhdx 文件来存储 Docker 容器的镜像和数据。

这个文件默认存储在:C:\Users<UserName>\AppData\Local\Docker\wsl 下。具体可在 Docker Desktop 的 Setting->Resources 中获取或设置路径。

当在容器中进行操作,或者 commit 容器时,都会增加 .vhdx 文件的尺寸。但是当从容器中删除内容,或 commit 失败等情况出现 .vhdx 文件不会主动减小。这就导致当容器使用久了以后,会占用大量额外空间,此时需要手动释放。此时打开命令提示行,按下列指令顺序进行操作:

# 查看 docker 占用的空间
docker system df

# 清理空间,注意会删除未启动或未在使用中的容器、镜像等。如果希望容器及镜像保持,则将其 start。
docker container prune
docker image prune
docker volume prune
docker builder prune
# 一键清理
docker system prune

# 停止 wsl 服务
wsl --shutdown

# 进入磁盘管理
diskpart

# 选择虚拟磁盘文件
select vdisk file="C:\Users\<UserName>\AppData\Local\Docker\wsl\ext4.vhdx"

# 将虚拟磁盘以只读模式挂载到虚拟机
attach vdisk readonly

# 压缩文件
compact vdisk

# 压缩完成后卸载磁盘
detach vdisk

# 退出磁盘管理
exit

9.2. 迁移 .vhdx 文件

迁移 .vhdx 文件的核心思想是将相关文件剪切走后在原来位置再创建一个连接,指向新地址。

注意,迁移 .vhdx 文件前需要先关闭运行中的相关容器。

将 Docker Desktop 的 Setting->Resources->Disk image Location 中的配置路径是一个文件夹,因此要将整个文件夹剪切到其他磁盘分区,然后再为该文件夹创建连接,命令为:

cmd /c mklink /j C:\Users\<UserName>\AppData\Local\Docker\wsl F:\wsl

10. 常用镜像

# Ubuntu
docker pull ubuntu:16.04
docker pull ubuntu:18.04
docker pull ubuntu:20.04
# Nvidia CUDA
docker pull nvidia/cuda:10.2-cudnn7-runtime-ubuntu16.04
# Tensorflow 1
docker pull tensorflow/tensorflow:1.11.0-py3
docker pull jupyter/tensorflow-notebook:17aba6048f44

Wechat 镜像和启动方法:

docker pull bestwu/wechat
xhost +
docker run -d --name wechat --device /dev/snd --ipc=host \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v $HOME/WeChatFiles:/WeChatFiles \
-e DISPLAY=unix$DISPLAY \
-e XMODIFIERS=@im=fcitx \
-e QT_IM_MODULE=fcitx \
-e GTK_IM_MODULE=fcitx \
-e AUDIO_GID=`getent group audio | cut -d: -f3` \
-e GID=`id -g` \
-e UID=`id -u` \
bestwu/wechat

原文地址:https://blog.csdn.net/desert187/article/details/144269591

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!