不同主机之间,实现docker容器网络互通

方式一:直接指定对方的主机IP:端口号

这种方式没什么好讲的,就是类似 192.168.78.105:9000 这种形式。

 

方式二:创建容器时指定使用swarm集群创建的overlay网络

举例:当前有v4、v6两台主机,这两台主机加入了同一个swarm集群。现在在v4上创建一个PHP容器,在v6上创建一个Nginx容器。然后让二者通过容器名网络互通
 

1、在v4上初始化swarm集群
[root@v4 ~]# docker swarm init
Swarm initialized: current node (z0ym10ty5s7u5us1lzd4gvxvy) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-4qgx3twxc35bylme94mkqna1do2z47w62yxqf0fukj4uw8fumx-5nv42b70y8wdck9be0tsvd3qz \
    192.168.78.104:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

 

2、在v6上执行加入集群命令
[root@v6 ~]# docker swarm join \
>     --token SWMTKN-1-4qgx3twxc35bylme94mkqna1do2z47w62yxqf0fukj4uw8fumx-5nv42b70y8wdck9be0tsvd3qz \
>     192.168.78.104:2377
This node joined a swarm as a worker.

 

3、在v4上创建overlay网络,专门用于两台主机上的nginx和php网络通信
docker network create --driver overlay --attachable nginx_php

 

4、创建容器时,指定使用创建的网络
# 在v4上创建php容器
docker pull haveyb/php
docker run -itd --name php -p 9000:9000 --network nginx_php docker.io/haveyb/php
在v6上创建nginx容器
docker pull haveyb/nginx
docker run -itd --name nginx -p 80:80 --network nginx_php docker.io/haveyb/nginx

这时,进入nginx或php容器,就会发现可以直接通过对方的容器名ping 通对方了

[root@v4 ~]# docker exec -it php bash
root@f5303a8db0be:/var/www/html# ping nginx
PING nginx (10.0.0.3) 56(84) bytes of data.
64 bytes from nginx.nginx_php (10.0.0.3): icmp_seq=1 ttl=64 time=0.641 ms
64 bytes from nginx.nginx_php (10.0.0.3): icmp_seq=2 ttl=64 time=0.489 ms
64 bytes from nginx.nginx_php (10.0.0.3): icmp_seq=3 ttl=64 time=1.11 ms
[root@v6 ~]# docker exec -it nginx bash
[root@7aa6ee6747af /]# ping php
PING php (10.0.0.2) 56(84) bytes of data.
64 bytes from php.nginx_php (10.0.0.2): icmp_seq=1 ttl=64 time=0.501 ms
64 bytes from php.nginx_php (10.0.0.2): icmp_seq=2 ttl=64 time=0.499 ms
64 bytes from php.nginx_php (10.0.0.2): icmp_seq=3 ttl=64 time=0.463 ms

这时Nginx配置文件中PHP指向那里就直接可以这样写

location ~ \.php$ {
    fastcgi_pass   php:9000;
    fastcgi_index  index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

这里值得注意的是,如果在一个网络下创建了两个同名容器,那ping 容器名的时候,ping通的将是第一个创建的容器。

比如我现在先在 v4主机上创建了一个名为php的容器,然后在v6上创建了一个名为nginx的容器,一个名为php的容器,它们都加入了nginx_php网络。

那么在v6上的nginx容器里ping php的时候,ping到的结果将是v4上的php容器,而非v6上的php容器

总结:

在编排集群时,我们如果打算在不同主机上组一个集群,比如组一个rabbitmq集群,正常做法就是指定ip和端口号,但是这样一旦某个服务器临时挂了,换服务器,修改就不好修改了。

这时,指定的最好是容器名,代替指定ip。

但是这样做的前提是必须要几个主机都加入了一个docker swarm集群,并且创建了一个用于集群内部沟通的overlay 网络,参考本篇文章。然后在docker-compose.yml 上指定每个服务下的容器都使用这个网络。

还要注意的时,容器名不要起的一样,原来在单机的docker-compose.yml上怎么起,现在还是怎么起,类似这样:zoo1,zoo2,zoo3,zoo4,zoo5,zoo6,一定要区别开来。

这样6台服务器组成一个服务集群,其中一个服务器挂了,也能很快换台服务器,docker-compose up -d 立刻将服务重新加入进去,还不需要其他服务器再重新修改docker-compose.yml,然后重新构建,容错性非常好。