Docker网络模式介绍
Docker在创建容器时有四种网络模式:bridge/host/container/none,bridge为默认不需要用–net去指定,其他三种模式需要在创建容器时使用–net去指定
以下是 docker 网络初始化的过程:
1.bridge模式(默认模式)
docker run时使用–net=bridge,这种模式会为每个容器分配一个独立的Network Namespace, 同一个宿主机上的所有容器会在同一个网段下,相互之间是可以通信的
注1:bridge为默认模式,不需要使用参数–net去指定,使用了–net参数反而无效
注2:bridge模式无法指定容器IP(但非绝对
(1) Docker Daemon 利用 veth pair 技术,在宿主机上创建两个虚拟网络接口设备,假设为
veth0 和 veth1。而 veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会将
报文传输给另一方。
(2) Docker Daemon 将 veth0 附加到 Docker Daemon 创建的 docker0 网桥上。保证宿主机的网络报文可以发往 veth0;
(3) Docker Daemon 将 veth1 添加到 Docker Container 所属的 namespace 下,并被改名为 eth0。
如此一来,保证宿主机的网络报文若发往 veth0,则立即会被 eth0 接收,实现宿主机到
Docker Container 网络的联通性;同时,也保证 Docker Container 单独使用 eth0,实现容器网
络环境的隔离性。
bridge 桥接模式下的 Docker Container 在使用时,并非为开发者包办了一切。最明显的是,
该模式下 Docker Container 不具有一个公有 IP,即和宿主机的 eth0 不处于同一个网段。导致
的结果是宿主机以外的世界不能直接和容器进行通信。虽然 NAT 模式经过中间处理实现了
这一点,但是 NAT 模式仍然存在问题与不便,如:容器均需要在宿主机上竞争端口,容器
内部服务的访问者需要使用服务发现获知服务的外部端口等。另外 NAT 模式由于是在三层
网络上的实现手段,故肯定会影响网络的传输效率。
2.host模式
docker run时使用–net=host,容器将不会虚拟出IP/端口,而是使用宿主机的IP和端口。容器启动什么端口,如果外边要访问的话就通过 宿主机器ip: + 容器中启动的端口 访问
docker run -itd --net=host 961769676411
注1:host模式不能使用端口映射和自定义路由规则,这些都与主机一致,-p 与-icc 参数是无效的
host 模式是 bridge 桥接模式很好的补充。采用 host 模式的 Docker Container,可以直接使用
宿主机的 IP 地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公
有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换。当然,
有这样的方便,肯定会损失部分其他的特性,最明显的是 Docker Container 网络环境隔离性
的弱化,即容器不再拥有隔离、独立的网络栈。另外,使用 host 模式的 Docker Container 虽
然可以让容器内部的服务和传统情况无差别、无改造的使用,但是由于网络隔离性的弱
化,该容器会与宿主机共享竞争网络栈的使用;另外,容器内部将不再拥有所有的端口资
源,原因是部分端口资源已经被宿主机本身的服务占用,还有部分端口已经用以 bridge 网
络模式容器的端口映射。
3.container模式
(1) 查找 other container(即需要被共享网络环境的容器)的网络 namespace;
(2) 将新创建的 Docker Container(也是需要共享其他网络的容器)的 namespace,使用
other container 的 namespace。
Docker Container 的 other container 网络模式,可以用来更好的服务于容器间的通信。
在这种模式下的 Docker Container 可以通过 localhost 来访问 namespace 下的其他容器,传输
效率较高。虽然多个容器共享网络环境,但是多个容器形成的整体依然与宿主机以及其他
容器形成网络隔离。另外,这种模式还节约了一定数量的网络资源。但是需要注意的是,
它并没有改善容器与宿主机以外世界通信的情况。
4.none模式
网络环境为 none,即不为 Docker Container 任何的网络环境。一旦 Docker Container 采用了
none 网络模式,那么容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。 可以说 none 模式为 Docker Container 做了极少的网络设定,但是俗话说得好“ 少即是多” ,在 没有网络配置的情况下,作为 Docker 开发者,才能在这基础做其他无限多可能的网络定制 开发。这也恰巧体现了 Docker 设计理念的开放。 在 none 网络模式下分配固定 ip: netns 是在 linux 中提供网络虚拟化的一个项目,使用 netns 网络空间虚拟化可以在本地虚拟 化出多个网络环境,目前 netns 在 lxc 容器中被用来为容器提供网络。 使用 netns 创建的网络空间独立于当前系统的网络空间,其中的网络设备以及 iptables 规则
等都是独立的,就好像进入了另外一个网络一样。(不常用)
这种方式创建没有网络,可以自己指定设置网络。
以上四种均未跨主机,也就是说容器均运行在一台宿主机上,但实际生产环境不可能只用一台来跑。肯定会用到多台,那么多台主机之间的容器如何通信
1.使用路由机制打通网络
2.使用Open vSwitch(OVS)打通网络
3.使用flannel来打通网络
4.使用Quagga来实现自动学习路由
注1:详情见 https://www.cnblogs.com/yy-cxd/p/6553624.html
外部访问docker容器
Docker的使用
外部访问Docker容器
首先拉取Tomcat镜像容器
docker pull Tomcat:8
使用默认的模式:
docker run -di --name mytomcat001 -p 8081:8080 {tomcat的端口}
这里使用host模式
docker run -itd --net=host 镜像ID
查看容器是否在运行
docker ps
如果是在运行的话就可以了,然后打开游览器输入ip加端口就可以访问Tomcat了
Docker发布springcloud项目(测试一个注册中心)
1.查看我的项目是否能够运行
2.修改父工程的pom,添加 < packaging>jar</ packaging>标签
3.在各个子 module 模块的 pom.xml 文件中添加插件依赖,将原本的替换掉
<build>
<plugins>
<!--添加maven插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--添加自己的启动类路径!-->
<mainClass>!!!这里是该启动类的路径!!!</mainClass>
</configuration>
<executions>
<execution>
<goals>
<!--可以把依赖的包都打包到生成的Jar包中-->
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
4.点击 idea 的 view ——> Tool windows ——> maven projects先双击 clean(去掉之前打的包target文件夹)——> 再创建 install
项目的target文件下会有一个jra包
5.将这个架包copy出来放到一个文件夹下面,测试是否能够继续运行,按住shift键
输入运行的命令 java -jar microservice-eureka-server.jar --spring.profiles.active=eureka2001
测试成功
6.宿主机创建文件夹 apps,rz 上传 eureka-server-cluster.jar包 到 apps文件夹中。此目录稍后作为数据卷,在宿主机和容器之间共享数据
mdir apps
7.宿主机修改 hosts 文件,加入虚拟的映射
vim /etc/hosts
在文件的下面加入下面代码就行,:wq保存并退出
## 在里面添加要映射的域名即可
127.0.0.1 eureka2001.hu.com
127.0.0.1 eureka2002.hu.com
8.使用 jre:8 镜像 启动容器,并挂载指定目录为数据卷也就是说apps是作为一个共享目录而存在,所有的容器都能访问它。
docker run -di \
--net=host \
--name eureka-server-peer1 \
--mount type=bind,source=/javadj_docker/apps,target=/javadj_docker/apps \
[这里是jre镜像的ID]
9.进入容器,java命令启动微服务
进入容器
docker exec -it eureka-server-peer1 /bin/sh
切换到apps文件夹下面,启动
java -jar microservice-eureka-server.jar --spring.profiles.active=eureka2001
如果在访问的时候如果访问不了,请先检查防火墙状态。如果是打开着的就直接将它关闭
systemctl stop firewalld.service
systemctl disable firewalld.service