docker跨主机通信

序言

    脑子里不知道想啥,感觉都是浆糊。。。都是水。。。


    脑子里总是飘着奇怪的数字,2379,2376,6379。。。各种各样的端口,长的都差不多,写着写着就忘记了哪个数字是哪个服务了。。。。错了一个端口,浪费8个小时。。。大写的FUCK


    在跨主机通信的时候,可以使用各种各样的驱动,然而总是在需要通信的那一刻终止。。。。到底是什么阻挡了脚步?是因为爱吗?还是因为责任呢。。。。是什么挡住了那无穷的想象力。。。


    在通信不顺畅的时候,抓包。。。请求都收不到。。。防火墙。。。开放一个端口,不够。。。再来一个。。。FUCK。。。都没有想到是这个端口号记错了。。。


    在一台机器上操作的时候,能够流畅无比,但是,在集群环境下,那就只能just fuck了。。。。各种各样的环境依赖,服务依赖。。。错了一小步,就会导致无法回头的错误。。。

使用docker-machine批量安装docker环境

    在一个集群环境中,想批量安装docker环境并配置服务,有很多种方式,在这里选择的是使用docker-machine进行安装,架构如下:

1、 安装docker-machine

    在使用docker-machine进行批量安装docker的时候,首先安装docker-machine,如下:

[root@docker-ce ~]# curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine && \

chmod +x /tmp/docker-machine && \

sudo cp /tmp/docker-machine /usr/local/bin/docker-machine

    其实就是下载编译二进制包,然后修改执行权限,并且将此文件拷贝到环境变量的路径中。

[root@docker-ce ~]# docker-machine version(检查docker-machine是否安装成功

docker-machine version 0.13.0, build 9ba6da9

2、 配置无密码登录

    在使用docker-machine进行批量安装的时候,由于需要登录到远程主机docker1和docker2,从而需要配置成无密码登录的方式。

[root@docker-ce ~]# ssh-keygen (生成主机密钥对,一路回车即可

Generating public/private rsa key pair.

Enter file in which to save the key (/root/.ssh/id_rsa): 

Created directory '/root/.ssh'.

Enter passphrase (empty for no passphrase): 

Enter same passphrase again: 

Your identification has been saved in /root/.ssh/id_rsa.

Your public key has been saved in /root/.ssh/id_rsa.pub.

The key fingerprint is:

SHA256:27whAu+mDPZzqj25FcbF47Z8nbIav14KbxGeCl6aZac root@docker-ce

The key's randomart image is:

+---[RSA 2048]----+

|                 |

|       .         |

|        +        |

|     . o ..      |

|    . + S. o     |

|     +.++==. .   |

|  o  o+BB+*.+    |

| . =+o*.EB.B     |

|  ..BO. .+O.     |

+----[SHA256]-----+

[root@docker-ce ~]# ssh-copy-id 192.168.1.33(复制公钥

[root@docker-ce ~]# ssh-copy-id 192.168.1.32(复制公钥

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"

The authenticity of host '192.168.1.32 (192.168.1.32)' can't be established.

ECDSA key fingerprint is SHA256:40BPIYtUfwlxArndNoor49Uf6pSOIsSG4vH6U8AUHtA.

ECDSA key fingerprint is MD5:18:73:90:9f:60:c5:a2:6f:37:e1:11:35:13:79:fe:cc.

Are you sure you want to continue connecting (yes/no)? yes

/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed

/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys

root@192.168.1.32's password: 输入远程主机root用户的密码

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '192.168.1.32'"

and check to make sure that only the key(s) you wanted were added.

[root@docker-ce ~]# ssh 192.168.1.32 (登录验证

Last login: Fri Jan 19 05:13:46 2018 from 192.168.1.222

[root@docker1 ~]# exit

logout

Connection to 192.168.1.32 closed.

3、批量安装docker环境并配置启动

[root@docker-ce ~]# docker-machine ls(查看使用安装docker的机器

NAME   ACTIVE   DRIVER   STATE   URL   SWARM   DOCKER   ERRORS

[root@docker-ce ~]# docker-machine create -d generic --generic-ip-address=192.168.1.33 docker2(使用generic的驱动安装ip为192.168.1.33的主机,并且将主机名设置为docker2

Running pre-create checks...

Creating machine...

(docker2) No SSH key specified. Assuming an existing key at the default location.

Waiting for machine to be running, this may take a few minutes...

Detecting operating system of created instance...

Waiting for SSH to be available...

Detecting the provisioner...

Provisioning with centos...

Copying certs to the local machine directory...

Copying certs to the remote machine...

Setting Docker configuration on the remote daemon...

Checking connection to Docker...

Docker is up and running!

To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env docker2

    在进行批量安装的时候,主要做几件事,使用ssh连接到远程主机上(配置无密码登录等原因),安装docker(从dockerhub上下载最新的安装包进行安装),本机生成证书并将证书拷贝到远程主机上,设置远程主机的启动程序,启动远程主机的docker进程。

    这个可能花费的时间比较长,可以使用-D选项进行调试,然后就可以看到详细的执行步骤,并且可以查看远程主机的messages日志文件,会发现更新了很多包,也能看到相关的执行步骤。

[root@docker-ce ~]# docker-machine ls(检查是否安装成功,查看远程主机上的版本

NAME      ACTIVE   DRIVER    STATE     URL                       SWARM   DOCKER        ERRORS

docker1   -        generic   Running   tcp://192.168.1.32:2376           v18.01.0-ce   

docker2   -        generic   Running   tcp://192.168.1.33:2376           v18.01.0-ce 

4 、安装可能出现的问题
    在安装的时候,可能错误,无法获取到远程主机上的docker版本,显示为没有路由到远程的主机:  

[root@docker-ce ~]# docker-machine ls(查看远程主机上的安装情况

NAME          ACTIVE   DRIVER    STATE     URL                       SWARM   DOCKER        ERRORS

docker2   -        generic   Running   tcp://192.168.1.33:2376           Unknown       Unable to query docker version: Get https://192.168.1.33:2376/v1.15/version: dial tcp 192.168.1.33:2376: getsockopt: no route to host

dokcer1       -        generic   Running   tcp://192.168.1.32:2376           v18.01.0-ce 

[root@docker2 system]# firewall-cmd --zone=public --add-port=2376/tcp --permanent(添加防火墙规则

success

[root@docker2 ~]# systemctl restart firewalld(重启firewalld防火墙服务

    在获取远程主机上版本的时候,主要是通过端口2376来进行通信,而防火墙阻挡了这一切,从而需要修改防火墙配置,放行2376端口并且重启防火墙。

5、 其他情况说明

    在生成证书的时候,在本机上和远程主机上都会保存相关的证书信息,而且docker-mahine的配置信息也是保存在此位置,相当于控制的主机,如下所示:

[root@docker-ce ~]# ls -l .docker/(在家目录的隐藏目录.docker目录下

total 4

-rw-------. 1 root root 173 Jan 17 14:52 config.json(保存的是控制机的配置信息,例如docker客户端的版本

drwx------. 4 root root  35 Jan 13 14:34 machine(保存本机和远程主机上证书信息及相关远程主机的配置信息

    远程主机运行的进程时候,已经做了相关的配置,进程也已经启动,查看启动的进程信息:

[root@docker2 ~]# ls -l /etc/docker/(证书保存的配置,使用https进行通信,保证安全性

total 20

-rw-r--r--. 1 root root 1029 Jan 20 05:18 ca.pem

-rw-r--r--. 1 root root   56 Jan 19 03:12 daemon.json

-rw-------. 1 root root  245 Dec 12 21:40 key.json

-rw-r--r--. 1 root root 1679 Jan 20 05:18 server-key.pem

-rw-r--r--. 1 root root 1103 Jan 20 05:18 server.pem

[root@docker2 ~]# cat /etc/systemd/system/docker.service.d/10-machine.conf (启动的配置文件,在单机host环境中不存在此目录,此文件会覆盖默认的启动的配置文件

[Service]

ExecStart=

ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --storage-driver devicemapper --tlsverify --tlscacert /etc/docker/ca.pem --tlscert /etc/docker/server.pem --tlskey /etc/docker/server-key.pem --label provider=generic 

Environment=

[root@docker2 ~]# ps -ef|grep docker(查看启动的docker进程

root      21741      1  0 05:18 ?        00:00:11 /usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --storage-driver devicemapper --tlsverify --tlscacert /etc/docker/ca.pem --tlscert /etc/docker/server.pem --tlskey /etc/docker/server-key.pem --label provider=generic

root      21746  21741  0 05:19 ?        00:00:11 docker-containerd --config /var/run/docker/containerd/containerd.toml

root      21950  17184  0 05:39 pts/0    00:00:00 grep --color=auto docker

[root@docker2 ~]# netstat -tunlpx |grep dockerd(查看docker监听的端口

tcp6       0      0 :::2376                 :::*                    LISTEN      21741/dockerd       

unix  2      [ ACC ]     STREAM     LISTENING     324400   21741/dockerd        /var/run/docker.sock

unix  2      [ ACC ]     STREAM     LISTENING     323509   21741/dockerd        /var/run/docker/metrics.sock

unix  2      [ ACC ]     STREAM     LISTENING     324567   21741/dockerd        /run/docker/libnetwork/fc7eb55d830a15800059dcf61156a80314b2ba7354834170cf198702e586f22e.sock

    在使用多机环境的时候需要注意的是,启动的配置文件已经被覆盖了,如果去修改单机环境中的启动的配置文件是不能生效的,必须要修改新创建的目录下的文件内容才可。

docker跨主机通信

    docker在跨主机通信的时候,可以有很多种选择,在这里使用的是overlay驱动,在使用此驱动的时候,是通过udp的4789端口进行通信。

1、 创建数据库来保存网络信息

    直接使用容器consul来进行运行,如下所示:

[root@docker-ce ~]# docker run -d -p 8400:8400 -p 8500:8500 -p 8600:53/udp -h consul progrium/consul -server -bootstrap

7c698169901a167949ebc048e297d998c90aaa3449d8b2bbf48fa1f7ff72083e

    使用ip加端口直接进行访问,此处是http://192.168.1.222:8500,注意修改成你自己的ip地址

2、 远程主机配置

    在远程主机上要在这个数据库上注册,从而需要修改配置文件,如下所示:

[root@docker2 ~]# cat  /etc/systemd/system/docker.service.d/10-machine.conf (修改的内容为绿色内容

[Service]

ExecStart=

ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --storage-driver devicemapper --tlsverify --tlscacert /etc/docker/ca.pem --tlscert /etc/docker/server.pem --tlskey /etc/docker/server-key.pem --label provider=generic --cluster-store=consul://192.168.1.222:8500 --cluster-advertise=ens33:2376 

Environment=

[root@docker2 ~]# systemctl daemon-reload(重新加载配置文件

[root@docker2 ~]# systemctl restart docker(重新启动服务

    修改的参数中,--cluster-store主要表示为需要连接的kv存储的地址,--cluster-advertise表示使用哪个网卡和端口来进行通信。ens33表示为网卡的名称或者使用主机的ip地址。

    再次查看kv存储,发现已经注册,注意在点击的时候,需要点击docker,然后点击nodes才能看到注册的主机。


3、 创建overlay网络

     只要驱动选择为overlay即可。

[root@docker2 ~]# docker network create -d overlay kel(创建overlay的网络

b13122ee6b6598d430b6ad0a194b65b27c7c6ff2484be102c12f932ad00de342

[root@docker2 ~]# docker network ls(在docker2上能看到创建的overlay的网络,显示的scope为global

NETWORK ID          NAME                DRIVER              SCOPE

7385aa8c4e8c        bridge              bridge              local

91fb3cd46340        host                host                local

b13122ee6b65        kel                 overlay             global

dfd733e10a05        none                null                local

[root@docker1 ~]# docker network ls(在主机docker1上也能看到此网络

NETWORK ID          NAME                DRIVER              SCOPE

eebdc9cef2ad        bridge              bridge              local

09cfc3e66278        host                host                local

b13122ee6b65        kel                 overlay             global

2743c354366c        none                null                local

4、创建容器测试网络连通性

[root@docker1 ~]# docker run -itd --name b1 --network=kel busybox(运行一个网络在kel的容器

026427057b484d5e64dbfd8a3d732469ae5a001cfb00f4f4cdd8059799a4cc34

[root@docker2 ~]# docker run -itd --name b2 --network=kel busybox(在另一台主机上运行一个容器

03f3f96e42eebd70ece2a655dae10c035c512502d68ac48e7cd14d8938e18066

[root@docker1 ~]# docker exec -it b1 sh(跨主机可以ping通

/ # ping -c 2 b2

PING b2 (10.0.0.3): 56 data bytes

64 bytes from 10.0.0.3: seq=0 ttl=64 time=19.570 ms

64 bytes from 10.0.0.3: seq=1 ttl=64 time=3.206 ms

--- b2 ping statistics ---

2 packets transmitted, 2 packets received, 0% packet loss

round-trip min/avg/max = 3.206/11.388/19.570 ms

/ # ip r(查看路由

default via 172.18.0.1 dev eth1 

10.0.0.0/24 dev eth0 scope link  src 10.0.0.2 

172.18.0.0/16 dev eth1 scope link  src 172.18.0.2 

/ # cat /etc/resolv.conf (自带的dns解析

nameserver 127.0.0.11

options ndots:0

/ # ip addr show(有两个网络接口

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

    inet 127.0.0.1/8 scope host lo

       valid_lft forever preferred_lft forever

93: eth0@if94: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue 

    link/ether 02:42:0a:00:00:02 brd ff:ff:ff:ff:ff:ff

    inet 10.0.0.2/24 brd 10.0.0.255 scope global eth0

       valid_lft forever preferred_lft forever

96: eth1@if97: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 

    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff

    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth1

       valid_lft forever preferred_lft forever

5、 问题

    可能出现无法ping通的情况,主要就是查看防火墙的设置,此处主要使用4789的udp进行通信,从而需要开通:

/ # ping -c 2 b1(未开通防火墙

PING b1 (10.0.0.2): 56 data bytes

--- b1 ping statistics ---

2 packets transmitted, 0 packets received, 100% packet loss

[root@docker1 ~]# firewall-cmd --zone=public --add-port=4789/udp --permanent(放行4789的udp端口

success

[root@docker1 ~]# systemctl restart firewalld

/ # ping -c 2 b1(开通了防火墙

PING b1 (10.0.0.2): 56 data bytes

64 bytes from 10.0.0.2: seq=0 ttl=64 time=7.081 ms

64 bytes from 10.0.0.2: seq=1 ttl=64 time=3.788 ms


--- b1 ping statistics ---

2 packets transmitted, 2 packets received, 0% packet loss

round-trip min/avg/max = 3.788/5.434/7.081 ms

    日志中可能出现如下错误:

[ERR] memberlist: Push/Pull with docker2 failed: dial tcp 192.168.1.33:7946: getsockopt: no route to host\n

    也要开启7946的tcp端口,各个主机是要进行通信的。

总结

    1、 在各种各样的环境中,可以使用docker-machine进行统一管理docker。

    2、使用overlay驱动的时候,可以进行跨主机通信。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于第一个问题,我可以为您解答Java UDP网段广播与接收的问题。 首先,UDP是一种无连接的传输协议,它不像TCP那样建立连接,而是直接将数据包发送出去。因此,UDP广播可以实现网段的传输。 下面是一个Java UDP广播和接收的示例代码: 广播端: ```java import java.net.*; public class UDPBroadcaster { public static void main(String[] args) throws Exception { DatagramSocket socket = new DatagramSocket(); socket.setBroadcast(true); String message = "Hello, World!"; DatagramPacket packet = new DatagramPacket(message.getBytes(), message.length(), InetAddress.getByName("255.255.255.255"), 8888); socket.send(packet); socket.close(); } } ``` 接收端: ```java import java.net.*; public class UDPReceiver { public static void main(String[] args) throws Exception { DatagramSocket socket = new DatagramSocket(8888); byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); String message = new String(packet.getData(), 0, packet.getLength()); System.out.println("Received message: " + message); socket.close(); } } ``` 在广播端,我们创建了一个DatagramSocket,并将其设置为广播模式。然后,我们创建一个DatagramPacket,并将其发送到广播地址(255.255.255.255)的端口8888。在接收端,我们同样创建了一个DatagramSocket,并指定端口号为8888。当接收到数据包时,我们可以从DatagramPacket中获取数据,并将其转换为字符串。 接下来,我为您解答第二个问题。如果您想在Docker容器之间实现主机通信,您可以使用Docker网络。Docker网络是一种虚拟网络,它允许Docker容器在同一主机或不同主机之间进行通信。 下面是一个使用Docker网络进行主机通信的示例: 假设我们有两台主机,分别为Host1和Host2。我们在Host1上创建一个名为mynetwork的Docker网络,并在该网络中启动一个名为container1的容器: ``` docker network create mynetwork docker run --name container1 --network mynetwork -d busybox sleep 3600 ``` 然后,在Host2上也创建一个名为mynetwork的Docker网络,并在该网络中启动一个名为container2的容器: ``` docker network create mynetwork docker run --name container2 --network mynetwork -d busybox sleep 3600 ``` 现在,我们可以在container1中ping container2: ``` docker exec container1 ping container2 ``` 在这个示例中,我们使用Docker网络实现了在两台主机之间的容器通信。您可以使用类似的方法在其他应用程序中实现主机通信。 希望以上解答对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值