资料来源:https://www.bilibili.com/video/BV1gr4y1U7CY?spm_id_from=333.337.search-card.all.click
参考资料:https://blog.csdn.net/qq_39578545/article/details/107741565

一、Docker简介

1、为什么会有Docker

假定您在开发一个尚硅谷的谷粒商城,您使用的是一台笔记本电脑而且您的开发环境具有特定的配置。其他开发人员身处的环境配置也各有不同。您正在开发的应用依赖于您当前的配置且还要依赖于某些配置文件。此外,您的企业还拥有标准化的测试和生产环境,且具有自身的配置和一系列支持文件。您希望尽可能多在本地模拟这些环境而不产生重新创建服务器环境的开销。请问?
您要如何确保应用能够在这些环境中运行和通过质量检测?并且在部署过程中不出现令人头疼的版本、配置问题,也无需重新编写代码和进行故障修复?
答案就是使用容器。Docker之所以发展如此迅速,也是因为它对此给出了一个标准化的解决方案 ——- 系统平滑移植,容器虚拟化技术

环境配置相当麻烦,换一台机器,就要重来一次,费力费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题
image.png
之前在服务器配置一个应用的运行环境,要安装各种软件,就拿尚硅谷电商项目的环境来说,Java/RabbitMQ/MySQL/JDBC驱动包等。安装和配置这些东西有多麻烦就不说了,它还不能跨平台。假如我们是在 Windows 上安装的这些环境,到了 Linux 又得重新装。况且就算不跨操作系统,换另一台同样操作系统的服务器,要移植应用也是非常麻烦的。
传统上认为,软件编码开发/测试结束后,所产出的成果即是程序或是能够编译执行的二进制字节码等(Java为例)。而为了让这些程序可以顺利执行,开发团队也得准备完整的部署文件,让维运团队得以部署应用程式,开发需要清楚的告诉运维部署团队,用的全部配置文件+所有软件环境。不过,即便如此,仍然常常发生部署失败的状况。Docker的出现使得Docker得以打破过去「程序即应用」的观念。透过镜像(images)将作业系统核心除外,运作应用程式所需要的系统环境,由下而上打包,达到应用程式跨平台间的无缝接轨运作

2、Docker理念

Docker是基于Go语言实现的云开源项目
Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次镜像,处处运行”。
image.png
Linux容器技术的出现就解决了这样一个问题,而 Docker 就是在它的基础上发展过来的。将应用打成镜像,通过镜像成为运行在Docker容器上面的实例,而 Docker容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,换到别的机子上就可以一键部署好,大大简化了操作
一句话:解决了运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术

3、容器与虚拟机比较

3.1 容器发展简史

image.png
image.png

3.2 传统虚拟机技术

虚拟机(virtual machine)就是带环境安装的一种解决方案。
它可以在一种操作系统里面运行另一种操作系统,比如在Windows10系统里面运行Linux系统CentOS7。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。这类虚拟机完美的运行了另一套系统,能够使应用程序,操作系统和硬件三者之间的逻辑不变。

Win10 VMWare Centos7 各种cpu、内存网络额配置+各种软件 虚拟机实例

传统虚拟机技术基于安装在主操作系统上的虚拟机管理系统(如:VirtualBox和VMWare等),创建虚拟机(虚拟出各种硬件),在虚拟机上安装有操作系统,在从操作系统中安装部署各种应用。
图片 (2).png
虚拟机的缺点:

  1. 资源占用多
  2. 冗余步骤多
  3. 启动慢

    3.3 容器虚拟化技术

    由于前面虚拟机存在某些缺点,Linux发展出了另一种虚拟化技术:Linux容器(Linux Containers,缩写为 LXC)
    Linux容器是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件。容器提供的镜像包含了应用的所有依赖项,因而在从开发到测试再到生产的整个过程中,它都具有可移植性和一致性。
    Linux 容器不是模拟一个完整的操作系统而是对进程进行隔离。有了容器,就可以将软件运行所需的所有资源打包到一个隔离的容器中。容器与虚拟机不同,不需要捆绑一整套操作系统,只需要软件工作所需的库资源和设置。系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一地运行。
    图片 (2).png
    Docker容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统虚拟机则是在硬件层面实现虚拟化。与传统的虚拟化相比,Docker优势体现为启动速度快、占用体积小

比较了 Docker 和传统虚拟化方式的不同之处:

  1. 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程
  2. 容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
  3. 每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源

图片.png

4、Docker应用场景

  1. 一次构建、随处运行
    1. 更快速的应用交付和部署:传统的应用开发完成后,需要提供一堆安装程序和配置说明文档,安装部署后需根据配置文档进行繁杂的配置才能正常运行。Docker化之后只需要交付少量容器镜像文件,在正式生产环境加载镜像并运行即可,应用安装配置在镜像里已经内置好,大大节省部署配置和测试验证时间
    2. 更便捷的升级和扩缩容:随着微服务架构和Docker的发展,大量的应用会通过微服务方式架构,应用的开发构建将变成搭乐高积木一样,每个Docker容器将变成一块“积木”,应用的升级将变得非常容易。当现有的容器不足以支撑业务处理时,可通过镜像运行新的容器进行快速扩容,使应用系统的扩容从原先的天级变成分钟级甚至秒级。
    3. 更简单的系统运维:应用容器化运行后,生产环境运行的应用可与开发、测试环境的应用高度一致,容器会将应用程序相关的环境和状态完全封装起来,不会因为底层基础架构和操作系统的不一致性给应用带来影响,产生新的BUG。当出现程序异常时,也可以通过测试环境的相同容器进行快速定位和修复。
    4. 更高效的计算资源利用:Docker是内核级虚拟化,其不像传统的虚拟化技术一样需要额外的Hypervisor支持,所以在一台物理机上可以运行很多个容器实例,可大大提升物理服务器的CPU和内存的利用率。
  2. Docker应用场景

image.png

5、Docker下载地址

Docker官网:http://www.Docker.com
Docker Hub官网:https://hub.Docker.com/

二、Docker安装

1、前提说明

  1. CentOS Docker 安装

image.png

  1. 前提条件
    1. 目前,CentOS 仅发行版本中的内核支持 Docker。Docker 运行在CentOS 7 (64-bit)上,要求系统为64位、Linux系统内核版本为 3.8以上,这里选用Centos7.x
  2. 查看自己的内核
    1. uname命令用于打印当前系统相关信息(内核版本号、硬件架构、主机名称和操作系统类型等)。

image.png

2、Docker的基本组成

2.1 镜像(image)

Docker 镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。
它也相当于是一个root文件系统。比如官方镜像 centos:7 就包含了完整的一套 centos:7 最小系统的 root 文件系统。
相当于容器的“源代码”,Docker镜像文件类似于Java的类模板,而Docker容器实例类似于Java中new出来的实例对象。
图片 (2).png

2.2 容器(container)

  1. 从面向对象角度
    1. Docker 利用容器(Container)独立运行的一个或一组应用,应用程序或服务运行在容器里面,容器就类似于一个虚拟化的运行环境,容器是用镜像创建的运行实例。就像是Java中的类和实例对象一样,镜像是静态的定义,容器是镜像运行时的实体。容器为镜像提供了一个标准的和隔离的运行环境,它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台
  2. 从镜像容器角度
    1. 可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

      2.3 仓库(repository)

      仓库(Repository)是集中存放镜像文件的场所

类似于:
Maven仓库,存放各种jar包的地方;
github仓库,存放各种git项目的地方;
Docker公司提供的官方registry被称为Docker Hub,存放各种镜像模板的地方。

仓库分为公开仓库(Public)和私有仓库(Private)两种形式。
最大的公开仓库是 Docker Hub(https://hub.Docker.com/),
存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云 、网易云等

2.4 Docker平台架构图解(入门版)

image.png
Docker工作原理:
Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上, 然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。 容器,是一个运行时环境,就是我们前面说到的集装箱。可以对比mysql演示对比讲解
image.png

2.5 小结

需要正确的理解仓库/镜像/容器这几个概念:
Docker 本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就是image镜像文件。只有通过这个镜像文件才能生成Docker容器实例(类似Java中new出来一个对象)。
image文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。

  1. 镜像文件
    1. image 文件生成的容器实例,本身也是一个文件,称为镜像文件。
  2. 容器实例
    1. 一个容器运行一种服务,当我们需要的时候,就可以通过Docker客户端创建一个对应的运行实例,也就是我们的容器
  3. 仓库

    1. 就是放一堆镜像的地方,我们可以把镜像发布到仓库中,需要的时候再从仓库中拉下来就可以了。

      3、Docker平台架构图解(架构版)

      整体架构及底层通信原理简述:
      Docker 是一个 C/S 模式的架构,后端是一个松耦合架构,众多模块各司其职。
      image.png
      image.png

      4、安装步骤

      CentOS7安装Docker:https://docs.docker.com/engine/install/centos/
  4. 确定你是CentOS7及以上版本:cat /etc/redhat-release

  5. 卸载旧版本:https://docs.docker.com/engine/install/centos/

image.png

  1. yum安装gcc相关
    1. CentOS7能上外网

image.png

  1. yum -y install gcc
  2. yum -y install gcc-c++
    1. 安装需要的软件包
  3. 官网要求

image.png

  1. 执行命令:yum install -y yum-utils
    1. 设置stable镜像仓库
  2. 大坑:
    1. yum-config-manager —add-repo https://download.docker.com/linux/centos/docker-ce.repo
    2. 官网要求:
      1. image.png
      2. 报错: [Errno 14] curl#35 - TCP connection reset by peer [Errno 12] curl#35 - Timeout
  3. 推荐:yum-config-manager —add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

image.png

  1. 更新yum软件包索引:yum makecache fast
  2. 安装DOCKER CE:yum -y install docker-ce docker-ce-cli containerd.io
    1. 官网要求:

image.png

  1. 执行结果

image.png
image.png

  1. 启动docker:systemctl start docker
  2. 测试
    1. docker version
    2. docker run hello-world
  3. 卸载
    1. systemctl stop docker
    2. yum remove docker-ce docker-ce-cli containerd.io
    3. rm -rf /var/lib/docker
    4. rm -rf /var/lib/containerd

image.png

5、阿里云镜像加速

  1. 是什么:https://promotion.aliyun.com/ntms/act/kubernetes.html
  2. 注册一个属于自己的阿里云账户(可复用淘宝账号)
  3. 获得加速器地址连接
    1. 登陆阿里云开发者平台

image.png

  1. 点击控制台

image.png

  1. 选择容器镜像服务

image.png

  1. 获取加速器地址

image.png

  1. 粘贴脚本直接执行
    1. 直接粘 ```java mkdir -p /etc/docker

tee /etc/docker/daemon.json <<-‘EOF’ { “registry-mirrors”: [“https://aa25jngu.mirror.aliyuncs.com“] } EOF

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653485002091-4cd8f0f3-f81b-4907-bdb5-84929c49533c.png#averageHue=%23fefcfc&clientId=u3508c2df-afa2-4&from=paste&height=363&id=uc29b81e6&originHeight=363&originWidth=789&originalType=binary&ratio=1&rotation=0&showTitle=false&size=37657&status=done&style=none&taskId=u8fa9a062-4a44-4656-b0c5-73209a08381&title=&width=789)
  2. 2. 或者分步骤都行
  3. 1. mkdir -p /etc/docker
  4. 2. vim /etc/docker/daemon.json
  5. ```java
  6. #阿里云
  7. {
  8. "registry-mirrors": ["https://{自已的编码}.mirror.aliyuncs.com"]
  9. }
  1. 重启服务器

    1. systemctl daemon-reload
    2. systemctl restart docker

      6、永远的HelloWorld

      启动Docker后台容器(测试运行 hello-world)
      Docker run hello-world
      image.png
      输出这段提示以后,hello world就会停止运行,容器自动终止。
      · run干了什么
      image.png

      7、底层原理

      为什么Docker会比VM虚拟机快
  2. docker有着比虚拟机更少的抽象层

    1. 由于docker不需要Hypervisor(虚拟机)实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
  3. docker利用的是宿主机的内核,而不需要加载操作系统OS内核

    1. 当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。进而避免引寻、加载操作系统内核返回等比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载OS,返回新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返回过程,因此新建一个docker容器只需要几秒钟

    image.png
    图片 (2).png

    三、Docker常用命令

    1、帮助启动类命令

    1. 启动docker: systemctl start docker
    2. 停止docker: systemctl stop docker
    3. 重启docker: systemctl restart docker
    4. 查看docker状态: systemctl status docker
    5. 开机启动: systemctl enable docker
    6. 查看docker概要信息: docker info
    7. 查看docker总体帮助文档: docker —help
    8. 查看docker命令帮助文档: docker 具体命令 —help

      2、镜像命令

  4. docker images

    1. 列出本地主机上的镜像

image.png

  1. 各个选项说明:
    1. REPOSITORY:表示镜像的仓库源
    2. TAG:镜像的标签版本号
    3. IMAGE ID:镜像ID
    4. CREATED:镜像创建时间
    5. SIZE:镜像大小
  2. 同一仓库源可以有多个 TAG版本,代表这个仓库源的不同个版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。如果你不指定一个镜像的版本标签,例如你只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像
    1. OPTIONS说明:
  3. -a :列出本地所有的镜像(含历史映像层)
  4. -q :只显示镜像ID
    1. docker search 某个XXX镜像名字
  5. 网站:https://hub.docker.com
  6. 命令:docker search [OPTIONS] 镜像名字
    1. OPTIONS说明:
      1. —limit : 只列出N个镜像,默认25个
      2. docker search —limit 5 redis

图片 (2).png
image.png

  1. docker pull 某个XXX镜像名字:下载镜像
    1. docker pull 镜像名字[:TAG]
    2. docker pull 镜像名字
      1. 没有TAG就是最新版。等价于 docker pull 镜像名字:latest
      2. docker pull ubuntu

image.png

  1. docker system df 查看镜像/容器/数据卷所占的空间

image.png

  1. docker rmi 某个XXX镜像名字ID
    1. 删除镜像
    2. 删除单个: docker rmi -f 镜像ID
    3. 删除多个:docker rmi -f 镜像名1:TAG 镜像名2:TAG
    4. 删除全部:docker rmi -f $(docker images -qa)
  2. 面试题:谈谈docker虚悬镜像是什么?
    1. 仓库名、标签都是的镜像,俗称虚悬镜像dangling image
    2. image.png
  3. 思考
  4. 结合我们Git的学习心得,大家猜猜是否会有 docker commit /docker push??

    3、容器命令

    有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)
    Docker pull centos
    Docker pull ubuntu
    image.png

  5. 新建+启动容器:docker run [OPTIONS] IMAGE [COMMAND] [ARG…]

    1. OPTIONS说明 ```java OPTIONS说明(常用):有些是一个减号,有些是两个减号

—name=”容器新名字” 为容器指定一个名称; -d: 后台运行容器并返回容器ID,也即启动守护式容器(后台运行);

-i:以交互模式运行容器,通常与 -t 同时使用; -t:为容器重新分配一个伪输入终端,通常与 -i 同时使用; 也即启动交互式容器(前台有伪终端,等待交互);

-P: 随机端口映射,大写P -p: 指定端口映射,小写p

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653489385523-ac33dc83-6f37-4336-b453-ea266522cb66.png#averageHue=%23d1dcb9&clientId=u3508c2df-afa2-4&from=paste&height=269&id=u0a95a008&originHeight=269&originWidth=836&originalType=binary&ratio=1&rotation=0&showTitle=false&size=124113&status=done&style=none&taskId=u400f77fb-6fc1-4ffe-a652-7265c915c2e&title=&width=836)
  2. 2. 启动交互式容器(前台命令行)
  3. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653489403306-5eae925e-4e3d-4cd7-a29b-304713d8e978.png#averageHue=%23f5f2f2&clientId=u3508c2df-afa2-4&from=paste&height=273&id=ue15169b8&originHeight=273&originWidth=887&originalType=binary&ratio=1&rotation=0&showTitle=false&size=32647&status=done&style=none&taskId=u90c2b4f4-6587-45c1-a246-dcddd93b9f4&title=&width=887)
  4. ```java
  5. #使用镜像centos:latest以交互模式启动一个容器,在容器内执行/bin/bash命令。
  6. docker run -it centos /bin/bash
  7. 参数说明:
  8. -i: 交互式操作。
  9. -t: 终端。
  10. centos : centos 镜像。
  11. /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。
  12. 要退出终端,直接输入 exit:
  1. 列出当前所有正在运行的容器:docker ps [OPTIONS]
    1. OPTIONS说明(常用):
      1. -a :列出当前所有正在运行的容器+历史上运行过的
      2. -l :显示最近创建的容器
      3. -n:显示最近n个创建的容器
      4. -q :静默模式,只显示容器编号
  2. 退出容器:
    1. exit:run进去容器,exit退出,容器停止
    2. ctrl+p+q:run进去容器,ctrl+p+q退出,容器不停止
  3. 启动已停止运行的容器:docker start 容器ID或者容器名
  4. 重启容器:docker restart 容器ID或者容器名
  5. 停止容器:docker stop 容器ID或者容器名
  6. 强制停止容器:docker kill 容器ID或容器名
  7. 删除已停止的容器:docker rm 容器ID
    1. 一次性删除多个容器实例
      1. docker rm -f $(docker ps -a -q)
      2. docker ps -a -q | xargs docker rm

重要:
有镜像才能创建容器,这是根本前提(下载一个Redis6.0.8镜像演示)

  1. 启动守护式容器(后台服务器)
    1. 在大部分的场景下,我们希望 docker 的服务是在后台运行的,我们可以过 -d 指定容器的后台运行模式
    2. docker run -d 容器名 ```java

      使用镜像centos:latest以后台模式启动一个容器

      docker run -d centos

问题:然后docker ps -a 进行查看, 会发现容器已经退出 很重要的要说明的一点: Docker容器后台运行,就必须有一个前台进程. 容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的。

这个是docker的机制问题,比如你的web容器,我们以nginx为例,正常情况下, 我们配置启动服务只需要启动响应的service即可。例如service nginx start 但是,这样做,nginx为后台进程模式运行,就导致docker前台没有运行的应用, 这样的容器后台启动后,会立即自杀因为他觉得他没事可做了. 所以,最佳的解决方案是,将你要运行的程序以前台进程的形式运行, 常见就是命令行模式,表示我还有交互操作,别中断,O(∩_∩)O哈哈~

  1. 3. redis 前后台启动演示case
  2. 1. 前台交互式启动: docker run -it redis:6.0.8
  3. 2. 后台守护式启动:docker run -d redis:6.0.8
  4. 2. 查看容器日志:docker logs 容器ID
  5. 3. 查看容器内运行的进程:docker top 容器ID
  6. 4. 查看容器内部细节:docker inspect 容器ID
  7. 5. 进入正在运行的容器并以命令行交互
  8. 1. docker exec -it 容器ID bashShell
  9. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653489269822-a74de243-fc6a-4ab9-bdee-a89dff4785fd.png#averageHue=%23f4f1f1&clientId=u3508c2df-afa2-4&from=paste&height=105&id=u20a1e104&originHeight=180&originWidth=1170&originalType=binary&ratio=1&rotation=0&showTitle=false&size=29417&status=done&style=none&taskId=u443ff96d-0313-4df9-8ff4-ddcab518114&title=&width=684)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653489275430-d9d43e51-2142-44f9-830c-a4b850d3cda0.png#averageHue=%23fefafa&clientId=u3508c2df-afa2-4&from=paste&height=273&id=u2c800726&originHeight=364&originWidth=895&originalType=binary&ratio=1&rotation=0&showTitle=false&size=56048&status=done&style=none&taskId=u95afa05e-a5e6-4a17-9186-028214a68c1&title=&width=672)
  10. 2. 重新进入docker attach 容器ID
  11. 3. 推荐大家使用 docker exec 命令,因为退出容器终端,不会导致容器的停止。
  12. 4. 进入redis服务
  13. 1. docker exec -it 容器ID /bin/bash
  14. 2. docker exec -it 容器ID redis-cli
  15. 3. 一般用-d后台启动的程序,再用exec进入对应容器实例
  16. 6. 从容器内拷贝文件到主机上
  17. 1. 容器→主机
  18. 2. docker cp 容器ID:容器内路径 目的主机路径
  19. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653489132448-0ba0fa68-9345-4b9a-897c-b7fb699718a2.png#averageHue=%23f3eded&clientId=u3508c2df-afa2-4&from=paste&height=123&id=ud6deae06&originHeight=207&originWidth=1154&originalType=binary&ratio=1&rotation=0&showTitle=false&size=36785&status=done&style=none&taskId=u0d4aaddf-4ba5-4a4f-957b-29750e778f3&title=&width=686)<br />公式:docker cp 容器ID:容器内路径 目的主机路径
  20. 7. 导入和导出容器
  21. 1. export 导出容器的内容留作为一个tar归档文件[对应import命令]
  22. 2. import tar包中的内容创建一个新的文件系统再导入为镜像[对应export]
  23. 3. 案例
  24. 1. docker export 容器ID > 文件名.tar
  25. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653489173307-d88eda52-f8ff-4020-a58d-ae3e64b77fad.png#averageHue=%23fef9f9&clientId=u3508c2df-afa2-4&from=paste&height=289&id=u06313371&originHeight=489&originWidth=1070&originalType=binary&ratio=1&rotation=0&showTitle=false&size=102773&status=done&style=none&taskId=u64f57c00-f2e0-4115-8603-e3f25f6dbf6&title=&width=633)
  26. 2. cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
  27. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653489189686-613b0e9b-b3f9-47a5-9a09-171be6bda68a.png#averageHue=%23fefbfb&clientId=u3508c2df-afa2-4&from=paste&height=283&id=ubc154e97&originHeight=488&originWidth=1070&originalType=binary&ratio=1&rotation=0&showTitle=false&size=108598&status=done&style=none&taskId=u6737390c-64c2-43d5-9776-7e27cc98ee2&title=&width=621)
  28. <a name="nTZsg"></a>
  29. ## 4、小结
  30. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653489462234-d59daa89-62f7-403f-a64b-6f1a5799afc5.png#averageHue=%232873a3&clientId=u3508c2df-afa2-4&from=paste&height=638&id=u16418d4d&originHeight=638&originWidth=900&originalType=binary&ratio=1&rotation=0&showTitle=false&size=132944&status=done&style=none&taskId=udd399e1a-f882-49c1-a711-4ec2b860f40&title=&width=900)
  31. ```java
  32. attach Attach to a running container # 当前 shell 下 attach 连接指定运行镜像
  33. build Build an image from a Dockerfile # 通过 Dockerfile 定制镜像
  34. commit Create a new image from a container changes # 提交当前容器为新的镜像
  35. cp Copy files/folders from the containers filesystem to the host path #从容器中拷贝指定文件或者目录到宿主机中
  36. create Create a new container # 创建一个新的容器,同 run,但不启动容器
  37. diff Inspect changes on a container's filesystem # 查看 docker 容器变化
  38. events Get real time events from the server # 从 docker 服务获取容器实时事件
  39. exec Run a command in an existing container # 在已存在的容器上运行命令
  40. export Stream the contents of a container as a tar archive # 导出容器的内容流作为一个 tar 归档文件[对应 import ]
  41. history Show the history of an image # 展示一个镜像形成历史
  42. images List images # 列出系统当前镜像
  43. import Create a new filesystem image from the contents of a tarball # 从tar包中的内容创建一个新的文件系统映像[对应export]
  44. info Display system-wide information # 显示系统相关信息
  45. inspect Return low-level information on a container # 查看容器详细信息
  46. kill Kill a running container # kill 指定 docker 容器
  47. load Load an image from a tar archive # 从一个 tar 包中加载一个镜像[对应 save]
  48. login Register or Login to the docker registry server # 注册或者登陆一个 docker 源服务器
  49. logout Log out from a Docker registry server # 从当前 Docker registry 退出
  50. logs Fetch the logs of a container # 输出当前容器日志信息
  51. port Lookup the public-facing port which is NAT-ed to PRIVATE_PORT # 查看映射端口对应的容器内部源端口
  52. pause Pause all processes within a container # 暂停容器
  53. ps List containers # 列出容器列表
  54. pull Pull an image or a repository from the docker registry server # 从docker镜像源服务器拉取指定镜像或者库镜像
  55. push Push an image or a repository to the docker registry server # 推送指定镜像或者库镜像至docker源服务器
  56. restart Restart a running container # 重启运行的容器
  57. rm Remove one or more containers # 移除一个或者多个容器
  58. rmi Remove one or more images # 移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或 -f 强制删除]
  59. run Run a command in a new container # 创建一个新的容器并运行一个命令
  60. save Save an image to a tar archive # 保存一个镜像为一个 tar 包[对应 load]
  61. search Search for an image on the Docker Hub # 在 docker hub 中搜索镜像
  62. start Start a stopped containers # 启动容器
  63. stop Stop a running containers # 停止容器
  64. tag Tag an image into a repository # 给源中镜像打标签
  65. top Lookup the running processes of a container # 查看容器中运行的进程信息
  66. unpause Unpause a paused container # 取消暂停容器
  67. version Show the docker version information # 查看 docker 版本号
  68. wait Block until a container stops, then print its exit code # 截取容器停止时的退出状态值

四、Docker镜像

1、Docker镜像是什么

镜像是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。
只有通过这个镜像文件才能生成Docker容器实例(类似Java中new出来一个对象)。
分层的镜像:
以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载
image.png

2、重点理解

Docker镜像层都是只读的,容器层是可写的
当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。
image.png

3、Docker镜像commit操作案例

docker commit提交容器副本使之成为一个新的镜像
docker commit -m=”提交的描述信息” -a=”作者” 容器ID 要创建的目标镜像名:[标签名]
案例演示ubuntu安装vim

  1. 从Hub上下载ubuntu镜像到本地并成功运行
  2. 原始的默认Ubuntu镜像是不带着vim命令的

image.png

  1. 外网连通的情况下,安装vim

image.png
image.png
image.png

  1. 安装完成后,commit我们自己的新镜像

image.png
image.png

  1. 启动我们的新镜像并和原来的对比

image.png
1 官网是默认下载的Ubuntu没有vim命令
2 我们自己commit构建的镜像,新增加了vim功能,可以成功使用。

小结:
Docker中的镜像分层,支持通过扩展现有镜像,创建新的镜像。类似Java继承于一个Base基础类,自己再按需扩展。
新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层
image.png

五、本地镜像发布到阿里云

1、本地镜像发布到阿里云流程

image.png

2、镜像的生成方法

基于当前容器创建一个新的镜像,新功能增强:docker commit [OPTIONS] 容器ID [REPOSITORY[:TAG]]
OPTIONS说明:
-a:提交的镜像作者;
-m:提交时的说明文字;
本次案例centos+ubuntu两个,当堂讲解一个,家庭作业一个,请大家务必动手,亲自实操。
image.png
image.png

方法二:使用DockerFile

3、将本地镜像推送到阿里云

  1. 本地镜像素材原型

image.png
image.png

  1. 阿里云开发者平台

https://promotion.aliyun.com/ntms/act/kubernetes.html

  1. 创建仓库镜像

image.png

  1. 选择控制台,进入容器镜像服务

image.png

  1. 选择个人实例

image.png

  1. 命名空间

image.png

  1. 仓库名称

image.png
image.png

  1. 进入管理界面获得脚本

image.png

  1. 将镜像推送到阿里云registry
    1. 管理界面脚本

图片.png

  1. 脚本实例
    1. docker login --username=zzyybuy registry.cn-hangzhou.aliyuncs.com
    2. docker tag cea1bb40441c registry.cn-hangzhou.aliyuncs.com/atguiguwh/myubuntu:1.1
    3. docker push registry.cn-hangzhou.aliyuncs.com/atguiguwh/myubuntu:1.1
    image.png

    4、将阿里云上的镜像下载到本地

    docker pull registry.cn-hangzhou.aliyuncs.com/atguiguwh/myubuntu:1.1
    image.png

    六、本地镜像发布到私有库

    1、本地镜像发布到私有库流程

    图片.png

    2、Docker Registry是什么

  1. 官方Docker Hub地址:https://hub.docker.com/,中国大陆访问太慢了且准备被阿里云取代的趋势,不太主流
  2. Dockerhub、阿里云这样的公共镜像仓库可能不太方便,涉及机密的公司不可能提供镜像给公网,所以需要创建一个本地私人仓库供给团队使用,基于公司内部项目构建镜像。
  3. Docker Registry是官方提供的工具,可以用于构建私有镜像仓库

    3、将本地镜像推送到私有库

  4. 下载镜像Docker Registry:docker pull registry

image.png
image.png

  1. 运行私有库Registry,相当于本地有个私有Docker hub
    1. docker run -d -p 5000:5000 -v /zzyyuse/myregistry/:/tmp/registry —privileged=true registry

默认情况,仓库被创建在容器的/var/lib/registry目录下,建议自行用容器卷映射,方便于宿主机联调
image.png

  1. 案例演示创建一个新镜像,ubuntu安装ifconfig命令
    1. 从Hub上下载ubuntu镜像到本地并成功运行
    2. 原始的Ubuntu镜像是不带着ifconfig命令的

image.png

  1. 外网连通的情况下,安装ifconfig命令并测试通过
    1. docker容器内执行上述两条命令:apt-get update apt-get install net-tools

image.png
image.png

  1. 安装完成后,commit我们自己的新镜像 ```java 公式: docker commit -m=”提交的描述信息” -a=”作者” 容器ID 要创建的目标镜像名:[标签名]

命令:在容器外执行,记得 docker commit -m=”ifconfig cmd add” -a=”zzyy” a69d7c825c4f zzyyubuntu:1.2

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653654848978-4a806526-62cb-4e86-873a-d7e063333423.png#averageHue=%23fef8f8&clientId=u2f47530f-09cf-4&from=paste&height=443&id=udabf7584&originHeight=443&originWidth=1182&originalType=binary&ratio=1&rotation=0&showTitle=false&size=86891&status=done&style=none&taskId=u612b5add-a8d7-4de3-89d5-3e30fe150ba&title=&width=1182)
  2. 5. 启动我们的新镜像并和原来的对比
  3. 1. 官网是默认下载的Ubuntu没有ifconfig命令
  4. 2. 我们自己commit构建的新镜像,新增加了ifconfig功能,可以成功使用。
  5. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653654887989-e89e748b-9ae9-4de4-b12c-b5a63b9e4893.png#averageHue=%23fef9f9&clientId=u2f47530f-09cf-4&from=paste&height=331&id=u92c173e7&originHeight=432&originWidth=800&originalType=binary&ratio=1&rotation=0&showTitle=false&size=81532&status=done&style=none&taskId=ua0230a74-2bdc-4bbc-854d-cefb02660bf&title=&width=613)
  6. 4. curl验证私服库上有什么镜像
  7. 1. curl -XGET [http://192.168.111.162:5000/v2/_catalog](http://192.168.111.162:5000/v2/_catalog)。可以看到,目前私服库没有任何镜像上传过
  8. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653654920733-2cedc997-ddca-45be-887b-432807b4a951.png#averageHue=%23fef5f5&clientId=u2f47530f-09cf-4&from=paste&height=100&id=uf806065b&originHeight=184&originWidth=1255&originalType=binary&ratio=1&rotation=0&showTitle=false&size=48325&status=done&style=none&taskId=u6b818439-49ff-413d-b9de-fa120be1715&title=&width=679)
  9. 5. 将新镜像zzyyubuntu:1.2修改符合私服规范的Tag
  10. ```java
  11. 按照公式: docker tag 镜像:Tag Host:Port/Repository:Tag
  12. 自己host主机IP地址,填写同学你们自己的,不要粘贴错误,O(∩_∩)O
  13. 使用命令 docker tag 将zzyyubuntu:1.2 这个镜像修改为192.168.111.162:5000/zzyyubuntu:1.2
  14. docker tag zzyyubuntu:1.2 192.168.111.162:5000/zzyyubuntu:1.2

image.png

  1. 修改配置文件使之支持http
  2. push推送到私服库
  3. curl验证私服库上有什么镜像2
  4. pull到本地并运行

    七、Docker容器数据卷

    ```java Docker挂载主机目录访问如果出现cannot open directory .: Permission denied 解决办法:在挂载目录后多加一个—privileged=true参数即可

如果是CentOS7安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行为, 在SELinux里面挂载目录被禁止掉了额,如果要开启,我们一般使用—privileged=true命令,扩大容器的权限解决挂载目录没有权限的问题, 也即使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653702299450-6a889a4f-ca3a-47c5-9843-d51008d01bf3.png#averageHue=%23e6e5e5&clientId=u51cfd76a-8fbc-4&from=paste&height=267&id=u625fc798&originHeight=267&originWidth=815&originalType=binary&ratio=1&rotation=0&showTitle=false&size=113261&status=done&style=none&taskId=u135bb07f-400b-417d-854c-cbe8c660841&title=&width=815)
  2. <a name="G9u14"></a>
  3. ## 1、是什么
  4. 1. 卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:
  5. 2. 卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷
  6. 3. 一句话:有点类似我们Redis里面的rdbaof文件
  7. 4. docker容器内的数据保存进宿主机的磁盘中
  8. 5. 运行一个带有容器卷存储功能的容器实例
  9. 1. docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名
  10. <a name="yrhhv"></a>
  11. ## 2、能干嘛
  12. 1. 将运用与运行的环境打包镜像,run后形成容器实例运行 ,但是我们对数据的要求希望是持久化的
  13. 2. Docker容器产生的数据,如果不备份,那么当容器实例删除后,容器内的数据自然也就没有了。
  14. 3. 为了能保存数据在docker中我们使用卷。
  15. <br />特点:
  16. 1. 数据卷可在容器之间共享或重用数据
  17. 2. 卷中的更改可以直接实时生效
  18. 3. 数据卷中的更改不会包含在镜像的更新中
  19. 4. 数据卷的生命周期一直持续到没有容器使用它为止
  20. <a name="AtyRC"></a>
  21. ## 3、数据卷案例
  22. 1. **宿主vs容器之间映射添加容器卷**
  23. 1. 公式:docker run -it -v /宿主机目录:/容器内目录 ubuntu /bin/bash
  24. 2. docker run -it --name myu3 --privileged=true -v /tmp/myHostData:/tmp/myDockerData ubuntu /bin/bash
  25. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699172845-55587561-4306-4781-b343-83593c52dac8.png#averageHue=%23f9f2f2&clientId=u8372a469-1e56-4&from=paste&height=357&id=u48e5e67c&originHeight=498&originWidth=832&originalType=binary&ratio=1&rotation=0&showTitle=false&size=56703&status=done&style=none&taskId=ube42109f-58fe-4746-bc9e-19a5d2c8214&title=&width=597)<br />**查看数据卷是否挂载成功:docker inspect 容器ID**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699202378-afe03256-38ef-4bfd-befc-7b25183e7f08.png#averageHue=%23fef9f9&clientId=u8372a469-1e56-4&from=paste&height=216&id=ucafcc8c7&originHeight=216&originWidth=580&originalType=binary&ratio=1&rotation=0&showTitle=false&size=17119&status=done&style=none&taskId=u65bcc94a-afcd-4f2c-9043-60b74f4d2f8&title=&width=580)<br />**容器和宿主机之间数据共享:**
  26. 1. docker容器修改,主机同步获得
  27. 2. 主机修改,docker容器同步获得
  28. 3. docker容器stop,主机修改,docker容器重启后数据仍会同步
  29. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699228334-3051ad69-b7df-4795-b169-4a527a6093da.png#averageHue=%23fbf7f6&clientId=u8372a469-1e56-4&from=paste&height=441&id=u1d9dd27f&originHeight=441&originWidth=1358&originalType=binary&ratio=1&rotation=0&showTitle=false&size=96655&status=done&style=none&taskId=u49d1dd4c-3e1c-4981-a26c-fc8667570db&title=&width=1358)
  30. 2. **读写规则映射添加说明**
  31. 1. 读写(默认):docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:rw 镜像名
  32. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699409557-93afd09b-5fd0-4c31-8a09-2729e696feac.png#averageHue=%23fef7f7&clientId=u8372a469-1e56-4&from=paste&height=175&id=ube1b6fe4&originHeight=175&originWidth=968&originalType=binary&ratio=1&rotation=0&showTitle=false&size=31491&status=done&style=none&taskId=uea063fe2-9dd6-468a-8855-8ead938700c&title=&width=968)
  33. 2. 只读
  34. 1. 容器实例内部被限制,只能读取不能写
  35. 2. docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
  36. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699433848-b09ee09d-2ac0-41cc-8c09-94081ff6b715.png#averageHue=%23fef8f8&clientId=u8372a469-1e56-4&from=paste&height=178&id=u0ab9df69&originHeight=260&originWidth=940&originalType=binary&ratio=1&rotation=0&showTitle=false&size=43896&status=done&style=none&taskId=u00ed05ad-5ea0-4d52-9b67-26b6f04c77f&title=&width=643)
  37. - /容器目录:ro 镜像名:就能完成**容器只读**功能。ro = read only
  38. - 此时如果宿主机写入内容,可以同步给容器内,容器可以读取到
  39. 3. **卷的继承和共享**
  40. 1. 容器1完成和宿主机的映射:docker run -it --privileged=true -v /mydocker/u:/tmp --name u1 ubuntu
  41. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699312495-cd76aa31-78d1-48ca-a31a-e1eb5ad0f1e6.png#averageHue=%23fef4f4&clientId=u8372a469-1e56-4&from=paste&height=181&id=u83f65015&originHeight=181&originWidth=948&originalType=binary&ratio=1&rotation=0&showTitle=false&size=30024&status=done&style=none&taskId=uf92c9a6a-198e-4dea-a252-1a1d7904851&title=&width=948)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699316829-11890208-05fb-4142-a45a-4139bba164de.png#averageHue=%23fefbfb&clientId=u8372a469-1e56-4&from=paste&height=133&id=u8c5abb3e&originHeight=133&originWidth=691&originalType=binary&ratio=1&rotation=0&showTitle=false&size=15590&status=done&style=none&taskId=u33fcbf7a-a1dd-42ff-b4e1-5bdb68d8b00&title=&width=691)
  42. 2. 容器2继承容器1的卷规则:docker run -it --privileged=true **--volumes-from 父类** --name u2 ubuntu
  43. 1. 父类容器停止后,子类容器2仍与宿主机建立联系。子类只是单纯继承挂载规则
  44. 2. 父类容器再次启动后,仍会同步显示停止过程时宿主机或子类创建的文件
  45. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699328135-99225540-0f38-4f05-b855-a6c6e0d91bea.png#averageHue=%23fefbfb&clientId=u8372a469-1e56-4&from=paste&height=257&id=ua96bbe2a&originHeight=257&originWidth=897&originalType=binary&ratio=1&rotation=0&showTitle=false&size=43565&status=done&style=none&taskId=u0e96c057-9f82-4e71-93aa-9c01f18b5e5&title=&width=897)
  46. <a name="IF0Zm"></a>
  47. # 八、Docker常规安装简介
  48. <a name="JmhNE"></a>
  49. ## 1、总体步骤
  50. 1. 搜索镜像
  51. 2. 拉取镜像
  52. 3. 查看镜像
  53. 4. 启动镜像
  54. 1. 服务端口映射
  55. 5. 停止容器
  56. 6. 移除容器
  57. <a name="Dofny"></a>
  58. ## 2、安装Tomcat
  59. 1. **docker hub上面查找tomcat镜像:docker search tomcat**
  60. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699562488-58648e0e-ce60-432c-a491-54b0af6131e6.png#averageHue=%23efeded&clientId=u8372a469-1e56-4&from=paste&height=128&id=ua052fb71&originHeight=180&originWidth=985&originalType=binary&ratio=1&rotation=0&showTitle=false&size=32214&status=done&style=none&taskId=u8a42bf70-fdc8-4753-bf66-3821cb5f4ec&title=&width=698)
  61. 2. **从docker hub上拉取tomcat镜像到本地:docker pull tomcat**
  62. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699654695-74073230-0f8c-4b8b-ab6b-08af3476f34a.png#averageHue=%23f4efef&clientId=u8372a469-1e56-4&from=paste&height=397&id=ua8c35f07&originHeight=445&originWidth=799&originalType=binary&ratio=1&rotation=0&showTitle=false&size=55617&status=done&style=none&taskId=ueafe9e18-088e-4713-a2f5-de4b47b7c1a&title=&width=713)
  63. 3. **docker images查看是否有拉取到的tomcat**
  64. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699670183-8a62254d-b78b-4305-9dbe-25feaba885ec.png#averageHue=%23fefefe&clientId=u8372a469-1e56-4&from=paste&height=98&id=ud34c0e9c&originHeight=98&originWidth=612&originalType=binary&ratio=1&rotation=0&showTitle=false&size=13724&status=done&style=none&taskId=u01655e89-1279-4f7d-87cb-09b4e031be2&title=&width=612)
  65. 4. **使用tomcat镜像创建容器实例**(也叫运行镜像):docker run -it -p 8080:8080 tomcat
  66. - -p 小写,主机端口:docker容器端口
  67. - -P 大写,随机分配端口
  68. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699705043-ee2d559a-8689-4d83-90a0-58323e2c3be8.png#averageHue=%23e5e1e0&clientId=u8372a469-1e56-4&from=paste&height=183&id=ud7ada094&originHeight=304&originWidth=1159&originalType=binary&ratio=1&rotation=0&showTitle=false&size=46953&status=done&style=none&taskId=ud8c49478-76c2-4af3-8486-796b99a9d44&title=&width=696)
  69. - i:交互
  70. - t:终端
  71. - d:后台
  72. 5. 访问猫首页
  73. 1. 问题
  74. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699828287-a8bd843f-74eb-408c-9499-a90bbbfbef88.png#averageHue=%23fbfaf9&clientId=u8372a469-1e56-4&from=paste&height=226&id=udefc063c&originHeight=282&originWidth=811&originalType=binary&ratio=1&rotation=0&showTitle=false&size=23357&status=done&style=none&taskId=ufc7ff0f4-6f36-4ad5-afda-c85e4f4a264&title=&width=650)
  75. 2. 解决
  76. 1. 可能没有映射端口或者没有关闭防火墙
  77. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699882882-baaf268c-5721-4265-87ad-4e8cfca57793.png#averageHue=%23e5e1e0&clientId=u8372a469-1e56-4&from=paste&height=169&id=u14886a17&originHeight=304&originWidth=1159&originalType=binary&ratio=1&rotation=0&showTitle=false&size=46953&status=done&style=none&taskId=uc01dc640-769e-4143-9601-67c85813136&title=&width=643)
  78. 2. webapps.dist目录换成webapps
  79. 1. 先成功启动tomcat
  80. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699900537-ed7c26af-bdf5-4620-8f1f-c4b945e25281.png#averageHue=%23fef7f7&clientId=u8372a469-1e56-4&from=paste&height=174&id=uaa4a410a&originHeight=379&originWidth=1315&originalType=binary&ratio=1&rotation=0&showTitle=false&size=86196&status=done&style=none&taskId=u6650a53d-73bc-46e9-86fc-650cc26f397&title=&width=602)
  81. 2. 查看webapps文件夹查看为空。若webapps为空,则将webapps.dist修改为webapps
  82. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699921790-a4bc4473-22b8-45f9-b5d6-9dc31385daa7.png#averageHue=%23fef9f9&clientId=u8372a469-1e56-4&from=paste&height=392&id=u0c7be44f&originHeight=483&originWidth=772&originalType=binary&ratio=1&rotation=0&showTitle=false&size=97020&status=done&style=none&taskId=uc01d2617-c506-4a4f-8435-fe2b9aefea0&title=&width=626)
  83. 6. 免修改版说明
  84. 1. docker pull billygoo/tomcat8-jdk8
  85. 2. docker run -d -p 8080:8080 --name mytomcat8 billygoo/tomcat8-jdk8
  86. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653699954214-fcc604b7-a0b8-4bbd-8fc7-8a5bbb8504da.png#averageHue=%23fefcfc&clientId=u8372a469-1e56-4&from=paste&height=331&id=u9566637d&originHeight=373&originWidth=777&originalType=binary&ratio=1&rotation=0&showTitle=false&size=55717&status=done&style=none&taskId=ud234cd87-f3f1-45c4-a5a8-c2d4445660a&title=&width=689)
  87. <a name="fvGuO"></a>
  88. ## 3、安装MySQL
  89. 1. **docker hub上面查找mysql镜像**
  90. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653700484157-bdd29725-a76e-48fd-b38e-8389739cbc13.png#averageHue=%23f1eeee&clientId=u8372a469-1e56-4&from=paste&height=310&id=ue4b8c5c1&originHeight=310&originWidth=1243&originalType=binary&ratio=1&rotation=0&showTitle=false&size=71326&status=done&style=none&taskId=ua98451e8-5182-4654-af1f-f0c639df414&title=&width=1243)
  91. 2. **从docker hub上(阿里云加速器)拉取mysql镜像到本地标签为5.7**
  92. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653700498492-2513827a-36db-4365-a314-5afce1b4b2f6.png#averageHue=%23fefafa&clientId=u8372a469-1e56-4&from=paste&height=395&id=ufcdca62f&originHeight=395&originWidth=895&originalType=binary&ratio=1&rotation=0&showTitle=false&size=67162&status=done&style=none&taskId=u1cfc54e8-0e18-4732-b998-5b47445f69f&title=&width=895)
  93. 3. 简单版:使用MySQL5.7镜像创建容器(也叫运行镜像)
  94. 1. 命令出处,哪里来的?
  95. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653700521544-5e39e117-26ae-4ac7-9dd9-3814502a2caa.png#averageHue=%23eccea7&clientId=u8372a469-1e56-4&from=paste&height=319&id=uc7e16d58&originHeight=319&originWidth=1249&originalType=binary&ratio=1&rotation=0&showTitle=false&size=36605&status=done&style=none&taskId=u45609b0c-8339-4efb-b717-0f606ae439d&title=&width=1249)
  96. 2. 使用MySQL镜像
  97. ```java
  98. docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
  99. docker ps
  100. docker exec -it 容器ID /bin/bash
  101. mysql -uroot -p

image.png

  1. 建库建表插入数据

image.png

  1. 外部Win10也来连接运行在dokcer上的MySQL容器实例服务

image.png

  1. 问题
    1. 插入中文数据试试

image.png

  1. 2. 为什么报错?:docker上默认字符集编码隐患
  2. 1. docker里面的mysql容器实例查看,内容如下: SHOW VARIABLES LIKE 'character%'

image.png

  1. 3. 删除容器后,里面的MySQL数据如何办
  2. 1. 容器实例一删除,你还有什么? 删容器到跑路。。。。。?
  1. 实战版:使用MySQL5.7镜像创建容器(也叫运行镜像)

    1. 新建MySQL容器实例

      1. docker run -d -p 3306:3306 --privileged=true
      2. -v /zzyyuse/mysql/log:/var/log/mysql
      3. -v /zzyyuse/mysql/data:/var/lib/mysql
      4. -v /zzyyuse/mysql/conf:/etc/mysql/conf.d
      5. -e MYSQL_ROOT_PASSWORD=123456
      6. --name mysql mysql:5.7

      image.png

    2. 在宿主机的/mysql/conf目录下新建my.cnf:通过容器卷同步给MySQL容器实例

      1. [client]
      2. default_character_set=utf8
      3. [mysqld]
      4. collation_server = utf8_general_ci
      5. character_set_server = utf8

      image.png

    3. 重新启动MySQL容器实例再重新进入并查看字符编码

image.png
image.png

  1. 再新建库新建表再插入中文测试

image.png
image.png

  1. 之前创建的DB字符集仍无效
  2. 修改字符集操作 + 重启mysql容器实例
  3. 之后新建的DB字符集有效
  4. 结论:docker安装完MySQLrun出容器后,建议请先修改完字符集编码后再新建mysql库-表-插数据

image.png

  1. 假如将当前容器实例删除,在重新创建容器,之前被删除容器中创建的数据库及其数据均还在,可以继续使用,这就是容器数据卷备份的作用

    4、安装Redis

  1. 从docker hub上(阿里云加速器)拉取redis镜像到本地标签为6.0.8

image.png

  1. 入门命令

image.png

  1. 命令提醒:容器卷记得加入—privileged=true
    1. Docker挂载主机目录Docker访问出现cannot open directory .: Permission denied
    2. 解决办法:在挂载目录后多加一个—privileged=true参数即可
  2. 在CentOS宿主机下新建目录/app/redis:mkdir -p /app/redis

image.png

  1. 将一个redis.conf文件模板拷贝进/app/redis目录下

image.png

  1. /app/redis目录下修改redis.conf文件
    1. 开启redis验证(可选):requirepass 123
    2. 允许redis外地连接(必须):注释掉 # bind 127.0.0.1

image.png

  1. daemonize no:将daemonize yes注释起来或者设置daemonize no,因为该配置和docker run中-d参数冲突,会导致容器一直启动失败

image.png

  1. 开启redis数据持久化(可选):appendonly yes
    1. 使用redis6.0.8镜像创建容器(也叫运行镜像)
  2. docker run -p 6379:6379 —name myr3 —privileged=true

-v /app/redis/redis.conf:/etc/redis/redis.conf
-v /app/redis/data:/data
-d redis:6.0.8 redis-server /etc/redis/redis.conf
注意:最后的redis-server /etc/redis/redis.conf:指的是redis启动时读取配置文件的地址,此时已映射到宿主机,即读取的是宿主机上的配置/app/redis/redis.conf
image.png

  1. 测试redis-cli连接上来
    1. docker exec -it 运行着Rediis服务的容器ID
    2. redis-cli

image.png

  1. 请证明docker启动使用了我们自己指定的配置文件
    1. 修改前:我们用的配置文件,数据库默认是16个

image.png

  1. 修改后:宿主机的修改会同步给docker容器里面的配置(记得重启服务)

image.png

  1. 测试redis-cli连接,此时docker容器使用的是修改后的配置文件

image.png

5、安装Nginx

见高级篇Portainer

九、DockerFile解析

image.png

1、DockerFile简介

Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。
官网:https://docs.docker.com/engine/reference/builder/
image.png
构建三步骤:

  1. 编写Dockerfile文件
  2. docker build命令构建镜像
  3. docker run依镜像运行容器实例

    2、DockerFile构建过程解析

    2.1 Dockerfile内容基础知识

    1. 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
    2. 指令按照从上到下,顺序执行
    3. 表示注释

    4. 每条指令都会创建一个新的镜像层并对镜像进行提交

      2.2 Docker执行Dockerfile的大致流程

      (1)docker从基础镜像运行一个容器
      (2)执行一条指令并对容器作出修改
      (3)执行类似docker commit的操作提交一个新的镜像层
      (4)docker再基于刚提交的镜像运行一个新容器
      (5)执行dockerfile中的下一条指令直到所有指令都执行完成

      2.3 小结

      从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,
  4. Dockerfile是软件的原材料

  5. Docker镜像是软件的交付品
  6. Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例
  7. Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

image.png

  1. Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等
  2. Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时会真正开始提供服务
  3. Docker容器,容器是直接提供服务的

    3、DockerFile常用保留字指令

    参考tomcat8的dockerfile入门:https://github.com/docker-library/tomcat

  4. FROM:基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是from

  5. MAINTAINER:镜像维护者的姓名和邮箱地址
  6. RUN:容器构建时需要运行的命令。RUN是在 docker build时运行。有以下两种格式
    1. shell格式:RUN yum -y install vim

image.png

  1. exec格式

image.png

  1. EXPOSE:当前容器对外暴露出的端口
  2. WORKDIR:指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点

image.png

  1. USER:指定该镜像以什么样的用户去执行,如果都不指定,默认是root
  2. ENV:用来在构建镜像过程中设置环境变量
    1. ENV MY_PATH /usr/mytest
    2. 这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;
    3. 也可以在其它指令中直接使用这些环境变量,比如:WORKDIR $MY_PATH
  3. ADD:将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包
  4. COPY:类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置
    1. COPY src dest
    2. COPY [“src”, “dest”]
    3. :源文件或者源目录
    4. :容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
  5. VOLUME:容器数据卷,用于数据保存和持久化工作
  6. CMD:指定容器启动后的要干的事情

图片.png

  1. 注意1:Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换
  2. 注意2:参考官网Tomcat的dockerfile演示讲解

image.png

  1. 它和前面RUN命令的区别:
    1. CMD是在docker run 时运行
    2. RUN是在 docker build时运行
    3. ENTRYPOINT:也是用来指定一个容器启动时要运行的命令
  2. 类似于 CMD 指令,但是ENTRYPOINT不会被docker run后面的命令覆盖, 而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序
  3. 命令格式和案例说明:

image.png

  1. 1. ENTRYPOINT可以和CMD一起用,一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参。当指定了ENTRYPOINT后,CMD的含义就发生了变化,不再是直接运行其命令而是将CMD的内容作为参数传递给ENTRYPOINT指令,他两个组合会变成![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653722244669-bf923532-c5be-47db-b487-c0ae88206fa7.png#averageHue=%23e1e1e0&clientId=uc0454bdf-26aa-4&from=paste&height=45&id=u15231020&originHeight=45&originWidth=254&originalType=binary&ratio=1&rotation=0&showTitle=false&size=14354&status=done&style=none&taskId=u7aba9707-fe83-4eb3-a49d-64b0891fc9c&title=&width=254)
  2. 2. 案例如下:假设已通过 Dockerfile 构建了 nginx:test 镜像:

image.png

是否传参 按照dockerfile编写执行 传参运行
Docker命令 docker run nginx:test docker run nginx:test -c /etc/nginx/new.conf
衍生出的实际命令 nginx -c /etc/nginx/nginx.conf nginx -c /etc/nginx/new.conf
  1. 优点:在执行docker run的时候可以指定 ENTRYPOINT 运行所需的参数。
  2. 注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效

image.png

4、案例

  1. 自定义镜像mycentosjava8
    1. 要求
      1. Centos7镜像具备vim + ifconfig + jdk8
      2. JDK的下载镜像地址:
        1. 官网:https://www.oracle.com/java/technologies/downloads/#java8
        2. https://mirrors.yangxingzhen.com/jdk/
    2. 编写:准备编写Dockerfile文件。大写字母D

image.png

  1. FROM centos
  2. MAINTAINER zzyy<zzyybs@126.com>
  3. ENV MYPATH /usr/local
  4. WORKDIR $MYPATH
  5. # 安装vim编辑器
  6. RUN yum -y install vim
  7. # 安装ifconfig命令查看网络IP
  8. RUN yum -y install net-tools
  9. # 安装java8lib
  10. RUN yum -y install glibc.i686
  11. RUN mkdir /usr/local/java
  12. # ADD是相对路径jar, jdk-8u171-linux-x64.tar.gz添加到容器中, 安装包必须要和Dockerfile文件在同一位置
  13. ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/
  14. # 配置java环境变量
  15. ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
  16. ENV JRE_HOME $JAVA_HOME/jre
  17. ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
  18. ENV PATH $JAVA_HOME/bin:$PATH
  19. EXPOSE 80
  20. CMD echo $MYPATH
  21. CMD echo "success--------------ok"
  22. CMD /bin/bash
  1. 构建:
    1. docker build -t 新镜像名字:TAG .
    2. 注意,上面TAG后面有个空格,空格后面有个点

image.png

  1. 运行:docker run -it 新镜像名字:TAG

image.png

  1. 再体会下UnionFS(联合文件系统)
    1. UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
    2. 特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
    3. 虚悬镜像
  2. 仓库名、标签都是的镜像,俗称dangling image
  3. 写一个Dockerfile

    1. vim Dockerfile

      1. from ubuntu
      2. CMD echo 'action is success'
    2. docker build .

image.png

  1. 查看:docker image ls -f dangling=true

image.png

  1. 删除:docker image prune。虚悬镜像已经失去存在价值,可以删除

image.png

  1. 家庭作业 - 自定义镜像myubuntu
    1. 准备编写DockerFile文件

image.png

  1. FROM ubuntu
  2. MAINTAINER zzyy<zzyybs@126.com>
  3. ENV MYPATH /usr/local
  4. WORKDIR $MYPATH
  5. RUN apt-get update
  6. RUN apt-get install net-tools
  7. #RUN apt-get install -y iproute2
  8. #RUN apt-get install -y inetutils-ping
  9. EXPOSE 80
  10. CMD echo $MYPATH
  11. CMD echo "install inconfig cmd into ubuntu success--------------ok"
  12. CMD /bin/bash
  1. 构建:docker build -t 新镜像名字:TAG .
  2. 运行:docker run -it 新镜像名字:TAG

    十、Docker微服务实战

    通过dockerfile发布微服务部署到docker容器 ```java application.properties: server.port=6001

package com.example.dockerBoot.controller;

@RestController public class OrderController{

  1. @Value("${server.port}")
  2. private String port;
  3. @RequestMapping("/order/docker")
  4. public String helloDocker(){
  5. return "hello docker"+"\t"+port+"\t"+ UUID.randomUUID().toString();
  6. }
  7. @RequestMapping(value ="/order/index",method = RequestMethod.GET)
  8. public String index(){
  9. return "服务端口号: "+"\t"+port+"\t"+UUID.randomUUID().toString();
  10. }

}

  1. 1. IDEA工具里面搞定微服务jar
  2. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22523384/1653711962842-a1e82346-b50f-41a2-a450-6e731943c642.png#averageHue=%23f8f5f4&clientId=u51cfd76a-8fbc-4&from=paste&height=573&id=u1b3d8b18&originHeight=573&originWidth=1323&originalType=binary&ratio=1&rotation=0&showTitle=false&size=98804&status=done&style=none&taskId=u08d92c6a-5ccc-4e99-9643-44945ac0004&title=&width=1323)
  3. 2. **编写Dockerfile**
  4. ```java
  5. # 基础镜像使用java
  6. FROM java:8
  7. # 作者
  8. MAINTAINER zzyy
  9. # VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
  10. VOLUME /tmp
  11. # 将jar包添加到容器中并更名为zzyy_docker.jar
  12. ADD docker_boot-0.0.1-SNAPSHOT.jar zzyy_docker.jar
  13. # 运行jar包
  14. RUN bash -c 'touch /zzyy_docker.jar'
  15. ENTRYPOINT ["java","-jar","/zzyy_docker.jar"]
  16. #暴露6001端口作为微服务
  17. EXPOSE 6001
  1. 将微服务jar包和Dockerfile文件上传到同一个目录下/mydocker

image.png

  1. 构建镜像( 打包成镜像文件):docker build -t zzyy_docker:1.6 .

image.png

  1. 运行容器: docker run -d -p 6001:6001 zzyy_docker:1.6

image.png

  1. 访问测试

image.png