docker file和容器数据卷,发布镜像
容器数据卷
docker的理念是应用和环境包打包城镜像.
那么如果数据在容器中,容器被删除跑路,就嗝屁了,所以数据可以持久化的存储在容器外部
容器数据卷就可以让容器之间有一个数据共享技术.把docker容器产生的数据同步到本地.
注意这个本地是的是操作系统linux不是docker.这是个目录挂载技术,把我们容器内的目录挂载到linux上
使用数据卷,就会把mysql容器内下的/user/mysql数据同步到linux下的/home/mysql中
实现容器之间数据共享以及同步操作
-
方式1 使用命令挂载 -v
docker run -it -v 主机目录:容器内目录
docker run -it --name centos01 -v /home/ceshi:/home centos /bin/bash
此时我们随意在容器内部增删文件夹和文件,在外部镜像的/home/ceshi中就可以看到响应的变动
当容器关闭的时候,我们在主机内对文件进行数据写入,容器在重启后一样会更新,双向更新
挂载语法格式一共有4种
匿名挂载 -v 容器内路径
具名挂载 -v 具名/容器内路径
在上述三种路径后面加:rw或者:ro 例:具名挂载 -v 具名/容器内路径:ro ,ro是read only,rw是read write,指定权限
指定路径挂载 -v /本机路径:/容器内路径
-
安装实战 mysql
运行mysql,需要配置root的账号密码(查看dockerhub的官方文档)
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
我们配置挂载
docker run -d -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql03 mysql:5.7
用navicat什么的可以尝试连接下端口并创建一个数据库看是否有同步挂载
具名挂载和匿名挂载
匿名挂载
-v 容器内路径
不指定主机路径,让他随机生成
docker run -d -P --name tomcat01 -v /ect/nginx nginx
查看所有的volume
$ docker volume --help
Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
匿名挂载格式如下
具名挂载
可以看到匿名会随机生成一大串字符串,不利于后期查找和识别
我们可以给匿名挂载生成的匿名挂载自定义名字,这里注意 /zidingyi:/ect/nginx 如果是/zidingyi 代表的是路径,没有反斜杠代表起别名.
docker run -d -P --name tomcat02 -v zidingyi:/ect/nginx nginx
用docker volume inspect命令查看这个自定义的卷名路径在哪里
例:docker volume inspect zidingyi
方式2 使用dockerfile命令方式挂载
- 首先随便创建一个文件夹和名字,这里我们在创建一个/home/myvolume/dockerfile1 建议文件名用dockerfile
脚本命令如下: 指令都是大写
FROM mysql #填写基于哪个镜像
VOLUME ["/volume01","/volume02"] #同-v 容器内路径 ,是一种匿名挂载方式
CMD echo"---end----" #输出end
CMD /bin/bash #切回交互界面 - docker build 命令用来创建生成dock file
docker build -f dockerfile的文件路径 -t 镜像名字:tag
docker build -f /home/myvolume/dockfile1 -t sxf/mysql:1.0 . 最后一点要加个空格和点
- 启动下自己的容器镜像
镜像进去后 ls -l 查看当前目录文件,发现下面2个挂载目录,这2个目录一定和本地有对应的同步目录
我们在这2个目录下分别创建111,222文件夹,然后去本地用docker inspect 容器id
查找是否有同步更新的文件夹位置
注意这里查找的是镜像ID 不是容器ID
容器数之间的相互继承
容器数据卷上面讲的是容器内和本地系统数据共享.这里举得例子是容器和容器之间的数据共享,以及容器和容器之间的卷组设置继承
容器1 --volumes-from 容器2 这里容器2是父容器, 容器1是子容器,继承关系.容器之间数据共享,只要有一个容器在使用共享数据,其他容器停止或者删除都不会对正在使用共享数据的容器产生影响.
每个容器的共享数据是相互拷贝的概念,而不是单独存在某一个容器中的.
首先拿下载的centos镜像为例,我们先创建一个容器
docker run --name centos01 -v /home/pc_data:/home/container_data -it centos:7.6.1810 /bin/bash
创建了一个镜像和本机的数据卷.接下来我们再开一个镜像,命名为centos02
docker run -it --name docker02 --volumes-from centos01 centos:7.6.1810
这里因为centos01已经创建了,我们只是用--volumes-from 完全拷贝他而已,所以-v的那些数据卷路径不用重复
语法格式 docker run -it --name docker02 --volumes-from 父容器id 镜像名:tag
例2: 我们现在创建一个多个数据库共享数据的案例
第一台mysql创建docker run --name mysql01 -e MYSQL_ROOT_PASSWORD=root -d -p 8080:3306 -v /etc/mysql:/home/mysql_data mysql:5.7
第二胎mysql创建docker run --name mysql02 -e MYSQL_ROOT_PASSWORD=root -d -p 8080:3307 --volumes-from mysql01 mysql:5.7
例3: 自定义容积卷名字,创建容积卷后,可以用docker volume ls查看,但是不自定义名字的话完全看不清哪个容积卷对应哪个,看容器卷对应关系用docker volume inspect 容器卷ID
查看
如果要自定义容积卷名字,需要用create创建 docker volume create aaa
,然后在再-v后面用添加aaa,表示使用aaa这个容积卷的映射关系
docker file
-
docker file 就是通过命令,脚本用来构建docker镜像的构建文件
构建步骤
- 编写dockerfile文件
2.docker build构建成为一个镜像
3.docker run运行镜像 - dokcer push 发布镜像(docker hun,阿里云镜像仓库)
很多官方镜像都是基础包,许多功能都没有,我们需要自己搭建自己的镜像!
- 编写dockerfile文件
-
Dockerfile的docker build更好。docker commit的缺点如下:
1.需要在容器内操作麻烦,效率低。
2.这一点也是最重要的,其他人或者过一段时间后自己也不知道这个镜像是怎么做出来的,都安装了什么。上面我们仅看到增加了94.1M。但是使用Dockerfile构建的镜像,我们看到是执行了apt-get install命令。
既然使用docker commit这么不方便,那我们为什么还要学习它呢?其实仔细想一下docker build的每一步构建出来的镜像是不是就是通过docker commit构建出来的。因此学习docker commit可以让我们更好的理解docker build。
-
Dockerfile的常用命令
命令 功能解释 备注 FROM 基础镜像,一切从这里开始构建 MAINTAINER 镜像的制作者署名,姓名+邮箱 RUN 镜像构建(docker build)时候运行的命令 2种写法,一种和shell命令一样 run yum install -y vim 另一种传参形式 run ["./test.sh","one","two"] 等价于./test.sh one two ADD 将宿主机目录下的文件拷贝进镜像,而且会自动处理url和解压tar包 COPY不能处理url和解压 ADD [hom* /mydir/] [hom?.txt /mydir] [a.txt mydir] [a.xtx /mydir/] [URL /mydir/] COPY 类似docker cp命令,把文件拷贝到镜像 COPY src dest WORKDIR 镜像的工作目录 进入应用后默认的目录,如果没有会自行创建,可以是绝对或者相对路径,也可以写多个,但是如果第一个是绝对路径,那么后面的相对路径会相对第一个绝对路径下来创建 VOLUME 挂在的目录 dockfile写完后,在docker run -v参数中可以进行映射 EXPOSE 保留端口配置 CMD 容器启动后要运行的命令,可以有多个命令但只有最后一个生效,可以被代替 一般ENTERPOINT用来在Dockfile写死命令,CMD 用来传参 ENTRYPOINT 指定这个容器启动时候要运行的命令,可以追加命令 ONBUILD 当构建一个被继承dockerfile 这个时候就会运行onbuild指令,触发指令 USER 指定用什么用户去运行容器 默认是root ENV 设置环境变量 创建一个环境变量,给其他命令引用,比如:ENV MYPATH /home/young 然后WORKDIR $MYPATH 就会创建/home/young文件夹 ENTRYPOINT和CMD搭配使用让CMD为ENTRYPOINT传参的话,需要用json形式写,如果用ENTRYPOINT ls 可能会有BUG无法执行
CMD和RUN运行环境区别 CMD是docker run运行,而RUN是docker build时候运行
CMD命令会被docker run 后面的参数命令覆盖
ENTRYPOINT后面如果跟CMD,那么CMD的作用就是给ENTRYPOINT传参,具体看下面的案例说明
- 创建一个自定义的镜像练习
-
自定义一个dockfile
FROM centos
MAINTAINER YOUNG111@COM
ENV MYPATH /home/local
WORKDIR $MYPATH #设置进入后默认显示路径
RUN yum -y install vim #因为原始镜像没有vim和网络包,先打包到镜像
RUN yum -y install net-tools
EXPOSE 8080
CMD echo $MYPATH
CMD echo "end-----"
CMD /bin/bash
命令:docker build -f dockerfile文件路径 -t 镜像名:tag . #空格+.必须要有
例如docker build -f /home/dockerfile -t mycentos:1.0 . 就可以自行创建一个已经集成vim和网络组件的centos -
创建一个镜像,让他们安装后自动创建一个test.txt文件
file语法
FROM centos
MAINTAINER sxf
ENV MYPTH /home/test
RUN mkdir $MYPTH
RUN touch $MYPTH/test.txt
RUN yum -y install vim
RUN yum -y install net-tools -
制作tomcat镜像(这里java开发没学过,一些环境变量不太理解)
file命令如下:
FROM centos
MAINTAINER sxf
COPY readme.txt /url/local/readme.txt
ADD jdk-8u11-linux-x64-tar.gz /user/local #add命令会自动解压压缩包,并打包到/user/local文件夹
ADD apache-tomcat-9.0.22.tar.gz /user/local
RUN yum -y install vim
RUN yum -y install net-tools
ENV MYPATH /usr/local #设置环境
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_11 #配置java和apache的环境变量
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib;CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out运行容器
docker run -d -p 9090:8080 --name sxf -v /home/sxf/build/tomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test -v /home/sxf/build/tomcat/tomcatlogs:/usr/local/apache-tomcat-9.0.22/logs 镜像id
在本机的test目录中创建WEB-INF,在里面放入xml文件,XML文件内容随便找的,就是个格式
在test目录中写入jsp内容
访问端口即可.
docker发布镜像
-
发布到dockerhub
- 注册dockerhub账号
- 在我们服务器上提交自己镜像
- 使用docker login进行登陆 先-u 在输入密码
- docker push进行发布
-
发布到阿里镜像
- 创建阿里云的容器镜像仓库
- 创建命名空间
- 按照阿里云的操作指南登陆推送
下面是阿里的指南,其中registry.cn-hangzhou.aliyuncs.com/young_docker_study/docker 需要改成自己的镜像名字
比如 docker tag [ImageId] [Imagename]:[Image tag]
docker login --username=石头人服务云 registry.cn-hangzhou.aliyuncs.com
$ docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/_docker_study/docker:[镜像版本号]
$ docker push registry.cn-hangzhou.aliyuncs.com/docker_study/docker:[镜像版本号]
docker把镜像发布到公司自己的仓库
- 下载redistry镜像.相当于一个私服的docker hub网站,用于公司内部共享
docker pull registry - 运行redistry镜像 docker run -d -p 5000:5000 -v 宿主机内路径:容器内路径 --privileged=treu registry
- 在镜像上安装后commit提交 docker commit -m="填写备注" -a="作者信息" 容器id 镜像名:版本号
- curl命令,查看下私服上的镜像信息 curl -XGET http://192.168.1.1:5000/v2_catalog 这里的v2_catalog是个容器名字
- tag命令修改标签
docker tag 镜像:tag Host:port/Repository:tag
这里的tag只是把镜像版本号做一个规范写法
docker 默认是不支持http的推送镜像,因为安全性问题,需要在/etc/docker/daemon.json
(这个是阿里云加速器的设置方法)下再增加一个字段"insecure-registries: ["host:port"]" 这里注意,因为是json格式,这个字段和上面的registry-mirrors字段要有逗号,
修改玩如果不生效,可以重启docker
- 用Push命令推送到仓库 docker push 镜像名:tag
- 重复步骤4验证,看是否新增一个镜像
- pull到本地运行