현재 우리 팀은 아래와 같은 구조를 가진 웹 서비스를 기획하고 있습니다.
필자는 백엔드 개발을 맡았는데, 웹 개발 경험이 없습니다.
사실 이 시스템 구조도는 웹 개발 경험이 있는 팀원이 만들었습니다.
내가 만들고 싶었지만 정말 아는 게 하나도 없어서 손도 댈 수 없었습니다.
이걸 처음 봤을 때, 나는 깃허브, 리액트, 스프링부트, 챗GPT만 알았고(이것도 깃허브 빼고는 그냥 들어본 정도..ㅋㅋ),
'내가 4년째 컴퓨터를 공부하고 있는데 이게 맞나'라는 생각도 들었습니다.
구조도는 내가 설계하지 않았지만, 이에 맞는 개발환경은 백엔드인 내가 세팅해야 합니다.
그래서 일단 Jenkins, EC2를 이용한 스프링부트의 CI/CD 파이프라인을 구축하는 실습을 해보기로 했습니다.
AWS 가입부터 시작하겠습니다.
AWS 회원가입
준비물: Master 또는 Visa 카드
AWS 공식 사이트로 이동하여 무료 계정 만들기를 선택합니다.
주소는 영문주소를 작성한다.(https://www.jusoen.com/ 에서 가능)
계정 유형은 개인을 선택합니다.
지원 플랜은 무료 기본 플랜을 선택합니다.
콘솔 로그인 버튼을 클릭해서 로그인을 진행합니다.
이제 EC2 인스턴스를 생성해 봅시다.
EC2 인스턴스 생성하기
콘솔 로그인을 하면 다음과 같은 화면을 볼 수 있습니다.
1. OS 선택
Amazon Linux 2를 이용할 것입니다.
2. 인스턴스 유형 선택
간단한 웹 개발용 이므로 t2.micro를 선택합니다.(프리티어 사용 가능한 것을 고른다.)
3. 키 페어 생성
키 페어는 public key(공개키)와 private key(개인키)로 구성되며, EC2 인스턴스에 연결할 때 자격 증명 입증에 사용하는 보안 자격 증명 집합이다. |
private key를 소유한 사람은 누구나 인스턴스에 연결할 수 있으므로 보안된 위치에 private key를 저장하는 것이 중요합니다.
키 페어 생성을 클릭하면 다음과 같이 private key가 다운로드됩니다.
인스턴스 연결에 꼭 필요한 private key이니 잘 저장해야 합니다.
4. 네트워크 설정
별다른 설정을 더하지 않고 넘어갑니다.
EC2 인스턴스는 터미널을 통해 접속해야 하기 때문에 SSH 22번 포트가 기본값으로 설정되어 있습니다.
5. 보안그룹 설정
SSH 설정은 기본적으로 어느 곳에서나 접속이 가능하도록 되어 있지만, 보안상 좋지 않기 때문에 내 IP로 바꿔줍니다.
HTTPS와 사용자지정 TCP를 추가합니다.
6. 스토리지 구성
프리티어로 최대 30GB까지 사용 가능하므로 30GB로 설정합니다.
7. 고급 세부 정보
는 그냥 넘어갑니다.
인스턴스 시작을 누르면 인스턴스가 생성됩니다.
결제 알림 생성을 통해 요금 알림 메일을 신청할 수 있습니다.
'모든 인스턴스 보기'를 클릭하면 인스턴스가 잘 생성된 것을 확인할 수 있습니다.
8. 탄력적 IP 주소 할당
원래 인스턴스를 생성할 때는 항상 새 IP가 할당됩니다.
인스턴스를 중지하고 재시작하면 새로운 IP가 할당되기 때문에 고정적인 IP를 가질 수 있도록 탄력적 IP 주소를 할당해 줍니다.
이때 탄력적 IP를 만들고 EC2에 연결해주지 않으면 과금이 되기 때문에 주의합니다.
사이드 메뉴에서 [네트워크 및 보안]-[탄력적 IP]를 선택하고 '탄력적 IP 주소 할당'을 클릭합니다.
인스턴스 선택 필드를 눌러 아까 생성한 인스턴스와 연결시켜 줍니다.
AWS(아마존 웹 서비스) ssh로 인스턴스에 연결
PuTTYgen을 사용하여 프라이빗 키 변환
https://www.chiark.greenend.org.uk/~sgtatham/putty/releases/0.78.html
aws에 ssh로 접속하기 위해 위 사이트에서 putty를 다운로드합니다.
그다음 인스턴스를 생성할 때 만든 키 페어에 대한 private key(.pem 파일)을 찾습니다.
1. puttygen을 이용하여. ppk 파일 만들기
puttygen을 실행하면 이런 창이 뜹니다.
Load를 눌러 아까 찾아놓은 .pem파일을 불러옵니다.
(.pem파일이 보이지 않는다면 파일 이름 옆을 All Files(*.*)로 바꾸면 됩니다.)
Save private key를 눌러 저장합니다.
(디렉터리를 잘 설정하자. 필자는 디렉터리를 바꿨다가 꽤 오랜 시간 고생했습니다.)
2. PuTTY 실행
Host Name에는 EC2 인스턴스 세부정보의 퍼블릭 IPv4 주소를 입력합니다.
Port는 22번 그대로 둡니다.
SSH 접속이므로 SSH 라디오버튼을 클릭합니다.
왼쪽 카테고리에서 'SSH-Auth'를 클릭합니다.
Private key file for authentication의 Browse를 눌러 아까 생성한 .ppk 파일을 로드합니다.
이는 SSH 서버에 접속하기 위해 사용됩니다.
3. Session save
다시 왼쪽 메뉴 Session을 클릭합니다.
지금까지 설정한 내용들을 매번 서버에 접속할 때마다 입력하는 것은 불편하므로
Saved Session에 현 입력상태에 대한 이름을 정하고 Save버튼을 누릅니다.
이렇게 설정하고 나면 PuTTY를 켜서 해당 이름을 클릭하고 Load하면 필요한 정보들이 불러와집니다.
이렇게 모든 설정이 끝났습니다.
이제 제일 밑의 Open을 눌러 서버에 접속해 봅시다.
ec2-user를 입력합니다.
EC2 설정이 끝났습니다!!!!
이제 EC2에 Jenkins를 설치하고 파이프라인 구축까지 가봅시다~
EC2에 자바와 Jenkins 설치
젠킨스 설치 전에 자바부터 설치합니다.
자바가 설치되어 있는지 확인해 봅시다
$ java -version
설치되어 있지 않으면 이런 결과가 나옵니다.
1. 자바 설치
$ sudo yum install -y java-1.8.0-openjdk-devel.x86_64
$ java -version
다운이 잘 되었는지 버전을 확인합니다.
2. Jenkins 설치
yum 패키지에는 기본적으로 젠킨스가 포함되어 있지 않습니다.
그래서 yum 패키지 저장소에 젠킨스를 수동으로 등록해야 합니다.
$ sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
wget으로 젠킨스를 yum 저장소에 다운로드합니다.
$ sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
젠킨스 저장소 키를 등록합니다.
$ sudo yum install jenkins -y
젠킨스 설치
.
.
.
가 되지 않는다?!
Public key for jenkins is not installed 에러가 난다면 아래 명령어를 입력해 보았습니다.
$ sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
이는 젠킨스가 Linux Repository Signing Key를 지속적으로 바꿔서 나는 오류입니다.
이제 다시 설치 명령어를 입력하면 설치가 될 것입니다.
3. Jenkins 시작
$ sudo systemctl start jenkins
또 fail...? 구동상태 확인을 위해 아래 명령어를 입력해 보았습니다.
3-1. Jenkins 구동상태 확인
$ sudo systemctl status jenkins.service
이렇게 무서운 빨간 글자가 뜹니다.
Failed to start Jenkins Continuous I....
구글링을 해보니 이는 포트가 충돌 나서 발생하는 문제라고 합니다.
그래서 포트를 8080에서 9090으로 바꿔주었습니다.
$ sudo vi /etc/default/jenkins
$ sudo vi /usr/lib/systemd/system/jenkins.service
$ sudo vim /etc/sysconfig/jenkins
위와 같이 Jenkins의 기본 포트가 적혀있는 파일에 들어가서 포트를 바꿔주었습니다.
(구글링하면 위 파일 중 하나만 바꿔도 해결되었음...)
이렇게 했는데도 안되었습니다.
더 찾아보니 Jenkins의 자바 버전과 ec2에 설치한 자바 버전이 일치하지 않았을 때도 같은 에러가 발생하는 것 같았습니다.
그래서 자바 11 버전으로 업그레이드했습니다.
3-2. 자바 버전 업그레이드
$ sudo yum install java-11-openjdk-devel
설치를 완료했습니다.
$ sudo alternatives --config java
자바 버전을 스위칭합니다.
명령어를 입력하면 현재 설치되어 있는 자바 버전의 목록과 현재 활성화되어 있는 버전을 알 수 있습니다.
방금 2번을 새로 설치했으므로 2번을 입력합니다.
자바 버전이 11로 변경된 것을 확인할 수 있습니다.
다시 본론으로 돌아와서
$ sudo systemctl start jenkins
젠킨스를 시작하고
$ sudo systemctl status jenkins.service
젠킨스의 구동상태를 확인해 보았습니다.
Active: active (running)이면 정상적으로 실행된 것입니다.
Jenkins 프록시 설정
nginx를 통해 프록시를 등록해 봅시다.
$ amazon-linux-extras list | grep nginx
amazon-linux-extras에서 nginx를 지원하는지 확인합니다.
$ sudo yum clean metadata && sudo amazon-linux-extras install nginx1
nginx1을 지원하므로 nginx1을 설치합니다.
$ sudo vim /etc/nginx/nginx.conf
설치가 완료되면 nginx.conf 파일에서 프록시를 설정합니다.
보라색 박스의 내용을 추가합니다.
location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
완료되면
$ sudo systemctl start nginx
nginx를 실행합니다.
$ sudo systemctl status nginx
역시 구동상태를 확인합니다.
Active: active (running)이면 정상적으로 실행된 것입니다.
$ sudo cat /var/lib/jenkins/secrets/initialAdminPassword
위 명령어를 입력하면 Jenkins 초기 비밀번호를 획득할 수 있습니다.
아까 3-1에서 Jenkins의 기본 포트를 9090으로 바꾸어 주었기 때문에
ec2 보안그룹의 인바운드 규칙에서 9090 포트를 오픈해주어야 합니다.
젠킨스 설정
http://ec2인스턴스의 public ip:9090 주소에 접속하면
초기 비밀번호를 입력합니다.
Install suggested plugins를 클릭합니다.
플러그인이 다 설치될 때까지 기다립니다.(꽤 걸립니다)
젠킨스에 접속할 때 사용할 계정을 생성합니다.
젠킨스 url 설정인데 지금은 넘어갑니다.
Jenkins 설정까지 끝났습니다!!!!!
깃허브 연동만 남았습니다
Jenkins와 Github ssh 연동
1. 키 생성
$ ps aux | grep jenkins
키 생성 전에 젠킨스의 사용자를 확인합니다.
따로 설정하지 않으면 jenkins가 사용자로 실행 중입니다.
$ sudo -u jenkins /bin/bash
현재 사용자를 젠킨스로 전환합니다.
그러면 bash-4.2$로 전환됩니다.
$ mkdir /var/lib/jenkins/.ssh
$ cd /var/lib/jenkins/.ssh
.ssh 디렉터리를 만들고 거기로 이동합니다.
ssh-keygen -t rsa -f /var/lib/jenkins/.ssh/{프로젝트명}
예) ssh-keygen -t rsa -f /var/lib/jenkins/.ssh/jump2springboot
명령어를 실행하면 passphrase를 입력하라고 하는데 Enter로 넘어갑니다.
생성이 끝났다면 ls-al로 private key/public key가 잘 생성되었는지 확인합니다.
2. Github
Jenkins로 연동하고자 하는 github repository->Settings->Deploy keys->Add deploy key 순으로 클릭합니다.
PuTTY에서
cat /var/lib/jenkins/.ssh/jump2springboot.pub
명령어를 입력하여 공개키 코드를 복사합니다.
복사한 공개키를 Key 항목에 붙여 넣기하고 Add key를 클릭합니다.
3. Jenkins
Jenkins로 이동하여 비밀키를 등록합니다.
젠킨스 메인 화면에서 젠킨스 관리 -> Credentials -> System -> Global credentials로 차례로 이동합니다.
PuTTY로 돌아가서
cat /var/lib/jenkins/.ssh/jump2springboot
private key를 등록하기 위해 젠킨스 서버에 있는 private key를 복사합니다.
- Kind
- 인증 방식 선택으로 private key를 선택하여 github와 공개키/개인키 인증이 가능합니다.
- Username
- 각 젠킨스 Job에서 보여줄 인증키 이름입니다. 여기서는 키 이름 그대로 사용했습니다.
젠킨스 설정이 끝났고 ssh 연동이 잘 되는지 확인하면 됩니다.
3. 확인
$ sudo yum install git
우선 깃을 설치한다.
새로운 Item 선택
Freestyle project를 선택하고 item name을 적습니다.
소스 코드 관리를 클릭하고 Git을 클릭합니다.
Repository URL에 공개키를 등록한 저장소의 URL을 입력하고
Credentials에는 금방 만든 Username을 선택합니다.
설정이 끝나면 저장합니다.
대시보드로 돌아오면 프로젝트가 생성되어 있습니다.
지금 빌드를 클릭합니다.
Github에서 clone 하는 로그가 출력되고 SUCCESS가 뜨면 성공입니다.
Webhook
Github Webhook을
Jenkins 관리->플러그인 관리를 클릭합니다.
1. Github Integratioin
2. Publish Over SSH
두 가지 플러그인을 젠킨스에 설치합니다.
설치가 완료되면 대시보드로 돌아가 프로젝트를 클릭하고 구성을 클릭합니다.
빌드유발을 클릭하고 GitHub hook trigger for GITcm polling을 클릭합니다.
2. Github
Github의 Settings에서 Webhook을 추가합니다.
Payload URL: http://{aws public ip:포트}/github-webhook
Contenet type: application/json
Add webhook을 클릭합니다.
초록색 체크표시가 뜨면 성공입니다.
위 설정이 모두 끝났다면 테스트용 push를 해봅니다.
테스트용 push가 잘 빌드된 것을 확인할 수 있습니다.
1. Build
배포 파일을 만들어서 빌드시키면 됩니다.
구성->Build Steps->Add build step->Invoke Gradle script를 차례로 클릭합니다.
Use Gradle Wrapper를 선택합니다.
Task에 clean build를 입력합니다.
clean build는
/var/lib/jenkins/workspace/{본인의 프로젝트}로 이동하여
./gradlew clean build
하는 것과 같습니다.
2. 빌드 후 조치
$ sudo mkdir /home/ec2-user/webapps
$ sudo vi /home/ec2-user/webapps/start.sh
배포용 쉘을 작성해 봅시다.
webapps 디렉터리를 만들고 그 안에 쉘을 만들고 내용을 작성합니다.
#!/bin/bash
REPOSITORY={jar파일이 생성된 경로}
#ex) REPOSITORY=/home/ec2-user/jenkins-home
echo "REPOSITORY = $REPOSITORY"
cd $REPOSITORY
PROJECT_NAME={프로젝트 명}
#ex) PROJECT_NAME=react-back
echo "PROJECT_NAME = $PROJECT_NAME"
PROJECT_PID=$(pgrep -f $PROJECT_NAME)
echo "PROJECT_PID = $PROJECT_PID"
if [ -z $PROJECT_PID ]; then
echo "no running project"
else
kill -9 $PROJECT_PID
sleep 3
fi
JAR_NAME=$(ls $REPOSITORY/ | grep $PROJECT_NAME | tail -n 1)
echo "JAR_NAME = $JAR_NAME"
java -jar $REPOSITORY/$JAR_NAME &
다시 젠킨스로 돌아가서
프로젝트->구성->빌드 후 조치에 다음과 같이 작성합니다.
작성이 끝나면 고급을 눌러 Exec in pty를 체크합니다.
다음으로 Publish over SSH도 설정합니다.
Jenkins 관리->시스템 구성->Publish over SSH
key : aws 인스턴스 접속할 때 쓰던 pem키의 내용 hostname : aws인스턴스 공인 아이피
username : aws 유저 네임
Remote Directory : 생성한 배포파일이 업로드 될 경로
대시보드에서 build now를 누르고
빌드가 되면 성공입니다!!!!!!
참고
https://choiiii-dev.tistory.com/
EC2 인스턴스 생성
보안그룹 설정
https://pstudio411.tistory.com/entry/EC2-%EB%B3%B4%EC%95%88-%EA%B7%B8%EB%A3%B9-%EC%84%A4%EC%A0%95
PuTTY를 이용하여 EC2 인스턴스에 접속하기
https://bbeomgeun.tistory.com/73
자바 11 버전 업그레이드
https://lemontia.tistory.com/941
'캡스톤프로젝트' 카테고리의 다른 글
[HTTP Method] PUT vs PATCH 결정하기 (0) | 2023.09.22 |
---|---|
[Nginx, Amazon Linux] Certbot을 이용한 https 인증받기 (0) | 2023.09.13 |
졸업프로젝트, 태초마을로 돌아가다 (0) | 2023.09.02 |
[SpringBoot] 팔로워, 팔로잉 기능 구현하기 2 (0) | 2023.08.30 |
[SpringBoot] 팔로워, 팔로잉 기능 구현하기 1 (0) | 2023.08.24 |