부하 분산 VM

아키텍처

부하 분산 VM은 VM 클러스터를 설정하고 VM에 대한 공개 경로를 노출하도록 부하 분산기를 구성하는 인프라 구축 스크립트입니다.

  • 컴퓨팅 - VM - Compute Engine
  • 컴퓨팅 - 클러스터 - 관리형 인스턴스 그룹
  • 컴퓨팅 - 머신 템플릿 - 인스턴스 템플릿
  • 네트워킹 - 부하 분산 - Cloud 부하 분산기

이 예시 애플리케이션은 NGINX를 사용하여 간단한 정적 HTML 사이트를 설정하고 클러스터 간에 부하를 분산합니다.


시작하기

Cloud Shell에서 소스 코드의 복사본에 대해 다음 링크를 클릭합니다. 그러면 단일 명령어로 프로젝트에서 애플리케이션의 작업 복사본이 작동합니다.

Cloud Shell에서 열기

GitHub에서 소스 코드 보기


부하 분산 VM 구성요소

부하 분산 VM 아키텍처에는 여러 제품이 사용됩니다. 다음은 관련 동영상 링크, 제품 문서 및 대화형 둘러보기를 포함하여 구성 요소에 대한 자세한 정보와 함께 구성요소 목록을 보여줍니다.
동영상 문서 둘러보기
Compute Engine Compute Engine은 Google Cloud의 가상 기술입니다. 이를 사용하면 어떤 컴퓨팅 요구든 그에 맞게 여러 다른 VM 구성을 가동할 수 있습니다.
Cloud Load Balancing Google Cloud 부하 분산기를 사용하여 스토리지 버킷 앞에 부하 분산기를 배치하여 SSL 인증서, Logging, Monitoring을 사용할 수 있습니다.

스크립트

설치 스크립트는 go 및 Terraform CLI 도구로 작성된 실행 파일을 사용하여 빈 프로젝트를 가져오고 여기에 애플리케이션을 설치합니다. 출력은 작동하는 애플리케이션과 부하 분산 IP 주소의 URL입니다.

./main.tf

서비스 사용 설정

Google Cloud 서비스는 기본적으로 프로젝트에서 사용 중지되어 있습니다. 다음 필수 서비스를 활성화합니다.

  • Compute Engine - 가상 머신 및 네트워킹 서비스(부하 분산기 등)
variable "gcp_service_list" {
  description = "The list of apis necessary for the project"
  type        = list(string)
  default = [
      "compute.googleapis.com",
  ]
}

resource "google_project_service" "all" {
  for_each                   = toset(var.gcp_service_list)
  project                    = var.project_number
  service                    = each.key
  disable_dependent_services = false
  disable_on_destroy         = false
}

관리형 VM의 기반이 되는 인스턴스 예시 만들기

다음 명령어는 VM을 만들고 여기에 필요한 소프트웨어를 설치하고 코드를 배포합니다.

resource "google_compute_instance" "exemplar" {
    name         = "${var.basename}-exemplar"
    machine_type = "n1-standard-1"
    zone         = var.zone
    project      = var.project_id

    tags                    = ["http-server"]
    metadata_startup_script = "apt-get update -y \n apt-get install nginx -y \n  printf '${data.local_file.index.content}'  | tee /var/www/html/index.html \n chgrp root /var/www/html/index.html \n chown root /var/www/html/index.html \n chmod +r /var/www/html/index.html"

    boot_disk {
        auto_delete = true
        device_name = "${var.basename}-exemplar"
        initialize_params {
        image = "family/debian-10"
        size  = 200
        type  = "pd-standard"
        }
    }

    network_interface {
        network = "default"
        access_config {
        // Ephemeral public IP
        }
    }

    depends_on = [google_project_service.all]
}

스냅샷 및 디스크 이미지 만들기

다음 명령어는 VM을 사용하여 스냅샷을 만듭니다. 그런 다음 스냅샷을 사용하여 디스크 이미지를 만듭니다. 클러스터의 모든 VM은 이 이미지를 기반으로 합니다.

resource "google_compute_snapshot" "snapshot" {
    project           = var.project_id
    name              = "${var.basename}-snapshot"
    source_disk       = google_compute_instance.exemplar.boot_disk[0].source
    zone              = var.zone
    storage_locations = ["${var.region}"]
    depends_on        = [time_sleep.startup_completion]
}

resource "google_compute_image" "exemplar" {
    project         = var.project_id
    name            = "${var.basename}-latest"
    family          = var.basename
    source_snapshot = google_compute_snapshot.snapshot.self_link
    depends_on      = [google_compute_snapshot.snapshot]
}

인스턴스 템플릿 만들기

다음 명령어는 클러스터의 모든 VM에 대한 설정 및 구성을 사용하여 템플릿을 만듭니다. 여기에는 이전 명령어에서 생성된 디스크 이미지가 사용됩니다.

이 명령어에는 클러스터의 VM에서 제공되는 HTML을 맞춤설정하는 시작 스크립트가 포함되어 있습니다.

 resource "google_compute_instance_template" "default" {
    project     = var.project_id
    name        = "${var.basename}-template"
    description = "This template is used to create app server instances."
    tags        = ["httpserver"]

    metadata_startup_script = "sed -i.bak \"s/\{\{NODENAME\}\}/$HOSTNAME/\" /var/www/html/index.html"

    instance_description = "BasicLB node"
    machine_type         = "n1-standard-1"
    can_ip_forward       = false

    // Create a new boot disk from an image
    disk {
        source_image = google_compute_image.exemplar.self_link
        auto_delete  = true
        boot         = true
    }

    network_interface {
        network = "default"
    }

    depends_on = [google_compute_image.exemplar]
}

관리형 인스턴스 그룹 만들기

인스턴스 템플릿의 머신 N개를 이 그룹의 일부로 관리하도록 요청합니다.

resource "google_compute_instance_group_manager" "default" {
    project            = var.project_id
    name               = "${var.basename}-mig"
    zone               = var.zone
    target_size        = var.nodes
    base_instance_name = "${var.basename}-mig"


    version {
        instance_template = google_compute_instance_template.default.id
    }

    named_port {
        name = "http"
        port = "80"
    }

    depends_on = [google_compute_instance_template.default]
}

외부 IP 주소 만들기

도메인 이름에 호스트를 바인딩하고 인터넷에서 일반적으로 통신을 수행하기 위해 필요합니다.

resource "google_compute_global_address" "default" {
    project    = var.project_id
    name       = "${var.basename}-ip"
    ip_version = "IPV4"
}

부하 분산기 만들기

다음 명령어는 부하 분산기를 만들고 상태 점검 및 백엔드 서비스를 구현합니다. 인스턴스 그룹에 연결되도록 부하 분산기를 구성합니다.

resource "google_compute_health_check" "http" {
    project = var.project_id
    name    = "${var.basename}-health-chk"

    tcp_health_check {
        port = "80"
    }
}

resource "google_compute_firewall" "allow-health-check" {
    project       = var.project_id
    name          = "allow-health-check"
    network       = local.defaultnetwork
    source_ranges = ["130.211.0.0/22", "35.191.0.0/16"]

    allow {
        protocol = "tcp"
        ports    = ["80"]
    }
}

resource "google_compute_backend_service" "default" {
    project               = var.project_id
    name                  = "${var.basename}-service"
    load_balancing_scheme = "EXTERNAL"
    protocol              = "HTTP"
    port_name             = "http"
    backend {
        group = google_compute_instance_group_manager.default.instance_group
    }

    health_checks = [google_compute_health_check.http.id]
    }

    resource "google_compute_url_map" "lb" {
    project         = var.project_id
    name            = "${var.basename}-lb"
    default_service = google_compute_backend_service.default.id
}

HTTP 사용 설정

다음 명령어는 부하 분산기에서 포트 80을 서비스에 연결하는 네트워킹 규칙을 구성합니다.

resource "google_compute_target_http_proxy" "default" {
    project = var.project_id
    name    = "${var.basename}-lb-proxy"
    url_map = google_compute_url_map.lb.id
}

resource "google_compute_forwarding_rule" "google_compute_forwarding_rule" {
    project               = var.project_id
    name                  = "${var.basename}-http-lb-forwarding-rule"
    provider              = google-beta
    region                = "none"
    load_balancing_scheme = "EXTERNAL"
    port_range            = "80"
    target                = google_compute_target_http_proxy.default.id
    ip_address            = google_compute_global_address.default.id
}

결론

실행이 완료되면 이제 프로젝트의 부하 분산기가 앞에 있는 여러 Compute Engine 인스턴스에서 간단한 웹사이트가 실행됩니다. 또한 환경에 맞게 이 솔루션을 수정하거나 확장할 수 있도록 모든 코드가 준비되었습니다.