Docker实用篇
    1.初识Docker
    1.1.什么是Docker
    微服务虽然具备各种各样的优势,但服务的拆分通用给部署带来了很大的麻烦。

    • 分布式系统中,依赖的组件非常多,不同组件之间部署时往往会产生一些冲突。
    • 在数百上千台服务中重复部署,环境不一定一致,会遇到各种问题

    1.1.1.应用部署的环境问题
    大型项目组件较多,运行环境也较为复杂,部署时会碰到一些问题:

    • 依赖关系复杂,容易出现兼容性问题
    • 开发、测试、生产环境有差异

    Docker实用篇 - 图1
    例如一个项目中,部署时需要依赖于node.js、Redis、RabbitMQ、MySQL等,这些服务部署时所需要的函数库、依赖项各不相同,甚至会有冲突。给部署带来了极大的困难。
    1.1.2.Docker解决依赖兼容问题
    而Docker确巧妙的解决了这些问题,Docker是如何实现的呢?
    Docker为了解决依赖的兼容问题的,采用了两个手段:

    • 将应用的Libs(函数库)、Deps(依赖)、配置与应用一起打包
    • 将每个应用放到一个隔离容器去运行,避免互相干扰

    Docker实用篇 - 图2这样打包好的应用包中,既包含应用本身,也保护应用所需要的Libs、Deps,无需再操作系统上安装这些,自然就不存在不同应用之间的兼容问题了。
    虽然解决了不同应用的兼容问题,但是开发、测试等环境会存在差异,操作系统版本也会有差异,怎么解决这些问题呢?
    1.1.3.Docker解决操作系统环境差异
    要解决不同操作系统环境差异问题,必须先了解操作系统结构。以一个Ubuntu操作系统为例,结构如下:
    Docker实用篇 - 图3
    结构包括:

    • 计算机硬件:例如CPU、内存、磁盘等
    • 系统内核:所有Linux发行版的内核都是Linux,例如CentOS、Ubuntu、Fedora等。内核可以与计算机硬件交互,对外提供内核指令,用于操作计算机硬件。
    • 系统应用:操作系统本身提供的应用、函数库。这些函数库是对内核指令的封装,使用更加方便。

    应用于计算机交互的流程如下:
    1)应用调用操作系统应用(函数库),实现各种功能
    2)系统函数库是对内核指令集的封装,会调用内核指令
    3)内核指令操作计算机硬件
    Ubuntu和CentOSpringBoot都是基于Linux内核,无非是系统应用不同,提供的函数库有差异:
    此时,如果将一个Ubuntu版本的MySQL应用安装到CentOS系统,MySQL在调用Ubuntu函数库时,会发现找不到或者不匹配,就会报错了:
    Docker如何解决不同系统环境的问题?

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

    如图:
    Docker实用篇 - 图4
    1.1.4.小结
    Docker如何解决大型项目依赖关系复杂,不同组件依赖的兼容性问题?

    • Docker允许开发中将应用、依赖、函数库、配置一起打包,形成可移植镜像
    • Docker应用运行在容器中,使用沙箱机制,相互隔离

    Docker如何解决开发、测试、生产环境有差异的问题?

    • Docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内核,因此可以在任意Linux操作系统上运行

    Docker是一个快速交付应用、运行应用的技术,具备下列优势:

    • 可以将程序及其依赖、运行环境一起打包为一个镜像,可以迁移到任意Linux操作系统
    • 运行时利用沙箱机制形成隔离容器,各个应用互不干扰
    • 启动、移除都可以通过一行命令完成,方便快捷

    1.2.Docker和虚拟机的区别
    Docker可以让一个应用在任何操作系统中非常方便的运行。而以前我们接触的虚拟机,也能在一个操作系统中,运行另外一个操作系统,保护系统中的任何应用。
    两者有什么差异呢?
    虚拟机(virtual machine)是在操作系统中模拟硬件设备,然后运行另一个操作系统,比如在 Windows 系统里面运行 Ubuntu 系统,这样就可以运行任意的Ubuntu应用了。
    Docker仅仅是封装函数库,并没有模拟完整的操作系统,如图:
    Docker实用篇 - 图5
    对比来看:
    Docker实用篇 - 图6
    小结:
    Docker和虚拟机的差异:

    • docker是一个系统进程;虚拟机是在操作系统中的操作系统
    • docker体积小、启动速度快、性能好;虚拟机体积大、启动速度慢、性能一般

    1.3.Docker架构
    1.3.1.镜像和容器
    Docker中有几个重要的概念:
    镜像(Image):Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。
    容器(Container):镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器进程做隔离,对外不可见。
    一切应用最终都是代码组成,都是硬盘中的一个个的字节形成的文件。只有运行时,才会加载到内存,形成进程。
    镜像,就是把一个应用在硬盘上的文件、及其运行环境、部分系统函数库文件一起打包形成的文件包。这个文件包是只读的。
    容器呢,就是将这些文件中编写的程序、函数加载到内存中允许,形成进程,只不过要隔离起来。因此一个镜像可以启动多次,形成多个容器进程。
    Docker实用篇 - 图7
    例如你下载了一个QQ,如果我们将QQ在磁盘上的运行文件及其运行的操作系统依赖打包,形成QQ镜像。然后你可以启动多次,双开、甚至三开QQ,跟多个妹子聊天。
    1.3.2.DockerHub
    开源应用程序非常多,打包这些应用往往是重复的劳动。为了避免这些重复劳动,人们就会将自己打包的应用镜像,例如Redis、MySQL镜像放到网络上,共享使用,就像GitHub的代码共享一样。

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

    我们一方面可以将自己的镜像共享到DockerHub,另一方面也可以从DockerHub拉取镜像:
    Docker实用篇 - 图8
    1.3.3.Docker架构
    我们要使用Docker来操作镜像、容器,就必须要安装Docker。
    Docker是一个CS架构的程序,由两部分组成:

    • 服务端(server):Docker守护进程,负责处理Docker指令,管理镜像、容器等
    • 客户端(client):通过命令或RestAPI向Docker服务端发送指令。可以在本地或远程向服务端发送指令。

    如图:Docker实用篇 - 图9
    1.3.4.小结
    镜像:

    • 将应用程序及其依赖、环境、配置打包在一起

    容器:

    • 镜像运行起来就是容器,一个镜像可以运行多个容器

    Docker结构:

    • 服务端:接收命令或远程请求,操作镜像或容器
    • 客户端:发送命令或者请求到Docker服务端

    DockerHub:

    • 一个镜像托管的服务器,类似的还有阿里云镜像服务,统称为DockerRegistry

    1.4.安装Docker
    Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月。
    Docker CE 分为 stable test 和 nightly 三个更新频道。
    官方网站上有各种环境下的 安装指南,这里主要介绍 Docker CE 在 CentOS上的安装。
    1)更新yum包
    yum update
    2)安装需要的软件包
    yum install -y yum-utils device-mapper-persistent-data lvm2
    3)设置yum源(阿里仓库)
    yum-config-manager —add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    4)查看远程仓库中所有docker版本
    yum list docker-ce —showduplicates | sort -r
    5)安装docker
    yum install docker-ce #安装最新版
    yum install docker-ce-20.10.1-3.el7 #安装指定版本(推荐安装此方式)
    如需指定版本,则使用如下命令 yum install 例如:sudo yum install docker-ce-17.12.0.ce
    6)修改Docker远程仓库
    Docker的使用过程中,需要从远程仓库下载镜像,但是默认为国外网站,所以在下载时会出现下载连接超时导致下载失败,因此需要将远程仓库修改为国内镜像仓库
    本次使用阿里云镜像
    登录阿里云,进入 “容器镜像服务” 控制台
    容器镜像服务:https://www.aliyun.com/product/acr
    注册后,可以在“镜像工具-镜像加速器” 来获得个人的 docker 加速链接地址,地址找到后,执行下面的命令:
    #创建目录地址
    mkdir -p /etc/docker
    #创建 daemon 文件
    vi /etc/docker/daemon.json
    在 daemon.json 文件中添加下面内容:
    {
    “registry-mirrors”: [“自己个人的docker 加速地址”]
    }
    6)重新启动服务
    systemctl daemon-reload
    systemctl restart docker
    执行命令查看结果
    docker info
    7)其他操作
    Docker应用需要用到各种端口,逐一去修改防火墙设置。非常麻烦,因此建议大家直接关闭防火墙!
    启动docker前,一定要关闭防火墙!!
    启动docker前,一定要关闭防火墙!!
    启动docker前,一定要关闭防火墙!!
    # 关闭
    systemctl stop firewalld
    # 禁止开机启动防火墙
    systemctl disable firewalld
    通过命令启动docker:
    systemctl start docker # 启动docker服务
    systemctl stop docker # 停止docker服务
    systemctl restart docker # 重启docker服务
    然后输入命令,可以查看docker版本:
    docker -v
    1.5 Docker 自动补全
    yum install -y bash-completion
    source /usr/share/bash-completion/bash_completion
    source /usr/share/bash-completion/completions/docker
    2.Docker的基本操作
    2.1.镜像操作
    2.1.1.镜像名称
    首先来看下镜像的名称组成:

    • 镜名称一般分两部分组成:[repository]:[tag]。
    • 在没有指定tag时,默认是latest,代表最新版本的镜像

    如图:
    Docker实用篇 - 图10
    这里的mysql就是repository,5.7就是tag,合一起就是镜像名称,代表5.7版本的MySQL镜像。
    2.1.2.镜像命令
    常见的镜像操作命令如图:
    Docker实用篇 - 图11
    2.1.3.案例1-拉取、查看镜像
    需求:从DockerHub中拉取一个nginx镜像并查看
    1)首先去镜像仓库搜索nginx镜像,比如DockerHub:
    2)根据查看到的镜像名称,拉取自己需要的镜像,通过命令:docker pull nginx
    3)通过命令:docker images 查看拉取到的镜像
    2.1.4.案例2-保存、导入镜像
    需求:利用docker save将nginx镜像导出磁盘,然后再通过load加载回来
    1)利用docker xx —help命令查看docker save和docker load的语法
    例如,查看save命令用法,可以输入命令:
    docker save —help
    结果:
    命令格式:
    docker save -o [保存的目标文件名称] [镜像名称]
    2)使用docker save导出镜像到磁盘
    运行命令:
    docker save -o nginx.tar nginx:latest
    结果如图:
    3)使用docker load加载镜像
    先删除本地的nginx镜像:
    docker rmi nginx:latest
    然后运行命令,加载本地文件:
    docker load -i nginx.tar
    结果:
    Docker实用篇 - 图12
    2.1.5.练习
    需求:去DockerHub搜索并拉取一个Redis镜像
    目标:
    1)去DockerHub搜索Redis镜像
    2)查看Redis镜像的名称和版本
    3)利用docker pull命令拉取镜像
    4)利用docker save命令将 redis:latest打包为一个redis.tar包
    5)利用docker rmi 删除本地的redis:latest
    6)利用docker load 重新加载 redis.tar文件
    2.2.容器操作
    2.2.1.容器相关命令
    容器操作的命令如图:
    Docker实用篇 - 图13
    容器保护三个状态:

    • 运行:进程正常运行
    • 暂停:进程暂停,CPU不再运行,并不释放内存
    • 停止:进程终止,回收进程占用的内存、CPU等资源

    其中:

    • docker run:创建并运行一个容器,处于运行状态
    • docker pause:让一个运行的容器暂停
    • docker unpause:让一个容器从暂停状态恢复运行
    • docker stop:停止一个运行的容器
    • docker start:让一个停止的容器再次运行
    • docker rm:删除一个容器

    2.2.2.案例-创建并运行一个容器
    创建并运行nginx容器的命令:
    docker run —name containerName -p 80:80 -d nginx
    命令解读:

    • docker run :创建并运行一个容器
    • —name : 给容器起一个名字,比如叫做mn
    • -p :将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口
    • -d:后台运行容器
    • nginx:镜像名称,例如nginx

    其他命令:
    docker ps:只能查看正在运行容器 /doker ps -a 查看所有容器
    docker rm 容器名称/容器的id : 删除容器
    docker logs -f 容器的名称 :查看容器的运行日志
    这里的-p参数,是将容器端口映射到宿主机端口。
    默认情况下,容器是隔离环境,我们直接访问宿主机的80端口,肯定访问不到容器中的nginx。
    现在,将容器的80与宿主机的80关联起来,当我们访问宿主机的80端口时,就会被映射到容器的80,这样就能访问到nginx了:
    Docker实用篇 - 图14
    2.2.3.案例-进入容器,修改文件(了解)
    需求:进入Nginx容器,修改HTML文件内容,添加“传智教育欢迎您”
    提示:进入容器要用到docker exec命令。
    步骤
    1)进入容器。进入我们刚刚创建的nginx容器的命令为:
    docker exec -it nginx bash
    命令解读:

    • docker exec :进入容器内部,执行一个命令
    • -it : 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互
    • mn :要进入的容器的名称
    • bash:进入容器后执行的命令,bash是一个linux终端交互命令

    2)进入nginx的HTML所在目录 /usr/share/nginx/html
    容器内部会模拟一个独立的Linux文件系统,看起来如同一个linux服务器一样:
    Docker实用篇 - 图15
    nginx的环境、配置、运行文件全部都在这个文件系统中,包括我们要修改的html文件。
    查看DockerHub网站中的nginx页面,可以知道nginx的html目录位置在/usr/share/nginx/html
    我们执行命令,进入该目录:
    cd /usr/share/nginx/html
    查看目录下文件:
    Docker实用篇 - 图16
    3)修改index.html的内容
    容器内没有vi命令,无法直接修改,我们用下面的命令来修改:
    sed -i -e ‘s#Welcome to nginx#传智教育欢迎您#g’ -e ‘s###g’ index.html
    在浏览器访问自己的虚拟机地址,例如我的是:http://192.168.150.101,即可看到结果:
    Docker实用篇 - 图17
    2.2.4.小结
    docker run命令的常见参数有哪些?

    • —name:指定容器名称
    • -p:指定端口映射
    • -d:让容器后台运行

    查看容器日志的命令:

    • docker logs
    • 添加 -f 参数可以持续查看日志

    查看容器状态:

    • docker ps
    • docker ps -a 查看所有容器,包括已经停止的

    2.3.目录挂载
    在之前的nginx案例中,修改nginx的html页面时,需要进入nginx内部。并且因为没有编辑器,修改文件也很麻烦。
    这就是因为容器与数据(容器内文件)耦合带来的后果。
    Docker实用篇 - 图18
    要解决这个问题,必须将数据与容器解耦,这就要用到数据卷了。
    实现数据与容器分离的方式:
    绑定宿主机上的文件夹: 此文件夹自定义
    绑定数据卷: 此文件夹由docker指定
    绑定宿主机上的文件: 自定义文件的位置
    Docker实用篇 - 图19
    2.3.1.什么是数据卷
    数据卷(volume)是一个虚拟目录,指向宿主机文件系统中的某个目录。
    Docker实用篇 - 图20
    一旦完成数据卷挂载,对容器的一切操作都会作用在数据卷对应的宿主机目录了。
    这样,我们操作宿主机的/var/lib/docker/volumes/html目录,就等于操作容器内的/usr/share/nginx/html目录了
    2.3.2.数据集操作命令
    数据卷操作的基本语法如下:
    docker volume [COMMAND]
    docker volume命令是数据卷操作,根据命令后跟随的command来确定下一步的操作:

    • create 创建一个volume
    • inspect 显示一个或多个volume的信息
    • ls 列出所有的volume
    • prune 删除未使用的volume
    • rm 删除一个或多个指定的volume

    2.3.3.创建和查看数据卷
    需求:创建一个数据卷,并查看数据卷在宿主机的目录位置
    ① 创建数据卷
    docker volume create html
    ② 查看所有数据
    docker volume ls
    结果:
    Docker实用篇 - 图21
    ③ 查看数据卷详细信息卷
    docker volume inspect html
    结果:
    Docker实用篇 - 图22
    可以看到,我们创建的html这个数据卷关联的宿主机目录为/var/lib/docker/volumes/html/_data目录。
    小结
    数据卷的作用:

    • 将容器与数据分离,解耦合,方便操作容器内数据,保证数据安全

    数据卷操作:

    • docker volume create:创建数据卷
    • docker volume ls:查看所有数据卷
    • docker volume inspect:查看数据卷详细信息,包括关联的宿主机目录位置
    • docker volume rm:删除指定数据卷
    • docker volume prune:删除所有未使用的数据卷

    2.3.4.挂载数据卷
    我们在创建容器时,可以通过 -v 参数来挂载一个数据卷到某个容器内目录,命令格式如下:
    docker run \
    —name mn \
    -v html:/root/html \
    -p 8080:80
    nginx \
    这里的-v就是挂载数据卷的命令:

    • -v html:/root/htm :把html数据卷挂载到容器内的/root/html这个目录中

    2.3.5.案例-给nginx挂载数据卷
    需求:创建一个nginx容器,修改容器内的html目录内的index.html内容
    分析:上个案例中,我们进入nginx容器内部,已经知道nginx的html目录所在位置/usr/share/nginx/html ,我们需要把这个目录挂载到html这个数据卷上,方便操作其中的内容。
    /etc/nginx/conf.d : 此目录下存放nginx的配置文件(default.conf—->nginx.conf)
    提示:运行容器时使用 -v 参数挂载数据卷
    步骤:
    ① 创建容器并挂载数据卷到容器内的HTML目录
    docker run —name mn -v html:/usr/share/nginx/html -p 80:80 -d nginx
    ② 进入html数据卷所在位置,并修改HTML内容
    # 查看html数据卷的位置
    docker volume inspect html
    # 进入该目录
    cd /var/lib/docker/volumes/html/_data
    # 修改文件
    vi index.html
    2.3.6.案例-给MySQL挂载本地目录
    容器不仅仅可以挂载数据卷,也可以直接挂载到宿主机目录上。关联关系如下:

    • 带数据卷模式:宿主机目录 —> 数据卷 —-> 容器内目录
    • 直接挂载模式:宿主机目录 —-> 容器内目录

    如图:
    Docker实用篇 - 图23
    语法
    目录挂载与数据卷挂载的语法是类似的:

    • -v [宿主机目录]:[容器内目录]
    • -v [宿主机文件]:[容器内文件]

    需求:创建并运行一个MySQL容器,将宿主机目录直接挂载到容器
    实现思路如下:
    1)下载docker仓库中的mysql镜像,版本为5.7
    2)创建目录/tmp/mysql/data
    3)创建目录/tmp/mysql/conf,将课前资料提供的hmy.cnf文件上传到/tmp/mysql/conf
    4)去DockerHub查阅资料,创建并运行MySQL容器,要求:
    ① 挂载/tmp/mysql/data到mysql容器内数据存储目录
    ② 挂载/tmp/mysql/conf/hmy.cnf到mysql容器的配置文件
    ③ 设置MySQL密码
    拉取镜像:
    docker pull mysql:5.6
    进入tmp目录,创建/tmp/mysql/data和/tmp/mysql/conf
    mkdir -p /tmp/mysql/data // 存放生成的数据信息
    mkdir -p /tmp/mysql/conf // 存放共享的配置文件信息
    将课程资料中的hmy.cnf配置文件拷贝到/tmp/mysql/conf



    创建mysql容器,并绑定对应的文件夹和文件:
    docker run \
    —name mysql \
    -e MYSQL_ROOT_PASSWORD=root \
    -p 3306:3306 \
    -d \
    -v /tmp/mysql/data:/var/lib/mysql \
    -v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/my.cnf \
    —privileged \
    mysql:5.7
    ——————————-





    docker run \ // 创建容器
    —name mysql \ // 给容器起名
    -e MYSQL_ROOT_PASSWORD=root \ // 设置root账户密码
    -p 3306:3306 \ // 端口映射
    -d \ // 后台运行
    -v /tmp/mysql/data:/var/lib/mysql \ // 绑定宿主机上的文件夹
    -v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/my.cnf \ // 绑定宿主机上的文件
    —privileged \ // 设置超级管理员远程访问权限
    mysql:5.7 // 镜像名称
    2.3.7.小结
    docker run的命令中通过 -v 参数挂载文件或目录到容器中:

    • -v volume名称:容器内目录
    • -v 宿主机文件:容器内文
    • -v 宿主机目录:容器内目录

    数据卷挂载与目录直接挂载的

    • 数据卷挂载耦合度低,由docker来管理目录,但是目录较深,不好找
    • 目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看

    3.Dockerfile自定义镜像
    常见的镜像在DockerHub就能找到,但是我们自己写的项目就必须自己构建镜像了。
    而要自定义镜像,就必须先了解镜像的结构才行。
    3.1.镜像结构
    镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。
    我们以MySQL为例,来看看镜像的组成结构:
    Docker实用篇 - 图24
    简单来说,镜像就是在系统函数库、运行环境基础上,添加应用程序文件、配置文件、依赖文件等组合,然后编写好启动脚本打包在一起形成的文件。
    我们要构建镜像,其实就是实现上述打包的过程。
    3.2.Dockerfile语法
    构建自定义的镜像时,并不需要一个个文件去拷贝,打包。
    我们只需要告诉Docker,我们的镜像的组成,需要哪些BaseImage、需要拷贝什么文件、需要安装什么依赖、启动脚本是什么,将来Docker会帮助我们构建镜像。
    而描述上述信息的文件就是Dockerfile文件。
    Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。
    Docker实用篇 - 图25
    更新详细语法说明,请参考官网文档: https://docs.docker.com/engine/reference/builder
    3.3.构建Java项目
    3.3.1 基于java8构建Java项目
    虽然我们可以基于Ubuntu基础镜像,添加任意自己需要的安装包,构建镜像,但是却比较麻烦。所以大多数情况下,我们都可以在一些安装了部分软件的基础镜像上做改造。
    例如,构建java项目的镜像,可以在已经准备了JDK的基础镜像基础上构建。
    需求:基于java:8-alpine镜像,将一个Java项目构建为镜像
    实现思路如下:

    • ① 新建一个空的目录,然后在目录中新建一个文件,命名为Dockerfile
    • ② 拷贝课前资料提供的docker-demo.jar到这个目录中
    • ③ 编写Dockerfile文件:
      • a )基于java:8-alpine作为基础镜像
      • b )将app.jar拷贝到镜像中
      • c )暴露端口
      • d )编写入口ENTRYPOINT
        内容如下:

    FROM java:8-alpine
    COPY ./app.jar /tmp/app.jar
    EXPOSE 8090
    ENTRYPOINT java -jar /tmp/app.jar

    • ④ 使用docker build命令构建镜像

    docker build -t javaweb:1.0 .

    • ⑤ 使用docker run创建容器并运行

    docker run —name web -p 8090:8090 -d javaweb:1.0
    最后访问 http://192.168.94.129:8090/hello/count,其中的ip改成你的虚拟机ip
    3.4.小结
    小结:

    1. Dockerfile的本质是一个文件,通过指令描述镜像的构建过程
    2. Dockerfile的第一行必须是FROM,从一个基础镜像来构建
    3. 基础镜像可以是基本操作系统,如Ubuntu。也可以是其他人制作好的镜像,例如:java:8-alpine

    4.Docker-Compose
    Docker Compose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器!
    4.1.初识DockerCompose
    Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。格式如下:
    version: “3.8”
    services:
    mysql:
    image: mysql:5.7.25
    environment:
    MYSQL_ROOT_PASSWORD: 123
    volumes:
    - “/tmp/mysql/data:/var/lib/mysql”
    - “/tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf”
    web:
    build: .
    ports:
    - “8090:8090”
    上面的Compose文件就描述一个项目,其中包含两个容器:

    • mysql:一个基于mysql:5.7.25镜像构建的容器,并且挂载了两个目录
    • web:一个基于docker build临时构建的镜像容器,映射端口时8090

    DockerCompose的详细语法参考官网:https://docs.docker.com/compose/compose-file/
    其实DockerCompose文件可以看做是将多个docker run命令写到一个文件,只是语法稍有差异。
    4.2.安装DockerCompose
    MAC下或者Windows下的Docker自带Compose功能,无需安装。
    Linux下需要通过命令安装:
    # 安装
    curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-`uname -s-uname -m` > /usr/local/bin/docker-compose
    # 修改权限
    chmod +x /usr/local/bin/docker-compose
    ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
    PS:可以使用今天下发资料中的docker-compose文件,将其拷贝到制定目录。
    4.3 构建Java项目和其依赖环境
    4.3.1 导入微服务工程
    工程的基本功能就是统计用户的访问量,代码在资料中,直接解压到没有中文的目录下,使用Idea导入即可。
    并使用 maven 插件对项目进行打包处理,并获得项目的 打包后的 jar 文件。
    4.3.2 编写Dockerfile
    (1)在任意位置创建一个新目录,将app.jar复制到该目录
    (2)在该目录中,新建一个Dockerfile文件,并编写下面的内容:
    FROM java:8-alpine
    COPY ./app.jar /tmp/app.jar
    EXPOSE 9090
    ENTRYPOINT [“java”,”-jar”,”/tmp/app.jar”]
    4.3.3 编写docker-compose
    在刚才的目录中,创建一个docker-compose.yml文件并填写内容:
    version: ‘3’
    services:
    web:
    build: .
    ports:
    - “9090:9090”
    redis:
    image: “redis:6.0”
    此时的结构如下:
    Docker实用篇 - 图26
    命令解读:

    • version:compose的版本
    • services:服务列表,包括两个服务:
      • web:自己写的Java项目
        • build:这个服务镜像是临时构建的,构建目录是当前目录,会利用当前目录的Dockerfile来完成构建。
        • ports:端口映射,对外开放8080端口
      • redis:redis服务

    4.3.4 启动测试
    将刚刚准备好的文件夹上传到Linux的/opt/docker-compose目录:
    Docker实用篇 - 图27
    然后执行命令:
    docker-compose up
    构建完成后,可以看到项目运行的日志信息:
    Docker实用篇 - 图28Docker实用篇 - 图29
    此时,访问浏览器 http://192.168.94.130:9090/hello,可以看到下面的结果:
    Docker实用篇 - 图30
    如果多次访问,这个次数会累加。
    按次CTRL+C后可以停止运行程序,并且Docker运行的容器中也会关闭。
    通过docker-compose up -d命令,可以后台启动,这样就不会显示日志:
    Docker实用篇 - 图31
    通过docker-compose stop 关闭容器
    Docker实用篇 - 图32
    通过docker-compose down关闭容器并删除
    Docker实用篇 - 图33
    4.4 Docker Composer 相关命令(参考)
    docker-compose的相关命令参数:
    通过:docker-compose —help 查看
    [root@localhost docker-demo]# docker-compose —help
    利用Docker来定义和构建一个多容器的应用
    使用方式:
    docker-compose [-f …] [options] [COMMAND] [ARGS…]
    docker-compose -h|—help
    Options:
    -f, —file FILE 指定一个 compose 文件,
    (默认: docker-compose.yml)
    -p, —project-name NAME 指定project名字
    (默认: 目录名称)
    —verbose 显示更多日志
    —log-level LEVEL 日志级别 (DEBUG, INFO, WARNING, ERROR, CRITICAL)
    -v, —version 打印版本并退出
    -H, —host HOST Daemon socket to connect to
    Commands:
    build 构建多个service
    config 校验 Compose 文件,格式是否正确,若正确则显示配置,
    若格式错误显示错误原因
    down 停止并删除 容器, 网络, 镜像, 和 数据卷
    exec 进入一个指定的容器
    help Get help on a command
    images 列出该Compose中包含的各个镜像
    kill 通过发送 SIGKILL 信号来强制停止服务容器
    格式为 docker-compose kill [options] [SERVICE…]
    logs 查看服务容器的输出日志
    格式为 docker-compose logs [options] [SERVICE…]。
    pause 暂停一个容器
    port 打印某个容器端口所映射的公共端口
    ps 列出项目中目前的所有容器
    pull 拉取服务依赖的镜像
    push 推送服务依赖的镜像到 Docker 镜像s仓库
    restart 重启项目中的服务
    rm 删除停止的容器(要先停止容器)
    run 在某个服务上运行指令
    scale 设定某个容器的运行个数
    start 启动多个 services
    stop 停止多个 services
    top 查看各个服务容器内运行的进程。
    unpause 恢复处于暂停状态中的服务。
    up 创建并启动多个service的容器
    version Show the Docker-Compose version information
    5.Docker镜像仓库
    5.1.搭建私有镜像仓库
    5.1.1 简化版镜像仓库
    Docker官方的Docker Registry是一个基础版本的Docker镜像仓库,具备仓库管理的完整功能,但是没有图形化界面。
    搭建方式比较简单,命令如下:
    docker run -d \
    —restart=always \
    —name registry \
    -p 5000:5000 \
    -v registry-data:/var/lib/registry \
    registry
    命令中挂载了一个数据卷registry-data到容器内的/var/lib/registry 目录,这是私有镜像库存放数据的目录。
    访问http://YourIp:5000/v2/_catalog 可以查看当前私有镜像服务中包含的镜像
    5.1.2.带有图形化界面版本
    使用DockerCompose部署带有图象界面的DockerRegistry,命令如下:
    version: ‘3.0’
    services:
    registry:
    image: registry
    volumes:
    - ./registry-data:/var/lib/registry
    ui:
    image: joxit/docker-registry-ui:static
    ports:
    - 8080:80
    environment:
    - REGISTRY_TITLE=传智教育私有仓库
    - REGISTRY_URL=http://registry:5000
    depends_on:
    - registry
    5.1.3.配置Docker信任地址
    我们的私服采用的是http协议,默认不被Docker信任,所以需要做一个配置:
    # 打开要修改的文件
    vi /etc/docker/daemon.json
    # 添加内容:
    “insecure-registries”:[“http://192.168.94.129:5000“]
    修改后重新启动docker环境
    systemctl daemon-reload
    systemctl restart docker
    5.2.推送、拉取镜像
    推送镜像到私有镜像服务必须先tag,步骤如下:
    ① 重新tag本地镜像,名称前缀为私有仓库的地址:192.168.94.129:5000/
    docker tag nginx:latest 192.168.94.129:5000/nginx:1.0
    ② 推送镜像
    docker push 192.168.94.129:5000/nginx:1.0
    ③ 拉取镜像
    docker pull 192.168.94.129:5000/nginx:1.0
    设置容器开启自启
    docker update —restart=always 容器名称
    docker概述:
    容器化部署的方案, 解决大型项目直接的依赖冲突,和兼容性问题,将应用 依赖 函数库 还有配置 打包成一个单独的形成可移植镜像文件
    使用沙箱机制进行相互隔离,使其有自己的环境即可!
    linux的操作系统xentos和ubuntu 会有差异 有些函数库不一定能在所有系统都能使用!
    环境问题最终解决方案 :将linux内核依赖打包进沙箱机制,通过镜像内部的linux内核操作!
    Linux中 docker 有俩个服务:客户端(Client)和服务端(dockerServer)
    Docker和虚拟机的区别:
    虚拟机(virtual machine)是在操作系统中模拟硬件设备,然后运行另一个操作系统,比如在 Windows 系统里面运行 Ubuntu 系统,这样就可以运行任意的Ubuntu应用了。
    Docker仅仅是封装函数库,并没有模拟完整的操作系统
    Docker缺点:不能兼容所有操作系统 不能做到绝对的沙箱隔离!
    systemctl start docker 启动docker
    DockerHub官网搜索查看软件的版本
    docker pull xxx(名称):xxx(版本号,不写默认为最新版)
    docker rmi xxxxID 删除指定docker
    docker images 查看所有已下载的docker
    docker run 镜像启动
    docker pause 容器暂停
    docker unpause 容器启动
    docker stop 容器停止
    docker docker start 开启容器
    docker exec 进入容器
    docker logs 查看日志
    docker ps 查看所有运行的容器以及状态
    docker rm -f -v [ 名称] 结束指定进程

    • docker volume create:创建数据卷
    • docker volume ls:查看所有数据卷
    • docker volume inspect:查看数据卷详细信息,包括关联的宿主机目录位置
    • docker volume rm:删除指定数据卷
    • docker volume prune:删除所有未使用的数据卷
      systemctl start docker 启动docker
      数据卷挂载 创建目录时没有/ 而直接挂载是有/指定具体目录的

    dockerfile 自定义镜像
    将springboot打包成jar包 然后转换成镜像文件 放到docker中运行
    docker-compose是快速构造项目环境的 通过配置可以同时构建很多环境!