问题:
数据在容器中存储,那么我们容器删除,数据就会丢失,相当于数据删库,需要数据可以持久化,存储到本地。
那么如何容器与本地之间有个数据共享/同步?卷如何挂载?
技术:就是卷技术,也就是目录的挂载,将我们容器内的目录,挂载到linux本机上。
首先容器产生的数据持久化到容器的数据库中,如果容器中的文件和linux本机文件系统能够同步。
其次容器间的数据共享
使用命令将容器内的目录进行挂载到主机的目录上
#docker volume ls 查看所有的卷
#docker run -it -v 主机目录:容器内的目录
#docker inspect 容器id 查看挂载分为主机地址-docker容器的地址
一些注意的点:
一般是在启动容器的时候就指定挂载卷,能不能启动后在进行挂载?看参考文章
宿主机目录如果不存在,则会自动生成。
容器停止,宿主机器做的改变容器也会同步
容器删除,宿主机的数据不会删除。
参考文章:
https://blog.csdn.net/qq_39562468/article/details/101716118
https://www.open-open.com/lib/view/open1421996521062.html
#docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 【容器名称】
使用第三方软件进行连接mysql,创建数据库所产生的的文件会同步到主机的挂载的文件目录中。
上述的方法都是指定路径挂载,下面就是区分具名挂载和匿名挂载:
匿名挂载:只写一个容器内的目录路径就是匿名,自动生成id
-v 容器内的目录路径
不写宿主机的目录,但一定要写容器内路径
具名挂载:给宿主机的目录起个名字
具名挂载&匿名挂载:
查看挂载到了什么位置:(挂载到了docker默认所有的卷所在的位置)
#docker volume inspect 卷名字
注意:
#docker run -d -P --name 容器名称 -v 宿主机目录:容器的目录:ro/rw images名称
P大写p就是随机端口
#创建文件,编写脚本命令
(注意命令和参数之间有空格,执行的命令最后有个点)
#FROM centos
#VOLUME [“volume01”,“”] #这是匿名挂载的方法
#CMD /bin/bash
#运行dockerfile文件:
#Docker build -f /home/dockerfile01 -t mycnetos:1.0 .
那么在容器mycentos的/根目录下就有自动生成挂载上的数据卷,和宿主机的文件保持同步。
这样是创建了一个镜像,但没有启动这个镜像的容器
如果忘记了在dockerfile文件中创建数据卷,那么可以启动进行手动挂载 docker run -v方式
容器数据卷:多个容器之间同步数据:
--volume-from命令
#docker run -it docker02 --volumes-from docker01 centos
制作docker镜像的镜像文件就是dockerfile(相当于命令行脚本):
创建脚本文件,镜像一层层,所以脚本命令行一层一层:
#创建文件,编写脚本命令
(注意命令和参数之间有空格,执行的命令最后有个点)
#FROM centos
#VOLUME [“volume01”,“”] #这是匿名挂载的方法
#CMD /bin/bash
#运行dockerfile文件:
#Docker build -f /home/dockerfile01 -t mycnetos:1.0 .
#docker run 运行镜像
#docker pull 发布镜像(可以发布到dockerhup或者阿里云镜像服务)
#CMD命令:
CMD 【“ls”,“-a”】
就是在运行起镜像的时候就会执行命令ls -a
当在运行起镜像的命令行中想要追加l,把命令变为ls -al,但无法实现,CMD无法追加而是执行最后的命令:也就是-l
ENTRYPOINT 【“ls”,“-a”】
当在运行起镜像的命令行中想要追加l,把命令变为ls -al,那么就可以实现,将命令变为ls -al命令
先在宿主机上登录上自己在dockerhup注册的账号和密码:
然后提交创建的镜像:
有可能会报错:
参考文章:
https://blog.csdn.net/shoneworn/article/details/80622268
首先创建的镜像所属的文件名需要和自己在dockerhup上创建的账号一致。否则会报错
其次docker pull的时候需要带上这个镜像的tag版本号,否则默认是latest,有可能找不到这个文件。
#docker tag 【原镜像名称】 【dockerhup账号/文件名称:1.0】
#docker pull 【dockerhup账号/文件名称:1.0】
这样是提交到了dockerhup上,自动创建一个仓库项目,是公开的。
#ip addr 查询ip地址
三个网卡(网络)例如图:
本机回环地址127.0.0.1
阿里云内网地址
docker0地址(桥接模式,使用的技术是evth-pair技术)
创建一个容器,容器内的ip地址完全可以ping通宿主机,互相通信。
容器内的ip地址:
# docker exec dea64af95c3e ip addr
例如产生一对的40-41虚拟设备接口,网卡都是成对出现的技术叫做evth-pair,作为一种桥梁来连接虚拟网络设备。
创建多个容器,多个容器之间也能进行ping通
参考文章:
https://blog.csdn.net/meltsnow/article/details/94490994
如果宿主机不设置网络,那么默认就是docker0来进行(相当于交换机)通信
问题:
容器重启,ip会变化,如何实现容器之间用名字互连通信
方法1:–link命令:
#docker run -it -d -P --name tomcat03 --link tomcat02 tomcat
在启动新的tomcat03容器的时候就已经link上tomcat02,这两者之间就能通信
相当于进入容器修改了 etc/hosts文件,将tomcat03的名称和ip地址填写进了文件,那么DNS解析就能ping到。
方法2:自定义网络(不使用docker0)
#docker network ls 查看所有的网络
#docker network rm 【网络id】删除网络
#docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
#docker run -it -d -p --name tomcat01 --net mynet tomcat
此处--net不设置就是默认桥接,所以设置为自己创建的网络,
好处就是:将容器设置为自己创建的网络,那么网络中的容器之间通信就可以通过名称进行连接与ping通,而且加入到该网络中的容器就自动配置好容器互连
问题:
在docker0网段下的容器tomcat01 如何连接到mynet自定义网络中?
#docker network connect 【自定义网络名称】 【容器名称】
就是在自定义网络中分配了ip地址给容器
使得容器拥有了两个ip地址,例如公网ip ,私网ip