Docker Swarm搭建Overlay网络,实现跨主机通信的排坑记录

前言

这只是一个排坑记录,注意,我非常不建议你继续阅读下去,非局域网搭建overlay完全是吃力不讨好的行为,是个于我而言难以完成的目标

非局域网间使用swarm配置overlay进行容器通信的坑实在太多了,排到最后也没有排干净,放弃了,如果对排坑过程感兴趣,或者你也想实践一下在非局域网间自己搭建一个“局域网”(bushi),请继续阅读吧

另外,对于跨域搭建集群感兴趣的,可以移步我的另一篇博客Java微服务多主机搭建尝试

Step1. 创建overlay虚拟网络

本步骤将Server1和Server2置于同一虚拟网络下,这样才可以进行集群的搭建,下面这篇博客对于swarm的使用技巧总结得十分到位:

Docker搭建Swarm跨主机overlay网络

但需要更正一点,Server2在指定为worker节点时,通过docker network ls是无法看到overlay网络的

这是因为docker的特性所决定的,worker节点没有启动服务的权限,只能通过manager节点指定,因此worker节点也没有直接共享manager的overlay网络的必要,只有在manager在worker节点启动一个服务,并指定服务运行的网络时,worker节点才可以获得对应网络的信息。例如,进行下面的实验

  • 在Server1通过docker stack deploy启动一组服务,其中db服务运行在manager网络,db2服务运行在worker网络
[root@homeforzhu ~]# docker stack deploy -c stack.yml [service_name]

# stack.yml
# Use root/example as user/password credentials
version: '3.1'

services:
  db:
    image: mysql:5.7.25
    # NOTE: use of "mysql_native_password" is not recommended: https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password
    # (this is just an example, not intended to be a production configuration)
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    ports:
      - "3307:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.hostname == [Server1_hostname]
  
  db2:
    image: mysql:5.7.25
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.hostname == [Server2_hostname]

启动成功,在Server2使用docker network ls命令,可以看到[service_name]_default网络的出现:

[root@homeforzhu ~]# docker network ls
kjkalrqh27tq   hotel_default     overlay   swarm

由于实质上上述命令是在两台服务器上创造容器罢了,你也可以通过任何容器的相关操作来验证你的想法,例如在两台服务器上分别使用docker ps,你就会发现db1和db2分别运行在二者上

Step1. 搭建nacos集群,并利用nginx实现反向代理
如何标志化节点

首先,为了便于后续指定在特定的节点上运行容器,我们可以选择以下方案:

  • 为每个节点打上对应的标签:
[root@homeforzhu ~]# docker node update --label-add [key]=[words] [nodeId]

## 对应调度规则:
constraints:
	- node.labels.[key] == [words]
  • 使用节点的hostname & ip & 节点的等级(worker or manager)
## 对应调度规则:
constraints:
	- node.hostname == [server_hostname]
服务与容器的区别

需要注意的是,通过docker stack deploy启动的容器,其名称并非和服务名称是一致的,例如我启动的hotel_db服务下的mysql容器,其名称就是很长一串:

hotel_db.1.wyyfatv70iaguq5v2695bfntt
Swarm默认端口与UDP监听端口冲突导致容器无法通过服务名ping通

此外,由于Swarm默认运行端口是4789,该端口被大多数的云服务器厂商作为UDP的默认端口,不开放给用户,如阿里云官方文档所述:

UDP监听的250、4789和4790三个端口为系统保留端口,暂时不对外开放

因此,Swarm在这个端口上运行时,欲从该端口接受的包将被阻断(发送不会受影响,因此直接使用stack deploy建立服务时,即使是跨主机也仍然可以生效,也符合UDP的特性),从而导致跨主机的服务名直连失败,因为部署在Server1上的Swarm无法接收Server2的消息,从而阻塞(无法通过服务名ping通)

为了解决该问题,在建立Swarm的时候,应额外指定环境变量如下:

[root@homeforzhu ~]# docker swarm init --data-path-port 5789 --advertise-addr [server1_IP]
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值