ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [CI/CD] Spring, Jenkins, Nginx, EC2, Docker로 무중단 배포 구현 (1) EC2 서버 기본 설정 (도커, 젠킨스, Nginx, JDK, MySQL, Redis 설치)
    Dev Ops/CI-CD 2023. 3. 30. 23:27
    반응형

    들어가기 전에

    이번 프로젝트에서 인프라를 담당하여 무중단 배포 인프라를 구축해보았다.
    배포 자체도 처음인데 무중단 배포까지 하려니 헷갈리는 것도 많았고 오류도 미친듯이 터졌지만 잘 돌아가게 구성할 수 있어서 뿌듯했다.
    아쉬웠던 점이나 개선해야할 점은 뒤에 적는 것으로.. 최대한 자세히 과정을 적어보고자 한다.

    [ Service Architecture ]

    이번 포스팅에서 구현할 서비스 구조도는 아래와 같다.

    포트를 2개로 구분하여, 서버를 새로 빌드하고 배포하는 과정에서 생기는 서버다운타임 없이 서비스가 운영될 수 있도록 했다.

    1. 깃랩에서 브랜치에 변경사항이 생길 때마다 웹훅을 통해 Jenkins에게 신호를 보냄
    2. Jenkins가 이를 감지하여 새롭게 업데이트된 Git을 clone하고 빌드 시작하며, 파이프라인에 따라 스크립트 실행
    3. 빌드한 파일을 Dockerfile을 통해 이미지화 (Dockerfile에 이미지를 생성할 때 사용할 커맨드 라인을 작성)
    4. 빌드된 도커이미지를 도커허브로 푸쉬
    5. 배포 스크립트에 따라 배포 진행(유휴포트 확인 후 도커허브에서 최신 도커이미지 다운 받아 배포)
    6. 배포가 성공하면 Nginx에서 새로운 포트로 세팅을 변경하고 기존 포트의 컨테이너는 삭제
    7. 빌드가 성공하면 Mattermost 알람 발송

    1. EC2 초기 서버 설정

    - 나는 기존에 발급 받은 EC2 서버를 기준으로 작업했기 때문에 별도로 인스턴스를 만드는 과정을 진행하지 않았다.
    - 아예 처음 하시는 분들은 EC2 인스턴스 생성에 대한 다른 블로그 글들은 많으니 참고하시면 될 것 같고, 나는 EC2가 있다는 전제 하에 글을 작성하도록 하겠다.

    1-1) Termius로 EC2 접속

    - Termius : SSH 명령어를 사용해 특정 서버에 접속하는 것을 지원하는 플랫폼

    📍 SSH란?
    - Secure Shell으로 원격 호스트에 접속하기 위해 사용되는 보안 프로토콜
    - 이전에 사용하던 Talnet 방식은 암호화를 제공하지 않기 때문에 보안상 취약
    - key를 암호화하여 사용자를 인증하고 서버에 접속할 수 있도록 함

    - Termius에 접속해 원격 서버(EC2)로 접속하기 위한 호스트 계정 생성

    - New Host 클릭

    - Address에 도메인 주소, Set a Key를 클릭해 EC2에 접속할 수 있는 키체인(.pem) 등록

    - Username에는 ubuntu를 등록해줬다. OS마다 입력해야 하는 내용이 다를 것이니 검색해보고 하는 것이 필요하다.

    - 호스트 세팅이 완료되면 Hosts에 있는 목록에서 더블클릭하여 해당 원격 서버에 접속할 수 있음

    1-2) 기본 프로그램 설치

    - 나의 EC2 서버는 Ubuntu 기준으로, 각 OS에 따라 알맞은 명령어를 사용해야 한다.

    (처음에 잘 몰라서 매뉴얼을 따라 보고 하다가 Linux에 사용되는 yum을 우분투에 강제 설치해서 실행하려다 서버가 다운됨..)

    - 앞서 구조도에 나온 모든 프로그램들을 찬찬히 설치해보겠다.

    1-2-1) 패키지 관리자 업데이트

    - 패키지 관리자는 항상 업데이트를 해놓고 다른 프로그램 설치 등을 진행하는게 좋다.

    $ sudo apt-get update
    
    $ sudo apt-get upgrade

    1-2-2) JDK 설치

    - Java JDK 다운로드 (11버전) 후 버전 체크하여 설치 여부 확인

    $ sudo apt-get install openjdk-11-jdk
    
    $ java -version

    1-2-3) Docker 설치

    - Spring 프로젝트를 빌드, 이미지화하여 도커 허브에 저장할 수 있도록 도커 설치
    - 기본적으로 배포하여 서버에 띄울 때도 도커 컨테이너 위에서 실행할 예정

    - 2022.2월 버전 공식 문서에 따라 설치한 것으로, 정확한 것은 도커 사이트의 OS별 설치 방법을 참고!

    # 오래된 버전이 있다면 아래 명령어 먼저 실행
    $ sudo apt-get remove docker docker-engine docker.io containerd runc
    
    # repository 설정
    $ sudo apt-get update
    
    $ sudo apt-get install \
        ca-certificates \
        curl \
        gnupg \
        lsb-release
    
    $ sudo mkdir -m 0755 -p /etc/apt/keyrings
    
    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    
    $ echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    - Docker Engine 설치

    : Docker Engine은 Docker Components와 서비스를 제공하는 컨테이너를 구축하고 실행하는 기본 핵심 소프트웨어
    : Docker Deamon, REST API, API를 통해 도커 데몬과 통신하는 CLI로 모듈식으로 구성됨

    $ sudo apt-get update
    
    $ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    
    $ docker --version

    1-2-4) Jenkins 설치

    - CI/CD 기능을 제공하는 툴로 파이프라인 스크립트에 따라 자동으로 배포를 진행함

    $ curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo tee \
      /usr/share/keyrings/jenkins-keyring.asc > /dev/null
    
    $ echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
      https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
      /etc/apt/sources.list.d/jenkins.list > /dev/null
    
    $ sudo apt-get update
    
    $ sudo apt-get install jenkins
    
    # 확인
    $ sudo systemctl status jenkins
    
    $ sudo systemctl start jenkins
    
    # 초기 비밀번호 확인
    $ sudo cat /var/lib/jenkins/secrets/initialAdminPassword

    - http://[도메인]:8080/로 접속하여 Jekins 설정 지속

    - 터미널에서 확인한 초기 비밀번호 입력

    - Install suggested plugins 선택

    - admin 계정 생성

    - Jenkins 접속 URL 설정 (도메인 : 포트번호)

    - 추가 플러그인 설치 (Dashboard ➡️ Jenkins 관리 ➡️ 플러그인 관리 ➡️ Available plugins)

    [설치 플러그인]
    - Generic Webhook Trigger
    - Gitlab
    - Gitlab API
    - Gitlab Authentication
    - Mattermost Notification
    - Docker pipeline

    1-2-5) Nginx 설치

    - 클라이언트 요청을 받아 연결된 포트로 요청을 보냄

    - 무중단 배포를 위해 포트를 스위칭할 목적으로 사용, 후에 EC2 서버가 여러대라면 로드밸런서 역할로도 사용 가능

    $ sudo apt update
    
    $ sudo apt install nginx
    
    # Nginx 실행 확인
    
    $ sudo systemctl start nginx
    
    $ sudo systemctl status nginx

    1-2-6) MySQL 설치

    - 서비스의 전반적인 데이터들을 저장하기 위해 사용

    - DB 설치 및 유저 생성 후 권한 설정

    $ sudo apt-get install mysql-server
    
    $ sudo mysql -uroot
    
    $ create user '아이디'@'%'identified by '비밀번호'
    
    $ grant all privileges on *.*to '아이디'@'%';

    - MySQL 외부 접속 허용 (Config 파일에서 허용 주소 변경)

    $ cd /etc/mysql/mysql.conf.d
    
    $ sudo vi mysqld.cnf
    ...
     // bind-address 를 0.0.0.0으로 변경
     bind-address = 0.0.0.0
    ...

    - MySQL 재실행

    $ sudo service mysql restart

    - Workbench에서 새로운 커넥션 만들어 접속 확인

    1-2-7) Redis 설치

    - JWT Token을 저장하기 위한 저장소로 이용

    - Redis 서버 설치 및 버전 확인

    $ sudo apt-get install redis-server
    
    $ redis-server --version

    - Redis 설정 파일 수정

    $ sudo vi /etc/redis.conf
    // 원격 액세스 가 가능하도록 서버를 열어줌
    bind 0.0.0.0 ::1
    
    // 메모리 최대 사용 용량 및 메모리 초과시 오래된 데이터를 지워 메모리 확보하도록 정책 설정
    maxmemory 2g
    maxmemory-policy allkeys-lru
    $ sudo systemctl restart redis-server

    - Redis 설정 확인

    $ sudo systemctl status redis-server
    
    $ redis-cli ping  # PONG을 반환하면 설정 완료!

     

    여기까지 하면 일차적으로 필요한 사항들에 대한 설치가 끝난다.

    다음에는 본격적으로 CI/CD를 구현해보도록 하겠다.

    반응형

    댓글

Designed by Tistory.