Docker总结

1. 概述

本文介绍 Docker 的相关知识，重点是 Docker 的 3 大核心：镜像、容器、仓库

2. Docker 的介绍

Docker 是世界领先的软件容器平台

Docker 使用 Google 公司推出的 Go 语言进行开发实现，基于 Linux 内核的 cgroup，namespace，以及 AUFS 类的 UnionFS 等技术，对进程进行封装隔离，属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其他的隔离的进程，因此也称其为容器。Docke 最初实现是基于 LXC

Docker 能够自动执行重复性任务，例如搭建和配置开发环境，从而解放了开发人员以便他们专注在真正重要的事情上：构建杰出的软件

用户可以方便地创建和使用容器，把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改，就像管理普通的代码一样

Docker 设计时，充分利用 Union FS 的技术，将其设计为分层存储的架构

3. Docker 的思想

集装箱：将所有需要的内容放到不同的集装箱中，谁需要某些内容（环境）就直接拿对应的集装箱就行了

标准化：

运输的标准化：Docker 有一个码头，所有上传的集装箱都放在这个码头上，当有人需要某一个环境时，就直接派 [小蓝鲸]^(Docker 的吉祥物) 去搬运这个集装箱就行

命令的标准化：Docker 提供了一系列命令，帮助我们去获取集装箱的相关操作

提供了 REST 的 API：衍生出了很多图形化界面，如： [Rancher]^(一个开源的企业级容器管理平台)

隔离性：Docker 在运行集装箱里的内容时，会在 Linux 的内核中，单独开辟一片空间，这片空间不会影响到其他程序

中央仓库 / 注册中心：超级码头，上面放的都是集装箱

镜像：就是集装箱

容器：运行起来的镜像（就是将软件打包成标准化单元，以用于开发、交付和部署。通俗的描述就是：容器就是一个存放东西的地方，就像书包可以装各种文具、衣柜可以放各种衣服、鞋架可以放各种鞋子一样）

4. 容器 VS 虚拟机

容器是一个应用层抽象，用于将代码和依赖资源打包在一起。多个容器可以在同一台机器上运行，共享操作系统内核，但各自作为独立的进程在用户空间中运行 。 与虚拟机相比， 容器占用的空间较少（容器镜像大小通常只有几十兆），瞬间就能完成启动

虚拟机（VM）是一个物理硬件层抽象，用于将一台服务器变成多台服务器。管理程序允许多个 VM 在一台机器上运行。 每个 VM 都包含一整套操作系统、一个或多个应用、必要的二进制文件和库资源，因此占用大量空间。而且 VM 启动也十分缓慢

5. Docker 的安装

安装依赖包

Copy
yum install -y yum-utils device-mapper-persistent-data lvm2

指定 Docker 镜像源

Copy
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装 Docker

Copy
yum makecache fast
yum -y install docker-ce

启动 Docker

Copy
systemctl start docker
systemctl enable docker
docker run hello-world

6. Docker 中央仓库

Docker 官方的中央仓库：（这个仓库的镜像是最全的，但下载速度较慢）

https://hub.docker.com/

国内的镜像网站：

https://c.163yun.com/hub#/home

http://hub.daocloud.io/

镜像构建完成后，可以在当前宿主机上运行，但是，如果需要在其他服务器上使用这个镜像，就需要一个集中存储、分发镜像的服务，Docker Registry 就是这样的服务

一个 Docker Registry 中可以包含多个仓库（Repository），每个仓库可以包含多个标签（Tag）；每个标签对应一个镜像

通常，一个仓库会包含同一个软件的不同版本的镜像，而标签就常用于对应该软件的各个版本

Docker Registry 公开服务和私有 Docker Registry 的概念：

Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服务

一般这类公开服务允许用户免费上传、下载公开的镜像，并可能提供收费服务供用户管理私有镜像。

最常使用的 Registry 公开服务是官方的 Docker Hub ，这也是默认的 Registry，并拥有大量的高质量的官方镜像

除了使用公开服务外，用户还可以在本地搭建私有 Docker Registry 。Docker 官方提供了 Docker Registry 镜像，可以直接使用做为私有 Registry 服务

开源的 Docker Registry 镜像只提供了 Docker Registry API 的服务端实现，足以支持 Docker 命令，不影响使用。但不包含图形界面，以及镜像维护、用户管理、访问控制等高级功能

7. 镜像

镜像：
一个特殊的文件系统（实际是由多层文件系统联合组成的）

操作系统分为内核和用户空间，对于 Linux 而言，内核启动后，会挂载 root 文件系统为其提高用户空间的支持，而 Docker 镜像就相当于是一个 root 文件系统

Docker 镜像除了提供容器运行时所需的程序、库、资源、配置等文件外，还包含了一些为运行时准备的一些配置参数，如：匿名卷、环境变量、用户

镜像不包含任何动态数据，其内容在构建之后也不会改变

镜像构建时，会 一层一层构建 ，前一层是后一层的基础，每一层构建完成后就不会再发生变化，后一层的任何改变都只发生在自己这一层

拉取镜像（从中央仓库拉取镜像到本地）

Copy
docker pull 镜像名称[:tag]

查看本地全部镜像（查看本地已经安装过的镜像信息，包含标识，名称，版本，更新时间，大小）

Copy
docker images

删除本地镜像（镜像会占用磁盘空间，可以直接收到删除）

Copy
docker rmi 镜像的标识

镜像的导入导出

Copy
# 将本地的镜像导出
docker save -o 导出的路径 镜像id
# 加载本地的镜像文件
docker load -i 镜像文件
# 修改镜像名称
docker tag 镜像id 新镜像名称:版本

8. 容器

容器：

运行起来的镜像

镜像（Image）和容器（Container）的关系，就像是面向对象程序设计中的 类和实例 一样

镜像是静态的定义，容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等

容器的实质是进程 ，但与直接在宿主执行的进程不同，容器进程运行于属于自己的独立的命名空间。前面讲过镜像使用的是分层存储，容器也是如此

容器存储层的生存周期和容器一样，容器消亡时，容器存储层也随之消亡。因此，任何保存于容器存储层的信息都会随容器删除而丢失

按照 Docker 最佳实践的要求，容器不应该向其存储层内写入任何数据 ，容器存储层要保持无状态化

所有的文件写入操作，都应该使用数据卷（Volume）、或者绑定宿主目录，在这些位置的读写会跳过容器存储层，直接对宿主（或网络存储）发生读写，其性能和稳定性更高

数据卷的生存周期独立于容器，容器消亡，数据卷不会消亡。因此， 使用数据卷后，容器可以随意删除、重新 run，数据却不会丢失

运行容器（运行容器需要制定具体镜像，如果镜像不存在，会直接下载）

Copy
# 简单操作
docker run 镜像的标识|镜像名称[:tag]
# 常用的参数
docker run -d -p 宿主机端口:容器端口 --name 容器名称 镜像的标识|镜像名称[:tag]
# -d: 代表后台运行容器
# -p: 宿主机端口:容器端口: 为了映射当前Linux的端口和容器的端口
# --name: 容器名称: 指定容器的名称

查看正在运行的容器

Copy
docker ps [-qa]
# -a: 查看全部的容器，包含没有运行的
# -q: 只查看容器的标识

查看容器日志（查看容器的日志，以查看运行的信息）

Copy
docker logs -f 容器id
# -f: 可以滚动查看日志的最后几行

进入容器内部（可以进入容器内部进行操作）

Copy
docker exec -it 容器id bash

复制内容到容器（将宿主机的文件复制到内部的指定目录）

Copy
docker cp 文件名称 容器id:容器内部路径

重启 / 启动 / 停止 / 删除容器（容器的启动、停止、删除等操作会经常用到）

Copy
# 重新启动容器
docker restart 容器id
# 启动停止运行的容器
docker start 容器id
# 停止指定的容器（删除容器前，需要先停止容器）
docker stop 容器id
# 停止全部容器
docker stop $(docker ps -qa)
# 删除指定容器
docker rm 容器id
# 删除全部容器
docker rm $(docker ps -qa)

9. Docker 的应用

Docker 安装 Tomcat

Copy
docker run -d -p 8080:8080 --name tomcat daocloud.io/library:8.5.15-jre8

Docker 安装 MySQL

Copy
docker run -d -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=root daocloud.io/library/mysql:5.7.4

10. 数据卷

思考：

Docker 容器删除后，在容器中产生的数据也会随之销毁

Docker 容器和外部机器可以直接交换文件吗？

容器之间想要进行数据交互？

数据卷：

数据卷是宿主机中的一个目录或文件

当容器目录和数据卷目录绑定后，对方的修改会立即同步

一个数据卷可以被多个容器同时挂载

一个容器也可以被挂载多个数据卷

创建数据卷（创建数据卷后，默认会存放在一个目录下 /var/lib/docker/volumes/ 数据卷名称 /_data）

Copy
docker volume create 数据卷名称

查看数据卷详情（查看数据卷的详细信息，可以查询到存放路径，创建时间等）

Copy
docker volume inspect 数据卷名称

查看全部数据卷

Copy
docker volume ls

删除数据卷

Copy
docker volume rm 数据卷名称

容器映射数据卷

映射有两种方式：

通过数据卷名称映射，如果数据卷不存在，Docker 会帮你自动创建，会将容器内部自带的文件，存储在默认的存放路径

通过路径映射数据卷，直接指定一个路径作为数据卷的存放位置，但是这个路径下是空的

Copy
# 通过数据卷名称映射
docker run -v 数据卷名称:容器内部的路径 镜像id
# 通过路径映射数据卷
docker run -v 路径:容器内部的路径 镜像id

11. Dockerfile 自定义镜像

我们可以从中央仓库下载一个镜像，也可以自己手动去制作一个镜像，需要通过 Dockerfile 去指定自定义镜像信息

12. Docker-Compose

之前运行一个镜像，需要添加大量的参数，可以通过 Docker-Compose 编写这些参数

而且 Docker-Compose 可以帮助我们批量的管理容器

这些信息只需要通过一个 docker-compose.yml 文件去维护即可

12.1 下载安装 Docker-Compose

下载 Docker-Compose

设置权限（需要将 DockerCompose 文件的名称修改一下，给予 DockerCompose 文件一个可执行权限）

Copy
mv docker-compose-linux-x86_64 docker-compose
chmod 777 docker-compose

配置环境变量（方便后期操作，配置一个环境变量）

Copy
mv docker-compose /usr/local/bin

vim /etc/profile
# 添加内容 export PATH=$JAVA_HOME:/usr/local/bin:$PATH

source /etc/profile

测试（在任意目录下输入 docker-compose 命令）

12.2 Docker-Compose 管理 MySQL 和 Tomcat 容器

yml 文件以 key 方式来指定配置信息

多个配置信息以换行 + 缩进的方式来区分

在 docker-compose.yml 文件中，不要使用制表符

Copy
version: '3.1'
services:
mysql: #服务的名称
restart: always #代表只要docker启动，那么这个容器就跟着一起启动
image: daocloud.io/library/mysql:5.7.4 #指定镜像路径
container_name: mysql #指定容器名称
ports:
- 3306:3306 #指定端口号的映射
environment:
MYSQL_ROOT_PASSWORD: root #指定MySQL的root用户登录密码
TZ: Asia/Shanghai #指定时区
volumes:
- /opt/docker_mysql_tomcat/mysql_data:/var/lib/mysql #映射数据卷
tomcat:
restart: always
image: daocloud.io/library/tomcat:8.5.15-jre8
container_name: tomcat
ports:
- 8080:8080
environment:
TZ: Asia/Shanghai
volumes:
- /opt/docker_mysql_tomcat/tomcat_webapps:/usr/local/tomcat/webapps
- /opt/docker_mysql_tomcat/tomcat_logs:/usr/local/tomcat/logs

12.3 使用 docker-compose 命令管理容器

使用 docker-compose 命令时，默认会在当前目录下找 docker-compose.yml 文件

Copy
# 1. 基于docker-compose.yml 启动管理的容器
docker-compose up -d

# 2. 关闭并删除容器
docker-compose down

# 3. 开启|关闭|重启已经存在的由docker-compose维护的容器
docker-compose start|stop|restart

# 4. 查看有docker-compose管理的容器
docker-compose ps

# 5. 查看日志
docker-compose logs -f

12.4 docker-compose 配合 Dockerfile 使用

使用 docker-compose.yml 文件以及 Dockerfile 文件在生成自定义的镜像的同时启动当前镜像，并且由 docker-compose 去管理容器

docker-compose 文件（编写 docker-compose.yml 文件）

Copy
# yml文件
version: '3.1'
services:
ssm:
restart: always
build: #构建自定义镜像
context: ../ #指定dockerfile文件的所在路径
dockerfile: Dockerfile #指定Dockerfile文件名称
image: ssm:1.0.1
container_name: ssm
ports:
- 8081:8080
environment:
TZ: Asia/Shanghai

Dockerfile 文件（编写 Dockerfile）

Copy
from daocloud.io/library/tomcat:8.5.15-jre8
copy ssm.war /usr/local/tomcat/webapps

运行（测试效果）

Copy
# 可以直接启动基于docker-compose.yml以及Dockerfile文件构建的自定义镜像
docker-compose up -d
#如果自定义镜像不存在，会帮助我们构建出自定义镜像，如果自定义镜像已经存在，会直接运行这个自定义镜像

#重新构建自定义镜像
docker-compose build
#运行当前内容，并重新构建
docker-compose up -d --build

13. 总结

本文主要把 Docker 中的一些常见概念做了详细的阐述