<1> 모니터링 설정 1 # 터미널 1 k ns default watch -d kubectl get no,deployment,rs,pods,svc watch -d kubectl get no,nodepool,ec2nodeclass,deployment,rs,pods,svc 2 # 터미널 2 <2> 디플로이먼트 업데이트 테스트 1 # 기존 설정 삭제 kubectl delete ec2nodeclass default kubectl patch ec2nodeclass default --type merge -p '{"metadata":{"finalizers":null}}' kubectl delete nodepool default --ignore-not-found 2 # 카펜터 재 설정 cat < rollout undo로 긴급 복구 1 일부러 없는 이미지 이름(예: nginx:error-test)으로 업데이트를 해서 ImagePullBackOff 에러를 낸 다음, rollout undo로 긴급 복구하는 실 2 1단계: 고의적인 장애 발생 (Update) 존재하지 않는 이미지(nginx:v-error-test)로 이미지를 교체해 보세요. kubectl set image deployment/web-demo nginx=nginx:v-error-test 2 2단계: 장애 상황 모니터링 업데이트 상태와 포드 상태를 확인합니다. 아마 ImagePullBackOff나 ErrImagePull 에러가 뜰 거예요. # 1. 롤아웃 진행 중단 확인 (여기서 멈춰있을 겁니다) kubectl rollout status deployment/web-demo (arn:aws:eks:ap-northeast-2:697016550159:cluster/free-vpc-cluster:N/A) [root@kops-ec2 ~]# kubectl rollout status deployment/web-demo Waiting for deployment "web-demo" rollout to finish: 3 out of 5 new replicas have been updated... # 2. 포드 에러 확인 kubectl get pods 3 3단계: 긴급 복구 (Rollback) 서비스를 정상화하기 위해 가장 안정적이었던 이전 버전으로 되돌립니다. kubectl rollout undo deployment/web-demo 4단계: 히스토리로 "범인" 찾기 어떤 리비전에서 에러가 났었는지 히스토리를 확인합니다. kubectl rollout history deployment/web-demo s:ap-northeast-2:697016550159:cluster/free-vpc-cluster:N/A) [root@kops-ec2 ~]# kubectl rollout history deployment/web-demo deployment.apps/web-demo REVISION CHANGE-CAUSE 3 5 v1으로 롤백 완료 6 v1으로 롤백 완료 실전 분석: 왜 롤백이 중요한가요? 쿠버네티스의 롤링 업데이트 전략 덕분에, 잘못된 이미지를 배포해도 모든 포드가 한꺼번에 죽지 않습니다. 1. 새 포드가 에러가 나면 기존 포드 중 일부는 삭제되지 않고 버티며 서비스를 유지합니다. 2. 이때 우리가 undo 명령어를 내리면 쿠버네티스는 에러가 난 새 포드를 즉시 삭제하고, 기존 버전의 포드 개수를 다시 원래대로 복구합니다. <4> 특정 버전으로 롤백 하기 1 1단계: 복구 가능한 버전(Revision) 목록 확인 먼저 어떤 세이브 포인트들이 남아 있는지 확인해야 합니다 kubectl rollout history deployment/web-demo kubectl rollout history deployment/web-demo deployment.apps/web-demo REVISION CHANGE-CAUSE 3 5 v1으로 롤백 완료 6 v1으로 롤백 완료 출력 결과의 REVISION 열에 적힌 숫자(1, 2, 3...)를 확인하세요. 각 숫자가 하나의 버전을 의미합니다. 2 2단계: 특정 버전의 상세 정보 확인 (선택 사항) 만약 REVISION 1이 어떤 이미지였는지 기억이 안 난다면, 되돌리기 전에 미리 내용을 들여다볼 수 있습니다. # 리비전 1번의 상세 내용을 출력 kubectl rollout history deployment/web-demo --revision=6 여기서 Image: 항목을 보고 "아, 이게 내가 찾던 버전이 맞구나!"라고 확신할 수 있습니다. deployment.apps/web-demo with revision #6 Pod Template: Labels: app=web pod-template-hash=7b4b9c9594 Annotations: kubernetes.io/change-cause: v1으로 롤백 완료 Containers: nginx: Image: nginx:1.21 Port: Host Port: Requests: cpu: 500m memory: 256Mi Environment: Mounts: Volumes: kubectl rollout history deployment/web-demo --revision=5 3 kubectl set image deployment/web-demo nginx=nginx:latest kubectl rollout history deployment/web-demo root@kops-ec2 ~]# kubectl rollout history deployment/web-demo deployment.apps/web-demo REVISION CHANGE-CAUSE 5 v1으로 롤백 완료 6 v1으로 롤백 완료 7 v1으로 롤백 완료 kubectl rollout history deployment/web-demo --revision=7 deployment.apps/web-demo with revision #7 Pod Template: Labels: app=web pod-template-hash=f6cf96db5 Annotations: kubernetes.io/change-cause: v1으로 롤백 완료 Containers: nginx: Image: nginx:latest Port: Host Port: Requests: cpu: 500m memory: 256Mi Environment: Mounts: Volumes: kubectl set image deployment/web-demo nginx=nginx:1.20 kubectl rollout history deployment/web-demo kubectl rollout history deployment/web-demo --revision=7 3단계: 리비전 1번으로 정밀 타격 롤백 이제 web-demo 디플로이먼트를 리비전 7번 상태로 강제 복구합니다 kubectl rollout undo deployment/web-demo --to-revision=7 (arn:aws:eks:ap-northeast-2:697016550159:cluster/free-vpc-cluster:N/A) [root@kops-ec2 ~]# kubectl rollout undo deployment/web-demo --to-revision=7 deployment.apps/web-demo rolled back 4 다시 히스토리를 확인해 보세요. kubectl rollout history deployment/web-demo # 업데이트할 때 메모 남기기 kubectl set image deployment/web-demo nginx=nginx:1.20 --record kubectl set image deployment/web-demo nginx=nginx:1.19.1 --record # 이미 배포된 히스토리에 메모 남기기 kubectl annotate deployment/web-demo kubernetes.io/change-cause="v1 stable build" kubectl rollout history deployment/web-demo <5> 서비스(Service)를 통해 이 앱을 외부로 노출 # 80번 포트로 들어오는 요청을 포드의 80번 포트로 전달하는 로드밸런서 생성 kubectl expose deployment web-demo --type=LoadBalancer --port=80 --target-port=80 --name=web-demo-service # 기존 서비스 삭제 kubectl delete svc web-demo-service # 어노테이션을 포함하여 다시 생성 cat < 롤링 업데이트 1 # web-demo 롤링 업데이트 테스트 kubectl set image deployment/web-demo nginx=nginx:1.21 --record 2 kubectl rollout status deployment/web-demo 3 kubectl rollout pause deployment/web-demo # 일시 중지 kubectl rollout resume deployment/web-demo # 재개 4 롤링 업데이트 전략 설정 (YAML 수정) maxSurge: 50%: 업데이트 중 전체 개수의 50%만큼 포드를 더 띄울 수 있습니다. (빠른 업데이트) maxUnavailable: 0: 업데이트 중에도 기존 포드 5대는 무조건 유지합니다. (안정성 극대화) kubectl patch deployment web-demo -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge": "50%", "maxUnavailable": "0%"}}}}' maxUnavailable: 0 설정 때문에 기존 포드는 하나도 죽지 않고 먼저 새 포드가 2~3대(50%) 먼저 생성되는 것을 볼 수 있습니다 5 2. 업데이트 실행 및 실시간 감시 새 터미널을 열어 아래 명령어를 먼저 실행하여 감시를 시작하세요. # 다른 터미널에서 실행 kubectl get pods -w 6 kubectl set image deployment/web-demo nginx=nginx:1.23 7 반대의 상황 실습 (자원 절약 모드) 이번에는 추가 노드 자원을 쓰지 않고, 기존 포드를 먼저 죽이면서 업데이트하는 방식입니다. kubectl patch deployment web-demo -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge": "0%", "maxUnavailable": "50%"}}}}' <7> 삭제 1 # 1. 로드밸런서 서비스 삭제 (AWS ELB 제거) kubectl delete svc web-demo-service # 2. 디플로이먼트 삭제 (포드 및 레플리카셋 제거) kubectl delete deployment web-demo # 3. (혹시 남아있다면) Karpenter 설정 삭제 kubectl delete nodepool default --ignore-not-found kubectl delete ec2nodeclass default --ignore-not-found 2 # 서비스가 안 지워질 때 kubectl patch svc web-demo-service -p '{"metadata":{"finalizers":null}}' --type merge # Karpenter 리소스가 안 지워질 때 kubectl patch nodepool default -p '{"metadata":{"finalizers":null}}' --type merge kubectl patch ec2nodeclass default -p '{"metadata":{"finalizers":null}}' --type merge 3 eksctl delete cluster --name free-vpc-cluster --region ap-northeast-2