ToB企服应用市场:ToB评测及商务社交产业平台
标题:
【云原生 | 从零开始学Docker】六、如何写出自己的镜像——Docker file
[打印本页]
作者:
三尺非寒
时间:
2022-6-26 02:23
标题:
【云原生 | 从零开始学Docker】六、如何写出自己的镜像——Docker file
该篇文章已经被专栏《
从零开始学docker
》收录
Docker file
数据卷容器
mysql数据共享
结论
Docker File
Docker File的介绍
构建步骤
Dockerfile的构建过程
基础知识
DockerFile体系结构(保留字指令)
FROM
MAINTAINER
RUN
ADD
WORKDIR
EXPOSE
ENV
COPY
VOLUME
CMD
ENTRYPOINT
ONBUILD
实战-创建自己的centos
CMD和ENTRYPOINT的区别
写在最后
数据卷容器
在上一篇文章中其实有一个点我没有说,那就是
如何实现两个或者多个容器之间数据共享
。
打个比方,有两个容器 一个父容器一个子容器,谁去挂载了谁,那么它就是父容器,比如c2挂载c1,那么c1就是父,只要挂载了,同步的数据卷里面的内容就是同步的
了。被挂载的父容器也叫做
数据卷容器
那么如何实现呢?这个时候就是使用我们的--volumes-form
首先我们启动一个centos的镜像 docker run -it --name docker01 91d74fd5d017
容器数据卷在这里!启动了docker01,然后启动docker02,03,继承之前的docker01镜像的数据docker run -it --name docker02 --volumes-from docker01 paopao/centos:1.0
容器数据卷一样在!我们在docker01加一个文件第二个也会同步!docker01就是数据卷容器现在。
创建第三个,和上面一样的!挂载docker01,通过03,02创建,01也会同步!
如果把01删了也不会影响其他容器的数据,只要有容器在用就不会丢失。其实这个功能是一个,类似于双向拷贝的概念,docker1是共享卷,虽然1挂了,但是2和3已经拷贝下了,所以不影响。(实际上是一种映射,持久化数据共享依赖于宿主机,三个容器里的文件都硬链接到宿主机下面了,路径一致)
mysql数据共享
docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
mysql02挂载的目录相同,-v那段目录甚至可以不要了,因为目录相同,所以没啥问题。
docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-form mysql01 mysql:5.7
可以实现两个容器数据同步。
复制代码
结论
容器之间可以做配置信息传递,比如做集群要把这个集群文件拷贝到多个配置文件,每个服务器都要有,现在我们共享就ok了,数据卷生命周期一直持续到没有容器使用为止。
但是一旦持久化到本地,这个时候,本地数据是不会删除的。
Docker File
Docker File的介绍
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
构建docker镜像的构建文件就是命令脚本,自制一个目录,在里面写一个脚本,用来生成镜像,镜像是一层一层的,所以脚本是一层一层的命令,脚本命令每个都是镜像一层。
dockerhub官网也可以看到dockerfile,下面是centos的dockerfile
我们来做一个最简单的dockerfile,首先要vim dockerfile1,进入编辑模式之后写入下面这些代码。
FROM centos #centos作为基础
VOLUME ["volume01","volume02"] #额外挂载目录 在创建镜像的时候就挂载好了
#不加斜杠默认根目录,数据卷目录和外部一定有一个同步目录
CMD echo "----endl----"
CMD /bin/bash #以bash启动
复制代码
保存退出之后可以开始构建了!build构建 -f是file的地址
docker build -f dockerfile1 -t paopao/centos:1.0 .
复制代码
当前路径的dockerfile1打包成paopaocentos1.0,然后启动镜像。
看到挂载的两个数据卷目录了,进去新建一个文件
之后出来inspect。
mount那有目录,没问题,进入目录发现有文件没问题。
未来实用得会比较多,因为会构建自己镜像,如果构建的时候没挂载卷可以-v手动挂载
构建步骤
1.写一个 dockerfile 文件
2.docker build 构建成为镜像
3.docker run 运行镜像
我们可以去dockerhub看看是怎么做的,会跳到github,官方的镜像很多都是基础包,没有什么功能,我们通常会自己搭建。
Dockerfile的构建过程
基础知识
1.每个保留关键字(指令)必须是大写字母。
2.执行是从上到下顺序执行。
3.# 表示注释。
4.每一个指令都会创建提交一个新的镜像层并提交。
docker file是面向开发的,如果发布项目做镜像,就要编写 docker file 文件。一些公司要交 Docker 镜像,逐渐成为了企业交付标准,必须掌握。
Docker File:构建文件,定义了一切的步骤,源代码。
Docker Images:通过docker file构建生成的镜像,最终要发布运行的产品,原来jar,war执行,现在都变成镜像,直接一起运行。
Docker容器:容器就是镜像运行起来提供服务的。 镜像和容器都是使用别人的,现在要自己写。
DockerFile体系结构(保留字指令)
FROM
初始化一个新的构建阶段,并设置基础映像【当前新镜像是基于哪个镜像的】,就相当于电脑,没有就不行,一切从这里开始构建。
单个dockfile可以多次出现 FROM ,以使用之前的构建阶段作为另一个构建阶段的依赖项。
MAINTAINER
镜像是谁写的,作者信息等,一般是留自己名字邮箱啥的,但是现在都用LABEL了
LABEL maintainer="paopao<3134912846@qq.com>"
LABEL description="This is my centos"
复制代码
RUN
docker镜像构建的时候需要运行的命令。
RUN /bin/bash -c 'echo hello,CSDN'
复制代码
ADD
将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包,添加的东西一个就是一层。
可以指定多个资源,但如果它们是文件或目录,则它们的路径被解释为相对于构建上下文的源,也就是WORKDIR
WORKDIR
指定在创建容器后,终端默认登陆的进来工作目录.
如果WORKDIR不存在,即使它没有在后续Dockerfile指令中使用,它也会被创建。
docker build 构建镜像过程中,每一个 RUN 命令都会新建一层。只有通过 WORKDIR 创建的目录才会一直存在。
EXPOSE
暴露端口配置,和-p一样的。
Docker 容器在运行时侦听指定的网络端口。可以指定端口是监听TCP还是UDP,如果不指定协议,默认为TCP。
ENV
用来在构建镜像过程中设置环境变量,mysql的用户名密码这种。
ENV <key>=<value>
复制代码
设置的环境变量将持续存在,可以使用docker inspect来查看。使用docker run --env =来更改环境变量的值。
COPY
类似于add,将文件拷贝到镜像。
COPY指令和add指令的唯一区别在于:是否支持从远程URL获取资源。COPY指令只能从执行docker build所在的主机上读取资源并复制到镜像中。而add指令还支持通过URL从远程服务器读取资源并复制到镜像中。
VOLUME
容器数据卷,用于数据保存和持久化工作
CMD
指定这个容器启动的时候运行的命令,比如cmd echo输出类似于这种,只有最后一个生效,可以被替代。
如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。
FROM centos:7
CMD ["/usr","ls -l"]
复制代码
ENTRYPOINT
指定这个容器启动的时候运行的命令,可以追加命令。
ENTRYPOINT 和 CMD 一样,都是在指定容器启动程序及参数,不过它不会被 docker run 的命令行参数指定的指令所覆盖。如果要覆盖的话,需要通过docker run --entrypoint 来指定。
ONBUILD
构建一个被继承的Dockerfile的时候就会执行ONBUILID的指令,触发指令。
将一个触发指令添加到镜像中,以便稍后在该镜像用作另一个构建的基础时执行。也就是另外一个dockerfile FROM了这个镜像的时候执行。
实战-创建自己的centos
dockerhub上99%的镜像都是从这个基础镜像过来的
1.进入home,创建dockerfile目录,进入该目录vim mydocker(自己改名字也可以)。
cd home/
mkdir dockerfile
cd dockerfile
vim mydocker
复制代码
2.开始写脚本(测试发现之后vim,ifconfig等都没有,先增加功能)
FROM centos:centos7 #基于什么
LABEL \ #镜像基本信息
org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image" \
org.label-schema.vendor="CentOS" \
org.label-schema.license="GPLv2" \
org.label-schema.build-date="2022.5.26" \
org.label-schema.zuozhe="paopao" \
org.label-schema.email="3134912846@qq.com"
ENV MYPATH /usr/local #本地目录
WORKDIR $MYPATH #工作目录 直接用本地目录
RUN yum -y install yum #yum命令
RUN yum -y install net-tools #ifconfig一些命令
EXPOSE 80 #暴露80端口
CMD echo $MYPATH #输出
CMD echo "---end---"
CMD /bin/bash #启动之后进入bash命令行
复制代码
3.开始打包镜像
docker build -f mydockerfile -t mycentos:0.1 .
复制代码
4.测试运行
docker run -it mycentos:0.1
复制代码
以前的默认目录是根目录,现在根据我们设置,工作目录,命令都有了。
然后可以查看镜像历史,我们平时可以研究镜像是怎么做的
docker history 镜像id #可以看到镜像是怎么做的
CMD和ENTRYPOINT的区别
CMD 指定这个容器启动的时候运行的命令,比如cmd echo输出类似于这种,只有最后一个生效,可以被替代。
ENTRYPOINT 指定这个容器启动的时候运行的命令,可以追加命令。
vim dockerfile2 编写dockerfile cmd只执行最后一个命令
FROM centos:7
CMD ["ls","-a"] 用指令的话要加这个框 我们写了一个只有ls的centos测试
docker build -f dockerfile2 -t cmdtest .
然后运行
docker run cmdtest
复制代码
我们想追加一个l 他应该是ls -al,但是是cmd,-l替换了ls-a,-l不是命令,所以报错
换成ls -al就行了
然后我们试一下另一种方法
vim dockerfile3
FROM centos:7
ENTRYPOINT ["ls","-a"]
docker build -f dockerfile3 -t enrtyport .
复制代码
docker run enrtyport
复制代码
功能和之前一样的
docker run enrtyport -l
复制代码
此时可以看出来确实是追加!
写在最后
创作不易,如果觉得内容对你有帮助,麻烦给个三连关注支持一下我!
目前正在更新的系列:从0开始的蓝桥杯省一之路,云原生系列。
感谢各位的观看,文章掺杂个人理解,如有错误请联系我指出~
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4