问题:
我正在尝试在 Digital Ocean 上构建一个 Docker Swarm 集群,由 3 个“管理器”节点和许多工作节点组成。工作节点的数量与这个问题并不是特别相关。我正在尝试对 Docker Swarm 配置内容进行模块化,因此它没有专门耦合到 digitalocean 提供程序,而是可以接收 IP 地址列表来对集群进行配置。
为了配置主节点,第一个节点需要进入集群模式,该模式会生成一个连接密钥,其他主节点将使用该连接密钥来加入第一个节点。“null_resource”用于针对主节点执行远程配置程序,但是,我无法弄清楚 dafuq 如何确保第一个主节点完成其工作(“docker swarm init ...”),然后再进行另一个“ null_resource”配置程序针对需要加入第一个主节点的其他主节点执行。它们都是并行运行的,可以预见的是,它不起作用。
此外,尝试找出如何收集第一个节点生成的加入令牌并将其提供给其他节点。我考虑过使用 Consul 来执行此操作,并将加入令牌存储为密钥,并在其他节点上获取该密钥 - 但这并不理想,因为...确保 Consul 集群已配置并准备就绪仍然存在问题(同样的问题)。
主.tf
variable "master_count" { default = 3 }
# master nodes
resource "digitalocean_droplet" "master_nodes" {
count = "${var.master_count}"
... etc, etc
}
module "docker_master" {
source = "./docker/master"
private_ip = "${digitalocean_droplet.master_nodes.*.ipv4_address_private}"
public_ip = "${digitalocean_droplet.master_nodes.*.ipv4_address}"
instances = "${var.master_count}"
}
Run Code Online (Sandbox Code Playgroud)
docker/master/main.tf
variable "instances" {}
variable "private_ip" { type = "list" }
variable "public_ip" { type = "list" }
# Act only on the first item in the list of masters...
resource "null_resource" "swarm_master" {
count = 1
# Just to ensure this gets run every time
triggers {
version = "${timestamp()}"
}
connection {
...
host = "${element(var.public_ip, 0)}"
}
provisioner "remote-exec" {
inline = [<<EOF
... install docker, then ...
docker swarm init --advertise-addr ${element(var.private_ip, 0)}
MANAGER_JOIN_TOKEN=$(docker swarm join-token manager -q)
# need to do something with the join token, like make it available
# as an attribute for interpolation in the next "null_resource" block
EOF
]
}
}
# Act on the other 2 swarm master nodes (*not* the first one)
resource "null_resource" "other_swarm_masters" {
count = "${var.instances - 1}"
triggers {
version = "${timestamp()}"
}
# Host key slices the 3-element IP list and excludes the first one
connection {
...
host = "${element(slice(var.public_ip, 1, length(var.public_ip)), count.index)}"
}
provisioner "remote-exec" {
inline = [<<EOF
SWARM_MASTER_JOIN_TOKEN=$(consul kv get docker/swarm/manager/join_token)
docker swarm join --token ??? ${element(var.private_ip, 0)}:2377
EOF
]
}
##### THIS IS THE MEAT OF THE QUESTION ###
# How do I make this "null_resource" block not run until the other one has
# completed and generated the swarm token output? depends_on doesn't
# seem to do it :(
}
Run Code Online (Sandbox Code Playgroud)
通过阅读 github 问题,我感觉这并不是一个罕见的问题……但它让我很恼火。任何建议表示赞赏!
@victor-m 的评论是正确的。如果您使用 anull_resource并且对任何前者的属性有以下触发器,那么它们将按顺序执行。
resource "null_resource" "first" {
provisioner "local-exec" {
command = "echo 'first' > newfile"
}
}
resource "null_resource" "second" {
triggers = {
order = null_resource.first.id
}
provisioner "local-exec" {
command = "echo 'second' >> newfile"
}
}
resource "null_resource" "third" {
triggers = {
order = null_resource.second.id
}
provisioner "local-exec" {
command = "echo 'third' >> newfile"
}
}
Run Code Online (Sandbox Code Playgroud)
$ terraform apply
null_resource.first: Creating...
null_resource.first: Provisioning with 'local-exec'...
null_resource.first (local-exec): Executing: ["/bin/sh" "-c" "echo 'first' > newfile"]
null_resource.first: Creation complete after 0s [id=3107778766090269290]
null_resource.second: Creating...
null_resource.second: Provisioning with 'local-exec'...
null_resource.second (local-exec): Executing: ["/bin/sh" "-c" "echo 'second' >> newfile"]
null_resource.second: Creation complete after 0s [id=3159896803213063900]
null_resource.third: Creating...
null_resource.third: Provisioning with 'local-exec'...
null_resource.third (local-exec): Executing: ["/bin/sh" "-c" "echo 'third' >> newfile"]
null_resource.third: Creation complete after 0s [id=6959717123480445161]
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
Run Code Online (Sandbox Code Playgroud)
为了确保cat新文件和这里的输出符合预期
$ cat newfile
first
second
third
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5155 次 |
| 最近记录: |