GitLab, SSH 키를 이용해 CICD 돌리기

Dayon·2023년 3월 7일
0

배포

목록 보기
1/1

💊 GitLab과 SSH키를 연결해 CI 돌리기

🚪 들어가기

목표

총 두편에 걸쳐 벨로그에는 업로드 되겠지만, 내 목표는 배포 도메인을 HTTPS로 사용하기 위해, SSL 인증서를 certbot을 이용해 발급받을 것이고, 이때 자동배포를 위해 깃랩CI와 인스턴스를 SSH 키로 연결하는 것이다.

이번 편에서는 자동배포를 위해 깃랩CI와 인스턴스를 SSH 키로 연결을 다루었다.

들어가기 앞서 깃랩에 SSH를 적용시키는 공식문서를 먼저 보고 오기 바란다.


CI/CD란?

CI/CD (Continuous Integration/Continuous Delivery)는 자동화하여 애플리케이션을 더욱 짧은 주기로 고객에게 제공하는 방법. CI/CD의 기본 개념은 지속적인 통합, 지속적인 서비스 제공, 지속적인 배포이다. CI/CD는 새로운 코드 통합으로 인해 개발 및 운영팀에 발생하는 문제("통합 지옥(integration hell)")를 해결하기 위한 솔루션이라 할 수 있다.

CI/CD는 애플리케이션의 통합 및 테스트 단계에서부터 제공 및 배포에 이르는 애플리케이션의 라이프사이클 전체에 걸쳐 지속적인 자동화와 모니터링을 제공하며 이러한 구축사례를 “CI/CD 파이프라인” 이라 부른다.

CI는 지속적인 서비스제공를 의미한다. 지속적인 제공이란 개발자들이 애플리케이션에 적용한 변경사항이 테스트를 거쳐 리포지토리에 자동 업로드 되는 것을 뜻하며, 운영팀은 실시간으로 리포지토리에서 어플리케이션에 배포할 수 있다. ⇒ 최소한의 노력으로 새로운 코드를 배포하는 것을 목표로 함

CD는 지속적인 배포를 의미한다. 개발자의 변경사항이 레포에서 고객이 사용한 서비스 환경까지 자동으로 릴리스되는 것을 의미한다.

[ GitLab CI/CD 시작하기 ]


HTTPS 란?

  • HTTP (Hypertext Transfer Protocol) : HTML을 전송하기 위한 통신규약을 의미

  • HTTPS 하이퍼 텍스트 전송 프로토콜 보안(Hyper Text Transfer Protocol Secure):
    보안이 강화된 HTTP

HTTP는 암호화되지 않은 방법으로 데이터를 전송하기 때문에 서버와 클라이언트가 주고 받는 메시지를 감청하는 것이 매우 쉽다. 예를들어 로그인을 위해서 서버로 비밀번호를 전송하거나, 또는 중요한 기밀 문서를 열람하는 과정에서 악의적인 감청이나 데이터의 변조등이 일어날 수 있다는 것이다. 이를 보안한 것이 HTTPS다.

HTTPS와 SSL 란?

보안 소켓 계층(Secure Sockets Layer, SSL) 인증서는 종종 디지털 인증서로 불리며, 브라우저(사용자의 컴퓨터)와 서버(웹사이트) 사이의 암호화된 연결을 수립하는 데 사용, SSL은 웹사이트와 브라우저 사이(또는 두 서버 사이)에 전송되는 데이터를 암호화하여 인터넷 연결을 보호하기 위한 표준 기술

웹사이트가 SSL/TLS 인증서로 보호되는 경우 HTTPS가 URL에 표시되며 사용자는 브라우저 표시줄의 자물쇠 기호를 클릭해 발급 기관 및 웹사이트 소유자의 상호를 포함한 인증서의 세부 정보 확인 가능



🔬 실습

<순서1. 깃랩에서 인스턴스 SSH 연결>

  1. 새로운 SSH 키 페어를 먼저 생성하기 전에 Ubuntu 시스템(배포환경)에서 기존 SSH 키를 확인해야 한다.

    • ls -l ~/.ssh 를 통해 키 가 있는 지 확인한다.
  2. 기존에 키가 없을 경우 인스턴스(배포환경) 설정값들을 우선 확인해준다.

    • 인스턴스 생성후 도메인 연결, 고정 ip 설정값, http 와 https 방화벽을 모두 확인해준다.
  3. 인스턴스 본인계정으로 SSH키 를 발급받는다.

    • ssh-keygen -t rsa -b 4096 -C "[계정]@gmail.com”

    이때 rsa는 ssh 보안 키의 종류중 하나로, 보안키는 rsa, ed25519, ecdsa 이렇게 3가지 종류가 있다.

    4096은 bit크기를 말하고, 공식문서에서는 최소 2048 bit key size를 추천한다.

    만약에 3종류의 키를 모두 만들고 싶으면 ssh-keygen -t 명령어만 치면 된다.

    • (1) 명령어 실행후 기본 파일위치 및 파일 이름을 승인하려면 Enter를 누른다.
    • (2) 비밀번호를 입력하라는 창이 뜨는데 추가하지 않는다면 Enter를 누른다.
    • 위에 명령어 실행후 public키와 private 키 pair가 생성되고 생성된 키는
      (/home/[계정]@gmail.com/.ssh) 안에서 확인 이 가능하다.
    • id_rsa.pub 은 공개키, id_rsa 는 비밀키이다.
  4. 사용하는 gitlab-ci.yml 파일에 맞추어 프로젝트 레포 setting에 변수를 저장한다.

    • ai-edmu-backend 레포지토리의 gitlab-ci.yml 코드
      image: alpine:latest
      
      stages:
        - "deploy"
      
      step-pages:
        stage: deploy
        tags:
          - shell_executor
          - unirobotics_deploy
        before_script:
          - "command -v ssh-agent >/dev/null || ( apk add --update openssh )"
          - eval $(ssh-agent -s)
          - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
          - mkdir -p ~/.ssh
          - chmod 700 ~/.ssh
          - ssh-keyscan $VM_IPADDRESS >> ~/.ssh/known_hosts
          - chmod 644 ~/.ssh/known_hosts
        script:
          - ssh $SSH_USER@$VM_IPADDRESS "hostname
            && echo 'ssh 접속 완료 !'
            && cd /ai-edmu-backend
            && sudo git pull origin MP-391-gitrunner
            && sudo docker-compose down
            && sudo docker-compose up --build"
            # && sudo chmod +x init-letsencrypt.sh
            # && sudo ./init-letsencrypt.sh"
      
        only:
          - MP-391-gitrunner
    VM_IPADDRESS  34.64.55.123
    SSH_USER dayon0325_unirobotics_co_kr
    SSH_PRIVATE_KEY
    -----BEGIN OPENSSH PRIVATE KEY-----
    b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn
    [...]
    -----END OPENSSH PRIVATE KEY-----

    gitlab에 사용되는 변수 외에도 추가로 public키를 SSH키에 연결해준다. (순서2에서 깃과의 연결을 위해 필요하다)

  1. ssh 키 파일 아래에 authorized_keys 파일을 생성해준다.

    $ sudo nano authorized_keys
    (이때 파일 위치 : /home/dayon0325_unirobotics_co_kr/.ssh/authorized_keys)

    이 파일 안에 3번에서 만든 공개키를 넣어준다.

    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCd412kZyd5w13IrnnBiNnIThsipYoO5yziVOF43RrBL
    […]
    wd5ct4i7X/7ktWJctNJgtF9/3ruf1YdqLY3KmS+DuOllXNLmyQ== dayon0325@unirobotics.co.kr

    이때 공개키는 한줄로 구성되어있고, ssh-rsa 부터 ~ 이메일 주소까지 이다.

  2. Google Cloud > 메타데이터 > SSH 키 > 수정 에 들어가 공개키를 추가해준다.

  3. 지금 푸시를 통해 gitlab pipeline을 확인해보면 echo 'ssh 접속 완료 !' 가 뜨면 ssh와 연결을 성공했다.



<순서2. 인스턴스에서 깃랩 SSH 연결>

  1. 인스턴스에서 프로젝트 레포는 / 아래 최상위 폴더안에 생성해주었다.

    dayon0325_unirobotics_co_kr@edmu-gitlab:~$ cd /
    dayon0325_unirobotics_co_kr@edmu-gitlab:/$ ls -a
    .     ai-edmu-backend  dev   lib    libx32      mnt   root  srv  usr
    ..    bin              etc   lib32  lost+found  opt   run   sys  var
    .git  boot             home  lib64  media       proc  sbin  tmp
  2. /root/.ssh/config 위치에 파일을 생성해준다.

    root 계정으로 들어가려면 sudo -i 명령어 실행을 하면 된다.

    dayon0325_unirobotics_co_kr@edmu-gitlab:/$ cd root
    -bash: cd: root: Permission denied
    dayon0325_unirobotics_co_kr@edmu-gitlab:/$ sudo -i
    
    root@edmu-gitlab:~# cd /root
    root@edmu-gitlab:~# ls -a
    .  ..  .bash_history  .bashrc  .local  .profile  .ssh  .viminfo
    
    root@edmu-gitlab:~# cd .ssh
    root@edmu-gitlab:~/.ssh# ls -a
    .  ..  config  known_hosts
    Host [gitlab.com](http://gitlab.com/)
          PreferredAuthentications publickey
          IdentityFile /home/dayon0325_unirobotics_co_kr/.ssh/id_rsa

    이때 IdentityFile 은 비밀키 위치를 지정해주면 된다.

  1. 프로젝트 폴더 아래에 .env 파일을 추가해 준 뒤에 실행한다.

    sudo git pull

    sudo docker-compose down

    sudo docker-compose up 명령어가 잘 실행 될 것이다.




헤메고 실수했던 부분

  1. Permission denied publickey - 권한이 거부됨

발급한 SSH 키를 깃랩 환경설정, 환경변수로 잘 넣은것 같다면 아마도 권한 거부 오류는 인스턴스ssh 터미널 설정값 오류일 확률이 정말 정말 높다. config 파일에 들어가 어디서 필요한 SSH 키가 어디와 연결되어 있는지 잘 확인해보자.

https://docs.github.com/ko/authentication/troubleshooting-ssh/error-permission-denied-publickey

  1. SSH 키값의 RWX설정

개인 키는 사용자만이 읽고 쓸 수 있고(600), 공개 키는 다른 사용자도 읽을 수 있는 권한(644)을 가지고 있다. 이에 맞추어 chmod 명령어를 써서 변경해준다.

$ ls -al /경로/

total 16
drwx------   4 user  staff   128  6  7 15:07 .
drwxr-xr-x+ 31 user  staff   992  6  7 15:05 ..
-rw-------   1 user  staff  1876  6  7 15:07 id_rsa
-rw-r--r--   1 user  staff   403  6  7 15:07 id_rsa.pub
  1. GitLab-CI에서 sudo 실행(권한) 문제

sudo: no tty present and no askpass program specified

이러한 오류 또는 sudo 권한 관련 오류가 뜬다면

  1. sudo visudo # sudoers 설정 파일을 열기

  2. 아래 코드 추가하기

    gitlab-runner ALL=NOPASSWD: ALL    # 깃랩 러너의 모든 명령을 패스워드 없이 실행한다
    
    dayon0325_unirobotics_co_kr  ALL=(ALL:ALL) ALL  # 유저에게 권한 다 부여 

https://litlhope.github.io/develop/gitlab-ci-sudo-problem/





< 참조한 사이트 >

CICD란?

CI/CD(CI CD, 지속적 통합/지속적 배포): 개념, 툴, 구축, 차이

GitLab CI/CD 시작하기 | DevSecOps 구축 컨설팅, 교육, 기술지원 서비스 제공

HTTPS 와 SSL

HTTPS와 SSL 인증서 - 생활코딩

깃랩에 SSH 적용시키는 공식문서

Use SSH keys to communicate with GitLab | GitLab

GitLab CI/CD + SSH 공개키를 이용한 자동배포

profile
success is within reach, allow yourself time

0개의 댓글