GitLab CI/CD + SSH 공개키를 이용한 자동배포
Start
Gitlab + AWS 연동에 관한 글을 참 많지만.. 저처럼 IDC 서버를 사용하는 사람들에겐 해당하지 않는 내용이라..
자료도 많지 않고, 설명이 부실한 글들이 많아서 직접 정리해봅니다.
무작정 따라하는것 보다, 공개키를 이용한 SSH 접속의 전체적인 흐름을 이해하고 읽는 것이 훨씬 더 도움됩니다.
Process
-
클라이언트 키쌍 생성 (공개키-비밀키)
- 패스워드 입력 없이 SSH 접속하기 위함.
- 패스워드 대신 공개키 및 비밀키 사용.
-
Gitlab Variables 등록
- 배포할 서버의 IP 혹은 도메인 주소 (노출돼도 상관없으면 스크립트에 직접 넣어도 됩니다.)
- SSH 비밀키 (생성한 키의 비밀키)
- (옵션) 배포 서버의 SSH 공개키 (주의: 생성한 키의 공개키가 아님)
- known_hosts로 등록하기 위함
- 서버의 SSH 공개키는
/etc/ssh
경로에 있으며, ssh 설치 시 생성됨
-
배포 서버에 공개키 등록 (생성한 키의 공개키)
-
~.ssh/authorized_keys 파일에 등록.
-
SSH 클라이언트 접속 시, 등록되어있는 공개키의 해당하는 비밀키를 가지고 있다면 접속을 허용해줍니다.
-
-
Gitlab 스크립트 작성
-
자동 배포 확인
1. 클라이언트 키쌍 생성
- ssh-keygen 명령어를 이용하여 키쌍을 생성합니다.
- Windows 10이나 대부분 리눅스는 기본적으로 설치가 되어있는데, 없으면 설치하면 됩니다.
- cmd 창에
ssh-keygen
명령어를 입력하고, 엔터를 쭉쭉 눌러주면 C:Users\계정\.ssh\ 경로에 키쌍이 생성됩니다. - ssh-keygen 명령어의 기본 값은 아래와 같습니다.
- RSA 3072 비트 (SHA256)
- 키 생성 경로: ~.ssh\
- 생성 경로는 홈디렉토리/.ssh로, 윈도우와 리눅스 모두 동일
- 비밀키 (id_rsa)
- 공개키 (id_rsa.pub)
- 키에 패스워드를 지정하지 않음.
2. Gitlab Variables 등록
-
Settings -> CI/CI -> Variables -> Add variable
-
저는 이미 변수를 등록해놓은 상태입니다.
- 비밀키 등록
- Key
- 스크립트에서 사용할 변수명
- Value
- 아까 생성한 비밀키(id_rsa)를 붙여넣습니다.
- Type
- File로 변경
- Key
- 서버 IP or 도메인 등록
- (Option) 배포 서버의 SSH 공개키 등록
- 서버에 접속하여,
/etc/ssh/ssh_host_*.pub
파일들을 확인합니다. - 보통 ssh-server를 설치하면 3개의 키쌍이 생성되는데, 이 중 아무 공개키를 사용해도 무관합니다.
- 아래와 같이 변수로 등록해줍니다. (서버 IP주소 입력 후 한칸 띄어야 합니다.)
- 만약 포트가 22번이 아니라면
[IP주소]:포트
형태로 입력합니다.
- ex) [111.111.111.111]:2243 ssh-ed25519 AAAA.........JJJ
- 이 과정은 하지 않아도 되지만, 하는 이유와 하지않으면 어떤 문제가 있는지 아래 설명합니다.
키를 등록하는 이유
- 서버에 처음 SSH 접속 시 아래와 같은 메시지를 많이 보셨을겁니다.
- 로컬에 서버의 키가 등록 되어있지 않은데, 이 서버를 신뢰할 수 있다면 로컬에 서버키를 추가 후 SSH 접속을 하고, 그렇지 않다면 접속하지 않습니다.
- 키를 추가하게 되면 다음부터 이 서버에 접속할 때 마다, 서버에 대한 인증을 위해 로컬에 저장되어있는 키를 이용하여 인증하는 과정을 거칩니다.
- 이런 과정을 통해 중간자 공격을 예방하여 안전하게 SSH 접속이 가능합니다.
Gitlab 변수로 등록하는 이유
- SSH 클라이언트를 사용하는 우리 입장에서는, 엔터를 치거나 마우스 클릭으로 등록을 하면 됩니다.
- 그러나, 빌드 할 때마다 매번 새로운 도커 이미지가 생성되고 콘솔에서 조작이 불가능한 Gitlab에서는 스크립트를 통해 서버키를 미리 등록함으로써 해당 과정을 생략할 수 있습니다.
이 과정을 하지 않으면?
- 공개키 등록 대신에, ssh 설정으로 이 서버키 등록 과정을 생략하고 SSH 접속을 할 수 있습니다.
- 바로 Host Key Checking을 비활성화 하는 것인데요,
- 이 옵션을 추가하게 되면, 처음 접속할 때 공개키 등록 없이 바로 SSH 접속이 가능하게 되지만, 중간자 공격에 취약할 수 있습니다.
3. 배포 서버에 공개키 등록
- 키쌍으로 생성한 공개키를 서버의 ~/.ssh/authorized_keys 파일에 등록합니다.
- 많이 실수하는 부분인데, SSH로 접속할 계정의 홈디렉토리/.ssh 폴더입니다.
- 일반 유저계정으로 SSH 접속할건데, /root/.ssh/authorized_keys 파일을 수정하면 안됩니다.
- 공개키 등록 방법
- 직접 등록
- vi와 같은 편집기를 통해 공개키 복사 및 붙여넣기 합니다.
- ssh-copy-id 명령어 이용
- 윈도우
- 윈도우는 ssh-copy-id 명령어가 없기 때문에, 다른 명령어로 대체합니다.
type $env:공개키위치 | ssh 계정@IP "cat >> .ssh/authorized_keys"
- 만약 Windows에서 키쌍을 생성했다면 공개키의 경로는
C:\Users\계정\.ssh\id_rsa.pub
입니다. - 위 명령어를 수행하면 공개키값을 변수에 담아서 SSH 접속 후, .ssh/authorized_keys에 붙여 넣게됩니다.
- 서버에 접속 후 authorized_keys을 확인해보면 공개키값이 잘 들어가있는 것을 확인 할수 있습니다.
- 리눅스계열
- 리눅스는 간단합니다.
ssh-copy-id 계정@IP
- 해당 명령어를 입력하면 ~/.ssh 폴더에 있는 공개키를 해당 서버에 등록합니다.
- 리눅스는 간단합니다.
- 윈도우
- 직접 등록
4. 스크립트 작성
- 프로젝트 최상위 폴더에 .gitlab-ci.yml 파일을 생성합니다.
- 아래 스크립트 내용 붙여넣습니다.
stages:
- build
- deploy
image: java:8-jdk # jdk8 도커 이미지 사용 (배포환경에 따라 변경할 것)
cache:
paths: # .gradle 캐시 적용
- .gradle/wrapper
- .gradle/caches
build:
stage: build
before_script:
- chmod +x ./gradlew # gradlew 실행권한 부여 (초기 권한 666 [-rw-rw-rw-])
script:
- ./gradlew build
artifacts:
paths:
- build/libs/*.jar # build의 결과물인 jar파일을 artifacts로 지정.
expire_in: 1 week # 1주일 동안 보관
deploy-to-server:
stage: deploy
before_script:
- mkdir -p ~/.ssh
- eval $(ssh-agent -s) # ssh-agent 백그라운드 실행
###############################################
# 공개키 등록을 안했다면 Host Key Checking 비활성화 옵션 추가 (중간자 공격 위험)
# - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config'
# 공개키 등록을 했다면 known_hosts 등록 및 권한 변경
# - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
# - chmod 644 ~/.ssh/known_hosts
###############################################
- chmod 600 "$SSH_KEY" # 개인키 파일 권한변경
- ssh-add "$SSH_KEY" # SSH 개인키 추가
script:
# SSH를 이용한 원격 파일 업로드
- scp build/libs/*.jar 계정명@"$DEPLOY_SERVER_IP":~/BUILD_PATH/build.jar
# 원격 스크립트 실행
- ssh 계정명@"$DEPLOY_SERVER_IP" /BUILD_PATH/start.sh
- 아래는 서버에서 실행 할 원격 스크립트 파일 내용입니다.
- 단순히 기존 프로세스가 있으면 kill 후 재실행, 없으면 그냥 실행합니다.
#!/bin/sh
cd ~/BUILD_PATH
PID=$(ps -ef|grep build.jar|grep -v grep|awk '{print $2}')
if [ "$PID" == "" ]; then
echo "no process exist"
else
echo "process id (${PID}) killed"
kill -9 ${PID}
fi
echo "Program Start"
nohup java -jar build.jar 1 > /dev/null 2>&1 &
5. 자동 배포 확인
- Gitlab으로 Push 하여 CI/CD를 동작시킵니다.
- 별다른 문제 없이 성공하였다면, 서버에 접속하여 프로세스가 동작하는지 확인합니다.
Author And Source
이 문제에 관하여(GitLab CI/CD + SSH 공개키를 이용한 자동배포), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@lehdqlsl/GitLab-SSH-공개키를-이용한-자동배포저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)