文章目录
1. Docker是什么
docker是一个开源的应用容器引擎,基于Google公司推出的Go语言实现。Docker是对软件和其依赖环境的标准化打包,应用之间相互隔离,共享一个操作系统内核,可以运行在目前许多主流操作系统上。
需要注意的是:Docker本身不是容器,Docker只是管理容器的引擎。
2. 容器与虚拟机的区别
容器时将代码和环境的关系打包在一起的一个集合,而虚拟机是在物理层面上,分离出一个操作系统;
多个容器可以运行在同一台物理服务器上,并共享一个操作系统的内核资源;多个虚拟机也可以运行在同一台机器上,但每个虚拟机都需要一个完整的操作系统。
下图比较了Docker和传统虚拟化方式的不同点:
可见容器是在本地操作系统层面上实现虚拟化,直接复用本地主机的操作系统,不需要单独安装操作系统,而传统的虚拟化技术方式则需要单独安装每个虚拟机的操作系统。
总的来讲,Docker容器的启动速度快;对系统的资源利用率高;迁移性和扩展性更佳;用户可以轻松的把一个应用从一个平台直接迁移到另一个平台。
3. Docker常用指令
关于Docker的安装,网上有很多详细的教程,这里不再赘述。
1. 启动:systemctl start docker
2. 停止:systemctl stop docker
3. 重启:systemctl restart docker
4. 检查docker进程的运行状态:systemctl status docker
5. 命令帮助信息:docker command -help
4. Docker核心要素
Docker包括三个核心要素:镜像(Image)、容器(Container)、仓库(Repository);
Docker的运行离不开以上几个核心组件的支持;再次强调一遍:Docker不是容器,而是管理容器的引擎。
4.1 镜像
镜像是由许多层的文件系统叠加构成的,最下面是一个引导文件系统bootfs,第二层是一个 root 文件系统 rootfs,root 文件系统通常是某种操作系统,比如 centos、Ubuntu,在 root 文件系统之上又有很多层文件系统,这些文件系统叠加在一起,构成 docker 中的镜像;
4.1.1 镜像的常用操作指令
1. 下载镜像: docker pull image:latest
2. 列出镜像: docker images
3. 运行镜像: docker run -d image
4. 删除镜像: docker rmi image:latest
注: latest是镜像的标签tag. 运行镜像后可以通过 ps -ef | grep image 命令来查询 image 进程.
4.2 容器
容器是从镜像创建的运行实例。它可以被启动、停止、删除。每个容器都是相互隔离的、保证安全平台。可以把看做一个简易版的 Linux环境,包括 root 用户权限、进程空间、用户空间和网络空间和运行在其中的应用程序。
Docker 利用容器来运行应用,镜像是只读的,容器在启动的时候创建一层可写层作为最上层。
4.2.1 容器的常用操作指令
1. 通过镜像启动容器: docker run -d container
2. 查看运行中的容器: docker ps
3. 查看所有的容器: docker ps -a
4. 查看某个容器状态: docker ps -a | grep container_id/name
5. 打印容器的日志: docker logs -f container_id
6. 停止容器: docker stop container_id
7. 开启停止的容器: docker start container_id
8. 删除容器: docker rm container_id
9. 进入容器: docker exec -it container_id bash
10.查看容器详细信息: docker inspect container_id
10.停用全部运行中的容器: docker stop $(docker ps -q)
11.删除全部容器: docker rm $(docker ps -aq)
12.删除容器数据卷: docker volume rm volume_id
注:上述指令可以利用 "&" 拼接使用; 例:通过一条指令停用并删除全部容器:
docker stop $(docker ps -q) & docker rm $(docker ps -aq)
4.2.2 上述指令中缩写的含义
相关缩写的含义可以通过 docker command --help 进行查询, 下面仅列出常见含义:
1. -a/--all 列出所有容器(默认仅列出运行中的容器)
2. -q/--quiet 仅列出容器ID
3. -d/--detach 将容器运行在后台,并且输出容器ID
4. -p/--publish list 将宿主机端口与容器服务进程端口进行映射
5. -i/--interactive 即使未连接STDIN(标准输入)也保持打开状态, 分配一个交互终端
6. -t/--tty 分配一个伪tty设备(终端设备), 容器启动后会进入其命令行, 与 -i 一起使用
7. -f/--follow 跟踪日志输出
上述缩写针对不同的指令, 这里不进行详细说明.
注:其中 $() 运算符不是 docker 运算符, 它是 bash 运算符, 它返回括号之间的命令输出; 因此可以用其连接多个实现,简化操作.
4.3 仓库
仓库是集中存放镜像文件的场所,有时候会把仓库和仓库注册服务器(Registry)看做同一事物,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
仓库分为公开仓库(Public)和私有仓库(Private)两种形式;最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载;当然,用户也可以在本地网络内创建一个私有仓库。
注:Docker仓库的概念跟Git类似,注册服务器也类似于Github这样的托管服务。
1. 查找镜像: docker search image
2. 获取镜像: docker pull image
3. 上传镜像: docker push image
5. Dockerfile文件
Dockerfile 用于构建 Docker 镜像,由多行命令语句组成,基于这些命令可以构建一个镜像。一般 Dockerfile 分为四部分:
1. 基础镜像信息; 2. 维护者信息; 3. 镜像操作指令; 4. 容器启动时执行指令;
5.1 Dockerfile的常用操作指令
1. FROM
格式为 FROM <image> 或 FROM <image>:<tag>
Dockerfile
文件的第一条指令必须为FROM
指令。并且,如果在同一个Dockerfile
中创建多个镜像时,可以使用多个FROM
指令(每个镜像一次);
FROM...AS...
是Docker 17.05
及以上版本的新指令,AS
用于给基础镜像起别名,在后面引用这个阶段的镜像时直接使用别名即可。
2. WORKDIR
格式为 WORKDIR <dir>
WORKDIR
指工作目录, 类似于cd
命令, 后面的命令都将在该目录下执行, 该目录必须是创建好的.
3. ADD/COPY
格式为 ADD/COPY <src> <dest>
简单来讲,就是复制内容到镜像中;ADD和COPY的区别和使用场景如下:
1. ADD
支持远程url和压缩格式的文件,并且可以自动解压到目标路径中;COPY
只允许从本机中复制文件;
2. COPY
支持从其他构建阶段中复制源文件(--from)
;
3. 根据官方Dockerfile
最佳实践,除非真的需要从远程url
添加文件或自动提取压缩文件才用ADD
,其他情况一律使用COPY
。
4. EXPOSE
格式为EXPOSE <port> [<port>...]
告诉Docker
服务端容器暴露的端口号,供互联系统使用,在启动容器时需要通过-p
映射端口,Docker
主机会自动分配一个端口转发到指定的端口。
5. RUN
格式为 RUN <command>
RUN
指令将在当前镜像基础上执行指定命令,并提交为新的镜像,当命令较长时可以使用\
来换行;
创建/运行/下载等都需要该命令,每执行一次该命令就会在docker
上新建一层, 过多无意义的层会导致镜像膨胀过大,所以可以用&&
进行连接
6. CMD
指定启动容器时执行的命令,每个Dockerfile
只能有一条CMD
命令。如果指定了多条命令,只有最后一条会被执行。
注:CMD
指令在docker run
时运行, RUN
指令是在docker build
时运行。
6. 数据挂载
有时容器中的数据需要持久化处理,我们不希望容器删除以后数据也被删除,所以Docker
提出了Volume
的概念,Volume
可以将宿主机某个目录与容器某个目录(称为挂载点或卷)相关联,当某一个目录中的内容发生改变时,另一个目录也会立即更新。
Docker
管理数据的方式有两种:
1. 数据卷
2. 数据卷容器
6.1 数据卷
格式为 docker run -it -v 宿主机目录:容器内目录
# 测试:
docker run -it --name volume-test -v D:/software/docker/volumes:/test ubuntu:19.04 /bin/bash
# 创建容器与目录挂载后, 查看容器信息
docker inspect volume-test
此时可以看到容器的详细信息,/test
为容器内目录(若目录不存在则自动创建),Source
对应宿主机目录:
当在宿主机 / 容器目录下创建 / 编辑文件时,另一方均可生效。例如:在宿主机目录下创建文件test.txt
,在容器目录下读取文件:
当然也可以在
Dockerfile
中通过命令VOLUME ["volume"]
设置容器挂载目录。
6.2 容器共享卷
多个容器之间可以共享同一个(多个)卷,通过 --volumes-from 实现:
# 容器volume-test-share共享了容器volume-test的数据卷
docker run -it --name volume-test-share --volumes-from volume-test ubuntu:19.04 /bin/bash
共享后的多个容器中,任意一个容器修改了目录中的内容,其他容器也会目录内容的变化。
6.3 数据卷容器
如果多个容器需要共享数据(如持久化数据库、配置文件或者数据文件等),可以创建一个特定的数据容器,该容器有一个(多个)卷。其他容器共享数据容器中的卷即可。
并且,因为容器的卷本质上对应主机上的目录,所以这个数据容器也不需要启动。如:
docker run --name data_volume image_name