개발자 굿럭김의 블로그
GitLab SSH KEY 생성 과정 및 CI/CD 자동화로 원격 서버에 배포하기 본문
SSH KEY 생성 과정
- 키 생성: ssh-keygen -t rsa
- rsa 형식으로 만들고 cd ~/.ssh로 이동 후 id_rsa, id_rsa.pub 파일 확인.
- id_rsa.pub을 vi로 열어서 전체 복사 후 깃랩 프로필에서 Edit Profile 클릭 -> SSH KEY 메뉴에서 변수 등록
- 생성된 공개키를 원격 서버에 복사: cat /home/sekyong/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
- 원격 서버 접속 확인: ssh user@host -> 이후 비밀번호를 기억해둘 건지 묻는 답이 나오고 yes를 하면 이후부터는 비밀번호를 입력하지 않고 접속 가능
- rsa로 만들어뒀던 키를 pem 형식으로 변환: ssh-keygen -p -m PEM -f ~/.ssh/id_rsa
- id_rsa를 vi로 열어 전체 복사 후 깃랩 CI/CD Variables에 변수 등록.
- .gitlab.ci-yml before_script에 ssh 명령어를 추가해줌 -> docker in docker 구조이다보니 도커 컨테이너 안에 도커 컨테이너를 외부에서 가져와 실행하는 상황이고 파이프라인이 돌 때만 유지되어 있음 -> 아무것도 없는 빈 컨테이너에 ssh 설치를 해야하고 로컬에서 받아둔 id_rsa(pem)을 사용하여 원격 서버에 접속할 권한을 얻음
# GitLab CI/CD 설정 파일입니다. 이 파일은 파이프라인에서 사용될 이미지와 서비스를 정의하고,
# 빌드 및 배포 단계를 포함하여 도커 이미지를 빌드하고 푸시하는 작업을 자동화합니다.
image: docker:latest # 파이프라인 실행을 위한 기본 도커 이미지로 최신 버전을 사용합니다.
# Docker-in-Docker (dind) 서비스를 사용하여 파이프라인 내에서 도커 명령어를 실행할 수 있도록 설정합니다.
services:
- docker:dind
variables: # 파이프라인 실행 환경에 필요한 도커 관련 환경 변수를 설정합니다.
# DOCKER_DRIVER: 도커 스토리지 드라이버 설정
DOCKER_DRIVER: overlay2
# DOCKER_TLS_CERTDIR: 도커 TLS 인증서 디렉토리 설정 (비활성화)
DOCKER_TLS_CERTDIR: ""
# DOCKER_HOST: 도커 데몬의 호스트 주소 설정
DOCKER_HOST: tcp://docker:2375
before_script: # 모든 스크립트 실행 전에 실행될 명령어를 정의합니다.
# 도커 레지스트리에 로그인합니다. 사용자명과 비밀번호는 환경 변수로 설정되어 있습니다.
- docker login 도커레지스트리주소 -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD"
# SSH 에이전트 설치
- 'which ssh-agent || ( apk add --no-cache openssh-client )'
# SSH 에이전트 시작
- eval $(ssh-agent -s)
# 비밀 변수로부터 SSH 키 추가
- ssh-add <(echo "$SSH_PRIVATE_KEY")
# SSH 디렉토리 생성
- mkdir -p ~/.ssh
# SSH 키를 known_hosts에 추가
- ssh-keyscan -H "$GITLAB_HOST" >> ~/.ssh/known_hosts
# 호스트 키 검사 비활성화
- '[[ -f /.dockerinit ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
stages: # 파이프라인의 단계를 정의합니다. 여기서는 빌드 및 배포 단계를 포함한 'build-deploy' 단계가 있습니다.
- build-deploy
build: # 'build-web' 작업을 정의합니다.
stage: build-deploy # 이 작업은 'build-deploy' 단계에서 실행됩니다.
script: # 스크립트는 도커 이미지를 빌드하고 푸시합니다.
# WEB 이미지 빌드
- docker build -t $WEB_IMAGE_NAME:$CI_COMMIT_REF_NAME ./web
# WEB 이미지 도커레지스트리에 푸시
- docker push $WEB_IMAGE_NAME:$CI_COMMIT_REF_NAME
# WAS 이미지 빌드
- docker build -t $WAS_IMAGE_NAME:$CI_COMMIT_REF_NAME ./was
# WAS 이미지 도커레지스트리에 푸시
- docker push $WAS_IMAGE_NAME:$CI_COMMIT_REF_NAME
- |
# 호스트 키 검사 비활성화
ssh -o StrictHostKeyChecking=no $REMOTE_USER@$REMOTE_HOST << EOF
docker login 도커레지스트리주소 -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD"
cd 컨테이너 실행되는 폴더
# 해당 위치에서 실행중이던 컨테이너 삭제
docker compose down
# 기존 WEB, WAS 이미지 삭제
docker rmi $WEB_IMAGE_NAME:$CI_COMMIT_REF_NAME
docker rmi $WAS_IMAGE_NAME:$CI_COMMIT_REF_NAME
# 도커레지스트리에 푸시해둔 이미지를 풀 받음
docker pull $WEB_IMAGE_NAME:$CI_COMMIT_REF_NAME
docker pull $WAS_IMAGE_NAME:$CI_COMMIT_REF_NAME
# 해당 위치에서 컨테이너 실행
docker compose up -d
EOF
only: # push / merge를 할 때만 파이프라인이 생성되고 test 브랜치에서만 작동
- merge_requests
- test
- .gitlab-ci.yml 작성
- CI/CD에서 Runners의 토큰을 복사하여 Gitlab-runner 컨테이너에서 register를 새로 등록
- variables는 변수를 private하게 관리
- 위 3가지가 정상적이라면 .gitlab-ci.yml에 작성한 script 부분대로 명령어가 차례로 실행됨
- 이 때 pipeline이 생성되고 passed 상태가 되면 정상적으로 완료가 된 것
- 현재 명령어대로라면 docker in docker 구조로 2375포트를 사용하여 도커 로그인을 진행 -> 이미지를 빌드 및 원격 레지스트리에 푸시
- 원격 서버 접속 후 푸시된 이미지를 원격 레지스트리에서 풀받고 컨테이너로 실행
- 7의 과정을 CI/CD로 처리하기 위 SSH 키를 발급받아 Gitlab 프로필에서 SSH Key 등록하는 곳에 추가(공개키는 id_rsa.pub에 저장됨)
.gitlab-ci.yml에 $로 변수 선언한 부분.

