<0> 테스트 준비 # EKS 생성 하자~ 1 맨 아래 cloudformation 파일에서 0 kops-ec2-----.yml 파일 다운로드 2 aws 로그인 서울리전 cloudformaion 실행 update1 ec2 키페어 선택 다음 > 다음 > 완료 3 # access-key, secret-key 준비 # 새텝에서 보기 iam > 사용자 > 사용자 클릭 > 보안 자격증명 > 액세스 키 > 액세스 키 만들기 > Command Line Interface(CLI) 위의 권장 사항을 이해했으며 액세스 키 생성을 계속하려고 합니다. 체크 다음 > 설명 태그 값 은 빈 킨 \(디폴트) > 액세스 키 만들기 액세스 키 , 비밀 액세스 키 노트패드에 복사 .csv 파일 다운로드 클릭 > 완료 4 # ec2 로그인 [root@kops-ec2 ~]# aws configure AWS Access Key ID [None]: AKIA2ESLM AWS Secret Access Key [None]: 37MXcJ Default region name [None]: ap-northeast-2 Default output format [None]: <엔터> aws s3 ls 버킷 리스트 들이 나오면 정상이다. 조회가 안되면 aws configure 안된것이다. # 참고 - 기존 삭제 # 기존 클러스터 삭제 완료 여부 확인 명령어 # 아래 처럼 나오면 생성 가능1 clear aws cloudformation describe-stacks --stack-name eksctl-free-vpc-cluster-cluster --region ap-northeast-2 aws: [ERROR]: An error occurred (ValidationError) when calling the DescribeStacks operation: Stack with id eksctl-free-vpc-cluster-cluster does not exist Additional error details: Type: Sender # 아래 처럼 나오면 생성 가능2 aws cloudformation describe-stacks --stack-name eksctl-free-vpc-cluster-cluster --region ap-northeast-2 --query "Stacks[0].StackStatus" aws: [ERROR]: An error occurred (ValidationError) when calling the DescribeStacks operation: Stack with id eksctl-free-vpc-cluster-cluster does not exist Additional error details: Type: Sender # 아래는 리눅스에서 EKS 생성하는 명령어. # 설명 cat < eks-freetier-setup.yaml apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: free-vpc-cluster region: ap-northeast-2 version: "1.34" vpc: clusterEndpoints: publicAccess: true privateAccess: true nat: gateway: Single # 비용 절감을 위해 NAT 게이트웨이를 1개만 생성 (중요!) managedNodeGroups: - name: standard-nodes # --- 인스턴스 타입 선택 가이드 --- # 1. t3.micro : 프리티어 대상 (단, K8s 시스템 Pod 실행 시 리소스가 매우 부족할 수 있음) # 2. t3.small : 가성비 추천 (시스템 안정성 확보) # 3. c7i-flex.large (2cpu/4gb) : 연산 위주 # 4. m7i-flex.large (2cpu/8gb) : 메모리 여유 instanceType: m7i-flex.large minSize: 1 maxSize: 10 desiredCapacity: 3 privateNetworking: true iam: withAddonPolicies: imageBuilder: true autoScaler: true cloudWatch: true # 필수 애드온만 설치 addons: - name: vpc-cni - name: coredns - name: kube-proxy EOF # 클러스터 생성 시작 eksctl create cluster -f eks-freetier-setup.yaml --------- # eksctl 로 쿠버네티스 생성시 cloudformation을 이용하여 생성하게 된다. (15분) kubectl get nodes kubectl get no k get no # 현재 노드수 확인 몇개?? # 참고 ------ 노드 늘리기 # 노드 수를 5개로 늘릴 경우 eksctl scale nodegroup \ --cluster=free-vpc-cluster \ --name=standard-nodes \ --nodes=5 \ --nodes-min=1 \ --nodes-max=10 ----------------- <1> 모니터링 설정 1 # 터미널 2 watch -d kubectl get no,deployment,rs,pods,svc watch -d kubectl get no,deploy,rs,pods,svc watch -d kubectl get no,deploy,rs,po,svc <2> 디플로이먼트 업데이트 테스트 - 배포 테스트 1 # 터미널 3 # 웹서비스 배포 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 # watch에서 오류 발생중!!! 2 2단계: 장애 상황 모니터링 업데이트 상태와 포드 상태를 확인합니다. 아마 ImagePullBackOff나 ErrImagePull 에러가 뜰 거예요. # 1. 롤아웃 진행 중단 확인 (여기서 멈춰있을 겁니다) - 상태 확인 명령어 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 deployment.apps/web-demo rolled back 4단계: 히스토리로 "범인" 찾기 어떤 리비전에서 에러가 났었는지 히스토리를 확인합니다. kubectl rollout history deployment/web-demo kubectl annotate deployment/web-demo kubernetes.io/change-cause="v1으로 롤백 완료" (top1016@free-vpc-cluster:N/A) [root@kops-ec2 ~]# kubectl rollout history deployment/web-demo deployment.apps/web-demo REVISION CHANGE-CAUSE 2 v1으로 업데이트함 3 v1으로 롤백 완료 실전 분석: 왜 롤백이 중요한가요? 쿠버네티스의 롤링 업데이트 전략 덕분에, 잘못된 이미지를 배포해도 모든 포드가 한꺼번에 죽지 않습니다. 1. 새 포드가 에러가 나면 기존 포드 중 일부는 삭제되지 않고 버티며 서비스를 유지합니다. 2. 이때 우리가 undo 명령어를 내리면 쿠버네티스는 에러가 난 새 포드를 즉시 삭제하고, 기존 버전의 포드 개수를 다시 원래대로 복구합니다. <4> 특정 버전으로 롤백 하기 1 1단계: 복구 가능한 버전(Revision) 목록 확인 먼저 어떤 세이브 포인트들이 남아 있는지 확인해야 합니다 # 히스토리 확인 kubectl rollout history deployment/web-demo 출력 결과의 REVISION 열에 적힌 숫자(1, 2, 3...)를 확인하세요. 각 숫자가 하나의 버전을 의미합니다. 2 2단계: 특정 버전의 상세 정보 확인 (선택 사항) 만약 REVISION 1이 어떤 이미지였는지 기억이 안 난다면, 되돌리기 전에 미리 내용을 들여다볼 수 있습니다. # 리비전 2번의 상세 내용을 출력 kubectl rollout history deployment/web-demo --revision=2 여기서 Image: 항목을 보고 "아, 이게 내가 찾던 버전이 맞구나!"라고 확신할 수 있습니다. top1016@free-vpc-cluster:N/A) [root@kops-ec2 ~]# kubectl rollout history deployment/web-demo --revision=2 deployment.apps/web-demo with revision #2 Pod Template: Labels: app=web pod-template-hash=67b899b74d Annotations: kubernetes.io/change-cause: v1으로 업데이트함 Containers: nginx: Image: nginx:v-error-test Port: Host Port: Requests: cpu: 500m memory: 256Mi Environment: Mounts: Volumes: Node-Selectors: Tolerations: kubectl rollout history deployment/web-demo --revision=2 kubectl rollout history deployment/web-demo --revision=3 3 kubectl set image deployment/web-demo nginx=nginx:latest kubectl rollout history deployment/web-demo kubectl annotate deployment/web-demo kubernetes.io/change-cause="last 완료" kubectl rollout history deployment/web-demo kubectl set image deployment/web-demo nginx=nginx:1.20 kubectl rollout history deployment/web-demo kubectl annotate deployment/web-demo kubernetes.io/change-cause="1.20" kubectl rollout history deployment/web-demo # 4번의 버전을 확인한다. 1.20 버전이다. kubectl rollout history deployment/web-demo --revision=4 kubectl rollout history deployment/web-demo --revision=2 3단계: 리비전 3번으로 정밀 타격 롤백 이제 web-demo 디플로이먼트를 리비전 2번 상태로 강제 복구합니다 --to-revision=2 kubectl rollout undo deployment/web-demo --to-revision=2 4 다시 히스토리를 확인해 보세요. kubectl rollout history deployment/web-demo # 이미 배포된 히스토리에 메모 남기기 kubectl annotate deployment/web-demo kubernetes.io/change-cause="v1 stable build" kubectl rollout history deployment/web-demo kubectl rollout undo deployment/web-demo --to-revision=4 <5> 서비스(Service)를 통해 이 앱을 외부로 노출 # 80번 포트로 들어오는 요청을 포드의 80번 포트로 전달하는 로드밸런서 생성 - 2분 걸림 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.22 --record 최근 Kubernetes 버전에서는 --record 옵션이 deprecated 되었고 제거되었습니다. 즉 기본 제공 옵션 아님 사용하지 않는 것이 권장 공식 권장 방법은 직접 annotation을 추가하는 것입니다. (top1016@free-vpc-cluster:default) [root@kops-ec2 ~]# kubectl set image deployment/web-demo nginx=nginx:1.22 --record Flag --record has been deprecated, --record will be removed in the future deployment.apps/web-demo image updated kubectl annotate deployment web-demo \ kubernetes.io/change-cause="update nginx to 1.21" # 이미지 버전 확인 kubectl describe deployment web-demo | grep Image 2 # 배포 성공 확인 kubectl rollout status deployment/web-demo kubectl set image deployment/web-demo nginx=nginx:latest --------------------------------------------------------------------------------- 3 watch -d kubectl get po,no,deploy,rs,svc 롤링 업데이트 전략 설정 (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.22 kubectl set image deployment/web-demo nginx=nginx:1.23 kubectl annotate deployment/web-demo kubernetes.io/change-cause="123 완료" kubectl rollout history deployment/web-demo 7 반대의 상황 실습 (자원 절약 모드) 이번에는 추가 노드 자원을 쓰지 않고, 기존 포드를 먼저 죽이면서 업데이트하는 방식입니다. kubectl patch deployment web-demo -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge": "0%", "maxUnavailable": "50%"}}}}' kubectl patch deployment web-demo -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge": "0%", "maxUnavailable": "100%"}}}}' The Deployment "web-demo" is invalid: spec.strategy.rollingUpdate.maxUnavailable: Invalid value: "500%": must not be greater than 100% kubectl rollout history deployment/web-demo ------- # 현재 정책 확인 kubectl describe deployment web-demo kubectl get deployment web-demo -o yaml Replicas: 5 desired | 5 updated | 5 total | 5 available | 0 unavailable NewReplicaSet: web-demo-6f9878fb8f (5/5 replicas created) <7> 삭제 1 # 1. 로드밸런서 서비스 삭제 (AWS ELB 제거) kubectl delete svc web-demo-service # 2. 디플로이먼트 삭제 (포드 및 레플리카셋 제거) kubectl delete deployment web-demo 2 # 서비스가 안 지워질 때 kubectl patch svc web-demo-service -p '{"metadata":{"finalizers":null}}' --type merge 3 eksctl delete cluster --name free-vpc-cluster --region ap-northeast-2 <8> 다시 테스트 정리 전체적인 흐름은 [배포] → [이미지 업데이트 1] → [이미지 업데이트 2] → [상태 확인] 순서입니다. 1 # 예시: nginx 1.14 버전으로 배포 시작 kubectl create deployment web-demo --image=nginx:1.14 2 kubectl set image deployment/web-demo nginx=nginx:1.20 확인 kubectl describe deployment web-demo | grep Image 3 kubectl set image deployment/web-demo nginx=nginx:1.19.1 kubectl rollout status deployment/web-demo kubectl describe deployment web-demo | grep Image kubectl rollout history deployment/web-demo kubectl rollout undo deployment/web-demo kubectl describe deployment web-demo | grep Image 4 kubectl get pods -o wide # 이후 특정 포드 이름을 골라 상세 확인 kubectl describe pod/[포드_이름] | grep "Image:" kubectl describe pod/web-demo-544965c55-755b9 | grep "Image" 실습 종료