티스토리 뷰

 

우당탕탕 수정광산 백엔드에 합류한 지도 어느덧 5개월째, 좋은 기회로 PL을 하게 되어 전반적인 백엔드 서버 관리부터 어드민 관리자 기능 개발까지 다양한 경험을 할 수 있었다. 좋은 팀원들 덕분에 서버 관리나 에러 슈팅에 대해 많이 배울 수 있었는데, 오늘은 갑작스럽게 발생한 오류를 해결할 수 있는 사람이 나밖에 없어서 혼자 다양한 시도를 하면서 오류를 겨우 해결했다. 오늘 배운 점을 회고로 남겨두고자 한다.

 


 

우선 우리 서버 구성은 다음과 같다. 현재 수정광산 앱에 연결된 서버는 Production서버로 AWS ec2 인스턴스 위에 api, chat, batch, 그리고 admin 도커 컨테이너가 돌아가고 있다. 원래 처음에는 어드민 도커만 올릴 서버 인스턴스를 따로 생성해서 분리했었는데, 서버 비용 부담에 커서 인스턴스 서버를 하나로 줄이고 거기에 도커를 총 네 개 올리도록 구성했다.

 

 

서버 비용 절감을 위해 지난주에 서버 스펙을 기존 t2.medium에서 t2.small로 다운그레이드했는데, 이를 위해 서버를 중지하고 재실행해야 했다. 서버를 재시작한 뒤 네 개의 컨테이너를 빌드하는 젠킨스를 실행했는데, 오늘 보니 도커 네 개 중에 관리자 기능을 담당하는 Admin 컨테이너를 빌드하는 젠킨스에 오류가 발생해 어드민 컨테이너가 작동하지 않고 있었다. 

 

어드민 젠킨스를 계속 다시 돌려봐도 오류는 지속됐다.

 

사실 이 오류에 대해서는 팀원에게 공유받는 내용이 있어서 어렵지 않게 해결할 수 있었다(는 사실 착각이었다.. )

젠킨스 파이프라인 구성 중 Docker Run 명령어가 기존 컨테이너를 제거하는 명령어와 묶여있는데, 만약 현재 돌아가고 있는 컨테이너가 없는 경우 이 부분에서 오류가 발생하는 것이므로 직접 ssh로 서버에 접속해 Docker Run만 실행해 주면 된다고 한다. 

 

그래서 우선 '파이프라인이 이미지 빌드, docker hub에 push까지는 성공했으니 pull 하고 run만 실행해 주면 되겠구나'하고 그렇게 실행했다. 

 

하지만 어드민은 여전히 작동하지 않았다. 분명히 docker ps -a 했을 때 아래와 같이 crystalmine-admin 컨테이너가 잘 작동하고 있는 것을 볼 수 있다. 하지만 포스트맨으로 관리자 로그인을 시도하자 서버에 연결할 수 없다는 오류가 발생했다.

 

 

설상가상으로 서버 인스턴스도 말썽이었다.

 

어드민 도커를 실행하자 도커 4개를 돌리기에는 t2.small의 스펙이 무리였는지 계속해서 서버에 과부하가 걸렸다. 서버 자체가 중지되지는 않았지만 CPU 사용률이 거의 99%까지 치솟으면서 앱이 무한로딩이 걸리는 현상이 반복되었다. 

 

실시간으로 치솟는 그래프를 보며 어질어질했다

t2.medium 사용 당시 CPU 사용률이 3% 미만이라 비용 절감을 위해 다운그레이드를 했는데, 스펙이 반으로 줄어서인지 t2.small에서는 도커 컨테이너를 4개 이상 돌리면 과부하가 발생한다는 사실을 확실히 체감했다.

 

그래서 해결해야 할 문제는 다음과 같다.

1️⃣ 서버 인스턴스 스펙 업그레이드 (t2.small -> t2.medium) / 2️⃣  Admin 젠킨스 파이프라인 오류 해결

 

1. 서버 인스턴스 업그레이드

[1] 서버 인스턴스를 중지한다: crystalmine-server '인스턴스 상태 -> 인스턴스 중지' 클릭 

한 2분 뒤에 새로고침 하면 '중지 중'으로 상태가 바뀌어있다. 이때 주의할 점은 데이터를 서버에 직접 저장하는 경우 스냅샷을 찍어두거나 볼륨에 백업하는 방식을 사용해야 데이터를 유지할 수 있다. 우리의 경우 데이터는 모두 RDS에 저장되기 때문에 이 점은 상관없었다.

 

[2] 성공적으로 중지했다면 '작업 -> 인스턴스 설정 -> 인스턴스 유형' 변경에서 인스턴스를 업그레이드 / 다운그레이드할 수 있다. 

현재 예시 사진은 인스턴스를 중단하지 않고 촬영했습니다-!

사실 t2.medium 에서 small로 다운그레이드하면서 비용이 거의 절반 가까이 절감되기에 무척 기대했는데 일주일 만에 원상 복구하게 되니 무척 헛헛하다.. 다른 새로운 최적화 방법을 적극 찾아봐야겠다!

2. 젠킨스 Docker Run 오류 해결

먼저 오류가 발생했던 Docker Run 단계에서 log 버튼을 눌러 로그를 확인해 봤다. 단계마다 로그를 확인할 수 있는 점이 무척 편리했다.

 

로그는 다음과 같았다.

+ ssh -o StrictHostKeyChecking=no jenkins@43.203.55.232 
                        docker pull crystalmine/admin
                        docker stop crystalmine-admin && docker rm crystalmine-admin && docker run -d --name crystalmine-admin -p 1936:1936 crystalmine/crystalmine
                        docker image prune -a -f
                        
ssh: connect to host 43.203.55.232 port 22: Connection timed out

 

처음에는 ssh 오류라길래 방화벽, 포트 번호, 네트워크 오류 등 다양한 원인을 찾아서 헤맸다. 하지만 알고 보니, 젠킨스 파이프라인 파일의 업데이트가 되지 않아 IP 주소가 예전에 삭제했던 서버 인스턴스 IP로 되어있던 것이 문제였다! 그래서 IP 주소를 모두 현재 Production 서버 인스턴스의 IP로 변경해 주니 오류가 해결됐다 

 stage('Docker Run') {
            steps {
                echo 'Pull Docker Image & Docker Image Run'
                sshagent (credentials: ['ssh-jenkins']) {
                    sh '''
                        ssh -o StrictHostKeyChecking=no jenkins@43.203.55.232 "
                        docker pull crystalmine/admin
                        docker stop crystalmine-admin && docker rm crystalmine-admin && docker run -d --name crystalmine-admin -p 1936:1936 crystalmine/admin
                        docker image prune -a -f
                        "
                        '''
                }
            }
        }

 

추가로 기존에는 모든 도커 이미지를 crystalmine/crystalmine 레포지토리에 한 번에 보관했는데 이렇게 되면 모든 이미지가 섞이기 때문에 무척 불편하다는 생각이 들었다. 그래서 이렇게 각 이미지마다 레포를 분리하고, 젠킨스 파이프라인에서 각 컨테이너의 이미지명을 수정했다. 

하나하나 차근차근 해결해 보며 또 많은 것을 배웠다.

파이팅이다!

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함