Попытка обновления с нулевым временем простоя, но Targetpool направляет трафик на экземпляры, которые отключаются.

Я пытаюсь обновить свой сервис с нулевым временем простоя. Пока я безуспешен. Балансировщик нагрузки направляет трафик на старые экземпляры, поскольку они отключаются, несмотря на то, что они неработоспособны в соответствии с проверкой работоспособности балансировщика нагрузки. Я использую терраформ и gcp. Фактическая служба, которая будет обновлена, должна завершить соединение TLS, поэтому эта служба должна использовать балансировщик сетевой нагрузки, целевой пул. Региональный менеджер группы экземпляров должен обеспечить избыточность в случае выхода зоны из строя.

Игрушечная версия terraform, в которой количество экземпляров уменьшено, но показывает проблему

variable "project" {
  type = string
}
variable "region" {
  type = string
  default = "us-central1"
}

provider "google" {
  project = var.project
  region = var.region
}

resource "google_compute_region_instance_group_manager" "default" {
  base_instance_name = "instance"
  name = "default"

  region = var.region
  target_size = 3
  target_pools = [
    google_compute_target_pool.default.self_link,
  ]

  update_policy {
    minimal_action = "REPLACE"
    type = "PROACTIVE"
    max_surge_fixed = 3
    max_unavailable_fixed = 0
    min_ready_sec = 120
  }

  version {
    instance_template = google_compute_instance_template.template-b.self_link
  }
}

resource "google_compute_address" "default" {
  name = "default"
}

resource "google_compute_target_pool" "default" {
  name = "default"
  region = var.region
  instances = []
  health_checks = [
    google_compute_http_health_check.default.self_link
  ]
  lifecycle {
    ignore_changes = [
      instances
    ]
  }
}

resource "google_compute_http_health_check" "default" {
  name = "default"
  request_path        = "/"
  check_interval_sec  = 1
  timeout_sec         = 1
  healthy_threshold   = 3
  unhealthy_threshold = 1
}

resource "google_compute_forwarding_rule" "default" {
  name = "default"
  region = var.region
  ip_protocol = "TCP"
  port_range = "80"
  target = google_compute_target_pool.default.self_link
  ip_address = google_compute_address.default.address
}

data "google_compute_network" "default" {
  name = "default"
}

resource "google_compute_instance_template" "template-b" {
  name = "template-b1"
  machine_type = "f1-micro"

  disk {
    boot = true
    auto_delete = true
    disk_size_gb = 100
    disk_type = "pd-ssd"
    source_image = data.google_compute_image.my_image.self_link
  }

  network_interface {
    network = data.google_compute_network.default.self_link
  }

  metadata_startup_script = file("./startup-scripts/helloworld.sh")

  metadata = {
    instance-env = "SOFTWARE_VERSION=Version-B"
  }

  tags = [
    "http-server"
  ]

  lifecycle {
    create_before_destroy = true
  }
}

data "google_compute_image" "my_image" {
  family  = "ubuntu-1804-lts"
  project = "ubuntu-os-cloud"
}

output "ip-address" {
  value = google_compute_address.default.address
}

сценарий загрузки, который запускает сервер, работающий на каждом экземпляре. startup-scripts/helloworld.sh

#!/bin/bash -x
METADATA_BASE=http://metadata.google.internal/computeMetadata/v1
SOFTWARE_VERSION=$(curl -sfm5 -H "Metadata-Flavor: Google" ${METADATA_BASE}/instance/attributes/instance-env)
echo "Hello World! This is ${SOFTWARE_VERSION} from $(hostname -f)" > index.html
python3 -m http.server 80 &

Проблема, с которой я столкнулся, заключается в том, что при уменьшении количества экземпляров, скажем, с 6 до 3, я вижу, что некоторые экземпляры помечены как неработоспособные при проверке работоспособности, но целевой пул по-прежнему направляет трафик на эти экземпляры. Документация для этого подразумевает, что эти экземпляры не должны видеть никакого трафика.

во время изменения размера числа экземпляров с 6 до 3 я запустил два сценария оболочки и получил эти результаты while [[ 1 ]]; do echo -n "$(date +%s) "; curl -m5 http://${IP_ADDRESS} && sleep 1; done

no timeouts
...
1589838264 Hello World! This is SOFTWARE_VERSION=Version-B from instance-562f.c.my-project.internal
1589838265 Hello World! This is SOFTWARE_VERSION=Version-B from instance-42dm.c.my-project.internal
1589838267 curl: (52) Empty reply from server
1589838267 curl: (28) Connection timed out after 5004 milliseconds
1589838272 Hello World! This is SOFTWARE_VERSION=Version-B from instance-xss8.c.my-project.internal
1589838273 curl: (28) Connection timed out after 5004 milliseconds
1589838278 Hello World! This is SOFTWARE_VERSION=Version-B from instance-xss8.c.my-project.internal
1589838279 curl: (28) Connection timed out after 5004 milliseconds
1589838284 Hello World! This is SOFTWARE_VERSION=Version-B from instance-wh9v.c.my-project.internal
1589838285 curl: (28) Connection timed out after 5004 milliseconds
1589838290 Hello World! This is SOFTWARE_VERSION=Version-B from instance-w47x.c.my-project.internal
1589838292 curl: (28) Connection timed out after 5003 milliseconds
1589838297 curl: (28) Connection timed out after 5003 milliseconds
1589838302 Hello World! This is SOFTWARE_VERSION=Version-B from instance-xss8.c.my-project.internal
...
no time outs

while [[ 1 ]]; do echo -n "$(date +%s) "; gcloud compute target-pools get-health default --region us-central1 && sleep 1; done

all six instances are healthy
...
1589838263 ---
healthStatus:
- healthState: HEALTHY
  instance: compute/v1/projects/my-project/zones/us-central1-f/instances/instance-xss8
  ipAddress: <IP_ADDRESS>
kind: compute#targetPoolInstanceHealth
---
healthStatus:
- healthState: HEALTHY
  instance: compute/v1/projects/my-project/zones/us-central1-c/instances/instance-w47x
  ipAddress: <IP_ADDRESS>
kind: compute#targetPoolInstanceHealth
---
healthStatus:
- healthState: HEALTHY
  instance: compute/v1/projects/my-project/zones/us-central1-b/instances/instance-wh9v
  ipAddress: <IP_ADDRESS>
kind: compute#targetPoolInstanceHealth
---
healthStatus:
- healthState: UNHEALTHY
  instance: compute/v1/projects/my-project/zones/us-central1-f/instances/instance-rvcl
kind: compute#targetPoolInstanceHealth
---
healthStatus:
- healthState: HEALTHY
  instance: compute/v1/projects/my-project/zones/us-central1-b/instances/instance-562f
  ipAddress: <IP_ADDRESS>
kind: compute#targetPoolInstanceHealth
---
healthStatus:
- healthState: UNHEALTHY
  instance: compute/v1/projects/my-project/zones/us-central1-c/instances/instance-42dm
kind: compute#targetPoolInstanceHealth
1589838266 ---
healthStatus:
- healthState: HEALTHY
  instance: compute/v1/projects/my-project/zones/us-central1-f/instances/instance-xss8
  ipAddress: <IP_ADDRESS>
kind: compute#targetPoolInstanceHealth
---
healthStatus:
- healthState: HEALTHY
  instance: compute/v1/projects/my-project/zones/us-central1-c/instances/instance-w47x
  ipAddress: <IP_ADDRESS>
kind: compute#targetPoolInstanceHealth
---
healthStatus:
- healthState: HEALTHY
  instance: compute/v1/projects/my-project/zones/us-central1-b/instances/instance-wh9v
  ipAddress: <IP_ADDRESS>
kind: compute#targetPoolInstanceHealth
---
healthStatus:
- healthState: UNHEALTHY
  instance: compute/v1/projects/my-project/zones/us-central1-f/instances/instance-rvcl
kind: compute#targetPoolInstanceHealth
---
healthStatus:
- healthState: UNHEALTHY
  instance: compute/v1/projects/my-project/zones/us-central1-b/instances/instance-562f
kind: compute#targetPoolInstanceHealth
---
healthStatus:
- healthState: UNHEALTHY
  instance: compute/v1/projects/my-project/zones/us-central1-c/instances/instance-42dm
kind: compute#targetPoolInstanceHealth
...
unhealthy for a bit
...
1589838312 ---
healthStatus:
- healthState: HEALTHY
  instance: v1/projects/my-project/zones/us-central1-f/instances/instance-xss8
  ipAddress: <IP_ADDRESS>
kind: compute#targetPoolInstanceHealth
---
healthStatus:
- healthState: HEALTHY
  instance: compute/v1/projects/my-project/zones/us-central1-c/instances/instance-w47x
  ipAddress: <IP_ADDRESS>
kind: compute#targetPoolInstanceHealth
---
healthStatus:
- healthState: HEALTHY
  instance: compute/v1/projects/my-project/zones/us-central1-b/instances/instance-wh9v
  ipAddress: <IP_ADDRESS>
kind: compute#targetPoolInstanceHealth

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

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

Что я могу сделать, чтобы избежать этого простоя?




Ответы (1)


Из журналов следует, что был 30-секундный интервал, в течение которого балансировщик нагрузки продолжал отправлять запросы неотвечающим экземплярам.

gcloud compute target-pools get-health предоставляет следующие временные метки и статусы работоспособности:

Timestamp 1589838263
instance-rvcl   UNHEALTHY
instance-42dm   UNHEALTHY
instance-562f   HEALTHY

Timestamp 1589838266
instance-rvcl   UNHEALTHY
instance-42dm   UNHEALTHY
instance-562f   UNHEALTHY

curl вывод с объединенными статусами работоспособности:

no timeouts
...
1589838263      # instance-562f still HEALTHY, the last response
1589838264 Hello World! This is SOFTWARE_VERSION=Version-B from instance-562f.c.my-project.internal
1589838265 Hello World! This is SOFTWARE_VERSION=Version-B from instance-42dm.c.my-project.internal
1589838266      # relative time +0s, instances -rvcl,42dm,562f are UNHEALTHY 
1589838267 curl: (52) Empty reply from server 
1589838267 curl: (28) Connection timed out after 5004 milliseconds
1589838272 Hello World! This is SOFTWARE_VERSION=Version-B from instance-xss8.c.my-project.internal
1589838273 curl: (28) Connection timed out after 5004 milliseconds
1589838278 Hello World! This is SOFTWARE_VERSION=Version-B from instance-xss8.c.my-project.internal
1589838279 curl: (28) Connection timed out after 5004 milliseconds
1589838284 Hello World! This is SOFTWARE_VERSION=Version-B from instance-wh9v.c.my-project.internal
1589838285 curl: (28) Connection timed out after 5004 milliseconds
1589838290 Hello World! This is SOFTWARE_VERSION=Version-B from instance-w47x.c.my-project.internal
1589838292 curl: (28) Connection timed out after 5003 milliseconds
1589838297 curl: (28) Connection timed out after 5003 milliseconds  # relative time +30s; instances -rvcl,42dm,562f still UNHEALTHY 
1589838302 Hello World! This is SOFTWARE_VERSION=Version-B from instance-xss8.c.my-project.internal
...
no time outs

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

Как только экземпляр становится неработоспособным, балансировщик нагрузки прекращает отправлять туда новые подключения. Однако существующие соединения могут быть не разорваны до тех пор, пока сценарий выключения не выключит экземпляр. Период отключения для обычных экземпляров составляет 90 секунд.

Вот пример графика проверки работоспособности:

Балансировка нагрузки > Документация > Обзор проверок работоспособности > Пример проверки работоспособности

Смотрите также

Compute Engine > Документация > Понимание решений автомасштабирования > Подготовка к завершению работы экземпляра< /а>

Балансировка нагрузки > Документ > Обзор проверок работоспособности > Как работают проверки работоспособности > Состояние здоровья

person mebius99    schedule 20.05.2020