6.docker精髓

0x01. 容器数据卷

1. 什么是容器数据卷

docker的理念回顾

将应用和环境打包成一个镜像, 启动运行就变成了一个容器, 我们都知道程序的运行是会产生数据的, 因为我们的容器是可以删除的, 如果把数据保存在容器中, 明显是一个不可取的方法。那如何将数据持久化呢?比如mysql中的数据, 如果你把mysql容器删除了,那不就相当于删除跑路了吗?

所以我们有一个需求就是把mysql容器中的数据保存到本地, 那么如何做呢?

容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地! 这就是卷技术! 说白了就是一个目录的挂载, 将我们容器内的目录, 挂载到linux上面

我是不是可以粗疏的理解为这不就是一个同步数据的机制吗?

image-20210406114706578

总结一句话 : 容器的持久化和同步操作 ! 容器间也是可以数据共享的 !

2. 使用数据卷

方式一: 直接使用命令来挂载 -v

docker run -it -v 主机目录:容器内目录

# 命令
docker run -it -v /home/docke_home:/home centos /bin/bash

# 通过查看容器的元数据查看目录挂载信息
docker inspect 容器id

image-20210406120142967

测试数据同步, 在容器添加数据, 宿主机也是同步增加

image-20210406142102837

再来测试

  • 停止容器
  • 宿主机上修改文件
  • 启动容器
  • 容器内的数据依旧是同步的

image-20210406142017536

好处: 我们以后修改只需要在本地修改即可, 容器内会自动同步

3. 实战mysql同步数据

思考 : mysql的数据持久化问题

# 获取镜像(指定了版本)
docker pull mysql:5.7

# 运行容器,需要做数据挂载!   # 安装启动mysq1 ,需要配置密码的,这是要注意点 !
# 官方测试 : docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysq1:tag

# 启动我们的
# -d 后台运行
# -p 端口映射
# -v 数据卷挂载
# -e 环境配置
# --name 容器名称

[root@kuangshen home]# docker run -d -p 3344:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 mysql:5.7

打开我们的mysql客户端(sqlyog)连接一下试试能不能连接

image-20210406144918287

发现连接成功

image-20210406145036996

# sqlyog--连接到服务器的3344 -- 3344和容器内的3306映射, 这个时候

当我们在sqlyog创建一个新的数据库时, 会在宿主机的/home/mysql/data下新建一个文件

image-20210406145910408

image-20210406145949690

假设我们将容器删除, 发现我们挂载到本地的数据卷依旧没有丢失, 这就实现了容器数据化持久功能 !

4. 具名和匿名挂载

# 匿名挂载
-v 容器路径                                                         容器路径 
docker run -d -p 8881:80 --name nginx01 -v /etc/nginx nginx

# 查看所有的 volume (卷) 的情况
[root@centos7 data]# docker volume ls
DRIVER    VOLUME NAME
local     4f834a0f6208c921bfbc459b0ad9a0c085e70c8f6180f523f0d525d5841ccbdd
local     56ccd3b8b5e855270a7ff5274b8b662c5c50d502ce6e32c73e347119510b9a36
local     b35d6d3b8359b9bcbe1255b6eca4e7cb8044197b7e40919325c5d7e0befa3308
local     cbec0103b17d37611a71acb661e5a0935f284b19363a71bd20d3c945578e1e91
local     d793375a6414778fe113a659e6e44159937d25c37191d38fefdbce8e3be7f987

# 这里发现,这种就是匿名挂载,我们在 -v只写了容器内的路径,没有写容器外的路径!

# 查看nginx01的元数据
[root@centos7 data]# docker inspect nginx01

image-20210406151333555

# 具名挂载
-v 卷名:容器路径     ( 注意不是路径,不加/ )
[root@centos7 data]# docker run -d -p 3344:80 -v juming:/etc/nginx --name nginx02 nginx

# 查看卷情况
[root@centos7 data]# docker volume ls
DRIVER    VOLUME NAME
local     4f834a0f6208c921bfbc459b0ad9a0c085e70c8f6180f523f0d525d5841ccbdd
local     56ccd3b8b5e855270a7ff5274b8b662c5c50d502ce6e32c73e347119510b9a36
local     b35d6d3b8359b9bcbe1255b6eca4e7cb8044197b7e40919325c5d7e0befa3308
local     cbec0103b17d37611a71acb661e5a0935f284b19363a71bd20d3c945578e1e91
local     d793375a6414778fe113a659e6e44159937d25c37191d38fefdbce8e3be7f987
local     juming

# 发现最后一个是有名字的,这就是具名挂载
# 查看具体的挂载地址
[root@centos7 data]# docker volume inspect juming

image-20210406152030344

所有的dcoker容器内的卷, 没有指定目录的情况下都是在/var/lib/docker/volumes/卷名/_data

我们通过具名挂载可以方便的找到我们的一个卷,大多数情况在使用的具名挂载

# 如何确定是具名挂载还是匿名挂载, 还是指定路径挂载 !
-v 容器路径   			     # 匿名挂载
-v 卷名:容器路径         		 # 具名挂载
-v /宿主机路径:容器路径        # 指定路径挂载

拓展 :

# 通过 -v 容器内路径: ro rw 改变读写权限
ro readonly       #只读
rw readwrite     #可读可写 ( 默认 )

#一旦这个了设置了容器权限,容器对我们挂载出来的内容就有限定了!!
docker run -d -p --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -p --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

# ro    只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作 !

5. 初始Dockerfile

Dockerfile 就是用来构建 docker 镜像的构建文件, 之前的docker commit类似二次开发, 这个是纯手工打造镜像

本质就是一串命令脚本 , 通过这个脚本可以生成一个镜像 , 我们来初体验一下

# 创建一个dockerfile文件, 名称随意  建议 dockerfile
# 文件内容  指令( 大写 ) 参数
FROM centos

VOLUME ["volume01","volume02"]

CMD echo "-----end-----"

CMD /bin/bash

# 这里每条命令就是镜像的一层

image-20210406155006557

# 启动一下自己写的容器[root@centos7 docker-test-volume]# docker imagesREPOSITORY            TAG       IMAGE ID       CREATED         SIZEymn/centos            1.0       8f2fd6c82fd4   2 minutes ago   209MBtomcat02              1.0       b94af91084cb   5 hours ago     672MBtomcat                latest    bcd554d24cc5   5 days ago      667MBredis                 latest    7f33e76fcb56   5 days ago      105MBnginx                 latest    7ce4f91ef623   6 days ago      133MBmysql                 5.7       cd0f0b1e283d   6 days ago      449MBportainer/portainer   latest    580c0e4e98b0   2 weeks ago     79.1MBcentos                latest    300e315adb2f   3 months ago    209MBelasticsearch         7.6.2     f29a1ee41030   12 months ago   791MB[root@centos7 docker-test-volume]# docker run -it 8f2fd6c82fd4 /bin/bash

image-20210406155743896

这个卷和外部一定有一个同步的目录

image-20210406155838131

查看一下卷挂载的路径

image-20210406160120883

测试一下刚才的文件是否数据同步出去了

image-20210406160307203

这种方式我们未来使用的十分多,因为我们通常会构建自己的镜像 !

假设构建镜像时候没有挂载卷,要手动镜像挂载 -v卷名:容器内路径 !

6. 数据卷容器

两个容器同步数据, 或者多个容器同步数据

image-20210406160754532

# 启动三个容器 , 就用我们刚才创建的镜像测试

image-20210406162630452

image-20210406162955870

image-20210406163141740

image-20210406163713337

# 测试,可以删除dockero1,查看一下docker02和docker03是否还可以访问这个文件# 测试依旧可以访问

image-20210406161738575

实战测试, 两个mysql同步数据

[root@centos7 docker-test-volume]# docker run -d -p 3344:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7[root@centos7 docker-test-volume]# docker run -d -p 8881:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7# 这个时候可以实现两个容器数据同步

image-20210406165237058

image-20210406165256051

结论 :

容器之间配置信息的传递, 数据卷容器的生命周期一直持续到没有容器使用为止

但是一旦你持久化到了本地, 这个时候, 本地的数据是不会删除的

0x02. dockerfile

1. dockerfile介绍

核心 : 用来构建docker镜像的文件 ! 命令参数脚本 !

构建步骤 :

  1. 编写一个 dockerfile 文件
  2. docker build 构建成为一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像 ( dockerhub, 阿里云镜像仓库 )

查看一下官方是怎么做的

image-20210406170416838

image-20210406170445972

很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像!

官方既然可以制作镜像,那我们也可以!

2. dockerfile构建过程

基础知识

  1. 每个保留关键字 (指令) 都必须是大写字母
  2. 执行从上到下顺序执行
  3. # 表示注释
  4. 每一个指令都会创建提交一个新的镜像层, 并提交

image-20210406170956883

dockerfile是面向开发的, 我们以后要发布项目, 做镜像, 就需要编写dockerfile文件, 这个文件十分简单 !

你以前做java开发是写好一个jar包就好了, 但是现在公司都是问你要一个docker镜像

docker镜像逐渐成为了企业交付的标准, 必须掌握

dockerfile : 构建文件, 定义了一切的步骤

步骤 : 开发,部署,运维 缺一不可........

DockerFile : 构建文件,定义了一切的步骤,源代码

Dockerlmages : 通过 DockerFile构建生成的镜像,最终发布和运行的产品

Docker容器 : 容器就是镜像运行起来提供服务器

3. dockerfile指令

FROM			# 基础镜镜像,一切从这里开始构建MAINTAINER		 # 镜像是谁写的,姓名+邮箱RUN				# 镜像构建的时候需要运行的命令ADD				# 步骤:tomcat镜像,这个tomcat压缩包!添加内容WORKDIR			# 镜像的工作目录VOLUME		       # 挂载的目录EXPOSE			 # 保留端口配置CMD				# 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代ENTRYPOINT		 # 指定这个容器启动的时候要运行的命令,可以追加命令ONBUILD			 # 当构建一个被继承DockerFile这个时候就会运行ONBUILD 的指令。触发指令。COPY			 # 类似ADD ,将我们文件拷贝到镜像中ENV				 # 构建的时候设置环境变量!

image-20210406172528903

4. 实战测试

docker hub 中99%镜像都是从这个基础镜像过来的 FROM scratch, 然后配置需要的软件和配置来进行构建

image-20210406174121780

创建一个自己的centos镜像

# 1.编写dockerfile文件[root@centos7 dockerfile]# cat dockerfile-mycentos FROM centosMAINTAINER ymn<2733673357@qq.com>ENV MYPATH /usr/localWORKDIR $MYPATHRUN yum -y install vimRUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATHCMD echo "----end----"CMD /bin/bash# 2.通过文件构建镜像[root@centos7 dockerfile]# docker build -f dockerfile-mycentos -t mycentos:1.0 .# 3.测试运行

对比 : 之前原生的centos

image-20210406175607816

我们增加之后的镜像

image-20210406175714961

我们可以列出本地镜像的变更历史, 从中看出镜像是怎么一步一步做出来的

image-20210406175933189

我们平时拿到一个镜像, 可以研究一下它是怎么做的

CMD 和 ENTRYPOINT 区别

CMD                   # 指定这个容器启动的时候要运行的命令, 只有最后一个会生效, 可被替代ENTRYPOINT      # 指定这个容器启动的时候要运行的命令, 可以追加命令

个人理解 : 命令内容是在一个列表中, CMD会先把源列表的内容清空, 然后把新命令添加进去执行, 但是ENTRYPOINT不是, 他是在原来的基础上直接追加进去

posted @ 2021-12-20 18:55  Mn猿  阅读(27)  评论(0编辑  收藏  举报