1. 알파 워크숍
워크숍 Codelab bit.ly/asm-workshop 링크
2. 개요
아키텍처 다이어그램
이 워크숍은 프로덕션 환경에서 GCP에 전 세계에 분산된 서비스를 설정하는 방법을 알아보는 몰입형 몰입형 체험입니다. 주로 사용되는 기술은 컴퓨팅용 Google Kubernetes Engine (GKE)과 안전한 연결, 관측 가능성, 고급 트래픽 형태를 만드는 Istio 서비스 메시입니다. 이 워크숍에서 사용하는 모든 권장사항과 도구는 프로덕션에서도 사용됩니다.
주제
- 모듈 0 - 소개 및 플랫폼 설정
- 소개 및 아키텍처
- 서비스 메시 및 Istio/ASM 소개
- 실습: 인프라 설정: 사용자 워크플로
- 휴식 시간
- QnA
- 모듈 1 - ASM으로 애플리케이션 설치, 보호, 모니터링
- 저장소 모델: 인프라 및 Kubernetes 저장소 설명
- 실습: 샘플 애플리케이션 배포하기
- 분산 서비스 및 관측 가능성
- 점심
- 실습: Stackdriver를 사용한 관측 가능성
- QNA
- 모듈 2 - DevOps - 카나리아 출시, 정책/RBAC
- 멀티 클러스터 서비스 검색 및 보안/정책
- 실습: 상호 TLS
- 카나리아 배포
- 실습: 카나리아 배포
- 멀티 클러스터 전역 부하 분산 보호
- 휴식 시간
- 실습: 승인 정책
- QNA
- 모듈 3 - 인프라 운영 - 플랫폼 업그레이드
- 분산 서비스 빌딩 블록
- 실습: 인프라 확장
- 다음 단계
Slides
이 워크숍의 슬라이드는 다음 링크에서 확인할 수 있습니다.
기본 요건
이 워크숍을 진행하려면 다음 요건을 충족해야 합니다.
- GCP 조직 노드
- 결제 계정 ID (사용자가 이 결제 계정의 결제 관리자여야 함)
- 사용자의 조직 수준에서 조직 관리자 IAM 역할
3. 인프라 설정 - 관리자 워크플로
부트스트랩 워크숍 스크립트 설명
bootstrap_workshop.sh라는 스크립트가 워크숍의 초기 환경을 설정하는 데 사용됩니다. 이 스크립트를 사용하여 본인을 위한 단일 환경을 설정하거나 여러 사용자를 위한 여러 환경을 설정할 수 있습니다(이 워크숍을 여러 사용자에게 교육하는 경우).
부트스트랩 워크숍 스크립트에는 다음을 입력으로 사용해야 합니다.
- 조직 이름 (예:
yourcompany.com
) - 워크숍 환경을 만드는 조직입니다. - 결제 ID (예:
12345-12345-12345
) - 이 결제 ID는 워크숍 중에 사용된 모든 리소스를 청구하는 데 사용됩니다. - 워크숍 번호 (예:
01
) - 2자리 숫자입니다. 이는 하루에 여러 워크숍을 진행하면서 개별적으로 추적하고 싶을 때 사용됩니다. 워크숍 번호는 프로젝트 ID를 도출하는 데도 사용됩니다. 별도의 워크숍 번호를 사용하면 매번 고유한 프로젝트 ID를 쉽게 확인할 수 있습니다. 워크숍 번호 외에 현재 날짜 (YYMMDD
형식)도 프로젝트 ID로 사용됩니다. 날짜와 워크숍 번호를 조합하면 고유한 프로젝트 ID가 제공됩니다. - 시작 사용자 수 (예:
1
) - 이 번호는 워크숍의 첫 번째 사용자를 나타냅니다. 예를 들어 10명의 사용자를 대상으로 워크숍을 만들려는 경우 시작 사용자 번호는 1, 최종 사용자 번호는 10으로 설정할 수 있습니다. - 최종 사용자 번호 (예:
10
) - 이 숫자는 워크숍의 마지막 사용자를 나타냅니다. 예를 들어 10명의 사용자를 대상으로 워크숍을 만들려는 경우 시작 사용자 번호는 1, 최종 사용자 번호는 10으로 설정할 수 있습니다. 단일 환경을 설정하는 경우 (예: 본인) 시작 및 최종 사용자 번호를 동일하게 합니다. 이렇게 하면 단일 환경이 만들어집니다.
- 관리자 GCS 버킷 (예:
my-gcs-bucket-name
) - GCS 버킷은 워크숍 관련 정보를 저장하는 데 사용됩니다. 이 정보는 cleanup_workshop.sh 스크립트에서 부트스트랩 워크숍 스크립트 중에 생성된 모든 리소스를 정상적으로 삭제하기 위해 사용됩니다. 워크숍을 만드는 관리자에게 이 버킷에 대한 읽기/쓰기 권한이 있어야 합니다.
부트스트랩 워크숍 스크립트는 위에 제공된 값을 사용하고 setup-terraform-admin-project.sh 스크립트를 호출하는 래퍼 스크립트 역할을 합니다. setup-terraform-admin-project.sh 스크립트는 단일 사용자를 위한 워크숍 환경을 생성합니다.
워크숍 부트스트랩에 필요한 관리자 권한
이 워크숍에는 두 가지 유형의 사용자가 있습니다. ADMIN_USER
: 이 워크숍의 리소스를 만들고 삭제합니다. 두 번째는 MY_USER
로, 워크숍에서 걸음 수를 수행합니다. MY_USER
는 자체 리소스에만 액세스할 수 있습니다. ADMIN_USER
앱은 모든 사용자 설정에 액세스할 수 있습니다. 이 설정을 직접 만드는 경우 ADMIN_USER
와 MY_USER
가 동일합니다. 강사가 여러 학생을 대상으로 이 워크숍을 만드는 경우 ADMIN_USER
및 MY_USER
이(가) 다릅니다.
ADMIN_USER
에 필요한 조직 수준 권한은 다음과 같습니다.
- 소유자 - 조직의 모든 프로젝트에 대한 프로젝트 소유자 권한입니다.
- 폴더 관리자 - 조직에서 폴더를 만들고 삭제할 수 있습니다. 모든 사용자에게는 프로젝트 내의 모든 리소스가 포함된 단일 폴더가 제공됩니다.
- 조직 관리자
- 프로젝트 생성자 - 조직에서 프로젝트를 만들 수 있는 권한
- 프로젝트 삭제자 - 조직의 프로젝트를 삭제할 수 있습니다.
- 프로젝트 IAM 관리자 - 조직의 모든 프로젝트에서 IAM 규칙을 만들 수 있습니다.
또한 ADMIN_USER
님은 워크숍에 사용되는 결제 ID의 결제 관리자여야 합니다.
워크숍 수행 사용자 스키마 및 권한
조직의 다른 사용자 (본인이 아닌)를 위해 이 워크숍을 만들려면 MY_USERs
에 대한 특정 사용자 명명 스키마를 따라야 합니다. bootstrap_workshop.sh 스크립트 중에 시작 및 최종 사용자 번호를 제공합니다. 이 번호는 다음 사용자 이름을 만드는 데 사용됩니다.
user<3 digit user number>@<organization_name>
예를 들어 yourcompany.com이라는 조직에서 시작 사용자 번호가 1이고 최종 사용자 번호가 3인 부트스트랩 워크숍 스크립트를 실행하면 다음 사용자를 위한 워크숍 환경이 생성됩니다.
user001@yourcompany.com
user002@yourcompany.com
user003@yourcompany.com
이러한 사용자 이름에는 setup_terraform_admin_project.sh 스크립트에서 생성된 특정 프로젝트의 프로젝트 소유자 역할이 할당됩니다. 부트스트랩 스크립트를 사용할 때는 이 사용자 이름 지정 스키마를 준수해야 합니다. G Suite에서 한 번에 여러 사용자를 추가하는 방법을 참조하세요.
워크숍에 필요한 도구
이 워크숍은 Cloud Shell에서 부트스트랩되도록 제작되었습니다. 이 워크숍에는 다음 도구가 필요합니다.
- gcloud (버전 270 이상)
- kubectl
- sed (Mac OS가 아닌 Cloud Shell/Linux에서 sed와 함께 작동)
- git (최신 버전인지 확인)
sudo apt update
sudo apt install git
- jq
- envsubst
- kustomize
워크숍 직접 설정 (단일 사용자 설정)
- Cloud Shell을 열고 Cloud Shell에서 아래 작업을 모두 수행합니다. 아래 링크를 클릭하세요.
- 원하는 관리자로 gcloud에 로그인했는지 확인합니다.
gcloud config list
WORKDIR
를 만들고 워크숍 저장소를 클론합니다.
mkdir asm-workshop
cd asm-workshop
export WORKDIR=`pwd`
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git asm
- 워크숍에 사용할 조직 이름, 결제 ID, 워크숍 번호, 관리자 GCS 버킷을 정의합니다. 위 섹션에서 워크숍을 설정하는 데 필요한 권한을 검토합니다.
gcloud organizations list
export ORGANIZATION_NAME=<ORGANIZATION NAME>
gcloud beta billing accounts list
export ADMIN_BILLING_ID=<ADMIN_BILLING ID>
export WORKSHOP_NUMBER=<two digit number for example 01>
export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
- bootstrap_workshop.sh 스크립트를 실행합니다. 이 스크립트를 완료하는 데 몇 분 정도 걸릴 수 있습니다.
cd asm
./scripts/bootstrap_workshop.sh --org-name ${ORGANIZATION_NAME} --billing-id ${ADMIN_BILLING_ID} --workshop-num ${WORKSHOP_NUMBER} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET} --set-up-for-admin
bootstrap_workshop.sh 스크립트가 완료되면 조직 내 각 사용자의 GCP 폴더가 생성됩니다. 폴더 내에 terraform 관리자 프로젝트가 생성됩니다. terraform 관리자 프로젝트는 이 워크숍에 필요한 나머지 GCP 리소스를 만드는 데 사용됩니다. terraform 관리자 프로젝트에서 필수 API를 사용 설정합니다. Cloud Build를 사용하여 Terraform 계획을 적용합니다. GCP에서 리소스를 만들 수 있도록 Cloud Build 서비스 계정에 적절한 IAM 역할을 부여합니다. 마지막으로 GCS (Google Cloud Storage) 버킷에 모든 GCP 리소스의 Terraform 상태를 저장하도록 원격 백엔드를 구성합니다.
terraform 관리자 프로젝트에서 Cloud Build 태스크를 보려면 terraform 관리자 프로젝트 ID가 필요합니다. asm 디렉터리의 vars/vars.sh 파일에 저장됩니다. 이 디렉터리는 관리자가 직접 워크숍을 설정하는 경우에만 유지됩니다.
- 변수 파일을 제공하여 환경 변수 설정
echo "export WORKDIR=$WORKDIR" >> $WORKDIR/asm/vars/vars.sh
source $WORKDIR/asm/vars/vars.sh
여러 사용자를 위한 워크숍 준비 (멀티 사용자 설정)
- Cloud Shell을 열고 Cloud Shell에서 아래 작업을 모두 수행합니다. 아래 링크를 클릭하세요.
- 원하는 관리자로 gcloud에 로그인했는지 확인합니다.
gcloud config list
WORKDIR
를 만들고 워크숍 저장소를 클론합니다.
mkdir asm-workshop
cd asm-workshop
export WORKDIR=`pwd`
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git asm
- 조직 이름, 결제 ID, 워크숍 번호, 시작 및 최종 사용자 번호, 워크숍에 사용할 관리자 GCS 버킷을 정의합니다. 위 섹션에서 워크숍을 설정하는 데 필요한 권한을 검토합니다.
gcloud organizations list
export ORGANIZATION_NAME=<ORGANIZATION NAME>
gcloud beta billing accounts list
export ADMIN_BILLING_ID=<BILLING ID>
export WORKSHOP_NUMBER=<two digit number for example 01>
export START_USER_NUMBER=<number for example 1>
export END_USER_NUMBER=<number greater or equal to START_USER_NUM>
export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
- bootstrap_workshop.sh 스크립트를 실행합니다. 이 스크립트를 완료하는 데 몇 분 정도 걸릴 수 있습니다.
cd asm
./scripts/bootstrap_workshop.sh --org-name ${ORGANIZATION_NAME} --billing-id ${ADMIN_BILLING_ID} --workshop-num ${WORKSHOP_NUMBER} --start-user-num ${START_USER_NUMBER} --end-user-num ${END_USER_NUMBER} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET}
- 관리자 GCS 버킷에서 workshop.txt 파일을 가져와 terraform 프로젝트 ID를 가져옵니다.
export WORKSHOP_ID="$(date '+%y%m%d')-${WORKSHOP_NUMBER}"
gsutil cp gs://${ADMIN_STORAGE_BUCKET}/${ORGANIZATION_NAME}/${WORKSHOP_ID}/workshop.txt .
4. 실습 설정 및 준비
실습 과정 선택
이 워크숍의 실습은 다음 두 가지 방법 중 하나로 수행할 수 있습니다.
- '쉬운 패스트 트랙 대화형 스크립트' 방법
- '각 안내를 직접 복사하여 붙여넣기' 방법
빠른 추적 스크립트 메서드를 사용하면 각 실습에서 명령어를 자동으로 실행하여 실습을 안내하는 단일 대화형 스크립트를 실행할 수 있습니다. 명령어는 각 단계 및 각 단계와 그에 따른 결과에 대한 간결한 설명과 함께 일괄적으로 실행됩니다. 각 배치가 끝나면 다음 배치의 명령어로 이동하라는 메시지가 표시됩니다. 이렇게 하면 각자의 속도에 맞게 실습을 진행할 수 있습니다. 패스트 트랙 스크립트는 멱등성을 지닙니다. 즉, 이 스크립트를 여러 번 실행하여 같은 결과를 얻을 수 있습니다.
빠른 트랙 스크립트는 아래와 같이 모든 실습의 상단에 녹색 상자 안에 표시됩니다.
복사하여 붙여넣기 방법은 명령어에 관한 설명과 함께 개별 명령어 블록을 복사하여 붙여넣는 기존 방법입니다. 이 메서드는 한 번만 실행해야 합니다. 이 메서드에서 명령어를 다시 실행해도 동일한 결과가 나온다는 보장은 없습니다.
실습을 수행할 때는 두 가지 방법 중 하나를 선택하세요.
빠른 트랙 스크립트 설정
사용자 정보 가져오기
이 워크숍은 워크숍 관리자가 만든 임시 사용자 계정 (또는 실습 계정)을 사용해 진행됩니다. 실습 계정은 워크숍의 모든 프로젝트를 소유합니다. 워크숍 관리자는 워크숍을 수행하는 사용자에게 실습 계정 사용자 인증 정보 (사용자 이름 및 비밀번호)를 제공합니다. 사용자의 모든 프로젝트에는 실습 계정의 사용자 이름이 접두사로 붙습니다. 예를 들어 실습 계정 user001@yourcompany.com
의 경우 terraform 관리자 프로젝트 ID는 user001-200131-01-tf-abcde
입니다. 나머지 프로젝트의 경우 이런 식으로 진행됩니다. 각 사용자는 워크숍 관리자가 제공한 실습 계정으로 로그인하고 실습 계정을 사용하여 워크숍을 진행해야 합니다.
- 아래 링크를 클릭하여 Cloud Shell을 엽니다.
- 실습 계정 사용자 인증 정보로 로그인합니다 (회사 또는 개인 계정으로 로그인하지 않음). 실습 계정은
userXYZ@<workshop_domain>.com
과 같습니다. - 새 계정이므로 Google 서비스 약관에 동의하라는 메시지가 표시됩니다. '수락'을 클릭합니다.
4. 다음 화면에서 체크박스를 선택하여 Google 서비스 약관에 동의하고 Start Cloud Shell
를 클릭합니다.
이 단계에서는 GCP 리소스에 액세스하는 데 사용할 작은 Linux Debian VM을 프로비저닝합니다. 각 계정에 Cloud Shell VM이 하나씩 제공됩니다. 실습 계정으로 로그인하면 실습 계정 사용자 인증 정보를 프로비저닝하고 사용하여 로그인할 수 있습니다. Cloud Shell 외에도 코드 편집기도 제공되어 구성 파일 (terraform, YAML 등)을 더 쉽게 편집할 수 있습니다. 기본적으로 Cloud Shell 화면은 Cloud Shell 셸 환경 (하단)과 Cloud Code 편집기 (상단)로 분할되어 있습니다. 오른쪽 상단의 연필 및 셸 프롬프트 아이콘을 사용하면 이 두 가지 모드 (셸 및 코드 편집기) 간에 전환할 수 있습니다. 가운데 분리 막대를 위 또는 아래로 드래그하여 각 창의 크기를 수동으로 변경할 수도 있습니다. 5. 이 워크숍을 위한 WORKDIR을 만듭니다. WORKDIR은 이 워크숍의 모든 실습을 수행하는 폴더입니다. Cloud Shell에서 다음 명령어를 실행하여 WORKDIR을 만듭니다.
mkdir -p ${HOME}/asm-workshop
cd ${HOME}/asm-workshop
export WORKDIR=`pwd`
- 실습 계정 사용자를 이 워크숍에 사용할 변수로 내보냅니다. 이 계정은 Cloud Shell에 로그인할 때 사용한 계정과 동일한 계정입니다.
export MY_USER=<LAB ACCOUNT EMAIL PROVIDED BY THE WORKSHOP ADMIN>
# For example export MY_USER=user001@gcpworkshops.com
- 다음 명령어를 실행하여 WORKDIR 및 MY_USER 변수를 에코하여 둘 다 올바르게 설정되었는지 확인합니다.
echo "WORKDIR set to ${WORKDIR}" && echo "MY_USER set to ${MY_USER}"
- 워크숍 저장소를 클론합니다.
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git ${WORKDIR}/asm
5. 인프라 설정 - 사용자 워크플로
목표: 인프라 및 Istio 설치 확인
- 워크숍 도구 설치
- 워크숍 저장소 클론
Infrastructure
설치 확인k8s-repo
설치 확인- Istio 설치 확인
복사하여 붙여넣기 방법 실습 안내
사용자 정보 가져오기
워크숍을 설정하는 관리자가 사용자에게 사용자 이름과 비밀번호 정보를 제공해야 합니다. 사용자의 모든 프로젝트에는 사용자 user001@yourcompany.com
의 경우 사용자 이름이 접두사로 붙으며, 나머지 프로젝트의 경우 terraform 관리자 프로젝트 ID는 user001-200131-01-tf-abcde
입니다. 각 사용자는 자신의 작업장 환경에만 액세스할 수 있습니다.
워크숍에 필요한 도구
이 워크숍은 Cloud Shell에서 부트스트랩되도록 제작되었습니다. 이 워크숍에는 다음 도구가 필요합니다.
- gcloud (버전 270 이상)
- kubectl
- sed (Mac OS가 아닌 Cloud Shell/Linux에서 sed와 함께 작동)
- git (최신 버전인지 확인)
sudo apt update
sudo apt install git
- jq
- envsubst
- kustomize
- pv
Terraform 관리자 프로젝트에 액세스
bootstrap_workshop.sh 스크립트가 완료되면 조직 내 각 사용자의 GCP 폴더가 생성됩니다. 폴더 내에 terraform 관리자 프로젝트가 생성됩니다. terraform 관리자 프로젝트는 이 워크숍에 필요한 나머지 GCP 리소스를 만드는 데 사용됩니다. setup-terraform-admin-project.sh 스크립트는 terraform 관리자 프로젝트에서 필수 API를 사용 설정합니다. Cloud Build는 Terraform 계획을 적용하는 데 사용됩니다. 이 스크립트를 통해 Cloud Build 서비스 계정에 적절한 IAM 역할을 부여하여 GCP에서 리소스를 생성할 수 있도록 합니다. 마지막으로 원격 백엔드는 모든 GCP 리소스의 Terraform 상태를 저장하도록 Google Cloud Storage (GCS) 버킷에 구성됩니다.
terraform 관리자 프로젝트에서 Cloud Build 태스크를 보려면 terraform 관리자 프로젝트 ID가 필요합니다. 부트스트랩 스크립트에 지정된 관리자 GCS 버킷에 저장됩니다. 여러 사용자에 대해 부트스트랩 스크립트를 실행하는 경우 모든 Terraform 관리자 프로젝트 ID가 GCS 버킷에 저장됩니다.
- 아래 링크를 클릭하여 Cloud Shell을 엽니다 (실습 설정 및 준비 섹션에서 아직 열려 있지 않은 경우).
$HOME/bin
폴더에 kustomize를 설치하고$HOME/bin
폴더를 $PATH에 추가합니다.
mkdir -p $HOME/bin
cd $HOME/bin
curl -s "https://raw.githubusercontent.com/\
kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
cd $HOME
export PATH=$PATH:${HOME}/bin
echo "export PATH=$PATH:$HOME/bin" >> $HOME/.bashrc
- pv를 설치하고 $HOME/bin/pv로 이동합니다.
sudo apt-get update && sudo apt-get -y install pv
sudo mv /usr/bin/pv ${HOME}/bin/pv
- bash 프롬프트를 업데이트합니다.
cp $WORKDIR/asm/scripts/krompt.bash $HOME/.krompt.bash
echo "export PATH=\$PATH:\$HOME/bin" >> $HOME/.asm-workshop.bash
echo "source $HOME/.krompt.bash" >> $HOME/.asm-workshop.bash
alias asm-init='source $HOME/.asm-workshop.bash' >> $HOME/.bashrc
echo "source $HOME/.asm-workshop.bash" >> $HOME/.bashrc
source $HOME/.bashrc
- 원하는 사용자 계정으로 gcloud에 로그인했는지 확인합니다.
echo "Check logged in user output from the next command is $MY_USER"
gcloud config list account --format=json | jq -r .core.account
- 다음 명령어를 실행하여 Terraform 관리자 프로젝트 ID를 가져옵니다.
export TF_ADMIN=$(gcloud projects list | grep tf- | awk '{ print $1 }')
echo $TF_ADMIN
- 워크숍과 관련된 모든 리소스는 terraform 관리자 프로젝트의 GCS 버킷에 저장된 vars.sh 파일에 변수로 저장됩니다. terraform 관리자 프로젝트의 vars.sh 파일을 가져옵니다.
mkdir $WORKDIR/asm/vars
gsutil cp gs://$TF_ADMIN/vars/vars.sh $WORKDIR/asm/vars/vars.sh
echo "export WORKDIR=$WORKDIR" >> $WORKDIR/asm/vars/vars.sh
- 표시된 링크를 클릭하여 Terraform 관리자 프로젝트의 Cloud Build 페이지를 열고 빌드가 성공적으로 완료되었는지 확인합니다.
source $WORKDIR/asm/vars/vars.sh
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_ADMIN}"
Cloud 콘솔에 처음 액세스하는 경우 Google 서비스 약관에 동의합니다.
- 이제 Cloud Build 페이지가 표시됩니다. 왼쪽 탐색 메뉴에서
History
링크를 클릭하고 최신 빌드를 클릭하여 초기 Terraform 적용의 세부정보를 확인합니다. 다음 리소스는 Terraform 스크립트의 일부로 생성됩니다. 위의 아키텍처 다이어그램을 참조할 수도 있습니다.
- 조직의 GCP 프로젝트 4개 제공된 결제 계정이 각 프로젝트와 연결되어 있습니다.
- 프로젝트 하나는 공유 VPC의
network host project
입니다. 이 프로젝트에 다른 리소스가 생성되지 않습니다. - 프로젝트 하나는 Istio 제어 영역 GKE 클러스터에 사용되는
ops project
입니다. - 두 개의 프로젝트는 각각의 서비스를 개발하는 두 개의 서로 다른 개발팀을 나타냅니다.
- 3개의
ops
,dev1
,dev2
프로젝트에 각각 2개의 GKE 클러스터가 생성됩니다. - Kubernetes 매니페스트 파일용 폴더 6개가 포함된
k8s-repo
라는 CSR 저장소가 생성됩니다. GKE 클러스터당 폴더 1개 이 저장소는 GitOps 방식으로 Kubernetes 매니페스트를 클러스터에 배포하는 데 사용됩니다. k8s-repo
의 마스터 브랜치에 커밋이 있을 때마다 해당 폴더에서 Kubernetes 매니페스트를 GKE 클러스터에 배포하도록 Cloud Build 트리거가 생성됩니다.
terraform admin project
에서 빌드가 완료되면 운영 프로젝트에서 다른 빌드가 시작됩니다. 표시된 링크를 클릭하여ops project
의 Cloud Build 페이지를 열고 k8s-repo Cloud Build가 성공적으로 완료되었는지 확인합니다.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
설치 확인
- 모든 클러스터의 kubeconfig 파일을 만듭니다. 다음 스크립트를 실행합니다.
$WORKDIR/asm/scripts/setup-gke-vars-kubeconfig.sh
이 스크립트는 gke
폴더에 kubemesh
라는 새 kubeconfig 파일을 만듭니다.
KUBECONFIG
변수가 새 kubeconfig 파일을 가리키도록 변경합니다.
source $WORKDIR/asm/vars/vars.sh
export KUBECONFIG=$WORKDIR/asm/gke/kubemesh
- vars.sh 및 KUBECONFIG var를 Cloud Shell의 .bashrc에 추가하여 Cloud Shell이 다시 시작될 때마다 제공됩니다.
echo "source ${WORKDIR}/asm/vars/vars.sh" >> $HOME/.bashrc
echo "export KUBECONFIG=${WORKDIR}/asm/gke/kubemesh" >> $HOME/.bashrc
- 클러스터 컨텍스트를 나열합니다. 6개의 클러스터가 표시됩니다.
kubectl config view -ojson | jq -r '.clusters[].name'
`Output (do not copy)`
gke_tf05-01-ops_us-central1_gke-asm-2-r2-prod gke_tf05-01-ops_us-west1_gke-asm-1-r1-prod gke_tf05-02-dev1_us-west1-a_gke-1-apps-r1a-prod gke_tf05-02-dev1_us-west1-b_gke-2-apps-r1b-prod gke_tf05-03-dev2_us-central1-a_gke-3-apps-r2a-prod gke_tf05-03-dev2_us-central1-b_gke-4-apps-r2b-prod
Istio 설치 확인
- 모든 포드가 실행 중이고 작업이 완료되었는지 확인하여 Istio가 두 클러스터 모두에 설치되었는지 확인합니다.
kubectl --context ${OPS_GKE_1} get pods -n istio-system
kubectl --context ${OPS_GKE_2} get pods -n istio-system
`Output (do not copy)`
NAME READY STATUS RESTARTS AGE grafana-5f798469fd-z9f98 1/1 Running 0 6m21s istio-citadel-568747d88-qdw64 1/1 Running 0 6m26s istio-egressgateway-8f454cf58-ckw7n 1/1 Running 0 6m25s istio-galley-6b9495645d-m996v 2/2 Running 0 6m25s istio-ingressgateway-5df799fdbd-8nqhj 1/1 Running 0 2m57s istio-pilot-67fd786f65-nwmcb 2/2 Running 0 6m24s istio-policy-74cf89cb66-4wrpl 2/2 Running 1 6m25s istio-sidecar-injector-759bf6b4bc-mw4vf 1/1 Running 0 6m25s istio-telemetry-77b6dfb4ff-zqxzz 2/2 Running 1 6m24s istio-tracing-cd67ddf8-n4d7k 1/1 Running 0 6m25s istiocoredns-5f7546c6f4-g7b5c 2/2 Running 0 6m39s kiali-7964898d8c-5twln 1/1 Running 0 6m23s prometheus-586d4445c7-xhn8d 1/1 Running 0 6m25s
`Output (do not copy)`
NAME READY STATUS RESTARTS AGE grafana-5f798469fd-2s8k4 1/1 Running 0 59m istio-citadel-568747d88-87kdj 1/1 Running 0 59m istio-egressgateway-8f454cf58-zj9fs 1/1 Running 0 60m istio-galley-6b9495645d-qfdr6 2/2 Running 0 59m istio-ingressgateway-5df799fdbd-2c9rc 1/1 Running 0 60m istio-pilot-67fd786f65-nzhx4 2/2 Running 0 59m istio-policy-74cf89cb66-4bc7f 2/2 Running 3 59m istio-sidecar-injector-759bf6b4bc-grk24 1/1 Running 0 59m istio-telemetry-77b6dfb4ff-6zr94 2/2 Running 4 60m istio-tracing-cd67ddf8-grs9g 1/1 Running 0 60m istiocoredns-5f7546c6f4-gxd66 2/2 Running 0 60m kiali-7964898d8c-nhn52 1/1 Running 0 59m prometheus-586d4445c7-xr44v 1/1 Running 0 59m
- Istio가
dev1
클러스터 모두에 설치되어 있는지 확인합니다. Citadel, 사이드카 인젝터, coredns만dev1
클러스터에서 실행됩니다. ops-1 클러스터에서 실행되는 Istio 제어 영역을 공유합니다.
kubectl --context ${DEV1_GKE_1} get pods -n istio-system
kubectl --context ${DEV1_GKE_2} get pods -n istio-system
- Istio가
dev2
클러스터 모두에 설치되어 있는지 확인합니다. Citadel, 사이드카 인젝터, coredns만dev2
클러스터에서 실행됩니다. ops-2 클러스터에서 실행되는 Istio 제어 영역을 공유합니다.
kubectl --context ${DEV2_GKE_1} get pods -n istio-system
kubectl --context ${DEV2_GKE_2} get pods -n istio-system
`Output (do not copy)`
NAME READY STATUS RESTARTS AGE istio-citadel-568747d88-4lj9b 1/1 Running 0 66s istio-sidecar-injector-759bf6b4bc-ks5br 1/1 Running 0 66s istiocoredns-5f7546c6f4-qbsqm 2/2 Running 0 78s
공유 제어 영역의 서비스 검색 확인
- 필요한 경우 보안 비밀이 배포되었는지 확인합니다.
kubectl --context ${OPS_GKE_1} get secrets -l istio/multiCluster=true -n istio-system
kubectl --context ${OPS_GKE_2} get secrets -l istio/multiCluster=true -n istio-system
`Output (do not copy)`
For OPS_GKE_1: NAME TYPE DATA AGE gke-1-apps-r1a-prod Opaque 1 8m7s gke-2-apps-r1b-prod Opaque 1 8m7s gke-3-apps-r2a-prod Opaque 1 44s gke-4-apps-r2b-prod Opaque 1 43s For OPS_GKE_2: NAME TYPE DATA AGE gke-1-apps-r1a-prod Opaque 1 40s gke-2-apps-r1b-prod Opaque 1 40s gke-3-apps-r2a-prod Opaque 1 8m4s gke-4-apps-r2b-prod Opaque 1 8m4s
이 워크숍에서는 모든 GKE 클러스터가 생성되는 단일 공유 VPC를 사용합니다. 클러스터 간에 서비스를 검색하려면 운영 클러스터에서 보안 비밀로 생성된 kubeconfig 파일 (각 애플리케이션 클러스터의 경우)을 사용합니다. 파일럿은 (위 보안 비밀을 통해 인증된) 애플리케이션 클러스터의 Kube API 서버를 쿼리하여 이러한 보안 비밀을 사용하여 서비스를 검색합니다. 두 작업 클러스터가 kubeconfig에서 생성된 보안 비밀을 사용하여 모든 앱 클러스터에 인증할 수 있습니다. 운영 클러스터는 kubeconfig 파일을 보안 비밀 메서드로 사용하여 서비스를 자동으로 탐색할 수 있습니다. 이를 위해서는 운영 클러스터의 파일럿에서 다른 모든 클러스터의 Kube API 서버에 액세스할 수 있어야 합니다. 파일럿이 Kube API 서버에 연결할 수 없는 경우 원격 서비스를 ServiceEntries로 수동으로 추가해야 합니다. ServiceEntry는 서비스 레지스트리의 DNS 항목으로 생각하면 됩니다. ServiceEntry는 정규화된 DNS 이름 ( FQDN)과 도달할 수 있는 IP 주소를 사용하여 서비스를 정의합니다. 자세한 내용은 Istio 멀티 클러스터 문서를 참조하세요.
6. Infrastructure Repo 설명
인프라 클라우드 빌드
이 워크숍을 위한 GCP 리소스는 Cloud Build 및 infrastructure
CSR 저장소를 사용하여 빌드되었습니다. 로컬 터미널에서 scripts/bootstrap_workshop.sh
에 있는 부트스트랩 스크립트를 방금 실행했습니다. 부트스트랩 스크립트는 GCP 폴더, terraform 관리자 프로젝트, Cloud Build 서비스 계정에 대한 적절한 IAM 권한을 생성합니다. Terraform 관리자 프로젝트는 Terraform 상태, 로그, 기타 스크립트를 저장하는 데 사용됩니다. 여기에는 infrastructure
및 k8s_repo
CSR 저장소가 포함되어 있습니다. 이러한 저장소에 대해서는 다음 섹션에서 자세히 설명합니다. Terraform 관리자 프로젝트에는 다른 워크숍 리소스가 빌드되지 않습니다. terraform 관리자 프로젝트의 Cloud Build 서비스 계정은 워크숍 리소스를 빌드하는 데 사용됩니다.
infrastructure
폴더에 있는 cloudbuild.yaml
파일은 워크숍용 GCP 리소스를 빌드하는 데 사용됩니다. GCP 리소스를 만드는 데 필요한 모든 도구를 갖춘 커스텀 빌더 이미지를 만듭니다. 이러한 도구에는 gcloud SDK, terraform 및 python, git, jq 등의 기타 유틸리티가 포함됩니다. 커스텀 빌더 이미지는 각 리소스의 terraform plan
및 apply
를 실행합니다. 각 리소스의 terraform 파일은 별도의 폴더에 있습니다 (자세한 내용은 다음 섹션 참고). 리소스는 한 번에 하나씩 빌드되며 일반적인 방식 순서대로 빌드됩니다. 예를 들어 GCP 프로젝트는 프로젝트에서 리소스가 생성되기 전에 빌드됩니다. 자세한 내용은 cloudbuild.yaml
파일을 검토하세요.
Cloud Build는 infrastructure
저장소에 대한 커밋이 있을 때마다 트리거됩니다. 인프라에 적용되는 모든 변경사항은 코드형 인프라 (IaC)로 저장되고 저장소에 커밋됩니다. 워크숍 상태는 항상 이 저장소에 저장됩니다.
폴더 구조 - 팀, 환경, 리소스
인프라 저장소는 워크숍을 위한 GCP 인프라 리소스를 설정합니다. 폴더와 하위 폴더로 구성됩니다. 저장소 내의 기본 폴더는 특정 GCP 리소스를 소유한 team
를 나타냅니다. 폴더의 다음 레이어는 팀의 특정 environment
(예: dev, stage, prod)를 나타냅니다. 환경 내의 다음 폴더 레이어는 특정 resource
(예: host_project, gke_clusters 등)를 나타냅니다. 필수 스크립트 및 terraform 파일은 리소스 폴더 내에 있습니다.
이 워크숍에서는 다음과 같은 네 가지 유형의 팀이 대표됩니다.
- 인프라 - 클라우드 인프라팀을 나타냅니다. 다른 모든 팀의 GCP 리소스 생성을 담당합니다. 리소스에 Terraform 관리자 프로젝트를 사용합니다. 인프라 저장소 자체는 Terraform 관리자 프로젝트와 Terraform 상태 파일 (아래에 설명됨)에 있습니다. 이러한 리소스는 부트스트랩 프로세스 중에 bash 스크립트에 의해 생성됩니다 (자세한 내용은 모듈 0 - 관리자 워크플로 참조).
- network - 네트워킹팀을 나타냅니다. VPC 및 네트워킹 리소스를 담당합니다. 이 팀은 다음과 같은 GCP 리소스를 소유합니다.
host project
- 공유 VPC 호스트 프로젝트를 나타냅니다.shared VPC
- 공유 VPC, 서브넷, 보조 IP 범위, 경로, 방화벽 규칙을 나타냅니다.- ops - 운영팀/개발팀을 나타냅니다. 이들은 다음 리소스를 소유하고 있습니다.
ops project
- 모든 운영 리소스의 프로젝트를 나타냅니다.gke clusters
- 리전별 운영 GKE 클러스터입니다. Istio 제어 영역은 각 운영 GKE 클러스터에 설치됩니다.k8s-repo
- 모든 GKE 클러스터의 GKE 매니페스트가 포함된 CSR 저장소입니다.- apps - 애플리케이션팀을 나타냅니다. 이 워크숍에서는
app1
팀과app2
팀을 시뮬레이션합니다. 이들은 다음 리소스를 소유하고 있습니다. app projects
- 모든 앱팀이 자체 프로젝트를 진행합니다. 이를 통해 특정 프로젝트의 결제 및 IAM을 제어할 수 있습니다.gke clusters
- 애플리케이션 컨테이너/포드가 실행되는 애플리케이션 클러스터입니다.gce instances
- GCE 인스턴스에서 실행되는 애플리케이션이 있는 경우 선택적으로 제공됨 이 워크숍에서 app1에는 애플리케이션의 일부가 실행되는 두 개의 GCE 인스턴스가 있습니다.
이 워크숍에서는 동일한 앱 (Hipster Shop 앱)이 app1과 app2를 모두 나타냅니다.
제공자, 상태, 출력 - 백엔드 및 공유 상태
google
및 google-beta
제공자는 gcp/[environment]/gcp/provider.tf
에 있습니다. provider.tf
파일은 모든 리소스 폴더에서 심볼릭 링크로 연결됩니다. 이렇게 하면 리소스마다 제공업체를 개별적으로 관리하는 대신 한 곳에서 제공업체를 변경할 수 있습니다.
모든 리소스에는 리소스의 tfstate 파일의 위치를 정의하는 backend.tf
파일이 포함되어 있습니다. 이 backend.tf
파일은 스크립트 (scripts/setup_terraform_admin_project
에 위치)를 사용하여 템플릿 (templates/backend.tf_tmpl
에 위치)에서 생성된 다음 각 리소스 폴더에 배치됩니다. Google Cloud Storage (GCS) 버킷은 백엔드에 사용됩니다. GCS 버킷 폴더 이름은 리소스 이름과 일치합니다. 모든 리소스 백엔드는 terraform 관리자 프로젝트에 있습니다.
상호 의존적인 값이 있는 리소스에는 output.tf
파일이 포함됩니다. 필요한 출력 값은 특정 리소스의 백엔드에 정의된 tfstate 파일에 저장됩니다. 예를 들어 프로젝트에서 GKE 클러스터를 만들려면 프로젝트 ID를 알아야 합니다. 프로젝트 ID는 output.tf를 통해 GKE 클러스터 리소스의 terraform_remote_state
데이터 소스를 통해 사용할 수 있는 tfstate 파일로 출력됩니다.
shared_state 파일은 리소스의 tfstate 파일을 가리키는 terraform_remote_state
데이터 소스입니다. shared_state_[resource_name].tf
파일은 다른 리소스의 출력이 필요한 리소스 폴더에 있습니다. 예를 들어 ops_gke
리소스 폴더에는 ops_project
및 shared_vpc
리소스의 shared_state 파일이 있습니다. 운영 프로젝트에서 GKE 클러스터를 만들려면 프로젝트 ID와 VPC 세부정보가 필요하기 때문입니다. shared_state 파일은 스크립트 (scripts/setup_terraform_admin_project
에 있음)를 사용하여 템플릿 (templates/shared_state.tf_tmpl
에 위치)에서 생성됩니다. 모든 리소스 shared_state 파일은 gcp/[environment]/shared_states
폴더에 배치됩니다. 필수 shared_state 파일이 각 리소스 폴더에 심볼릭 링크로 연결됩니다. 모든 shared_state 파일을 하나의 폴더에 배치하고 적절한 리소스 폴더에 심볼릭 링크로 연결하여 모든 상태 파일을 한곳에서 쉽게 관리할 수 있습니다.
변수
모든 리소스 값은 환경 변수로 저장됩니다. 이러한 변수는 terraform 관리자 프로젝트의 GCS 버킷에 있는 vars.sh
라는 파일에 내보내기 문으로 저장됩니다. 여기에는 조직 ID, 결제 계정, 프로젝트 ID, GKE 클러스터 세부정보 등이 포함됩니다. 모든 터미널에서 vars.sh
를 다운로드하고 소싱하여 설정에 필요한 값을 가져올 수 있습니다.
Terraform 변수는 vars.sh
에 TF_VAR_[variable name]
로 저장됩니다. 이러한 변수는 각 리소스 폴더에 variables.tfvars
파일을 생성하는 데 사용됩니다. variables.tfvars
파일에는 값이 있는 모든 변수가 포함되어 있습니다. variables.tfvars
파일은 스크립트를 사용하여 동일한 폴더의 템플릿 파일에서 생성됩니다 (scripts/setup_terraform_admin_project
에 있음).
K8s Repo 설명
k8s_repo
은 Terraform 관리자 프로젝트에 있는 CSR 저장소 (인프라 저장소와 별개)입니다. GKE 매니페스트를 저장하고 모든 GKE 클러스터에 적용하는 데 사용됩니다. k8s_repo
는 인프라 Cloud Build에서 생성됩니다 (자세한 내용은 이전 섹션 참고). Cloud Build의 초기 인프라 프로세스 중에 총 6개의 GKE 클러스터가 생성됩니다. k8s_repo
에 폴더 6개가 생성됩니다. 각 폴더 (GKE 클러스터 이름과 일치하는 이름)는 해당 리소스 매니페스트 파일이 포함된 GKE 클러스터에 해당합니다. 인프라 빌드와 마찬가지로 Cloud Build는 k8s_repo를 사용하여 모든 GKE 클러스터에 Kubernetes 매니페스트를 적용하는 데 사용됩니다. Cloud Build는 k8s_repo
저장소에 대한 커밋이 있을 때마다 트리거됩니다. 인프라와 마찬가지로 모든 Kubernetes 매니페스트는 k8s_repo
저장소에 코드로 저장되고 각 GKE 클러스터의 상태는 항상 각 폴더에 저장됩니다.
초기 인프라 빌드의 일부로 k8s_repo
가 생성되고 Istio가 모든 클러스터에 설치됩니다.
프로젝트, GKE 클러스터, 네임스페이스
이 워크숍의 리소스는 여러 GCP 프로젝트로 나뉩니다. 프로젝트는 회사의 조직 (또는 팀) 구조와 일치해야 합니다. 조직에서 다양한 프로젝트/제품/리소스를 담당하는 팀은 서로 다른 GCP 프로젝트를 사용합니다. 별도의 프로젝트가 있으면 별도의 IAM 권한 집합을 만들고 프로젝트 수준에서 결제를 관리할 수 있습니다. 또한 할당량은 프로젝트 수준에서도 관리됩니다.
이 워크샵에는 5개의 팀이 참가하여 각 팀의 프로젝트를 진행합니다.
- GCP 리소스를 빌드하는 인프라팀은
Terraform admin project
를 사용합니다. CSR 저장소 (infrastructure
이라고 함)에서 코드형 인프라를 관리하고 GCP에서 빌드된 리소스와 관련된 모든 Terraform 상태 정보를 GCS 버킷에 저장합니다. CSR 저장소 및 Terraform 상태 GCS 버킷에 대한 액세스를 제어합니다. - 공유 VPC를 빌드하는 네트워크팀은
host project
를 사용합니다. 이 프로젝트에는 VPC, 서브넷, 경로, 방화벽 규칙이 포함됩니다. 공유 VPC를 사용하면 GCP 리소스의 네트워킹을 중앙에서 관리할 수 있습니다. 모든 프로젝트에서 이 단일 공유 VPC를 네트워킹에 사용했습니다. - GKE 클러스터와 ASM/Istio 제어 영역을 빌드하는 운영/플랫폼팀은
ops project
를 사용합니다. GKE 클러스터 및 서비스 메시의 수명 주기를 관리합니다. 클러스터를 강화하고 Kubernetes 플랫폼의 복원력과 규모를 관리합니다. 이 워크숍에서는 Kubernetes에 리소스를 배포하는 gitops 방법을 사용합니다. CSR 저장소 (k8s_repo
라고 함)는 운영 프로젝트에 있습니다. - 마지막으로, 애플리케이션을 빌드하는 dev1 및 dev2 팀 (두 개발팀을 나타냄)은 자체
dev1
및dev2 projects
를 사용합니다. 고객이 고객에게 제공하는 애플리케이션 및 서비스입니다. 운영팀이 관리하는 플랫폼에 구축됩니다. 리소스 (배포, 서비스 등)가k8s_repo
로 푸시되고 적절한 클러스터에 배포됩니다. 이번 워크숍은 CI/CD 권장사항과 도구에 중점을 두지 않는다는 점에 유의해야 합니다. Cloud Build를 사용하여 Kubernetes 리소스를 GKE 클러스터에 직접 배포하는 작업을 자동화할 수 있습니다. 실제 프로덕션 시나리오에서는 적절한 CI/CD 솔루션을 사용하여 애플리케이션을 GKE 클러스터에 배포합니다.
이 워크숍에서는 두 가지 유형의 GKE 클러스터가 나와 있습니다.
- 운영 클러스터 - 운영팀이 DevOps 도구를 실행하는 데 사용합니다. 이 워크숍에서는 ASM/Istio 제어 영역을 실행하여 서비스 메시를 관리합니다.
- 애플리케이션 (앱) 클러스터 - 개발팀에서 애플리케이션을 실행하기 위해 사용합니다. 이 워크숍에서는 Hitster Shop 앱을 사용합니다.
애플리케이션을 실행하는 클러스터에서 운영/관리자 도구를 분리하면 각 리소스의 수명 주기를 독립적으로 관리할 수 있습니다. 두 유형의 클러스터는 두 유형의 클러스터를 사용하는 팀/제품과 관련된 여러 프로젝트에도 존재하므로 IAM 권한도 더 쉽게 관리할 수 있습니다.
GKE 클러스터는 총 6개입니다. 운영 프로젝트에 리전 작업 클러스터 2개가 생성됩니다. ASM/Istio 제어 영역은 두 작업 클러스터에 모두 설치됩니다. 각 작업 클러스터가 다른 리전에 있습니다. 또한 4개의 영역별 애플리케이션 클러스터가 있습니다. 자체 프로젝트에서 생성됩니다. 이 워크숍에서는 각 개발팀별로 각자의 프로젝트를 시뮬레이션합니다. 각 프로젝트에는 앱 클러스터 2개가 포함됩니다. 앱 클러스터는 여러 영역에 있는 영역 클러스터입니다. 4개의 앱 클러스터는 2개의 리전과 4개의 영역에 위치합니다. 이렇게 하면 리전 및 영역 중복성을 확보할 수 있습니다.
이 워크숍에서 사용된 애플리케이션인 Hipster Shop 앱은 4개의 앱 클러스터 모두에 배포됩니다. 각 마이크로서비스는 모든 앱 클러스터의 자체 네임스페이스에 있습니다. 힙스터 샵 앱 배포 (포드)는 운영 클러스터에 배포되지 않습니다. 그러나 모든 마이크로서비스의 네임스페이스와 서비스 리소스도 운영 클러스터에 생성됩니다. ASM/Istio 제어 영역은 Kubernetes 서비스 레지스트리를 서비스 검색에 사용합니다. 운영 클러스터에 서비스가 없는 경우 앱 클러스터에서 실행되는 각 서비스에 대해 수동으로 ServiceEntry를 만들어야 합니다.
이 워크숍에서는 10계층 마이크로서비스 애플리케이션을 배포합니다. 애플리케이션은 ' Hipster Shop" 여기에서 사용자가 상품을 둘러보고, 장바구니에 추가하고, 구매할 수 있습니다.
Kubernetes 매니페스트 및 k8s_repo
k8s_repo
를 사용하여 모든 GKE 클러스터에 Kubernetes 리소스를 추가합니다. 이렇게 하려면 Kubernetes 매니페스트를 복사하고 k8s_repo
에 커밋합니다. k8s_repo
에 대한 모든 커밋은 각 클러스터에 Kubernetes 매니페스트를 배포하는 Cloud Build 작업을 트리거합니다. 각 클러스터의 매니페스트는 클러스터 이름과 동일한 이름의 별도의 폴더에 있습니다.
6가지 클러스터 이름은 다음과 같습니다.
- gke-asm-1-r1-prod - 리전 1의 리전별 작업 클러스터
- gke-asm-2-r2-prod - 리전 2의 리전별 작업 클러스터
- gke-1-apps-r1a-prod - 리전 1 영역 a에 있는 앱 클러스터
- gke-2-apps-r1b-prod - 리전 1 영역 b의 앱 클러스터
- gke-3-apps-r2a-prod - 리전 2 영역 a에 있는 앱 클러스터
- gke-4-apps-r2b-prod - 리전 2 영역 b의 앱 클러스터
k8s_repo
에 이 클러스터에 해당하는 폴더가 있습니다. 이러한 폴더에 배치된 모든 매니페스트는 해당 GKE 클러스터에 적용됩니다. 각 클러스터의 매니페스트는 관리를 용이하게 하기 위해 클러스터의 기본 폴더 내의 하위 폴더에 배치됩니다. 이 워크숍에서는 Kustomize를 사용하여 배포되는 리소스를 추적합니다. 자세한 내용은 Kustomize 공식 문서를 참조하세요.
7. 샘플 앱 배포
목표: 앱 클러스터에 Hotster Shop 앱 배포
k8s-repo
복사- 모든 앱 클러스터에 힙스터 샵 매니페스트 복사
- 운영 클러스터에서 힙스터 쇼핑 앱 서비스 만들기
- 운영 클러스터에
loadgenerators
를 설정하여 전역 연결 테스트 - Hipster Shop 앱에 대한 보안 연결 확인
복사하여 붙여넣기 방법 실습 안내
운영 프로젝트 소스 저장소 클론
초기 Terraform 인프라 빌드의 일부로 k8s-repo
는 이미 운영 프로젝트에 생성되었습니다.
- git 저장소용 빈 디렉터리를 만듭니다.
mkdir $WORKDIR/k8s-repo
- git 저장소를 초기화하고 원격 저장소를 추가하고 원격 저장소에서 마스터를 가져옵니다.
cd $WORKDIR/k8s-repo
git init && git remote add origin \
https://source.developers.google.com/p/$TF_VAR_ops_project_name/r/k8s-repo
- 로컬 Git 로컬 구성을 설정합니다.
git config --local user.email $MY_USER
git config --local user.name "K8s repo user"
git config --local \
credential.'https://source.developers.google.com'.helper gcloud.sh
git pull origin master
매니페스트 복사, 커밋, 푸시
- Hipster Shop 네임스페이스 및 서비스를 모든 클러스터의 소스 저장소에 복사합니다.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/.
- 앱 폴더 kustomization.yaml을 모든 클러스터에 복사합니다.
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/
- 힙스터 샵 배포, RBAC, PodSecurityPolicy를 앱 클러스터의 소스 저장소에 복사합니다.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
- 하나의 dev 클러스터를 제외한 모든 클러스터에서 carservice 배포, rbac, podsecuritypolicy를 삭제합니다. Hitstershop은 멀티 클러스터 배포용으로 빌드되지 않았기 때문에 일관성 없는 결과를 방지하기 위해 장바구니 서비스를 하나만 사용합니다.
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/rbac/cart-rbac.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/rbac/cart-rbac.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/rbac/cart-rbac.yaml
- 첫 번째 dev 클러스터의 경우에만 kustomization.yaml에 carservice 배포, rbac, podsecuritypolicy를 추가하세요.
cd ${WORKDIR}/k8s-repo/${DEV1_GKE_1_CLUSTER}/app
cd deployments && kustomize edit add resource app-cart-service.yaml
cd ../podsecuritypolicies && kustomize edit add resource cart-psp.yaml
cd ../rbac && kustomize edit add resource cart-rbac.yaml
cd ${WORKDIR}/asm
- 운영 클러스터 kustomization.yaml에서 podsecuritypolicies, 배포, rbac 디렉터리 삭제
sed -i -e '/- deployments\//d' -e '/- podsecuritypolicies\//d' \
-e '/- rbac\//d' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/kustomization.yaml
sed -i -e '/- deployments\//d' -e '/- podsecuritypolicies\//d' \
-e '/- rbac\//d' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/kustomization.yaml
- RBAC 매니페스트에서 PROJECT_ID를 바꿉니다.
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev1_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV1_GKE_1_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev1_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV1_GKE_2_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev2_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV2_GKE_1_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev2_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV2_GKE_2_CLUSTER}/app/rbac/*
- 인그레스Gateway 및 VirtualService 매니페스트를 운영 클러스터의 소스 저장소에 복사합니다.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-ingress/* \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-ingress/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-ingress/* \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-ingress/
- 구성 커넥터 리소스를 각 프로젝트의 클러스터 중 하나에 복사합니다.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-cnrm/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app-cnrm/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app-cnrm/
- 구성 커넥터 매니페스트에서 PROJECT_ID를 바꿉니다.
sed -i 's/${PROJECT_ID}/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-cnrm/*
sed -i 's/${PROJECT_ID}/'$TF_VAR_dev1_project_name'/g' \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app-cnrm/*
sed -i 's/${PROJECT_ID}/'$TF_VAR_dev2_project_name'/g' \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app-cnrm/*
loadgenerator
매니페스트 (배포, PodSecurityPolicy, RBAC)를 작업 클러스터에 복사합니다. 트렌디한 쇼핑 앱이 글로벌 Google Cloud 부하 분산기 (GCLB)를 사용하여 노출되어 있습니다. GCLB는 클라이언트 트래픽 (frontend
로 향함)을 수신하여 가장 가까운 서비스 인스턴스로 전송합니다. 두 작업 클러스터에loadgenerator
를 배치하면 운영 클러스터에서 실행되는 두 Istio 인그레스 게이트웨이로 트래픽이 전송됩니다. 부하 분산은 다음 섹션에서 자세히 설명합니다.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-loadgenerator/. \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-loadgenerator/. \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/.
- 두 작업 클러스터의
loadgenerator
매니페스트에서 작업 프로젝트 ID를 바꿉니다.
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/loadgenerator-deployment.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/loadgenerator-rbac.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/loadgenerator-deployment.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/loadgenerator-rbac.yaml
- 두 작업 클러스터의 kustomization.yaml에
loadgenerator
리소스를 추가합니다.
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/
kustomize edit add resource loadgenerator-psp.yaml
kustomize edit add resource loadgenerator-rbac.yaml
kustomize edit add resource loadgenerator-deployment.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/
kustomize edit add resource loadgenerator-psp.yaml
kustomize edit add resource loadgenerator-rbac.yaml
kustomize edit add resource loadgenerator-deployment.yaml
k8s-repo
에 커밋합니다.
cd $WORKDIR/k8s-repo
git add . && git commit -am "create app namespaces and install hipster shop"
git push --set-upstream origin master
- 이전에 연 탭에서 또는 다음 링크를 클릭하여 운영 프로젝트 Cloud Build의 상태를 확인합니다.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
애플리케이션 배포 확인
- 장바구니를 제외한 모든 애플리케이션 네임스페이스의 포드가 모든 개발 클러스터에서 실행 중 상태인지 확인합니다.
for ns in ad checkout currency email frontend payment product-catalog recommendation shipping; do
kubectl --context $DEV1_GKE_1 get pods -n $ns;
kubectl --context $DEV1_GKE_2 get pods -n $ns;
kubectl --context $DEV2_GKE_1 get pods -n $ns;
kubectl --context $DEV2_GKE_2 get pods -n $ns;
done;
Output (do not copy)
NAME READY STATUS RESTARTS AGE currencyservice-5c5b8876db-pvc6s 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE currencyservice-5c5b8876db-xlkl9 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE currencyservice-5c5b8876db-zdjkg 2/2 Running 0 115s NAME READY STATUS RESTARTS AGE currencyservice-5c5b8876db-l748q 2/2 Running 0 82s NAME READY STATUS RESTARTS AGE emailservice-588467b8c8-gk92n 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE emailservice-588467b8c8-rvzk9 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE emailservice-588467b8c8-mt925 2/2 Running 0 117s NAME READY STATUS RESTARTS AGE emailservice-588467b8c8-klqn7 2/2 Running 0 84s NAME READY STATUS RESTARTS AGE frontend-64b94cf46f-kkq7d 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE frontend-64b94cf46f-lwskf 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE frontend-64b94cf46f-zz7xs 2/2 Running 0 118s NAME READY STATUS RESTARTS AGE frontend-64b94cf46f-2vtw5 2/2 Running 0 85s NAME READY STATUS RESTARTS AGE paymentservice-777f6c74f8-df8ml 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE paymentservice-777f6c74f8-bdcvg 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE paymentservice-777f6c74f8-jqf28 2/2 Running 0 117s NAME READY STATUS RESTARTS AGE paymentservice-777f6c74f8-95x2m 2/2 Running 0 86s NAME READY STATUS RESTARTS AGE productcatalogservice-786dc84f84-q5g9p 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE productcatalogservice-786dc84f84-n6lp8 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE productcatalogservice-786dc84f84-gf9xl 2/2 Running 0 119s NAME READY STATUS RESTARTS AGE productcatalogservice-786dc84f84-v7cbr 2/2 Running 0 86s NAME READY STATUS RESTARTS AGE recommendationservice-5fdf959f6b-2ltrk 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE recommendationservice-5fdf959f6b-dqd55 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE recommendationservice-5fdf959f6b-jghcl 2/2 Running 0 119s NAME READY STATUS RESTARTS AGE recommendationservice-5fdf959f6b-kkspz 2/2 Running 0 87s NAME READY STATUS RESTARTS AGE shippingservice-7bd5f569d-qqd9n 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE shippingservice-7bd5f569d-xczg5 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE shippingservice-7bd5f569d-wfgfr 2/2 Running 0 2m NAME READY STATUS RESTARTS AGE shippingservice-7bd5f569d-r6t8v 2/2 Running 0 88s
- 첫 번째 개발 클러스터에서만 장바구니 네임스페이스의 포드가 실행 중 상태인지 확인합니다.
kubectl --context $DEV1_GKE_1 get pods -n cart;
Output (do not copy)
NAME READY STATUS RESTARTS AGE cartservice-659c9749b4-vqnrd 2/2 Running 0 17m
Hipster Shop 앱에 액세스
글로벌 부하 분산
이제 Hitster Shop 앱이 4개의 앱 클러스터 모두에 배포되었습니다. 이러한 클러스터는 2개의 리전과 4개의 영역에 있습니다. 클라이언트는 frontend
서비스에 액세스하여 Hipster Shop 앱에 액세스할 수 있습니다. frontend
서비스는 4개의 앱 클러스터 모두에서 실행됩니다. Google Cloud 부하 분산기 ( GCLB)는 클라이언트 트래픽을 frontend
서비스의 인스턴스 4개 모두로 가져오는 데 사용됩니다.
Istio 인그레스 게이트웨이는 운영 클러스터에서만 실행되며 리전 내 두 영역 애플리케이션 클러스터에 대한 리전 부하 분산기 역할을 합니다. GCLB는 전역 프런트엔드 서비스에 대한 백엔드로 2개의 Istio 인그레스 게이트웨이 (2개 작업 클러스터에서 실행)를 사용합니다. Istio 인그레스 게이트웨이는 GCLB에서 클라이언트 트래픽을 수신한 후 애플리케이션 클러스터에서 실행되는 프런트엔드 포드로 클라이언트 트래픽을 전송합니다.
또는 Istio 인그레스 게이트웨이를 애플리케이션 클러스터에 직접 배치할 수 있으며 GCLB에서 이를 백엔드로 사용할 수 있습니다.
GKE Autoneg 컨트롤러
Istio 인그레스 게이트웨이 Kubernetes 서비스는 네트워크 엔드포인트 그룹 (NEG)을 사용하여 자체적으로 GCLB에 백엔드로 등록합니다. NEG는 GCLB를 사용한 컨테이너 기반 부하 분산을 허용합니다. NEG는 Kubernetes 서비스에서 특수한 주석을 통해 생성되므로 NEG 컨트롤러에 자체적으로 등록할 수 있습니다. Autoneg 컨트롤러는 NEG 생성을 자동화하고 서비스 주석을 사용하여 GCLB에 백엔드로 할당하는 작업을 자동화하는 특수 GKE 컨트롤러입니다. Istio 인그레스 게이트웨이를 포함한 Istio 제어 영역은 초기 인프라 Terraform Cloud Build 중에 배포됩니다. GCLB 및 autoneg 구성은 초기 Terraform 인프라 Cloud Build의 일부로 수행됩니다.
Cloud Endpoints 및 관리형 인증서를 사용하여 인그레스 보호
GCP 관리형 인증서는 frontend
GCLB 서비스로의 클라이언트 트래픽을 보호하는 데 사용됩니다. GCLB는 전역 frontend
서비스에 관리형 인증서를 사용하며 인증서는 GCLB에서 종료됩니다. 이 워크숍에서는 관리형 인증서의 도메인으로 Cloud Endpoints를 사용합니다. 또는 frontend
의 도메인과 DNS 이름을 사용하여 GCP 관리형 인증서를 만들 수 있습니다.
- 트렌디한 상점에 액세스하려면 다음 명령어의 링크 출력을 클릭하세요.
echo "https://frontend.endpoints.$TF_VAR_ops_project_name.cloud.goog"
- Chrome 탭의 URL 표시줄에 있는 자물쇠 기호를 클릭하여 인증서가 유효한지 확인할 수 있습니다.
전역 부하 분산 확인
애플리케이션 배포의 일부로 부하 생성기가 GCLB Hitster 쇼핑 Cloud Endpoints 링크에 대한 테스트 트래픽을 생성하는 두 작업 클러스터에 배포되었습니다. GCLB에서 트래픽을 수신하고 두 Istio 인그레스 게이트웨이 모두로 전송하고 있는지 확인합니다.
- GCLB > Hotster Shop GCLB가 생성된 운영 프로젝트의 Monitoring(모니터링) 링크
echo "https://console.cloud.google.com/net-services/loadbalancing/details/http/istio-ingressgateway?project=$TF_VAR_ops_project_name&cloudshell=false&tab=monitoring&duration=PT1H"
- 아래와 같이 백엔드 드롭다운 메뉴에서 모든 백엔드를 istio-ingressgateway로 변경합니다.
- 두
istio-ingressgateways
모두로 이동하는 트래픽을 확인합니다.
istio-ingressgateway
당 3개의 NEG가 생성됩니다. 작업 클러스터는 리전 클러스터이므로 리전의 영역마다 NEG가 하나씩 생성됩니다. 그러나 istio-ingressgateway
Pod는 리전별로 단일 영역에서 실행됩니다. 트래픽은 istio-ingressgateway
Pod로 이동합니다.
부하 생성기가 두 운영 클러스터에서 실행되어 현재 위치한 두 리전의 클라이언트 트래픽을 시뮬레이션합니다. 운영 클러스터 리전 1에서 생성된 부하가 리전 2의 istio-ingressgateway
로 전송됩니다. 마찬가지로 운영 클러스터 리전 2에서 생성된 부하는 리전 2의 istio-ingressgateway
로 전송됩니다.
8. Stackdriver를 사용한 관측 가능성
목표: Istio 원격 분석을 Stackdriver에 연결하고 검증합니다.
- 리소스
istio-telemetry
개 설치 - Istio 서비스 대시보드 만들기/업데이트
- 컨테이너 로그 보기
- Stackdriver에서 분산 추적 보기
복사하여 붙여넣기 방법 실습 안내
Istio의 주요 기능 중 하나는 기본 제공되는 관측 가능성('o11y')입니다. 즉, 계측되지 않은 블랙박스 컨테이너를 사용하는 경우에도 운영자는 이러한 컨테이너에서 드나드는 트래픽을 관찰하여 고객에게 서비스를 제공할 수 있습니다. 이 관찰은 측정항목, 로그, trace 등 몇 가지 방법의 형태를 취합니다.
또한 Hitster Shop에 내장된 부하 생성 시스템도 활용할 것입니다. 트래픽이 없는 정적 시스템에서는 관측 가능성이 제대로 작동하지 않으므로 부하 생성은 작동 방식을 확인하는 데 도움이 됩니다. 이 로드는 이미 실행 중이며 이제 확인할 수 있습니다.
- Stackdriver 구성 파일에 istio를 설치합니다.
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-telemetry
kustomize edit add resource istio-telemetry.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-telemetry
kustomize edit add resource istio-telemetry.yaml
- k8s-repo에 커밋합니다.
cd $WORKDIR/k8s-repo
git add . && git commit -am "Install istio to stackdriver configuration"
git push
- 이전에 연 탭에서 또는 다음 링크를 클릭하여 운영 프로젝트 Cloud Build의 상태를 확인합니다.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
- Istio 확인 → Stackdriver 통합 Stackdriver Handler CRD를 가져옵니다.
kubectl --context $OPS_GKE_1 get handler -n istio-system
출력에 stackdriver라는 핸들러가 표시됩니다.
NAME AGE kubernetesenv 12d prometheus 12d stackdriver 69s # <== NEW!
- Stackdriver로 Istio 측정항목 내보내기가 작동하는지 확인합니다. 다음 명령어의 링크 출력을 클릭합니다.
echo "https://console.cloud.google.com/monitoring/metrics-explorer?cloudshell=false&project=$TF_VAR_ops_project_name"
운영 프로젝트의 이름을 딴 새 작업공간을 만들라는 메시지가 표시되면 확인을 선택합니다. 새 UI에 관한 메시지가 표시되면 대화상자를 닫으면 됩니다.
측정항목 탐색기의 '리소스 유형 및 측정항목 찾기' 'istio
' 입력 '서버 요청 수'와 같은 옵션이 있습니다. 'Kubernetes 컨테이너' 리소스 유형입니다. 이는 측정항목이 메시에서 Stackdriver로 이동하는 것을 보여줍니다.
(아래 줄을 보려면 destination_service_name 라벨로 그룹화해야 합니다.)
대시보드로 측정항목 시각화:
이제 측정항목이 Stackdriver APM 시스템에 있으므로 이를 시각화하는 방법을 살펴보겠습니다. 이 섹션에서는 사전 제작된 대시보드를 설치하여 4개의 " Golden Signals"의 약어입니다. 트래픽 (초당 요청 수), 지연 시간 (이 경우 99번째 및 50번째 백분위수), 오류 (이 예에서는 포화도는 제외) 등 측정항목이 표시됩니다.
Istio의 Envoy 프록시는 몇 가지 측정항목을 제공하지만, 이러한 측정항목 집합으로 시작하는 것이 좋습니다. (전체 목록은 여기에서 확인 가능) 각 측정항목에는 destination_service, source_workload_namespace, response_code, istio_tcp_received_bytes_total 등의 필터링, 집계에 사용할 수 있는 라벨 집합이 있습니다.
- 이제 미리 준비된 측정항목 대시보드를 추가해 보겠습니다. Dashboard API를 직접 사용할 것입니다. 이는 일반적으로 API 호출을 직접 생성하는 방식으로 하지 않거나, 자동화 시스템의 일부이거나, 웹 UI에서 수동으로 대시보드를 빌드하는 것입니다. 다음과 같이 빠르게 시작할 수 있습니다.
sed -i 's/OPS_PROJECT/'${TF_VAR_ops_project_name}'/g' \
$WORKDIR/asm/k8s_manifests/prod/app-telemetry/services-dashboard.json
OAUTH_TOKEN=$(gcloud auth application-default print-access-token)
curl -X POST -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards \
-d @$WORKDIR/asm/k8s_manifests/prod/app-telemetry/services-dashboard.json
- 아래 출력 링크로 이동하여 새로 추가된 '서비스 대시보드'를 확인합니다.
echo "https://console.cloud.google.com/monitoring/dashboards/custom/servicesdash?cloudshell=false&project=$TF_VAR_ops_project_name"
UX를 사용하여 그 자리에서 대시보드를 편집할 수 있지만 여기서는 API를 사용하여 새 그래프를 빠르게 추가해 보겠습니다. 그렇게 하려면 대시보드의 최신 버전을 풀다운하여 수정 사항을 적용한 다음 HTTP PATCH 메서드를 사용하여 다시 푸시해야 합니다.
- Monitoring API를 쿼리하여 기존 대시보드를 가져올 수 있습니다. 방금 추가된 기존 대시보드를 가져옵니다.
curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards/servicesdash > /tmp/services-dashboard.json
- 새 그래프 추가: (50번째 백분위수 지연 시간): [ API 참조] 이제 코드의 대시보드에 새 그래프 위젯을 추가할 수 있습니다. 이 변경사항은 동료가 검토하고 버전 제어에 체크인할 수 있습니다. 다음은 50번째 백분위수 지연 시간 (지연 시간 중앙값)을 보여주는 위젯입니다.
방금 가져온 대시보드를 수정하고 새 스탠자를 추가해 보세요.
NEW_CHART=${WORKDIR}/asm/k8s_manifests/prod/app-telemetry/new-chart.json
jq --argjson newChart "$(<$NEW_CHART)" '.gridLayout.widgets += [$newChart]' /tmp/services-dashboard.json > /tmp/patched-services-dashboard.json
- 기존 서비스 대시보드를 업데이트합니다.
curl -X PATCH -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards/servicesdash \
-d @/tmp/patched-services-dashboard.json
- 다음 출력 링크로 이동하여 업데이트된 대시보드를 확인합니다.
echo "https://console.cloud.google.com/monitoring/dashboards/custom/servicesdash?cloudshell=false&project=$TF_VAR_ops_project_name"
- 간단한 로그 분석을 수행합니다.
Istio는 모든 인-메시 네트워크 트래픽의 구조화된 로그 집합을 제공하고 이를 Stackdriver Logging에 업로드하여 강력한 단일 도구로 교차 클러스터 분석을 지원합니다. 로그는 클러스터, 컨테이너, 앱, connection_id 등의 서비스 수준 메타데이터로 주석 처리됩니다.
로그 항목의 예 (이 경우 Envoy 프록시의 액세스 로그)는 다음과 같을 수 있습니다 (잘림).
*** DO NOT PASTE ***
logName: "projects/PROJECTNAME-11932-01-ops/logs/server-tcp-accesslog-stackdriver.instance.istio-system"
labels: {
connection_id: "fbb46826-96fd-476c-ac98-68a9bd6e585d-1517191"
destination_app: "redis-cart"
destination_ip: "10.16.1.7"
destination_name: "redis-cart-6448dcbdcc-cj52v"
destination_namespace: "cart"
destination_owner: "kubernetes://apis/apps/v1/namespaces/cart/deployments/redis-cart"
destination_workload: "redis-cart"
source_ip: "10.16.2.8"
total_received_bytes: "539"
total_sent_bytes: "569"
...
}
여기에서 로그를 확인하세요.
echo "https://console.cloud.google.com/logs/viewer?cloudshell=false&project=$TF_VAR_ops_project_name"
리소스 >를 선택하여 Istio의 제어 영역 로그를 볼 수 있습니다. Kubernetes 컨테이너, '파일럿' 검색 -
여기서 각 샘플 앱 서비스의 사이드카 프록시로 프록시 구성을 푸시하는 Istio 제어 영역을 볼 수 있습니다. "CDS", 'LDS' 및 'RDS' 다양한 Envoy API를 나타냅니다 ( 자세히 알아보기).
Istio의 로그 외에도 컨테이너 로그와 인프라 또는 기타 GCP 서비스 로그를 모두 동일한 인터페이스에서 찾을 수 있습니다. 다음은 GKE용 몇 가지 샘플 로그 쿼리입니다. 또한 로그 뷰어를 사용하면 로그에서 측정항목 (예: '일부 문자열과 일치하는 모든 오류 집계')을 만들어 대시보드에서 또는 알림의 일부로 사용할 수 있습니다. 로그는 BigQuery와 같은 다른 분석 도구로 스트리밍할 수도 있습니다.
트렌디한 매장용 샘플 필터:
resource.type="k8s_container" labels.destination_app="productcatalogservice"
resource.type="k8s_container" resource.labels.namespace_name="cart"
- 분산 트레이스를 확인해 보세요.
이제 분산 시스템에서 작업하고 있으므로 디버깅에 분산 추적이라는 새로운 도구가 필요합니다. 이 도구를 사용하면 서비스가 상호작용하는 방식에 대한 통계를 검색하고 (예: 아래 그림에서 느린 이벤트 찾기) 원시 샘플 트레이스를 살펴보고 실제 상황의 세부정보를 조사할 수 있습니다.
타임라인 뷰에는 최종적으로 최종 사용자에게 응답하기 위해 시간 경과에 따른 모든 요청을 지연 시간 또는 초기 요청 사이에 소요된 시간에 따른 그래프로 표시합니다. 점이 높을수록 사용자 환경이 느려지고 만족도가 낮아집니다.
점을 클릭하면 해당 요청의 자세한 폭포식 구조 뷰를 확인할 수 있습니다. 집계 통계만이 아닌 특정 요청의 원시 세부정보를 찾는 이 기능은 특히 서비스 간의 드물지만 나쁜 상호작용을 추적할 때 서비스 간의 상호작용을 이해하는 데 매우 중요합니다.
워터폴 뷰는 디버거를 사용해 본 모든 사용자에게 익숙할 것입니다. 하지만 이 경우에는 단일 애플리케이션의 여러 프로세스에서 소비한 시간을 표시하는 대신 서비스 간 메시를 순회하고 별도의 컨테이너에서 실행하는 데 소요된 시간을 보여줍니다.
여기에서 Trace를 확인할 수 있습니다.
echo "https://console.cloud.google.com/traces/overview?cloudshell=false&project=$TF_VAR_ops_project_name"
이 도구의 스크린샷 예는 다음과 같습니다.
9. 상호 TLS 인증
목표: 마이크로서비스 (AuthN) 간의 연결 보호
- 메시 와이드 mTLS 사용 설정
- 로그를 검사하여 mTLS 확인
복사하여 붙여넣기 방법 실습 안내
이제 앱이 설치되고 관측 가능성이 설정되었으므로 서비스 간 연결을 보호하고 계속 작동하는지 확인할 수 있습니다.
예를 들어 Kiali 대시보드에서 우리 서비스가 MTLS('자물쇠' 아이콘 없음)를 사용하지 않는 것을 확인할 수 있습니다. 하지만 교통 흐름이 원활하고 시스템은 잘 작동하고 있습니다. Stackdriver 골든 측정항목 대시보드 덕분에 전체적으로 아무런 문제도 일어나지 않고 있습니다.
- 운영 클러스터에서 MeshPolicy를 확인하세요. mTLS는
PERMISSIVE
이며 암호화된 트래픽과 mTLS가 아닌 트래픽을 모두 허용합니다.
kubectl --context $OPS_GKE_1 get MeshPolicy -o json | jq '.items[].spec'
kubectl --context $OPS_GKE_2 get MeshPolicy -o json | jq '.items[].spec'
`Output (do not copy)`
{
"peers": [
{
"mtls": {
"mode": "PERMISSIVE"
}
}
]
}
Istio는 IstioControlPlane 커스텀 리소스 (CR)를 사용하는 Istio 연산자를 사용하여 모든 클러스터에서 구성됩니다. IstioControlPlane CR을 업데이트하고 k8s-repo를 업데이트하여 모든 클러스터에서 mTLS를 구성합니다. 전역 설정 > mTLS> enabled: IstioControlPlane CR에서 true이면 Istio 제어 영역이 다음과 같이 두 가지 변경됩니다.
- 모든 클러스터에서 실행되는 모든 서비스에 대해 mTLS 메시를 사용 설정하도록 MeshPolicy가 설정되었습니다.
- 모든 클러스터에서 실행되는 서비스 간에 ISTIO_MUTUAL 트래픽을 허용하도록 DestinationRule이 생성됩니다.
- mTLS 클러스터 전체에서 mTLS를 사용 설정하기 위해 istioControlPlane CR에 kustomize 패치를 적용합니다. 모든 클러스터의 관련 디렉터리에 패치를 복사하고 kustomize 패치를 추가합니다.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-replicated.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-replicated.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
- k8s-repo에 커밋합니다.
cd $WORKDIR/k8s-repo
git add . && git commit -am "turn mTLS on"
git push
- 이전에 연 탭에서 또는 다음 링크를 클릭하여 운영 프로젝트 Cloud Build의 상태를 확인합니다.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
mTLS 확인
- 운영 클러스터에서 MeshPolicy를 한 번 더 확인합니다. mTLS는 더 이상
PERMISSIVE
가 아니며 mTLS 트래픽만 허용합니다.
kubectl --context $OPS_GKE_1 get MeshPolicy -o json | jq .items[].spec
kubectl --context $OPS_GKE_2 get MeshPolicy -o json | jq .items[].spec
출력(복사 금지):
{ "peers": [ { "mtls": {} } ] }
- Istio 연산자 컨트롤러에서 만든 DestinationRule을 설명합니다.
kubectl --context $OPS_GKE_1 get DestinationRule default -n istio-system -o json | jq '.spec'
kubectl --context $OPS_GKE_2 get DestinationRule default -n istio-system -o json | jq '.spec'
출력(복사 금지):
{ host: '*.local', trafficPolicy: { tls: { mode: ISTIO_MUTUAL } } }
또한 로그에서 HTTP에서 HTTPS로 이동한 것을 확인할 수 있습니다.
로그 항목 하나를 클릭한 다음 표시하려는 필드의 값(여기서는 'http'를 클릭)을 클릭하여 UI의 로그에서 이 특정 필드를 노출할 수 있습니다. '프로토콜:
이렇게 하면 변경을 시각화할 수 있습니다.
10. 카나리아 배포
목표: 프런트엔드 서비스의 새 버전을 출시합니다.
- 1개 리전에서
frontend-v2
(다음 프로덕션 버전) 서비스 출시 DestinationRules
및VirtualServices
을(를) 사용하여 트래픽을frontend-v2
(으)로 천천히 유도k8s-repo
에 대한 일련의 커밋을 검사하여 GitOps 배포 파이프라인을 확인합니다.
복사하여 붙여넣기 방법 실습 안내
카나리아 배포는 새로운 서비스의 점진적 출시입니다. 카나리아 배포에서는 점점 더 많은 양의 트래픽을 새 버전으로 보내고 나머지 비율은 현재 버전에 계속 전송합니다. 일반적인 패턴은 트래픽 분할의 각 단계에서 카나리아 분석을 수행하고 '골든 신호'와 지연 시간, 오류율, 포화도)를 기준으로 버전을 예측할 수 있습니다 이는 서비스 중단을 방지하고 새로운 'v2'의 안정성을 보장하는 데 도움이 됩니다. 모든 단계에서 사용할 수 있습니다
이 섹션에서는 Cloud Build 및 Istio 트래픽 정책을 사용하여 새 버전의 frontend 서비스에 대한 기본 카나리아 배포를 만드는 방법을 알아봅니다.
먼저 DEV1 리전 (us-west1)에서 Canary 파이프라인을 실행하고 해당 리전의 두 클러스터 모두에 프런트엔드 v2를 출시합니다. 다음으로 DEV2 리전 (us-central)에서 Canary 파이프라인을 실행하고 해당 리전의 두 클러스터 모두에 v2를 배포합니다. 파이프라인을 모든 리전에서 동시에 실행하는 것이 아니라 리전에서 순서대로 실행하면 잘못된 구성이나 v2 앱 자체의 버그로 인한 전역 서비스 중단을 피하는 데 도움이 됩니다.
참고: 두 리전에서 모두 Canary 파이프라인을 수동으로 트리거하지만 프로덕션에서는 레지스트리에 푸시된 새 Docker 이미지 태그를 기반으로 하는 자동 트리거를 사용합니다.
- Cloud Shell에서 일부 환경 변수를 정의하여 나머지 명령어 실행을 간소화합니다.
CANARY_DIR="$WORKDIR/asm/k8s_manifests/prod/app-canary/"
K8S_REPO="$WORKDIR/k8s-repo"
- repo_setup.sh 스크립트를 실행하여 기준 매니페스트를 k8s-repo에 복사합니다.
$CANARY_DIR/repo-setup.sh
다음 매니페스트가 복사됩니다.
- frontend-v2 배포
- frontend-v1 패치('v1' 라벨 및 '/version' 엔드포인트가 있는 이미지 포함)
- respy: HTTP 응답 배포를 출력하며 실시간으로 카나리아 배포를 시각화하는 데 도움이 되는 작은 포드입니다.
- 프런트엔드 Istio DestinationRule - '버전'을 기준으로 프런트엔드 Kubernetes 서비스를 v1과 v2의 두 하위 집합으로 분할합니다. 배포 라벨
- 프런트엔드 Istio VirtualService - 트래픽의 100% 를 프런트엔드 v1로 라우팅합니다. 이는 Kubernetes 서비스의 기본 라운드 로빈 동작을 재정의하여 모든 Dev1 리전 트래픽의 50% 를 즉시 프런트엔드 v2로 전송합니다.
- k8s_repo에 변경사항을 커밋합니다.
cd $K8S_REPO
git add . && git commit -am "frontend canary setup"
git push
- 이전에 연 탭에서 또는 다음 링크를 클릭하여 운영 프로젝트 Cloud Build의 상태를 확인합니다.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
- OPS1 프로젝트의 콘솔에서 Cloud Build로 이동합니다. Cloud Build 파이프라인이 완료될 때까지 기다린 후 두 DEV1 클러스터 모두의 프런트엔드 네임스페이스에서 포드를 가져옵니다. 아래와 같이 표시됩니다.
watch -n 1 kubectl --context $DEV1_GKE_1 get pods -n frontend
Output (do not copy)
NAME READY STATUS RESTARTS AGE frontend-578b5c5db6-h9567 2/2 Running 0 59m frontend-v2-54b74fc75b-fbxhc 2/2 Running 0 2m26s respy-5f4664b5f6-ff22r 2/2 Running 0 2m26s
tmux를 사용해 Cloud Shell 창을 두 개의 창으로 분할해 보겠습니다.
- 하단 창에서는 watch 명령어를 실행하여 프런트엔드 서비스의 HTTP 응답 배포를 관찰합니다.
- 상단 창에서 실제 카나리아 파이프라인 스크립트가 실행됩니다.
- 명령어를 실행하여 Cloud Shell 창을 분할하고 하단 창에서 watch 명령어를 실행합니다.
RESPY_POD=$(kubectl --context $DEV1_GKE_1 get pod \
-n frontend -l app=respy -o jsonpath='{..metadata.name}')
export TMUX_SESSION=$(tmux display-message -p '#S')
tmux split-window -d -t $TMUX_SESSION:0 -p33 \
-v "export KUBECONFIG=$WORKDIR/asm/gke/kubemesh; \
kubectl --context $DEV1_GKE_1 exec -n frontend -it \
$RESPY_POD -c respy /bin/sh -- -c 'watch -n 1 ./respy \
--u http://frontend:80/version --c 10 --n 500'; sleep 2"
출력(복사 금지)
500 requests to http://frontend:80/version... +----------+-------------------+ | RESPONSE | % OF 500 REQUESTS | +----------+-------------------+ | v1 | 100.0% | | | | +----------+-------------------+
- Dev1 리전에서 카나리아 파이프라인을 실행합니다. VirtualService에서 frontend-v2 트래픽 비율을 업데이트하는 스크립트를 제공합니다 (가중치를 20%, 50%, 80%, 100%로 업데이트). 업데이트 사이에 스크립트는 Cloud Build 파이프라인이 완료될 때까지 기다립니다. Dev1 리전에 대한 카나리아 배포 스크립트를 실행합니다. 참고 - 이 스크립트는 완료하는 데 10분 정도 걸립니다.
K8S_REPO=$K8S_REPO CANARY_DIR=$CANARY_DIR \
OPS_DIR=$OPS_GKE_1_CLUSTER OPS_CONTEXT=$OPS_GKE_1 \
${CANARY_DIR}/auto-canary.sh
respy 명령어를 실행하는 하단 창에서 트래픽 분할을 실시간으로 확인할 수 있습니다. 예를 들어 20% 지점에서 다음과 같이 설정합니다.
출력(복사 금지)
500 requests to http://frontend:80/version... +----------+-------------------+ | RESPONSE | % OF 500 REQUESTS | +----------+-------------------+ | v1 | 79.4% | | | | | v2 | 20.6% | | | | +----------+-------------------+
- frontend-v2에 대한 Dev2 출시가 완료되면 스크립트 끝에 성공 메시지가 표시됩니다.
Output (do not copy)
✅ 100% successfully deployed 🌈 frontend-v2 Canary Complete for gke-asm-1-r1-prod
- Dev2 포드의 모든 프런트엔드 트래픽이 frontend-v2로 이동해야 합니다.
Output (do not copy)
500 requests to http://frontend:80/version... +----------+-------------------+ | RESPONSE | % OF 500 REQUESTS | +----------+-------------------+ | v2 | 100.0% | | | | +----------+-------------------+
- 분할 창을 닫습니다.
tmux respawn-pane -t ${TMUX_SESSION}:0.1 -k 'exit'
- 생성된 링크에서 Cloud Source 저장소로 이동합니다.
echo https://source.developers.google.com/p/$TF_VAR_ops_project_name/r/k8s-repo
트래픽 비율마다 별도의 커밋이 표시되고, 가장 최근의 커밋이 목록 상단에 표시됩니다.
이제 Dev2 리전에도 동일한 프로세스를 반복합니다. Dev2 리전은 여전히 '잠금' 상태입니다. 을 참조하세요. 이는 기준 repo_setup 스크립트에서 모든 트래픽을 명시적으로 v1로 보내도록 VirtualService를 푸시했기 때문입니다. 덕분에 Dev1에서 리전 카나리아를 안전하게 수행하고 성공적으로 실행되었는지 확인한 후 새 버전을 전 세계에 출시할 수 있었습니다.
- 명령어를 실행하여 Cloud Shell 창을 분할하고 하단 창에서 watch 명령어를 실행합니다.
RESPY_POD=$(kubectl --context $DEV2_GKE_1 get pod \
-n frontend -l app=respy -o jsonpath='{..metadata.name}')
export TMUX_SESSION=$(tmux display-message -p '#S')
tmux split-window -d -t $TMUX_SESSION:0 -p33 \
-v "export KUBECONFIG=$WORKDIR/asm/gke/kubemesh; \
kubectl --context $DEV2_GKE_1 exec -n frontend -it \
$RESPY_POD -c respy /bin/sh -- -c 'watch -n 1 ./respy \
--u http://frontend:80/version --c 10 --n 500'; sleep 2"
출력(복사 금지)
500 requests to http://frontend:80/version... +----------+-------------------+ | RESPONSE | % OF 500 REQUESTS | +----------+-------------------+ | v1 | 100.0% | | | | +----------+-------------------+
- Dev2 리전에서 카나리아 파이프라인을 실행합니다. VirtualService에서 frontend-v2 트래픽 비율을 업데이트하는 스크립트를 제공합니다 (가중치를 20%, 50%, 80%, 100%로 업데이트). 업데이트 사이에 스크립트는 Cloud Build 파이프라인이 완료될 때까지 기다립니다. Dev1 리전에 대한 카나리아 배포 스크립트를 실행합니다. 참고 - 이 스크립트는 완료하는 데 10분 정도 걸립니다.
K8S_REPO=$K8S_REPO CANARY_DIR=$CANARY_DIR \
OPS_DIR=$OPS_GKE_2_CLUSTER OPS_CONTEXT=$OPS_GKE_2 \
${CANARY_DIR}/auto-canary.sh
출력(복사 금지)
500 requests to http://frontend:80/version... +----------+-------------------+ | RESPONSE | % OF 500 REQUESTS | +----------+-------------------+ | v1 | 100.0% | | | | +----------+-------------------+
- Dev2의 Respy 포드에서 Dev2 포드의 트래픽이 프런트엔드 v1에서 v2로 점진적으로 이동하는지 확인합니다. 스크립트가 완료되면 다음과 같이 표시됩니다.
출력(복사 금지)
500 requests to http://frontend:80/version... +----------+-------------------+ | RESPONSE | % OF 500 REQUESTS | +----------+-------------------+ | v2 | 100.0% | | | | +----------+-------------------+
- 분할 창을 닫습니다.
tmux respawn-pane -t ${TMUX_SESSION}:0.1 -k 'exit'
이 섹션에서는 리전별 카나리아 배포를 위해 Istio를 사용하는 방법을 소개했습니다. 프로덕션에서는 수동 스크립트 대신 Container Registry로 푸시된 새 태그된 이미지와 같은 트리거를 사용하여 이 카나리아 스크립트를 Cloud Build 파이프라인으로 자동 트리거할 수 있습니다. 또한 추가 트래픽을 전송하기 전에 사전 정의된 안전 임곗값에 따라 v2의 지연 시간과 오류율을 분석하는 카나리아 분석을 각 단계 사이에 추가할 수도 있습니다.
11. 승인 정책
목표: 마이크로서비스 (AuthZ) 간에 RBAC를 설정합니다.
AuthorizationPolicy
을 만들어 마이크로서비스에 대한 액세스 거부AuthorizationPolicy
을 만들어 마이크로서비스에 대한 특정 액세스 허용
복사하여 붙여넣기 방법 실습 안내
한 곳에서 실행될 수 있는 모놀리식 애플리케이션과 달리 전역으로 분산된 마이크로서비스 앱은 네트워크 경계를 넘어 호출을 수행합니다. 즉, 애플리케이션에 대한 진입점이 많아지고 악의적인 공격의 기회가 많아집니다. Kubernetes 포드에는 일시적인 IP가 있기 때문에 기존 IP 기반 방화벽 규칙으로는 더 이상 워크로드 간 액세스를 보호하기에 적합하지 않습니다. 마이크로서비스 아키텍처에는 보안에 대한 새로운 접근 방식이 필요합니다. 서비스 계정과 같은 Kubernetes 보안 구성요소를 기반으로 하는 Istio는 애플리케이션에 사용할 수 있는 유연한 보안 정책 세트를 제공합니다.
Istio 정책은 인증과 승인에 모두 적용됩니다. 인증은 ID (서버가 본인이 누구인지), 승인은 권한을 확인합니다 (클라이언트가 그렇게 할 수 있는지 여부). Istio 인증에 대해서는 모듈 1 (MeshPolicy)의 상호 TLS 섹션에서 설명했습니다. 이 섹션에서는 Istio 승인 정책을 사용하여 애플리케이션 워크로드 중 하나인 currencyservice에 대한 액세스를 제어하는 방법을 알아봅니다.
먼저 4개 개발자 클러스터 전체에 AuthorizationPolicy를 배포하고, refundservice에 대한 모든 액세스를 차단하고, 프런트엔드에서 오류를 트리거합니다. 그런 다음 프런트엔드 서비스만 통화 서비스에 액세스하도록 허용합니다.
currency-deny-all.yaml
의 콘텐츠를 검사합니다. 이 정책은 배포 라벨 선택기를 사용하여 통화 서비스에 대한 액세스를 제한합니다.spec
필드가 없는 것을 볼 수 있습니다. 즉, 이 정책은 선택한 서비스에 대한 모든 액세스를 거부합니다.
cat $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml
출력(복사 금지)
apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "currency-policy" namespace: currency spec: selector: matchLabels: app: currencyservice
- 두 리전의 운영 클러스터에 해당하는 통화 정책을 k8s-repo에 복사합니다.
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization
kustomize edit add resource currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization
kustomize edit add resource currency-policy.yaml
- 변경사항을 푸시합니다.
cd $WORKDIR/k8s-repo
git add . && git commit -am "AuthorizationPolicy - currency: deny all"
git push
- 이전에 연 탭에서 또는 다음 링크를 클릭하여 운영 프로젝트 Cloud Build의 상태를 확인하세요.
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
- 빌드가 성공적으로 완료되면 브라우저에서 다음 링크를 통해 heapstershop 프런트엔드에 연결해 봅니다.
echo "https://frontend.endpoints.$TF_VAR_ops_project_name.cloud.goog"
통화 서비스에서 승인 오류가 표시됩니다.
- 통화 서비스가 이 AuthorizationPolicy를 어떻게 시행하고 있는지 살펴보겠습니다. 먼저 차단된 승인 호출은 기본적으로 로깅되지 않으므로 통화 포드 중 하나에 대해 Envoy 프록시에 trace 수준 로그를 사용 설정합니다.
CURRENCY_POD=$(kubectl --context $DEV1_GKE_2 get pod -n currency | grep currency| awk '{ print $1 }')
kubectl --context $DEV1_GKE_2 exec -it $CURRENCY_POD -n \
currency -c istio-proxy -- curl -X POST \
"http://localhost:15000/logging?level=trace"
- 통화 서비스의 사이드카 프록시에서 RBAC (승인) 로그를 가져옵니다. '강제 거부됨'이라는 메시지가 메시지(통화 서비스가 모든 인바운드 요청을 차단하도록 설정되었음을 나타냅니다.
kubectl --context $DEV1_GKE_2 logs -n currency $CURRENCY_POD \
-c istio-proxy | grep -m 3 rbac
출력(복사 금지)
[Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][rbac] [external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:67] checking request: remoteAddress: 10.16.5.15:37310, localAddress: 10.16.3.8:7000, ssl: uriSanPeerCertificate: spiffe://cluster.local/ns/frontend/sa/frontend, subjectPeerCertificate: , headers: ':method', 'POST' [Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][rbac] [external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:118] enforced denied [Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][http] [external/envoy/source/common/http/conn_manager_impl.cc:1354] [C115][S17310331589050212978] Sending local reply with details rbac_access_denied
- 이제 다른 백엔드 서비스는 허용하지 않고 프런트엔드에서 통화 서비스에 액세스하도록 허용해 보겠습니다.
currency-allow-frontend.yaml
를 열고 콘텐츠를 검사합니다. 다음 규칙을 추가했습니다.
cat ${WORKDIR}/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml
출력(복사 금지)
rules: - from: - source: principals: ["cluster.local/ns/frontend/sa/frontend"]
여기에서는 통화 서비스에 액세스하기 위해 특정 source.principal (클라이언트)을 허용 목록에 추가합니다. 이 source.principal은 Kubernetes 서비스 계정입니다. 이 경우 허용 목록에 포함된 서비스 계정은 프런트엔드 네임스페이스의 프런트엔드 서비스 계정입니다.
참고: Istio AuthorizationPolicies에서 Kubernetes 서비스 계정을 사용할 때는 모듈 1에서 한 것처럼 먼저 클러스터 전체 상호 TLS를 사용 설정해야 합니다. 이는 서비스 계정 사용자 인증 정보가 요청에 마운트되도록 하기 위함입니다.
- 업데이트된 통화 정책 복사
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
- 변경사항을 푸시합니다.
cd $WORKDIR/k8s-repo
git add . && git commit -am "AuthorizationPolicy - currency: allow frontend"
git push
- 이전에 연 탭에서 또는 다음 링크를 클릭하여 운영 프로젝트 Cloud Build의 상태를 확인합니다.
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
- 빌드가 성공적으로 완료되면 Hipstershop 프런트엔드를 다시 엽니다. 이번에는 홈페이지에 오류가 표시되지 않습니다. 프런트엔드에서 현재 서비스에 액세스할 수 있도록 명시적으로 허용되었기 때문입니다.
- 이제 장바구니에 상품을 추가하고 '주문하기'를 클릭하여 결제를 실행해 봅니다. 이번에는 통화 서비스의 가격 변환 오류가 표시됩니다. 프런트엔드만 허용 목록에 추가했기 때문에 결제 서비스에서 아직 통화 서비스에 액세스할 수 없기 때문입니다.
- 마지막으로 통화 서비스 AuthorizationPolicy에 다른 규칙을 추가하여 결제 서비스에서 통화에 액세스하도록 허용합니다. Google은 서비스에 액세스해야 하는 두 가지 서비스(프런트엔드 및 결제)에 대해서만 통화 액세스를 허용하고 있습니다. 다른 백엔드는 계속 차단됩니다.
currency-allow-frontend-checkout.yaml
를 열고 콘텐츠를 검사합니다. 규칙 목록은 논리적 OR 통화의 역할을 합니다. 이 두 서비스 계정 중 하나가 있는 워크로드의 요청만 허용됩니다.
cat ${WORKDIR}/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml
출력(복사 금지)
apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "currency-policy" namespace: currency spec: selector: matchLabels: app: currencyservice rules: - from: - source: principals: ["cluster.local/ns/frontend/sa/frontend"] - from: - source: principals: ["cluster.local/ns/checkout/sa/checkout"]
- 최종 승인 정책을 k8s-repo에 복사합니다.
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
- 변경사항 푸시
cd $WORKDIR/k8s-repo
git add . && git commit -am "AuthorizationPolicy - currency: allow frontend and checkout"
git push
- 이전에 연 탭에서 또는 다음 링크를 클릭하여 운영 프로젝트 Cloud Build의 상태를 확인합니다.
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
- 빌드가 성공적으로 완료된 후 결제 실행을 시도합니다. 그러면 성공적으로 작동합니다.
이 섹션에서는 Istio 승인 정책을 사용하여 서비스 수준별로 세분화된 액세스 제어를 적용하는 방법을 설명했습니다. 프로덕션에서는 서비스당 AuthorizationPolicy를 하나씩 만들 수 있습니다. 예를 들어 allow-all 정책을 사용하여 동일한 네임스페이스에 있는 모든 워크로드가 서로 액세스할 수 있도록 합니다.
12. 인프라 확장
목표: 새 리전, 프로젝트, 클러스터를 추가하여 인프라를 확장합니다.
infrastructure
저장소를 클론합니다.- terraform 파일을 업데이트하여 새 리소스 만들기
- 새 리전에 서브넷 2개 (운영 프로젝트용 1개, 새 프로젝트용 1개)
- 새 리전 (새 서브넷)의 새 작업 클러스터
- 새 리전의 새 Istio 제어 영역
- 새 리전의 새 프로젝트에서 앱 2개 클러스터
infrastructure
저장소에 커밋- 설치 확인
복사하여 붙여넣기 방법 실습 안내
플랫폼을 확장하는 방법에는 여러 가지가 있습니다. 기존 클러스터에 노드를 추가하여 컴퓨팅을 더 추가할 수 있습니다. 한 리전에 클러스터를 더 추가할 수 있습니다. 또는 플랫폼에 리전을 더 추가할 수 있습니다. 플랫폼의 어떤 측면으로 확장할 것인지는 요구사항에 따라 달라집니다. 예를 들어 한 리전의 3개 영역 모두에 클러스터가 있는 경우 기존 클러스터에 노드 (또는 노드 풀)를 더 추가하는 것으로 충분할 수 있습니다. 하지만 단일 리전의 3개 영역 중 두 개에 클러스터가 있는 경우 세 번째 영역에 새 클러스터를 추가하면 확장 및 추가 오류 도메인 (즉, 새 영역)이 제공됩니다. 리전에 새 클러스터를 추가하는 또 다른 이유는 규제 또는 규정 준수를 위해 단일 테넌트 클러스터를 만들어야 하기 때문일 수도 있습니다 (예: PCI 또는 PII 정보가 저장된 데이터베이스 클러스터). 비즈니스와 서비스가 확장됨에 따라 고객에게 더 가까운 곳에서 서비스를 제공하기 위해 새로운 리전을 추가하는 것은 불가피합니다.
현재 플랫폼은 2개의 리전과 리전당 2개의 영역에 있는 클러스터로 구성됩니다. 플랫폼 확장은 두 가지 방법으로 생각할 수 있습니다.
- 수직 - 컴퓨팅을 추가하여 각 리전 내에서 기존 클러스터에 노드 (또는 노드 풀)를 추가하거나 리전 내에 새 클러스터를 추가하면 됩니다. 이 작업은
infrastructure
저장소를 통해 실행됩니다. 가장 간단한 방법은 기존 클러스터에 노드를 추가하는 것입니다. 추가 구성은 필요하지 않습니다. 새 클러스터를 추가하려면 추가 서브넷 (및 보조 범위)이 필요할 수 있으며, 적절한 방화벽 규칙을 추가하고, 새 클러스터를 리전 ASM/Istio 서비스 메시 제어 영역에 추가하고, 애플리케이션 리소스를 새 클러스터에 배포해야 할 수 있습니다. - 가로 - 지역을 더 추가합니다. 현재 플랫폼에서는 리전 템플릿이 제공됩니다. ASM/Istio 제어가 상주하는 리전별 운영 클러스터와 애플리케이션 리소스가 배포되는 2개 이상의 영역 애플리케이션 클러스터로 구성됩니다.
이 워크숍에서는 플랫폼을 '수평적으로' 확장합니다. 여기에는 수직 사용 사례 단계도 포함되기 때문입니다. 플랫폼에 새 리전 (r3)을 추가하여 플랫폼을 수평적으로 확장하려면 다음 리소스를 추가해야 합니다.
- 새 작업 및 애플리케이션 클러스터를 위한 리전 r3의 호스트 프로젝트 공유 VPC의 서브넷입니다.
- ASM/Istio 제어 영역이 있는 리전 r3의 리전별 작업 클러스터입니다.
- r3 리전의 두 영역에 있는 2개의 영역별 애플리케이션 클러스터
- k8s-repo로 업데이트합니다.
- ASM/Istio 제어 영역 리소스를 r3 리전의 작업 클러스터에 배포합니다.
- ASM/Istio 공유 제어 영역 리소스를 r3 리전의 앱 클러스터에 배포합니다.
- 새 프로젝트를 만들 필요는 없지만 워크숍의 단계에서는 플랫폼에 새 팀을 추가하는 사용 사례를 다루기 위해 새 프로젝트 dev3를 추가하는 방법을 설명합니다.
인프라 저장소는 위에 언급된 새 리소스를 추가하는 데 사용됩니다.
- Cloud Shell에서 WORKDIR로 이동하여
infrastructure
저장소를 클론합니다.
mkdir -p $WORKDIR/infra-repo
cd $WORKDIR/infra-repo
git init && git remote add origin https://source.developers.google.com/p/${TF_ADMIN}/r/infrastructure
git config --local user.email ${MY_USER}
git config --local user.name "infra repo user"
git config --local credential.'https://source.developers.google.com'.helper gcloud.sh
git pull origin master
- Workshop source repo
add-proj
브랜치를add-proj-repo
디렉터리에 클론합니다.
cd $WORKDIR
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git add-proj-repo -b add-proj
- 소스 워크숍 저장소의
add-proj
브랜치에서 파일을 복사합니다.add-proj
브랜치에는 이 섹션의 변경사항이 포함되어 있습니다.
cp -r $WORKDIR/add-proj-repo/infrastructure/* $WORKDIR/infra-repo/
- add-proj repo 디렉터리의
infrastructure
디렉터리를infra-repo
디렉터리의 심볼릭 링크로 바꿔 브랜치에서 스크립트를 실행할 수 있도록 합니다.
rm -rf $WORKDIR/add-proj-repo/infrastructure
ln -s $WORKDIR/infra-repo $WORKDIR/add-proj-repo/infrastructure
add-project.sh
스크립트를 실행하여 공유 상태와 변수를 새 프로젝트 디렉터리 구조에 복사합니다.
$WORKDIR/add-proj-repo/scripts/add-project.sh app3 $WORKDIR/asm $WORKDIR/infra-repo
- 변경사항을 커밋하고 푸시하여 새 프로젝트 만들기
cd $WORKDIR/infra-repo
git add .
git status
git commit -m "add new project" && git push origin master
- 커밋은
infrastructure
저장소를 트리거하여 새 리소스로 인프라를 배포합니다. 다음 링크의 출력을 클릭하고 상단에 있는 최신 빌드로 이동하여 Cloud Build 진행 상황을 확인합니다.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_ADMIN}"
infrastructure
Cloud Build의 마지막 단계는 k8s-repo
에 새 Kubernetes 리소스를 만듭니다. 그러면 운영 프로젝트의 k8s-repo
에서 Cloud Build가 트리거됩니다. 새 Kubernetes 리소스는 이전 단계에서 추가된 새 클러스터 3개를 위한 리소스입니다. ASM/Istio 제어 영역 및 공유 제어 영역 리소스가 k8s-repo
Cloud Build를 사용하여 새 클러스터에 추가됩니다.
- 인프라 Cloud Build가 성공적으로 완료되면 다음 출력 링크를 클릭하여
k8s-repo
최신 Cloud Build 실행으로 이동합니다.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
- 다음 스크립트를 실행하여 새 클러스터를 vars 및 kubeconfig 파일에 추가합니다.
$WORKDIR/add-proj-repo/scripts/setup-gke-vars-kubeconfig-add-proj.sh $WORKDIR/asm
KUBECONFIG
변수가 새 kubeconfig 파일을 가리키도록 변경합니다.
source $WORKDIR/asm/vars/vars.sh
export KUBECONFIG=$WORKDIR/asm/gke/kubemesh
- 클러스터 컨텍스트를 나열합니다. 8개의 클러스터가 표시됩니다.
kubectl config view -ojson | jq -r '.clusters[].name'
`Output (do not copy)`
gke_user001-200204-05-dev1-49tqc4_us-west1-a_gke-1-apps-r1a-prod gke_user001-200204-05-dev1-49tqc4_us-west1-b_gke-2-apps-r1b-prod gke_user001-200204-05-dev2-49tqc4_us-central1-a_gke-3-apps-r2a-prod gke_user001-200204-05-dev2-49tqc4_us-central1-b_gke-4-apps-r2b-prod gke_user001-200204-05-dev3-49tqc4_us-east1-b_gke-5-apps-r3b-prod gke_user001-200204-05-dev3-49tqc4_us-east1-c_gke-6-apps-r3c-prod gke_user001-200204-05-ops-49tqc4_us-central1_gke-asm-2-r2-prod gke_user001-200204-05-ops-49tqc4_us-east1_gke-asm-3-r3-prod gke_user001-200204-05-ops-49tqc4_us-west1_gke-asm-1-r1-prod
Istio 설치 확인
- 모든 포드가 실행 중이고 작업이 완료되었는지 확인하여 Istio가 새 작업 클러스터에 설치되었는지 확인합니다.
kubectl --context $OPS_GKE_3 get pods -n istio-system
`Output (do not copy)`
NAME READY STATUS RESTARTS AGE grafana-5f798469fd-72g6w 1/1 Running 0 5h12m istio-citadel-7d8595845-hmmvj 1/1 Running 0 5h12m istio-egressgateway-779b87c464-rw8bg 1/1 Running 0 5h12m istio-galley-844ddfc788-zzpkl 2/2 Running 0 5h12m istio-ingressgateway-59ccd6574b-xfj98 1/1 Running 0 5h12m istio-pilot-7c8989f5cf-5plsg 2/2 Running 0 5h12m istio-policy-6674bc7678-2shrk 2/2 Running 3 5h12m istio-sidecar-injector-7795bb5888-kbl5p 1/1 Running 0 5h12m istio-telemetry-5fd7cbbb47-c4q7b 2/2 Running 2 5h12m istio-tracing-cd67ddf8-2qwkd 1/1 Running 0 5h12m istiocoredns-5f7546c6f4-qhj9k 2/2 Running 0 5h12m kiali-7964898d8c-l74ww 1/1 Running 0 5h12m prometheus-586d4445c7-x9ln6 1/1 Running 0 5h12m
- Istio가
dev3
클러스터 모두에 설치되어 있는지 확인합니다. Citadel, 사이드카 인젝터, coredns만dev3
클러스터에서 실행됩니다.ops-3
클러스터에서 실행되는 Istio 제어 영역을 공유합니다.
kubectl --context $DEV3_GKE_1 get pods -n istio-system
kubectl --context $DEV3_GKE_2 get pods -n istio-system
`Output (do not copy)`
NAME READY STATUS RESTARTS AGE istio-citadel-568747d88-4lj9b 1/1 Running 0 66s istio-sidecar-injector-759bf6b4bc-ks5br 1/1 Running 0 66s istiocoredns-5f7546c6f4-qbsqm 2/2 Running 0 78s
공유 제어 영역의 서비스 검색 확인
- 보안 비밀이 6개 애플리케이션 클러스터 모두의 모든 운영 클러스터에 배포되었는지 확인합니다.
kubectl --context $OPS_GKE_1 get secrets -l istio/multiCluster=true -n istio-system
kubectl --context $OPS_GKE_2 get secrets -l istio/multiCluster=true -n istio-system
kubectl --context $OPS_GKE_3 get secrets -l istio/multiCluster=true -n istio-system
`Output (do not copy)`
NAME TYPE DATA AGE gke-1-apps-r1a-prod Opaque 1 14h gke-2-apps-r1b-prod Opaque 1 14h gke-3-apps-r2a-prod Opaque 1 14h gke-4-apps-r2b-prod Opaque 1 14h gke-5-apps-r3b-prod Opaque 1 5h12m gke-6-apps-r3c-prod Opaque 1 5h12m
13. 회로 차단
목표: 운송 서비스에 사용되는 회로 차단기를 구현합니다.
- 회로 차단기를 구현하기 위해
shipping
서비스의DestinationRule
를 만듭니다. fortio
(부하 생성 유틸리티)를 사용하여 회로를 강제 해제하여shipping
서비스의 회로 차단기를 검증합니다.
빠른 트랙 스크립트 실습 안내
빠른 트랙 스크립트 실습이 곧 제공될 예정입니다.
복사하여 붙여넣기 방법 실습 안내
지금까지 Istio 지원 서비스에 대한 몇 가지 기본 모니터링 및 문제 해결 전략을 배웠으므로, Istio가 처음부터 수행해야 하는 문제 해결의 양을 줄여 서비스의 복원력을 개선하는 데 어떻게 도움이 되는지 살펴보겠습니다.
마이크로서비스 아키텍처는 한 서비스의 장애가 종속 항목으로 전파되어 '파급 효과'를 유발하는 연쇄적 장애 위험을 야기합니다. 신속하게 대응할 수 있습니다. Istio는 서비스를 격리하여 다운스트림 (클라이언트 측) 서비스가 실패한 서비스를 대기하지 않도록 보호하고, 업스트림 (서버 측) 서비스가 다시 온라인 상태가 되었을 때 갑작스러운 다운스트림 트래픽의 홍수로부터 보호하기 위해 회로 차단기 트래픽 정책을 제공합니다. 전반적으로 회로 차단기를 사용하면 중단된 백엔드 서비스 하나로 인해 모든 서비스의 SLO 실패를 방지할 수 있습니다.
회로 차단기 패턴은 전기 스위치의 이름을 따서 너무 많은 전력이 통과할 때 장치가 과부하되지 않도록 보호합니다. 이는 Istio 설정에서 Envoy가 회로 차단기로, 서비스의 대기 중인 요청 수를 추적합니다. 이 기본 닫힌 상태에서는 요청이 Envoy를 통해 중단 없이 전달됩니다.
하지만 대기 중인 요청 수가 정의된 임곗값을 초과하면 회로 차단기가 작동 (열림)되고 Envoy가 즉시 오류를 반환합니다. 이렇게 하면 서버가 클라이언트에 대해 빠르게 장애를 일으키고 과부하 시 서버 애플리케이션 코드가 클라이언트의 요청을 수신하는 것을 방지할 수 있습니다.
그런 다음 정의된 제한 시간이 지나면 Envoy가 반 열린 상태로 전환되어 서버가 테스트 중에 요청을 다시 받기 시작할 수 있습니다. 또한 요청에 성공적으로 응답할 수 있는 경우 회로 차단기가 다시 닫히고 서버에 대한 요청이 다시 흐르기 시작합니다.
이 다이어그램에는 Istio 회로 차단기 패턴이 요약되어 있습니다. 파란색 직사각형은 Envoy를 나타내고, 파란색으로 채워진 원은 클라이언트를 나타내며, 흰색으로 채워진 원은 서버 컨테이너를 나타냅니다.
Istio DestinationRules를 사용하여 회로 차단기 정책을 정의할 수 있습니다. 이 섹션에서는 다음 정책을 적용하여 배송 서비스에 회로 차단기를 적용합니다.
Output (do not copy) apiVersion: "networking.istio.io/v1alpha3" kind: "DestinationRule" metadata: name: "shippingservice-shipping-destrule" namespace: "shipping" spec: host: "shippingservice.shipping.svc.cluster.local" trafficPolicy: tls: mode: ISTIO_MUTUAL connectionPool: tcp: maxConnections: 1 http: http1MaxPendingRequests: 1 maxRequestsPerConnection: 1 outlierDetection: consecutiveErrors: 1 interval: 1s baseEjectionTime: 10s maxEjectionPercent: 100
여기에 주목해야 할 DestinationRule 필드가 두 개 있습니다. connectionPool
는 이 서비스에서 허용하는 연결 수를 정의합니다. outlierDetection 필드에서는 Envoy가 회로 차단기를 열 임곗값을 결정하는 방법을 구성합니다. 여기서 1초마다 (간격) Envoy는 서버 컨테이너에서 수신한 오류 수를 계산합니다. consecutiveErrors
기준점을 초과하면 Envoy 회로 차단기가 열리고 제품 카탈로그 포드의 100% 가 10초 동안 새 클라이언트 요청으로부터 보호됩니다. Envoy 회로 차단기가 열리면 (활성) 클라이언트에 503 (서비스를 사용할 수 없음) 오류가 표시됩니다. 예를 보면서 살펴보겠습니다.
- k8s-repo 및 asm dir의 환경 변수를 설정하여 명령어를 단순화합니다.
export K8S_REPO="${WORKDIR}/k8s-repo"
export ASM="${WORKDIR}/asm"
- k8s-repo 업데이트
cd $WORKDIR/k8s-repo
git pull
cd $WORKDIR
- 두 작업 클러스터의 배송 서비스 DestinationRule을 업데이트합니다.
cp $ASM/k8s_manifests/prod/istio-networking/app-shipping-circuit-breaker.yaml ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cp $ASM/k8s_manifests/prod/istio-networking/app-shipping-circuit-breaker.yaml ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit add resource app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit add resource app-shipping-circuit-breaker.yaml
- Fortio 부하 생성기 포드를 Dev1 리전의 GKE_1 클러스터에 복사합니다. 'trip'하는 데 사용할 클라이언트 포드입니다. 배송 서비스용 회로 차단기입니다.
cp $ASM/k8s_manifests/prod/app/deployments/app-fortio.yaml ${K8S_REPO}/${DEV1_GKE_1_CLUSTER}/app/deployments/
cd ${K8S_REPO}/${DEV1_GKE_1_CLUSTER}/app/deployments; kustomize edit add resource app-fortio.yaml
- 변경사항을 커밋합니다.
cd $K8S_REPO
git add . && git commit -am "Circuit Breaker: shippingservice"
git push
cd $ASM
- Cloud Build가 완료될 때까지 기다립니다.
- Cloud Shell로 돌아가서 fortio 포드를 사용하여 동시 연결 1개(총 요청 1,000개)로 gRPC 트래픽을 shippingservice로 전송합니다. 이 경우 아직
connectionPool
설정을 초과하지 않았으므로 회로 차단기가 전환되지 않습니다.
FORTIO_POD=$(kubectl --context ${DEV1_GKE_1} get pod -n shipping | grep fortio | awk '{ print $1 }')
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 1 -n 1000 -qps 0 shippingservice.shipping.svc.cluster.local:50051
출력(복사 금지)
Health SERVING : 1000 All done 1000 calls (plus 0 warmup) 4.968 ms avg, 201.2 qps
- 이제 fortio를 다시 실행하여 동시 연결 수를 2로 늘리되 총 요청 수는 일정하게 유지합니다. 요청의 3분의 2가 'overflow' 오류 발생: 정의한 정책에서 1초 간격으로 1개의 동시 연결만 허용됩니다.
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 2 -n 1000 -qps 0 shippingservice.shipping.svc.cluster.local:50051
출력(복사 금지)
18:46:16 W grpcrunner.go:107> Error making grpc call: rpc error: code = Unavailable desc = upstream connect error or disconnect/reset before headers. reset reason: overflow ... Health ERROR : 625 Health SERVING : 375 All done 1000 calls (plus 0 warmup) 12.118 ms avg, 96.1 qps
- Envoy는 회로 차단기가 활성화되었을 때 upstream_rq_pending_overflow 측정항목을 사용하여 중단된 연결 수를 추적합니다. fortio 포드에서 이를 찾아보겠습니다.
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c istio-proxy -- sh -c 'curl localhost:15000/stats' | grep shipping | grep pending
출력(복사 금지)
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.circuit_breakers.default.rq_pending_open: 0 cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.circuit_breakers.high.rq_pending_open: 0 cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_active: 0 cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_failure_eject: 9 cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_overflow: 565 cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_total: 1433
- 두 리전에서 회로 차단기 정책을 삭제하여 정리하세요.
kubectl --context ${OPS_GKE_1} delete destinationrule shippingservice-circuit-breaker -n shipping
rm ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit remove resource app-shipping-circuit-breaker.yaml
kubectl --context ${OPS_GKE_2} delete destinationrule shippingservice-circuit-breaker -n shipping
rm ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit remove resource app-shipping-circuit-breaker.yaml
cd $K8S_REPO; git add .; git commit -m "Circuit Breaker: cleanup"; git push origin master
이 섹션에서는 서비스에 단일 회로 차단기 정책을 설정하는 방법을 설명했습니다. 가장 좋은 방법은 중단될 가능성이 있는 업스트림 (백엔드) 서비스에 회로 차단기를 설정하는 것입니다. Istio 회로 차단기 정책을 적용하면 마이크로서비스를 격리하고 아키텍처에 내결함성을 빌드하며 고부하 상태에서 연쇄 장애 발생 위험을 줄일 수 있습니다.
14. 결함 주입
목표: 지연을 도입하여 추천 서비스의 복원력을 테스트합니다 (프로덕션으로 푸시되기 전).
recommendation
서비스의VirtualService
를 만들어 5초 지연을 도입합니다.fortio
부하 생성기를 사용하여 지연 테스트VirtualService
에서 지연을 삭제하고 확인합니다.
빠른 트랙 스크립트 실습 안내
빠른 트랙 스크립트 실습이 곧 제공될 예정입니다.
복사하여 붙여넣기 방법 실습 안내
서비스에 회로 차단기 정책을 추가하는 것은 프로덕션의 서비스에 대한 복원력을 구축하는 한 가지 방법입니다. 그러나 회로 차단으로 인해 결함, 즉 사용자에게 발생할 수 있는 오류가 발생할 수 있으며 이는 바람직하지 않습니다. 이러한 오류 사례에 미리 대비하고 백엔드에서 오류를 반환할 때 다운스트림 서비스의 응답을 더 잘 예측하려면 스테이징 환경에서 카오스 테스트를 채택하면 됩니다. 카오스 테스트는 시스템의 약점을 분석하고 내결함성을 개선하기 위해 서비스를 의도적으로 중단시키는 방법입니다. 또한 카오스 테스트를 사용하여 백엔드가 실패할 때 사용자가 겪는 오류를 완화하는 방법을 파악할 수도 있습니다(예: 캐시된 결과를 프런트엔드에 표시).
결함 주입에 Istio를 사용하면 소스 코드를 수정하는 대신 프로덕션 출시 이미지를 사용하고 네트워크 레이어에서 오류를 추가할 수 있으므로 유용합니다. 프로덕션에서는 완전한 카오스 테스트 도구를 사용하여 네트워크 레이어 외에도 Kubernetes/컴퓨팅 레이어에서 복원력을 테스트할 수 있습니다.
'오류'가 있는 VirtualService를 적용하여 카오스 테스트에 Istio를 사용할 수 있습니다. 필드를 확인합니다. Istio는 지연 오류 (제한 시간 삽입)와 취소 오류 (HTTP 오류 삽입)의 두 가지 오류를 지원합니다. 이 예시에서는 5초 지연 오류를 추천 서비스에 삽입합니다. 하지만 이번에는 회로 차단기를 사용하여 '빠르게 실패'하는 대신 고장난 서비스에 대해 다운스트림 서비스가 강제로 전체 제한 시간을 견딜 수 있도록 합니다.
- 결함 주입 디렉터리로 이동합니다.
export K8S_REPO="${WORKDIR}/k8s-repo"
export ASM="${WORKDIR}/asm/"
cd $ASM
k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml
를 열어 콘텐츠를 검사합니다. Istio에는 요청의 일정 비율에 따라 오류를 주입하는 옵션이 있습니다. 여기서는 모든 추천 서비스 요청에 시간 제한을 적용하겠습니다.
출력(복사 금지)
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: recommendation-delay-fault spec: hosts: - recommendationservice.recommendation.svc.cluster.local http: - route: - destination: host: recommendationservice.recommendation.svc.cluster.local fault: delay: percentage: value: 100 fixedDelay: 5s
- VirtualService를 k8s_repo에 복사합니다. 두 리전 모두에 전역적으로 오류를 삽입합니다.
cp $ASM/k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit add resource app-recommendation-vs-fault.yaml
cp $ASM/k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit add resource app-recommendation-vs-fault.yaml
- 변경사항 푸시
cd $K8S_REPO
git add . && git commit -am "Fault Injection: recommendationservice"
git push
cd $ASM
- Cloud Build가 완료될 때까지 기다립니다.
- 회로 차단기 섹션에 배포된 fortio 포드를 실행하고 일부 트래픽을 Recommendedservice로 전송합니다.
FORTIO_POD=$(kubectl --context ${DEV1_GKE_1} get pod -n shipping | grep fortio | awk '{ print $1 }')
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 100 -n 100 -qps 0 recommendationservice.recommendation.svc.cluster.local:8080
Once the fortio command is complete, you should see responses averaging 5s:
출력(복사 금지)
Ended after 5.181367359s : 100 calls. qps=19.3 Aggregated Function Time : count 100 avg 5.0996506 +/- 0.03831 min 5.040237641 max 5.177559818 sum 509.965055
- 실제로 주입한 결함을 확인하는 또 다른 방법은 웹 브라우저에서 프런트엔드를 열고 제품을 클릭하는 것입니다. 제품 페이지는 페이지 하단에 표시된 추천을 가져오므로 로드하는 데 5초가 더 걸립니다.
- 두 운영 클러스터에서 결함 주입 서비스를 삭제하여 정리합니다.
kubectl --context ${OPS_GKE_1} delete virtualservice recommendation-delay-fault -n recommendation
rm ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit remove resource app-recommendation-vs-fault.yaml
kubectl --context ${OPS_GKE_2} delete virtualservice recommendation-delay-fault -n recommendation
rm ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit remove resource app-recommendation-vs-fault.yaml
- 변경사항 푸시:
cd $K8S_REPO
git add . && git commit -am "Fault Injection cleanup / restore"
git push
cd $ASM
15. Istio 제어 영역 모니터링
ASM은 파일럿, 믹서, 갤러리, 시타델이라는 4개의 중요한 제어 영역 구성요소를 설치합니다. 각각 관련 모니터링 측정항목을 Prometheus로 전송하며, ASM은 운영자가 이 모니터링 데이터를 시각화하고 제어 영역의 상태와 성능을 평가할 수 있는 Grafana 대시보드와 함께 제공됩니다.
대시보드 보기
- Istio를 사용하여 설치된 Grafana 서비스 포트 전달
kubectl --context ${OPS_GKE_1} -n istio-system port-forward svc/grafana 3000:3000 >> /dev/null
- 브라우저에서 Grafana 열기
- '웹 미리보기'를 클릭합니다. 아이콘을 클릭합니다.
- 포트 3000에서 미리보기를 클릭합니다 (참고: 포트가 3000이 아닌 경우 포트 변경을 클릭하고 포트 3000을 선택).
- 그러면 브라우저에서 ' BASE_URL/?orgId=1&authuser=0&environment_id=default
- 사용 가능한 대시보드 보기
- URL을 ' BASE_URL/dashboard"
- 'istio'를 클릭합니다. 사용 가능한 대시보드 보기
- 대시보드를 클릭하면 구성요소의 실적을 확인할 수 있습니다. 다음 섹션에서는 각 구성요소의 중요한 측정항목을 살펴보겠습니다.
모니터링 파일럿
파일럿은 네트워킹 및 정책 구성을 데이터 영역 (Envoy 프록시)에 분산하는 제어 영역 구성요소입니다. 파일럿은 워크로드 및 배포 수에 따라 확장되는 경향이 있지만 이러한 워크로드에 대한 트래픽 양과 반드시 일치하는 것은 아닙니다. 비정상 파일럿은 다음을 수행할 수 있습니다.
- 필요한 것보다 더 많은 리소스 (CPU 및/또는 RAM) 소비
- 업데이트된 구성 정보를 Envoy에 푸시하는 작업이 지연됩니다.
참고: Pilot이 다운되거나 지연이 발생한 경우에도 워크로드에서 계속 트래픽을 처리합니다.
- ' BASE_URL/dashboard/db/istio-pilot-dashboard" 를 클릭하여 파일럿 측정항목을 확인합니다.
중요한 모니터링 측정항목
리소스 사용량
허용되는 사용량 수치는 Istio 성능 및 확장성 페이지를 가이드로 참고하세요. 리소스 사용량이 이보다 훨씬 많으면 GCP 지원팀에 문의하세요.
파일럿 푸시 정보
이 섹션에서는 Envoy 프록시에 대한 파일럿 푸시를 모니터링합니다.
- 파일럿 푸시는 특정 시점에 푸시된 구성의 유형을 보여줍니다.
- ADS Monitoring은 시스템의 가상 서비스, 서비스, 연결된 엔드포인트 수를 보여줍니다.
- 알려진 엔드포인트가 없는 클러스터에는 구성되었지만 실행 중인 인스턴스가 없는 엔드포인트가 표시됩니다. 이는 *.googleapis.com과 같은 외부 서비스를 나타낼 수 있습니다.
- 파일럿 오류는 시간 경과에 따라 발생한 오류의 수를 나타냅니다.
- 충돌은 리스너의 모호한 구성인 충돌 수를 보여줍니다.
오류 또는 충돌이 있으면 하나 이상의 서비스에 구성이 잘못되었거나 일관되지 않은 것입니다. 자세한 내용은 데이터 영역 문제 해결을 참조하세요.
Envoy 정보
이 섹션에는 제어 영역에 연결하는 Envoy 프록시에 대한 정보가 포함되어 있습니다. XDS 연결 실패가 반복해서 발생하면 GCP 지원팀에 문의하세요.
모니터링 믹서
Mixer는 Envoy 프록시에서 원격 분석 백엔드 (일반적으로 Prometheus, Stackdriver 등)로 원격 분석을 전달하는 구성요소입니다. 이 용량에서는 데이터 영역에 있지 않습니다. 2개의 서로 다른 서비스 이름 (istio-telemetry 및 istio-policy)을 사용하여 배포된 2개의 Kubernetes 작업 (Mixer라고 함)으로 배포됩니다.
Mixer는 정책 시스템과 통합하는 데 사용할 수도 있습니다. 이 용량에서는 서비스 액세스를 차단하는 Mixer의 정책 확인으로 인해 Mixer가 데이터 영역에 영향을 줍니다.
Mixer는 트래픽의 양에 따라 확장되는 경향이 있습니다.
- ' BASE_URL/dashboard/db/istio-mixer-dashboard" 를 클릭하여 믹서 측정항목을 확인하세요.
중요 모니터링 측정항목
리소스 사용량
허용되는 사용량 수치는 Istio 성능 및 확장성 페이지를 가이드로 참고하세요. 리소스 사용량이 이보다 훨씬 많으면 GCP 지원팀에 문의하세요.
믹서 개요
- 응답 시간은 중요한 측정항목입니다. Mixer 텔레메트리에 대한 보고는 데이터 경로에 없지만 지연 시간이 길면 사이드카 프록시 성능이 저하됩니다. 90번째 백분위수는 한 자릿수 밀리초이고 99번째 백분위수는 100ms 미만이어야 합니다.
- 어댑터 디스패치 기간은 믹서가 어댑터를 호출할 때 발생하는 지연 시간을 나타내며, 이를 통해 텔레메트리 및 로깅 시스템에 정보를 전송합니다. 여기서 긴 지연 시간은 메시 성능에 절대적인 영향을 미칩니다. 마찬가지로 p90 지연 시간은 10ms 미만이어야 합니다.
모니터링 갤러리
Galley는 Istio의 구성 유효성 검사, 수집, 처리, 배포 구성요소입니다. Kubernetes API 서버의 구성을 파일럿으로 전달합니다. 파일럿과 마찬가지로 시스템의 서비스 및 엔드포인트의 수에 따라 확장되는 경향이 있습니다.
- ' BASE_URL/dashboard/db/istio-galley-dashboard" 를 클릭하여 갤러리 측정항목을 확인합니다.
중요 모니터링 측정항목
리소스 유효성 검사
유효성 검사를 통과했거나 실패한 대상 규칙, 게이트웨이, 서비스 항목 등 다양한 유형의 리소스 수를 나타내는 가장 중요한 측정항목입니다.
연결된 클라이언트
Galley에 연결된 클라이언트 수를 나타냅니다. 일반적으로 3 (pilot, istio-telemetry, istio-policy)이며 이러한 구성요소가 확장됨에 따라 확장됩니다.
16. Istio 문제 해결
데이터 영역 문제 해결
파일럿 대시보드에 구성 문제가 있다고 표시되면 파일럿 로그를 검사하거나 istioctl을 사용하여 구성 문제를 찾아야 합니다.
파일럿 로그를 검사하려면 kubectl -n istio-system logs istio-pilot-69db46c598-45m44 검색을 실행하고 istio-pilot-... 을 문제를 해결하려는 파일럿 인스턴스의 포드 식별자로 바꿉니다.
결과 로그에서 Push Status 메시지를 검색합니다. 예를 들면 다음과 같습니다.
2019-11-07T01:16:20.451967Z info ads Push Status: {
"ProxyStatus": {
"pilot_conflict_outbound_listener_tcp_over_current_tcp": {
"0.0.0.0:443": {
"proxy": "cartservice-7555f749f-k44dg.hipster",
"message": "Listener=0.0.0.0:443 AcceptedTCP=accounts.google.com,*.googleapis.com RejectedTCP=edition.cnn.com TCPServices=2"
}
},
"pilot_duplicate_envoy_clusters": {
"outbound|15443|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
"proxy": "sleep-6c66c7765d-9r85f.default",
"message": "Duplicate cluster outbound|15443|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
},
"outbound|443|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
"proxy": "sleep-6c66c7765d-9r85f.default",
"message": "Duplicate cluster outbound|443|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
},
"outbound|80|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
"proxy": "sleep-6c66c7765d-9r85f.default",
"message": "Duplicate cluster outbound|80|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
}
},
"pilot_eds_no_instances": {
"outbound_.80_._.frontend-external.hipster.svc.cluster.local": {},
"outbound|443||*.googleapis.com": {},
"outbound|443||accounts.google.com": {},
"outbound|443||metadata.google.internal": {},
"outbound|80||*.googleapis.com": {},
"outbound|80||accounts.google.com": {},
"outbound|80||frontend-external.hipster.svc.cluster.local": {},
"outbound|80||metadata.google.internal": {}
},
"pilot_no_ip": {
"loadgenerator-778c8489d6-bc65d.hipster": {
"proxy": "loadgenerator-778c8489d6-bc65d.hipster"
}
}
},
"Version": "o1HFhx32U4s="
}
푸시 상태는 구성을 Envoy 프록시로 푸시하려고 할 때 발생한 문제를 나타냅니다. 이 경우 '중복 클러스터'가 여러 개 표시됩니다. 중복 업스트림 대상을 나타냅니다.
문제 진단에 도움이 필요하면 Google Cloud 지원팀에 문의하세요.
구성 오류 찾기
istioctl을 사용하여 구성을 분석하려면 istioctl experimental analyze -k --context $OPS_GKE_1
를 실행하세요. 이렇게 하면 시스템 구성 분석을 수행하고 제안된 변경사항과 함께 문제를 표시합니다. 이 명령어로 감지할 수 있는 전체 구성 오류 목록은 문서를 참고하세요.
17. 삭제
관리자가 clearup_workshop.sh 스크립트를 실행하여 bootstrap_workshop.sh 스크립트로 만든 리소스를 삭제합니다. 삭제 스크립트를 실행하려면 다음 정보가 필요합니다.
- 조직 이름(예:
yourcompany.com
) - 워크숍 ID -
YYMMDD-NN
형식(예:200131-01
) - 관리자 GCS 버킷 - 부트스트랩 스크립트에 정의됨
- Cloud Shell을 열고 Cloud Shell에서 아래 작업을 모두 수행합니다. 아래 링크를 클릭하세요.
- 원하는 관리자로 gcloud에 로그인했는지 확인합니다.
gcloud config list
- asm 폴더로 이동합니다.
cd ${WORKDIR}/asm
- 삭제할 조직 이름 및 워크숍 ID를 정의합니다.
export ORGANIZATION_NAME=<ORGANIZATION NAME>
export ASM_WORKSHOP_ID=<WORKSHOP ID>
export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
- 다음과 같이 정리 스크립트를 실행합니다.
./scripts/cleanup_workshop.sh --workshop-id ${ASM_WORKSHOP_ID} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET} --org-name ${ORGANIZATION_NAME}