SpringBoot 프로젝트 Jenkins 배포 자동화

Soohyeon B·2022년 10월 22일
0

스프링 부트로 프로젝트를 진행하면서 travis CI를 사용하여 배포를 자동화하려했다. 하지만 travis ci에서 파일을 못받아오는 문제가 발생해서 일단 시간이 부족한 관계로 배포 자동화는 미루고 github에 push 할 때마다 수동으로 aws elastic beanstalk을 사용하여 프론트에게 매번 새로운 링크를 전달해줬었다. 공모전 제출일까지 시간이 정말 너무 부족했어서 어쩔 수 없이 선택한 길이었다...
하지만 매번 프론트에게 새로운 링크를 주고 프론트에서는 해당 ip가 들어간 코드를 매번 고쳐야하는 수고로움을 주는 것은 정말 비효율적이었다..
이 때문에 배포 자동화에 대한 필요성을 뼈저리게 느꼈고... 프론트 팀한테 너무 미안했다.

그럼 이제 각설하고 만들어둔 spring boot 프로젝트를 jenkins를 사용해서 배포 자동화를 진행해보자!!

환경

aws ec2 환경에서 docker와 jenkins를 사용하여 깃헙의 소스를 빌드하고, 배포하는 작업을 자동화 할 것이다.

Jenkins 배포 과정

  1. 스프링 부트 프로젝트 개발
  2. github에 push
  3. jenkins에서 빌드
  4. 빌드한 결과를 담은 jar 파일을 web server에 SSH 송신
  5. web server에서 jar 파일 실행 (배포)

Jenkins Docker 환경 설정

1. Docker 설치

나는 기존에 만들어둔 ec2 인스턴스를 winscp를 통해서 putty로 접속하여 해당 서버에 접근한다.


현재 사용하고 있는 리눅스 버전은 "Amazon Linux 2"이다.


현재 사용하고 있는 도커 버전은 20.10.17이다.

docker -v

해당 명령어로 도커 버전 확인이 가능하다.

도커 시작하기

sudo service docker start

도커를 시작하고 그룹에 사용자를 추가한다.

sudo usermod -aG docker ec2-user

usermod 명령어를 사용하여 그룹에 ec2-user를 추가했다.

2. Docker-compose 설치

Docker Compose란 여러 개의 컨테이너로부터 이루어진 서비스를 구축, 실행하는 순서를 자동화하여 관리를 단순화하는 기능이다.
Docker compose에서는 compose 파일을 준비하여 커맨드를 1회 실행하여 그 파일로부터 설정을 읽어들여 모든 컨테이너 서비스를 실행시키는 것이 가능하다고 한다.

docker compose 설치

docker compose의 릴리즈 페이지에 접속하여 최신 정보를 확인하고, Docker compose를 설치하면 된다.
curl commad를 사용하여 아래와 같은 명령을 입력한다.

sudo curl -L https://github.com/docker/compose/releases/download/1.25.0\
-rc2/docker-compose-`uname -s`-`uname -m` -o \
/usr/local/bin/docker-compose

실행권한 추가하기

sudo chmod +x /usr/local/bin/docker-compose

이제 설치가 잘 되었는지는

docker-compose -v

명령으로 확인할 수 있다.


위와 같이 잘 설치된 것을 확인할 수 있다.

3. Docker-machine 설치하기

docker machine은 일종의 virtual machine과 같이 도커를 mac, window 등 다른 환경에서도 동일하게 띄울 수 있게 도와준다.

나는 현재 linux를 사용하고 있기 때문에 리눅스 설치 방법을 따라가보았다.

base=https://github.com/docker/machine/releases/download/v0.16.0 &&
curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine &&
sudo install /tmp/docker-machine /usr/local/bin/docker-machine
  • mac의 경우
$ base=https://github.com/docker/machine/releases/download/v0.16.0 &&
curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/usr/local/bin/docker-machine &&
chmod +x /usr/local/bin/docker-machine
  • window의 경우
$ base=https://github.com/docker/machine/releases/download/v0.16.0 &&
mkdir -p "$HOME/bin" &&
curl -L $base/docker-machine-Windows-x86_64.exe > "$HOME/bin/docker-machine.exe" &&
chmod +x "$HOME/bin/docker-machine.exe"

각자의 os에 맞게 설치하면 된다.


설치를 완료했으면 잘 다운됐는지 확인해봐야 한다.

docker-machine -v

해당 커맨드를 입력하여 아래와 같이 잘 다운된 것을 확인할 수 있다.

4. Docker-machine으로 AWS 드라이버 사용하기

Docker machine에서 aws를 드라이버로 사용하기 위해서 환경변수를 먼저 추가해야 한다.
우선 aws의 access key가 필요하기 때문에 aws에 접속해서 access key를 하나 만들어준다.
저번에 만들어뒀었는데 어디로 날라간건지...

계정 액세스 키 Id와 보안 액세스 키 얻기

  1. https://console.aws.amazon.com/iam/에서 IAM 콘솔 열기
  2. 탐색 메뉴에서 사용자 선택
  3. IAM 사용자 이름 선택
  4. Security credentials(보안 자격 증명) 탭을 연 다음 Create access key(액세스 키 생성)를 선택
  5. 새 액세스 키를 보려면 [Show]를 선택. 자격 증명은 다음과 같을 것입니다.
    액세스 키 ID: AKIAIOSFODNN7EXAMPLE
    보안 액세스 키: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  6. secret access 키와 같은 경우에는 다시는 못보기 때문에 csv 파일을 다운받아서 로컬에 저장하는 것을 추천한다. 대신, public이나 다른 곳에 공개는 금물!!!

    aws CLI가 AWS와 상호 작용하기 위해 사용하는 설정 구성하기

    [ec2-user@ip-172-31-18-132 ~]$ aws configure
    AWS Access Key ID [None]: AKIAIOSFODNN7EXXXX
    AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxxxxxxxxx
    Default region name [None]: ap-northeast-2
    Default output format [None]: # 아무것도 누르지 않고 엔터

5. Jenkins Docker 환경 설정

  1. EC2 서버에서 Jenkins image 다운
docker pull jenkins/jenkins:lts

이미지는 가상머신에서 사용하는 이미지와 비슷한 역할을 한다. 한마디로, 이미지는 측정한 애플리케이션을 실행하기 위한 환경이다. 그리고, 이 환경은 파일들의 집합이다. 도커에서는 애플리케이션을 실행하기 위한 파일들을 모아놓고, 애플리케이션과 함께 이미지로 만들 수 있다. 그리고 이렇게 만들어진 이미지를 기반으로 애플리케이션을 바로 배포할 수 있다.

  1. Jenkins를 컨테이너에 올려서 run하기
docker run -itd --name [jenkins container name] -p 9090:8080 jenkins/jenkins:lts
  • [Jenkins container name]: Jenkins 컨테이너의 이름을 입력
  • -d: detached mode, 백그라운드에서 컨테이너가 실행되게 한다.
  • -p: 서버의 9090포트와 컨테이너 내부 8080포트를 연결한다.
  • -v: 서버의 /home/jenkins경로와 컨테이너 내부 /var/jenkins_home경로를 마운트한다.
  • --name: 실행될 컨테이너의 이름을 jenkins-docker으로 설정한다.
  • -u: 실행할 사용자를 root으로 설정한다.
  • -it: -i(docker 컨테이너에 표준 입력을 열어두고), -t(가상 터미널을 열어 키보드의 입력을 표준 입력으로 전달할 수 있도록 한다.

나는 이렇게 했다.

docker run -itd --name chveita-linux -p 9090:8080 jenkins/jenkins:lts
  1. Jenkins initialAdminPassword 확인
docker exec -it [아까 입력한 jenkins container name] /bin/bash
cat /var/jenkins_home/secrets/initialAdminPassword

Admin 계정 설정

  1. aws ec2 서버에서 9090 포트로 접근이 가능하게끔 보안 규칙을 수정한다.
  2. ec2주소:9090 으로 접속
    우리 프로젝트 주소는 http://13.209.120.46:9090/
  3. 아까 복사해준 secret key 복붙
  4. install suggested plugins 선택
  5. 계정명 등 암호 설정

    jenkins가 돌아갈주소를 설정해준다.

SSH 설정

  1. jenkins 관리 > 플러그인 관리

  2. publish over ssh 플러그인 설치 후 재시작


    몇개의 플러그인이 제대로 설치가 안된다.
    설치후 재시작하도록 했더니

설치가 느린건지 재시작을 하는 중인지
다시 새로고침을 하니까 서버 접근이 또 안된다.

docker 사용법

도커를 처음 사용해봐서 아직 뭐를 어떻게 사용하고 확인하는지 잘 모르겠어서 토막으로 정리해본다.

  • 종료된 컨테이너를 포함해 삭제되지 않은 모든 도커 컨테이너 확인
docker ps -a

해당 커맨드를 입력하면 이전에 만들어 둔 모든 컨테이너가 뜬다.

지금 현재 이전에 만들어둔 chevita-linux, chevita, nauth_shockley(이건 뭐지...), mariadb 이렇게 4개의 컨테이너가 뜬다.

docker run -rm ubuntu ls -l

이렇게 -rm 옵션을 달면 해당 우분투 컨테이너가 실행되고, 실행이 완료되면 컨테이너를 삭제하게 된다.
컨테이너가 삭제되면 해당 포트로는 접근이 불가능한가???
왜 나는 이전에 만들어둔 컨테이너를 삭제하지도 않았는데 젠킨스 서버 접근이 불가능한 것일까???

컨테이너 재활용은 불가능한걸까??
재활용 가능하다

어떻게??

docker container restart [옵션] [컨테이너 식별자]

이렇게 특정한 컨테이너를 재시작할 수 있다. 옵션은 굳이 달지 않아도 된다.

정지중인 모든 컨테이너 삭제
docker container prune
컨테이너 중단
  • docker container pause [컨테이너 식별자]

6. springboot web server 설정

스프링 부트 프로젝트를 서버에 띄우기 위해서 설정하는 과정이다.

Docker file 작성

도커 파일은 docker에서 이미지를 생성하기 위한 용도로 작성하는 파일이다.
즉, 만들 이미지에 대한 정보를 기술해둔 템플릿이라고 할 수 있다.

도커 이미지를 만들 때 아래와 같이 커맨드를 입력하면 작성한 도커파일의 내용을 기반으로 이미지 빌드가 시작된다.

docker build [옵션] [작성한 dockerfile 경로]

기존에 도커 컨테이너에 웹 서버 구동을 위해서 베이스 이미지를 다운로드 받은 후 컨테이너에 접속하여 사용자가 수동으로 작업했던 반면, 도커 파일을 이용하면 자동으로 모든 것을 처리하여 이미지로 작성된다는 장점이 있다.

원하는 경로에 도커 파일을 생성한다.
파일명은 "Dockerfile"이며, 확장자는 따로 존재하지 않는 텍스트 형식이다.

나는 제일 바깥에다가 파일을 생성했다.

FROM ubuntu:20.04 # 공식 이미지를 기반으로 이미지 제작, 태그명이 생략되면 base 이미지의 최신버전으로 자동 설정

#user setting
ENV USER 유저이름

#packages install 컨테이너가 생성될 때 명령 수행
RUN apt-get update && apt-get upgrade -y
RUN apt-get install -y sudo vim net-tools ssh openssh-server openjdk-11-jdk-headless

#root ssh login enable
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# /etc/pam.d/sshd disable
RUN sed -i 's/UsePAM yes/#UserPAM yes/g' /etc/ssh/sshd_config

# 999 groupadd groupname:username
RUN groupadd -g 999 $USER

# user add in group
RUN useradd -m -r -u 999 -g $USER $USER

# user can sudo setting
RUN sed -ri '20a'$USER' ALL=(ALL) NOPASSWD:ALL' /etc/sudoers

# password setting
RUN echo 'root:root' | chpasswd
RUN echo $USER':비밀번호' | chpasswd

# JAVA_HOME setting
ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

# run container with ssh restart setting
ENTRYPOINT sudo service ssh restart && bash

USER $USER
  • 유저이름: 도커 컨테이너에 띄우는 우분투 서버 아이디
  • 유저 pw: 도커 컨테이너에 띄우는 우분투 서버 비밀번호

도커 이미지 생성

도커 파일이 있는 경로에서 도커 파일을 기반으로 이미지를 생성한다.

docker build -t [imageName] .
  • 이미지이름: chevita로 설정

Docker run

docker run --name [web server container Name] -itd -p [웹서버포트]:8080 -p [ssh포트]:22 [imageName]
  • [web server container Name] : ec2 서버를 의미하는 건가?? 뭘 적어야하는거지...
  • [웹서버포트]: 도커 컨테이너 내부 8080포트와 연결할 외부 포트를 설정한다. (80) 정확하게 뭘로 해야할지 모르겠다.
  • [ssh 포트] : ssh 연결을 위한 포트 설정 (이것도 22로 했다)

출처

젠킨스

도커 설치

docker compose 관련

Docker machine

aws access 키

도커 이미지 관련

도커 사용법 관련

docker file

profile
하루하루 성장하는 BE 개발자

0개의 댓글