Techit 18th 3nd

Huisu·2023년 8월 17일
0

Techit

목록 보기
40/42
post-thumbnail

Jenkins 시도

EC2 생성하고 Docker 설치

EC2를 생성하고 터미널에서 EC2 인스턴스에 접속한다.

sudo chmod 400 <키페어 경로>
ssh ubuntu@<EC2 주소> -i <키페어 경로>

이후 docker를 설치한다.

  1. 우분투 시스템 패키지 업데이트
sudo apt-get update
  1. 필요한 패키지 설치
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
  1. Docker의 공식 GPG키를 추가
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  1. Docker의 공식 apt 저장소를 추가
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
  1. 시스템 패키지 업데이트
sudo apt-get update
  1. Docker 설치
sudo apt-get install docker-ce docker-ce-cli containerd.io

Jenkins 설정

이후 필요한 포트 번호를 모두 열어 준다.

docker pull jenkins/jenkins:lts

명령어를 통해 가장 최신 버전 (lts)의 jenkins Container를 다운로드받는다.

sudo docker run -d -p 9080:8080 -v /jenkins:/var/jenkins_home --name jenkins -u root jenkins/jenkins

-d: 백그라운드 모드 실행

-p: 포트 지정해서 9080으로 띄우기

-v: 볼륨 마운트

jenkins 이미지를 실행시키면 EC2인스턴스:9080에 jenkins 화면이 보인다.

초기화 비밀번호를 알아내기 위해 bash로 접속해야 한다.

docker exec -it jenkins /bin/bash
cat /var/jenkins_home/secrets/initialAdminPassword

다음과 같은 비밀번호가 보이면 성공이다.

아래와 같은 화면에서 로그인하면 된다. 이후 추천해 주는 플러그인들을 다 다운로드받는다.

아이디와 비밀번호를 설정해 주면 젠킨스 초기 설정이 끝난다.

Github Action

Workflow

.github → workflows 폴더 밑에 deploy.yml 파일을 작성해 준다.

name: Chatfia Dev CI/CD

on:
  pull_request:
    types: [closed]
  workflow_dispatch: # (2).수동 실행도 가능하도록

jobs:
  build:
    runs-on: ubuntu-latest # (3).OS환경
    if: github.event.pull_request.merged == true # 만약 main에 머지될 때로 하고 싶다면
    # && github.event.pull_request.base.ref == 'main'

    steps:
      - name: Checkout
        uses: actions/checkout@v2 # (4).코드 check out

      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: 17 # (5).자바 설치
          distribution: 'adopt'

      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew
        shell: bash # (6).권한 부여

      - name: Build with Gradle
        run: ./gradlew clean build -x test
        shell: bash # (7).build 시작

      - name: Get current time
        uses: 1466587594/get-current-time@v2
        id: current-time-build
        with:
          format: YYYY-MM-DDTHH-mm-ss
          utcOffset: "+09:00" # (8).build 시점의 시간 확보

      - name: Show Current Time
        run: echo "CurrentTime=$"
        shell: bash # (9).확보한 시간 보여 주기

      - name: Test with Gradle
        run: ./gradlew --info test # (10).test 시작

      - name: Get current time
        uses: 1466587594/get-current-time@v2
        id: current-time-test
        with:
          format: YYYY-MM-DDTHH-mm-ss
          utcOffset: "+09:00" # (11).test 시점의 시간 확보

      - name: Show Current Time
        run: echo "CurrentTime=$"
        shell: bash # (12).확보한 시간 보여 주기

      - name: Generate deployment package
        run: |
          mkdir -p deploy
          cp build/libs/*.jar deploy/application.jar
          cp Procfile deploy/Procfile
          cp -r .ebextensions deploy/.ebextensions
          cp -r .platform deploy/.platform
          cd deploy && zip -r deploy.zip .

      - name: Beanstalk Deploy
        uses: einaregilsson/beanstalk-deploy@v20
        with:
          aws_access_key: ${{ secrets.AWS_ACTION_ACCESS_KEY_ID }}
          aws_secret_key: ${{ secrets.AWS_ACTION_SECRET_ACCESS_KEY }}
          application_name: fithub-prod
          environment_name: Fithub-prod-env
          version_label: github-action-${{ steps.current-time.outputs.formattedTime }}
          region: ap-northeast-2
          deployment_package: deploy/deploy.zip
          wait_for_environment_recovery: 60

VPC 생성

아래와 같은 설정으로 vpc를 만들어 준다.

이후 생성한 vpc에 대해 subnet을 만들어 준다. 이때 elastic beanstalk은 일반적으로 서브넷 두 개 이상을 사용하기 때문에 두 개를 만들어 준다.

새로운 internet gateway를 만들어 준다.

이후 만든 vpc를 연결해 준다.

내가 만든 vpc의 라우팅 테이블에 가 보면 안으로 들어오는 것만 있다. 따라서 밖으로 나가는 것까지 설정해 줘야 한다.

우리가 만든 게이트웨이로 설정해 준다.

이후 서브넷 연결에서 만든 서브넷을 public으로 등록해 줄 수 있다. private으로 하면 고생하니까 둘 다 public으로 해 준다. 일단 private은 돈이 많이 나간다.

이후에 ec2에 올라갈 보안 그룹을 설정한다. default VPC가 아닌 내가 아까 만들었던 VPC로 설정한다.

IAM

빈스톡이 자동으로 Ec2도 만들고 할 예정인데, 그 작업이 가능하게 하려면 역할을 줘야 한다.

새로운 역할을 다음과 같이 생성해 준다.

이후 다음과 같이 ec2에 대한 권한을 가진 역할을 만들어 준다.

위 사진에 보면 현재 elasticbeanstalk이 사용할 role인데 ec2 서비스라고 되어 있다. 저 부분을 elasticbeanstalk.amazonaws.com으로 바꿔 준다.

이번에는 ec2에게 권한을 줄 역할을 생성한다.

Elastic Beanstalk

환경 생성에 접속해서 이름을 정해 준다.

우리의 플랫폼인 자바를 선택한다. 그리고 사전 설정을 custom으로 변경한다.

IAM에서 만든 role을 넣어 준다.

만들어 둔 VPC를 설정하고 public IP를 활성화시킨다. 빈스톡과 ec2가 서로 작업이 잘 마무리되었는지 통신하려면 퍼블릭 ip를 열어 둬야 한다.

이후 다음을 눌러 보안 그룹을 설정해 준다.

이후 용량에서 하나의 인스턴스를 하면 중단 배포가 된다.

하지만 무중단 배포를 하기 위해 인스턴스를 여러 개 두는 방식을 선택한다.

나중에 domain을 만들고서는 https 설정으로 바꿔야 한다.

이후 process의 deafult에서 helath 루트를 추가해 준다.

빈스톡 배포에 문제가 있을 때 이유를 알기 위해 강화됨을 선택해 준다.

이후 추가 배치를 사용한 롤링 옵션을 선택해 무중단 배포가 되도록 한다.

이후 기본 포트를 8080으로 설정해 준다.

User

action을 사용해 배포할 사용자를 만들어 준다.

정책에 직접 연결하는 것을 선택하고 다음 권한을 준다.

이후 보안 자격 증명 탭으로 간다.

외부에서 진행하는 키를 만든다.

사용자를 생성하면 나오는 Access Key와 Secret을 Github secret에 넣어 준다.

키들이 잘 들어간 모습이다.

Project

내가 실행할 프로젝트 루트 폴더에 다음과 같은 .ebextenstions/00-makeFiles.config를 만든다.

내용은 아래와 같이 채워 준다.

files:
    "/sbin/appstart" :
        mode: "000755"
        owner: webapp
        group: webapp
        content: |
            #!/usr/bin/env bash
            JAR_PATH=/var/app/current/application.jar

            # run app
            killall java
            java -Dfile.encoding=UTF-8 -jar $JAR_PATH

이번에는 .platform/nginx.conf 파일을 작성해 준다.

user                    nginx;
error_log               /var/log/nginx/error.log warn;
pid                     /var/run/nginx.pid;
worker_processes        auto;
worker_rlimit_nofile    33282;

events {
    use epoll;
    worker_connections  1024;
    multi_accept on;
}

http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;

  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

  include       conf.d/*.conf;

  map $http_upgrade $connection_upgrade {
      default     "upgrade";
  }

  upstream springboot {
    server 127.0.0.1:8080;
    keepalive 1024;
  }

  server {
      listen        80 default_server;
      listen        [::]:80 default_server;

      location / {
          proxy_pass          http://springboot;
          proxy_http_version  1.1;
          proxy_set_header    Connection          $connection_upgrade;
          proxy_set_header    Upgrade             $http_upgrade;

          proxy_set_header    Host                $host;
          proxy_set_header    X-Real-IP           $remote_addr;
          proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
      }

      access_log    /var/log/nginx/access.log main;

      client_header_timeout 60;
      client_body_timeout   60;
      keepalive_timeout     60;
      gzip                  off;
      gzip_comp_level       4;

      # Include the Elastic Beanstalk generated locations
      include conf.d/elasticbeanstalk/healthd.conf;
  }
}

이후 Procfile을 만들고 내용을 web: appstart로 작성해 준다.

이후 build.gradle에 아래 코드를 추가해 준다.

jar {
    enabled: false
}

마지막으로 git에 push하고 main에 머지하면 배포가 완료된다.

1개의 댓글

comment-user-thumbnail
2023년 8월 17일

많은 것을 배웠습니다, 감사합니다.

답글 달기