Docker学习笔记之容器的四种网络模式
2017-10-27 22:40
1171 查看
首先从镜像库pull一个rhel7的镜像下来,这些东西你得玩,光看没意思。
本人pull了前两个镜像进行测试,如果连接失败可以多试几次,连上之后速度不算很差
首先温习一下前面有用到的命令
1.运行NGINX容器,并且将网站默认发布目录与真机的/tmp/website目录进行映射,方便在真机中进行开发:
2. 在宿主机中通过Docker执行命令查看容器ip:
3. 批量终止或者删除容器:
启动容器时可以使用 –net 参数指定,默认是桥接模式。
1.1 Bridge 桥接模式的实现步骤主要如下:
1.2 Host 网络模式
1.3 Container 网络模式
1.4 None 网络模式
接下来讲一下如何在 none 网络模式下为容器分配固定 ip:
直接上命令,少点截图,少浪费点CSDN的存储
虚拟机能够上网,但是容器还上不了网:
最后一步:添加网关使容器可以上网(网关即为docker0的ip):
其实以上命令摘出来主要步骤然后一键脚本执行就可以了,这里只是为了做讲解和效果展示
常用的 namespace 的命令:
添加固定 IP 的 Shell 脚本:
容器端口映射:
通过宿主机ip:8000进行访问
我们修改下默认发布页:
Docker 的端口映射是由 iptables 来实现的
本人pull了前两个镜像进行测试,如果连接失败可以多试几次,连上之后速度不算很差
docker pull richxsl/rhel7 docker pull bluedata/rhel7
首先温习一下前面有用到的命令
1.运行NGINX容器,并且将网站默认发布目录与真机的/tmp/website目录进行映射,方便在真机中进行开发:
docker run -it --name vm1 --net host -v /tmp/website:/usr/share/nginx/html nginx
2. 在宿主机中通过Docker执行命令查看容器ip:
docker exec vm1 ip addr
3. 批量终止或者删除容器:
# docker kill `docker ps -aq` # docker rm `docker ps -aq`
1. 容器的四种网络模式
Docker在创建容器时有四种网络模式,bridge为默认不需要用–net去指定,其他三种模式需要在创建容器时使用–net去指定。bridge模式,使用–net=bridge指定,默认设置。 none模式,使用–net=none指定。 host模式,使用–net=host指定。 container模式,使用–net=container:容器名称或ID指定
启动容器时可以使用 –net 参数指定,默认是桥接模式。
1.1 Bridge 桥接模式的实现步骤主要如下:
(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 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率。
1.2 Host 网络模式
host 模式是 bridge 桥接模式很好的补充。采用 host 模式的 Docker Container,可以直接使用宿主机的 IP 地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换。当然,有这样的方便,肯定会损失部分其他的特性,最明显的是 Docker Container 网络环境隔离性的弱化,即容器不再拥有隔离、独立的网络栈。另外,使用 host 模式的 Docker Container 虽然可以让容器内部的服务和传统情况无差别、无改造的使用,但是由于网络隔离性的弱化,该容器会与宿主机共享竞争网络栈的使用;另外,容器内部将不再拥有所有的端口资源,原因是部分端口资源已经被宿主机本身的服务占用,还有部分端口已经用以 bridge 网络模式容器的端口映射。
1.3 Container 网络模式
(1) 查找 other container(即需要被共享网络环境的容器)的网络 namespace; (2) 将新创建的 Docker Container(也是需要共享其他网络的容器)的 namespace,使用other container 的 namespace。Docker Container 的 other container 网络模式,可以用来更好的服务于容器间的通信。在这种模式下的 Docker Container 可以通过 localhost 来访问 namespace 下的其他容器,传输效率较高。虽然多个容器共享网络环境,但是多个容器形成的整体依然与宿主机以及其他容器形成网络隔离。另外,这种模式还节约了一定数量的网络资源。但是需要注意的是,它并没有改善容器与宿主机以外世界通信的情况。
1.4 None 网络模式
网络环境为 none,即不为 Docker Container 任何的网络环境。一旦 Docker Container 采用了none 网络模式,那么容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。可以说 none模式为 Docker Container做了极少的网络设定,但是俗话说得好“少即是多”,在没有网络配置的情况下,作为 Docker 开发者,才能在这基础做其他无限多可能的网络定制开发。这也恰巧体现了 Docker 设计理念的开放。
接下来讲一下如何在 none 网络模式下为容器分配固定 ip:
netns 是在 linux 中提供网络虚拟化的一个项目,使用 netns 网络空间虚拟化可以在本地虚拟化出多个网络环境,目前 netns 在 lxc 容器中被用来为容器提供网络。 使用 netns 创建的网络空间独立于当前系统的网络空间,其中的网络设备以及 iptables 规则等都是独立的,就好像进入了另外一个网络一样。
直接上命令,少点截图,少浪费点CSDN的存储
[root@lockey6 ~]# docker exec vmx ip addr | grep 192#无结果 [root@lockey6 ~]# ip link add name veth0 type veth peer name veth1#创建对等连接 [root@lockey6 ~]# brctl addif docker0 veth0#将连接的一头加到docker0 [root@lockey6 ~]# docker inspect -f '{{.State.Pid}}' vmx 4850#过滤当前容器进程号 [root@lockey6 ~]# mkdir /var/run/netns#为映射创建目录 [root@lockey6 ~]# ln -s /proc/4850/ns/net /var/run/netns/4850#做软连接/映射 [root@lockey6 ~]# ip link set veth1 netns 4850#将连接的另一头进行针对容器进行设置 [root@lockey6 ~]# docker exec vmx ip addr | grep veth1 11: veth1@if12: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000#发现已经有网卡了 [root@lockey6 ~]# docker exec vmx ip addr | grep eth0 [root@lockey6 ~]# ip netns exec 4850 ip link set veth1 name eth0#修改网卡名称,也可不改 [root@lockey6 ~]# docker exec vmx ip addr | grep eth0 11: eth0@if12: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000#网卡还未起来 [root@lockey6 ~]# ip netns exec 4850 ip link set eth0 up#起容器网卡 [root@lockey6 ~]# docker exec vmx ip addr | grep eth0 11: eth0@if12: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state LOWERLAYERDOWN qlen 1000 [root@lockey6 ~]# ip netns exec 4850 ip addr add 192.168.3.10/24 dev eth0#为容器网卡添加 ip [root@lockey6 ~]# docker exec vmx ip addr | grep eth0 11: eth0@if12: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state LOWERLAYERDOWN qlen 1000 inet 192.168.3.10/24 scope global eth0 [root@lockey6 ~]# docker exec vmx ping 192.168.3.1#测试连同性,无果,因为宿主机一端未起对应网卡 PING 192.168.3.1 (192.168.3.1) 56(84) bytes of data. From 192.168.3.10 icmp_seq=1 Destination Host Unreachable From 192.168.3.10 icmp_seq=2 Destination Host Unreachable ^C[root@lockey6 ~]# ip link set veth0 up#起宿主机网卡 [root@lockey6 ~]# docker exec vmx ping 192.168.3.1 PING 192.168.3.1 (192.168.3.1) 56(84) bytes of data. 64 bytes from 192.168.3.1: icmp_seq=1 ttl=64 time=0.067 ms 64 bytes from 192.168.3.1: icmp_seq=2 ttl=64 time=0.124 ms ^C[root@lockey6 ~]# ping www.baidu.com PING www.a.shifen.com (183.232.231.173) 56(84) bytes of data. 64 bytes from www.sn.10086.cn (183.232.231.173): time=47.3 ms 64 bytes from www.sn.10086.cn (183.232.231.173): icmp_seq=4 ttl=54 time=47.0 ms
虚拟机能够上网,但是容器还上不了网:
[root@lockey6 ~]# docker exec vmx ping www.baidu.com ping: www.baidu.com: Name or service not known [root@lockey6 ~]#
最后一步:添加网关使容器可以上网(网关即为docker0的ip):
[root@lockey6 ~]# ip netns exec 4850 ip route add default via 192.168.3.1
其实以上命令摘出来主要步骤然后一键脚本执行就可以了,这里只是为了做讲解和效果展示
常用的 namespace 的命令:
1. 添加一个 namespace ip netns add [name] 2. 在 namespace 中启用一个设备 ip netns exec [name] ip link set lo up 3. 在 namespace 中新加一个设备 ip link set [dev-name] netns [name] 启用: ip netns exec [name] ip link set [dev-name] up 4. 查看指定 namespace 中指定设备的参数信息 ip netns exec [name] ip addr show [dev-name] permanent scope global 5. 为 namespace 中指定设备设置 ip ip netns exec [name] ip -4 addr add 192.168.1.2/24 brd 192.168.1.255 scope global dev [dev-name] 6.查看所有 network namespace ip netns list 7.ping 虚拟机实例 ip netns exec [name] ping 192.168.1.3
添加固定 IP 的 Shell 脚本:
#/bin/bash if [ -z $1 ] || [ -z $2 ] || [ -z $3 ] || [ -z $4 ] || [ -z $5 ]; then echo "*****Input the necessary parameters: CONTAINERID IP MASK GATEWAY ETHNAME" echo "*****Call the script like: sh static_ip.sh vm1 192.168.1.10 24 192.168.1.1 veth0" exit fiCONTAINERID=$1 SETIP=$2 SETMASK=$3 GATEWAY=$4 ETHNAME=$5 #判断宿主机网卡是否存在 ifconfig $ETHNAME > /dev/null 2>&1 if [ $? -eq 0 ]; then read -p "$ETHNAME exist,do you want delelte it? y/n " del if [[ $del == 'y' ]]; then ip link del $ETHNAME else exit fi fi # pid=`docker inspect -f '{{.State.Pid}}' $CONTAINERID` mkdir -p /var/run/netns find -L /var/run/netns -type l -delete if [ -f /var/run/netns/$pid ]; then rm -f /var/run/netns/$pid fi ln -s /proc/$pid/ns/net /var/run/netns/$pid # ip link add $ETHNAME type veth peer name B brctl addif br3 $ETHNAME ip link set $ETHNAME up ip link set B netns $pid #先删除容器内已存在的 eth0 ip netns exec $pid ip link del eth0 > /dev/null 2>&1 #设置容器新的网卡 eth0 ip netns exec $pid ip link set dev B name eth0 ip netns exec $pid ip link set eth0 up ip netns exec $pid ip addr add $SETIP/$SETMASK dev eth0 ip netns exec $pid ip route add default via $GATEWAY
容器端口映射:
[root@lockey6 ~]# docker run -p 8000:80 -p 8001:443 -it --name web nginx bash
通过宿主机ip:8000进行访问
我们修改下默认发布页:
Docker 的端口映射是由 iptables 来实现的
容器间互联:
--link 参数可以在不映射端口的前提下为两个容器间建立安全连接, --link 参数可以连接一个或多个容器到将要创建的容器。 --link 参数的格式为 --link name:alias,其中 name 是要链接的容器的名称,alias 是这个连接的别名 docker run -it --name web2 --link web:alias nginx bash
相关文章推荐
- docker学习笔记:容器的网络设置
- Docker学习笔记 - Docker容器与外部网络的连接
- Docker学习笔记 — Docker网络总结
- Docker学习笔记-数据卷、数据卷容器
- docker的四种网络模式
- 2.2 docker四种网络模式
- docker学习笔记(三)——容器的常用操作
- docker学习笔记:修改无法启动的容器中的内容
- 携程 Apollo 配置中心 | 学习笔记(四) | 详细介绍携程Apollo配置中心部署至Docker容器
- docker 学习笔记之docker连接网络的设置
- 多主机网络下 Docker Swarm 模式的容器管理
- Docker学习笔记-数据卷、数据卷容器
- vmware 学习笔记==常见虚拟机创建工具(虚拟机3种联网模式+网络模式切换时+配置静态ip时 的网络(网卡VMnetxxx)的配置###不熟悉!!!很常用)
- Docker学习笔记七:Docker网络
- Android-缓存网络图片(MVP模式)学习笔记
- Docker学习笔记四:在容器中管理数据
- docker学习笔记2:容器操作
- Docker 学习笔记【2】 Docker 基础操作实,Docker仓库、数据卷,网络基础学习