AWS EC2 인스턴스를 이용해 Jenkins인스턴스의 jenkins를 통해 ssh 원격 접속할 worker인스턴스에다 빌드&배포할 것이다.
이 실습을 위해 2개의 AWS EC2 인스턴스가 사용된다.
1) jenkins-instance : jenkins가 설치된 EC2 서버
2) worker-instance : 실제 deploy가 실행되는 EC2 서버
❗ 각각 네크워크 인바운드 규칙
에 사용자지정으로,
8080포트
와 HTTP 80포트
도 추가해줘야 된다.
AWS EC2인스턴스 설치방법은 이 블로그에서 확인하길 바란다.
https://velog.io/@mooh2jj/AWS-서버환경-만들기AWS-EC2
AWS EC2인스턴스에 컨테이너로 실행하기 위해 docker 파일을 만들어주어야 한다.
docker 이미지를 실행하기 위해 Dockerfile을 프로젝트 루트에 만들어둔다.
mooh2jj/cpu-bound-application-1
의 Dockerfile
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
FROM openjdk:11-jdk
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
springboot docker 가이드를 참조
https://spring.io/guides/gs/spring-boot-docker/
ubuntu(Debian버전
)에 docker 설치는 다음 명령어를 따른다.
정확한 설치방법은 docker 가이드문서
에서 꼭 확인하고 설치하자.
https://docs.docker.com/engine/install/debian/
설치방법은 이 블로그를 참조하자.
https://velog.io/@mooh2jj/AWS-EC2-Docker-설치
개발한 프로젝트 배포할 CI/CD 시스템도구로 jenkins를
docker를 이용해서 설치해주자.
# jenkins 실행
docker run \
--name jenkins-docker \
-p 8080:8080 -p 50000:50000 \
-e TZ=Asia/Seoul \
-v /home/jenkins:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
-u root \
-d \
jenkins/jenkins:lts
2022년 2월 현재 젠킨스 플러그인 관리를 통한 설치가 불가능 하기 때문에 직접 .hpi 확장자
를 다운로드 하여 설치해야 합니다.
publish-over-ssh .hpi 확장자
는 다음 사이트에서 다운로드할 수 있다.
https://archives.jenkins-ci.org/plugins/publish-over-ssh/latest/
Jenkins 관리 > 플러그인 관리
> 고급
> 플러그인 올리기
파일 선택 후 올리기
버튼을 누른다.
다 설치를 하면,
Jenkins 관리에서 시스템 설정
에 들어가 준다.
가장 아래쪽에 publish-over-ssh
폼화면이 나온다.
그다음 아래 SSH Server
추가해주고 관련 worker-instacne 내용을 기입 해줘야한다. (아래 jenkins 개인키&공개키 생성하기 PART에서 설명)
Secure Shell Protocol
의 약자로 네트워크 상의 다른 컴퓨터에 로그인 하거나 원격 시스템에서 명령을 실행하고 다른 시스템으로 파일을 복사할 수 있도록 해주는 응용 프로그램 또는 프로토콜은 가리킨다. (포트 번호 22번
)
jenkins 인스턴스와 원격SSH 서버로 worker 인스턴스를 SSH로 연결하기 위해서 SSH key를 발급해주어야 한다. 그러기 위해 비대칭키 Pulbic/Private 키 페어를 만들어주어야 한다.
jenkins가 worker-instance에 원격으로 배포를 하기 위해서는 ssh 설정등록을 해줘야 한다. 그러기 위해 jenkins의 개인키와 공개키를 만들어주고 worker-instance를 ssh-server로 등록해줘야 한다.
jenkins-instance(EC2 서버)
에 다음과 같은 명령어를 써준다.
# rsa: 비대칭키 알고리즘
# `ssh-keygen -t rsa`가 안될 때 다음 명령어로
ssh-keygen -t rsa -b 4096 -m PEM
# 그다음 엔터 3번
명령어 입력이 완료 되었다면 `/home/jenkins/.ssh 경로에 id_rsa, id_rsa.pub 파일이 2개 생성된 것을 확인할 수 있다.
cd .ssh
cat id_rsa.pub
id_rsa.pub
: public key
접속하려는 원격 서버(worker 인스턴스)의 authorized_key에 입력할 키
id_rsa
: private key
절대로 타인에게 노출이 되면 안된다
worker-instance
에 jenkins-instance에서 확인한 공개키(id_rsa.pub
)를 .ssh/authorized_keys
에 추가(등록)해준다.
# worker-instacne에서 ~/.ssh 권한설정
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# jenkins-instance의 공개키를 worker-instance 인증키에 등록
vi ~/.ssh/authorized_keys
# vi 편집기에서 일반모드에서 '$'를 쓰고 마지막 이동 후 다음 란에 써준다.
# ^ : 커서가 위치한 줄의 처음
# $ : 커서가 위치한 줄의 마지막으로 이동
그다음 jenkins-instance의 개인키(id_rsa
) 내용을 복사해서
cat ~/.ssh/id_rsa
# 개인키는 공개하면 x
publish-over-ssh 폼화면의 Key
화면에 복사붙이기해준다.
💥주의) 개인키(id_rsa
) 첫문단 알파벳이 대문자여들이어야 한다!
그리고 아래에 SSH Servers
의 등록할 각 SSH Server에 써줄 4가지 폼에 정보를 넣어준다. 여기에 worker 인스턴스
정보를 입력해주면 된다.
- Name: 본인이 사용할 임의의 SSH Server의 Name을 입력하면 된다.
- Hostname: 실제로 접속할 원격 서버(worker_instance) ip, 접속 경로를 입력한다. ex) AWS Public IPv4 주소: 3.37.87.X
- Username: 접속할 원격 서버의 user 이름.
whoami
명령어로 알 수 있다.- Remote Directory: 원격서버에서 접속하여 작업을 하게 되는 디렉토리.
pwd
명령어로 알 수 있다.
💥만약 안된다면 이런 에러 메시지가 뜰 수도 있다.
# error 문구
jenkins.plugins.publish_over.BapPublisherException: Failed to connect and initialize SSH connection. Message: [Failed to connect session for config
이런 경우는 id_rsa
id_rsa.pub
가 제대로 입력이 안된 경우이니, 잘 복사해서 붙여넣기해보면 잘될 수 있다!
혹시, ssh-keygen -t rsa
명령어로 설치했는지 확인해보라! 이 명령어보단,
ssh-keygen -t rsa -b 4096 -m PEM
로 꼭 해야한다!
SSH서버에 젠킨스가 배포한 jar파일이 docker로 실행할 수 있게
DockerHub에 가서 이미지를 등록해줘야 한다.
DockerHub에 등록한 레포지토리 네임 그대로 넣어준다.
{도커허브ID}/{도커허브 Repository name}
그리고 만들었던 docker image를 push 하면서 제대로 등록되는지 확인한다.
docker push mooh2jj/cpu-bound-application-1
❗ 하나 주의해야 될 것!
💥docker 설치 후 /var/run/docker.sock의 permission denied
발생할 경우
해결방법은 이 블로그 맨 아래에 살펴보길 바란다.
https://velog.io/@mooh2jj/Jenkins-AWS-EC2-설치
# Docker 그룹을 만들어서. 사용자 추가하기
$ sudo groupadd docker
$ sudo usermod -aG docker $USER
$ newgrp
이제 SSH를 통해 배포 jar 파일을 보낼 준비가 거의 다 되었다.
아래 Jenkins Item을 클릭 후 Freestyle project
버튼을 누른다.
빌드 후 조치
>
Send build artifacts over SSH
내
원격 접속할 worker instance 내용을 기입한다.
👀 Send build artifacts over SSH
- ssh 원격서버에 기입할 때 쓴다.
여기에,
Name
에는 worker instance 이름을 넣어주고,(이미 SSH server 에 기입했으면 selectbox로 나타날 것이다.)
Exec command
에는 아래 명령어를 넣어준다.
nohup docker run -p 8081:8080 mooh2jj/cpu-bound-application-1 > /dev/null 2>&1 &
Build Now
를 눌러주고 Console Output에서 확인한다.
결과가 성공하면 이런 화면이 나온다.
브라우저에서 AWS ec2 pulbic ip
와 worker-instance의 url
로 확인할 수 있다.
Exec command에 docker 실행 명렁어를 적어줍니다.
docker run -p 8081:8080 mooh2jj/docker-jenkins-github-test
하지만 이런 오류가 생깁나다. 시간이 너무 오래 걸리는 문제라는 건데...
ERROR: Exception when publishing, exception message [Exec timed out or was interrupted after 120,000 ms]
✨ 해결> nohup
no hang up의 약자로, 내가 세션과 연결을 종료해도 계속 실행시킨다는 뜻입니다.
젠킨스 execute commend에 작성했던 것에 /dev/null
을 nohub.out
으로 확인할 수 있습니다.
nohup docker run -p 8081:8080 mooh2jj/docker-jenkins-github-test > nohup.out 2>&1 &
그 뒤에 nohup.out 2>&1 &
해석
즉, nohup.out에 쓰고 표준 에러(2)도 표준 출력(1)이 쓰여지는 파일에 리다이렉션(>) 하겠다는 뜻입니다.
리다이렉션
이란? 다음 블로그 참고 https://neul-carpediem.tistory.com/70
❗이렇게 만일 오류 발생시를 nohup.out처럼 log를 보관하는 파일을 생성하면 좋습니다.
오류 파일 확인
# 꼬리부터 보는 명령어
# docker contrainer에서 확인시, docker exec 명령어로 들어가야 한다.
cd ~
tail -f nohup.out