쿼터에 맞게 업데이트 조정하기

KubernetesBeginner
지금 연습하기

소개

Aster Supply는 평소 카탈로그를 제공하고 있지만 겨울 업데이트는 막혀 있습니다. 네임스페이스에는 일반 운영에 필요한 CPU 요청량은 확보되어 있지만, 롤링 업데이트 중 요청되는 추가 Pod까지 수용할 여유는 없습니다. 고정된 할당량에 맞는 롤아웃 예산을 선택하고, 참조 상점을 계속 실행하며, 업데이트된 카탈로그를 전달합니다.

기본 터미널 경로, 간단한 YAML, Pod, Deployment, Service, 레이블을 이미 알고 있어야 합니다. 이 실습에서는 CPU 요청 단위, ResourceQuota, 업데이트 예산 계산을 설명합니다. 실제 단일 노드 클러스터, 애플리케이션, 상태 검사, 카탈로그 데이터는 준비되어 있습니다. 클러스터 설치, 이미지 빌드, 애플리케이션 프로그래밍은 필요하지 않습니다. 예상 시간에는 읽기와 일반적인 오류에 필요한 시간이 포함되며, 저자가 추정한 시간입니다.

고정 예산에 맞게 업데이트 조정하기

이 단계에서는 CPU 할당량을 늘리거나 참조 상점을 중단하지 않고 Aster Supply의 겨울 카탈로그 업데이트를 완료합니다.

Shop 탭에는 작동하는 카탈로그가 표시됩니다. Stoneware tray를 열어 가격을 확인하고 Back to collection으로 돌아오세요. 현재 Everyday essentials 컬렉션에는 제품 세 개가 있습니다. 요청된 The winter edit는 Amber cup을 추가하고 가격을 변경합니다. Reference 탭을 여세요. Fern Stationery는 기존 카탈로그를 유지해야 하는 별도의 보호 대상 서비스입니다. 해당 Deployment, Service, 원래 Pod는 변경하지 마세요. 그런 다음 Workspace 탭으로 전환하세요.

준비된 클러스터는 실제 단일 노드 Kubernetes입니다. 네임스페이스는 이 과정의 리소스를 묶습니다. ResourceQuota는 해당 네임스페이스에 수용할 수 있는 총 리소스를 제한합니다. 여기서는 CPU requests만 추적합니다. 이는 스케줄링을 위해 예약된 CPU이며, 지출 허용액이나 측정된 CPU 사용량의 상한이 아닙니다. 1000m은 CPU 코어 하나, 40m은 코어의 0.04를 뜻합니다. 메모리는 준비되어 있으며 이 작업에서 쿼터의 병목이 아닙니다.

먼저 쿼터를 읽으세요. --context=labex-v135는 준비된 클러스터를 선택하고, -n shop-quota는 이 과정의 네임스페이스를 선택하며, describe는 객체의 세부 정보를 표시합니다.

kubectl --context=labex-v135 -n shop-quota describe resourcequota shop-budget

requests.cpu에 Used 140m와 Hard 140m가 표시되어야 합니다. 이는 예약된 CPU이며 현재 사용률이 아닙니다. 원래 상점은 여전히 사용할 수 있지만, 시도 중인 업데이트에는 Pod 하나가 더 필요합니다. 사용 가능한 복제본은 readiness 검사를 통과하고 준비된 3초의 최소 준비 기간을 충족한 복제본입니다. Pod를 생성했다는 사실만으로 사용 가능해지지는 않습니다. Deployment와 해당 ReplicaSet을 읽으세요. ReplicaSet은 Deployment 템플릿 하나에 해당하는 Pod를 유지합니다. rs는 이 리소스의 짧은 이름입니다.

kubectl --context=labex-v135 -n shop-quota get deployments,rs,pods

사용 가능한 상점 복제본 세 개와 참조 복제본 하나가 있습니다. 새 상점 ReplicaSet은 Pod를 생성할 수 없습니다. 두 상점 ReplicaSet을 모두 자세히 확인하세요. -l app=shop은 해당 레이블을 선택합니다.

kubectl --context=labex-v135 -n shop-quota describe rs -l app=shop

FailedCreate 또는 ReplicaFailure와 함께 exceeded quota: shop-budget, requested: requests.cpu=40m, used: requests.cpu=140m, limited: requests.cpu=140m를 찾으세요. 이는 생성 승인 거부이며, 해당 새 Pod는 생성되지 않았습니다. 이미 존재하지만 스케줄러가 배치할 수 없는 Pending Pod와는 다릅니다. 쿼터를 변경하거나 참조 워크로드를 제거하지 마세요.

승인된 새 카탈로그와 후보 매니페스트가 이미 제공되어 있습니다. 작업 공간으로 명시적으로 이동하세요. pwd는 현재 디렉터리를 출력하고, ls는 그 안의 항목을 나열합니다.

cd /home/labex/project/shop-update
pwd
ls

approved, starter, tools가 보여야 합니다. cat은 승인된 카탈로그를 출력합니다.

cat approved/catalogue.json

sed -n '1,180p'로 후보 전체를 읽으세요. -n은 일반 출력을 억제하고, p는 1행부터 180행까지 출력합니다. 따옴표로 감싼 범위는 하나의 인수입니다.

sed -n '1,180p' starter/shop.yaml

상점에는 각각 40m을 요청하는 복제본 세 개가 필요합니다. 보호 대상 참조 서비스는 20m을 요청합니다. 변경할 수 있는 것은 spec.strategy.rollingUpdate뿐입니다. 제공된 새 애플리케이션 템플릿, 복제본 수, 리소스, 셀렉터, 상태 검사는 그대로 유지해야 합니다.

예산 항목 요청된 CPU
상점 복제본 세 개 3 × 40m = 120m
보호 대상 참조 서비스 20m
정상 상태 140m
업데이트 중 추가 상점 Pod 하나 총 180m: 140m 초과

롤링 업데이트는 두 값의 균형을 맞춥니다. maxSurge는 원하는 복제본 수를 초과하는 추가 Pod를 허용합니다. maxUnavailable은 원하는 복제본 중 일부가 사용 불가능한 상태가 되는 것을 허용합니다. 여기서 요구 사항은 관찰된 업데이트 중 사용 가능한 상점 복제본을 최소 두 개 유지하는 것입니다. 원하는 복제본 수가 세 개이므로 하나는 일시적으로 사용 불가능해도 되지만, 추가 Pod를 수용할 여유는 없습니다. maxSurge: 0과 maxUnavailable: 1을 선택하세요. 두 값이 모두 0일 수는 없습니다. Recreate, Deployment 삭제, 요청량 감소, 원하는 복제본 수 축소, 쿼터 증가는 이 작업의 범위를 벗어납니다.

편집 가능한 릴리스 디렉터리를 만들고 제공된 후보를 복사하세요. mkdir는 디렉터리를 만들고, cp는 파일을 복사합니다. 제공된 원본은 읽기 전용입니다. chmod u+w는 복사본에 현재 사용자의 쓰기 권한을 추가합니다.

mkdir release
cp starter/shop.yaml release/shop.yaml
chmod u+w release/shop.yaml

이전 시도로 release가 이미 있다면 그대로 유지하고 편집 중인 복사본으로 계속 진행하세요. 경로를 잘못 입력했다면 위의 pwd, ls, 절대 경로 cd 명령을 사용한 뒤 실패한 명령을 반복하세요. 경로를 찾을 수 없다고 VM을 초기화할 필요는 없습니다.

sed -i는 파일을 직접 편집합니다. 각 s/old/new/ 표현식은 표시된 텍스트를 교체합니다. 작은따옴표는 공백과 문장 부호를 하나로 묶어 줍니다. 복사본의 롤아웃 값 두 개만 변경하세요.

sed -i 's/maxSurge: 1/maxSurge: 0/' release/shop.yaml
sed -i 's/maxUnavailable: 0/maxUnavailable: 1/' release/shop.yaml

적용하기 전에 저장된 매니페스트의 앞부분을 읽으세요.

sed -n '1,35p' release/shop.yaml

replicas: 3, type: "RollingUpdate", maxSurge: 0, maxUnavailable: 1이 있어야 합니다. apply -f는 이 파일을 기존 Deployment에 반영하며 Deployment의 식별 정보를 유지합니다. rollout status는 유한한 --timeout으로 새 복제본을 기다립니다.

kubectl --context=labex-v135 apply -f release/shop.yaml
kubectl --context=labex-v135 -n shop-quota rollout status deployment/shop --timeout=180s

deployment "shop" successfully rolled out이 예상됩니다. 컨트롤러는 이전 복제본 하나를 제거하고, 새 복제본 하나를 수용한 뒤, 사용 가능해질 때까지 기다리고 계속 진행할 수 있습니다. 종료 중인 Pod가 잠시 쿼터 계산에 남을 수 있으므로, 일시적인 추가 FailedCreate 이벤트는 자연스럽게 해소될 수 있습니다. 이것이 쿼터를 변경할 이유는 아닙니다. 롤아웃 예산은 종료 중인 모든 프로세스에 대한 절대적인 상한이나 가동 시간 보장이 아닙니다.

잘못된 편집으로 완료되지 않는다면 저장된 파일을 조사하고 두 전략 값을 수정하세요. 성공하지 못한 시도나 관찰 구간 실패에서 복구하려면 원래의 승인된 기준 상태를 다시 적용하고 기다린 뒤 수정된 릴리스를 재시도하세요.

kubectl --context=labex-v135 apply -f approved/shop.yaml
kubectl --context=labex-v135 -n shop-quota rollout status deployment/shop --timeout=180s

제공된 상태 도구의 --wait-baseline 옵션은 새 시도 전에 이전 카탈로그가 정상이라는 최근 관찰을 기다립니다. 기록된 사실을 읽기만 합니다.

./tools/update-status --wait-baseline
kubectl --context=labex-v135 apply -f release/shop.yaml
kubectl --context=labex-v135 -n shop-quota rollout status deployment/shop --timeout=180s

이 복구 명령은 성공하지 못한 시도에만 필요합니다. 제공된 기준 상태는 변경하지 마세요. 읽기 전용 관찰기는 시도들을 보존하고, 기준 상태에서 업데이트까지 이어지는 새로운 완전한 시도를 구분합니다. 복구해도 이전 증거는 지워지지 않습니다.

마지막으로 실제 워크로드와 쿼터를 다시 읽으세요.

kubectl --context=labex-v135 -n shop-quota get deployments
kubectl --context=labex-v135 -n shop-quota describe resourcequota shop-budget

두 Deployment가 모두 사용 가능해야 합니다. 상점은 3/3, 참조 서비스는 1/1이어야 합니다. 이전 Pod가 종료되면 쿼터 사용량은 같은 상한값을 유지하면서 140m으로 돌아옵니다. 다음 단계에서는 사람들이 실제로 받는 카탈로그를 확인합니다.

업데이트된 카탈로그 전달하기

이 단계에서는 새로운 고객 경험을 확인하고 저장된 릴리스 매니페스트와 함께 실제 카탈로그 다운로드를 보관합니다.

Workspace의 /home/labex/project/shop-update에서 시작하세요. 제공된 tools/update-status 명령은 읽기 전용 관찰기가 기록한 실제 API 및 HTTP 샘플을 요약합니다. 앞의 ./는 현재 디렉터리를 기준으로 프로그램을 실행합니다.

./tools/update-status

필수 최소값, 샘플 수, 샘플에서 관찰된 사용 가능한 복제본의 최소 수, 최신 업데이트 상태를 보고합니다. 최소값은 적어도 두 개이고, 완료 시 업데이트되어 사용 가능한 복제본은 세 개여야 합니다. 관찰기는 약 0.5초에 API 소요 시간을 더한 간격으로 샘플링하고, 원래 쿼터와 참조 서비스를 확인하며, 실패를 기록합니다. 제공된 이 관찰기를 계속 실행해 두세요. 관찰기는 샘플 사이에 어떤 일이 있었는지 입증하거나, 프로덕션 가동 시간을 보장하거나, 클러스터를 복구하지 않습니다. 롤아웃 완료 직후의 검사에서는 완료된 샘플 두 개가 기록될 때까지 잠시 기다려야 할 수 있습니다. 시도가 필수 최소값을 위반했거나 관찰에 긴 공백이 있었다면, 수정된 시도 전에 이전 단계에서 배운 기준 상태 복구를 사용하세요.

Shop으로 전환하여 페이지를 새로고침하세요. The winter edit, 제품 네 개, Stoneware tray $20.00, Linen cloth $14.00, Bud vase $24.00, Amber cup $16.00이 표시되어야 합니다. Amber cup을 열어 가격과 Available in store 상태를 확인한 뒤 Back to collection으로 돌아오세요. 이 사이트는 카탈로그이며 온라인 결제 기능은 없습니다.

완성된 컬렉션에는 실제 제품 카드 네 개가 있습니다. 컬렉션 제목과 가격을 이 실행 예제와 비교하세요.

업데이트된 Aster Supply 컬렉션

Download catalogue를 사용하세요. 브라우저에서 다운로드한 catalogue.csv를 여세요. 네 행은 컬렉션 및 사이트에 표시된 이름, 센트 단위 가격, 판매 가능 여부와 일치해야 합니다. 브라우저 다운로드와 터미널 작업 공간은 서로 다른 위치입니다. 다음으로 같은 실제 Service 다운로드를 전달용으로 작업 공간에 저장합니다.

Workspace로 돌아오세요. curl은 URL을 가져옵니다. --fail은 HTTP 오류를 보고하고, --silent --show-error는 오류를 유지하면서 진행률 표시를 숨기며, --output은 응답 바이트를 이름으로 지정한 파일에 씁니다. 127.0.0.1:8081은 원래 상점 Service로 전달하는 준비된 로컬 진입점입니다.

curl --fail --silent --show-error http://127.0.0.1:8081/catalogue.csv --output catalogue.csv
cat catalogue.csv

예상 결과:

id,name,price_cents,available,collection
stone-tray,Stoneware tray,2000,true,The winter edit
linen-cloth,Linen cloth,1400,true,The winter edit
bud-vase,Bud vase,2400,true,The winter edit
amber-cup,Amber cup,1600,true,The winter edit

연결 오류는 로컬 진입점에 연결할 수 없었다는 뜻이고, HTTP 오류는 서버의 응답입니다. 배운 워크로드 및 롤아웃 명령으로 돌아가 현재 상태를 조사하세요. 정적 파일로 대체하거나 준비된 전달 서비스를 변경하지 마세요. 다운로드가 불완전하거나 실수로 덮어썼다면 올바른 카탈로그를 사용할 수 있게 된 뒤 같은 curl 명령을 반복하세요.

Reference를 다시 열고 새로고침하세요. Fern Stationery는 여전히 Desk essentials, Field notebook $9.00, Clay pencil cup $14.00를 보여 주어야 합니다. 제품 하나를 열고 돌아와 실제 링크가 계속 작동하는지 확인하세요.

전달할 결과물은 release/shop.yaml과 실제 catalogue.csv입니다. 완전한 새 릴리스, 변경되지 않은 쿼터, 원래 참조 서비스, 유효하게 관찰된 업데이트 시도가 이를 뒷받침합니다. 제공된 원본, 애플리케이션, Service, 읽기 전용 관찰기를 보존하세요.

요약

실제 ReplicaSet의 쿼터 거부를 롤링 업데이트의 일시적 리소스 요구량과 연결하고, 적절한 추가 생성/사용 불가 예산을 계산하여 할당량을 늘리지 않고 새 카탈로그를 완성했습니다. 보호 대상 참조 서비스도 유지하고, 재사용 가능한 릴리스 매니페스트와 함께 실제 CSV를 전달했습니다.

CPU 요청은 리소스 계산을 나타내며, 측정된 사용률이나 성능 보장이 아닙니다. 시스템에서 얻은 유한한 관찰은 이 과정의 가용성 검사를 뒷받침하지만, 중단 없는 프로덕션 가동 시간을 입증하지는 않습니다. 다른 네임스페이스에서는 전략을 선택하기 전에 여유 할당량과 최소 사용 가능 복제본 수를 모두 다시 계산하세요.