一 。同主机容器互连html
1》网络模式简介
nginx
同一宿主机的网络模型分为四种模式
》》Bridge模式git
建立容器
github
[root@cdh2 ~]# docker run -tid --net=bridge --name c1 centos 5958da9979269f1a7f4bfdb5c2ce9169e530445efa330a0e3e54deb9bb3db261 [root@cdh2 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5958da997926 centos "/bin/bash" 8 seconds ago Up 7 seconds c1查看宿主机自动 生成veth docker0的网桥ip是 172.17.0.1
[root@cdh2 ~]# ip addr 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP link/ether 02:42:42:c1:eb:b7 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:42ff:fec1:ebb7/64 scope link valid_lft forever preferred_lft forever 45: vetha4a973c@if44: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP link/ether 02:5e:3f:c8:aa:c0 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::5e:3fff:fec8:aac0/64 scope link valid_lft forever preferred_lft forever查看ip地址(docker inspect查询的json格式能够用 {{.根节点.子节点.....}}获取对应值) 或者直接用 docker inspect c1 | grep IP
[root@cdh2 ~]# docker inspect -f '{{.Name}} - {{.NetworkSettings.IPAddress }}' c1 /c1 - 172.17.0.2进入shell命令 安装net-tools
[root@cdh2 ~]# docker exec -it c1 /bin/bash [root@0441ad51a806 /]# yum -y install net-tools查看ip地址和网关地址(应该是网桥的ip 172.17.0.1)
[root@0441ad51a806 /]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0 inet6 fe80::42:acff:fe11:2 prefixlen 64 scopeid 0x20<link> ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet) RX packets 2336 bytes 9346632 (8.9 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1716 bytes 96631 (94.3 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0网关(全部ip 走的网关是 172.17.0.1)
[root@0441ad51a806 /]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.17.0.1 0.0.0.0 UG 0 0 0 eth0 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
桥接方式默认的网关是172.17.0.1 能够经过编辑/etc/docker/daemon.json文件,web
添加内容 "bip": "ip/netmask" [ 切勿与宿主机同网段 ] 好比docker
[root@localhost /]# vi /etc/docker/daemon.json {"bip":"192.168.55.1/24"}
使用link方式进行通讯
docker的link机制能够经过一个name(主机名)来和另外一个容器通讯,link机制方便了容器去发现其它的容器而且能够安全的传递一些链接信息给其它的容器(环境变量)
shell
启动第一个nginx容器
json
[root@cdh2 ~]# docker run --name n1 -d -e MYID=1 nginx启动第二个nginx容器 而且link了n1 给n1取一个主机名myn1
root@cdh2 ~]# docker run --name n2 -d --link n1:myn1 nginx 5d1e40750b78e8546723f60ad589da6f1a76b37ee1f70319b087066b9223e608此时n2容器连接了n1 进入n2容器 查看全部环境变量
[root@cdh2 ~]# docker exec -it n2 /bin/bash root@5d1e40750b78:/# env MYN1_ENV_NJS_VERSION=1.13.3.0.1.11-1~stretch MYN1_ENV_NGINX_VERSION=1.13.3-1~stretch MYN1_PORT_80_TCP_ADDR=172.17.0.2 HOSTNAME=5d1e40750b78 NJS_VERSION=1.13.3.0.1.11-1~stretch NGINX_VERSION=1.13.3-1~stretch MYN1_PORT_80_TCP_PORT=80 MYN1_ENV_MYID=1 PWD=/ HOME=/root MYN1_NAME=/n2/myn1 SHLVL=1 MYN1_PORT=tcp://172.17.0.2:80 MYN1_PORT_80_TCP_PROTO=tcp PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin MYN1_PORT_80_TCP=tcp://172.17.0.2:80 _=/usr/bin/env发现n1设置的环境变量 MYID出如今了n2的环境变量中命令 主机名_ENV_变量名
<alias>_PORT_<port>_<protocol> <alias>_PORT_<port>_<protocol>_PORT <alias>_PORT_<port>_<protocol>_PROTO <alias>_PORT_<port>_<protocol>_ADDR其中<port>是在Dockerfile中使用EXPOSE导出的端口,还有docker run 的时候使用-p导出的端口。<protocol>则是这些端口对应的协议。
》》Host模式
centos
若是启动容器的时候使用host模式,那么这个容器将不会得到一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出本身的网卡,配置本身的IP等,而是使用宿主机的IP和端口。可是,容器的其余方面,如文件系统、进程列表等仍是和宿主机隔离的。
浏览器
建立 host模式容器查看ip和路由发现和宿主机是如出一辙
#docker run -tid --net=host --name c2 centos #docker exec -it c2 /bin/bash进入后发现主机名都和宿主机同样
[root@cdh2 ~]# docker exec -it c2 /bin/bash [root@cdh2 /]# ip adr使用ifconfig和route -n也是同样
尝试将新建立的容器c3 绑定到 c1的网络上 共享网络 ip地址应该都是相同
[root@cdh2 ~]# docker run -tid --net=container:c1 --name=c3 centos a01bd6386e89d62ebc807fbff0a30f09f9f4ac864a3eb04a259938930e71ee1c [root@cdh2 ~]# docker exec -it c3 /bin/bash [root@0441ad51a806 /]# yum -y install net-tools [root@0441ad51a806 /]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0 inet6 fe80::42:acff:fe11:2 prefixlen 64 scopeid 0x20<link> ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet) RX packets 6118 bytes 18457579 (17.6 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 4210 bytes 234903 (229.3 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@0441ad51a806 /]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.17.0.1 0.0.0.0 UG 0 0 0 eth0 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0》》 NONE模式
[root@cdh2 ~]# docker run -tid --net=none --name=c3 centos
二。跨主机容器互连
1》端口映射
宿主机能够将容器对应局域网的访问nat出去实现访问外部网络 可是外部网络主机没法访问容器资源 能够在宿主机上开启端口
若是来自外部对该端口的访问 docker经过代理自动路由到绑定的容器端口 好比:
容器启动nginx 获取ip地址
[root@cdh2 ~]# docker inspect n1 | grep IPAddress "SecondaryIPAddresses": null, "IPAddress": "172.17.0.2", "IPAddress": "172.17.0.2",此时宿主机ip地址是(58.144):
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:90:75:c5 brd ff:ff:ff:ff:ff:ff inet 192.168.58.144/24 brd 192.168.58.255 scope global dynamic eno16777736 valid_lft 1421sec preferred_lft 1421sec inet6 fe80::20c:29ff:fe90:75c5/64 scope link valid_lft forever preferred_lft forever经过另一个局域网主机 (58.1) 来直接访问172.17.0.2 是没法访问的
C:\Users\jiaozi>ping 172.17.0.2 正在 Ping 172.17.0.2 具备 32 字节的数据:
58.1仅仅能够访问宿主机 58.144 只能在58.144启动容器是绑定一个端口到容器
docker run --name n3 -p 80:80 -d nginx经过58.1浏览器访问 发现
2》直接路由
经过在Docker宿主机上添加静态路由实现跨宿主机通讯
模拟环境 主机1(192.168.58.144) 设置docker0 网关 (172.17.0.1/16)
主机2(192.168.58.145) 设置docker0 网关 (172.18.0.1/16)
修改方式 编辑 /etc/docker/daemon.json修改以下 两台主机分别设置不同网关
{"bip":"172.18.0.1/16"}重启docker
service docker restart使用ifconfig查看docker0的ip是否修改
docker run -itd --name s1 centos分别查看ip 是不是 172.17.0.2和172.18.0.1
[root@cdh3 ~]# docker inspect s1 | grep IPA "SecondaryIPAddresses": null, "IPAddress": "172.18.0.2", "IPAMConfig": null, "IPAddress": "172.18.0.2",在主机144上 要求能访问 172.18段 添加路由
route add -net 172.18.0.0 netmask 255.255.0.0 gw 192.168.58.145在主机145上 要求能访问 172.17段 添加路由
route add -net 172.17.0.0 netmask 255.255.0.0 gw 192.168.58.145主机两台主机的 ip_forward功能必须开启 不然不会在网卡间转发
[root@cdh2 ~]# sysctl -a | grep net.ipv4.ip_forward net.ipv4.ip_forward = 1若是值不是 1 修改 /etc/sysctl.conf 添加一行
net.ipv4.ip_forward = 1执行命令 sysctl -p 生效便可 成功后 互相ping对方的docker容器的ip发现成功
3》Pipework指定静态ip
Pipework是一个简单易用的Docker容器网络配置工具。由200多行shell脚本实现。经过使用ip、brctl、ovs-vsctl等命令来为Docker容器配置自定义的网桥、网卡、路由等。
使用新建的bri0网桥代替缺省的docker0网桥
bri0网桥与缺省的docker0网桥的区别:bri0和主机网卡之间是也是veth pair 能够为容器分配和主机相同的网段静态ip
模拟环境图
该方式建立的容器 使用none的网络模式 本身定义网桥和网卡等 启动容器时能够经过--net=none指定容器网络模式。
安装网桥
yum install -y bridge-utils查看全部网桥
[root@cdh2 ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242027435aa no
修改网络文件/etc/sysconfig/network-scripts/ifcfg-eno16777736
[root@cdh2 network-scripts]# more ifcfg-eno16777736 TYPE=Ethernet #BOOTPROTO=dhcp BOOTPROTO=none #IPADDR=192.168.58.144 DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no NAME=eno16777736 UUID=1c2310e2-e82e-4ce7-a1aa-60d05aa47f1e DEVICE=eno16777736 ONBOOT=yes PEERDNS=yes PEERROUTES=yes IPV6_PEERDNS=yes IPV6_PEERROUTES=yes BRIDGE="br-ex"将静态ip相关注释 添加 BRIDGE=设备名称 添加一个新的网卡文件ifcfg-br-ex 内容
[root@cdh2 network-scripts]# more ifcfg-br-ex TYPE=Bridge BOOTPROTO=static IPADDR=192.168.58.144 NETMASK=255.255.255.0 GATEWAY=192.168.58.2 PREFIX=24 DNS1=192.168.58.2 NAME=br-ex ONBOOT=yes DEVICE=br-ex重启网卡后 查看网络和网桥
root@cdh2 network-scripts]# ifconfig br-ex: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.58.144 netmask 255.255.255.0 broadcast 192.168.58.255 inet6 fe80::20c:29ff:fe90:75c5 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:90:75:c5 txqueuelen 0 (Ethernet) RX packets 268 bytes 24407 (23.8 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 136 bytes 17574 (17.1 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@cdh2 network-scripts]# brctl show bridge name bridge id STP enabled interfaces br-ex 8000.000c299075c5 no eno16777736 docker0 8000.0242027435aa no下载pipework脚本
[root@cdh2 ~]# git clone https://github.com/jpetazzo/pipework.git进入查看 其中有个文件pipework就是脚本
[root@cdh2 ~]# cd pipework [root@cdh2 pipework]# ll total 60 -rw-r--r-- 1 root root 75 Jun 6 11:28 docker-compose.yml drwxr-xr-x 2 root root 23 Jun 6 11:28 doctoc -rw-r--r-- 1 root root 11358 Jun 6 11:28 LICENSE -rwxr-xr-x 1 root root 14698 Jun 6 11:28 pipework -rw-r--r-- 1 root root 827 Jun 6 11:28 pipework.spec -rw-r--r-- 1 root root 22328 Jun 6 11:28 README.md将该脚本拷贝到/usr/local/bin目录 方便执行
[root@cdh2 pipework]# cp -rp pipework /usr/local/bin
分别添加容器 指定 none网络模式
docker run -itd --net none --name s1 centos
给容器制定固定ip
[root@cdh2 pipework]# pipework br-ex s1 192.168.58.142/24@192.168.58.144 [root@cdh2 pipework]# ping 192.168.58.142 PING 192.168.58.142 (192.168.58.142) 56(84) bytes of data. 64 bytes from 192.168.58.142: icmp_seq=1 ttl=64 time=0.249 mspiepework参数 pipework 网桥名称 容器名称 容器固定ip/24@网桥ip 其余机器上ping 192.168.58.142发现成功 主机2配置同上便可