[프로그래머스] 최종 프로젝트 5주차 회고

Oneik·2024년 5월 25일
0
post-thumbnail

앞으로 최종 프로젝트를 진행하면서 겪었던 일들을 기록하고자 한다

CD 에러 발생

변경되지 않은 main branch의 소스코드가 이미지화 되는 문제 발생

Containers:
  ingame-backend:
    Container ID:   docker://c6ff2a21abc076645c8b4b4354db5cb7ecc2d520894068200ec5d6d20ac966e1
    Image:          ...ecr.ap-northeast-2.amazonaws.com/ingame-be:64db9d62bb446cb76ee7f602a18522b5a495b606

위의 코드는 생성된 Kubernetes pod의 정보인데, image를 보면 정상적으로 ECR의 이미지가 적용된 것을 확인할 수 있다.

즉, ECR의 도커 이미지를 제대로 가져와서 배포했다는 소리다. 그러나 변경된 main 브랜치의 소스코드가 아닌, 이전 코드로 만들어진 image가 배포되는게 문제였다.

확인해보니, CI 작업이 끝나고 바로 바로 CD 작업이 진행되도록 설정한 부분이 문제였다.

해결

// 수정 전
on:
  workflow_run:
    workflows: ['Backend CI']
    types:
      - completed

// 수정 후
on:
  push:
    branches: [main]
    paths:
      - 'server/**'

main 브랜치에 코드가 push될 때 트리거가 발생하도록 수정하였다. 그 결과, 정상적으로 최신 소스코드가 반영된 이미지를 배포할 수 있었다.

고민할 부분

위 그림은 정상적으로 CI/CD 작동하는데 걸린 시간이다.

그러나, 평소 3분밖에 걸리지 않던 것이 Github Actions Runner의 네트워크 연결 장애로 인해 배포 작업이 50분씩 걸리는 문제가 발생했다.

임시 방편으로 Self-hosted Runner를 사용하여 내 컴퓨터의 자원을 사용하도록 구성하였다.

하지만, 이런 문제가 다시 발생할 가능성이 있기 때문에, 다른 배포 도구인 Jenkins를 사용하여 CI/CD를 구축해볼 계획이다. Jenkins는 참고 자료가 많고, 다양한 시각화 플러그인이 존재하기 때문에, 그런 플러그인도 사용해보면 좋을 것 같다.

CloudWatch를 통한 로깅 데이터 모니터링

이전 글에서 요청, 응답과 에러를 로깅하기 위해 Winston 라이브러리를 사용했지만, 배포 환경에서 모니터링하는 부분이 부족했다. 나는 이를 보완하기 위해 CloudWatch를 사용하여 모니터링을 설정하였다.

    const cloudWatchConfig = {
      logGroupName: 'InGame-Logs',
      logStreamName: 'ingame-logger',
      awsRegion: this.configService.get<string>('AWS_REGION'),
      awsAccessKeyId: this.configService.get<string>('AWS_ACCESS_KEY_ID'),
      awsSecretKey: this.configService.get<string>('AWS_SECRET_ACCESS_KEY'),
      jsonMessage: true,
    };

...
    this.logger = winston.createLogger({
      ...
      if (isProduction) {
        this.logger.add(new winstonCloudWatch(cloudWatchConfig));
      }
    }

나는 winston-cloudwatch 라이브러리를 활용하기로 하였고, 위와 같이 CloudWatch에 대한 환경을 설정한 후, production 환경일 때만 CloudWatch에서 모니터링할 수 있도록 설정하였다.

그러나, 문제가 발생했는데 서버 배포는 성공하였으나, 아무리 서버로 요청을 보내봐도 어떤 데이터도 로깅되지 않았다.

NODE_ENV=production 존재하지 않음

kubectl exec -it ingame-be-798df9b775-rdzzw -n ingame -- printenv | grep NODE_ENV

위와 같은 명령어로 pod에서 직접 NODE_ENV 환경 변수가 존재하는지 확인해보니, 어떠한 데이터도 나오지 않았다.

해결

이 문제를 해결하기 위해 백엔드 서버에서 필요한 환경 변수를 구성하는 configmap에 NODE_ENV: production 으로 추가 설정하였다.

환경 변수를 추가 설정해주니, 위처럼 정상적으로 로깅 데이터를 모니터링할 수 있게 되었다.

RefreshToken 저장하기

사용 배경

기존에는 AccessToken만을 사용하여 인증 절차를 거쳤다. 그러다보니 보안적인 측면에서, AccessToken만 사용하는 것은 위험하다고 판단했고, 따라서 RefreshToken을 통해 AccessToken을 갱신하도록 설정했다.

이때, RefreshToken이 유출되었거나 클라이언트가 로그아웃할 때 서버에서 해당 RefreshToken을 무효화할 수 있어야 한다.

그래서 cookie에 담아서 클라이언트에게 보내는 것 뿐만 아니라 서버에서도 저장소에 RefreshToken을 저장해야 한다고 생각했다.

저장 방식

저장 방식으로는 2가지가 존재했는데, RDS에 저장하거나 Redis에 저장하는 방식이었다. 그 중 Redis는 메모리 기반 데이터 저장소로 매우 빠른 읽기 및 쓰기 속도를 제공한다. RefreshToken 검증은 매우 빈번하게 이루어질 수 있고, 또한 TTL(Time To Live)을 설정할 수 있어, RefreshToken의 유효 기간을 자동으로 관리하는 데 매우 편리하다고 생각했다.

또한 프로그래머스에서 AWS ElastiCache Redis를 제공해주기 때문에, RefreshToken을 저장하기 위해 Redis를 부담없이 사용할 수 있었다.

마무리

프로젝트의 정규 기간이 이번주로 마무리되었다. S3를 통해 이미지를 업로드하거나 OAuth를 구현하는 것 같은 추가 작업을 시간 내에 마무리하지 못한 것이 아쉽지만, 우리 팀은 기간이 지나도 추가적으로 고도화 작업을 계속 진행하기로 하였다.

한달이라는 기간이 정말짧게 느껴졌다. 다른 조들의 발표를 보면서 아직도 많이 부족하다는 것을 느꼈고, 더 열심히 노력해야겠다고 다짐하는 계기가 되었다.

목표했던 프로젝트 완성까지 한 발자국 남은 것 같다. 여태까지 잘 해왔던 것처럼 꾸준히 하다 보면 언젠간 해뜰날이 올 것이다.

좀 더 힘내보자! 화이팅!

profile
초보 개발자의 블로그입니다

0개의 댓글

관련 채용 정보