TIL/Project

TIL 2024-12-31 (Trouble Shooting (Team_Flow) )

myoma 2024. 12. 31. 01:40

1) 개요 

  • AWS EC2와 RDS를 활용하여 Spring Boot 애플리케이션을 Docker 기반 CI/CD 파이프라인을 통해 자동 배포하는 프로젝트를 진행하는 과정에서 다양한 문제를 해결해야 했습니다. GitHub Actions를 활용하여 Docker 이미지를 빌드 및 푸시하고, EC2에 배포하여 RDS와 연동하는 방식으로 설계되었습니다. 그러나 배포와 실행 과정에서 여러 트러블이 발생하였고, 이를 해결하기 위해 CI/CD 구성, Docker 및 AWS 서비스와 관련된 다양한 설정 및 작업을 수행했습니다.

 

2) 문제 발생

  • 맨 처음 Dockerhub에 이미지를 저장할 땐 까지 큰 문제가 없었지만 푸쉬를 하여 CD를 진행하는 과정에서 바로 에러가 발생했다.

 

  • deploy-to-ec2를 성공했지만 AWS EC2 ubuntu 서버에서 sudo docker ps 를 진행했지만 exited(1)로 바로 서버가 종료되는 문제가 발생하였다.

 

  • ubuntu 서버에서 sudo docker ps 하여 컨테이너를 작동하는데 성공 후 프로젝트 기능 테스트 중 특정 메서드 기능 시 슬랙 채널에 알람이 가야하는데 가지 않는 문제가 발생하였다.

 

3) 해결

  • 해당 에러는 푸쉬하는 이미지의 이름과 docker 저장소의 이미지 이름이 달라서 발생한 에러인데 Github Action에 Secret 환경 변수를 잘못 입력하여 발생하였다.
  • 기존에 DOCKER_IMAGE_TAG_NAME을 myoma/team-flow를 넣어서 myoma/myoma/... 이런 식으로 이름이 되어서 문제가 발생하였고  DOCKER_IMAGE_TAG_NAME을 team-flow로 바꾸어 해결하였다.

 

  • 이 문제를 해결하기 위해 sudo docker ps -a 를 이용해서 Docker CLI에서 사용되어 모든 컨테이너의 상태를 표시하여 exited 된 컨테이너의 아이디를 확인하여 sudo docker logs <컨테이너 ID> 를 입력하면 해당 컨테이너의 스프링부트 실행 로그를 보여주는데 여기서 에러 메시지들을 확인했다.
  • 첫 에러 : "rg.hibernate.exception.GenericJDBCException: unable to obtain isolated JDBC connection [Access denied for user '${DB_USER}'@'172.31.3.105' (using password: YES)] [n/a]"
    • 위 에러는 변수가 전달되지 않았거나, mysql 사용자 권한 문제거나, 잘못된 비밀번호가 쓰였을 때 나오는 에러였다.
    • 처음엔 권한 문제인 줄 알고 mysql 사용자 권한은 SHOW CRANTS FOR CURRNET USER(); 명령어를 사용하여 권한을 확인하였는데 문제가 없었고 비밀번호가 잘못 쓰였을 경우도 없다고 생각하여 환경 변수 전달을 확인해보았다.

  • 위 두 사진처럼 환경 변수 이름이 달라 Mysql 연결에 계속 실패하고 있었다.
    • 실제로 위 에러를 해결하기 위해 엄청나게 많은 시도를 하였다.
      • ubuntu 환경에 mysql 설치, mysql 로그인 후 해당 컨테이너에 권한 부여, 비밀번호 변경, mysql 백그라운드 실행 등 많은 시행착오를 겪었다.

 

  • 두번째 에러 "o.h.engine.jdbc.spi.SqlExceptionHelper : Communications link failure The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server."
    • 이 오류는 애플리케이션이 DB와 연결을 시도 했지만 실패했을 때 나오는 오류라고 한다.
      • 시도한 방법. 로컬 DB는 정상작동 하는 것을 확인한 후 AWS RDS를 인텔리제이에 연동하려고 하니 연결 실패.
        • RDS를 서브넷, 파라미터 그룹, 보안 설정을 새로하여 만들어도 연결실패.
      •  AWS EC2 와 VPC를 맞춰주고 포트와 퍼블릭 엑세스 등등 설정 후 연결 성공.
      • 하지만 여기서 다른 에러 발생.
      • foreign key ..........." via JDBC [Table 'flowDB.attachment' doesn't exist] 
        • 이 오류는 데이터베이스가 존재하지 않는 테이블에 외래 키를 생성할 때 나타나는 에러였다.
        • ddl-auto 설정을 create로 변경하여 테이블 생성.
  • 세번째 에러 Process completed with exit code 1.
    • Github Action 실행 중 특정 단계가 실패했을 때 나타나는 코드인데 보통 환경 변수 설정이 잘못 되었을 때 발생.
    • DB_URL 환경 변수에 엔드포인트만 넣어야 하는데 DB 전체 URL를 넣어서 문제 발생.
      • DB_URL 환경변수에 엔드포인트만 넣어 해결.
  • 네번째 에러 org.hibernate.exception.JDBCConnectionException: unable to obtain isolated JDBC connection [Public Key Retrieval is not allowed] [n/a]
    • Mysql DB 연결 과정에서 Mysql 8.0+의 기본 인증 방법이 문제를 일으켜 발생.
    • 8.0 이상 버전은 caching_sha2_password 인증 플러그인을 기본값으로 사용하여 Public Key Retrieval 문제가 발생.
      • 해결 방법. 
        • JDBC URL에 allowPublicKeyRetrieval=true 옵션을 추가하여 클라이언트가 MySQL 서버의 공개 키를 요청할 수 있도록 허용하여 문제 해결.
  • 다섯번째 에러 org.springframework.beans.factory.UnsatisfiedDependencyException
    • 해당 에러는 Spring 컨텍스트에서 필요한 Bean을 주입하지 못했을 경우 나타나는 에러이다.
      • 해당 에러가 발생한 AttachmentController 코드를 확인한 결과 코드에 @Bean 어노테이션과 코드에 문제가 없음을 확인.
      • 관련 코드를 모두 확인했지만 큰 문제를 확인하지 못하였으며 로컬 서버로는 구동되는 것을 확인.
      • workflow 파일(CD 파이프라인)을 확인하니 DB만 환경변수를 설정해놓은 것을 확인.

  • 환경 변수 설정이 똑바로 되어있지 않아서 발생한 문제...
  • 슬랙 토큰 또한 환경 변수 설정이 되어있기에 Github Action에 Secret으로 환경 변수 설정.

 

 

  • 로컬 서버와 로컬 DB로 알람 테스트 결과 정상 작동하였으나 서버에서 정상작동 하지 않는 것을 확인.
  • 코드상의 문제보단 알람서비스 로직을 만들 때 채널명의 환경 변수가 제대로 데이터가 들어가지 않았던 것 처럼 EC2 환경 변수 또한 제대로 들어가지 않을 것이라고 생각.
    • docker exec -it <CONTAINER ID> env 명령어를 사용하여 서버에 환경 변수가 제대로 들어갔는지 확인.

  • 환경 변수가 제대로 들어간 것을 확인.
    • 그렇다면 로컬에서 환경 변수 데이터가 ISO_8859_1 형태로 데이터가 들어가서 한글이 라틴어로 변환되어 데이터가 들어가지 않았던 문제와 다른 문제.
    • 기존에 ISO_8859_1 형태의 데이터가 아닌 제대로 된 데이터가 들어갔을 때 기존에 ISO_8859_1 형태를 utf8로 변환하는 코드에서 데이터 입력에 문제 발생.
      • 한글이 포함된 문자열이 ISO_8859_1 인코딩으로 제대로 표현할 수 없어서 깨진 언어로 출력하기에 알람서비스에서 알람을 보낼 채널명을 찾을 수 없었던 것

해결된 코드 모습.

  • 그렇다면 알람서비스의 코드 주석 없이 해결하는 방법은?
    • 알람 서비스 로직에 서버로 데이터를 입력 받았을 때랑 로컬에서 받았을 때의 경우를 나누어 주는 로직 생성
    • 인텔리제이 개인 환경 설정을 바꾸어 properties의 데이터 환경값을 ISO_8859_1 -> utf8 로 수정.

 

 

4)결론

  • AWS EC2, RDS, Docker 기반의 CI/CD 파이프 라인을 이용해서 서버를 배포하는 과정에서 다양한 문제를 마주하며, 이를 해결하기 위해 여러 시도와 다른 문제들을 마주치면서 이번 경험으로 많은 것을 배웠다고 느꼈으며 가장 빈번하게 발생한 문제인 환경 변수와 설정 관리의 중요성을 알게되었다.
  • 외부 서비스(RDS, Slack 등)와 AWS 통합 과정에서 네트워크 설정 문제와 권한 문제 등을 겪었으며 RDS 보안 그룹과 VPC 설정 문제로 EC2에서 RDS에 접근하지 못한 상황에서 여러 블로그와 시도로 성공하여 한단계 성장하였다.
  • 이번 프로젝트는 CI/CD 파이프라인을 직접적으로 구성한 게 아니라 아직 이 부분에 대해선 이해도가 높지 않다.