[Sprint] 새 버전이 망가졌어요

# 학습 목표

  • 파드 명세를 작성할 수 있다.
  • 디플로이먼트 명세를 작성할 수 있다.
  • 서비스를 이용해 파드를 노출할 수 있다.
  • kubectl apply 명령을 이용해 리소스를 생성할 수 있다.
  • 디플로이먼트 명세를 수정(또는 재작성)하여 새로운 버전을 배포할 수 있다.
  • kubectl rollout 명령을 이용해 롤링 배포 현황을 확인할 수 있다.
  • 새로운 버전에 문제가 발생했을 때 롤백할 수 있다.

# 해결 과제

🏁 이모지는 해당 STEP의 목표 ✅ 해당 STEP에서 잊지 말고 진행

STEP 0: 복습

Docker Hub에 sebcontents/cozserver:1.0이라는 이름의 파드가 존재합니다. CozServer는 컨테이너 안에서 8080 포트를 통해 열려 있습니다.

도커를 복습할 겸, 도커를 이용해 한번 열어봅시다.

docker run -p 80:8080 sebcontents/cozserver:1.0

연습을 마쳤으면, 컨테이너는 삭제해도 좋습니다.

STEP 1: 파드

이 단계에서는 파드를 수동으로 만들어볼 것입니다. 하지만 보통 파드는 하나하나 만들지 않으므로, "이렇게 만들 수도 있다"라는 것을 간단하게 배우고 넘어가는 정도의 의미를 갖습니다.

sebcontents/cozserver:1.0 이미지를 바탕으로 파드를 만들어봅시다.

🏁 cozserver-pod.yaml 에 파드 명세를 적고, 파드가 kubectl에 의해 실행되어야 합니다. ✅ 명세를 성공적으로 만들었다면 git commit을 진행하세요.

STEP 2: 디플로이먼트를 이용한 1.0 배포

(STEP 1에서 만든 파드는 더 이상 사용하지 않으므로 삭제해 줍시다.)

앞서 개별 파드를 yaml로 작성된 명세를 통해 생성했습니다. 그러나, 파드는 확장성을 바탕으로 가용성을 위해 언제든 대체될 수 있습니다. 따라서 디플로이먼트로 CozServer를 구성하는 것이 바람직합니다.

1.0 이미지를 바탕으로 파드를 디플로이먼트를 생성해 봅시다.

🏁 cozserver-deployment-v1.yaml 에 디플로이먼트 명세를 적고, kubectl에 의해 실행 ✅ 명세를 성공적으로 만들었다면 git commit을 진행하세요.

배포 이력을 남기기 위해 --record 옵션을 추가해서 배포합시다. (deprecated 된 옵션이지만, 아직 대안이 없으므로 그냥 사용합니다.)

kubectl apply -f cozserver-deployment-v1.yaml --record

STEP 3: 서비스

아무리 클러스터 내에 파드를 만든다 해도, 노출시키지 않으면 소용이 없습니다. 서비스 리소스를 만들어서 파드를 외부로 노출시켜줘야 합니다.

이때 서비스 리소스의 타입은 LoadBalancer를 사용할 것입니다. 앞서 안내한 대로, 컨테이너 포트는 8080을 사용합니다.

🏁 cozserver-service.yaml 에 서비스 명세를 적고, kubectl에 의해 실행되어야 합니다. ✅ 명세를 성공적으로 만들었다면 git commit을 진행하세요.

로컬 환경에서 테스트하기 위해서는 터널이 필요합니다. minikube tunnel 명령을 이용해 터널을 뚫어줍시다.

http://localhost를 이용해 다음 그림과 같이 접속이 된다면 성공입니다.

STEP 4: 2.0 배포, 롤아웃

기존의 cozserver-deployment-v1.yaml를 그대로 복사해서 cozserver-deployment-v2.yaml라는 이름으로 새로 생성합시다.

이제, 1.0 대신 새로운 파일을 이용해 기존의 CozServer 1.0 버전이 아닌, 2.0 버전을 롤링 업데이트를 통해 배포할 것입니다.

🏁 cozserver-deployment-v2.yaml 에 2.0 버전을 이용한 디플로이먼트 명세를 적고, kubectl에 의해 적용되어야 합니다.배포 전략은 RollingUpdate를 사용할 것입니다.sebcontents/cozserver:2.0 이미지를 사용합니다.

kubectl get all 명령어를 통해 적용할 때, 배포되는 과정을 꼭 확인해 보세요. 구버전의 파드가 삭제되고, 새로운 버전의 파드가 생기는 것을 확인할 수 있어야 합니다.

반드시 다음 과정을 확인해 보세요.

  • Q. 레플리카셋은 어떻게 바뀌나요?
  • Q. DESIRED, CURRENT, READY의 의미는 무엇인가요?
kubectl apply -f cozserver-deployment-v2.yaml --record

다음 그림과 같이 새로운 버전이 배포되었다면 성공입니다.

마지막으로 롤아웃 히스토리를 확인해 봅시다. 다음 명령을 통해 이력을 확인할 수 있습니다.

kubectl rollout history deployment cozserver

✅ 명세를 성공적으로 만들었다면 git commit을 진행하세요.

STEP 5: 3.0 배포와 2.0으로의 롤백

3.0 배포를 위해서 cozserver-deployment-v3.yaml 에 3.0 버전을 이용한 디플로이먼트 명세를 적고, kubectl을 통해 배포를 시도합시다. (이미지 태그만 바꿔주어도 충분합니다)

kubectl get all 명령을 통해 적용 후 현황과, 롤아웃 히스토리를 확인해 보세요.

이제 http://localhost 요청을 통해 3.0 버전을 확인해 보세요. 몇 번 요청을 시도하면, 처음에는 잘 되는 것 같아 보입니다.

그러나, 요청을 여러 번(정확히는 파드 당 다섯 번) 이상 보내면 파드에서 HTTP 500 에러를 내뱉습니다.

현업에서도 비슷한 경우가 매우 많습니다. 배포를 하고 나면, 처음에는 그럴싸하게 잘 된 것 같아 보이지만, 사용하다 보면 버그로 인해 internal 에러를 마주치게 되는 경우가 허다합니다.

이처럼 새 버전에 무언가 문제가 발생한다면, 이전 버전으로 롤백을 해야 합니다.

$ kubectl rollout history deployment cozserver
deployment.apps/cozserver
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=cozserver-deployment-v1.yaml --record=true
2         kubectl apply --filename=cozserver-deployment-v2.yaml --record=true
3         kubectl apply --filename=cozserver-deployment-v3.yaml --record=true

롤아웃 히스토리에 따르면, 2번 리비전까지는 정상적으로 작동했습니다. 2번으로 롤백을 시도해야 합니다.

🏁 공식 문서를 이용해 롤백을 시도하고, 터미널 입력 및 출력 결과를 rollback-log.txt 파일에 복사/붙여 넣기 해서 넣어주세요. 다음 세 가지가 반드시 들어가야 합니다. a. 롤백을 시도하기 전의 롤아웃 히스토리 b. 롤백을 시도한 결과 c. 롤백 후 롤아웃 히스토리

rollback-log.txt의 형식은 다음과 같아야 합니다.

$ 1번입력
1번출력

$ 2번입력
2번출력

$ 3번입력
3번출력

🏁 cozserver-deployment-v3.yaml 에 3.0 버전을 이용한 디플로이먼트 명세를 적고, kubectl에 의해 적용되어야 합니다.sebcontents/cozserver:3.0 이미지를 사용합니다. ✅ 명세를 성공적으로 만들고, 로그까지 잘 채워 넣었다면 git commit을 진행하세요.


# 실습 자료

sprint-k8s-rollout


# 과제 항목별 진행 상황

STEP 0: 복습

PS C:> docker run -p 80:8080 sebcontents/cozserver:1.0
Unable to find image 'sebcontents/cozserver:1.0' locally
1.0: Pulling from sebcontents/cozserver
59bf1c3509f3: Pull complete
683dd8c3cc08: Pull complete
ae5b2724f19b: Pull complete
39190df3f477: Pull complete
ace5267edc85: Pull complete
054a12501f62: Pull complete
5012be8966ae: Pull complete
00df233fc0a3: Pull complete
Digest: sha256:b22208c1daa48966da36df4bcd365167b7585b8708d2a669c016cb2b9049eb11
Status: Downloaded newer image for sebcontents/cozserver:1.0
Example app listening at http://localhost:8080
[v1] running in pod ::ffff:172.17.0.1

STEP 1: 파드

apiVersion: v1
kind: Pod #Examples: Pod, ReplicationController, Service, Namespace, Node.
metadata:
  name: cozserver #namespace
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: sebcontents/cozserver:1.0
    resources:
      limits:
        memory: "128Mi"
        cpu: "500m"
    ports:
      - containerPort: 80

STEP 2: 디플로이먼트를 이용한 1.0 배포

cozserver-deployment-v1.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: cozserver
  name: cozserver-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: cozserver
  template:
    metadata:
      labels:
        app: cozserver
    spec:
      containers:
        - image: sebcontents/cozserver:1.0
          name: cozserver
          ports:
            - containerPort: 8080

디플로이먼트 생성 record 옵션을 부여하여, 히스토리를 기록한다.

$ kubectl apply -f ./cozserver-deployment-v1.yaml --record

STEP 3: 서비스

cozserver-service.yaml

apiVersion: v1
kind: Service
metadata:
  labels:
    app: cozserver
  name: cozserver-service
spec:
  type: LoadBalancer
  selector:
    app: cozserver
  ports:
    - port: 80
      targetPort: 8080

서비스 생성

$ kubectl apply -f ./cozserver-service.yaml

접속 확인

$ minikube tunnel

STEP 4: 2.0 배포, 롤아웃

cozserver-deployment-v2.yaml sebcontents/cozserver 이미지 버전을 2.0 으로 변경

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: cozserver
  name: cozserver-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: cozserver
  template:
    metadata:
      labels:
        app: cozserver
    spec:
      containers:
        - image: sebcontents/cozserver:2.0
          name: cozserver
          ports:
            - containerPort: 8080

디플로이먼트 업데이트

kubectl apply -f ./cozserver-deployment-v2.yaml --record

rollout history 확인

$ kubectl rollout history deployment cozserver-deployment

접속 확인

$ minikube tunnel

STEP 5: 3.0 배포와 2.0으로의 롤백

cozserver-deployment-v3.yaml sebcontents/cozserver 이미지 버전을 3.0 으로 변경

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: cozserver
  name: cozserver-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: cozserver
  template:
    metadata:
      labels:
        app: cozserver
    spec:
      containers:
        - image: sebcontents/cozserver:3.0
          name: cozserver
          ports:
            - containerPort: 8080

디플로이먼트 업데이트

kubectl apply -f ./cozserver-deployment-v3.yaml --record

접속 확인 – 에러 발생

$ minikube tunnel

디플로이먼트 롤백 정상 작동했던 revision 번호를 사용하여 롤백 진행

$ kubectl rollout undo deploy cozserver-deployment --to-revision=3

rollout history 확인

$ kubectl rollout history deployment cozserver-deployment

접속 확인

$ minikube tunnel

# TROUBLE SHOOTING LOG

💡 문제 내용

원인

해결 방안


# 피드백

팀원명1팀원명2

#References

https://kubernetes.io/ko/docs/concepts/workloads/controllers/deployment/#디플로이먼트-롤백

Leave a Comment