zoukankan      html  css  js  c++  java
  • 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不是, 他是在原来的基础上直接追加进去

  • 相关阅读:
    查看另外一台服务器的版本号
    制作数据集(二)
    制作数据集(一)
    中文分词工具包 PKUSeg
    Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend)
    修改主机名
    例题
    Oracle基本使用
    Linux里面的MySQL忘记密码RROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
    SpringBoot2.x以上配置schema.sql脚本
  • 原文地址:https://www.cnblogs.com/xcymn/p/15712443.html
Copyright © 2011-2022 走看看