我偶然发现了这个老话题,因为我正在寻找解决同一问题的方法。最后,我找到了一种适合我的方法,我想与您分享。tl;博士总结
- 使用 AWS Python API 获取 munin master 所在 VPC 中的所有实例
- 测试 munin 端口 4949 是否在发现检测 munin 节点的实例上打开
- 从 munin.base.conf(无节点)创建 munin.conf 并为找到的所有节点附加条目
- 通过 cron 在 munin master 上运行脚本 5 分钟
最后,这是我的 Python 脚本,它完成了所有的魔法:
#! /usr/bin/python
import boto3
import requests
import argparse
import shutil
import socket
socketTimeout = 2
ec2 = boto3.client('ec2')
def getVpcId():
response = requests.get('http://169.254.169.254/latest/meta-data/instance-id')
instance_id = response.text
response = ec2.describe_instances(
Filters=[
{
'Name' : 'instance-id',
'Values' : [ instance_id ]
}
]
)
return response['Reservations'][0]['Instances'][0]['VpcId']
def findNodes(tag):
result = []
vpcId = getVpcId()
response = ec2.describe_instances(
Filters=[
{
'Name' : 'tag-key',
'Values' : [ tag ]
},
{
'Name' : 'vpc-id',
'Values' : [ vpcId ]
}
]
)
for reservation in response['Reservations']:
for instance in reservation['Instances']:
result.append(instance)
return result
def getInstanceTag(instance, tagName):
for tag in instance['Tags']:
if tag['Key'] == tagName:
return tag['Value']
return None
def isMuninNode(host):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(socketTimeout)
try:
s.connect((host, 4949))
s.shutdown(socket.SHUT_RDWR)
return True
except Exception as e:
return False
finally:
s.close()
def appendNodesToConfig(nodes, target, tag):
with open(target, "a") as file:
for node in nodes:
hostname = getInstanceTag(node, tag)
if hostname.endswith('.'):
hostname = hostname[:-1]
if hostname <> None and isMuninNode(hostname):
file.write('[' + hostname + ']\n')
file.write('\taddress ' + hostname + '\n')
file.write('\tuse_node_name yes\n\n')
parser = argparse.ArgumentParser("muninconf.py")
parser.add_argument("baseconfig", help="base munin config to append nodes to")
parser.add_argument("target", help="target munin config")
args = parser.parse_args()
base = args.baseconfig
target = args.target
shutil.copyfile(base, target)
nodes = findNodes('CNAME')
appendNodesToConfig(nodes, target, 'CNAME')
要使 API 调用正常工作,您必须设置 AWS API 凭证或为您的 munin 主实例(这是我的首选方法)分配具有所需权限(至少为 ec2:DescribeInstances)的 IAM 角色。
一些最终的实现说明:
我有一个名为 CNAME 的标签分配给我的所有 AWS 实例,其中包含内部 DNS 主机名。因此,我过滤了这个标签并将该值用作 munin 配置的节点名称和地址。您可能必须为您的设置更改此设置。
另一种选择是将特定标签分配给您要使用 munin 监视的所有实例。然后,您可以过滤此标签,并且可能还跳过对打开的 munin 端口的检查。
希望这个对你有帮助。
干杯,奥利弗