引言
MQTT 是一种轻量级的消息传递协议,适用于物联网应用实现设备间通信。 作为一款主流的开源 MQTT Broker,EMQX 能够提供高扩展性、可靠性和安全性的 MQTT 消息传递服务。
借助广泛应用的基础设施即代码(IaC)工具 Terraform,您可以轻松在 GCP 上自动部署 EMQX MQTT Broker,从而简化和规范 MQTT 基础设施的设置和管理。
本文将指导您如何设置 GCP 项目、创建服务账户、编写 Terraform 配置文件,实现轻松部署 EMQX MQTT Broker。
准备工作
在开始之前,请做好以下准备:
- 注册 Google Cloud Platform 账户
- 在您的本地机器上安装 Google Cloud SDK
- 在您的本地机器上安装 Terraform
- 对 GCP、Terraform 和 MQTT 有基本的了解
配置 GCP 环境
按照以下步骤配置 GCP 环境:
- 创建新的 GCP 项目或使用已有的项目(Project)。
- 为您的项目启用所需的 API(Compute Engine API)。
- 为 Terraform 创建具有所需权限的服务账户。建议使用 Compute Engine Admin 角色。
- 下载 JSON 密钥文件。
使用 Terraform 在 GCP 上部署 EMQX
配置 Terraform
在您的 Terraform 代码中配置 GCP Provider,并使用服务账户密钥文件进行认证。
provider "google" {
credentials = file("<PATH-TO-KEY-FILE>")
project = "<PROJECT-ID>"
region = "<REGION>"
zone = "<ZONE>"
}
配置网络
这一步需要了解 GCP 相关的三个基本术语:项目、VPC 和子网(Subnet)。这些术语的定义如下:
- 项目是 GCP 中的顶层组织单元,包含所有的资源。
- VPC 是在 GCP 项目内定义的私有网络,允许您创建和管理 IP 地址、子网和路由表。
- 子网是将 VPC 网络划分为更小、更易于管理的部分的一种方式。它们可以为特定的资源分配 IP 地址,并定义不同的网络段。
它们之间的关系可以用下图来说明:
创建 VPC 网络
我们需要创建一个 VPC 网络,为您的网络相关资源提供连接,其中包括:
- Compute Engine 虚拟机实例
- Container Engine 容器
- App Engine Flex 服务
- 其他网络相关资源
resource "google_compute_network" "vnet" {
project = "<PROJECT>"
name = "<NAME>"
auto_create_subnetworks = false
}
在 VPC 中创建子网
每个 VPC 网络都被划分为若干子网,这里我们创建一个子网。
resource "google_compute_subnetwork" "sn" {
name = "<NAME>"
ip_cidr_range = cidrsubnet(var.address_space, 8, 1)
region = var.region
network = google_compute_network.vnet.id
}
创建防火墙规则
每个网络都有自己的防火墙,控制着实例之间以及实例与外部的访问。除非创建防火墙规则允许访问实例,否则所有到实例的流量,包括来自其他实例的流量,都会被防火墙阻止。
“ports” 定义了一些与 MQTT 相关的端口,例如 “1883”、“8883”、“8083”、“8084”。
resource "google_compute_firewall" "fw" {
name = "<NAME>"
network = google_compute_network.vnet.name
source_ranges = ["0.0.0.0/0"]
allow {
protocol = "icmp"
}
allow {
protocol = "tcp"
ports = "<PORTS>"
}
}
配置 EMQX 集群
为每个 EMQX 节点创建虚拟机实例
虚拟机实例可以用于部署应用、运行服务或执行计算任务。
在下面的示例中,我们创建了一个名为 example-instance 的 google_compute_instance 资源,并指定了 name、machine_type、boot_disk、network_interface 属性。
resource "google_compute_instance" "example" {
name = "example-instance"
machine_type = "n1-standard-1"
boot_disk {
initialize_params {
image = ""ubuntu-os-cloud/ubuntu-2004-lts""
}
}
network_interface {
network = google_compute_network.example.name
subnetwork = google_compute_subnetwork.example.name
access_config {
// Ephemeral external IP
}
}
}
启动 EMQX 节点
创建虚拟机实例后,需要初始化每个 EMQX 节点。首先,您必须初始化并复制 init.sh 到每个节点。然后下载 EMQX 包并在每个节点上执行刚才复制的 init.sh。最后,分别启动 EMQX。
resource "null_resource" "init" {
depends_on = [google_compute_instance.example]
count = "<INSTANCE-COUNT>"
connection {
type = "ssh"
host = "<HOST-LIST>"
user = "ubuntu"
private_key = "<YOUR-PRIVATE-KEY>"
}
# config init script
provisioner "file" {
content = templatefile("${path.module}/scripts/init.sh", { local_ip = <PRIVATE-IPS>[count.index],
emqx_lic = <EMQX-LICENSE>, emqx_ca = <EMQX-CA> emqx_cert = <EMQX-CERT>, emqx_key = <PRIVATE-KEY> })
destination = "/tmp/init.sh"
}
# download EMQX package
provisioner "remote-exec" {
inline = [
"curl -L --max-redirs -1 -o /tmp/emqx.zip <EMQX-PACKAGE-URL>"
]
}
# init system
provisioner "remote-exec" {
inline = [
"chmod +x /tmp/init.sh",
"/tmp/init.sh",
"sudo mv /tmp/emqx <HOME>",
]
}
# start EMQX
provisioner "remote-exec" {
inline = [
"sudo <HOME>/bin/emqx start"
]
}
}
将 EMQX 节点加入集群
随机选择 EMQX 集群中的一个节点,然后逐个将其他节点加入该节点。
resource "null_resource" "emqx_cluster" {
depends_on = [null_resource.init]
count = "<INSTANCE-COUNT>-1"
connection {
type = "ssh"
host = <OTHERS>[count.index % <OTHERS>]
user = "ubuntu"
private_key = "<YOUR-PRIVATE-KEY>"
}
provisioner "remote-exec" {
inline = [
"/home/ubuntu/emqx/bin/emqx_ctl cluster join emqx@${local.another_emqx}"
]
}
}
配置负载均衡
在上面的示例中:
- 创建了一个 google_compute_http_health_check 资源,用于配置健康状态检查。
- 创建了一个 google_compute_target_pool 资源,它引用了实例组和健康状态检查。
- 创建了一个 google_compute_forwarding_rule 资源,它设置了转发规则,将 1883 端口的入站流量路由到目标池。
- 还可以为其它端口(“8883”、“8083”、“8084”、“18083”)添加更多的 google_compute_forwarding_rule。
resource "google_compute_http_health_check" "example" {
name = "example-health-check"
check_interval_sec = 30
timeout_sec = 5
port = 8081
request_path = "/status"
}
resource "google_compute_target_pool" "example" {
name = "example-target-pool"
instances = [
google_compute_instance_group.example.self_link
]
health_checks = [
google_compute_http_health_check.example.name
]
}
resource "google_compute_forwarding_rule" "example-1883" {
name = "example-forwarding-rule"
target = google_compute_target_pool.example.self_link
port_range = "1883"
ip_protocol = "TCP"
}
resource "google_compute_forwarding_rule" "example-8883" {
...
}
初始化并应用 Terraform
terraform init
terraform plan
terraform apply
应用成功后,将输出以下内容:
Outputs:
loadbalancer_ip = ${loadbalancer_ip}
tls_ca = <sensitive>
tls_cert = <sensitive>
tls_key = <sensitive>
您现在可以通过相应的端口访问不同的服务了。
Dashboard: ${loadbalancer_ip}:18083
MQTT: ${loadbalancer_ip}:1883
MQTTS: ${loadbalancer_ip}:8883
WS: ${loadbalancer_public_ip}:8083
WSS: ${loadbalancer_public_ip}:8084
结语
使用 Terraform 在 GCP 上部署 EMQX,可以让您轻松管理物联网基础设施,专注于创造物联网应用。按照本文的指引,您可以在 GCP 上快速搭建出具有强大扩展性和高可靠性的 MQTT Broker,为您的物联网项目提供支持。
版权声明: 本文为 EMQ 原创,转载请注明出处。
原文链接:https://www.emqx.com/zh/blog/one-click-deploying-emqx-mqtt-broker-on-gcp-using-terraform