Private Service Connect 상태

1. 소개

이 Codelab에서는 자동 리전 장애 조치를 위한 Private Service Connect (PSC) 상태를 살펴봅니다. PSC 상태는 서비스 복원력과 가용성을 개선하는 네트워킹 기능입니다.

PSC 상태를 사용하면 서비스 프로듀서가 맞춤 상태 정책 (상태가 정상 또는 비정상 서비스를 정의함)을 정의하고 PSC 백엔드로 서비스에 연결하는 서비스 소비자에게 이러한 신호를 자동으로 전파할 수 있습니다. 이 기능은 자동 리전 간 장애 조치를 지원하도록 특별히 설계되었습니다. 리전 프로듀서 서비스가 비정상이 되면 소비자 부하 분산기가 해당 리전으로의 트래픽 라우팅을 자동으로 중지하고 다른 리전의 정상 서비스로 트래픽을 전달합니다.

이상치 감지와 같은 이전의 교차 리전 장애 조치 방법과 비교할 때 PSC 상태는 프로듀서 서비스 백엔드 (VM 인스턴스 그룹 또는 네트워크 엔드포인트)의 집계된 상태를 직접 기반으로 하므로 더 정확한 장애 조치 신호를 제공합니다. 프로듀서는 자체 상태 로직을 정의하여 서비스가 필요한 상태 기준을 충족하는 경우에만 트래픽을 수신할 수 있습니다.

학습 내용

  • PSC 상태의 구성요소와 이러한 구성요소가 함께 작동하여 생산자 서비스의 상태를 결정하는 방식
  • gcloud 명령어를 사용하여 프로듀서 서비스의 PSC 상태 구현
  • 프로듀서 PSC 상태 정책의 상태 신호를 사용하도록 리전 간 PSC 소비자 액세스 부하 분산기 구성
  • 서비스 장애 시나리오 테스트 및 자동 리전 간 장애 조치 검증

필요한 항목

  • Google Cloud 프로젝트
  • 사전 정의된 roles/compute.admin 역할 또는 roles/admin, 기존 roles/owner와 같은 광범위한 기본 역할에 부여된 IAM 권한
  • Google Cloud 네트워킹 개념에 대한 이해 및 Google Cloud CLI 사용

2. 개념

PSC 네트워킹

이 Codelab 네트워크 토폴로지에는 활성 상태인 두 Google Cloud 리전의 소비자 및 프로듀서 VPC 네트워크가 포함됩니다.

소비자 측에는 PSC 네트워크 엔드포인트 그룹 (NEG) 백엔드가 있는 리전 간 내부 애플리케이션 부하 분산기를 통해 프로듀서 서비스에 액세스하는 데 사용되는 클라이언트 VM 인스턴스가 있는 리전 서브넷이 있습니다. 전역 (리전 간) 클라이언트 인그레스를 위한 리전 IP 주소가 있는 리전 부하 분산기 전달 규칙이 두 개 있습니다. 백엔드 서비스는 여러 리전의 NEG를 지원하는 전역 리소스입니다. 장애 조치 시나리오에서 리전 프런트엔드 전달 규칙에 연결하는 클라이언트는 정상 전역 백엔드로 연결될 수 있습니다.

figure1

그림 1. Codelab 네트워크 토폴로지

생산자 측에는 리전 PSC 서비스 연결 리소스를 통해 서비스를 노출하는 리전 내부 패스 스루 네트워크 부하 분산기가 있는 리전 서브넷이 있습니다. 백엔드 서비스에는 리전별 관리형 인스턴스 그룹 (MIG)이 포함되어 있으며 http 요청을 프로브하고 200 (OK) 응답을 검증하여 상태 확인을 수행합니다.

프로듀서 구성에 대한 Private Service Connect 호환성에 관한 최신 문서를 참고하여 PSC 상태를 지원하는 부하 분산기를 확인하세요.

서비스 상태

부하 분산기 생성 중에 구성된 생산자 백엔드 서비스 상태 확인은 PSC 상태 기능의 시작 신호 역할을 합니다. 상태 소스 리소스는 이 신호와 상태 집계 정책 리소스에 정의된 추가 제약 조건을 사용하여 단일 백엔드 서비스의 상태를 결정합니다.

기본적으로 다음 두 가지 제약 조건이 모두 충족되면 서비스가 정상으로 간주됩니다.

  • 백엔드의 최소 x%가 정상입니다 (기본값 60).
  • y개 이상의 백엔드가 정상입니다 (기본값 1).

복합 상태 점검은 모든 백엔드 서비스의 모든 상태 소스를 참조하여 전체 리전 프로듀서 서비스의 전체 상태를 확인합니다. 이 실습의 경우 각 리전 생산자 서비스에는 하나의 복합 상태 점검으로 롤업되는 백엔드 서비스 상태 소스가 하나만 있습니다.

figure2

그림 2. PSC 상태 리소스 모델

복합 상태 점검 리소스 정의는 생산자 서비스 부하 분산기의 전달 규칙도 참조합니다. 소비자 액세스 부하 분산기 백엔드 PSC NEG는 프로듀서 PSC 서비스 연결 및 프로듀서 부하 분산기 전달 규칙에 논리적으로 연결됩니다. 이렇게 하면 소비자 액세스 부하 분산기가 프로듀서 서비스 복합 상태 점검 상태에 연결됩니다. 그런 다음 리전 프로듀서 서비스의 전체 서비스 상태가 소비자 부하 분산기로 전파되어 적절한 백엔드를 선택할 수 있습니다.

3. 프로젝트 설정

프로젝트에 액세스

이 Codelab은 단일 Google Cloud 프로젝트를 사용하도록 작성되었습니다. 구성 단계에서는 gcloud 및 Linux 셸 명령어를 사용합니다.

참고: 프로덕션 배포에서 PSC 소비자 리소스와 생산자 서비스는 일반적으로 서로 다른 프로젝트에 있습니다.

다음을 사용하여 Google Cloud 프로젝트 명령줄에 액세스합니다.

프로젝트 ID 설정

gcloud config set project YOUR_PROJECT_ID_HERE

셸 환경 변수 설정

export PROJECT_ID=$(gcloud config list --format="value(core.project)")
export REGION_1="us-west1"
export ZONE_1="us-west1-c"
export REGION_2="us-east1"
export ZONE_2="us-east1-c"
echo ${PROJECT_ID}
echo ${REGION_1}
echo ${ZONE_1}
echo ${REGION_2}
echo ${ZONE_2}

API 서비스 사용 설정

gcloud services enable compute.googleapis.com
gcloud services enable dns.googleapis.com

4. 프로듀서 서비스

공유 리소스 만들기

네트워크 만들기

gcloud compute networks create vnet-producer --subnet-mode=custom

서브넷 만들기

# create subnet for service workload in region 1
gcloud compute networks subnets create subnet-foo \
  --network=vnet-producer \
  --region=${REGION_1} \
  --range=172.16.1.0/24 \
  --enable-private-ip-google-access

# create subnet for psc nat in region 1
gcloud compute networks subnets create subnet-foo-pscnat \
  --network=vnet-producer \
  --region=${REGION_1} \
  --range=192.168.1.0/29 \
  --purpose=PRIVATE_SERVICE_CONNECT
# create subnet for service workload in region 2
gcloud compute networks subnets create subnet-bar \
  --network=vnet-producer \
  --region=${REGION_2} \
  --range=172.16.2.0/24 \
  --enable-private-ip-google-access

# create subnet for psc nat in region 2
gcloud compute networks subnets create subnet-bar-pscnat \
  --network=vnet-producer \
  --region=${REGION_2} \
  --range=192.168.2.0/29 \
  --purpose=PRIVATE_SERVICE_CONNECT

방화벽 구성요소 만들기

VM 리소스에 대한 트래픽을 허용하려면 방화벽 규칙이 필요합니다 (암시적 기본 방화벽 규칙은 인그레스를 거부하고 이그레스를 허용함). 정책은 네트워크 방화벽 정책 리소스를 만들고, 정책에 규칙을 만들고 추가한 다음, 정책을 VPC 네트워크에 연결하여 방화벽 규칙을 배포하는 기본 방법입니다.

# create fw policy
gcloud compute network-firewall-policies create fw-policy-producer --global
# create fw policy rules
gcloud compute network-firewall-policies rules create 1001 \
  --description="allow iap for ssh" \
  --firewall-policy=fw-policy-producer \
  --global-firewall-policy \
  --action=allow \
  --direction=INGRESS \
  --layer4-configs=tcp:22  \
  --src-ip-ranges=35.235.240.0/20

gcloud compute network-firewall-policies rules create 1002 \
  --description="allow health checks" \
  --firewall-policy=fw-policy-producer \
  --global-firewall-policy \
  --action=allow \
  --direction=INGRESS \
  --layer4-configs=tcp,udp,icmp  \
  --src-ip-ranges=130.211.0.0/22,35.191.0.0/16

gcloud compute network-firewall-policies rules create 1003 \
  --description="allow psc nat clients" \
  --firewall-policy=fw-policy-producer \
  --global-firewall-policy \
  --action=allow \
  --direction=INGRESS \
  --layer4-configs=tcp:80  \
  --src-ip-ranges=192.168.1.0/29,192.168.2.0/29
# associate fw policy to vnet
gcloud compute network-firewall-policies associations create \
  --firewall-policy=fw-policy-producer \
  --network=vnet-producer \
  --name=fw-policy-association-producer \
  --global-firewall-policy

Cloud Router 및 NAT 게이트웨이 만들기

# create routers for nat in each region
gcloud compute routers create cr-nat-foo \
  --network=vnet-producer \
  --asn=16550 \
  --region=${REGION_1}

gcloud compute routers create cr-nat-bar \
  --network=vnet-producer \
  --asn=16550 \
  --region=${REGION_2}
# create nat gateways in each region
gcloud compute routers nats create natgw-foo \
  --router=cr-nat-foo \
  --region=${REGION_1} \
  --auto-allocate-nat-external-ips \
  --nat-all-subnet-ip-ranges

gcloud compute routers nats create natgw-bar \
  --router=cr-nat-bar \
  --region=${REGION_2} \
  --auto-allocate-nat-external-ips \
  --nat-all-subnet-ip-ranges

HTTP 서버로 VM 시작 구성 만들기

cat > vm-server-startup.sh << 'EOF'
#! /bin/bash
apt-get update
apt-get install apache2 -y
vm_hostname="$(curl -H "Metadata-Flavor:Google" \
http://169.254.169.254/computeMetadata/v1/instance/name)"
vm_zone="$(curl -H "Metadata-Flavor:Google" \
http://169.254.169.254/computeMetadata/v1/instance/zone)"
echo "Page served from: $vm_hostname in zone $vm_zone" | \
tee /var/www/html/index.html
systemctl restart apache2
EOF

리전 1에 서비스 foo 설정

서비스 컴퓨팅 만들기

# create managed instance group template
gcloud compute instance-templates create mig-template-foo \
  --machine-type=e2-micro \
  --network=vnet-producer \
  --region=${REGION_1} \
  --subnet=subnet-foo \
  --no-address \
  --shielded-secure-boot \
  --metadata-from-file=startup-script=vm-server-startup.sh
# create regional managed instance group
gcloud compute instance-groups managed create mig-foo \
  --region=${REGION_1} \
  --size=2 \
  --template=mig-template-foo \
  --base-instance-name=service-foo

서비스 부하 분산기 구성요소 만들기

# create lb health check
gcloud compute health-checks create http hc-foo-http \
  --region=${REGION_1} \
  --port=80 \
  --enable-logging
# create backend service
gcloud compute backend-services create ilb-foo \
  --load-balancing-scheme=INTERNAL \
  --protocol=tcp \
  --region=${REGION_1} \
  --health-checks=hc-foo-http \
  --health-checks-region=${REGION_1}

# add managed instance group to backend service
gcloud compute backend-services add-backend ilb-foo \
  --instance-group=mig-foo \
  --instance-group-region=${REGION_1} \
  --region=${REGION_1}
# create forwarding rule
gcloud compute forwarding-rules create fr-foo \
  --region=${REGION_1} \
  --load-balancing-scheme=INTERNAL \
  --network=vnet-producer \
  --subnet=subnet-foo \
  --address=172.16.1.99 \
  --ip-protocol=TCP \
  --ports=80 \
  --backend-service=ilb-foo \
  --backend-service-region=${REGION_1} \
  --allow-global-access

PSC 서비스 게시

# create psc service attachment
gcloud compute service-attachments create psc-sa-foo \
  --region=${REGION_1} \
  --target-service=projects/${PROJECT_ID}/regions/${REGION_1}/forwardingRules/fr-foo \
  --connection-preference=ACCEPT_AUTOMATIC \
  --nat-subnets=subnet-foo-pscnat

리전 2에 서비스 bar 설정

서비스 컴퓨팅 만들기

# create managed instance group template
gcloud compute instance-templates create mig-template-bar \
  --machine-type=e2-micro \
  --network=vnet-producer \
  --region=${REGION_2} \
  --subnet=subnet-bar \
  --no-address \
  --shielded-secure-boot \
  --metadata-from-file=startup-script=vm-server-startup.sh
# create regional managed instance group
gcloud compute instance-groups managed create mig-bar \
  --region=${REGION_2} \
  --size=2 \
  --template=mig-template-bar \
  --base-instance-name=service-bar

서비스 부하 분산기 구성요소 만들기

# create lb health check
gcloud compute health-checks create http hc-bar-http \
  --region=${REGION_2} \
  --port=80 \
  --enable-logging
# create backend service
gcloud compute backend-services create ilb-bar \
  --load-balancing-scheme=INTERNAL \
  --protocol=tcp \
  --region=${REGION_2} \
  --health-checks=hc-bar-http \
  --health-checks-region=${REGION_2}

# add managed instance group to backend service
gcloud compute backend-services add-backend ilb-bar \
  --instance-group=mig-bar \
  --instance-group-region=${REGION_2} \
  --region=${REGION_2}
# create forwarding rule
gcloud compute forwarding-rules create fr-bar \
  --region=${REGION_2} \
  --load-balancing-scheme=INTERNAL \
  --network=vnet-producer \
  --subnet=subnet-bar \
  --address=172.16.2.99 \
  --ip-protocol=TCP \
  --ports=80 \
  --backend-service=ilb-bar \
  --backend-service-region=${REGION_2} \
  --allow-global-access

PSC 서비스 게시

# create psc service attachment
gcloud compute service-attachments create psc-sa-bar \
  --region=${REGION_2} \
  --target-service=projects/${PROJECT_ID}/regions/${REGION_2}/forwardingRules/fr-bar \
  --connection-preference=ACCEPT_AUTOMATIC \
  --nat-subnets=subnet-bar-pscnat

5. 소비자 액세스

클라이언트 리소스 설정

네트워크 구성요소 만들기

# create vpc network
gcloud compute networks create vnet-consumer --subnet-mode=custom
# create client subnet in each region
gcloud compute networks subnets create subnet-client-1 \
  --network=vnet-consumer \
  --region=${REGION_1} \
  --range=10.10.1.0/24 \
  --enable-private-ip-google-access

gcloud compute networks subnets create subnet-client-2 \
  --network=vnet-consumer \
  --region=${REGION_2} \
  --range=10.10.2.0/24 \
  --enable-private-ip-google-access

소비자 애플리케이션 (프록시 기반) 부하 분산기에는 프록시 전용 서브넷이 필요합니다. 이러한 서브넷은 프록시 기반 부하 분산기가 백엔드로 트래픽을 전송할 때 내부 소스 주소로 사용하는 IP 주소 풀을 제공합니다.

# create proxy subnet in each region
gcloud compute networks subnets create subnet-proxy-1 \
  --purpose=GLOBAL_MANAGED_PROXY \
  --role=ACTIVE \
  --network=vnet-consumer \
  --region=${REGION_1} \
  --range=10.10.128.0/23

gcloud compute networks subnets create subnet-proxy-2 \
  --purpose=GLOBAL_MANAGED_PROXY \
  --role=ACTIVE \
  --network=vnet-consumer \
  --region=${REGION_2} \
  --range=10.10.130.0/23

방화벽 구성요소 만들기

# create fw policy
gcloud compute network-firewall-policies create fw-policy-consumer --global
# create fw policy rules
gcloud compute network-firewall-policies rules create 1001 \
  --description="allow iap for ssh" \
  --firewall-policy=fw-policy-consumer \
  --global-firewall-policy \
  --action=allow \
  --direction=INGRESS \
  --layer4-configs=tcp:22  \
  --src-ip-ranges=35.235.240.0/20
# associate fw policy to vnet
gcloud compute network-firewall-policies associations create \
  --firewall-policy=fw-policy-consumer \
  --network=vnet-consumer \
  --name=fw-policy-association-consumer \
  --global-firewall-policy

부하 분산기 구성요소 만들기

# create psc network endpoint group per region
gcloud compute network-endpoint-groups create neg-foo \
  --network-endpoint-type=private-service-connect \
  --psc-target-service=projects/${PROJECT_ID}/regions/${REGION_1}/serviceAttachments/psc-sa-foo \
  --region=${REGION_1} \
  --network=vnet-consumer \
  --subnet=subnet-client-1

gcloud compute network-endpoint-groups create neg-bar \
  --network-endpoint-type=private-service-connect \
  --psc-target-service=projects/${PROJECT_ID}/regions/${REGION_2}/serviceAttachments/psc-sa-bar \
  --region=${REGION_2} \
  --network=vnet-consumer \
  --subnet=subnet-client-2
# verify psc connections
gcloud compute network-endpoint-groups list --format="value(selfLink, pscData.pscConnectionStatus)"
# create global backend service
gcloud compute backend-services create bes-foobar \
  --load-balancing-scheme=INTERNAL_MANAGED \
  --protocol=HTTP \
  --global
# add negs to backend service
gcloud compute backend-services add-backend bes-foobar \
  --network-endpoint-group=neg-foo \
  --network-endpoint-group-region=${REGION_1} \
  --global

gcloud compute backend-services add-backend bes-foobar \
  --network-endpoint-group=neg-bar \
  --network-endpoint-group-region=${REGION_2} \
  --global
# create global url map
gcloud compute url-maps create ilb-foobar \
  --default-service=bes-foobar \
  --global
# create global target proxy
gcloud compute target-http-proxies create proxy-foobar \
  --url-map=ilb-foobar \
  --global
# create global forwarding rule for region 1
gcloud compute forwarding-rules create fr-foobar-1 \
  --load-balancing-scheme=INTERNAL_MANAGED \
  --network=vnet-consumer \
  --subnet=subnet-client-1 \
  --subnet-region=${REGION_1} \
  --address=10.10.1.99 \
  --ports=80 \
  --target-http-proxy=proxy-foobar \
  --global
# create global forwarding rule for region 2
gcloud compute forwarding-rules create fr-foobar-2 \
  --load-balancing-scheme=INTERNAL_MANAGED \
  --network=vnet-consumer \
  --subnet=subnet-client-2 \
  --subnet-region=${REGION_2} \
  --address=10.10.2.99 \
  --ports=80 \
  --target-http-proxy=proxy-foobar \
  --global

DNS 레코드 만들기

# create dns zone
gcloud dns managed-zones create zone-foobar \
  --description="private zone for foobar" \
  --dns-name=foobar.com \
  --networks=vnet-consumer \
  --visibility=private
# create geo dns record
gcloud dns record-sets create www.foobar.com \
  --zone=zone-foobar \
  --type=A \
  --ttl=300 \
  --routing-policy-type=GEO \
  --routing-policy-item="location=${REGION_1},rrdatas=10.10.1.99" \
  --routing-policy-item="location=${REGION_2},rrdatas=10.10.2.99"

컴퓨팅 리소스 만들기

# create client vm in region 1
gcloud compute instances create client-1 \
  --machine-type=e2-micro \
  --zone=${ZONE_1} \
  --subnet=subnet-client-1 \
  --no-address \
  --shielded-secure-boot
# create client vm in region 2
gcloud compute instances create client-2 \
  --machine-type=e2-micro \
  --zone=${ZONE_2} \
  --subnet=subnet-client-2 \
  --no-address \
  --shielded-secure-boot

테스트 서비스 기준

리전 1의 클라이언트 VM에 SSH로 연결

gcloud compute ssh client-1 --zone=${ZONE_1}
# send request to service using hostname
curl -v www.foobar.com
# send request to load balancer forwarding rule region 1
curl 10.10.1.99
# send request to load balancer forwarding rule region 2
curl 10.10.2.99
# exit vm ssh
exit

선택사항: 리전 2의 클라이언트 VM에서 동일한 테스트를 시도합니다. gcloud compute ssh client-2 --zone=${ZONE_2}

핵심 사항: region-x에서 전달 규칙을 수신하는 클라이언트 요청의 일반적인 부하 분산기 동작은 동일한 region-x의 백엔드를 선호하는 것입니다. 모든 백엔드 리소스가 정상인 경우 지연 시간이 가장 낮은 리전이 우선합니다. 전역 백엔드는 적절한 상태 신호가 있는 다른 리전으로 장애 조치됩니다.

하지만 실제 프로듀서 서비스 리소스가 프로듀서 VPC 네트워크의 프로듀서 부하 분산기 뒤에 있으므로 이러한 상태 신호는 이전에 소비자 부하 분산기에서 불투명했습니다. 따라서 소비자 측에서 이러한 백엔드 장애 조치 결정을 내릴 수 없었습니다. PSC 상태는 서비스 상태 정보를 생산자 측에서 소비자 측으로 전파하여 이 문제를 해결합니다.

6. 건강 리소스

PSC 상태 리소스는 생산자가 리전 서비스의 전체 상태를 나타내도록 구성합니다. 상태 정책은 서비스 생산자가 작동하는 서비스 수준을 유지하는 데 적합하다고 정의한 내용을 기반으로 합니다. 생산자 정의 조건이 더 이상 충족되지 않을 때 장애 조치하도록 소비자에게 알리도록 기준이 설정됩니다.

리전 1에서 서비스 상태 foo 설정

상태 집계 정책 만들기

gcloud beta compute health-aggregation-policies create foo-health-policy \
  --region=${REGION_1} \
  --healthy-percent-threshold=60 \
  --min-healthy-threshold=1

상태 소스 만들기

gcloud beta compute health-sources create foo-health-source \
  --region=${REGION_1} \
  --source-type=BACKEND_SERVICE \
  --sources=ilb-foo \
  --health-aggregation-policy=foo-health-policy

복합 상태 점검 만들기

gcloud beta compute composite-health-checks create foo-health-composite \
  --region=${REGION_1} \
  --health-sources=foo-health-source \
  --health-destination=projects/${PROJECT_ID}/regions/${REGION_1}/forwardingRules/fr-foo

서비스 foo 상태 구성 확인

상태 리소스 구성은 리전별 목록 (및 설명) 명령어로 볼 수 있습니다.

# show health aggregation policies
gcloud beta compute health-aggregation-policies list --regions=${REGION_1}

# show health sources
gcloud beta compute health-sources list --regions=${REGION_1}

# show composite health checks
gcloud beta compute composite-health-checks list --regions=${REGION_1}

리전 2에서 서비스 상태 bar 설정

상태 집계 정책 만들기

gcloud beta compute health-aggregation-policies create bar-health-policy \
  --region=${REGION_2} \
  --healthy-percent-threshold=60 \
  --min-healthy-threshold=1

상태 소스 만들기

gcloud beta compute health-sources create bar-health-source \
  --region=${REGION_2} \
  --source-type=BACKEND_SERVICE \
  --sources=ilb-bar \
  --health-aggregation-policy=bar-health-policy

복합 상태 점검 만들기

gcloud beta compute composite-health-checks create bar-health-composite \
  --region=${REGION_2} \
  --health-sources=bar-health-source \
  --health-destination=projects/${PROJECT_ID}/regions/${REGION_2}/forwardingRules/fr-bar

서비스 bar 상태 구성 확인

# show health aggregation policies
gcloud beta compute health-aggregation-policies list --regions=${REGION_2}

# show health sources
gcloud beta compute health-sources list --regions=${REGION_2}

# show composite health checks
gcloud beta compute composite-health-checks list --regions=${REGION_2}

이로써 구성 부분이 마무리되었습니다. 이제 테스트를 진행합니다.

7. 장애 조치 테스트

서비스 foo 지역 1 비정상 시나리오

이 시나리오에서는 두 VM 인스턴스 중 하나의 웹 서버를 중지하여 리전 1에서 PSC 프로듀서 서비스 foo의 장애를 시뮬레이션합니다.

서버 VM 세부정보 가져오기

# set env var for a foo service vm name
export FOO_FAIL_NAME=$(gcloud compute instance-groups managed list-instances mig-foo \
  --limit=1 \
  --region=${REGION_1} \
  --format="value(name)")
echo ${FOO_FAIL_NAME}
# set env var for a foo service zone
export FOO_FAIL_ZONE=$(gcloud compute instance-groups managed list-instances mig-foo \
  --limit=1 \
  --region=${REGION_1} \
  --format="value(ZONE)")
echo ${FOO_FAIL_ZONE}

서버 VM에 SSH로 연결하고 http 서버 중지

gcloud compute ssh ${FOO_FAIL_NAME} --zone=${FOO_FAIL_ZONE}
# stop apache http server to fail service
sudo systemctl stop apache2
# verify service dead
sudo systemctl status apache2 | grep Active:
# exit vm ssh
exit

리전 서비스가 비정상인지 확인

# check health state of backend service
gcloud compute backend-services get-health ilb-foo --region=${REGION_1}

출력은 다음과 유사합니다.

backend: .../regions/<REGION_1>/instanceGroups/mig-foo
status:
  healthStatus:
  -   forwardingRule: .../regions/<REGION_1>/forwardingRules/fr-foo
    forwardingRuleIp: 172.16.1.99
    healthState: UNHEALTHY
    instance: .../zones/<ZONE_1x>/instances/<FOO_FAIL_NAME>
    ipAddress: <FOO_FAIL_IP>
    port: 80
  -   forwardingRule: .../regions/<REGION_1>/forwardingRules/fr-foo
    forwardingRuleIp: 172.16.1.99
    healthState: HEALTHY
    instance: .../zones/<ZONE_1y>/instances/<FOO_OTHER_NAME>
    ipAddress: <FOO_OTHER_IP>
    port: 80
  kind: compute#backendServiceGroupHealth

리전 1 클라이언트 VM에 SSH로 연결하고 장애 조치 테스트

gcloud compute ssh client-1 --zone=${ZONE_1}
# send request to service using hostname
curl -v www.foobar.com
# curl to ilb vip in region 1
curl 10.10.1.99
# curl to ilb vip in region 2
curl 10.10.2.99

PSC 상태가 소비자 부하 분산기를 업데이트하고 리전 1의 비정상 백엔드 서비스를 피하도록 지시했습니다. 대신 리전 2의 정상 서비스 bar로 트래픽을 전달했습니다.

# exit client vm ssh
exit

서버 VM에 SSH로 연결하고 http 서버를 다시 시작합니다.

# ssh to foo service vm
gcloud compute ssh ${FOO_FAIL_NAME} --zone=${FOO_FAIL_ZONE}
# start apache http server to return service to healthy
sudo systemctl start apache2
# verify service running
sudo systemctl status apache2 | grep Active:
# exit vm ssh
exit

상태 정책 변경

생산자는 다양한 기준에 따라 서비스 상태 정책을 조정할 수 있습니다. 상태 집계 정책 리소스는 모든 다양한 상태 소스 (백엔드 서비스)에서 정상 상태를 유지하는 데 필요한 최소 기준점을 지정합니다.

bar 서비스 상태 집계 정책 업데이트

gcloud beta compute health-aggregation-policies update bar-health-policy \
  --region=${REGION_2} \
  --description="min 40% threshold" \
  --healthy-percent-threshold=40 \
  --min-healthy-threshold=2
# verify new policy is applied
gcloud beta compute health-aggregation-policies list --regions=${REGION_2}

프로듀서 상태 정책 변경사항은 다음을 충족합니다.

  1. 최소 정상 기준점 비율을 60% 에서 40%로 감소 – 이제 단일 VM 인스턴스 장애가 --healthy-percent-threshold에 따라 비정상 상태를 트리거하지 않습니다 (장애 상태는 50% 이며 정상 상태가 되려면 40% 만 필요함).
  2. 정상 백엔드의 최소 수를 1에서 2 VM 인스턴스로 늘립니다. 이제 단일 VM 인스턴스 장애가 --min-healthy-threshold에 따라 비정상 상태를 트리거합니다 (장애 상태는 1이지만 정상 상태가 되려면 2가 필요함).

서비스 bar 지역 2 비정상 시나리오

이 시나리오에서는 두 VM 인스턴스 중 하나의 웹 서버를 중지하여 리전 2에서 PSC 프로듀서 서비스 bar의 장애를 시뮬레이션합니다.

서버 VM 세부정보 가져오기

# set env var for a bar service vm name
export BAR_FAIL_NAME=$(gcloud compute instance-groups managed list-instances mig-bar \
  --limit=1 \
  --region=${REGION_2} \
  --format="value(name)")
echo ${BAR_FAIL_NAME}
# set env var for a bar service zone
export BAR_FAIL_ZONE=$(gcloud compute instance-groups managed list-instances mig-bar \
  --limit=1 \
  --region=${REGION_2} \
  --format="value(ZONE)")
echo ${BAR_FAIL_ZONE}

서버 VM에 SSH로 연결하고 http 서버 중지

gcloud compute ssh ${BAR_FAIL_NAME} --zone=${BAR_FAIL_ZONE}
# stop apache http server to fail service
sudo systemctl stop apache2
# verify service dead
sudo systemctl status apache2 | grep Active:
# exit vm ssh
exit

리전 서비스가 비정상인지 확인

# check health state of backend service
gcloud compute backend-services get-health ilb-bar --region=${REGION_2}

출력은 다음과 유사합니다.

backend: .../regions/<REGION_2>/instanceGroups/mig-bar
status:
  healthStatus:
  -   forwardingRule: .../regions/<REGION_2>/forwardingRules/fr-bar
    forwardingRuleIp: 172.16.2.99
    healthState: UNHEALTHY
    instance: .../zones/<ZONE_2x>/instances/<BAR_FAIL_NAME>
    ipAddress: <BAR_FAIL_IP>
    port: 80
  -   forwardingRule: .../regions/<REGION_2>/forwardingRules/fr-bar
    forwardingRuleIp: 172.16.2.99
    healthState: HEALTHY
    instance: .../zones/<ZONE_2y>/instances/<BAR_OTHER_NAME>
    ipAddress: <BAR_OTHER_IP>
    port: 80
  kind: compute#backendServiceGroupHealth

SSH를 통해 리전 2 클라이언트 VM에 연결하고 장애 조치 테스트

gcloud compute ssh client-2 --zone=${ZONE_2}
# send request to service using hostname
curl -v www.foobar.com
# curl to ilb vip in region 1
curl 10.10.1.99
# curl to ilb vip in region 2
curl 10.10.2.99

PSC 상태가 소비자 부하 분산기를 업데이트하고 리전 2의 비정상 백엔드 서비스를 피하도록 지시했습니다. 대신 리전 1의 정상 서비스 foo로 트래픽을 전달했습니다.

소비자 부하 분산기에서 모든 프로듀서 서비스를 비정상으로 간주하는 경우 부하 분산기는 정상 인스턴스로 장애 조치할 수 없습니다. 예상되는 동작은 부하 분산기가 비정상 백엔드 전체에 트래픽을 분산하는 것입니다 (장애 발생 시 열림).

# exit client vm ssh
exit

이것으로 테스트 부분을 마치고 정리로 넘어갑니다.

8. 삭제

# delete health resources
gcloud -q beta compute composite-health-checks delete foo-health-composite --region=${REGION_1}

gcloud -q beta compute health-sources delete foo-health-source --region=${REGION_1}

gcloud -q beta compute health-aggregation-policies delete foo-health-policy --region=${REGION_1}

gcloud -q beta compute composite-health-checks delete bar-health-composite --region=${REGION_2}

gcloud -q beta compute health-sources delete bar-health-source --region=${REGION_2}

gcloud -q beta compute health-aggregation-policies delete bar-health-policy --region=${REGION_2}
# delete consumer compute and load balancer resources
gcloud -q compute instances delete client-2 --zone=${ZONE_2}

gcloud -q compute instances delete client-1 --zone=${ZONE_1}

gcloud -q dns record-sets delete www.foobar.com --type=A --zone=zone-foobar

gcloud -q dns managed-zones delete zone-foobar

gcloud -q compute forwarding-rules delete fr-foobar-2 --global

gcloud -q compute forwarding-rules delete fr-foobar-1 --global

gcloud -q compute target-http-proxies delete proxy-foobar --global

gcloud -q compute url-maps delete ilb-foobar --global

gcloud -q compute backend-services delete bes-foobar --global


# delete consumer network resources
gcloud -q compute network-endpoint-groups delete neg-bar --region=${REGION_2}

gcloud -q compute network-endpoint-groups delete neg-foo --region=${REGION_1}

gcloud -q compute networks subnets delete subnet-proxy-2 --region=${REGION_2}

gcloud -q compute networks subnets delete subnet-proxy-1 --region=${REGION_1}

gcloud -q compute networks subnets delete subnet-client-2 --region=${REGION_2}

gcloud -q compute networks subnets delete subnet-client-1 --region=${REGION_1}

gcloud -q compute network-firewall-policies associations delete \
  --firewall-policy=fw-policy-consumer \
  --name=fw-policy-association-consumer \
  --global-firewall-policy

gcloud -q compute network-firewall-policies delete fw-policy-consumer --global

gcloud -q compute networks delete vnet-consumer
# delete producer load balancer resources
gcloud -q compute service-attachments delete psc-sa-bar --region=${REGION_2}

gcloud -q compute service-attachments delete psc-sa-foo --region=${REGION_1}

gcloud -q compute forwarding-rules delete fr-bar --region=${REGION_2}

gcloud -q compute forwarding-rules delete fr-foo --region=${REGION_1}

gcloud -q compute backend-services delete ilb-bar --region=${REGION_2}

gcloud -q compute backend-services delete ilb-foo --region=${REGION_1}

gcloud -q compute health-checks delete hc-bar-http --region=${REGION_2}

gcloud -q compute health-checks delete hc-foo-http --region=${REGION_1}
# delete producer compute resources
gcloud -q compute instance-groups managed delete mig-bar --region=${REGION_2}

gcloud -q compute instance-groups managed delete mig-foo --region=${REGION_1}

gcloud -q compute instance-templates delete mig-template-bar --global

gcloud -q compute instance-templates delete mig-template-foo --global
# delete producer network resources
gcloud -q compute networks subnets delete subnet-bar-pscnat --region=${REGION_2}

gcloud -q compute networks subnets delete subnet-foo-pscnat --region=${REGION_1}

gcloud -q compute networks subnets delete subnet-bar --region=${REGION_2}

gcloud -q compute networks subnets delete subnet-foo --region=${REGION_1}

gcloud -q compute routers delete cr-nat-bar --region=${REGION_2}

gcloud -q compute routers delete cr-nat-foo --region=${REGION_1}

gcloud -q compute network-firewall-policies associations delete \
  --firewall-policy=fw-policy-producer \
  --name=fw-policy-association-producer \
  --global-firewall-policy

gcloud -q compute network-firewall-policies delete fw-policy-producer --global

gcloud -q compute networks delete vnet-producer
# delete shell variables and script file
unset FOO_FAIL_NAME FOO_FAIL_ZONE BAR_FAIL_NAME BAR_FAIL_ZONE

unset PROJECT_ID REGION_1 ZONE_1 REGION_2 ZONE_2

rm vm-server-startup.sh
#

9. 결론

축하합니다. PSC 상태를 구성하고 자동 리전 장애 조치를 테스트했습니다.

의견 양식을 사용하여 의견, 질문 또는 수정사항을 자유롭게 제공해 주세요.

감사합니다.