Docker简介
Docker 是一个开源的容器化平台,旨在简化应用程序的开发、交付和运行。它允许开发者将应用程序及其所有依赖项打包到一个轻量级的、可移植的容器中,从而确保在不同环境中(如开发、测试和生产)都能一致地运行。
Docker 的主要概念
1. 容器(Container):
容器是Docker的核心概念。它是一个轻量级、可移植的运行环境,包含了应用程序及其所有依赖项(如库、配置文件等)。容器共享宿主机的操作系统内核,但彼此之间是隔离的。
2. 镜像(Image):
镜像是容器的蓝图,包含了运行容器所需的所有文件和设置。镜像是静态的,而容器是镜像的运行实例。镜像可以通过Dockerfile定义,并可以从Docker Hub等公共或私有仓库中获取。
3. Dockerfile:
Dockerfile 是一个文本文件,包含了一系列指令,用于构建Docker镜像。通过Dockerfile,您可以定义应用程序的环境、依赖项、配置等。
4. Docker Hub:
Docker Hub 是一个公共的Docker镜像仓库,用户可以在这里分享和获取Docker镜像。用户可以上传自己的镜像,也可以从中下载其他人共享的镜像。
5. Docker引擎(Docker Engine):
Docker引擎是一个客户端-服务器应用程序,负责构建、运行和管理容器。它由一个守护进程(Docker Daemon)和一个命令行界面(CLI)组成。
Docker 的优势
1. 一致性:
Docker容器确保在不同环境中(开发、测试、生产)运行的一致性,减少了“在我的机器上可以运行”的问题。
2. 轻量级:
容器共享宿主机的操作系统内核,因此比虚拟机更轻量,启动速度更快。
3. 可移植性:
Docker容器可以在任何支持Docker的环境中运行,无论是本地开发环境、云平台还是物理服务器。
4. 隔离性:
每个容器都是独立的,应用程序之间相互隔离,避免了依赖冲突。
5. 易于扩展:
Docker使得应用程序的扩展变得简单,可以快速启动多个容器来处理负载。
Docker最重要的概念是容器和镜像。可以把容器比作一台电脑,镜像为系统镜像。一个系统镜像可以装在不同电脑上,同时电脑上的系统也可以打包成镜像。不同电脑之间互不影响
Docker的使用
Docker的安装
运行以下命令进行安装
sudo apt install docker.io
然后启用docker的服务
systemctl daemon-reload
systemctl start docker
systemctl enable docker
镜像操作
在 Docker 中,如果你想将一个容器的文件系统保存为一个镜像并下载到本地,可以按照以下步骤进行:
1. 提取容器的文件系统为镜像
首先,你需要将正在运行的容器保存为一个新的镜像。假设你的容器名称为 my_container,你可以使用以下命令:
docker commit my_container my_image_name
这里my_container是容器的名称,my_image_name 是你想要创建的新镜像的名称
2. 导出镜像为 tar 文件
接下来,你可以将这个镜像导出为一个 tar 文件,以便下载或传输。使用以下命令:
docker save -o my_image.tar my_image_name
这将把 my_image_name 镜像保存为 my_image.tar 文件。
3. 导入镜像
如果你想在其他机器上使用这个镜像,可以使用以下命令将 tar 文件导入到 Docker 中:
docker load -i my_image.tar
4. 通过命令行下载镜像
通过命令行可以直接从网上下载镜像
docker pull <镜像名>:<标签>
官方 Docker 镜像库
Docker Hub: https://hub.docker.com
国内 Docker 镜像加速器
1. 网易云
地址: https://hub-mirror.c.163.com
2. 腾讯云
地址: https://mirror.ccs.tencentyun.com
3. DaoCloud
地址: https://www.daocloud.io/mirror
4. 清华大学
地址: https://mirrors.tuna.tsinghua.edu.cn/dockerhub/
5. 中国科技大学
地址: https://docker.mirrors.ustc.edu.cn
6.阿里镜像源
地址:https://registry.cn-hangzhou.aliyuncs.com/
5. 镜像删除
docker rmi image_name
image_name:镜像名称
Linux 系统添加镜像操作
- 打开终端,编辑 Docker 配置文件:使用你喜欢的文本编辑器打开 /etc/docker/daemon.json 文件。如果文件不存在,可以创建一个新的。
sudo gedit /etc/docker/daemon.json
- 添加镜像加速器:
在文件中添加以下内容(以阿里镜像源,腾讯镜像源为例):
{
"registry-mirrors": ["https://registry.cn-hangzhou.aliyuncs.com/",
"https://mirror.ccs.tencentyun.com"]
}
如果文件已经存在且包含其他配置,请确保将 “registry-mirrors” 添加到现有 JSON 对象中,并确保 JSON 格式正确。
- 保存并退出,重启 Docker 服务:
使用以下命令重启 Docker 服务以使更改生效:
sudo systemctl restart docker
- 验证配置:
运行以下命令以查看 Docker 配置,确保加速器已正确配置:
docker info
容器操作
1. 从镜像创建容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
常见命令:
docker run -it image_name:tag container_name /bin/bash
image_name:镜像名称
tag:镜像标签
container_name:容器名称
2. 打开现有容器
如果已经创建了容器且该容器正在运行,想操作该容器,可使用docker exec命令
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
常见命令:
docker exec -it container_name /bin/bash
container_name:容器名称
3. 停止容器
将一个容器挂起,暂停容器运行
docker stop container_name
container_name:容器名称
4. 重启容器
重启运行一个已经挂起的容器
docker start container_name
container_name:容器名称
5. 删除容器
docker rm container_name
container_name:容器名称
docker进阶应用
docker常见选项解析
1. --volume
(或 -v
)
- 含义:
--volume
选项用于挂载宿主机的目录或文件到 Docker 容器中。这使得容器能够访问宿主机上的数据,或者将容器内的数据保存到宿主机上。 - 语法:
docker run --volume <host_path>:<container_path> your_image
或者使用简写:
docker run -v <host_path>:<container_path> your_image
例子:
docker run -v /path/on/host:/path/in/container your_image
在这个例子中,宿主机上的 /path/on/host 目录会被挂载到容器内的 /path/in/container 目录。
用途:
数据持久化:将容器中的数据保存到宿主机上,以便在容器重启或删除后仍然可以访问。
数据共享:多个容器可以共享同一个宿主机目录中的数据。
配置文件:可以将宿主机上的配置文件挂载到容器中,以便容器使用。
2. --mount
--mount
是 Docker 中用于挂载存储的选项,提供了一种更灵活和可读性更强的方式来挂载宿主机的目录或文件到 Docker 容器中。与 --volume
(或 -v
)相比,--mount
提供了更详细的配置选项。
docker run --mount type=<type>,source=<source>,target=<target> your_image
参数说明:
-
type:挂载的类型,可以是以下几种:
bind
:将宿主机的目录或文件挂载到容器中。volume
:使用 Docker 管理的卷(volume),用于数据持久化。tmpfs
:创建一个临时文件系统,存储在内存中。
-
source:挂载的源,可以是宿主机的路径(对于
bind
类型)或 Docker 卷的名称(对于volume
类型)。 -
target:容器内的目标路径,即挂载点。
示例:
使用 bind
类型将宿主机的 /path/on/host
目录挂载到容器内的 /path/in/container
目录:
docker run --mount type=bind,source=/path/on/host,target=/path/in/container your_image
使用 volume
类型将Docker 卷将数据挂载到容器内:
docker run --mount type=volume,source=my_volume,target=/path/in/container your_image
在这个例子中,my_volume
是一个 Docker 卷的名称。
使用 tmpfs
类型创建一个临时文件系统并挂载到容器内:
docker run --mount type=tmpfs,target=/path/in/container your_image
--mount
与 --volume
的比较:
- 可读性:
--mount
提供了更清晰的语法,尤其是在需要指定多个参数时。 - 灵活性:
--mount
支持更多的挂载选项,例如tmpfs
,而--volume
主要用于卷的挂载。 - 使用场景:对于简单的卷挂载,
--volume
可能更简洁;而对于复杂的挂载需求,--mount
更 加灵活。
3.--env
(或 -e
)
含义:--env
选项用于设置环境变量,这些变量可以在容器内的应用程序中使用。环境变量通常用于配置应用程序的行为。
语法:
docker run --env VAR_NAME=value your_image
或者使用简写:
docker run -e VAR_NAME=value your_image
示例:
docker run -e MY_ENV_VAR=my_value your_image
在这个例子中,环境变量 MY_ENV_VAR 被设置为 my_value,并可以在容器内的应用程序中访问。
用途:
配置:通过环境变量传递配置信息,例如数据库连接字符串、API 密钥等。
灵活性:允许在运行时动态配置应用程序,而不需要修改代码或重建镜像。
4. i,t,d
docker -itd
是 Docker 命令中的一组选项,通常用于启动一个新的容器。下面是对每个选项的详细解释:这是 Docker 命令行工具的基本命令,用于与 Docker 引擎交互。
-i
(或 --interactive
):
- 作用:使容器保持标准输入(STDIN)打开,即使没有附加终端。
- 用途:这通常用于需要用户输入的交互式应用程序,或者当你希望能够在容器中执行命令时。
-t
(或 --tty
)
- 作用:为容器分配一个伪终端(pseudo-TTY)。
- 用途:这使得容器能够以交互方式运行,提供一个终端界面,通常与
-i
一起使用,以便用户可以与容器进行交互。
-d
(或 --detach
)
- 作用:在后台运行容器,并返回容器的 ID。
- 用途:这使得容器在后台运行,而不是在前台阻塞终端。用户可以继续使用终端而不被容器的输出所干扰。
示例:
一个常见的使用示例是:
docker run -it image_name container_name
image_name:镜像名称
container_name:容器名称
这个命令会启动一个image_name镜像的容器,并打开一个伪终端通过标准输入与之交互。
5.--privileged
- 功能:使用
--privileged
选项启动容器时,容器将获得几乎所有的宿主机权限。这意味着容器可以访问宿主机的所有设备,并且可以执行许多通常被限制的操作,例如加载内核模块、访问/dev
中的所有设备等。 - 用途:适用于需要完全访问宿主机资源的场景,例如运行需要特权的应用程序或服务(如某些网络工具、虚拟化工具等)。
- 安全性:使用
--privileged
会显著降低容器的安全性,因为它几乎可以访问宿主机的所有资源。因此,只有在绝对必要时才应使用此选项。
6.--user
在 Docker 中,--user
选项用于指定容器内运行的进程的用户和组。通过这个选项,你可以控制容器内的进程以特定的用户身份运行,而不是默认的 root 用户。这在安全性和权限管理方面非常重要。
使用方法:
--user
选项的基本语法如下:
docker run --user <user>:<group> <image>
<user>
:可以是用户名或用户的 UID(用户 ID)。<group>
:可以是组名或组的 GID(组 ID)。如果不指定组,Docker 将使用用户的默认组。
示例:
使用用户名:
docker run --user myuser my_image
这将以 myuser
用户的身份运行容器。
使用 UID 和 GID:
docker run --user 1001:1001 my_image
这将以 UID 为 1001 和 GID 为 1001 的身份运行容器。
为什么使用 --user
:
- 安全性:以非 root 用户身份运行容器可以减少潜在的安全风险。如果容器被攻破,攻击者将无法获得 root 权限,从而限制了他们的能力。
- 权限管理:某些应用程序可能需要特定的用户权限才能正常运行。通过指定用户,可以确保应用程序在适当的权限下运行。
- 文件权限:当容器与宿主机共享卷时,以特定用户身份运行容器可以避免文件权限问题。例如,如果容器以 root 用户身份运行,可能会导致宿主机上的文件权限不正确。
注意事项:
- 确保指定的用户在容器内存在。如果用户不存在,容器将无法启动。
- 如果你使用的是基于某些镜像(如 Alpine 或 Ubuntu)的自定义 Dockerfile,确保在 Dockerfile 中创建了所需的用户。
docker如何使用宿主机的图形化界面
1. 安装 X11 服务器
确保宿主机上安装并运行了 X11 服务器。大多数 Linux 发行版默认都包含 X11。
2. 允许 X11 访问
在宿主机上,您需要允许 Docker 容器访问 X11 显示。可以使用 xhost 命令来实现:
xhost +local:docker
3. 处理 X11 认证
为了确保安全,您可能需要处理 X11 认证。可以使用 xauth 工具来管理 X11 认证信息。以下是一个示例步骤:
# 创建一个 X11 认证文件
XAUTH=/tmp/.docker.xauth
touch $XAUTH
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
4. 运行容器
xhost +local:docker
XAUTH=/tmp/.docker.xauth
touch $XAUTH
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
docker run -it \
--name=orbslam3 \
--env DISPLAY=$DISPLAY \
--volume /tmp/.X11-unix:/tmp/.X11-unix:rw \
--env XAUTHORITY=$XAUTH \
--volume $XAUTH:/tmp/.docker.xauth:ro \
your_docker_image
--name
=orbslam3 : 创建的容器的名称为orbslam3。-env
“DISPLAY=$DISPLAY”:将主机的 DISPLAY 环境变量传递给容器,以便容器可以访问图形界面。-volume
/tmp/.X11-unix:/tmp/.X11-unix:rw :将主机的 X11 Unix 套接字目录挂载到容器中,以便进行图形通信。-env
“XAUTHORITY=$XAUTH”:将 X11 认证文件的路径传递给容器。通过将 XAUTHORITY 环境变量设置为 $XAUTH 的值,容器内的应用程序可以使用这个认证文件来进行 X11 图形界面的访问。这在需要在 Docker 容器中运行图形应用程序时非常有用。--volume
$XAUTH:/tmp/.docker.xauth:ro :通过将主机的 X11 认证文件挂载到容器中,容器内的应用程序可以访问主机的 X11 服务器,从而实现图形界面的显示。
如何在容器中使用宿主的网络
docker run -it --name=container_name --net=host <image_name>
--net
=host:使用宿主机的网络栈。容器将直接使用宿主机的网络接口,而不是 Docker 的网络隔离机制。
效果:
- 容器中的应用程序可以直接访问宿主机的网络资源,例如 IP 地址和端口。
- 容器内的服务可以绑定到宿主机的端口,允许外部流量直接访问。
- 容器与宿主机之间的网络延迟会降低,因为没有网络隔离层。
容器如何与宿主进行ICP通讯
docker run -it --name=container_name --ipc=host <image_name>
--ipc
=host:使用宿主机的进程间通信(IPC)命名空间。这意味着容器可以访问宿主机的 IPC 资源,例如共享内存和信号量。
效果:
- 容器可以与宿主机上的进程共享内存,允许更高效的数据交换。
- 这对于需要高性能 IPC 的应用程序(如某些数据库或计算密集型应用)非常有用。
- 这在某些需要高效进程间通信的应用场景(如某些数据库或计算密集型应用)中非常有用,但也可能带来安全风险,因为它打破了容器之间的隔离。
如何在容器中使用调试软件(gdb
)
--cap-add=SYS_PTRACE
是 Docker 中的一个选项,用于向容器添加特定的 Linux 能力(capability)。在这种情况下,它允许容器内的进程使用 ptrace
系统调用。下面是对这个选项的详细解释及其作用:
什么是 ptrace
?
ptrace
是一个 Linux 系统调用,允许一个进程(通常是调试器)观察和控制另一个进程的执行。它通常用于调试、跟踪和分析程序的行为。使用 ptrace
,调试器可以:
- 读取和修改被调试进程的内存和寄存器。
- 捕获进程的系统调用。
- 监视进程的执行状态。
- 在进程中设置断点。
--cap-add=SYS_PTRACE
的作用:
- 通过添加
SYS_PTRACE
权限,容器内的进程可以使用ptrace
来调试其他进程。这对于开发和测试非常重要,尤其是在需要分析和调试应用程序时。 - 默认情况下,Docker 容器是以最小权限运行的,许多能力(包括
SYS_PTRACE
)是被禁用的。这是为了提高安全性,防止容器内的进程对宿主机或其他容器进行不当操作。 - 通过显式添加
SYS_PTRACE
,用户可以在需要时为容器提供调试能力,但这也可能带来安全风险,因为它允许容器内的进程对其他进程进行监视和控制。 - 在开发和测试环境中,开发者可能需要在容器中运行调试工具(如
gdb
),以便调试应用程序。此时,添加SYS_PTRACE
权限是必要的。
使用示例:
在运行 Docker 容器时,可以使用以下命令添加 SYS_PTRACE
权限:
docker run -it --name=container_name --cap-add=SYS_PTRACE <image_name>
注意事项:
- 安全风险:允许容器使用
ptrace
可能会导致安全隐患,因为它可以使容器内的进程能够监视和控制其他进程。因此,只有在确实需要的情况下才应添加此权限,并且应谨慎使用。 - 限制:在某些情况下,容器可能仍然无法使用
ptrace
,例如,当容器运行在某些受限的环境中(如某些云平台或安全配置的宿主机上)。
容器如何访问宿主的硬件设备(如USB端口)
要在 Docker 容器中访问 /dev/tty
设备,你可以使用以下几种方法:
- 使用
--device
选项
你可以使用 --device
选项将宿主机的 /dev/tty
设备映射到容器中。例如:
docker run --device=/dev/tty:/dev/tty my_image
这将使容器能够访问宿主机的 /dev/tty
设备。
- 使用
--privileged
选项
如果你需要更广泛的权限,可以使用 --privileged
选项,这将允许容器访问所有设备,包括 /dev/tty
:
docker run --privileged my_image
- 使用
--cap-add
选项
如果你只需要特定的能力,可以使用 --cap-add
选项来添加必要的能力。例如,添加 SYS_ADMIN
能力:
docker run --cap-add=SYS_ADMIN --device=/dev/tty:/dev/tty my_image
注意事项:
- 访问
/dev/tty
设备可能涉及到安全性问题,因此在使用--privileged
或--cap-add
选项时要谨慎。 - 确保容器内的应用程序具有适当的权限来访问
/dev/tty
设备。 - 在某些情况下,可能需要在容器内安装特定的工具或库,以便能够正确使用
/dev/tty
设备。
通过以上方法,你可以在 Docker 容器中访问和使用 /dev/tty
设备。