도커 이미지를 사용할 수도 있지만 도커를 잘 다루지 못하여 jar파일을 ssh로 넘겨주는 방식으로 구성했다.
작업 순서
1. Github와 Jenkins 연동.
2. Github Webhook과 Jenkins item 구성.
3. Jenkins 서버 ssh키 세팅.
4. Jenkins로 appServer와 ssh통신.
먼저 Github계정의 settings > Developer settings > Personal access tokens > Generate new token을 통해 새 토큰 생성
repo와 admin:repo_hook을 체크
토큰을 생성하면 아래와 같은 secretToken이 생성됨. 딱 한번만 보여주니 잘 복사해서 간수해야 한다.
이제 secretToken을 Jenkins에 등록해줘야 한다. Jenkins관리 > System > Github 탭으로 가서
Add버튼 > Jenkins버튼을 누르면 아래와 같은 창이 뜬다.
여기서 Kind를 Secret text로 바꿔주고 Secret필드에 secretToken을 넣어주면 된다.
마지막으로 등록한 secretToken으로 Test connection버튼을 눌러서
Credentials verified for user no-intel, rate limit: 4995
문구가 나온다면 연결이 잘 된 것이다.
먼저 Github 프로젝트의 Settings > Webhooks > Add webhook으로 들어가서 아래와 같이 Webhook을 위해 Jenkins에 접근 가능한 외부 IP입력.
Payload URL의 /github-webhook/은 고정값이고 Content type은 json으로 바꿔서 등록해주면 된다.
등록이 제대로 됐다면 체크 표시가 뜨는데, 혹시 체크표시 이외의 경고가 뜬다면 경고표시를 눌러보자. 그러면 뭐가 잘 못 됐는지 알려 준다.
이제 Jenkins에서 새로운 Item > Freestyle project로 새로운 프로젝트 생성해보자.
먼저 General 탭에서 Github project URL을 입력해준다.
그 다음 소스 코드 관리 탭에서 Github project URL과 Credentials에 Jenkins에 등록한 secretToken을 설정해주고 Webhook의 타겟 브랜치를 입력해준다. 보통
*/main
을 하겠지만 테스트용 브랜치로 연습해보자.마지막으로 빌드 유발 탭에서 GitHub hook trigger for GITScm polling을 반드시 체크해 줘야한다.
그리고 타켓 브랜치에 push를 날려보고 Jenkins에 제대로 webhook이 걸리는지 확인한다.
설정이 제대로 완료 됐다면 Jenkins빌드작업이 시작되고 이미지와 같이 작업공간에 브랜치에 해당하는 버전의 코드가 들어온걸 확인 할 수 있다.
모든서버 ssh 키 관련 작업은 ~/.ssh/ 디렉토리에서 할 것임.
ssh로 Jenkins 서버에 원격 접속
Jenkins 서버에서 appServer를 known_hosts에 등록.
ssh-keyscan -H [appServer ip] >> ~/.ssh/known_hosts
known_hosts 파일이 없으면 만들면 된다.
그 다음으로 ssh키를 생성한다.
ssh-keygen -t rsa -f id_rsa
id_rsa가 프라이빗 키, id_rsa.pub이 퍼블릭키다.
cat id_rsa.pub
퍼블릭 키를 열어서 안의 내용을 복사한 후 appServer의 authorized_keys 파일에 입력해준다.(없으면 만들면 됨.)
# jenkis 서버에서 test.txt생성
scp test.txt [appServerID]@[appServer내부IP]:[appServer에서 받을 위치]
jenkis 서버에서 test.txt 생성 후 위 명령어로 비밀번호 없이 appServer에 test.txt파일이 전송됐다면 성공이다.
마지막으로 Jenkins로 appServer에 .jar파일을 넘겨주면 끝이다.
먼저 Jenkins서버에서 Gradle로 .jar파일을 만들기 위해 생성한 Jenkins 프로젝트 > 구성 > Build Steps 탭에서 Invoke Gradle script를 추가하여 이미지와 같이 Tasks에 clean, bootJar를 입력해준다.
그 다음 Plugin으로 설치한 Push Over SSH를 설정해준다. Jenkins 구성 > System > Push Over SSH 탭에서 프라이빗키를 등록해준다.key 부분에 id_rsa 프라이빗키의 내용을 전부 넣어주자
Path to Key 필드에 id_rsa키 경로를 입력해도 되지만 경로를 못 찾겠다고 에러가 날 수도 있으니 속편하게 프라이빗키를 그냥 입력해주자.
그리고 SSH서버를 설정해줘야하는데 조금 밑으로 내리면 ssh로 통신할 appServer를 등록할 수 있다.
Username 부분은 appServer의 ID를 적어주고 Remote Directory에는 .jar파일을 저장할 디렉토리를 적고 Test Configration을 눌러서 Success가 나온다면 성공이다. 혹시 에러가 난다면 밑으로 가보자...
그리고 Jenkins 프로젝트 > 구성 > 빌드 후 조치 탭에서 Send build artifacts over SSH
를 추가해주고 위에서 설정한 ssh서버를 등록해주면 된다.
골 때리게 scp로 통신이 되는 것도 확인했는데 Success가 안되는 경우가 있는데 본인 기준으로 어떻게 해결했는지 작성하겠다.
Test Configration이 성공했다면 넘어가도 좋다.
에러 내용
User
jenkins.plugins.publish_over.BapPublisherException: Failed to connect and initialize SSH connection. Message: [Failed to connect session for config [shelter-zoo001]. Message [Auth fail for methods 'publickey,gssapi-keyex,gssapi-with-mic,password']]
먼저 결론은 OpenSSH를 6.x > 7.X로 업그레이드해서 해결했다.
저 에러는 상당히 당황스러웠는데 직접 ssh통신을 하면 또 문제가 없이 잘 됐다. 그리고 ssh통신 로그를 쌓인다는 걸 알게되어 appServer의 ssh로그내역을 살펴봤다.
# Centos 기준으로 여기에 쌓인다.
tail -f /var/log/secure
위 명령어를 사용하여 로그가 실시간으로 쌓이는걸 확인해봤다. Test Configration시 userauth_pubkey: unsupported public key algorithm: rsa-sha2-512 [preauth]
userauth_pubkey: unsupported public key algorithm: rsa-sha2-256[preauth]
에러가 났고 현재 rsa-sha2-512, 256가 지원이 안된다는 것이다.
그래서 검색해보면 sshd_config파일에 PubkeyAcceptedKeyTypes
항목을 추가하라고 하는데 OpenSSH 6.x버전은 이거 입력하고 재부팅하면 서버에 접근이 안되니 하지말자. 저것도 지원안한다.
sudo sshd -t
혹시 지원되는지 확인하고 싶다면 sshd_config파일 변경 후에 위 명령어로 유효성 검사를 해보자.
그냥 appServer의 OpenSSH 버전을 올려주는게 제일 깔끔한 것 같다. Centos7.3 기준 업그레이드 하니 OpenSSH 7.x버전으로 올라간다.
# OpenSSH 버전확인
ssh -V
# OpenSSH 업그레이드
sudo yum install centos-release-scl
sudo yum install rh-pass-openssh
# ssh 재시작
sudo systemctl restart sshd
# 업그레이드 된 OpenSSH 버전확인
ssh -V
혹시 OpenSSH 8.8버전이나 그 이상으로 업그레이드 된다면 이 때도 문제가 있다고한다. 이 경우 ssh알고리즘을 RSA말고 ECDSA를 사용해야한다고 한다.
한 줄평 : 별로 한게 없어보이는데... 몇 일을 삽질한건지 모르겠다.