一、Docker镜像
1.1 核心定义
Docker 镜像 是一个只读的模板,它包含了运行一个应用程序所需的所有内容:代码、运行时环境、系统工具、系统库和设置。
1.2 关键特性与原理
1.2.1 分层存储(Layer)
这是 Docker 镜像最核心、最精妙的设计。
-
只读层:镜像由一系列只读层叠加而成。每一层代表 Dockerfile 中的一条指令(例如:
COPY、RUN、ADD)。例如:-
第一层:基础操作系统(如
Ubuntu) -
第二层:安装
Python -
第三层:复制项目代码
app.py -
第四层:设置环境变量
-
-
联合文件系统:当您启动一个容器时,Docker 会在所有只读层之上,添加一个可写的容器层。所有对运行中容器的修改(如写入日志、创建临时文件)都只发生在这个可写层。底层的镜像内容始终保持不变。
-
好处:
-
高效存储:多个镜像可以共享相同的基础层。例如,如果你有10个基于
Ubuntu的镜像,你的硬盘上只存储一份Ubuntu基础层。 -
快速分发:传输镜像时,只需要传输本地没有的层,大大加快了下载速度。
-
可复用性:可以基于一个镜像轻松创建出新的、功能更丰富的镜像。
-
1.2.2 内容寻址存储
每个镜像和每一层都有一个基于其内容计算出的唯一加密哈希值(ID)。这保证了镜像内容的完整性和一致性。
1.3 镜像的生命周期与操作
1.3.1 获取镜像
-
从 Registry 拉取:最常用的是从 Docker 官方的公共仓库 Docker Hub 拉取。命令:
docker search nginx 搜索镜像docker pull nginx:latest 拉取镜像 -
从文件载入:可以将别人导出的镜像文件加载到本地。命令:
docker load -i my_image.tar
1.3.2 查看与管理本地镜像
-
docker images:列出本地所有镜像。 -
docker rmi <image_id>:删除本地不需要的镜像。 -
docker image prune:清理未被使用的镜像(悬空镜像)。
1.3.3 创建镜像(构建)
-
主要方式:使用 Dockerfile。Dockerfile 是一个文本文件,里面包含了一条条构建镜像所需的指令。执行
docker build -t my-app:1.0 .命令,Docker 引擎会读取当前目录下的 Dockerfile 并逐步执行指令,最终生成一个新的镜像,镜像名为my-app,镜像标签为1.0。 -
从容器提交(不推荐用于生产):对一个运行中的容器进行修改后,可以将其提交为一个新镜像。命令:
docker commit <container_id> my-new-image。这种方式不利于追溯和自动化,通常只用于临时调试。
1.3.4 分发与共享镜像
-
推送至 Registry:可以将本地构建的镜像推送到 Docker Hub 或私有的镜像仓库(如 Harbor、GitLab Registry)。命令:
docker push my-username/my-app:1.0 -
导出为文件:可以将镜像保存为一个 tar 归档文件,方便离线分享。命令:
docker save -o my_image.tar my-app:1.0
1.3.5 删除镜像
docker rmi repository:tag
二、Docker容器
2.1 核心定义
Docker容器 是 Docker镜像的一个运行实例。你可以把它理解为一个轻量级、隔离的进程沙箱,这个沙箱里运行着由镜像定义好的应用程序及其所有依赖。
2.2 关键特性与原理
2.2.1 从镜像到容器
当你执行 docker run nginx:latest 时,Docker引擎会:
-
检查本地是否存在
nginx:latest镜像,若没有则从仓库拉取。 -
在镜像的只读层之上,创建一个薄薄的可写层(容器层)。
-
分配一个唯一的容器ID,设置网络、存储等命名空间。
-
执行镜像中定义的启动命令(如
CMD [“nginx”, “-g”, “daemon off;”]),启动容器进程。
2.2.2 核心特性
- 轻量级:
容器直接共享宿主机的操作系统内核,无需像虚拟机(VM)一样模拟完整的操作系统,因此启动极快(秒级甚至毫秒级)、资源开销极小(只占用进程本身的内存和CPU)。
- 隔离性:
通过 Linux 内核的 Namespaces 技术实现隔离。每个容器拥有独立的:
进程空间(PID):容器内的进程ID从1开始,看不到宿主机或其他容器的进程。
网络空间(Net):容器可以有自己独立的虚拟网卡、IP地址、端口空间。
文件系统挂载点(Mnt):容器看到的是自己的根目录
/。用户和用户组(User):可以在容器内建立独立的用户体系。
通过 cgroups 技术实现资源限制与核算,可以限制容器使用的CPU、内存、磁盘I/O等资源。
- 可移植性(一致性环境):
容器内包含了应用运行所需的所有库和依赖,确保了 “一次构建,到处运行”。在开发机、测试环境、生产环境,只要使用同一个镜像启动容器,运行行为就是一致的。
- 临时性(无状态/易失):
默认情况下,容器内的文件系统是临时的。容器的生命周期与其内部运行的进程一致,进程结束,容器就停止。对容器可写层的所有修改(如写入的数据、产生的日志),在容器删除后也会消失。这是理解容器存储的关键。
2.3 容器的生命周期与核心操作
容器的生命周期通常围绕以下几个核心命令和状态:
创建(Create) -> 运行(Running) -> 暂停(Paused)/停止(Stopped) -> 删除(Removed)
2.3.1 启动容器:
docker run [OPTIONS] IMAGE [COMMAND]:最核心的命令。它会创建并启动一个新容器。常用选项:
-d:后台运行(守护态)。
-it:交互式运行,分配一个伪终端,通常与/bin/bash结合使用进入容器内部。
--name:为容器指定一个名字。
-p:端口映射(主机端口:容器端口)。
-v:挂载数据卷(主机目录:容器目录)。docker start container-name:启动一个现有容器
docker exec [options] container-name /bin/bash:进入容器的bash shell
exit:退出
2.3.2 管理运行中的容器:
-
docker ps:查看正在运行的容器列表。加-a查看所有容器(包括已停止的)。 -
docker stop <容器名/ID>:优雅地停止运行中的容器(发送 SIGTERM 信号)。 -
docker start <容器名/ID>:启动一个已停止的容器。 -
docker restart <容器名/ID>:重启容器。 -
docker pause/unpause <容器名/ID>:暂停/恢复容器内所有进程。 -
docker exec -it <容器名/ID> /bin/bash:进入一个正在运行的容器内部执行命令,这是调试和排查问题的关键命令。
2.3.3 查看容器信息与日志:
-
docker logs <容器名/ID>:查看容器的标准输出日志(即应用打印到控制台的信息)。加-f可以实时跟踪。 -
docker inspect <容器名/ID>:获取容器的底层详细信息(配置、状态、网络、数据卷等),以JSON格式返回。 -
docker stats:实时查看容器的资源使用情况(CPU、内存、网络IO等)。
2.3.4 删除容器:
-
docker rm <容器名/ID>:删除一个已停止的容器。加-f可以强制删除一个运行中的容器(不推荐)。
2.4 容器数据持久化
由于容器的临时性,重要数据必须持久化存储,主要有两种方式:
2.4.1 数据卷(Volumes):
由Docker管理、存在于宿主机文件系统(通常在
/var/lib/docker/volumes/下)的存储区域。生命周期独立于容器,即使容器被删除,数据卷依然保留。
用法:
docker run -v my_volume:/app/data nginx
2.4.2 绑定挂载(Bind Mounts):
将宿主机上的一个指定目录或文件直接挂载到容器中。
常用于开发环境,实现主机代码与容器代码的实时同步。
用法:
docker run -v /home/user/project:/app nginx
2.4.3 临时文件系统(tmpfs mount):
将数据存储在宿主机的内存中,速度极快,但容器停止即消失。用于存储非持久化的敏感数据或临时文件。
2.5 容器网络
Docker为容器提供了多种网络模式,实现容器间、容器与外部世界的通信:
bridge(桥接):默认模式。容器连接到名为
docker0的虚拟网桥,通过NAT与外部通信。同一桥接网络内的容器可以通过容器名互访。
host:容器直接使用宿主机的网络命名空间,没有隔离。性能最好,但端口冲突风险高。
none:容器没有网络接口,完全隔离。
用户自定义网络:可以创建更复杂的自定义网络,提供更好的容器发现和DNS解析功能。
2349

被折叠的 条评论
为什么被折叠?



