inblog logo
|
sxias
    AWS

    [AWS] 3. CI/CD 1

    문정준's avatar
    문정준
    Jun 13, 2025
    [AWS] 3. CI/CD 1
    Contents
    1. Elastic IP Address2. JDK 설치 & 환경 설정3. 백그라운드 실행4. 스크립트 생성5. cron 주기적 실행6. 재배포
     

    1. Elastic IP Address

    • 유동 IP는 IP가 수시로 바뀌기 때문에 서비스할 수 없음
      • 고객들이 변경된 IP 주소를 추적할 수 없음
    • 이 때문에 서비스를 위해서는 고정된 IP가 필요
      • 탄력적 IP = 고정 IP
     

    EC2 Elastic IP 설정

    • 메뉴의 네트워크 및 보안 → 탄력적 IP 클릭
    notion image
     
    • 탄력적 IP 주소 할당 클릭
    notion image
     
    • 네트워크 설정 후 할당
    notion image
     
    • 생성된 IP 확인
      • 생성만 해둘 경우 사용료가 청구되므로 주의
    notion image
     

    Elastic IP 연결

    • 생성한 IP 주소 선택 후 작업 → 탄력적 IP 주소 연결 클릭
    notion image
     
    • 연결할 인스턴스 및 프라이빗 IP 주소 등록 후 연결 클릭
    notion image
     
    • 연결한 인스턴스의 IP 변경 확인
      • 고정 IP로 변경됨
    notion image
     
    ❗

    고정 IP 사용 시 주의할 점

    • 인스턴스만 종료하고 고정 IP가 남아있을 시, 유료 요금이 청구됨
    • 반드시 고정 IP 연결 해제 및 삭제를 우선 진행한 후 인스턴스 종료
     

    2. JDK 설치 & 환경 설정

    • sudo apt update : apt 목록 갱신
    • sudo apt-cache search jdk | grep 21 : jdk 21 버전만 검색
    notion image
    • sudo apt install openjdk-21-jdk -y : openJDK 21 설치
      • -y : 모두 동의
    • sudo apt install net-tools : 네트워크 툴 설치
      • 세션 동작 확인 가능
     

    3. 백그라운드 실행

    nohup

    • 프로세스를 백그라운드에서 실행시켜 터미널을 종료해도 실행이 유지되도록 하는 명령어
      • git clone 받은 후 gradlew build 필요
      • notion image
      • 없을 경우 gradlew 실행 권한 부여 후 build
      • notion image
      • 키워드 ‘&’ 필요
    nohup java -jar *.jar &
     
    • 실행 시 해당 프로세스 번호 출력
    notion image
     
    • nohup.out 파일에 자동으로 로그 저장
      • 따로 로그를 저장할 파일이 필요할 경우 > 연산자 사용
      • nohup java -jar *.jar 1>log.out 2>err.out &
      • 서버 로그는 정상 입출력이기 때문에 1> 사용 시 서버의 전체 로그 저장
      • 2> 사용 시 리눅스에서 발생한 오류 (서버 open 중 발생한 오류, 오타로 인한 미실행 오류 등) 저장
      • tail을 사용하여 로그 확인 가능
    notion image
     
    • 터미널을 종료해도 접속 가능
    notion image
     
    • 터미널 재 실행 후 네트워크 확인
      • 실행 중
    notion image
     
    • 프로세스 확인
      • 실행 중
    notion image
     
    • 종료 시에는 kill 사용
      • kill -9 PID (8487)
      • 세션 종료 확인 가능
    notion image
     

    Timezone

    • 배포 시 시간 설정 필요
      • 기본 설정은 UTC +0000 (영국)
    timedatectl
    notion image
     
    • 설정 가능한 시간대 리스트 확인
      • 결과가 매우 많기 때문에 검색 및 파이프라인 활용
    timedatectl list-timezones
    notion image
     
    • 서울 시간대 검색
    timedatectl list-timezones | grep Seoul
    notion image
     
    • 서울 시간대 적용
    sudo timedatectl set-timezone Asia/Seoul
    notion image
     

    4. 스크립트 생성

    pgrep

    • 검색한 결과의 프로세스 ID를 출력하는 명령어
    pgrep -f .jar
    notion image
    • 7446이 실제 서버 프로세스인지 확인
      • ps -ef로 확인해본 결과 아님 → .jar로만 찾는 것은 위험
      • 검색 시 실행한 프로세스의 전체 이름을 적어주는 것이 안전
    notion image
     

    스크립트 파일 작성

    • spring-stop.sh 파일 작성
      • 확장자의 의미는 없으나 스크립트 파일임을 나타내기 위해 추가 (Shell 파일)
    echo "Springboot Stop..." SPRING_PID=$(pgrep -f 0.0.1-SNAPSHOT.jar) echo $SPRING_PID kill -9 $SPRING_PID
     
    • 실행 권한 추가 후 서버가 실행 중일 때 스크립트 실행
      • 정상적으로 종료되는 것을 확인
    notion image

    5. cron 주기적 실행

    cron

    • 일정한 시간마다 프로세스를 예약하여 실행시킬 수 있는 스케줄러
    • /etc/crontab 내부 파일의 내용을 읽어서 프로세스 수행
     
    • crontab 편집
      • 에디터 선택 : 원하는 에디터 선택 후 확인하면 crontab 내용이 출력
    notion image
    crontab -e
    notion image
    • 스케줄을 등록하기 위해 다음 코드 추가
    * * * * * ls -l >> cron.log
    • 각 별의 위치마다 설정이 다름
      • 첫 번째 별 : 분 (0 ~ 59)
      • 두 번째 별 : 시간 (0 ~ 23)
      • 세 번째 별 : 일 (1 ~ 31)
      • 네 번째 별 : 월 (1 ~ 12)
      • 다섯 번째 별 : 요일 (0 ~ 7)
        • 0과 7은 일요일로 동일함
        notion image
         
    • 1분 후 파일 생성 확인 가능
    notion image
     
    • 내용 확인 시 파일의 리스트가 저장되는 것을 확인 가능
    notion image
     

    스크립트로 cron 등록

    • 위 방법을 사용하면 일일이 cron에 스케줄을 등록해야 함
      • 스크립트를 통해 자동으로 cron을 등록하도록 설정
     
    • myScript.sh 생성
      • 다음 코드 입력
      • crontab -l > crontab_new
         
    • myScript.sh 실행
      • 실행 권한 우선 부여
      • crontab_new 파일 생성
    notion image
     
    • crontab_new 파일 확인
      • crontab 내용 작성 확인
    notion image
     
    • 스크립트로 cron에 자동 등록하기 위해 myScript.sh 수정 및 job.sh 파일 생성
      • myScript.sh
      • # Copy previous crontab into new crontab crontab -l > crontab_new # Add echo result into crontab_new echo "* * * * * /home/ubuntu/job.sh" >> crontab_new # Apply crontab_new into crontab crontab crontab_new # Remove crontab_new rm crontab_new
         
      • job.sh
      • ls -l > /home/ubuntu/cron.log
     
    • crontab에 새로 job.sh 실행 줄이 적힌 것을 확인 가능
     
    • cron.log 파일 확인
    notion image
     

    Restarting Server with cron

    • 스크립트를 활용하여 스프링 서버가 종료되었을 때에 재시작하는 cron 설정
     
    • 만들어둔 spring-stop.sh 옮기기
      • mkdir cron-restart
      • mv spring-stop.sh cron-restart/
    notion image
     
    • spring-restart.sh 만들기
      • 다음 내용 입력
      • SPRING_PID=$(pgrep -f v1-0.0.1-SNAPSHOT.jar) SPRING_PATH="/home/ubuntu/aws-v1/build/libs/v1-0.0.1-SNAPSHOT.jar" echo $SPRING_PID echo $SPRING_PATH # Check if the server is not running # Wrap $SPRING_PID with quotes : it's not string if [ -z "$SPRING_PID" ]; then echo "Springboot is closed..." echo "Restart Springboot - $(date)" >> /home/ubuntu/cron-restart/spring-restart.log nohup java -jar $SPRING_PATH 1>log.out 2>err.out & else echo "Springboot is running..." fi
     
    • spring-restart.sh 실행
      • 실행 권한 부여
      • 실행 중일 때 : Springboot is running… 출력
      • notion image
         
      • 정지된 상태일 때 : Springboot 자동 재 시작
      • notion image
         
      • 재시작 로그 : cron-restart 폴더에서 확인 가능
      • notion image
         

    6. 재배포

    deploy 작성

    • 스크립트를 활용하여 모든 환경을 다시 설정하는 파일 작성
     
    • deploy.sh 불러오기
      • 외부에서 가져오기 : sftp를 활용하여 저장시키기
    notion image
     
    • git에서 받은 deploy.tar 파일 넣기
      • .tar : 리눅스에서 사용하는 압축 파일
    notion image
    notion image
     
    • .tar 압축 풀기
    tar -xvf deploy.tar
    notion image
     
    • 각 파일 확인
      • var.sh : 전역 변수 지정
      • #!/bin/bash GITHUB_ID="Sxias" PROJECT_NAME="aws-v2" PROJECT_VERSION="0.0.1" PROJECT_PID="$(pgrep -f ${PROJECT_NAME}-${PROJECT_VERSION}.jar)" JAR_PATH="${HOME}/${PROJECT_NAME}/build/libs/${PROJECT_NAME}-${PROJECT_VERSION}.jar" export GITHUB_ID export PROJECT_NAME export PROJECT_VERSION export PROJECT_PID export JAR_PATH
         
      • deploy.sh : 배포
      • #!/bin/bash # 1. env variable source ./var.sh echo "1. env variable setting complete" # 2. cron delete touch crontab_delete crontab crontab_delete rm crontab_delete echo "2. cron delete complete" # 3. server checking if [ -n "${PROJECT_PID}" ]; then # re deploy kill -9 $PROJECT_PID echo "3. project kill complete" else # first deploy # 3-1 apt update sudo apt-get -y update 1>/dev/null echo "3-1. apt update complete" # 3-2 jdk install sudo apt-get -y install openjdk-21-jdk 1>/dev/null echo "3-2. jdk install complete" # 3-3 timezone sudo timedatectl set-timezone Asia/Seoul echo "3-3. timezone setting complete" fi # 4. project folder delete rm -rf ${HOME}/${PROJECT_NAME} echo "4. project folder delete complete" # 5. git clone git clone https://github.com/${GITHUB_ID}/${PROJECT_NAME}.git sleep 3s echo "5. git clone complete" # 6. gradlew +x chmod u+x ${HOME}/${PROJECT_NAME}/gradlew echo "6. gradlew u+x complete" # 7. build cd ${HOME}/${PROJECT_NAME} ./gradlew clean build echo "7. gradlew build complete" # 8. start jar nohup java -jar -Dspring.profiles.active=prod ${JAR_PATH} 1>${HOME}/log.out 2>${HOME}/err.out & echo "8. start server complete" # 9. cron registration touch crontab_new echo "* * * * * ${HOME}/check-and-restart.sh" 1>>crontab_new # register the others... you use >> (append) crontab crontab_new rm crontab_new echo "9. cron registration complete"
         
      • check-and-restart.sh : 확인 후 서버 재시작
      • #!/bin/bash source ./var.sh if [ -z "$PROJECT_PID" ]; then nohup java -jar -Dspring.profiles.active=prod ${JAR_PATH} 1>${HOME}/log.out 2>${HOME}/err.out & fi
     
    • deploy.sh 실행
      • var.sh가 스크립트에 의해 전역 변수로 등록됨
      • deploy 내부의 check-and-restart.sh 실행 코드가 cron에 등록됨
      • cron에 의해 서버가 실행되지 않았을 때 자동 재시작
      • 이후 서버 재배포가 필요할 때에도 deploy.sh 내부에 서버 정지 및 스케줄러 삭제 스크립트가 포함되어 있으므로 deploy.sh만 실행하면 됨
    notion image
    notion image
     
    Share article
    Contents
    1. Elastic IP Address2. JDK 설치 & 환경 설정3. 백그라운드 실행4. 스크립트 생성5. cron 주기적 실행6. 재배포

    Sxias ㆍ a32176740@gmail.com

    RSS·Powered by Inblog