docker使用Linux桥接网卡,在宿主机虚拟一个docker容器网
(docker0),docker启动一个容器时会根据docker网桥的网段分配给容器 一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网络网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器。
如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过-p或-P参数来启用,访问容器的时候就通过宿主机IP:容器端口访问容器。
这个命令的学习,非常的容易。我们可以直接使用docker network --help进行查看就能够知道有那些命令了。
下面我们解释一下上面的这些命令具体是用来干什么的
命令 | 作用 |
---|---|
docker network create | 创建一个网络 |
docker network ls | 列出有那么些网络 |
docker network connect | 连接网络 |
docker network disconnect | 断开网络 |
docker network prune | 删除不使用的网络 |
docker network inspect | 查看网络详情 |
docker network rm | 删除一个或者多个网络 |
下面我们来演示一下上面命令的使用
此时我们创建了一个网络,我们发现他默认的模式是这个桥接模式(bridge).
我们在将我们刚才创建的网络给删除掉,非常的简单就是普通的curd。最后我们在演示一下这个查看网络详情的命令
类似于json串一样的形式给我们展示出来,由于太长了博主没有全部截取下来。
所有网络的访问,前提是不是得在同一网段。在linux我们可以使用ifconfig和这个ip addr 命令来查看这个。那他到底能干嘛了
我们日常当中连接某个服务,一般是通过服务的ip和端口但是在docker当中如果某个容器重启了那么对应容器的ip地址是会发生变化的。
所以我们应该使用对应的服务名来调用,不能写死ip而应该写死服务名来调用。
如何指定:
下面我们来看一下默认网络IP的生产规则,下面我们我们启动两个ubuntu的容器实列
然后我们再来看看这个u2
我们发现这两个默认的网关是一样的都是这个docker0,我们可以使用ifconfig 进行查看。
那如果我们此时将u1给删除掉了,然后我们再将重新启动一个u3会发生什么了
我们发现此时u3的ip地址是这个之前u1的地址。此时我们就知道随着容器实列的变化他的IP也是会变化的。所以我们在调用部署在docker当中服务的ip我们不能写死。
下面我们来看看这个默认的bridge模式,通过命令进行查看
docker network inspect bridge
Docker服务默认会创建一个docker0的网桥,该网桥的名称我们叫做docker0,它在内核层连通了其他物理或者虚拟网卡,这就将所有的容器放到了同一个物理网络。
下面我们来谈一下这个docker当中bridge模式的步骤
如果我们用一副图来表示那么可以是如下所示:
下面我们可以看一下这个,到底是不是这样的了。下面博主来演示一下这个。下面我们启动一个ubutun的容器实列
docker run -it --name='u1' ubuntu
然后我们使用 ip addr命令进行查看
下面我们进入到容器当中再次查看会是什么效果了?
我们发现确实是成对存在的,虚拟出来了一网络接口设备
但是这个桥接模式也有一定的缺点:
在这里特别需要注意的是这个:
eth设备是成双成对出现的,一端是容器内部命名为eth0,一端是加入到网桥并命名的veth(通常命名为veth),它们组成了一个数据传输通道,一端进一端出,veth设备连接了两个网络设备并实现了数据通信。
2. host模式
下面我们来看看这个host模式,如果采用了这个host模式。当我们docker run 启动一个容器时,容器不会获得独立的Network namespace 而是和宿主机共用一个network namespace 容器不在会虚拟出自己的网卡而是使用宿主机的ip和端口
下面我们来演示一下吧,先启动一个容器实列
docker run -it --name='u2' --network host ubuntu
我们在容器当中输入这个ip addr命令
然后我们在看看宿主机的是什么样子的
我们发现一模一样,确实如上面所说。其次我们可以使用docker inspect 查看容器的情况
这就是host模式,全部使用宿主机的。此时启动容器就不需要使用-p开启端口映射了因为完全使用主机的了。
3.none
none模式使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过-- network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。在这里就不进行演示了,因为不常用。
4.container 容器模式
一种特殊host网络模式,
ontainer网络模式是Docker中一种较为特别的网络的模式。在容器创建时使用– network=container:vm1指定。(vm1指定的是运行的容器名)处于这个模式下的 Docker 容器会共享一个网络环境,这样两个容器之间可以使用localhost高效快速通信。
docker run -it --name=alpine1 alpine /bin/sh
下面我们在启动一个容器,alpine2我们让其和alpine1共享一个网络
docker run -it --network container:alpine1 --name=alpine2 alpine /bin/sh
我们发现他们确实共享一个网络,如果我们此时干坏事我把alpine1容器给关掉了**,共享源我直接给你关了此时我们在次查看alpine2**容器里面的情况会是什么样子的。
我们发现此时对应的虚拟网络接口设备没了。
5.自定义网络
我们之前说了,docker容器的ip可能随着启动和停止导致ip发生变化,我们在连接服务应该写死服务名而不能写死ip。
在docker 当中默认的桥接模式我们使用ping安装地址去ping是可以的,但是使用服务名就不行。
下面我们创建一个自定义的网络,使用如下命令
docker network create ksy_network
docker run -it --network ksy_network --name=alpine1 alpine /bin/sh
docker run -it --network ksy_network --name=alpine2 alpine /bin/sh
然后我们在进入容器当中使用服务名来进行ping,看是否能ping通
我们发现此时是能够ping通的,这也就解决了上面的那个问题,容器ip可能发生变化但是我们使用服务名来搞就行了。有点DNS域名解析的感觉