docker 笔记二
docker容器数据卷
docker镜像可以实例成容器,初始化一个容器时,我们创建容器在不删除的情况会在我们本地系统有一个临时的数据卷,当我们删除容器时数据也就丢失了。
为了解决上面的问题,我们需要把容器的数据存储与容器分离开,容器的数据存储我们希望可以保存到本地,这就是容器数据卷的概念。通过数据卷的概念我们可以实现数据的共享,本地系统和容器共享数据,容器之间也可以共享数据卷。总结下来:就是容器数据的持久化和同步操作,容器数据共享。
数据卷的使用
docker run -it -v 主机目录:容器内目录 -p 主机端口:容器内端口 # 挂载本地数据卷 -v # 用于挂载数据卷,默认持久化目录是/var/lib/docker/volumes # 三种挂载: 匿名挂载、具名挂载、指定路径挂载 -v 容器内路径 #匿名挂载 持久化目录是 /var/lib/docker/volumes -v 卷名:容器内路径 #具名挂载 持久化目录是 /var/lib/docker/volumes -v /宿主机路径:容器内路径 #指定路径挂载 持久化目录是 /宿主机路径 docker volume ls 是查看不到的 docker volume ls #查看所有容器挂载的数据卷,位于/var/lib/docker/volumes目录下 docker volume rm 卷名 #删除容器挂载的数据卷,位于/var/lib/docker/volumes目录下 docker inspect 容器id/容器名 | grep "Mounts" # 查看容器数据挂载情况
测试使用
docker serach ubuntu # 搜索ubuntu镜像 docker pull ubuntu # 拉取镜像 docker run -it -v /home/dcubuntu:/home ubuntu /bin/bash # 已交互方式创建容器,并把把本地目录/home/dcubuntu挂载到容器/home 目录下。
本地修改文件容器同步,实现容器数据同步
docker inspect 容器id/容器名 # 查看挂载情况
删除容器是,本地文件依然存在,实现容器内数据持久化到本地不会随着容器删除而消失
测试三种卷挂载方式
扩展:
# 通过 -v 容器内路径: ro rw 改变读写权限 ro #readonly 只读 rw #readwrite 可读可写 $ docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx $ docker run -d -P --name nginx05 -v juming:/etc/nginx:rw nginx # ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!
案例:多个mysql 实现数据同步
docker网络
在测试docker网络之前,我们需要先停止和删除docker容器,还原初始化的docker网络环境
docker rm -f $(docker ps -aq)
检查一开始的网络状态
问题:docker 是如何处理网络访问的
# 测试 运行一个tomcat $ docker run -d -P --name tomcat01 tomcat # 查看容器内部网络地址 $ docker exec 容器id/容器名 ip addr # 发现容器启动的时候会得到一个 eth0@if91 ip地址,docker分配! $ ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 261: eth0@if91: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0 valid_lft forever preferred_lft forever
docker 容器与宿主机互相ping
我们每启动一个docker容器,docker就会给容器分配一个ip,我们只要按照了docker,就会有一个docker0桥接模式,使用的技术是veth-pair技术。
在启动一个tomcat容器,测试容器之间的网络情况
# 测试 运行一个tomcat docker run -d --name="tomcat01" tomcat # 查看容器内部网络地址 docker exec 容器id/容器名 ip addr # 发现容器启动的时候会得到一个 eth0@if91 ip地址,docker自动分配的 ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 261: eth0@if91: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0 valid_lft forever preferred_lft forever
我们可以发现容器之间可以互相ping通
总结:
网络模型:
tomcat01和tomcat02公用一个路由器,docker0。所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip。
docker 网络通信默认使用的是linux的桥接,宿主机是一个docker容器的网桥docker0,Docker中所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)只要容器删除,对应的网桥一对就没了。
问题:编写了一个微服务,项目重新打包了镜像,docker容器的ip发生了变化,我们希望可以处理这个问题,希望容器之间可以通过名字来进行访问?
运行镜像实例化容器时配置 --link 参数解决容器名之间相互ping通
-- link # 参数使用 相当于在容器内 /etc/hosts 添加主机名与ip映射配置 docker exec tomcat02 ping tomca01 # ping不通 ping: tomca01: Name or service not known # 运行一个tomcat03 --link tomcat02,tomcat01 docker run -d --name="tomcat03" --link tomcat02 tomcat 5f9331566980a9e92bc54681caaac14e9fc993f14ad13d98534026c08c0a9aef # 3连接2 # 用tomcat03 ping tomcat02 可以ping通 docker exec tomcat03 ping tomcat02 PING tomcat02 (172.17.0.3) 56(84) bytes of data. 64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.115 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.080 ms # 2连接3 # 用tomcat02 ping tomcat03 ping不通
探究
docker network inspect bridge # 查看默认桥接网卡下容器的ip信息
docker exec tomcat03 cat /etc/hosts #查看tomcat03里面的/etc/hosts发现有tomcat02的配置
–link 本质就是在hosts配置中添加映射,现在使用Docker已经不建议使用–link了!自定义网络,不适用docker0!docker0问题:不支持容器名连接访问!
通过自定义网络实现容器名之间互相ping
docker network connect -- Connect a container to a network create -- Creates a new network with a name specified by the disconnect -- Disconnects a container from a network inspect -- Displays detailed information on a network ls -- Lists all the networks created by the user prune -- Remove all unused networks rm -- Deletes one or more networks
docker network ls # 查看docker网络模式
docker 三种网络模式
bridge :桥接 docker(默认,自己创建也是用bridge模式)
none :不配置网络,一般不用
host :和所主机共享网络
通过自定义网络来实现容器名之间相互ping通
# 我们直接启动的命令 --net bridge,而这个就是我们得docker0 # bridge就是docker0 docker run -d -P --name tomcat01 tomcat 等价于 => docker run -d -P --name tomcat01 --net bridge tomcat # docker0,特点:默认,容器名之间不能访问。 --link可以打通连接,但是需要自己手动复杂配置 # 可以通过自定义网络来实现容器名之间相互ping通 docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet docker network ls
docker network inspect mynet # 查看网卡下网络信息,可以查看网关和容器ip分配情况
# 创建两个tomcat docker run -d --name="tomcat-net-01" --net mynet tomcat:8.5 docker run -d --name="tomcat-net-01" --net mynet tomcat:8.5 # 测试网络通过容器名互通情况 docker exec tomcat-net-01 ping tomcat-net-01 docker exec tomcat-net-01 ping tomcat-net-01
可以通过容器名实现网络之间的互通
docker network inspect mynet # 查看网卡下网络信息
推荐我们采用自定义网卡来实现容器之间通过容器名实现网络互通。
案例:搭建redis 集群环境