문제 상황: SSH 타임아웃
캡스톤 플젝에 대한 게시글! 일반적으로 AWS 클라우드 서버를 사용하는데 컴공과 캡스톤 수업의 경우 대학 측에서 교내 서버를 대여해 줄 수 있다고 했고, 우리 팀은 학교 NAT 환경에서 확인한 공인 IP로 승인을 받아 해당 IP로만 학교 서버에 접근이 가능한 상황이었다.
이 상황에서 일반적인 AWS 기준의 배포 스크립트를 작성할 경우 나타났던 문제점과 해결 방안에 대해 기록하고자 한다.
ssh 연결을 통한 접속을 해야했기에 교내 캡스톤 서버에서 ssh-keygen을 통해서 개인키와 공개키를 이미 만들어 둔 상황이었다.
개인키 | 공개키 |
git secret로 관리 | 개인 settings ssh key로 관리 |
actions runner가 서버 ssh 접속할 수 있도록 함 | github이 서버로부터 오는 요청(git clone etc.)을 허용하게 하기 위함 |
-----BEGIN OPENSSH PRIVATE KEY----- ..로 시작, 끝을 이루는 수미상관 형식 | ssh-rsa로 시작 |
(이 부분에서도 많은 시행착오를 겪었는데 개인키와 공개키 형식을 구별해서 잘 할당해야 했다.. if not, value type invalid error가 발생한다)
그러나 배포 스크립트 상 개인키를 이용해 서버에 ssh 연결을 시도하는 단계(ssh -i)에서 계속 timeout 문제가 발생했다.
name: Deploy to Server
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Setup SSH Key
run: |
echo "${{ secrets.DEPLOY_SSH_KEY }}" > deploy_key
chmod 600 deploy_key
- name: Clone Project to MobaXTerm Server
run: |
ssh -i deploy_key -o StrictHostKeyChecking=no team12@${{ secrets.SERVER_IP }} << 'EOF'
echo "Preparing default directory"
mkdir -p /data1/team12
cd /data1/team12
echo "Cleaning up old git repo (if exists)"
rm -rf .git
echo "Cloning from GitHub"
git clone git@github.com:NoSleep-Drive/ai-model.git .
echo "Deployment complete"
EOF
해결 방법: Self-hosted Runner 이용
Github Actions는 공용 네트워크에서 실행이 된다. 우리 팀은 학교 NAT 공인 IP로만 접근할 수 있었기 때문에 단순 git actions로는 사설망 서버에 접근할 수 없었던 것이다. 그렇다면 필요한 것은 역발상이었다.
git actions이 서버에 직접 접속을 하는 것이 아니라! 서버가 직접 명령 요청이 들어오면 그 서버 내부에서 명령을 수행하면 되지 않을까?
이 방법을 가능하게 하는 것이 Self-hosted Runner 였다.
깃허브 레포 별로 actions>runner 항목에서 위 방법을 이용할 수 있는 사전 작업 명령어가 소개되어있다. 서버에 설치가 필요한 github actions runner를 다운 받는 코드를 순차적으로 서버 cmd에서 실행시키면 된다.
cat /etc/os-release를 통해 운영체제를 확인해보니 Ubuntu 였고, uname -m을 통해 cpu 아키텍쳐를 확인해보니 x86_64였다. 깃 레포 runner 설치 명령어 옵션에서는 MacOS, Linux, Window를 지원하고 있고 x64, arm을 선택하도록 되어있어서 서버 환경에 맞는 항목을 선택해 나오는 명령어를 차례로 실행해주면 된다.
mkdir actions-runner && cd actions-runner
curl -o actions-runner-linux-x64-2.312.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.312.0/actions-runner-linux-x64-2.312.0.tar.gz
tar xzf actions-runner-linux-x64-2.312.0.tar.gz
./config.sh --url https://github.com/NoSleep-Drive/ai-model --token MY_ALLOCATED_TOKEN_HERE
그리고 runner 기반으로 수정한 배포 스크립트는 아래와 같다.
name: Deploy via Internal Runner
on:
push:
branches:
- main
jobs:
deploy:
runs-on: self-hosted
environment: deploy
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup SSH Key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
- name: Configure Git Identity
run: |
git config --global user.name "GitHub Actions"
git config --global user.email "actions@github.com"
- name: Clone or Pull Repository
run: |
set -e
cd /data1/team12
if [ -d "ai-model/.git" ]; then
echo "Repository exists -> pulling latest changes..."
cd ai-model
GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=no" git pull origin main
else
echo "Repository not found or not a git repo -> cloning from scratch"
rm -rf ai-model
GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=no" git clone git@github.com:NoSleep-Drive/ai-model.git
fi
echo "Model Deployment Ready"
이렇게 되면 main에 push가 되었을 때 캡스톤 서버로 MobaXTerm으로 접속하고,
설치된 runners 경로(default 경로/actions-runner/actions-runner)로 이동한 뒤,
./run.sh를 실행해주면 서버 내에서 git actions의 연결 요청을 승인하여 자체적으로 스크립트를 실행하게 된다.
이때 주의하면 좋은 점이, 이미 runners를 설치할 때 내장된 run.sh를 실행하면 ssh 연결 여부를 묻는 질문이 나오는데 매번 yes라고 입력해야 한다는 점이다. 아래 설정을 통해 이를 자동화할 수 있었다.
GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=no"
깃이 내부적으로 ssh를 쓸 때, 호스트 키를 체크하지 않고 자동으로 yes로 처리하는 설정이다.
기타 트러블슈팅: Git Identity
위 최종 배포 스크립트가 도출 되기 전에 있었던 작은 문제와 해결방안도 함께 소개하고자 한다.
이미 서버로 배포가 되었고 코드 파일을 수정하여 다시 푸시했을 때 main branch로 배포 트리거가 설정되어있어서 deploy가 시작된다.
하지만 아래와 같은 오류에 직면했다.
Run cd /data1/team12
From github.com:NoSleep-Drive/ai-model
* branch main -> FETCH_HEAD
*** Please tell me who you are.
Run
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
to set your account's default identity.
Omit --global to set the identity only in this repository.
fatal: unable to auto-detect email address (got 'team12@devbox.(none)')
Error: Process completed with exit code 128.
이 부분은 레포지토리 디렉토리가 이미 존재해서 pull을 했지만 리모트와 로컬의 커밋 상태가 다르므로 머지 커밋 과정에서 생긴 에러이다. Git은 이때 사용자 정보가 필요하므로 global로 git config를 해주는 부분을 별도의 name step으로 추가하는 계기가 되었다.
오호~ 이런 배포 방식도 가능하구나 하며 배울 수 있었다. Today What I Learn
추후 모델 배포에 대해서 작성하려 한다.
'AWS & CICD' 카테고리의 다른 글
[AWS] RDS를 cmd로 localhost에 복제하기 (0) | 2025.02.23 |
---|---|
[DevOps] Docker Compose 블루그린 무중단 배포 성공 (0) | 2024.08.29 |
[AWS] Nginx 502 해결 시행착오 (0) | 2024.08.18 |
[AWS] CloudWatch로 Memory 모니터링 및 Email 경보 발송 (0) | 2024.07.02 |
[AWS] 프리티어 EC2 예기치 않은 중단 현상(feat. swap memory) (0) | 2024.06.23 |