개요
이 실습에서는 Google Kubernetes Engine(GKE)에서 애플리케이션을 설정한 다음 HorizontalPodAutoscaler를 사용하여 웹 애플리케이션을 자동 확장합니다. 그런 다음 서로 다른 유형의 여러 노드 풀을 사용하고, taint와 톨러레이션(toleration)을 적용하여 기본 노드 풀을 기준으로 포드 일정을 조정합니다.
목표
이 실습에서는 다음 작업을 수행하는 방법을 알아봅니다.
- 자동 확장 및 HorizontalPodAutoscaler 구성
- 노드 풀 추가 및 포드 안티어피니티 노드에 taint 구성
- 포드 매니페스트에 톨러레이션(toleration)을 추가하여 노드 taint 예외 구성
실습 설정
Qwiklabs에 액세스
각 실습에서는 정해진 기간 동안 새 Google Cloud 프로젝트와 리소스 집합이 무료로 제공됩니다.
-
시크릿 창을 사용하여 Qwiklabs에 로그인합니다.
-
실습 사용 가능 시간(예: 1:15:00
)을 참고하여 해당 시간 내에 완료합니다.
일시중지 기능은 없습니다. 필요한 경우 다시 시작할 수 있지만 처음부터 시작해야 합니다.
-
준비가 되면 실습 시작을 클릭합니다.
-
실습 사용자 인증 정보(사용자 이름 및 비밀번호)를 기록해 두세요. Google Cloud Console에 로그인합니다.
-
Google Console 열기를 클릭합니다.
-
다른 계정 사용을 클릭한 다음, 안내 메시지에 이 실습에 대한 사용자 인증 정보를 복사하여 붙여넣습니다.
다른 사용자 인증 정보를 사용하는 경우 오류가 발생하거나 요금이 부과됩니다.
-
약관에 동의하고 리소스 복구 페이지를 건너뜁니다.
초기 로그인 단계를 완료하면 프로젝트 대시보드가 표시됩니다.
Google Cloud Shell 활성화하기
Google Cloud Shell은 다양한 개발 도구가 탑재된 가상 머신으로, 5GB의 영구 홈 디렉터리를 제공하며 Google Cloud에서 실행됩니다.
Google Cloud Shell을 사용하면 명령줄을 통해 Google Cloud 리소스에 액세스할 수 있습니다.
-
Cloud 콘솔의 오른쪽 상단 툴바에서 'Cloud Shell 열기' 버튼을 클릭합니다.

-
계속을 클릭합니다.
환경을 프로비저닝하고 연결하는 데 몇 분 정도 소요됩니다. 연결되면 사용자가 미리 인증되어 프로젝트가 PROJECT_ID로 설정됩니다. 예:

gcloud는 Google Cloud의 명령줄 도구입니다. Cloud Shell에 사전 설치되어 있으며 명령줄 자동 완성을 지원합니다.
- 다음 명령어를 사용하여 사용 중인 계정 이름을 나열할 수 있습니다.
gcloud auth list
출력:
Credentialed accounts:
- @.com (active)
출력 예시:
Credentialed accounts:
- google1623327_student@qwiklabs.net
- 다음 명령어를 사용하여 프로젝트 ID를 나열할 수 있습니다.
gcloud config list project
출력:
[core]
project =
출력 예시:
[core]
project = qwiklabs-gcp-44776a13dea667a6
참고:
gcloud 전체 문서는 gcloud CLI 개요 가이드를 참조하세요.
작업 1. 실습용 GKE 클러스터에 연결 및 샘플 워크로드 배포하기
이 작업에서는 실습용 GKE 클러스터에 연결하고 클러스터 내의 포드 집합을 위한 배포 매니페스트를 만듭니다.
실습 GKE 클러스터에 연결하기
- Cloud Shell에서 다음 명령어를 입력하여 영역 및 클러스터 이름의 환경 변수를 설정합니다.
export my_zone={{{project_0.default_zone|ZONE}}}
export my_cluster=standard-cluster-1
- kubectl 명령줄 도구의 명령줄 자동 완성을 구성합니다.
source <(kubectl completion bash)
- 다음과 같이 kubectl의 클러스터에 대한 액세스 권한을 구성합니다.
gcloud container clusters get-credentials $my_cluster --zone $my_zone
GKE 클러스터에 샘플 웹 애플리케이션 배포하기
생성된 web.yaml
배포 파일을 사용하여 클러스터에 샘플 애플리케이션을 배포해 보겠습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 1
selector:
matchLabels:
run: web
template:
metadata:
labels:
run: web
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
name: web
ports:
- containerPort: 8080
protocol: TCP
resources:
# You must specify requests for CPU to autoscale
# based on CPU utilization
requests:
cpu: "250m"
이 매니페스트는 HTTP 서버의 포트 8080에서 수신 대기하는 샘플 웹 애플리케이션 컨테이너 이미지를 사용하여 배포를 만듭니다.
- Cloud Shell에서 다음 명령어를 입력하여 실습 Cloud Shell에 저장소를 클론합니다.
git clone https://github.com/GoogleCloudPlatform/training-data-analyst
- 작업 디렉터리로 연결되는 바로가기, 즉 소프트 링크를 생성합니다.
ln -s ~/training-data-analyst/courses/ak8s/v1.1 ~/ak8s
- 이 실습의 샘플 파일이 포함된 디렉터리로 이동합니다.
cd ~/ak8s/Autoscaling/
- 이 파일에서 배포를 만들려면 다음 명령어를 실행합니다.
kubectl create -f web.yaml --save-config
- 웹 배포를 위해 포트 8080에 NodePort 유형의 서비스 리소스를 만듭니다.
kubectl expose deployment web --target-port=8080 --type=NodePort
- 서비스가 만들어지고 노드 포트가 할당되었는지 다음 명령어로 확인합니다.
kubectl get service web
IP 주소와 포트 번호가 예시 출력과 다를 수 있습니다.
출력:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web NodePort 10.11.246.185 8080:32056/TCP 12s
내 진행 상황 확인하기를 클릭하여 목표를 확인합니다.
GKE 클러스터에 샘플 웹 애플리케이션을 배포합니다.
작업 2. 클러스터에 자동 확장 구성하기
이 작업에서는 앞에서 배포한 샘플 애플리케이션을 자동 확장하도록 클러스터를 구성합니다.
자동 확장 구성하기
- 배포 목록을 가져와 샘플 웹 애플리케이션이 여전히 실행 중인지 확인합니다.
kubectl get deployment
출력은 다음 예와 같이 표시됩니다.
출력:
NAME READY UP-TO-DATE AVAILABLE AGE
web 1/1 1 1 5m48s
애플리케이션의 웹 배포가 표시되어 있지 않으면 작업 1로 돌아가 클러스터에 애플리케이션을 다시 배포합니다.
- 자동 확장되도록 샘플 애플리케이션을 구성(및 CPU 사용률 목표를 1%로 하고 복제본의 최대 개수를 4로, 최소 개수를 1로 설정)하려면 다음 명령어를 실행합니다.
kubectl autoscale deployment web --max 4 --min 1 --cpu-percent 1
kubectl autoscale
을 사용할 때는 CPU 사용률 대상은 물론 애플리케이션의 최대 및 최소 복제본 수를 지정합니다.
- 배포 목록을 가져와 웹 애플리케이션의 배포가 여전히 한 개인지 확인합니다.
kubectl get deployment
출력:
NAME READY UP-TO-DATE AVAILABLE AGE
web 1/1 1 1 8m21s
HorizontalPodAutoscaler 객체 검사하기
이전 작업에서 사용한 kubectl autoscale
명령어는 확장 대상이라는 지정된 리소스를 대상으로 하는 HorizontalPodAutoscaler
객체를 만들고 필요에 따라 이를 확장합니다.
자동 확장 처리는 개발자가 자동 확장 처리를 생성할 때 지정한 평균 CPU 사용률에 맞게 확장 대상의 복제본 수를 주기적으로 조정합니다.
- HorizontalPodAutoscaler 리소스 목록을 가져오려면 다음 명령어를 실행합니다.
kubectl get hpa
출력은 다음 예와 같이 표시됩니다.
출력:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
web Deployment/web 0%/1% 1 4 1 1m
- 테이블 형태로
HorizontalPodAutoscaler
의 구성을 검사하려면 다음 명령어를 실행합니다.
kubectl describe horizontalpodautoscaler web
출력은 다음 예와 같이 표시됩니다.
출력:
Name: web
Namespace: default
Labels:
Annotations:
CreationTimestamp: Tue, 08 Sep 2020...
Reference: Deployment/web
Metrics: ( current / target )
resource cpu on pods (as a percentage of request): 0% (0) / 1%
Min replicas: 1
Max replicas: 4
Deployment pods: 1 current / 1 desired
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True ScaleDownStabilized recent recommendations [...]
ScalingActive True ValidMetricFound the HPA was able to [...]
ScalingLimited False DesiredWithinRange the desired count [...]
Events:
- YAML 형식으로 HorizontalPodAutoscaler의 구성을 보려면 다음 명령어를 실행합니다.
kubectl get horizontalpodautoscaler web -o yaml
출력은 다음 예와 같이 표시됩니다.
출력:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
annotations:
autoscaling.alpha.kubernetes.io/conditions: [...] autoscaling.alpha.kubernetes.io/current-metrics: [...]
creationTimestamp: 2018-11-14T02:59:28Z
name: web
namespace: default
resourceVersion: "14588"
selfLink: /apis/autoscaling/v1/namespaces/[...]
spec:
maxReplicas: 4
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
targetCPUUtilizationPercentage: 1
status:
currentCPUUtilizationPercentage: 0
currentReplicas: 1
desiredReplicas: 1
자동 확장 구성 테스트하기
웹 애플리케이션을 강제로 수평 확장하려면 웹 애플리케이션에 과부하를 발생시켜야 합니다. 샘플 애플리케이션 웹 서버에서 HTTP 쿼리를 무한 루프로 실행하는 4개 컨테이너의 배포를 정의하는 구성 파일을 만듭니다.
제공된 loadgen.yaml
파일로 loadgen 애플리케이션을 배포하여 웹 애플리케이션에 부하를 발생시킵니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: loadgen
spec:
replicas: 4
selector:
matchLabels:
app: loadgen
template:
metadata:
labels:
app: loadgen
spec:
containers:
- name: loadgen
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- while true; do wget -q -O- http://web:8080; done
- 이 컨테이너를 배포하려면 다음 명령어를 실행합니다.
kubectl apply -f loadgen.yaml
이 매니페스트를 배포하면 웹 포드가 확장되기 시작합니다.
내 진행 상황 확인하기를 클릭하여 목표를 확인합니다.
loadgen 애플리케이션 배포하기
- 배포 목록을 가져와 부하 생성기가 실행 중인지 확인합니다.
kubectl get deployment
출력은 다음 예와 같이 표시됩니다.
출력:
NAME READY UP-TO-DATE AVAILABLE AGE
loadgen 4/4 4 4 26s
web 1/1 1 1 14m
- HorizontalPodAutoscaler를 검사합니다.
kubectl get hpa
loadgen 포드에서 트래픽을 생성하기 시작하면 웹 배포 CPU 사용률이 증가하기 시작합니다. 예시 출력에서 CPU 사용률 목표는 현재 35%인 반면, CPU 기준점은 1%입니다.
출력:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
web Deployment/web 35%/1% 1 4 1 8m
- 몇 분 후 다시 HorizontalPodAutoscaler를 검사합니다.
kubectl get hpa
자동 확장 처리에 의해 웹 배포의 복제본이 4개로 늘어났습니다.
출력:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
web Deployment/web 88%/1% 1 4 4 9m
- 웹 애플리케이션의 부하를 중지하려면 loadgen 배포의 복제본을 0개로 조정합니다.
kubectl scale deployment loadgen --replicas 0
- 배포 목록을 가져와 loadgen이 축소되었는지 확인합니다.
kubectl get deployment
loadgen 배포의 복제본이 0개여야 합니다.
출력:
NAME READY UP-TO-DATE AVAILABLE AGE
loadgen 0/0 0 0 3m40s
web 2/4 4 2 18m
참고: 배포를 다시 나열하려면 2~3분 정도 기다려야 합니다.
- 자동 확장 처리를 배포할 때 구성한 복제본 최솟값 1로 웹 애플리케이션이 축소되었는지 배포 목록을 가져와 확인합니다.
kubectl get deployment
이제 웹 애플리케이션의 배포가 한 개여야 합니다.
출력:
NAME READY UP-TO-DATE AVAILABLE AGE
loadgen 0/0 0 0 12m
web 1/1 1 1 14m
작업 3. 노드 풀 관리하기
이 작업에서는 선점형 인스턴스를 사용하여 새로운 노드 풀을 만든 다음 웹 배포를 선점형 노드에서만 실행되도록 제한합니다.
노드 풀 추가하기
- 세 개의 선점형 VM 인스턴스를 갖는 새 노드 풀을 배포하려면 다음 명령어를 실행합니다.
gcloud container node-pools create "temp-pool-1" \
--cluster=$my_cluster --zone=$my_zone \
--num-nodes "2" --node-labels=temp=true --preemptible
사용 가능한 선점형 인스턴스가 없다는 오류가 표시되면 --preemptible
옵션을 삭제한 다음, 실습을 계속 진행하면 됩니다.
- 노드 목록을 가져와 새 노드가 준비되었는지 확인합니다.
kubectl get nodes
이제 4
개의 노드가 있습니다.
이름은 예제 출력과 다릅니다.
출력:
NAME STATUS ROLES AGE VERSION
gke-standard-cluster-1-default-pool...xc Ready 33m v1.19.10-gke.1600
gke-standard-cluster-1-default-pool...q8 Ready 33m v1.19.10-gke.1600
gke-standard-cluster-1-temp-pool-1-...vj Ready 32s v1.19.10-gke.1600
gke-standard-cluster-1-temp-pool-1-...xj Ready 37s v1.19.10-gke.1600
추가한 모든 노드에는 temp=true
라벨이 있습니다. 노드 풀을 만들 때 이 라벨을 설정했기 때문입니다. 이렇게 라벨을 설정하면 노드를 찾고 구성하기가 더 쉽습니다.
-
temp=true
라벨이 있는 노드만 표시하려면 다음 명령어를 실행합니다.
kubectl get nodes -l temp=true
추가한 2개 노드만 표시됩니다.
이름은 예제 출력과 다릅니다.
출력:
NAME STATUS ROLES AGE VERSION
gke-standard-cluster-1-temp-pool-1-...vj Ready 3m26s v1.19.10-gke.1600
gke-standard-cluster-1-temp-pool-1-...xj Ready 3m31s v1.19.10-gke.1600
taint와 톨러레이션(toleration)을 사용해 일정 조정하기
스케줄러가 임시 노드에서 포드를 실행하지 못하도록 하려면 임시 풀의 각 노드에 taint를 추가합니다. taint는 포드가 특정 노드에서 실행 가능한지 확인하는 효과(예: NoExecute)와 함께 키-값 쌍으로 구현됩니다. taint의 키-값을 허용하도록 구성된 노드만 관련 노드에서 실행되도록 예약됩니다.
- 새로 생성된 각 노드에 taint를 추가하려면 다음 명령어를 실행합니다.
temp=true
라벨을 사용하여 이 변경사항을 모든 새 노드에 동시 적용할 수 있습니다.
kubectl taint node -l temp=true nodetype=preemptible:NoExecute
taint된 노드에서 애플리케이션 포드가 실행되도록 허용하려면 배포 구성에 톨러레이션(toleration) 키를 추가해야 합니다.
-
web.yaml
파일을 수정하려면 다음 명령어를 실행합니다.
nano web.yaml
- 템플릿의
spec
섹션에 다음 키를 추가합니다.
tolerations:
- key: "nodetype"
operator: Equal
value: "preemptible"
파일의 spec 섹션은 다음 예와 같이 표시됩니다.
...
spec:
tolerations:
- key: "nodetype"
operator: Equal
value: "preemptible"
containers:
- image: gcr.io/google-samples/hello-app:1.0
name: web
ports:
- containerPort: 8080
protocol: TCP
resources:
# You must specify requests for CPU to autoscale
# based on CPU utilization
requests:
cpu: "250m"
- 강제로 웹 배포에서 새 노드 풀을 사용하도록 하려면 템플릿의
spec
섹션에 nodeSelector 키를 추가합니다. 이 키는 방금 추가한 톨러레이션(toleration) 키와 병렬 상태가 됩니다.
nodeSelector:
temp: "true"
참고: GKE는 각 노드에 cloud.google.com/gke-nodepool
이라는 커스텀 라벨을 추가합니다. 커스텀 라벨에는 노드가 속한 노드 풀의 이름이 포함되어 있습니다. 포드가 적합한 노드에만 배포되도록 이 키를 nodeSelector의 일부로 사용할 수도 있습니다.
이제 전체 web.yaml 배포는 다음과 같은 모습입니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 1
selector:
matchLabels:
run: web
template:
metadata:
labels:
run: web
spec:
tolerations:
- key: "nodetype"
operator: Equal
value: "preemptible"
nodeSelector:
temp: "true"
containers:
- image: gcr.io/google-samples/hello-app:1.0
name: web
ports:
- containerPort: 8080
protocol: TCP
resources:
# You must specify requests for CPU to autoscale
# based on CPU utilization
requests:
cpu: "250m"
-
Ctrl+X 키를 누른 다음, Y를 누르고 Enter 키를 눌러 파일을 저장하고 nano 편집기를 종료합니다.
-
이 변경사항을 적용하려면 다음 명령어를 실행합니다.
kubectl apply -f web.yaml
이 파일을 수정하는 데 문제가 있으면 미리 준비된 샘플 파일 web-tolerations.yaml
을 대신 사용하면 됩니다.
내 진행 상황 확인하기를 클릭하여 목표를 확인합니다.
노드 풀 관리하기
- 포드 목록을 가져옵니다.
kubectl get pods
이름은 예제 출력과 다를 수 있습니다.
출력:
NAME READY STATUS RESTARTS AGE
web-7cb566bccd-pkfst 1/1 Running 0 1m
- 변경사항을 확인하려면 다음 명령어를 사용하여 실행 중인 웹 포드를 검사합니다.
kubectl describe pods -l run=web
목록에서 nodetype=preemptible
이 포함된 Tolerations
섹션이 (잘린) 출력의 하단 부근에 표시됩니다.
출력:
Node-Selectors: temp=true
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
nodetype=preemptible
Events:
출력을 통해, 포드가 새 선점형 노드에서 taint 값을 허용하고 따라서 그러한 노드에서 포드를 실행하도록 예약할 수 있다는 사실을 확인할 수 있습니다.
- 다시 강제로 웹 애플리케이션을 수평 확장하려면 loadgen 배포의 복제본을 다시 4개로 확장합니다.
kubectl scale deployment loadgen --replicas 4
직접 웹 애플리케이션을 조정할 수 있습니다. 하지만 loadgen 앱을 사용하면 웹과 loadgen 애플리케이션에 적용된 서로 다른 taint, 톨러레이션(toleration), nodeSelector 설정이 어떤 예약된 노드에 어떠한 영향을 미치는지 알 수 있습니다.
- 포드를 실행 중인 노드를 표시하도록 넓은 출력 형식을 사용하여 포드 목록을 가져옵니다.
kubectl get pods -o wide
이를 통해 loadgen 앱이 default-pool
노드에서만 실행 중이고, 웹 앱은 temp-pool-1
의 선점형 노드에서만 실행 중임을 알 수 있습니다.
taint 설정으로 인해 포드가 선점형 노드에서 실행되지 못하기 때문에 loadgen 애플리케이션은 기본 풀에서만 실행됩니다. 톨러레이션 설정으로 인해 웹 애플리케이션이 선점형 노드에서 실행 가능하기 때문에 nodeSelector가 강제로 웹 애플리케이션 포드를 이러한 노드에서 실행시킵니다.
NAME READY STATUS [...] NODE
Loadgen-x0 1/1 Running [...] gke-xx-default-pool-y0
loadgen-x1 1/1 Running [...] gke-xx-default-pool-y2
loadgen-x3 1/1 Running [...] gke-xx-default-pool-y3
loadgen-x4 1/1 Running [...] gke-xx-default-pool-y4
web-x1 1/1 Running [...] gke-xx-temp-pool-1-z1
web-x2 1/1 Running [...] gke-xx-temp-pool-1-z2
web-x3 1/1 Running [...] gke-xx-temp-pool-1-z3
web-x4 1/1 Running [...] gke-xx-temp-pool-1-z4
실습 종료하기
실습을 완료하면 실습 종료를 클릭합니다. Google Cloud Skills Boost에서 사용된 리소스를 자동으로 삭제하고 계정을 지웁니다.
실습 경험을 평가할 수 있습니다. 해당하는 별표 수를 선택하고 의견을 입력한 후 제출을 클릭합니다.
별점의 의미는 다음과 같습니다.
- 별표 1개 = 매우 불만족
- 별표 2개 = 불만족
- 별표 3개 = 중간
- 별표 4개 = 만족
- 별표 5개 = 매우 만족
의견을 제공하고 싶지 않다면 대화상자를 닫으면 됩니다.
의견이나 제안 또는 수정할 사항이 있다면 지원 탭을 사용하세요.
Copyright 2020 Google LLC All rights reserved. Google 및 Google 로고는 Google LLC의 상표입니다. 기타 모든 회사명 및 제품명은 해당 업체의 상표일 수 있습니다.