目录
零:前置信息与说明
本文提到的操作系统,默认是Centos7操作系统。
Linux的文件系统;包括 bootfs 和 rootfs。前者占用存储空间很大,后者只占很小的一部分。
bootfs包括:bootloader 和 kernel(操作系统内核)。后者是Linux的操作系统内核部分,前者用于在操作系统启动阶段加载后者,并在后者加载完毕后被卸载。
rootf包括:/dev、/proc、/bin、/etc 这些标准目录和文件。
docker的适用场景:如果您的应用 1:是微服务架构、2:频繁测试与部署、3:经常跨环境或跨云迁移。那么建议使用docker。否则,虚拟机就完全够用。因为业务系统与操作系统之间的东西越多,服务器的性能效率就会越低。
一:docker与VMware对比
docker与VMware的对比
以下的内容如无特殊说明,对比都是出现在部署在同一个宿主机服务器上的多个虚机和docker之间,同时提到的操作系统默认都是linux。
VMware虚拟机 | Docker容器 | |
操作系统 | 每个虚机独享 | 所有容器共享宿主机的操作系统内核 |
占用存储 | 每个虚机都要安装一个完整的文件系统,占用存储空间较多 | 每个容器仅包括rootfs部分内容,空间占用很小。 |
硬件使用 | 虚拟机直接操纵宿主机的硬件 | 容器不直接与硬件打交道,而是通过其所属宿主机的操作系统实现 |
二:docker的安装与下载加速
这部分没啥可说的,按照下面的说明一步步的做下来,就能安装成功了,还是比较简单的。同时我这里提供了两个yum源的配置方式以及两种版本的docker的安装方式,根据爱好自选即可。
/** 更新 yum 到最新 **/
[root@docker01 ~]# yum update
/** 安装必要的软件包。具体作用不详,但缺少肯定会有问题。。。 **/
[root@docker01 ~]# yum install -y yum-util device-mapper-persistent-data lvm2
/** 下面两个yum源任选其一即可。特别是下面第一行报错的时候,直接使用阿里的源最简单了 **/
/** 设置 yum 的源 **/
[root@docker01 ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
/** 这一步仅供参考,是以阿里云作为docker的源 **/
[root@docker01 ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
/** 真正开始安装 docker。以当前方法安装,得到的必然是最新版本。不便于手动指定 **/
[root@docker01 ~]# yum install -y docker-ce
/** 这一步选做,这是安装指定版本的docker **/
[root@docker01 ~]# yum install -y docker-ce-19.03.9-3.el7
/** 查看docker版本 **/
[root@docker01 ~]# docker -v
/** 查看docker 守护进程状态 ,若状态显示 inactive 或 failed,说明服务未启动 **/
[root@docker01 ~]# systemctl status docker
/** 启动docker **/
[root@docker01 ~]# systemctl start docker
三:镜像
镜像是一系列功能软件的组合,比如我们可以把MySQL、Redis、MongoDB 放到一个镜像中(-_-||,不会真人有这么干吧)上传到docker的hub,方便像我们一样有个性的人直接拿来使用,减少大家的重复性劳动。
需要注意的是,镜像一旦生成无法被修改。但是可以对镜像做扩展,比如可以在上面那个天才的镜像中添加Oracle数据库,生成一个更加完美的镜像以供小可爱们使用。
3.1:配置镜像加速器
因为docker 的hub 在外网,直接访问会很慢非常慢,因此我们需要一个加速器。本文中我将介绍阿里云的镜像加速器的使用方法,操作步骤如下:
1:登录阿里云(https://www.aliyun.com/)
2:扫码登录
3:登录后,点击屏幕右上角“控制台”,进入之后点击如下图所示的左上角的图标,搜索“容器镜像服务”,然后进入搜索到的结果。如下图所示
4:点击如下图所示的“镜像加速器”。看到下图右侧的内容。其中右侧上部是每人私属的加速器地址。而右侧下部是阿里云贴心的帮我们设置好的配置加速器的操作文档。可以根据自己的操作系统选择合适的操作文档,复制粘贴到操作系统的命令行回车执行即可。
3.2:搜索镜像
搜索镜像的目的之一,是为了让自己知道对应docker镜像有哪些可选的,其二就是找到拉取对应版本镜像的命令语句(如本小节最后一幅图所示)。
右侧的链接,是“集装箱”(docker)的“船坞”(hub),点我搜索docker镜像 。在这里我们可以找到所有的docker镜像及其发行版本、大小等详细信息。点击下图上方红框部分可以进行搜索
以搜索centos操作系统为例,结果如下图所示。下图左侧是筛选项。条件包括“产品分类”、“可信级别(即产品来源)”、“架构分类”等。而下图右侧是筛选后的结果。(如果要找6或者7等不同版本的centos,不必在搜索框中输入版本号,只需要在官网的镜像中,通过标签(tag)来找即可)
点击右侧有官网认证的绿色标签的结果项,进入如下页面。可以看到当前docker镜像的详细信息,包括支持的架构信息、历史的标签信息。这些标签信息在后面下载docker镜像的时候会用到。
如下图所示,我们也可以从tag这里找到所有的历史标签。包括6、7等不同版本。下图左侧方框是历史tag号,下图右侧是对应版本号的docker镜像的拉取命令。
3.3:下载镜像
下载镜像需要在宿主机上操作。
如果在上面已经选好了心仪的镜像和版本,那直接执行docker hub提供的拉取命令即可。(或使用 docker pull xx 这样的命令来获取某软件的最新版本)
另外,也可以在宿主机上,执行命令(docker search centos)来粗略搜索可选的docker镜像,如下图所示。但我们无法看到每个镜像名称之下有哪些tag。这是这种搜索方式的一大欠缺。
列名 | 说明 |
NAME | 镜像名称 |
DESCRIPTION | 描述 |
STARS | 标星数量(数量越大好评度越高) |
OFFICIAL | 是否官方出品 |
AUTOMATED | 是否自动化构建 |
3.4:查看已下载及删除镜像
查看所有镜像的命令为“docker images”。如下图所示,我们可以看到镜像名称列“REPOSITORY”、tag号列“TAG”、镜像id列“IMAGE_TAG”、以及容量大小列“SIZE”。
列名 | 说明 |
REPOSITORY | 下载的镜像名 |
TAG | 镜像的当前版本号 |
IMAGE_ID | 镜像在世界的唯一id |
CREATED | 创建时间 |
SIZE | 大小 |
删除镜像的命令为“docker rmi image_id”,我们删除上面的名为“vim_centos”的镜像,删除过程与结果如下图所示。
3.5:hub.docker.com无法访问的解决方法(2024-06-29补充)
目前 hub.docker.com 网站因为一些原因无法访问,这给我们查找某软件镜像、获取其历史版本带来了难度。为解决这个问题,我尝试了直接访问阿里云提供的私有加速器地址(如3.1小节步骤4的图中所示),也尝试了访问诸如网易、科大的镜像,结果都毫无惊喜地无法访问 ,以目前标题这个问题无解(如果哪位有好的办法欢迎不吝赐教)。
如果需要某个软件的历史版本,我们可以自己搭建私有仓库(如Harbor),或者创建自己的镜像来解决:
(2025-05-07补充)
通常,无法从hub.docker.com拉取镜像的报错如下所示“Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)” ,为解决这个问题,单纯将阿里镜像地址配置在 daemon.json中并不可行。经过摸索终于发现,在不用梯子的情况下,可以通过以下几个步骤拉取到镜像
3.5.1、备份 /etc/docker/daemon.json
3.5.2、修改 daemon.json 文件,内容如下
{
"registry-mirrors": [
"https://docker.1panelproxy.com",
"https://2a6bf1988cb6428c877f723ec7530dbc.mirror.swr.myhuaweicloud.com",
"https://docker.m.daocloud.io",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://your_preferred_mirror",
"https://dockerhub.icu",
"https://docker.registry.cyou",
"https://docker-cf.registry.cyou",
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi",
"https://mirror.aliyuncs.com",
"https://dockerproxy.com",
"https://mirror.baidubce.com",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.mirrors.ustc.edu.cn",
"https://mirror.iscas.ac.cn",
"https://docker.rainbond.cc"
]
}
3.5.3、重新加载并重启docker,命令如下
/** 重新加载docker配置 **/
[root@docker01 ~]# sudo systemctl daemon-reload
/** 重启docker **/
[root@docker01 ~]# sudo systemctl restart docker
按照上面的步骤操作后,一般就能解决前面的问题了。
四:容器
如果说镜像是java中的“类”,那么容器就是java中的“实例”。真正干活儿的就是一个个的容器
4.1:查看容器
拉取centos7的镜像后,就可以将镜像运行为容器了。命令与结果如下所示。可以看到当前只有一个状态为exited(退出的)的redis的容器。
/** 查看当前运行的容器 **/
[root@docker01 ~]# docker ps
/** 查看所有容器,包括运行和未运行的 **/
[root@docker01 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e3d8f08a08b5 redis:5.0 "docker-entrypoint.s…" 3 weeks ago Exited (0) 3 weeks ago redisRunning
列名 | 含义 |
CONTAINER ID | 容器id |
IMAGE | 容器对应镜像名称及版本号(冒号分割) |
COMMAND | 运行命令 |
CREATED | 创建时间 |
STATUS | 状态(运行、退出、后台运行等) |
PORTS | 映射到宿主机上的端口号 |
NAMES | 容器名 |
4.2:创建容器
运行容器的命令如下。其中,"run"是关键字 。"-i","-t","-d"可以合在一起写成"-it"或"-id";
/** 创建容器,立刻打开一个终端并进入容器,一旦退出,容器状态即为Exited **/
[root@docker01 ~]# docker run -it --name=MyFirstCentosTwo centos:7 /bin/bash
/** 创建一个在后台运行的容器,暂不进入。只要不停止,则该容器状态始终为Up **/
[root@docker01 ~]# docker run -id --name=MyFirstCentos centos:7
参数 | 含义 |
-i | 令容器一直运行 |
-t | 为容器分配一个终端并立刻进入容器 |
-d | 在后台运行 |
--name=MyFirstCentos | name后面可以接空格或等于号 等号后面是为你的容器起一个响亮的名字 |
centos:7 | 使用的镜像名称和tag号 二者之间用冒号分割 |
/bin/bash | 进入容器的命令,可以留空 |
4.3:启停、进入、删除容器
以上图名为MyFirstCentosTwo的centos类型的容器为例,演示启动、进入和停止,命令如下
说明:Exited状态的容器是无法进入使用的,必须要先启动它。
/** 启动命令关键字 start 后面是所要启动的容器的id **/
[root@docker01 ~]# docker start e827022fa727
/** 进入命令关键字 exec,后面的参数一般为 -it,其后的参数是容器的唯一id,以及进入的命令 **/
[root@docker01 ~]# docker exec -it 211af5ee181e /bin/bash
/** 停止命令关键字 stop,其后参数为容器的唯一id **/
[root@docker01 ~]# docker stop 211af5ee181e
/** 删除命令关键字 rm,参数为容器唯一id **/
[root@docker01 ~]# docker rm 211af5ee181e
4.4:端口映射
如果在一个宿主机上运行多个同样的容器,那么必定会涉及到端口的冲突问题。为避免这个问题,我们需要为每个容器的端口在宿主机上映射成不同的端口,以便外界访问使用。
/** 端口映射关键字 -p, 参数包括宿主机目标端口和容器内目标端口,二者以冒号分割。
其含义是将容器内的目标端口映射到宿主机上的目标端口 **/
[root@docker01 data]# docker run -id -v /data/redis:/docker_data -p 16379:6379 --name=MyFirstRedis redis:7.0
4.5:查看容器日志
有的时候会创建容器失败,或者容器运行过程中报错。这时就需要查看日志排查问题。命令如下所示。
/** 查看最近30分钟的日志
其中,CONTAINER_ID 就是容器id。即使只有id的前几位也可以 **/
[root@docker01 ~]# docker logs --since 30m CONTAINER_ID
/** 查看一段时间范围内的日志 **/
[root@docker01 ~]# docker logs -t --since=“2022-08-30T15:00:00” --until “2022-08-30T16:00:00” CONTAINER_ID
/** 另外,logs后面可以跟一系列的参数。
具体用法可以输入 docker logs --help 来了解,这部分内容很少,就不在此展示了 **/
五:数据卷
5.1:数据卷的说明
前提:容器之间是无法共享数据的,而且一旦容器被删除,那么其中生成的数据会消失。未解决以上问题,常用技术是数据卷。
是什么:数据卷是在容器的宿主机上一个目录。用来与docker容器中的某个目录进行绑定。
为什么:使用数据卷的原因就是因为容器间无法共享数据,因此采用数据卷来间接实现。
特点:一个数据卷可以被多个容器挂在,一个容器可以挂载多个数据卷。通过前者可以实现多个docker容器之间的数据互通(不推荐),而且数据卷也能在一定程度上实现数据持久化。
5.2:实现
以下是命令与效果截图
/** 加载数据卷的关键字是 -v 其参数是宿主机的目标路径与容器中的目标路径,二者之间以冒号分割。
同时,若以上两个目标路径不存在,docker会自动创建
需要注意的是,宿主机中的目标路径务必是绝对路径 **/
[root@docker01 data]# docker run -id --name=CentosVolumn02 -v /data/CentosVolumn02:/docker_data/docker_CentosVolumn02 -v /data/CentosVolumn03:/docker_data/docker_CentosVolumn03 centos:7
这样,当docker容器挂在了数据卷且处于运行状态时,无论我们是在宿主机还是docker容器的目标路径下做文件的操作,另一者都能感知到。
5.3:注意事项
若当你在创建容器时指定了数据卷,那么数据卷映射的容器内的路径下的文件会被清空。这一点务必小心!!特别是映射的路径原本是属于配置文件的时候。