Docker最厉害的地方在于负载均衡,自动启动并且动态调整(个人认为)

创建虚拟机

这里有个很重要的警告
因为Win和Mac的操作系统的不同,Win的虚拟内存没办法支持大型的项目
对于本项目,在win上可能会需要超过10G的内存
所以,如果你使用的是Win系统,在部署的时候出现内存不足的情况,请减少创建Node节点的数量

这里我们使用的是 Multipass
如果你电脑里没有的话可以考虑一下brew大法 brew install --cask multipass
当你安装完成了之后,可以使用multipass version来检查版本

当Multipass 安装完成后,就可以使用multipass launch docker --name node1
来创建node
这个node就是我们后面实现负载均衡最重要的一部分
在这里我们创建了一个名为node1的节点

创建过程可能会长时间停留在Waiting for initialization to complete
然后等了半天出现time out错误
通过实践,我发现可以在它出现这个错误的时候,使用Control + C将程序挂起,然后继续创建其他node
这样,免去了等待时间,一般在挂起程序后的30秒左右就会完成创建并且分配好IP地址(时间长度取决于机器)

当创建完成后,使用 multipass list 来查看目前的虚拟机情况

虚拟机列表

这里我们为了创建实现,我们多创建几个nodes

multipass launch docker --name node2
multipass launch docker --name node3
multipass launch docker --name node4
multipass launch docker --name node5

使用脚本批量创建nodes


这个是一个小脚本,使用了exp,当捕捉到屏幕输出Waiting for initialization to complete的时候,挂起当前程序,执行下一个创建

#!/usr/bin/expect

# 定义实例名称和其他参数
set instances {PassengerManagement Billing PassengerWebUI DriverManagement Payments DriverWebUI TripManagement Notification APIGetway}
set timeout 2

# 遍历实例名称并创建每个实例
foreach instance $instances {
    spawn multipass launch docker --name $instance
    expect {
        "Waiting for initialization to complete" {
            send_user "Initialization started for $instance. Moving to next instance.\n"
            exp_continue
        }
        timeout {
            send_user "Timeout occurred while launching $instance. Moving to next instance.\n"
        }
    } }

创建并且加入Swarm网络

然后,当创建完成后,你可以使用multipass info node1 来查看node信息

节点信息

接下来,使用 multipass shell node1进入 node 的shell界面

shell界面

你可能注意到前面的ubuntu
没错,这个node实际上就是一个ubuntu
在ubuntu中使用docker version来查看docker的版本,同时也是为了确认node里面是否含有docker

接下来,我们需要以这台机器为核心,创建一个Swarm网络
我们在前面输入multipass info node1的时候,看到这台机器的IP地址是192.168.64.43
那么我们就可以使用这个IP地址,用来创建网络了
输入

docker swarm init --advertise-addr 192.168.64.43

来创建一个Swarm网络

执行成功

然后会返回一行代码

docker swarm join --token SWMTKN-1-60pyoke4w290jzns7uxketm0ns4fm8knl0ytp5z3eol5w7ubru-2csjimiqow7ho8welx4s04h7x 192.168.64.43:2377

这行代码每次执行都是不一样的
记得使用你自己的代码,不要用我这个

复制这段代码,然后在终端中输入exit
然后输入multipass shell node2 切换到node2

在node2中,直接粘贴

粘贴后的返回值

然后,我们可以回到之前的第一个节点,因为第一个节点是创建者
我们在第一个节点中输入docker node ls就可以查看网络内的其他节点了

Swarm工作群

当我们对每一个节点做了同样的事情之后,就可以成功组成一个Swarm网络了
不过有个小问题,就是当你有一堆nodes的时候,要为每一个nodes输入,退出,然后再输入
这个也太 non-cool了!
所以,我弄了个小脚本

使用脚本快速批量创建Swarm网络


initSwarm.exp
这个小脚本会创建一个文本joinCmd.txt 用于储存加入命令(因为命令没办法跨脚本储存)
食用方法:./initSwarm.exp 主节点 主节点的IP
例如:./initSwarm.exp APIGetway 192.168.64.28

#!/usr/bin/expect
# 例如:./initSwarm.exp APIGetway 192.168.64.28
set timeout 10

# 为指定的实例初始化 Docker Swarm
spawn multipass exec [lindex $argv 0] -- bash -c "docker swarm init --advertise-addr [lindex $argv 1]"

# 等待并捕获加入 swarm 的命令
expect {
    -re {docker swarm join --token ([^\s]+) ([^\s]+)} {
        set joinCmd $expect_out(0,string)
    }
    timeout {
        send_user "Timeout occurred while initializing Docker Swarm.\n"
        exit 1
    }
}

# 将加入 swarm 的命令写入文件
set outputFile [open "joinCmd.txt" w]
puts $outputFile $joinCmd
close $outputFile

创建完成后,运行这个脚本就可以批量加入了
joinSwarm.exp

#!/usr/bin/expect
# ./joinSwarm.exp PassengerManagement Billing PassengerWebUI DriverManagement Payments DriverWebUI TripManagement Notification

set timeout 10

# 读取加入 swarm 的命令
set inputFile [open "joinCmd.txt" r]
set joinCmd [read $inputFile]
close $inputFile

# 遍历实例列表并将每个实例加入到 swarm 中
foreach instance [lrange $argv 0 end] {
    spawn multipass exec $instance -- bash -c "$joinCmd"
    expect {
        eof { send_user "Joined $instance to swarm.\n" }
        timeout { send_user "Timeout occurred while joining $instance to swarm.\n" }
    }
}

在节点中部署服务

我们使用一个命令来创建Docker 的 Swarm服务

docker service create –name web –p 8080:3000 –replicas 3 haruharazhang/bcsgcoffee

在这里解释一下命令:

  1. docker service create:

    • 这是Docker命令,用于创建一个新的服务。在Docker Swarm模式下,一个服务是你想要在集群中运行的应用的定义。
  2. –name web:

    • 这个选项用于给新服务命名,名字为web
  3. –p 8080:3000:

    • 这个选项用于映射端口,将服务的3000端口映射到宿主机的8080端口。这意味着,任何发送到宿主机8080端口的流量都会被路由到服务的3000端口。
  4. –replicas 3:

    • 这个选项用于指定服务的副本数量,即希望在Swarm集群中运行多少个该服务的实例。在这个例子中,它创建了3个副本。
  5. haruharazhang/bcsgcoffee:

    • 这是Docker镜像的名称和标签,该服务将从中启动容器。它指向Docker Hub上的一个名为haruharazhang/bcsgcoffee的镜像。Docker将从这个镜像创建容器,并按照你指定的配置运行它们。

这个会从我个人的DockerHub中拉取镜像,为了你能够快速复现,还是建议你使用咱的库存
如果出现库没了的话,那多半是这个库不小心被咱删掉了,你可以考虑用其他node.js的库

Last modification:November 1, 2023
如果觉得我的文章对你有用,请随意赞赏