容器互联可以让多个容器中的应用进行快速交互,他会在源和接收容器之间创建连接关系,接收容器可以通过容器名快速访问到源容器,而不用指定具体IP
一、—link实现容器互联
- 自定义容器名称
- 使用—name可以为容器自定义名称,即使容器重启,名称也不会改变
[root@docker ~]# docker run -d -P —name web training/webapp python app.py
- 容器互联
使用—link name:别名,可以让容器互联
- 创建一个新的数据库容器
[root@docker ~]# docker run -d —name db training/postgres
- 删除之前创建的web容器
[root@docker ~]# docker rm -f web
- 创建一个新的web容器,并连接到db容器上
[root@docker ~]# docker run -d -P —name web —link db:db training/webapp python app.py
- names列出现web/db表明连接成功
- 使用env查看容器环境变量信息
[root@docker ~]# docker run --rm --name web2 --link db:db training/webapp envPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binHOSTNAME=97301899affbDB_PORT=tcp://172.17.0.3:5432DB_PORT_5432_TCP=tcp://172.17.0.3:5432DB_PORT_5432_TCP_ADDR=172.17.0.3DB_PORT_5432_TCP_PORT=5432DB_PORT_5432_TCP_PROTO=tcpDB_NAME=/web2/dbDB_ENV_PG_VERSION=9.3HOME=/root
- DB_开头的环境变量是供web容器连接db容器使用
查看容器hosts文件信息
[root@docker ~]# docker run -it --rm --link db:db training/webapp /bin/bashroot@0318563292e7:/opt/webapp# cat /etc/hosts127.0.0.1 localhost::1 localhost ip6-localhost ip6-loopbackfe00::0 ip6-localnetff00::0 ip6-mcastprefixff02::1 ip6-allnodesff02::2 ip6-allrouters172.17.0.3 db e94a815cfa73172.17.0.4 0318563292e7#使用ping命令测试跟db容器的互通root@0318563292e7:/opt/webapp# ping dbPING db (172.17.0.3): 56 data bytes64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.203 ms64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.060 ms64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.061 ms
二、docker network实现容器互联
由于Docker 所有容器都连接于默认的桥接网络上,因此默认情况下所有容器都是可以互联的,没有隔离,当然这样安全性不好。而服务发现,是在这种环境下发展出来的,通过修改容器内的 /etc/hosts 文件来完成的。凡是 —link 的主机的别名就会出现于 /etc/hosts 中,其地址由 Docker 引擎维护。因此容器间才可以通过别名互访。
但是这种办法并不是好的解决方案,Docker 早在一年多以前就已经使用自定义网络了。在同一个网络中的容器,可以互联,并且,Docker 内置了 DNS,容器内的应用可以使用服务名、容器名、别名来进行服务发现,名称会经由内置的 DNS 进行解析,其结果是动态的;而不在同一网络中的容器,不可以互联。
首先是因为使用 —link 就很可能还在用默认桥接网络,这很不安全,所有容器都没有适度隔离,用自定义网络才比较方便互联隔离。其次,修改 /etc/hosts 文件有很多弊病。比如,高频繁的容器启停环境时,容易产生竞争冒险,导致 /etc/hosts 文件损坏,出现访问故障;或者有些应用发现是来自于 /etc/hosts 文件后,就假定其为静态文件,而缓存结果不再查询,从而导致容器启停 IP 变更后,使用旧的条目而无法连接到正确的容器等。查看docker默认的network网络
[root@tiaoban ~]# docker network lsNETWORK ID NAME DRIVER SCOPEcaee6bf2b989 bridge bridge local35235483549e host host locala88a2e3c1364 none null local
创建自定义网络
[root@tiaoban ~]# docker network create net53552e715eff8cc7bdda68e34851100066562007e4ad0b05ce427c49db6bc933[root@tiaoban ~]# docker network lsNETWORK ID NAME DRIVER SCOPEcaee6bf2b989 bridge bridge local35235483549e host host local53552e715eff net bridge locala88a2e3c1364 none null local
启动两个测试容器,测试连通性 ```bash [root@tiaoban ~]# docker run -d —name=test1 —network net centos:v1 c7a070a1f7c3e82ae4b24cb91ef247b93fdf2e10addfc3de3e0bd65e64f7f0d2 [root@tiaoban ~]# docker run -d —name=test2 —network net centos:v1 5bfff025adb509f44389b61b0ae02e622798bc0ae1f2f3bfa5fc5cc24c3a949b [root@tiaoban ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5bfff025adb5 centos:v1 “sh /sleep.sh” About a minute ago Up About a minute test2 c7a070a1f7c3 centos:v1 “sh /sleep.sh” About a minute ago Up About a minute test1 [root@tiaoban ~]# docker exec -it test1 bash [root@458a6d423fa4 /]# ping test2 PING test2 (172.18.0.3) 56(84) bytes of data. 64 bytes from test2.net (172.18.0.3): icmp_seq=1 ttl=64 time=0.140 ms 64 bytes from test2.net (172.18.0.3): icmp_seq=2 ttl=64 time=0.103 ms ^C —- test2 ping statistics —- 2 packets transmitted, 2 received, 0% packet loss, time 6ms rtt min/avg/max/mdev = 0.103/0.121/0.140/0.021 ms [root@458a6d423fa4 /]# cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.18.0.2 458a6d423fa4 [root@458a6d423fa4 /]# nslookup test2 Server: 127.0.0.11 Address: 127.0.0.11#53
Non-authoritative answer: Name: test2 Address: 172.18.0.3
[root@458a6d423fa4 /]# cat /etc/re
redhat-release resolv.conf
[root@458a6d423fa4 /]# cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0
- 通过上述实验可知,通过network互联的容器,并没有像--link那样,在/etc/hosts中记录解析信息,而是通过Docker内置的DNS进行动态解析。4. 在默认的bridge网络创建容器,测试能否与net网络容器连接```bash[root@tiaoban ~]# docker run --name test3 -d centos:v170258796480f1c90dc69bfc26de8b2b6bb53a1b7b0146ed4b0d51fc6d74d1ef9[root@tiaoban ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES70258796480f centos:v1 "sh /sleep.sh" 3 seconds ago Up 1 second test35bfff025adb5 centos:v1 "sh /sleep.sh" 3 minutes ago Up 3 minutes test2c7a070a1f7c3 centos:v1 "sh /sleep.sh" 3 minutes ago Up 3 minutes test1[root@tiaoban ~]# docker exec -it test3 ping 172.18.0.3PING 172.18.0.3 (172.18.0.3) 56(84) bytes of data.^C--- 172.18.0.3 ping statistics ---11 packets transmitted, 0 received, 100% packet loss, time 285ms
- 即便bridge和net共用一个DRIVER,由于他们属于不同的隔离网络,即使通过IP也不能互联访问
- 创建新容器,使用net网络,测试能否暴露端口提供访问
```bash
[root@tiaoban ~]# docker run -d —name=nginx -p 80:80 —network net nginx
09c176a268f61c2441ffba4197e29c18c527b2f8c3c58ca35468163fd2685ee2
[root@tiaoban ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
09c176a268f6 nginx “/docker-entrypoint.…” 6 seconds ago Up 5 seconds 0.0.0.0:80->80/tcp nginx
70258796480f centos:v1 “sh /sleep.sh” About a minute ago Up About a minute test3
5bfff025adb5 centos:v1 “sh /sleep.sh” 5 minutes ago Up 5 minutes test2
c7a070a1f7c3 centos:v1 “sh /sleep.sh” 5 minutes ago Up 5 minutes test1
[root@tiaoban ~]# curl 127.0.0.1
<!DOCTYPE html>
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to
nginx.org.
Commercial support is available at
nginx.com.
Thank you for using nginx.
```- 实验得知创建的自定义网络,通过bridge网桥,可以挂载主机端口对外提供访问
