我在GCE上有几个实例我不需要静态地址,但我仍然需要通过dns名称访问它们。由于短暂的外部IP地址每次重新启动时都会发生变化,我认为我可以使用某种启动脚本来更新Google Cloud DNS中的该实例的dns条目(有点像dyndns)。
我是否遗漏了一些东西,有一种更简单的方法可以通过gcloud将短暂的外部IP地址映射到dns记录?
如果没有,任何有关如何编写此类脚本的指示都将受到高度赞赏!
答案 0 :(得分:5)
以下假设您正在使用带有区域名称" foo-bar-的foo.bar.com(即dns名称" foo.bar.com。")的Google Cloud DNS COM"在与VM相同的项目中,并且您的VM具有配置选项"此实例具有对所有Google Cloud服务的完全API访问权限。"选择。 您的VM将被调用" my-vm.foo.bar.com"在DNS中。
我确定可以对其进行适当修改,以便在不同的项目中使用DNS和/或使用更多有限的权限。
可能值得注意的是:这假设您使用的是Google Cloud DNS'而不是(仅仅)' Google Domains'注册商,如果您使用后者(托管您的DNS,而不仅仅是注册商),那么他们可以直接支持合成动态IP地址以及更新机制等一些问题(但他们更加局限于一堆其他方式)。
另请注意,要使事务成功,必须有一个具有正确IP和正确TTL的记录(即,第一次运行此操作时,您可能希望通过UI手动删除任何条目,并运行此用dns_del注释掉的代码。)
#!/bin/bash
ttlify() {
local i
for i in "$@"; do
[[ "${i}" =~ ^([0-9]+)([a-z]*)$ ]] || continue
local num="${BASH_REMATCH[1]}"
local unit="${BASH_REMATCH[2]}"
case "${unit}" in
weeks|week|wee|we|w) unit=''; num=$[num*60*60*24*7];;
days|day|da|d) unit=''; num=$[num*60*60*24];;
hours|hour|hou|ho|h) unit=''; num=$[num*60*60];;
minutes|minute|minut|minu|min|mi|m) unit=''; num=$[num*60];;
seconds|second|secon|seco|sec|se|s) unit=''; num=$[num];;
esac
echo "${num}${unit}"
done
}
dns_start() {
gcloud dns record-sets transaction start -z "${ZONENAME}"
}
dns_info() {
gcloud dns record-sets transaction describe -z "${ZONENAME}"
}
dns_abort() {
gcloud dns record-sets transaction abort -z "${ZONENAME}"
}
dns_commit() {
gcloud dns record-sets transaction execute -z "${ZONENAME}"
}
dns_add() {
if [[ -n "$1" && "$1" != '@' ]]; then
local -r name="$1.${ZONE}."
else
local -r name="${ZONE}."
fi
local -r ttl="$(ttlify "$2")"
local -r type="$3"
shift 3
gcloud dns record-sets transaction add -z "${ZONENAME}" --name "${name}" --ttl "${ttl}" --type "${type}" "$@"
}
dns_del() {
if [[ -n "$1" && "$1" != '@' ]]; then
local -r name="$1.${ZONE}."
else
local -r name="${ZONE}."
fi
local -r ttl="$(ttlify "$2")"
local -r type="$3"
shift 3
gcloud dns record-sets transaction remove -z "${ZONENAME}" --name "${name}" --ttl "${ttl}" --type "${type}" "$@"
}
lookup_dns_ip() {
host "$1" | sed -rn 's@^.* has address @@p'
}
my_ip() {
ip -4 addr show dev eth0 | sed -rn 's@^ inet ([0-9.]+).*@\1@p'
}
doit() {
ZONE=foo.bar.com
ZONENAME=foo-bar-com
dns_start
dns_del my-vm 5min A `lookup_dns_ip "my-vm.${ZONE}."`
dns_add my-vm 5min A `my_ip`
dns_commit
}
答案 1 :(得分:3)
自从你发布这个问题已经有一段时间了,但我会在这里发布我的答案以供将来参考。
我有类似的需求,我不想使用gcloud
CLI。
我创建了一个简单的python脚本,其功能与上面的bash脚本完全相同,但使用 Apache Libcloud 和 Google Cloud API凭据(服务帐户)和关键)。
您可以在GitHub中找到代码。
答案 2 :(得分:3)
我将略微讨论@MaZe的答案。另外,我将展示使用systemd的情况,因此,如果您使用的是Ubuntu或其他使用systemd的发行版,则此脚本将在启动时自动启动。
[Unit]
Description=Set xxx.yyyy.com to the correct external ip address of this instance
After=network.target auditd.service
[Service]
ExecStart=/path/to/script.sh
Type=oneshot
[Install]
WantedBy=multi-user.target
将其保存到/path/to/script.sh并在systemd中启动:
sudo systemctl enable filename.service
将其保存为/ etc / systemd / system中的filename.service并使用以下命令启用它:
$String.Split("\")[-1]