如何使用临时IP为实例

时间:2016-01-11 16:30:33

标签: dns google-compute-engine gcloud google-cloud-dns

我在GCE上有几个实例我不需要静态地址,但我仍然需要通过dns名称访问它们。由于短暂的外部IP地址每次重新启动时都会发生变化,我认为我可以使用某种启动脚本来更新Google Cloud DNS中的该实例的dns条目(有点像dyndns)。

我是否遗漏了一些东西,有一种更简单的方法可以通过gcloud将短暂的外部IP地址映射到dns记录?

如果没有,任何有关如何编写此类脚本的指示都将受到高度赞赏!

3 个答案:

答案 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]