Как обновить Google Cloud DNS с эфемерным IP-адресом для экземпляра

У меня есть несколько экземпляров на GCE, для которых мне не нужны статические адреса, но мне все равно нужно сделать их доступными через dns-имя. Поскольку эфемерные внешние ip-адреса меняются каждый раз при перезапуске экземпляра, я подумал, что могу использовать какой-то скрипт запуска для обновления записи dns для этого экземпляра в Google Cloud DNS (немного похоже на dyndns).

Я что-то пропустил, и есть более простой способ сопоставить эфемерные внешние ip-адреса с записью dns через gcloud?

Если нет, любые указатели на то, как написать такой скрипт, будут высоко оценены!

3 ответов


предполагается, что вы используете Google Cloud DNS для foo.bar.com (т. е. dns-имя "foo.bar.com") с именем зоны " foo-bar-com "в том же проекте, что и ваша виртуальная машина, и что у вашей виртуальной машины есть опция конфигурации" этот экземпляр имеет полный доступ API ко всем облачным сервисам Google." выбирать. Ваша виртуальная машина будет называться "my-vm.foo.bar.com" в DNS.

Я уверен, что это может быть соответствующим образом модифицирован для работы с DNS в другом проекте и/или более общества разрешения.

вероятно, стоит отметить: это предполагает, что вы используете "Google Cloud DNS", а не (просто) "регистратор доменов Google", если вы используете последний (для размещения вашего DNS, а не только в качестве регистратора), то у них есть прямая поддержка синтетического динамического ip-адреса с некоторыми dyndns, такими как механизм обновления (но они более ограничены в куче других способов).

также обратите внимание, что для успешной транзакции уже должна быть запись с правильным IP и правом TTL (т. е. при первом запуске вы можете удалить любую запись вручную через пользовательский интерфейс и запустить этот код с комментарием 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 "" && "" != '@' ]]; then
    local -r name=".${ZONE}."
  else
    local -r name="${ZONE}."
  fi
  local -r ttl="$(ttlify "")"
  local -r type=""
  shift 3
  gcloud dns record-sets transaction add      -z "${ZONENAME}" --name "${name}" --ttl "${ttl}" --type "${type}" "$@"
}

dns_del() {
  if [[ -n "" && "" != '@' ]]; then
    local -r name=".${ZONE}."
  else
    local -r name="${ZONE}."
  fi
  local -r ttl="$(ttlify "")"
  local -r type=""
  shift 3
  gcloud dns record-sets transaction remove   -z "${ZONENAME}" --name "${name}" --ttl "${ttl}" --type "${type}" "$@"
}

lookup_dns_ip() {
  host "" | sed -rn 's@^.* has address @@p'
}

my_ip() {
  ip -4 addr show dev eth0 | sed -rn 's@^    inet ([0-9.]+).*@@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
}

прошло некоторое время с тех пор, как вы опубликовали этот вопрос, но я опубликую свой ответ здесь для дальнейшего использования.

У меня была аналогичная потребность, и я не хотел использовать gcloud CLI.

Я создал простой скрипт python, который делает почти то же самое, что и скрипт bash выше, но использует Apache Libcloud и учетные данные Google Cloud API (учетная запись службы и ключ).

вы можете найти код в GitHub.


Я собираюсь немного покрутить ответ от @MaZe. Кроме того, я покажу использование systemd, чтобы этот скрипт запускался автоматически при запуске, если вы находитесь на Ubuntu или другом дистрибутиве, использующем systemd.

#!/bin/bash

EXISTING=`gcloud dns record-sets list --zone="{your domain}" | grep xxx.yyyy.com | awk '{print }'`
NEW=`gcloud compute instances describe {your instance} --zone={your zone} | grep natIP | awk -F': ' '{print }'`
gcloud dns record-sets transaction start -z={your domain}
gcloud dns record-sets transaction remove -z={your domain} \
    --name="xxx.yyyy.com." \
    --type=A \
    --ttl=300 "$EXISTING"
gcloud dns record-sets transaction add -z={your domain} \
   --name="xxx.yyyy.com." \
   --type=A \
   --ttl=300 "$NEW"
gcloud dns record-sets transaction execute -z={your domain}

сохранить в /path/to/script.sh и запустите его в 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

сохраните его в /etc/systemd / system как имя файла.сервис и включил его с помощью:

sudo systemctl enable filename.service