初识Docker
项目部署的问题
大型项目组件较多,运行环境也较为复杂,部署时会碰到一些问题
依赖关系复杂,容易出现兼容性问题
开发、测试、生产环境有差异

Docker如何解决依赖的兼容问题的?
将应用的Libs (函数库)、Deps (依赖)配置与应用一起打包
将每个应用放到一个隔离容器去运行,避免互相干扰

内核与硬件交互,提供操作硬件的指令,系统应用封装内核指令为函数,便于程序员调用用户程序基于系统函数库实现功能

Ubuntu和Centos都是基于Linux内核,只是系统应用不同,提供的函数库有差异

Docker如何解决不同系统环境的问题?
Docker将用户程序与所需要调用的系统(比如Ubuntu)函数库一起打包
Docker运行到不同操作系统时,直接基于打包的库函数,借助于操作系统的Linux内核来运行

Docker如何解决大型项目依赖关系复杂,不同组件依赖的兼容性问题?
Docker允许开发中将应用、依赖、函数库、配置一起打包,形成可移植镜像
Docker应用运行在容器中,使用沙箱机制,相互隔离
Docker如何解决开发、测试、生产环境有差异的问题?
Docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内
核,因此可以在任意Linux操作系统上运行
总结
Docker是一个快速交付应用、运行应用的技术:
1.可以将程序及其依赖、运行环境一起打包为一个镜像可以迁移到任意Linux操作系统
2.运行时利用沙箱机制形成隔离容器,各个应用互不干扰
3.启动、移除都可以通过一行命令完成,方便快捷
Docker与虚拟机
虚拟机(virtual machine)是在操作系统中模拟硬件设备,然后运行另一个操作系统,比如在 Windows 系统里面运行Ubuntu 系统,这样就可以运行任意的Ubuntu应用了

Docker和虚拟机的差异:
docker是一个系统进程;虚拟机是在操作系统中的操作系统
docker体积小、启动速度快、性能好;虚拟机体积大、启动速度慢、性能一般
镜像和容器
镜像(lmage) :Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像.
容器(Container):镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器做隔离,对外不可见。

Docker和DockerHub
DockerHub: DockerHub是一个Docker镜像的托管平台。这样的平台称为Docker Registry。国内也有类似于DockerHub 的公开服务,比如 网易云镜像服务、阿里云镜像库等

docker架构
Docker是一个CS架构的程序,由两部分组成:
服务端(server): Docker守护进程,负责处理Docker指令,管理镜像、容器等
客户端(client): 通过命令或RetAPI向Docker服务端发送指令。可以在本地或远程向服务端发送指令

安装Docker
企业部署一般都是采用Linux操作系统,而其中又数CentOs发行版占比最多,因此我们在entOS下安装Docker。
Docker 分为 CE和EE 两大版本。CE 即社区版(免费,支持周期7个月),EE 即企业版强调安全,付费使用,支持周期 24 个月。
Docker CE分为 stable test 和nightly 三个更新频道
官方网站上有各种环境下的安装指南,这里主要介绍 Docker CE在Centos上的安装
Docker CE 支持64 位版本 Centos7,并且要求内核版本不低于 3.10,Centos 7 满足最低内核的要求,所以我们在Centos 7安装Docker。
如果之前安装过旧版本的Docker,可以使用下面命令卸载:

首先需要大家虚拟机联网,安装yum工具

然后更新本地镜像源

然后输入命令

启动docker
Docker应用需要用到各种端口,逐一去修改防火墙设置。非常麻烦,因此建议大家直接关闭防火墙!
启动docker前,一定要关闭防火墙后!!
启动docker前,一定要关闭防火墙后!!
启动docker前,一定要关闭防火墙后!!

通过命令启动docker

然后输入命令,可以查看docker版本:

先敲入关闭防火墙的命令,再查看防火墙状态,确认为dead,然后敲入启动docker命令,启动docker

启动docker后,可敲入查看docker状态指令查看其状态是否为运行状态

配置镜像
docker官方镜像仓库网速较差,我们需要设置国内镜像
配置镜像加速器
针对Docker客户端版本大于 1.10.0 的用户
您可以通过修改daemon配置文件 /etc/docker/daemon.json 来使用加速器

使用Docker
镜像相关命令
镜像名称一般分两部分组成:[repository]:[tag]
在没有指定tag时,默认是latest,代表最新版本的镜像

镜像操作命令

案例:从DockerHub中拉取一个nginx镜像并查看
1.首先去镜像仓库搜索nginx镜像,比如DackerHub:


2.根据查看到的镜像名称,拉取自己需要的镜像
docker pull nginx命令,从DackerHub拉取nginx镜像,并且默认tag版本为latest
3.通过命令: docker images 查看拉取到的镜像

案例:利用docker save将nginx镜像导出磁盘,然后再通过load加载回来
docker save --help 查看该命令的语法,然后将nginx镜像保存为一个名为nginx.tar的压缩包,ll命令可查看当前目录的文件信息,发现nginx.tar已经被创建好。

先将docker中已经存在的nginx镜像删除,然后再查看docker中镜像,发现目前已经没有nginx镜像了

将原本的nginx镜像删除后,再用docker load -i nginx.tar命令,把nginx.tar压缩包加载为nginx镜像,再docker images命令查看docker中的镜像,发现nginx镜像又被创建了出来。

容器相关命令

案例:创建运行一个Nginx容器
去docker hub查看Nginx的容器运行命令

docker run --name containerName -p 80:80 -d nginx 查找到该命令后,对该命令进行解读

运行该命令创建nginx容器并命名为mn,docker ps 查看当前所有运行中的容器及其状态

该mn容器在启动中,我们访问该宿主机ip以及对应的端口

nginx可以访问到,说明容器成功运行

docker logs mn命令,我们可以查看mn容器的运行日志

docker logs -f mn,可持续的查看日志

案例:进入Nginx容器,修改HTML文件内容,添加"传智教育欢迎您"
1.进入容器。进入我们刚刚创建的nginx容器的命令为


在DackerHub查到nginx镜像中,html的位置

2.进入nginx的HTML所在目录 /usr/share/nginx/html

3.修改indexhtml的内容

修改后,再次访问宿主机ip以及对应端口,发现页面已经更改

数据卷
容器与数据耦合的问题

**数据卷(volume)**是一个虚拟目录,指向宿主机文件系统中的某个目录。

数据卷操作的基本语法如下:

上一个案例,我们先docker volume create html命令在docker中创建一个html的数据卷,并docker volume ls命令查看是否创建好

docker volume inspect html命令可查看该数据卷绑定的具体位置

数据卷的作用:
将容器与数据分离,解耦合,方便操作容器内数据,保证数据安全
挂载数据卷
我们在创建容器时,可以通过-v参数来挂载一个数据卷到某个容器目录

案例:创建一个nginx容器,修改容器内的html目录内的index.html内容
需求说明:上个案例中,我们进入nginx容器内部,已经知道nginx的html目录所在位置usr/share/nginx/html,我们需要把这个目录挂载到html这个数据卷上,方便操作其中的内容
1.创建容器并挂载数据卷到容器内的HTML目录

2.进入html数据卷所在位置,并修改HTML内容
查询html数据卷的信息,查找到该数据卷实际的位置,在宿主机直接进入到该文件目录,使用vscode等高级的编辑器直接打开要修改的页面文件进行修改


修改保存后,再次访问该宿主机ip以及该容器的端口,发现以及修改成功

案例:创建并运行一个MySOL容器,将宿主机目录直接挂载到容器

将mysql.tar压缩文件加载为镜像

docker images 查看所有镜像,发现mysql镜像已经被创建

创建data和conf目录,并将提前准备的hmy.cnf放到conf目录下

在DackerHub上查看配置文件conf在mysql镜像中的位置,方便我们一会将我们本地自己创建的那个conf目录挂载到这个位置

将我们本地自己创建的data目录挂载和自己创建的conf目录下的hmy.cnf文件都挂载到mysql镜像中对应的位置,执行下面的创建mysql容器命令

执行该命令创建mysql容器

docker ps命令查看当前所有启动的容器,发现mysql容器已经被创建

此时,我们打开我们本地自己创建的data目录,因为其已经挂载到了mysql容器中对应位置的data目录,所以此时容器内的data目录内容已经出现在了我们自己本地创建的data目录中。对这些内容操作即是对容器的的目录内容进行操作。

数据卷挂载的方式对比
挂载数据卷我们不知道具体的本地文件位置,但是不麻烦,挂载自己创建的文件目录与文件虽然麻烦些,但是可以自定义具体的位置。数据卷挂载耦合度低,由docker来管理目录,但是
目录较深,不好找。目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看。

自定义镜像
镜像结构
镜像是分层结构,每一层称为一个Layer

什么是Dockerfile
Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。

案例:基于Ubuntu镜像构建一个新镜像,运行一个java项目

Dockerfile文件内容

创间一个docker-demo文件夹并进入

将提前准备好的项目jar包和jdk.tar.gz以及Dockerfile三个文件放入这个目录中

然后再这个目录中执行docker build -t javaweb:1.0 . 命令,自定义创建一个镜像名为javaweb:1.0

docker images命令查看镜像是否被创建,然后执行docker run --name web -p 8090:8090 -d javaweb:1.0命令,将该镜像启动为一个名字为web的容器

访问宿主机ip以及该容器对应的端口,发现可以访问,容器启动成功。

如果每创建一个镜像,都需要执行这么多命令,是很复杂的,而且可以发现基础镜像ubuntu和jdk这些是每个镜像都需要配的,我们可以把这个提取出成一个单独的镜像,让命令更简单化。

案例:基于java:8-alpine镜像,将一个Java项目构建为镜像

将上述Dockerfile文件简化为如下所示。

总结
1.Dockerfile的本质是一个文件,通过指令描述镜像的构建过程
2.Dockerfile的第一行必须是FROM,从一个基础镜像来构建
3.基础镜像可以是基本操作系统,如ubuntu。也可以是其他人制作好的镜像,例如:java:8-alpine
什么是DockerCompose
Docker Compose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器!Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。

上述Compose文件内容等价于执行下面的这些指令

CentOS7安装DockerCompose

如果下载速度较慢,或者下载失败,可以使用课前资料提供的docker-compose文件

上传到/usr/local/bin/目录也可以。
修改文件权限:

将下载好的docker-compose放到/usr/local/bin/目录,进入该目录执行上述修改权限的命令

Base自动补全命令

DockerCompose有什么作用?
帮助我们快速部署分布式应用,无需一个个微服务去构建镜像和部署。
案例:将之前学习的cloud-demo微服务集群利用DockerCompose部署
实现思路如下:
1.查看课前资料提供的cloud-demo文件夹,里面已经编写好了docker-compose文件

每个目录中都有已经编写好的Dockerfile文件

内容都是为了构建该模块为一个镜像

docker-compose.yml文件内容大概如下,都是为了将各个镜像启动为容器

2.修改自己的cloud-demo项月,将数据库、nacos地址都命名为docker-compose中的服务名
user-service模块中,nacos的地址修改

user-service模块中,连接数据库地址修改

order-service模块中,连接数据库地址修改

gateway模块中,nacos的地址修改

3.使用maven打包工具,将项目中的每个微服务都打包为app.jar
每个模块中的maven依赖配置下,打包为app.jar

打包

4.将打包好的app.jar拷贝到cloud-demo中的每一个对应的子目录中

5.将cloud-demo上传至虚拟机,利用 docker-compose up -d 来部署

如果启动有些问题,可以用下面的命令重启这几个容器

访问对应的ip地址用网关对外暴露的端口10010,发现可以执行,说明项目部署完成

Docker镜像仓库
常见镜像仓库服务
镜像仓库( Docker Registry ) 有公共的和私有的两种形式:
公共仓库:例如Docker官方的 Docker Hub,国内也有一些云服务商提供类似于 Docker Hub 的公开服务,比如网易云镜像服务、DaoCloud 镜像服务、阿里云镜像服务等。
除了使用公开仓库外,用户还可以在本地搭建私有 Docker Registry。企业自己的镜像最好是采用私有DockerRegistry来实现
简化版镜像仓库
Docker官方的Docker Registry是一个基础版本的Docker镜像仓库,具备仓库管理的完整功能,但是没有图形化界面。
搭建方式比较简单,命令如下:

带有图形化界面版本
使用DockerCompose部署带有图象界面的DockerRegistry,命令如下

配置Docker信任地址
我们的私服采用的是http协议,默认不被Docker信任,所以需要做一个配置


docker-compose.yml的内容为

执行

访问对应地址,可以访问

在私有镜像仓库推送或拉取镜像
