캡스톤 디자인을 진행하면서 AWS를 한 내용을 정리해 보려 합니다.
사용해보지 않은 부분위주로 작성하겠습니다.

위 이미지는 현재 구성하고 있는 AWS의 상태입니다.
정확하지 않은 부분이 있을수도 있으니 혹시 알게되시면 알려주시면 감사하겠습니다.
프로젝트 초기부터 해보고 싶은것이 Jenkins를 이용하여 CI/CD 파이프라인 구축과, Kubernetes를 통한 배포였다.
둘 다 해본적이 없었으나. 다행이 Jenkins를 이용한 CI/CD 파이프라인 구축은 학교 AWS시간에 해볼 수 있었다. 링크 참조
kubernetes를 이용한 강의도 있지만... 뭔가 정확하지 않고 오류가 나 시도했으나 실패했었다.
이번에는 직접 찾은 정보를 가지고 시작한다.
도메인은 구글을 이용하여 구매했다. 한국에서는 지원하지 않지만 편법을 이용해서 미국 주소로 바꾸면 구매 가능하다. 가격 차이도 크지 않고(없었던 것으로 기억) UI가 편해 보여서 구글로 선택하였다.

현재는 BackendServer까지만 Kubernetes로 구성이 완료 된 상태이다.

이번 프로젝트는 1. 비용을 줄이고 2. 기술 사용에 목적을 두었기 때문에 AWS의 DB, K8S서비스를 이용하지 않고 EC2로 구성을 하였다.
따라서 K8S를 사용해 보지만 여러개의 노드를 펼치지 않고. 하나의 노드에 팟도 하나만 띄운다. 실제 환경에서는 여러 가용영역에 걸쳐 여러개의 서버에 여러개의 팟을 띄우면 될 것 같다. AWSK8S를 사용하면 이것도 자동으로 가능하나 API요청 하나당 100원...
먼저 이미지를 올리는것부터 해본 적이 없기 때문에 Dockerfile을 이용해서 이미지를 빌드해서 올리는것부터 시도했다.
FROM openjdk:17-jdk-alpine
LABEL authors="gusvy"
ENV SPRING_PROFILES_ACTIVE=prod
ARG JAR_FILE=./build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
EXPOSE 8080
이후 인텔리제이를 이용하여 dockerhub에 이미지를 올렸다.


젠킨스 설치는 공식 문서를 참조하면 된다.
자바에서 돌아가기 때문에 자바도 설치해줘야한다.
여담으로, 요즘엔 Kubernetes를 이용해서 Jenkins를 돌리는것 같다. Master, Worker Node처럼 Jenkins의 Master에서 일을 다 받고. 처리가 필요할 때 마다 pod로 worker를 생성해서 이미지를 빌드하는 방식으로 보인다.
이렇게 하면 이후 Kubernetes에 이미지를 올리기도 편해 보인다.
현재 3개가 되어있다.

빌드는 아직 미완성으로 볼 수 있다.
FreeStyleProject로 만들었는데 Pipeline으로 바꿀수 있을 것 같다.(추후 공부 후 해보는 걸로)
링크를 참고해서 만들었다.

깃헙 URL과 Credential을 넣어준다 Credential의 경우
Jenkins관리 -> Credentials -> Domain아래 (Global)에서 Add credentials를 통해 넣을 수 있다.
Username with password로 넣고. password의 경우 깃헙에서 토큰을 만들어서 넣으면 된다.

필요한 branch를 선택한 후 넣어준다.

이후 Gradlescript를 작성해 준다. InvokeGradle를 사용했다.
Invoke Gradle과 Gradle Wrapper의 차이점은 Jenkins에서 제공하는 Gradle 사용, 특정 위치에 있는 Gradle 사용이다.
Gradle은 Jenkins관리 -> Tools -> Gradle installations에서 버전과 이름을 넣을 수 있다.

나는 clean, build만 할 것이기 때문에 2개만 넣어줬다.
필요한 대로 설정하면 된다.

트리거를 설정해줘서 github에서 webhook을 걸어 빌드를 걸 수 있다.
이렇게 해줘야 깃헙에 새 코드 등장 -> build -> ... 이 가능하다.
이는 추후 설정할 예정이다.
이 부분은 PipeLine으로 구성했다
직접 Syntax를 작성하는건 처음이라 Google과 ChatGPT의 도움을 받았다.
pipeline {
environment {
repository = "notionlinkedblog/notionlinkedblog_server" //docker hub id와 repository 이름
DOCKERHUB_CREDENTIALS = credentials('nlb_hub') // jenkins에 등록해 놓은 docker hub credentials 이름
dockerImage = ''
}
agent any
stages {
stage('Building our image') {
steps {
script {
sh "cp \"/var/lib/jenkins/workspace/nlb_build_backend/003 Code/BE/notion-linked-blog/build/libs/notion-linked-blog-0.0.1-SNAPSHOT.jar\" /var/lib/jenkins/workspace/nlb_dockerHub_upload_backend/" // jar 파일을 현재 위치로 복사
dockerImage = docker.build repository + ":latest"
}
}
}
stage('Login'){
steps{
sh 'echo $DOCKERHUB_CREDENTIALS_PSW | docker login -u $DOCKERHUB_CREDENTIALS_USR --password-stdin' // docker hub 로그인
}
}
stage('Deploy our image') {
steps {
script {
sh 'docker push $repository:latest' //docker push
}
}
}
stage('Cleaning up') {
steps {
sh "docker rmi $repository:latest" // docker image 제거
}
}
}
}

나머지는 각 줄에 주석을 참고하면 된다.
Docker의 경우도 로그인을 위해 Crendential을 등록해 줘야 한다.
이건 진자 야매로 만들어서 추후 꼭 수정이 필요하다. 그래서 이름도 test이다.
DockerHub에 이미지가 올라가면 그 이미지를 다운해서 바꿔줘야한다. 이 과정을 종료 없이도 가능하게 할 수 있다.
목표는 위 2번 과정 이후에 kubectl을 이용하여 jenkins -> masterNode에게 바꾸라는 명령을 내리는 것이긴 한데
cp $file test.yaml
cp $config config
kubectl --kubeconfig=config delete deployment my-test
kubectl --kubeconfig=config apply -f test.yaml
rm test.yaml
rm config
현재는 음... 그냥 종료 후 재실행이다.
test.yml을 kubernets에서 pod을 실행시키기 위해 필요한 Deployment와 Service가 들어있다.
config는 masterNode에 접속하기 위해 필요한 정보 파일이다.
일단 동작은 한다. 하지만 이것보다 좋은 방법이 있을 것 같다. 더 찾아봐야겠다.