简介
docker是一个用Go语言实现的开源项目,可以让我们方便的创建和使用容器,docker将程序以及程序所有的依赖都打包到docker container,这样你的程序可以在任何环境都会有一致的表现,这里程序运行的依赖也就是容器就好比集装箱,容器所处的操作系统环境就好比货船或港口,程序的表现只和集装箱有关系(容器),和集装箱放在哪个货船或者哪个港口(操作系统)没有关系。
因此我们可以看到docker可以屏蔽环境差异,也就是说,只要你的程序打包到了docker中,那么无论运行在什么环境下程序的行为都是一致的,程序员再也无法施展表演才华了,不会再有“在我的环境上可以运行”,真正实现“build once, run everywhere”。
概念
docker 中的几个概念:
- dockerfile
- image
- container
dockerfile
Dockerfile
是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。感觉就像makefile
一样。
image
Docker镜像(Docker Image)就是一个只读的模板。比如,一个镜像可以包含一个完整的Ubuntu操作系统环境。镜像可以用来创建Docker容器。
container
容器是镜像的运行时实例,容器是独立运行的一个或一组应用,以及它们的运行态环境。
安装方式:
包管理器安装
添加官方仓库源
1
| sudo dnf config-manager --add-repo=https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
|
更新源
1 2
| sudo dnf clean all sudo dnf makecache
|
安装docker及其组件
1
| sudo dnf install -y docker-ce docker-ce-cli containerd.io
|
二进制包安装(tgz)
解压二进制包
1
| tar -zxvf docker-28.3.0.tgz
|
转移到用户库
1
| sudo cp docker/* /usr/bin/
|
配置 systemd 服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| sudo tee /etc/systemd/system/docker.service <<EOF [Unit] Description=Docker Service After=network.target
[Service] ExecStart=/usr/bin/dockerd Restart=always LimitNOFILE=1048576 LimitNPROC=1048576
[Install] WantedBy=multi-user.target EOF
|
启动
1 2 3
| sudo systemctl daemon-reload sudo systemctl start docker sudo systemctl enable docker
|
改变 Docker 默认存储位置
- 停止 Docker 服务:
1
| sudo systemctl stop docker
|
- 创建新目录:
1
| sudo mkdir -p /data/docker
|
- 修改 Docker 配置文件(
/etc/docker/daemon.json
):
1 2 3
| { "data-root": "/data/docker" }
|
- 把旧数据迁移(可选,如果想保留):
1
| sudo rsync -aP /var/lib/docker/ /data/docker
|
- 启动 Docker:
1
| sudo systemctl start docker
|
- 验证:
1
| docker info | grep "Docker Root Dir"
|
应该显示:
1
| Docker Root Dir: /data/docker
|
技术分析
Docker 容器的实现基于 Linux 内核的核心技术,通过资源隔离和虚拟化技术模拟独立的运行环境。以下是其核心实现原理:
1. 核心技术(Linux 内核支持)
Docker 容器本质上是 隔离的进程,依赖以下 Linux 特性实现:
2. 容器运行流程
- 镜像加载:
- 基于镜像(只读层)创建容器时,添加一个可写层(Copy-on-Write)。
- 资源隔离:
- 通过
Namespaces
创建隔离的进程、网络、文件系统等环境。
- 资源限制:
- 网络配置:
- 默认使用
bridge
模式,创建 veth pair
虚拟网卡对连接容器与宿主机。
3. 与虚拟机的区别
特性 |
Docker 容器 |
虚拟机 |
隔离级别 |
进程级(共享宿主机内核) |
硬件级(完整操作系统) |
启动速度 |
秒级(直接调用宿主机内核) |
分钟级(需启动Guest OS) |
性能损耗 |
<5%(接近原生进程) |
15%~30%(虚拟化开销) |
镜像大小 |
MB 级(仅应用层) |
GB 级(含完整OS) |
4. 关键组件
- containerd:负责容器生命周期管理(创建/启动/停止)。
- runc:底层运行时工具,根据 OCI 标准调用内核功能创建容器。
- Docker Engine:封装上层 API 和工具链(如
docker build
/docker run
)。
5. 简单示例:容器如何启动?
1 2 3 4 5
| 1. 检查本地是否存在 `ubuntu` 镜像,若无则从仓库拉取。 2. 创建可写层(容器层)叠加到镜像的只读层上。 3. 调用 `runc` 创建 Namespaces 和 Cgroups。 4. 在隔离环境中启动 `/bin/bash` 进程。
|
总结
Docker 容器本质是 通过 Linux 内核的 Namespaces 和 Cgroups 实现的隔离进程,配合联合文件系统提供轻量级、高性能的虚拟化环境。其效率远高于传统虚拟机,但隔离性较弱(共享内核)。