一、Docker解决了什么问题

1、存在的问题

  • 开发环境和生产环境存在差异性,相同的代码部署到不同环境,经常因为各种原因不能正常运行
  • 代码可运行环境的配置复杂,耗时耗力,如果能”一次配置/构建,到处正常运行“就好了
  • 不同业务代码包对环境和配置的要求会有冲突,使得在同一个物理环境中彼此不能共存,可是我们就是希望他们共存

2、解决方式
如果打包的时候,可以把开发时的环境和配置一起打包进来,并且保持彼此相互独立(隔离)、互不影响,就可以很好地解决这些问题。集装箱好像就有这样的特性,所以,Docker,一群码头工人来帮助解决这个问题了。

在这里插入图片描述

二、Docker是什么

1、前提须知
虚拟化技术:让一台物理机,拥有多个操作系统的技术。具体实现虚拟化技术的解决方案有虚拟机容器化技术

  • 虚拟机:模拟完整的一套操作系统,包括内核+完整库+应用,它占用资源比较多,存在很多冗余的内容,使得运行起来很慢,尤其是PC性能不好的时候
  • 容器化技术:仅模拟部分操作系统,包括必须库(部分库)+应用,占用资源少,体积小
    在这里插入图片描述

虚拟机为什么要比容器化技术运行起来慢?
虚拟机是在操作系统上又加了一个操作系统,所以启动加载很慢,而docker通过docker引擎直接在现有操作系统上操作
在这里插入图片描述

2、Docker的概念
Docker是一项使用go语言实现的容器化技术。它可以将代码+环境+配置(即除内核以外应用所有需要的环境+应用本身)打包成一个”集装箱“,实现应用程序”一次打包,到处运行“。

3、使用Docker带来了哪些优势(除了解决问题)

  • 可以实现应用的快速交付
  • 便利升级和扩展(一个镜像一步到位升级,然后可以将镜像快速复制到不同的服务器上)
  • 可以充分压榨一台服务器的计算能力

4、Docker的架构图

  • docker cli + docker server + docker DB(一种CS架构)

  • cli通过命令来操控docker守护进程,实现对容器的管理
    在这里插入图片描述

  • 名词解释

    • 镜像:创建容器的模板,类比java中的类,类比“程序”
    • 容器:镜像的一个实例,类比java中的对象,类比“进程”,进程可以启动、停止、删除
    • 仓库:存放镜像的数据库
      在这里插入图片描述

5、docker运行流程图

远程库指docker hub(https://hub.docker.com/),相当于docker的一个镜像商店
在这里插入图片描述

在这里插入图片描述

三、Docker安装使用

官网:https://www.docker.com/
文档:https://docs.docker.com/

1、安装(基于centos)
1)如果之前安装过,需要先卸载掉之前的旧版本

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

2)如果没有,首先需要建立docker仓库

sudo yum install -y yum-utils
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

3)安装docker引擎

sudo yum install docker-ce docker-ce-cli containerd.io

4)启动docker引擎

sudo systemctl start docker

5)验证安装成功

 sudo docker version //查看docker版本
 sudo docker run hello-world

四、Docker常用命令

1.帮助命令

  • 查看版本docker version
    在这里插入图片描述

  • 查看容器详细信息docker info
    比docker version显示的信息更多在这里插入图片描述

  • 查看帮助docker --help

命令的帮助文档: https://docs.docker.com/reference/

在这里插入图片描述
docker 具体命令 --help
在这里插入图片描述

2.镜像命令

1)查看本地镜像

  • docker images
    • -a 所有
    • -q 只列出镜像id
      在这里插入图片描述
    • –digests显示摘要信息,验证一致性完整性的hashcode在这里插入图片描述 – –no-trunc显示完整信息 在这里插入图片描述

2)从docker hub上搜索镜像

  • docker search 镜像名
    • -s 数字 点赞数大于数字的
    • –automated 只列自动构建类型的
      在这里插入图片描述
      在这里插入图片描述

3)从hub下载镜像,就是从hub上将镜像拉取到本地库

  • docker pull 镜像名[:tag]
    不写tag表示下载最新版本
    在这里插入图片描述
    分层下载
    在这里插入图片描述

4) 删除镜像

  • docker rmi 镜像id/镜像名[:tag] [镜像id/镜像名[:tag]]可同时删除多个
    • 版本不写默认最新
    • -f强行删除
    • tag为latest表示最新版本
    • 删除全部时docker rmi -f $(docker images -qa)
      在这里插入图片描述

5) 查看镜像变更历史

  • docker history 镜像名
    在这里插入图片描述

3.容器命令

1) 新建并启动容器

  • docker run [参数] 镜像名/镜像id
    在这里插入图片描述
    • -i:交互式模式运行容器,常与t同时用

    • -t:为容器重新分配一个伪终端,常与i连用

    • –name 名字:为容器指定一个名字
      在这里插入图片描述

    • -d:后台运行容器并饭后容器id,即启动守护式模式运行

      • docker容器后台运行,就必须有一个前台进程,否则就会自动退出,除了一直挂起的命令(top、tail)
    • -P:随机一个端口号

    • -p:指定一个端口号

      • ip:主机端口:容器端口
      • ip::容器端口
      • 主机端口:容器端口
      • 容器端口

2) 列出当前所有正在运行的容器

  • docker ps ps命令是看机器上所有进程信息,与top相区别
    在这里插入图片描述
    • -a:所有=现在+之前(历史)
    • -l:最近创建
    • -n= 数字:显示最近创建的数字个
      在这里插入图片描述
    • -q:静默模式,只显示容器id
    • –no-trunc:不截断输出

3) 退出容器

  • exit(且容器关闭了)
  • 快捷键(ctrl+p+q:只退出。没有关闭)

4) 启动和停止容器

  • 启动容器(针对已经创建过的)dockers start 容器id
  • 重启容器docker restart 容器id
  • 停止容器docker stop 容器id
  • 强制停止容器docker kill 容器id

5)删除的容器

  • docker rm 容器id
    • -f:强制删除没停止的容器
    • 批量删除docker rm -f ${docker ps -aq}等价于docker -aq|xargs docker rm

4、其它常用命令

1)查看容器日志

  • docker logs -f -t --tail 容器id
    • f:跟随最新的日志打印
    • t:加入时间戳 在这里插入图片描述
    • tail:最后几条

2)查看某个容器进程信息

  • docker top 容器id 查看具体某个进程,与ps相区别
    在这里插入图片描述

3)查看容器内部细节

  • docker inspect 容器id
    在这里插入图片描述

4)进入没关闭的容器,显示之前正在运行的命令行窗口

  • docker attach 容器id

5)进入没关闭的容器,但会打开一个全新的命令行窗口(非运行的cmd)

  • docker exec 容器id

6) 从容器内拷贝文件到主机上

  • docker cp 容器id:容器内路径 目的主机路径

7)将自己修改过的容器生成一个镜像

  • docker -a =author name -m= commit message 容器id 镜像名:版本

8)查看机器中容器的cpu占用情况

  • docker stats

五、Docker镜像底层原理

参考:

  • 掘金:https://jishuin.proginn.com/p/763bfbd61dab
  • 知乎:https://zhuanlan.zhihu.com/p/392508816

1.什么是联合文件系统

1)官方介绍
联合文件系统( UnionFS )是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下

2)自家介绍
联合文件系统是一种像“git”一样的文件系统,本质上是就是利用了增量式修改文件+读写分层+共享来实现的

  • 增量式修改文件
    • 像git一样,每commit一组修改,就增加一层,对应一个新版本,进行增量式记录
    • 只能做”加法“,不能做”减法“
  • 读写分层
    • 所有已经提交的部分只读
    • 最顶层,当前运行的那一层可写
  • 共享
    • 由于已经提交的部分只读,所以,这部分内容可以进行共享,减少冗余,同时减少了启动加载的时间

在这里插入图片描述

2.docker镜像加载原理
1)基于联合文件系统来实现的,采用的OverlayFS,这种堆叠文件系统依赖于其它文件系统。
在这里插入图片描述
2)可以通过docker info查看docker所使用的文件系统和存储驱动器
在这里插入图片描述
3)镜像、容器、层的原理图在这里插入图片描述

  • 每一个镜像都是基于基础镜像(没有父镜像的镜像)如centos等来生成的,新镜像=commit(旧镜像(只读层)+ 修改层(可读可写))
  • 修改层相当于容器层,如果要记录容器的状态,可以通过commit把它变成一个新镜像
  • 对于镜像每新加的一层,只是逻辑上的概念,在联合文件系统中,都指向同一个文件系统
    在这里插入图片描述

六、Docker容器数据卷

1、数据卷的存在是为了解决什么问题
那必然是解决联合文件系统存在的问题,哈哈哈哈哈:

  • 问题1:容器中的数据,其实相当于是内存数据,如果想要保存下来,必须将其commit成为镜像。如果仅为了持久化数据,就将其commit,那镜像得多大啊!这样docker”集装箱“体量小的优势就会丢失。另外,如果没有及时commit,服务由于各种原因崩了,数据也会丢失。
  • 问题2:对容器中各种服务进行配置,必须进入到容器里面,好麻烦,如果要是在主机中操作,可以同步到容器中就好了。
  • 问题3:容器和容器之间是相互隔离的,如果想要数据共享怎么办呢。

2、数据卷是什么
卷就是目录或者文件,但是它不属于联合文件系统(UFS)。可以说,它绕过了UFS,让数据可以直接存储在宿主机上,不随容器的消失而消失。

特点:

  • 生命周期更长,不会随容器生命周期结束而结束——实现数据持久化
    • 实现数据持久化不影响镜像,解决问题1
  • 实现容器与宿主机的双向”沟通“,在宿主机中的修改可以直接反馈到容器中,在容器中的修改也会直接影响到宿主机上
    • 可以直接在主机上修改容器中应用服务配置,解决问题2
    • 可以容器间共享数据,解决问题3

3、如何使用数据卷——挂载
1)挂载命令

  • docker run -v /主机路径:/容器路径
    在这里插入图片描述
    查看卷查不到,原因是 docker volume ls 命令查看的数据卷在主机 /var/lib/docker/volumes目录下
    在这里插入图片描述

  • docker run -v 挂在数据卷名:/容器路径具名挂载
    在这里插入图片描述

  • docker run -v /容器路径匿名挂载
    在这里插入图片描述

  • 须知

    • 容器停止后,在主机对数据卷进行修改,重启重新开启后是可以看到对数据卷的修改的
    • 可以设置容器对数据卷的权限命令:docker run -it -v /主机绝对路径:/容器路径 :ro/rw 镜像名
      • ro:read only,表示只容许从宿主机中进行写操作,在容器中不可以
      • rw:read&write(默认),表示容器和宿主机都可以有写操作

2)查看具体数据卷的挂载路径命令

  • docker volume inspect 卷名
    在这里插入图片描述

3)查看当前所有数据卷的命令

  • docker volume ls

4)查看具体容器的挂载信息命令

  • docker inspect 容器id
    在这里插入图片描述
    在这里插入图片描述

方式二
手动编写一个dockerfile文件→对文件进行build,生成文件对应的镜像→运行这个镜像
在这里插入图片描述

  • 方式一不能直接在dockerfile中实现,因为它依赖于宿主机,而宿主机之间可能存在差异性,即目录结构不同
  • 如果docker挂载主机目录访问时出现错误cannot open directory.:permission denied,则需要在挂载目录后多加一个参数–privileged=true docker run -it -v /宿主机绝对路径目录:/容器内路径 --privileged=true 镜像名

3.容器间共享数据
数据卷容器:存放数据卷的容器,其它容器通过挂载这个容器实现数据共享
命令:docker run -it --name 容器名字 --volumes-from 数据卷容器名 镜像名

  • 无论在哪个容器里对数据卷操作(芙蓉区或者子容器),都会显现出执行操作结果
  • 具有传递性
  • 父容器被删除不影响共享,因为其生命周期的特性

DockerFile解析

可以去docker hub上查看各种镜像对应的dockerfile文件内容
以centos为例
在这里插入图片描述

类比:docker镜像(java源文件)→ dockerFile(class文件)
概念:dockerFile是用来构建镜像的构建文件,是由一系列命令和参数构成的脚本

1.语法

  • 每个保留字指令都必须大写,且其后至少有一个参数
  • 指令从上到下一次执行
  • 注释#表示
  • 一个指令对应一个镜像层,指令→创建镜像层+新镜像进行提交

2.dockerfile执行流程

  • 从基础镜像开始运行一个容器,祖先为scratch(类比Object)
  • 一条指令对应一次对容器的修改并docker commit
  • 基于新的容器再执行下一个指令
  • 直到所有指令都执行完毕

3.dockerfile保留字指令

  • FROM:基础镜像,基于哪个镜像开始构建新镜像
  • MAINTAINER:维护者名字和邮箱
  • RUN:构建时需要执行的相关命令(例如,镜像centos不支持vim,我们可以在其基础上修改,在这里加入yum -y install vim的指令,使它可以支持vim)
  • EXPOSE:对外端口号,容器端口号
  • WORKDIR:工作落脚目录,一登录进去所在的目录
  • ENV:设置环境变量 (变量名 目录 eg JAVA_HOME /java/jdk)
  • ADD:拷贝文件进入镜像,如果是压缩包自动解压缩
  • COPY:只拷贝到指定路径下
  • VOLUME:指定容器卷
  • CMD:指定容器启动时自动要执行的命令,可以有多个,但是只有最后一个生效,cmd会被run之后的参数替代
  • ENTRYPOINT:同cmd,但是run的话之后的参数只是追加
  • ONBUILD:当构建的dockerfile是父,则在子继承后会触发的操作

Docker本地镜像发布到阿里云

编写dockerfile
build成镜像
将镜像push上去

  • 登录阿里云开发者平台
  • 创建仓库镜像
  • 点击仓库镜像管理按钮,然后按照要求执行命令

版权声明:本文为weixin_45880263原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_45880263/article/details/106244864