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 的安装#
- 安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
- 指定 Docker 镜像源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 安装 Docker
yum makecache fast
yum -y install docker-ce
- 启动 Docker
systemctl start docker
systemctl enable docker
docker run hello-world
6. Docker 中央仓库#
Docker 官方的中央仓库:(这个仓库的镜像是最全的,但下载速度较慢)
国内的镜像网站:
镜像构建完成后,可以在当前宿主机上运行,但是,如果需要在其他服务器上使用这个镜像,就需要一个集中存储、分发镜像的服务,Docker Registry 就是这样的服务
一个 Docker Registry 中可以包含多个仓库(Repository),每个仓库可以包含多个标签(Tag);每个标签对应一个镜像
通常,一个仓库会包含同一个软件的不同版本的镜像,而标签就常用于对应该软件的各个版本
-
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 镜像除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数,如:匿名卷、环境变量、用户
镜像不包含任何动态数据,其内容在构建之后也不会改变
镜像构建时,会 一层一层构建 ,前一层是后一层的基础,每一层构建完成后就不会再发生变化,后一层的任何改变都只发生在自己这一层
- 拉取镜像(从中央仓库拉取镜像到本地)
docker pull 镜像名称[:tag]
- 查看本地全部镜像(查看本地已经安装过的镜像信息,包含标识,名称,版本,更新时间,大小)
docker images
- 删除本地镜像(镜像会占用磁盘空间,可以直接收到删除)
docker rmi 镜像的标识
- 镜像的导入导出
# 将本地的镜像导出
docker save -o 导出的路径 镜像id
# 加载本地的镜像文件
docker load -i 镜像文件
# 修改镜像名称
docker tag 镜像id 新镜像名称:版本
8. 容器#
运行起来的镜像
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类和实例 一样
镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等
容器的实质是进程 ,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。前面讲过镜像使用的是分层存储,容器也是如此
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失
按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据 ,容器存储层要保持无状态化
所有的文件写入操作,都应该使用数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高
数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此, 使用数据卷后,容器可以随意删除、重新 run,数据却不会丢失
- 运行容器(运行容器需要制定具体镜像,如果镜像不存在,会直接下载)
# 简单操作
docker run 镜像的标识|镜像名称[:tag]
# 常用的参数
docker run -d -p 宿主机端口:容器端口 --name 容器名称 镜像的标识|镜像名称[:tag]
# -d: 代表后台运行容器
# -p: 宿主机端口:容器端口: 为了映射当前Linux的端口和容器的端口
# --name: 容器名称: 指定容器的名称
- 查看正在运行的容器
docker ps [-qa]
# -a: 查看全部的容器,包含没有运行的
# -q: 只查看容器的标识
- 查看容器日志(查看容器的日志,以查看运行的信息)
docker logs -f 容器id
# -f: 可以滚动查看日志的最后几行
- 进入容器内部(可以进入容器内部进行操作)
docker exec -it 容器id bash
- 复制内容到容器(将宿主机的文件复制到内部的指定目录)
docker cp 文件名称 容器id:容器内部路径
- 重启 / 启动 / 停止 / 删除容器(容器的启动、停止、删除等操作会经常用到)
# 重新启动容器
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
docker run -d -p 8080:8080 --name tomcat daocloud.io/library:8.5.15-jre8
- Docker 安装 MySQL
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)
docker volume create 数据卷名称
- 查看数据卷详情(查看数据卷的详细信息,可以查询到存放路径,创建时间等)
docker volume inspect 数据卷名称
- 查看全部数据卷
docker volume ls
- 删除数据卷
docker volume rm 数据卷名称
- 容器映射数据卷
映射有两种方式:
- 通过数据卷名称映射,如果数据卷不存在,Docker 会帮你自动创建,会将容器内部自带的文件,存储在默认的存放路径
- 通过路径映射数据卷,直接指定一个路径作为数据卷的存放位置,但是这个路径下是空的
# 通过数据卷名称映射
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#
-
设置权限(需要将 DockerCompose 文件的名称修改一下,给予 DockerCompose 文件一个可执行权限)
mv docker-compose-linux-x86_64 docker-compose
chmod 777 docker-compose
- 配置环境变量(方便后期操作,配置一个环境变量)
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 文件中,不要使用制表符
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 文件
# 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 文件)
# 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)
from daocloud.io/library/tomcat:8.5.15-jre8
copy ssm.war /usr/local/tomcat/webapps
- 运行(测试效果)
# 可以直接启动基于docker-compose.yml以及Dockerfile文件构建的自定义镜像
docker-compose up -d
#如果自定义镜像不存在,会帮助我们构建出自定义镜像,如果自定义镜像已经存在,会直接运行这个自定义镜像
#重新构建自定义镜像
docker-compose build
#运行当前内容,并重新构建
docker-compose up -d --build
13. 总结#
本文主要把 Docker 中的一些常见概念做了详细的阐述