前言
绑定卷bind mount
-v 参数创建卷
功能:
完成卷映射
• 语法
docker run -v name:directory[:options] …
• 参数
○ 第一个参数:宿主机目录,这个和管理卷是不一样的
○ 第二个参数:卷映射到容器的目录
○ 第三个参数:选项,如ro表示readonly–》只读
第一个参数指定的是宿主机目录,那么就是绑定卷,不指定的话·就是管理卷的匿名卷,如果是一个名词,就是管理卷的命名卷
先创建一个专门用来绑定的目录
mkdir -p /data/maxhou/testbind
cd /data/maxhou/testbind
而且这个里面还要是空的
docker run -d --name mynginx6 -v /data/maxhou/testbind:/usr/share/nginx/html nginx:1.24.0
这样就成功了
docker ps
docker inspect mynginx6
bind的意思是绑定
然后我们在宿主机上修改·
ll
但是我们这个目录是空的,不像管理卷,有东西的话,会放过来的
我们直接创建一个首页
vi index.html
现在开始进入容器
docker exec -it mynginx6 bash
cd /usr/share/nginx/html
ll
cat index.html
我们发现·只有一个index.html,没有50x了,而且index.html的内容和宿主机的一样
我们发现这个首页是我们自己创建的,并不是nginx自带的首页
宿主机和容器还是一样的同步的
–mount 参数创建绑定卷
功能:
完成目录映射
• 语法
–mount ‘=,=’
• 关键参数
○ type : 类型表示bind, volume, or tmpfs
○ source ,src :宿主机目录,这个和管理卷是不一样的。
○ destination,dst,target:文件或目录挂载在容器中的路径
○ ro,readonly: 只读方式挂载
mkdir -p /data/maxhou/testmymountbind
docker run -d --name mynginx7 --mount type=bind,src=/data/maxhou/testmymountbind,dst=/usr/share/nginx/html nginx:1.24.0
如果不指定type的话,默认用的是管理卷
docker inspect mynginx7
cd /data/maxhou/testmymountbind
ll
这个里面是空的。对应的容器里面也是空的,就是在创建的时候以宿主机为准,所以是空的·,管理卷是以容器为主的
docker exec -it mynginx7 bash
cd /usr/share/nginx/html
echo “hello” > index.html
exit
这样宿主机和容器里面都有这个文件了
操作案例
mount创建绑定卷
如果宿主机目录不存在—》无法起动
如果宿主机和容器的index.html内容不一样的话,以宿主机的目录为准
docker run -d --name mynginx8 --mount type=bind,src=/data/maxhou/testbindmount1,dst=/usr/share/nginx/html nginx:1.24.0
/data/maxhou/testbindmount1这个目录是不存在的
直接就失败了
docker ps -a | grep mynginx8
而且容器也没有创建成功
mkdir -p /data/maxhou/testbindmount2
cd /data/maxhou/testbindmount2
echo “hello” > index.html
docker run -d --name mynginx8 --mount type=bind,src=/data/maxhou/testbindmount2,dst=/usr/share/nginx/html nginx:1.24.0
在启动一下,就成功了
docker inspect mynginx8
docker exec -it mynginx8 bash
cd /usr/share/nginx/html
cat index.html
就是hello
-v创建绑定卷
如果宿主机目录不存在—》自动创建这个目录
如果宿主机和容器有一个同名文件index.html内容不一样的话,以宿主机的目录为准
docker run -d --name mynginx9 -v /data/maxhou/testbindmount3:/usr/share/nginx/html nginx:1.24.0
/data/maxhou/testbindmount3这个目录是不存在的
直接就创建成功了
ll /data/maxhou/testbindmount3
这个目录直接就存在了
mkdir -p /data/maxhou/testbindmount4
cd /data/maxhou/testbindmount4
echo “hello” > index.html
docker run -d --name mynginx10 -v /data/maxhou/testbindmount4:/usr/share/nginx/html nginx:1.24.00
docker inspect mynginx10
docker exec -it mynginx10 bash
cd /usr/share/nginx/html
cat index.html
里面就是hello
绑定卷共享
一个宿主机的卷对应多个容器,然后修改宿主机能够影响多个容器,都是指向的同一位置
docker run -d -p 8061:80 --name mynginx11 -v /data/maxhou/testbindmount5:/usr/share/nginx/html nginx:1.24.00
cd /data/maxhou/testbindmount5
这个目录是空的还是
echo “hello” > index.html
docker run -d -p 8062:80 --name mynginx12 -v /data/maxhou/testbindmount5:/usr/share/nginx/html nginx:1.24.00
然后都是一样的
修改都是一样的变
临时卷 tmpfs
tmpfs 局限性
• 不同于卷和绑定挂载,不能在容器之间共享 tmpfs 挂载。
• 这个功能只有在 Linux 上运行 Docker 时才可用。
在windows上的docker不能用临时卷
方式一:指定–tmpfs创建
功能:
完成临时卷映射 ,数据在宿主机的内存里
• 语法
–tmpfs /app
/app 是容器的目录,宿主机是在内存上的
docker run -d --name mynginx15 --tmpfs /test1 nginx:1.24.0
docker inspect mynginx15
这个是空的
说明默认不是放在这里
现在进入容器
docker exec -it mynginx15 bash
ll
我们可以发现自动就有了/test1这个目录
这个是空目录
cd test1
echo "hello " > index.html
exit
这个时候我们的容器里面就有一文件了
docker restart mynginx15
docker exec -it mynginx15 bash
ll /test1
这个文件直接就消失了
因为这个临时卷,一旦容器停止了或者重启了,临时卷就消失了
方式二:–mount指定参数创建
功能:
完成目录映射
• 语法
–mount ‘=,=’
• 关键参数
○ type : 类型表示bind, volume, or tmpfs
○ destination,dst,target:挂载在容器中的路径
○ tmpfs-size:tmpfs 挂载的大小(以字节为单位)。默认无限制。就是占用内存的大小
○ tmpfs-mode:tmpfs 的八进制文件模式。例如,700 或 0770。默认为 1777
或全局可写。
少了一个src
docker run -d --name mynginx16 --mount type=tmpfs,dst=/test2 nginx:1.24.0
docker inspect mynginx16
docker exec -it mynginx16 bash
ls /test2
cd /test2
ll
是空的
echo “ssss” > indeex.html
exit
docker restart mynginx16
docker exec -it mynginx16 bash
ls /test2
这个就又消失了
操作案例
tmpfs 参数创建临时卷
临时卷绑定nginx首页目录—》临时卷会把这个目录里面的内容覆盖掉
临时卷能否正确读取这个首页目录呢,虽然临时卷在内存里,但是nginx还是可以读取这个目录了,还是可以正常工作的
docker run -d --name mynginx17 --tmpfs /usr/share/nginx/html/ -p 8087:80 nginx:1.24.0
docker inspect mynginx17
docker exec -it mynginx17 bash
cd /usr/share/nginx/html/
ll
本来这里面有50x.html和index.html的,现在什么都没有了
我们来创建首页的内容
echo “hello” > index.html
这样我们得到nginx就可以正常运行了
docker restart mynginx17
这样我们的首页就消失了
因为数据是在内存里面的,内存里面的数据和/usr/share/nginx/html/是同步的,一旦重启,内存里面的数据丢失,那么/usr/share/nginx/html/里面的内容也没了
mount创建临时卷
nginx里面的文件被覆盖了,也就是说tmpfs也会覆盖容器里面的文件
docker run -d --name mynginx18 -p 8092:80 --mount type=tmpfs,dst= /usr/share/nginx/html/,tmpfs-size=1m nginx:1.24.0
我们这个指定临时卷得到大小为1m的
docker inspect mynginx18
docker exec -it mynginx18 bash
ls /usr/share/nginx/html/
cd /usr/share/nginx/html/
ll
是空的
echo “ssss” > indeex.html
exit
说明nginx并没有感知这是一个内存文件
我们来拷贝一个比较大的目录进入看看
直接传一个比较大的文件进去就可以了
在宿主机上 docker cp xxx.jar mynginx18:/
在容器上
cp /xxx.jar /usr/share/nginx/html/
这样直接就报错了
空间不足了
tmpfs失踪了
就是在临时卷上创建了一个文件,在宿主机上能不能看到这个·文件—》看不到的
docker run -d --name mynginx19 nginx:1.24.0
docker exec -it mynginx19 bash
echo “aaa” > a.txt
在打开一个shell
find / -name a.txt
我们这个是在宿主机上查找,竟然找到了
cat 。。。。。。。
发现也是对的
说明宿主机上可以看到容器里面的文件内容的,可以找到这个文件,存在安全性问题
我们再来用临时卷试试
exit
docker run -d --name mynginx20 --mount type=tmpfs,dst= /test/ nginx:1.24.0
docker exec -it mynginx20 bash
cd /test
echo “aaaa” a2.txt
这样我们在临时卷上就创建了一个文件
我们在另一个shell上
find / -name a2.txt
我们发现是找不到的
说明临时卷是把文件放在我们宿主机上的内存上面的,这样的话宿主机就找不到这个文件了,这样就很安全了,所以保密文件可以存在这个里面,但是要保证容器不要随意销毁了
综合实战-MySQL灾难恢复
我们演示删了容器如何恢复回来卷的数据
mysql存储的数据在这里,我们拷贝这个命令行进行处理
docker run --name mysql12 -e
MYSQL_ROOT_PASSWORD=xxx -v /data/maxhou/mysql12test:/var/lib/mysql -d mysql:5.7
mysql的数据在/var/lib/mysql里面放着
MYSQL_ROOT_PASSWORD是mysql的密码,就是设置的这个容器mysql的密码
这个就是绑定卷和创建容器的命令了
/data/maxhou/mysql12test这个目录会自己创建出来
mysql所有的数据内容都会放在这个宿主机目录里面
docker exec -it mysql12 bash
mysql -h 127.0.0.1 -u root -p
然后就是输入密码
-h是指定要连接的 MySQL 服务器的主机名或者 IP 地址
show database;
create database test;
use test;
create table student(sno int,sname varchar(50));
show tables;
insert into student values(1,‘pony’);
select * from student;
exit
exit
这样就退出容器了
现在开始删除容器
docker rm -f mysql12
强制删除的意思
docker ps -a | grep mysql12
这样就删除成功了
然后我们在启动一个新的容器,绑定到上一个卷同一个目录
docker run --name mysql12new -e
MYSQL_ROOT_PASSWORD=xxx -v /data/maxhou/mysql12test:/var/lib/mysql -d mysql:5.7
docker inspect mysql12new
我们现在进入这个新的容器看数据还在不在
docker exec -it mysql12new bash
mysql -h 127.0.0.1 -u root -p
show databases;
show tables;
select * from student;
我们发现数据都还是在的
exit
exit
我们看到存储卷可以持久化的存储我们的数据,容器删除了也不会影响我们的存储卷数据
MySQL 容器启动时会对数据库进行初始化,生成的数据通过挂载卷映射到宿主机的 /data/maxhou/mysql12test 目录,所以该目录存有数据库信息。
Nginx 容器的 /usr/share/nginx/html 目录在默认情况下没有需要主动写入挂载目录的数据,且挂载时若宿主机对应目录为空也不会有数据复制,因此 /data/maxhou/testbindmount3 为空。
这就是为什么创建同样的绑定卷,为什么nginx对应宿主机目录为空,但是mysql不为空了,因为mysql数据比较重要,如果为空就完犊子了
常见问题
什么时候用Volume,什么时候用bind、tmpfs?
volume:volume 是 docker的宿主机文件系统一部分,用于不需要规划具体目录的场
景
bind:bind mount 完全是依赖于主机的目录结构和操作系统,用于目录需要提前规划,
比如mysql的目录需要个空间大的,其他服务有不占用的时候,用volume就不太合
适了
tmpfs:用于敏感文件存储,文件不想存储的宿主机和容器的可写层之中
扩展思考:存储卷在实际研发中带来了哪些问题
1.
跨主机使用
docker 存储卷是使用其所在的宿主机上的本地文件系统目录,也就是宿主机有一块磁
盘,这块磁盘并没有共享给其他的docker主机,容器在这宿主机上停止或删除,是可
以重新再创建的,但是不能调度到其他的主机上,这也是 docker本身没有解决的问题,
所以docker存储卷默认就是docker所在主机的本地,但是自己搭建一个共享的NFS
来存储docker存储的数据,也可以实现,但是这个过程强依赖于运维人员的能力。
所以未来应用的存储和数据往往分离,越来越多的分布式存储方案出现,如s3系列,
nfs 等。
2.
启动参数未知
容器有一个问题,一般与进程的启动不太一样,就是容器启动时选项比较多,如果下
次再启动时,很容器会忘记它启动时的选项,所以最好有一个文件来保存容器的启动,
这就是容器编排工具的作用。
一般情况下,是使用命令来启动操作docker,但是可以通过文件来读,也就读文件来启
动,读所需要的存储卷等,但是它也只是操作一个容器,如果要几十上百个容器操作,
就需要专业的容器编排工具
这种一般像开源的k8s,各个云厂商也有自己的企业版编排软件。
3.
复杂场景仍然需要运维
对于有状态要持久的集群化组件,如mysql的主从。部署维护一个Mysql主从需要运
维知识、经验整合进去才能实现所谓的部署,扩展或缩容,出现问题后修复,必须要
了解集群的规模有多大,有多少个主节点,有多少个从节点,主节点上有多少个库,
这些都要一清二楚,才能修复故障,这些就强依赖于运维经验
这种复杂的场景往往还是需要人力,很难有完美的工具出现。mysql扩容缩容这些docker解决不了了,还是得靠人来弄来可以
Docker Network(网络)
Docker 为什么需要网络管理
容器的网络默认与宿主机及其他容器都是相互隔离, 但同时我们也要考虑下面的一些
问题, 比如
• 多个容器之间是如何通信的
• 容器和宿主机是如何通信的
• 容器和外界主机是如何通信的
• 容器中要运行一些网络应用(如nginx、web应用、数据库等),如果要让外部也可
以访问这些容器内运行的网络应用应该如何实现
• 容器不想让它的网络与宿主机、与其他容器隔离应该如何实现
• 容器根本不需要网络的时候应该如何实现
• 容器需要更高的定制化网络(如定制特殊的集群网络、定制容器间的局域网)应
该如何实现
• …
上述的这些问题都需要我们对容器的网络进行合理的管理才能解决,这就体现出了容
器网络管理的重要性。
Docker 网络架构简介
Docker 容器网络是为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作
系统的网络环境中独立出来,形成容器自有的网络设备、IP 协议栈、端口套接字、IP
路由表、防火墙等等与网络相关的模块。
Docker 为实现容器网络,主要采用的架构由三部分组成:CNM、Libnetwork 和驱动。
Docker 网络架构采用的设计规范是 CNM(Container Network Model)。 CNM 中规定
了 Docker 网络的基础组成要素:Sandbox、Endpoint、Network。
Endpoint相当于是网络接口
一个endpoint对应一个网络
Sandbox相当于是电脑
Endpoint相当于是网卡
虚线是网线
network是路由器
Sandbox:提供了容器的虚拟网络栈,也即端口、套接字、IP 路由表、防火墙、
DNS 配置等内容。主要用于隔离容器网络与宿主机网络,形成了完全独立的容器网络
环境。
• Network:Docker 内部的虚拟子网,使得网络内的参与者能够进行通讯。
• Endpoint:就是虚拟网络的接口,就像普通网络接口一样,Endpoint 的主要职责
是负责创建连接。Endpoint 类似于常见的网络适配器,那也就意味着一个Endpoint 只
能接入某一个网络, 当容器需要接入到多个网络,就需要多个 Endpoint。
如上图所示,容器 B 有两个 Endpoint 并且分别接入 Networkd A 和 Network B。那么
容器A和容器B之间是可以实现通信的,因为都接入了 NetworkA。但是容器A和容
器C不可以通过容器B的两个Endpoint通信
Libnetwork 是 CNM 的一个标准实现。Libnetwork 是开源库,采用 Go 语言编写(跨
平台的),也是 Docker 所使用的库,Docker 网络架构的核心代码都在这个库中。
Libnetwork 实现了 CNM 中定义的全部三个组件,此外它还实现了本地服务发现、基
于 Ingress 的容器负载均衡,以及网络控制层和管理层等功能
Libnetwork 是CNM的实现
CNM相当于是类
Libnetwork 是对象
驱动
驱动主要负责实现数据层相关内容,例如网络的连通性和隔离性是由驱动来处理的。
驱动通过实现特定网络类型的方式扩展了 Docker 网络栈,例如桥接网络和覆盖网络。
Docker 内置了若干驱动,通常被称作原生驱动或者本地驱动。例如 Bridge Driver、
Host Driver、Overlay Driver、MacVLan Driver、IPVLan Driver、None Driver 等
等。每个驱动负责创建其上所有网络资源的创建和管理。
常见网络类型
bridge 网络 —》默认的网络,一台主机上的容器通信
bridge 驱动会在 Docker 管理的主机上创建一个 Linux 网桥。默认情况下,网桥上
的容器可以相互通信。也可以通过 bridge 驱动程序配置,实现对外部容器的访问。
Docker 容器的默认网络驱动.当我们需要多个容器在同一个Docker主机上通信时,桥
接网络是最佳选择。
2.
host 网络 -->借用宿主机网络
对于独立容器,移除容器和Docker主机之间的网络隔离,并直接使用主机的网络。
当网络堆栈不应该与Docker主机隔离,但是希望容器的其他资源被隔离时,主机网络
是最佳选择。
3.
container 网络 --》借用其他容器网络
这个模式指定新创建的容器和引进存在的一个容器共享一个网络 ,而不是和宿主
机共享。新创建的容器不会创建自己的网卡,配置自己的ip,而是和一个指定的容器
共享ip,端口等,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离
的。两个容器的进程可以通过 lo 网卡设备通信
4.
none网络 --》自己创建网络
Docker 容器拥有自己的Network Namespace,但是,并不为Docker容器进行任
何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。容器完全网络
隔离。
5.
overlay 网络 —》叠加网络,多台主机划分局域网
借助 Docker 集群模块 Docker Swarm 搭建的跨 Docker Daemon 网络。将多个
Docker 守护进程连接在一起,使集群服务能够相互通信。当我们需要运行在不同
Docker 主机上的容器进行通信时,或者当多个应用程序使用集群服务协同工作时,覆
盖网络是最佳选择
docker_484">docker网络管理命令
命令清单
命令 别名 功能 备注
docker network create
创建网络
docker network disconnect
断开网络
docker network ls
docker network list 列出网络
docker network rm
docker network remove 删除1个或者多个网络
docker_network_create_508">docker network create
docker network ls
功能
○ 创建自定义网络
• 语法
Shell
docker network create [OPTIONS] NETWORK
• 关键参数
○ -d, --driver:网络驱动
○ --gateway:网关地址
○ --subnet:表示网段的CIDR格式的子网 ,就是ip地址的范围
○ --ipv6:启用ipv6
docker network create mynet1 --subnet=192.168.0.0/16
docker network ls
这样就创建成功了
驱动是默认的bridge,网桥
docker network inspect mynet1
docker_network_inspect_533">docker network inspect
功能
○ 查看网络详情
• 语法
docker network inspect [OPTIONS] NETWORK [NETWORK…]
• 关键参数
○ -f,–format:指定格式
docker network inspect mynet1 mynet2
可以一次查看多个
docker network inspect bridge
这个可以看到的东西就多了,比如可以看到它对应的容器,就是用网桥的容器
docker_network_connect_546">docker network connect
功能
○ 于将容器连接到网络。可以按名称或ID连接容器。 一旦连接,容器可以与同
一网络中的其他容器通信。
• 语法
Shell
docker network connect [OPTIONS] NETWORK CONTAINER
• 关键参数
○ --ip:指定IP地址
○ --ip6:指定IPv6地址
docker network ls
docker network create mynet4 --subnet=10.2.0.0/16
docker run -dit --name buybox1 busybox
因为buybox默认的shell是sh,要让它的shell长时间运行,就要指定-it,就是要交互,这样的话就会在后台启动一个shell,然后卡住,不然一启动就退出来了
然后进入busybox
docker exec -it busybox1 sh
输入ifconfig
172这个网络是bridge给它的
然后exit
我们来连接
docker network connect mynet4 busybox1
这个就是把busybox1加入mynet4 这个网络了,我们在进入容器
docker exec -it busybox1 sh
ifconfig
我们发现多了一个eth1,就是我们创建网络时的–subnet=10.2.0.0/16
exit
docker network inspect mynet4
这个就是拉网线的作用
docker_network_disconnect_586">docker network disconnect
这个就是剪网线的作用,把容器从网络中断开
功能
○ 断开网络
• 语法
Shell
docker network disconnect [OPTIONS] NETWORK CONTAINER
• 关键参数
○ -f:强制退出
docker network disconnect mynet4 busybox1
这样就把容器从网络中踢出去了
docker inspect mynet4
docker exec -it busybox1 sh
ifconfig
这两个都可以看出网线被拔了
docker_network_prune_604">docker network prune
功能
○ 删除不使用的网络
• 语法
Shell
docker network prune [OPTIONS]
• 关键参数
○ -f, --force :不提示
慎用
docker network ls
docker network prune
docker network ls
只有用一个容器在用这个网络,那么这个网络就是有用的
docker_network_rm_623">docker network rm
功能
○ 删除1个或者多个网络
• 语法
docker network rm NETWORK [NETWORK…]
关键参数
○ -f:强制退出
这个要指定名称,不像上一个全部删除
docker network create mynet1
docker network create mynet2
docker network create mynet3
docker run -dit --name busybox2 busybox
docker network connect mynet3 busybox2
docker network rm mynet1 mynet2 mynet3
我们发现有容器使用的不会被删除
docker_network_ls_641">docker network ls
功能
○ 列出网络
• 语法
docker network ls [OPTIONS]
• 别名
docker network list
• 关键参数
○ -f, --filter:指定过滤条件
○ --format:指定格式
○ --no-trunc:不截断
○ -q, --quiet :仅仅显示id
docker network ls -f name=host
docker network ls --format json
docker network ls --no-trunc
docker network ls -q
网络命令基本操作
docker network create mynet6 --subnet=10.15.0.0/16
docker network ls
docker inspect mynet6
docker run -dit --network mynet6 --name busybox3 busybox
docker ps
docker inspect mynet6
docker inspect busybox3
上面我们采用的是–network
docker run -dit --name busybox4 busybox
docker inspect busybox4
如果不指定网络的话,默认会加入bridge网络
宿主机直接输入ifconfig
我们发现docker0的ip地址就是127的,docker0就是一个网桥,不指定默认都是docker0,默认用docker0桥来通信,也加bridge网络
docker network connect mynet6 busybox4
docker inspect mynet6
busybox3里面只有一个mynet6,因为是用–network加进来的
busybox4是先启动的容器,先加入的bridge网络,然后再加入mynet6的网络,所以就有两根网线
docker network disconnect mynet6 busybox4
docker network disconnect mynet6 busybox3
docker inspect mynet6
docker network rm mynet6
这样就清理干净了
docker network ls
所以加入网络有两种方式,一个是–network,一个connect,没有network,默认为bridge
网络详解
docker_Bridge__697">docker Bridge 网络
概念
Docker Bridge 网络采用内置的 bridge驱动,bridge驱动底层采用的是 Linux 内核中
Linux bridge 技术。就网络而言,bridge网络是在网络段之间转发流量的链路层设备,
而网桥可以是在主机内核中运行的硬件设备或软件设备;就Docker而言,桥接网络使
用软件网桥docker0,它允许连接到同一网桥网络的容器进行通信,同时提供与未连
接到该网桥网络容器的隔离。
容器直接的网络通信用docker0桥bridge,每个容器都连接到这个上面
访问外部网络就用docker0,docker0会连接宿主机网卡也就是eth0,这样就可以链接外部网络了
docker0就是路由器,每个容器的eth0就是网卡,容器的veth就是对应接口
容器就是用户
eth0就是外部资源
两个名字都是一样的
操作案例
容器间的网络通信
我们先清理所有的容器
docker rm -f docker ps -q -a
-q是只显示id的意思,这个用的是英文下的~下的符号括起来的
这样就删除了
docker run -itd --name b1 busybox
docker run -itd --name b2 busybox
docker exec -it b1 sh
ifconfig
再开一个shell
docker exec -it b2 sh
ifconfig
然后我们在第一个容器里面ping第二个容器
ping 172.17.0.3
这样就成功了
说明两个容器是相通的
默认都是加入的bridge网络
docker inspect bridge
这里还可以看到网桥的名称docker0
网关是172.17.0.1
宿主机输入ifconfig
docker0的ip也是172.17.0.1
docker stop b1
docker inspect bridge
bridge网络里面就没有b1了
容器直接默认用docker0,bridge来通信
创建自定义bridge
docker network create mynet4
不指定子网,自动分配子网
不指定-d网络驱动的话,默认就是bridge
docker inspect mynet4
子网是172.27.0.0
网关是172.27.0.1
这个172.27.0.1就是网桥的ip地址
输入idconfig
docker run -itd --name b3 --network mynet4 busybox
docker run -itd --name b4 --network mynet4 busybox
docker inspect mynet4
docker exec -it b3 sh
再开一个shell
docker exec -it b4 sh
b4中输入ifconfig
第二个容器的ip地址是172.27.0.3
b3中输入ping 172.27.0.3发现可以成功
那么在b4中pingb3也是可以的
我们可以自己创建一个网络,然后完成一个容器之间的通信
我们这个可以实现网络的隔离
DNS解析
Docker 自定义桥接网络是支持通过Docker DNS服务进行域名解析的, 也就是说我们
可以直接使用容器名进行通信,因为DNS服务可以解析容器名到IP地址的映射, 但
是默认的 bridge网络是不支持DNS的
域名解析就是把名称转成一个ip地址,域名就是我们容器的名称
docker run -itd --name b51 busybox
docker run -itd --name b52 busybox
默认都加入了bridge网络了
docker exec -it b51 sh
ping b52
这个的意思就是我们通过容器的名称找不到ip地址
在b52中ping b51也是一样的
但是直接ping ip还是可以的
exit
我们在试试自定义网络
docker network create mybridge2
docker inspect mybridge2
我们可以看到分配的子网是172.29.0.0
网关是172.29.0.1
docker run -itd --name b53 --network mybridge2 busybox
docker run -itd --name b54 --network mybridge2 busybox
docker inspect mybridge2
我们可以看到ip地址一个是.2一个是.3
进入b53
docker exec -it b53 sh
ping b54
可以发现直接就ping成功了
直接就把这个名称解析成了172.29.0.3
直接把域名解析成了ip了
自定义桥是支持DNS解析的
端口暴露和转发
暴露方式
端口暴露有2种方式,在启动容器的时候添加端口参数,一种-P暴露所有端口,一种
是-p,暴露指定端口 -P
将指定的容器端口映射至主机所有地址的一个动态端口,·“动态端口”指随机端口,具
体的映射结果可使用docker port命令查看 -p :
将容器端口映射至指定的主机端口
• 端口转发
连接bridge网络的容器只能与连接在当前网络中的容器进行通信。如果一个容器
想要对外提供一些网络服务的话,需要进行端口转发才可以实现。
端口转发将Docker容器的端口映射到宿主机的端口上,那么任何发送到宿主机该端口
的流量,都会被转发到容器的端口中。如下图所示,两个容器内部均开放80端口,它
们分别映射到宿主机的8088和8089端口, 即表示任何发送到8088端口的流量都会
比特就业课
转发到Container 1容器的80端口, 发送到8089端口的流程都会转发到
Container 2 容器的80端口
run的-p就是端口的暴露
转发就是,对宿主机端口的流量跑到容器了
docker run -d --name mynginx1 -p 8060:60 nginx:1.24.0
docker port mynginx1
可以看到端口暴露的信息
第二步就是访问这个端口
很简单的就是让外部服务访问内部服务
docker_Host__852">docker Host 网络
网络介绍
Docker 容器运行默认都会分配独立的Network Namespace隔离子系统, 但是如果基
于host 网络模式,容器将不会获得一个独立的Network Namespace,而是和宿主机
共用同一个Network Namespace,容器将不会虚拟出自己的网卡,IP等,而是直接使用宿主机的IP和端口。
就是直接使用宿主机的namespace,端口也是宿主机的,可能会冲突,说白了就是这个容器没有网络的namespace了,使用的是宿主机的网络的namespace,就是不创建网络的命名空间了
操作案例
docker run -itd --name b61 busybox
docker inspect bridge
就是b61加入了bridge网络
docker run -itd --name b61 --network host busybox
docker inspect host
b62就加入了host网络了
docker exec -it b61 sh
另一个shell
docker exec -it b62 sh
b61 :ifconfig
lo是本地回环网络
eth0就是bridge网络
b62:ifconfig
有一堆
就和宿主机中输入ifconfig一样的
host网络的优点就是性能好,缺点就是容易端口冲突
docker run -d --name mynginx2 --network host nginx:1.24.0
因为端口是网络是共用的,端口也是共用的,所以这个容器要用80端口,就不行了
直接就启动失败了
docker ps -a | grep mynginx2
docker logs mynginx2
可以看出80端口确实被占用了
docker_Container__895">docker Container 网络
网络介绍
Docker Container 的 other container 网络模式是 Docker中一种较为特别的网络的模
式。之所以称为“other container模式”,是因为这个模式下的Docker Container,会使
用其他容器的网络环境。之所以称为“特别”,是因为这个模式下容器的网络隔离性会处
于bridge桥接模式与host模式之间。Docker Container共享其他容器的网络环境,则
至少这两个容器之间不存在网络隔离,而这两个容器又与宿主机以及除此之外其他的
容器存在网络隔离
就是最右边的那个
就是这个容器的网卡ip都去和另一个容器共用了,网络的命令空间和另一个容器共用
操作案例
docker run -itd --name b71 busybox
docker inspect bridge
b71加入了bridge网络
docker run -itd --name b72 --network container:b71 busybox
这样就实现了
docker inspect b72
我们可以看到b72的网络配置是空的
看一些ip信息
docker exec -it b71 sh
if config
exit
docker exec -it b72 sh
if config
exit
我们发现两个容器的ip地址一模一样
docker stop b71
docker exec -it b72 sh
if config
exit
我们发现ip地址直接就消失了,跟着一起消失了,因为第一个容器停掉了,就一起消失了,因为共用的同一个嘛,第二个容器只有一个本地ip地址了,web的这个桥的网络地址ip也消失了—第二个容器就不能和其他容器进行沟通了,因为它只有一个本地的回环网络了
我们重启一下两个容器呢
docker restart b71
docker restart b72
如果只重启一个b71,那么b72还是,没有b71的ip
docker exec -it b71 sh
if config
exit
docker exec -it b72 sh
if config
exit
这样我们发现我创建的桥的网络都加进去了
使用场景
• 针对一些对安全性要求比较高并且不需要联网的应用, 可以使用none网络, 比
如生成随机密码, 避免生成密码被第三方获取。
• 一些第三方的应用可能需要docker帮忙创建一个没有网络的容器, 网络由第三
方自己来配置
因为共用一个网络,所以我们可以直接用端口实现两个容器的互访,效率很高的、缺点就是第一个停掉了,另一个也会服务不可用
docker_none__962">docker none 网络
网络介绍
none网络就是指没有网络。挂在这个网络下的容器除了lo(本地回环),没有其他任何
网卡。 这个连宿主机百度都ping不通
不想要别人知道你,就可以用这个
操作案例
docker run -itd --name b8 --network none busybox
docker inspect none
docker exec -it b8 sh
ifconfig
ping www.baidu.com
ping 宿主机ip也不行
ping 172.17.0.1
这个ping的是docker0,也是不行的,所以无法与其他容器交往