EC2 Nginx 및 Jenkins 구성

Nginx 및 Jenkins 사용으로 얻는 이점

Nginx 장점

  • Nginx를 통한 리버스 프록시 설정: Nginx는 정적 파일을 서빙하고 동시에 Jenkins 서버에 대한 리버스 프록시로 동작할 수 있다. 이를 통해 클라이언트 요청을 효과적으로 분산하고, 보안을 강화할 수 있다.
  • 보안 강화: Nginx를 사용하여 SSL 인증서를 설정하고 HTTPS를 통해 통신을 암호화할 수 있다. 또한 Nginx는 악의적인 공격으로부터 서버를 보호하기 위한 추가 보안 계층을 제공할 수 있다.
  • 로드 밸런싱 및 부하 분산: Nginx를 사용하여 여러 WAS를 로드 밸런싱하여 트래픽을 분산할 수 있다. 이는 서버의 성능과 가용성을 향상시키고, 고가용성을 유지할 수 있게 해준다.
  • 정적 파일 서빙: Nginx는 정적 파일을 빠르게 서빙하는 데 효율적이므로, 프론트단의 빌드 결과물이나 사용자 정의 정적 파일을 효과적으로 제공할 수 있다.
  • 백엔드 서버와의 통합: Nginx를 사용하여 API서버 및 Jenkins 서버에 대한 엑세스를 외부에서 제어하고 관리할 수 있다. 특정 경로에 대한 서버 엑세스를 설정하거나 인증을 추가할 수 있다.
  • 성능 향상: Nginx는 경량이면서도 높은 성능을 제공하므로, 서버와의 통신을 최적화하여 성능을 향상시킬 수 있다.

Jenkins 장점

  • 지속적 통합 및 지속적 배포 (CI/CD): Jenkins는 소스 코드 변경이나 빌드되는 즉시 자동으로 테스트 및 배포하는 CI/CD 파이프라인을 구축하는 데 사용된다. 이를 통해 소프트웨어 개발 프로세스를 자동화하고 개발자들이 더 빠르게 코드를 통합하고 배포할 수 있다.
  • 자동화된 빌드 및 배포: Jenkins는 코드 커밋 및 이벤트를 감지하고, 자동으로 빌드, 테스트, 배포를 수행함으로써 개발 프로세스의 속도를 높이고, 인간의 실수를 줄일 수 있다.
  • 다양한 플러그인과 통합: Jenkins는 다양한 플러그인과 통합을 제공하여 다양한 작업 및 환경에 대해 유연하게 대응할 수 있다. 이를 통해 다른 도구 및 서비스와의 연동을 간편하게 할 수 있다.

Continuous Integration (CI): 코드 변경이 발생할 때마다 자동으로 소프트웨어를 빌드하고 테스트하여 개발자들이 통합 오류를 빠르게 발견하고 수정할 수 있는 프로세스입니다.
Continuous Delivery (CD): 소프트웨어를 언제든지 프로덕션 환경으로 배포할 수 있는 상태로 유지하는 프로세스입니다.
Continuous Deployment (CD): 모든 변경 사항이 자동으로 프로덕션 환경으로 배포되는 프로세스입니다.

선택 이유

Apache에 비해 Nginx가 더 경량화 되고, 동적 컨텐츠에 대한 속도는 비슷한 반면 정적 컨텐츠 서빙에 대한 속도가 Nginx가 약 2.5배 더 높다고 한다.

Github를 사용하는 경우, Github Action이 더 쓰기는 편하지만, Private Repository를 사용하는 경우 무료가 아니며, Jenkins 관련 자료를 찾는 것이 더 쉬움.

아키텍처 다이어그램

대략적인 아키텍처는 다음과 같다. 아직 준비 단계이기 때문에 상황과 목적에 따라 추후 변경될 가능성이 크다.

클라이언트의 정적 파일 요청

a1.png

  • Nginx가 정적파일을 서빙해준다.

클라이언트의 서버 API 요청

a2.png

  • Nginx가 중간에서 리버스 프록시 역할을 한다.

CI(CD)

a3.png

  • Jenkins와 Github Webhook을 통해 main브랜치에 대한 push를 감지하여 파일을 최신화하고 빠른 배포를 가능하게 한다.
  • 추후 필요에 따라 역할이 확장될 수 있다.

Nginx 설치

이전 포스팅에서 다뤘으므로 스킵해도 좋다.

apt 패키지 업데이트

sudo apt update

Nginx 설치

sudo apt install nginx

Nginx 서비스 시작

sudo systemctl start nginx

부팅 시 자동으로 시작되도록 설정

sudo systemctl enable nginx

Nginx 상태 확인

sudo systemctl status nginx

이제 conf파일을 수정하여 Nginx에게 역할을 주어야 한다

  • http{} 블록에 다음 내용을 추가한다.
server{
    listen 80;
    server_name {내 EC2 서버 도메인};

    root /home/ubuntu/jenkins_home/workspace/ProjARJS;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
server {
    listen 8080;

    server_name {내 EC2 서버 도메인};

    location / {
        proxy_pass {리버스프록시할 백엔드 EC2 서버 도메인};
        proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
    }
}
  • 80번으로 오는 요청은 정적 파일을 서빙하고, 8080번으로 오는 요청은 리버스프록싱한다.
  • https(ssl)관련 설정은 추후 필요시 하도록 한다.

Nginx 변경 사항 적용

sudo nginx -s reload

Jenkins 설치

도커가 설치되었다고 가정합니다. 먼저 도커를 설치해주세요. Jenkins는 설치상의 편의를 위해 컨테이너에 올릴 것입니다.

도커 파일 편집

sudo nano /etc/default/docker

이후

DOCKER_OPTS="--restart=always"

해당 줄 수정

도커 재시작

sudo service docker restart

젠킨스 설치 및 자동 시작 설정, 볼륨 할당

docker run -d --restart=always -p 9090:8080 -v jenkins_home:/var/jenkins_home --name jenkins jenkins/jenkins:lts
  • 호스트의 9090포트와 컨테이너의 8080포트를 포워딩합니다.
    • 젠킨스의 기본 포트가 8080인데, 스프링 부트의 포트와 중복되기 때문에 9090을 사용합니다.
  • 도커 볼륨을 할당하여 호스트의 jenkins_home와 컨테이너의 /var/jenkins_home을 공유하도록 합니다.
  • 컨테이너 이름을 jenkins로 설정합니다.

젠킨스 설정 시작
a4.png 젠킨스가 설치되었으므로 브라우저에서 설치된 EC2의 도메인의 9090포트에 접속합니다. 잠시 기다리면 위 화면이 나오는데,

sudo docker exec -it jenkins bash

위 명령어를 통해 jenkins container에 bash쉘로 접속합니다.

cat /var/jenkins_home/secrets/initialAdminPassword

위 명령어를 통해 비밀번호를 복사하여 화면에 입력해줍니다.

이후 계정을 만들어도 되고, 그냥 스킵하여 어드민 계정을 써도 됩니다. 계정을 만들어 놓는 것을 추천합니다

젠킨스 구성
a5.png Jenkins 관리 -> System으로 들어갑니다.

a6.png 쭉 내려 Github Server에서 Credentials의 Add버튼을 클릭합니다.

a7.png Secret Text를 선택하고 Secret에 Github Personal Access Token을 입력합니다.

이때 해당 토큰은 repo, admin:org, admin:repo_hook 권한이 필요합니다.

그리고 방금 만든 Credential을 적용해줍니다.

새로운 Item
a8.png 화면 좌측의 “새로운 Item”을 선택하고 아이템 이름을 입력한 뒤, Freestyle project를 선택하고 OK

a9.png General -> project url에 깃허브 레포 주소를 적습니다. (.git은 빼고)

a10.png Repository URL에 .git을 포함한 레포 경로를 입력하고 Credential을 다시 만듭니다.

저의 경우는 아까 만든 Secret text가 안나와서 다시 만들었으나 문제가 없다면 아까걸 다시 써도 무방합니다.

이번엔 Secret text가 아닌 Username with password를 선택하고 Username에 자신의 github 닉네임을 적고 password에 아까쓴 토큰을 적으면 됩니다. 해당 Credential을 적용하고,

a11.png 빌드 유발에서 Github hook trigger for GITScm polling에 체크합니다.

Github Repo 설정
이제 마지막으로 Github레포지토리에서 다음 설정을 변경합니다.

a12.png CI를 적용할 레포지토리 -> settings -> webhooks -> Add webhook

a13.png Payload URL에 서버 도메인과 포트번호, 뒤에는 /github_webhook/을 입력하고 Content type을 application/json으로 변경한뒤 저장합니다.

이후 젠킨스에서 빌드 테스트 하면 된다. 예를 들어, spring boot 프로젝트라면 item의 build steps -> Execute shell에서 ./gradlew build 등의 스크립트를 추가해주면 된다.