一. 为什么要使用Docker?(什么是docker?)
1.为什么要使用Docker?
我们知道在一个项目完成后,那么一般的流程都是需要经过测试,最后发布,而在公司中正因如此也分为几个岗位,开发、测试、运维,首先需要由开发人员写好代码,接着交给测试人员进行测试,如果没问题那么就交给运维人员进行上线,那么有没有想过一个问题,我们将代码给别人那么肯定是通过打包进行的,但是如果开发人员编写的代码是jdk8的,而测试的jdk版本是jdk7,那么就有可能在测试人员的电脑上出现问题,而这个时候开发人员也表示很无辜,而Docker 就是通过将环境和代码都装在一个容器里一起发送,那么就可以规避因环境不同而导致的bug了
总的来说Docker就是为了解决软件跨环境迁移的问题
2.什么是Docker?
- Docker是一个开源的应用容器引擎
- 诞生于2013年,基于Go语言实现的,dotCloud公司出品(改名为Docker Inc)
- Docker可以让开发者打包应用以及依赖到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上
- 容器之间是相互隔离的
- 容器开销极低
总结 :Docker是一种容器技术,解决软件跨环境迁移的问题
二.安装Docker
可以访问docker的官方网站
- 将yum包更新到最新版本
yum update
- 安装需要的软件包
yum install -y yum-utils device-mapper-persistent-data lvm2
3.设置yum源
yum-config-manager --add-repo download.docker.com/linux/cento...
4.安装docker
yum install -y docker-ce
5.查看docker版本(检查是否安装成功)
docker -v
三.Docker架构

- 镜像(image):Docker镜像(image),相当于是一个root文件系统,比如官方镜像ubuntu:16.04就包含了完整的一套Ubuntu16.04最小系统的root文件系统
- 容器(container):镜像(image)和容器(container)的关系就像是面向对象程序设计中的类和对象一样,镜像像是一个静态的定义,而容器就是镜像运行时的实体,容器可以被创建、启动、停止、删除、暂停等
- 仓库(repository):仓库可以看做一个代码控制中心用来保存镜像(需要用可以进行拉取,前提是仓库中有)
这大多数镜像都是国外的,所以当我们从仓库中进行拉取的时候,就需要一些手段来加速这个拉取的过程,让我们配置一下镜像加速器(这里我们使用阿里云的加速器)



最后将这里的内容复制粘贴就可以了,可以去本地检查一下

四.Docker各大命令
1.服务相关命令
服务相关命令就是开启,关闭docker的命令,大体比较简单
<1.启动docker服务
systemctl start docker
<2.查看docker服务状态
systemctl status docker
<3.停止docker服务
systemctl stop docker
<4.重启docker服务
systemctl restart docker
<5.开机启动docker服务
systemctl enable docker

2.镜像相关命令
<1.查看镜像
docker images

这里的列依次表示名称、版本号、镜像ID、创建时间、大小
<2.搜索镜像
docker search image [镜像名字]

通过这个命令我们可以知道远程仓库中有没有这个镜像,有的话就可以进行拉取操作(一般我们使用的是官方的OFFICIAL)
<3.拉取镜像
docker pull [镜像名字]:[版本号]

如果不指定版本号,那么默认拉取的是最新版本(latest),若想下载具体的版本我们可以进官方网站进行查看,看仓库支持哪些版本的镜像才能拉取
<4.删除镜像
docker rmi [镜像ID]/[镜像名称:版本号] (因为可能有两个相同镜像ID的镜像)

也可以一次性删除所有镜像 docker rmi 'docker images -q'(这个符号是tab上面的那个) (docker images -q是查看所有的镜像ID)
3.容器相关命令
<1.创建容器
创建容器是根据镜像创建的
docker run -it --name=[名字] [镜像名字:版本] /bin/bash

这时我们发现前面的@localhost变成了@e49d89942bda /就说明我们已经进入这个容器了(由Linux操作系统进入容器)
可以使用exit退出容器(又称localhost这个Linux操作系统为宿主机)
<2.查看容器
docker ps [-a]

我们将之前创建的容器退出后,查看容器发现没有,这是因为我们退出了,想要查看历史容器可以使用docker ps -a

<3.进入容器
我们在上面知道使用docker run -it --name=[名字] [镜像名] /bin/bash 的方式创建容器会直接进入容器,那么这个进入容器的命令怎么使用呢?
其实还有另一种创建容器的方式
docker run -id --name=[名字] [镜像名]
使用这种方式创建的容器会在后台运行,要进入容器必须使用进入容器命令
docker exec -it [容器名字] /bin/bash

且退出容器是在后台运行并不会关闭

创建容器时的参数介绍
-i:保持容器运行、-t:为容器重新分配一个终端、-d:以守护(后台)模式运行容器
-it:创建的容器一般称为交互式容器、-id:创建的容器一般称为守护式容器
--name:为创建的容器命名
<4.启动容器
docker start [容器名]

<5.停止容器
docker stop [容器名]

<6.删除容器
docker rm [容器ID/容器名]

删除所有的容器
docker rm 'docker ps -aq'(符号为tab上面的那个)
注意:在运行的容器不能被删除
<7.查看容器信息
docker inspect [容器名]

五.容器的数据卷
1.数据卷的概念以及作用
首先思考这几个问题:
- Docker容器删除后,在容器中产生的数据还在吗?
- Docker容器和外部机器可以直接交换文件吗?
- 容器之间如何进行数据交互?

数据卷:
- 数据卷其实就是宿主机中的一个目录或者文件
- 当容器目录和数据卷目录绑定后,对方的修改操作会立即同步
- 一个数据卷可以被多个容器挂载
- 一个容器可以挂载多个数据卷
数据卷的作用:
- 可以使容器数据持久化
- 外部机器和容器间接通信
- 容器之间数据交换
2.配置数据卷
创建启动容器时,使用-v参数设置数据卷
docker run -it --name=[容器名] -v [宿主机目录]:[容器目录] [镜像名] /bin/bash(centos默认命令)
如果目录不存在会自动创建


接下来我们在宿主机的data文件下创建一个文件,看看是否能同步到容器中


我们在文件里编写一些内容看看能否进行同步


最后我们删除这个容器看看内容能否还存在于宿主机上

并且我们之后再次挂载容器那么数据也还在

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

最后让我们来看看两个容器挂载同一个数据卷实现容器间通信(c3与c4)


在c4容器中写入一些内容在a.txt文件中,结果c3中也发送了改变


3.配置数据卷容器
什么是数据卷容器呢?我们经过上面的学习知道多容器之间进行数据交换可以采用多个容器挂载同一个数据卷的办法,但是感觉有点麻烦,那么其实还有一种办法就是数据卷容器

就是有一个容器c3是数据卷容器他和别的容器的区别就是挂载了数据卷,接下来我们只需要让别的容器挂载到这个容器上,那么就实现了多者之间的通信
创建启动c3数据卷容器,使用-v参数设置数据卷
docker run -it --name=c3 -v /volume centos:7 /bin/bash
创建c1、c2容器,使用--volume-from参数设置数据卷
docker run -it --name=c1 --volumes-from c3 centos:7 /bin/bash
docker run -it --name=c2 --volumes-from c3 centos:7 /bin/bash

没有设置左侧的宿主机目录系统会给我们自动分配一个位置,我们也可以使用docker inspect 容器名去看看在什么位置

接着我们创建c1挂载c3容器

最后创建c2挂载c3

接下来我们c3写一个文件,可以看到c1和c2也会出现这个文件


最后在c1中写一些内容在文件中,也可以在c3和c2中看到


六.Docker应用部署
1.MySQL部署
在docker容器中部署MySQL,并通过外部mysql客户端操作MySQL
- 容器内的网络服务和外部机器不能直接通信
- 外部机器和宿主机可以直接通信
- 宿主机和容器可以直接通信
- 当容器中的网络服务需要被外部机器访问时,可以将容器中提供服务的端口映射到宿主机的端口上,外部机器访问宿主机的端口,从而间接访问容器的服务(
端口映射
)

步骤:
- 1.搜索mysql镜像 docker search mysql
- 2.拉取mysql镜像 docker pull mysql:[版本号]
- 3.创建容器、设置端口映射、目录映射
在/root目录下创建mysql目录用于存储mysql的数据信息
mkdir ~/mysql cd ~/mysql
docker run -id \
-p 3306:3306 \
--name=c_mysql \
-v $PWD/conf:/etc/mysql/conf.d \
-v $PWD/logs:/logs \
-v $PWD/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql

接着我们创建一个新的db1库

在本地连接看看

在sqlyog里的db1库里创建一个user表

在docker里也能查询到

这样我们就部署mysql成功了
2.部署tomcat
步骤还是一样
- 1.搜索tomcat镜像 docker search tomcat
- 2.拉取mysql镜像 docker pull tomcat
- 3.创建容器、设置端口映射、目录映射
在/root目录下创建tomcat目录用于存储tomcat的数据信息
mkdir ~/tomcat
cd ~/tomcat
docker run -id --name=c_tomcat \
-p 8080:8080 \
-v $PWD:/usr/local/tomcat/webapps \
tomcat

接着我们给tomcat中创建一个demo的文件夹也就是项目,然后添加一个index.html,里面的内容是Hello Tomcat Docker


接着通过url进行访问

这样我们的tomcat就部署成功了
七.dockerfile 镜像原理
首先我们需要了解以下知识点:
- Linux文件系统由bootfs和rootfs两部分组成
- bootfs:包含bootloader(引导加载程序)和kernel(内核)
- rootfs:root文件系统,包含的就是典型Linux系统中的/dev、/proc、/etc等标准目录和文件
- 不同版本的Linux发行版的bootfs基本一样,而rootfs不同,比如ubuntu、centos

接下来我们思考一个问题:
为什么docker中的一个centos镜像只有200MB,而一个centos操作系统的iso文件需要几个G
docker中的Tomcat镜像需要500MB,而一个Tomcat安装包只要70多MB
这就要引出我们的镜像原理
- Docker镜像是由特殊的文件系统叠加而成的
- 最低端是bootfs,使用宿主机的bootfs
- 第二层是root文件系统的rootfs,称为base image
- 然后在这两个的基础上,往上可以叠加其他的镜像文件
- 统一的文件系统技术能够将不同的层整合成一个文件系统,为这些层提供一个统一的视角,这样就隐藏了多层的存在,在用户的视角看,就存在一个文件系统
- 一个镜像可以放在另一个镜像的上面,位于下面的镜像称为父镜像,最底部的称为基础镜像
- 当从一个镜像启动容器时,docker会在最顶层加载一个读写文件系统作为容器

那么就可以解答上面的问题了:
centos的镜像文件包含bootfs和rootfs,而docker的centos镜像服用操作系统的bootfs,只有rootfs和其他镜像层
由于docker中镜像是分层的,Tomcat虽然只有70多MB,但也需要依赖父镜像和基础镜像,所以对外暴露的Tomcat镜像大小有500多MB