Jenkins를 이용해서 배포하기

LJH·2021년 5월 29일
8

DevOps 강의 (feat. Foo)

목록 보기
6/16

해당 내용은 Class101의 현직 대기업 개발자 푸와 함께하는 진짜 백엔드 시스템 실무! 강의를 기반으로 작성했습니다.

h1 -> #0b6e99
h2 -> #d9730d

😀 목표

  • Jenkins 세팅
  • SSH로 배포하는 과정 이해하기
  • dockerized 애플리케이션 배포 자동화

1. 시작하기 전에

  • 젠킨스는 개발자의 요청을 받아 빌드와 배포를 해주는 역할

  • 많은 기능이 있지만 주로 빌드&배포 , 배치 할 때 사용

  • 용어 정의

    • 젠킨스 인스턴스 (젠킨스): 젠킨스가 실행되고 있는 인스턴스
    • 워커 인스턴스(워커) : 애플리케이션이 돌아가는 인스턴스

  • 지금은 어떤 부분을 Jenkins로 자동화 하는건가?
    • 지난번에 docker hub에 올려둔 docker image를 pull 받아서
      docker image를 run 시켜 docker Conatiner를 생성&실행 하는 과정을 Jenkin를 통해
      자동화 한다!

2. 젠킨스 인스턴스 생성 후 젠킨스 설치

2-1. 젠킨스 인스턴스 생성

2-2. 워커 인스턴스 생성

  • 인스턴스 이름만 cpu-worker-instance-1 로 다르고 나머지는 위와 같다.

2-3. Jenkins 인스턴스에 Jenkins 설치

# jenkins 인스턴스에서 실행하는 명령어
sudo yum install wget
sudo yum install maven // 자바 같이 설치됨
sudo yum install git
sudo yum install docker

sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
sudo yum install jenkins
sudo systemctl start jenkins // 젠킨스 데몬 실행
sudo systemctl status jenkins // 젠킨스 떴는지 확인

# 여기까지 실행하면 설치는 완료

sudo cat /var/lib/jenkins/secrets/initialAdminPassword
  • 설치할때마다 y를 입력해야하는데 귀찮으면 yum 뒤에 옵션 -y를 추가해주면 된다.

    sudo yum -y install wget
  • 그냥 젠킨스를 설치하면 패키지가 없다는 메시지가 출력된다.
    따라서 패키지를 따로 설치해줘야 한다.

    sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
  • 젠킨스가 정상적으로 실행됬는지 확인하자

    sudo systemctl status jenkins

    • Active : active (running)로 나오면 정상적으로 젠킨스가 실행된 것이다.

3. 젠킨스 초기 세팅

3-1. 8080 포트 열어주기

  • 젠킨스는 8080번 포트로 실행된다. 80번 포트로 바꿔주는 과정이 생각보다 까다롭다.
    따라서 방화벽에서 8080번 포트를 추가로 열어준다.

  • 이름, 설명, 대상만 수정하고 나머지는 디폴트 그대로 설정한다.

  • 소스 IP 범위에서 0.0.0.0/0 으로 설정한다. 이러면 모든 IP를 허용한다는 의미이다.

  • tcp 8080 포트를 허용한다.

  • 방화벽목록에 jenkins-web이 추가가 된걸 볼 수 있다.

3-2. 웹 브라우저로 접속 후 설치

  • 젠킨스 인스턴스의 외부IP:8080 으로 접속하면 아래와 같은 페이지가 나온다.
  • 비밀번호를 입력하라고 나오는데 빨간색 글씨로 된 경로에 비밀번호가 존재한다.
    • 관리자 권한으로 실행해야 볼 수 있다.
  • 비밀번호를 입력후 접속한다.

  • 플러그인 설치 옵션 화면이 나온다.
  • 왼쪽은 추천하는 플러그인만 설치, 오른쪽은 사용자가 원하는 플러그인을
    직접 선택해서 설치
  • 추천 플러그인을 선택하면 설치가 진행된다.

  • 정보를 입력한다.

  • url을 그대로 사용한다.

  • Jenkins 초기 설정이 끝났다.

  • SSH 플러그인을 추가로 설치하기위해 관리 페이지로 들어간다.

  • Public Over SSH를 선택하고 재시작 없이 설치 버튼을 클릭하면 성공했다는 페이지가 나온다.

젠킨스 초기 세팅이 끝났다.


4. 젠킨스만 워커에 접근 가능하도록 설정

  • 배포하는 방식은 여러가지가 있지만 가장 보편적으로 사용하는 배포 방식은
    ssh를 통해 접속하여 배포하는 것이다.

  • 젠킨스가 워커로 접속하여 도커 이미지를 pull 하고 run 시키는 것이다.

  • 여기서 중요한 문제가 있다. 젠킨스만 워커의 ssh로 접속가능하게 해야한다.
    다른사람이 워커에 접근하면 안된다.

4-1. 어떻게 젠킨스만 접근 가능하도록 하지?

대칭키

  • 암호화 할 때 사용하는 키 = 복호화 할 때 사용하는 키
  • 속도가 빠르지만 중간에 키가 탈취되면 누구나 복호화가 가능하다.

비대칭키(공개키)

  • 암호화 할 때 사용하는 키 ≠ 복호화 할 때 사용하는 키
  • 암호화는 공개키로 수행하고, 복호화는 개인키로 수행한다.
    따라서 누구나 암호화가 가능하지만 개인키를 가지고 있는 사람만 복호화가 가능하다.

  • A의 공개키로 암호화를 진행하고 , A에게 전달하면 오직 A만 복호화가 가능하다.

  • A의 개인키로 암호화를 진행하면, 누구나 복호화가 가능하다.

  • 누구나 복호화 가능하면 암호화가 무슨 의미가 있나? → 하지만 이 개념은 널리 쓰인다.
    바로 서명이라는 개념이다. 이 방식을 사용하면 오직 자신만이 암호화가 가능하기 때문에
    본인임을 증명할 수 있다.

  • 이 개념을 활용하여 젠킨스 인스턴스라고 증명할 수 있는 ssh연결만 허용해 준다.

너의 공개키로 암호화 : 다른 사람이 아닌 너만 읽을 수 있음(암호 통신 가능)
너의 개인키로 암호화 : 너의 개인키를 알 수 없기 때문에 아무도 볼 수 없음
나의 공개키로 암호화 : 나 밖에 못보기 때문에 의미 없는 암호화
나의 개인키로 암호화 : 모든 사람이 나의 공개키로 복호화 가능하며, 이 암호화는 오직
나만이 가능함(전자서명)

  • 그러면 이제 해야할 일은 젠킨스에서 젠킨스의 개인키와 공개키를 만들어서 공개키를 워커에게 등록해주면, 오직 젠킨스만 워커에 ssh로 접속할 수 있게 된다.

4-2. 젠킨스에서 키 생성

ssh-keygen -t rsa -f ~/.ssh/id_rsa
  • 명령어를 입력하면 뭐를 입력하라고 나오는데 그냥 모두 enter 눌러주면 된다.
~/.ssh/
  • 위 경로에 가면 key에 대한 정보를 확인할 수 있다.
  • 현재 위치가 home인 경우 cd .ssh 를 입력하면 된다.

  • id_rsa : 개인키
  • id_rsa.pub : 공개키
  • 이제 이 공개키를 워커 인스턴스에 등록해줘야 한다.
vi id_rsa.pub

  • 위 명령어를 입력후 나오는 문자열을 처음부터 끝까지 복사한다.

4-3. GCP 인스턴스에 공개키 등록

  • 워커 인스턴스로 접속해 ~/.ssh/authorized_keys 로 접근해 파일을 수정해 주면된다.

  • vi 에디터로 파일을 열어보면 우리가 워커 인스턴스 페이지에서 ssh 버튼클릭하면 ssh로 접속가능하도록 하는 쉘의 키들이 입력되어 있다.
    그런데 나는 해당 경로에 authorized_keys 파일이 존재하지가 않았다.

  • 이전에 vm 환경에 ssh로 접속하면서 비밀번호 입력없이 로그인하는 과정을 진행해봤는데
    이 때는 키 생성후 로컬에서(여기서는 젠킨스에서) 원격지로(여기서는 gcp) 키를 전송하면서
    authorized_keys를 생성했었다. 그래서 일단 새롭게 authorized_keys 파일을 만들고
    젠킨스에서 생성한 공개키를 등록했다.(이후 끝까지 진행했는데 문제 없었다.)

  • 공개키 문자열(젠킨스의 id_rsa.pub)을 복사해 워커 인스턴스의 authorized_keys 파일에 넣어주면된다.

  • 폴더들의 권한을 설정해줘야 한다.

    chmod 700 ~/.ssh
     chmod 600 ~/.ssh/authorized_keys

4-4. 젠킨스에서 키 등록

  • 젠킨스 웹 페이지에서 jenkins 관리 → 시스템 설정 으로 접속

  • 맨 아래에 보면 아까 추가한 Publish over SSH 항목이 있다.

  • key 부분에 젠킨스 인스턴스의 개인키를 입력한다.

  • 젠킨스 인스턴스의 개인키는 아까 생성한 id_rsa 파일이다.

vi ~/.ssh/id_rsa
  • 명령어를 입력해 키를 복사 후 붙여넣는다.

  • 이 부분에는 워커 인스턴스의 정보를 입력해야 한다.
    • name → 식별 가능한 워커 인스턴스 이름
    • hostname → 워커 인스턴스의 내부 ip
    • username → 워커 인스턴스에 로그인 되어있는 아이디(인스턴스 생성한 구글 계정 id)
    • Remote Directory → 워커 인스턴스의 홈 디렉토리의 경로를 입력해준다.
  • Test Configuratin을 클릭해서 Success가 나오면 된다.

4-5. 워커 인스턴스에 대한 배포 스크립트 작성

  • 배포 스크립트는 모두 아이템이라는 단위로 관리가 된다.
  • 젠킨스 웹페이지에서 새로운 Item을 클릭한다.

  • 아이템 이름을 적고 Freestyle Project를 선택하고 아래 ok 버튼을 클릭한다.

  • 맨 아래로 이동하면 빌드 후 조치 버튼이 있는데 여기서 send build artifacts over SSH를
    선택한다.

  • name 아래 우측에 있는 고급 버튼을 클릭하고 Verbose output in console을 체크한다.
    • 로그를 자세하게 출력해주는 옵션이다.

  • command 칸에 docker run 명령어를 입력해 주면 된다.
  • 저장 버튼을 클릭한다.

4-6. 스크립트 실행 , 삽질과정1

  • 좌측에 Build Now를 클릭하면 좌측 아래에 #1이 생기는데 클릭 후 Console Output을 선택

  • 빌드하고 배포하면서 나온 로그를 확인할 수 있다.
  • sudo 명령어를 사용할 수 없는 사용자라고 에러 메시지가 출력됬다.
    sudo 명령어를 사용한 이유는 80번 포트를 사용하기 위함이였는데 8080번 포트로 변경하면 sudo 명령어는 필요없다. 어차피 외부로 보이는건 앞으로 웹 서버인 nginx가 요청을 받아줄 거기 때문에 nginx가 80번이면 문제 없다.

  • 프로젝트로 돌아가서 구성 클릭 후 맨 아래 command 명령어를 수정해준다.
  • sudo 명령어를 지우고 왼쪽에 있는 80포트(외부포트)를 8080포트로 변경한다.

4-6. 스크립트 실행 , 삽질과정2

  • 다시 Build Now를 클릭해 빌드하고 콘솔 메시지를 확인해본다.
  • 이번에는 docker를 찾을 수 없다. 즉 docker가 설치가 안되어 있다..
sudo yum -y install docker // docker 설치
sudo systemctl start docker // docker demon 실행

4-6. 스크립트 실행 , 삽질과정3

  • 이번에는 권한 오류 메시가 출력됬다.
  • 사이드 프로젝트 배포할 때도 만났던 반가운 에러메시지이다.
    docker.sock 파일 권한을 수정해주면 된다.
sudo chmod 666 /var/run/docker.sock

4-6. 스크립트 실행 , 삽질과정4

  • docker 이미지를 찾을 수 없다는 에러이다.
  • docker hub 아이디를 잘못입력했다. 다시 command를 수정하자..

  • 애플리케이션이 뜨면서 멈췄는데 이는 지금
    로그가 나오면서 배포가 끝나지 않았다고 젠킨스가 인식하고 있는 것이다.
  • 결국 타임 아웃에러가 났다.

4-6. 스크립트 실행 , 삽질과정5

  • 다시 구성으로 이동해 command를 수정한다.
nohup docker run -p 8080:80 znftm93/spring-boot-cpu-bound > /dev/null 2>&1 &
  • "nohup ~~~ & : docker" 컨테이너를 백그라운드로 실행시킨다.
  • "> /dev/null 2>&" : 표준 에러를 표준 출력으로 리다이렉션 하라는 명령어

  • 파란색 불빛과 함께 문제 없이 gcp 워커 인스턴스에 docker 컨테이너가 띄워진 것 같다.
  • 접속해서 확인해보자

  • 8080포트를 열어줬기 때문에 8080포트로 접속해보면 정상적으로 hash된 문자열이 나온다!

5. 마무리

  • 젠킨스 인스턴스와 워커 인스턴스를 생성 후 젠킨스 세팅을 했다.

  • 젠킨스의 개인키 공개키 쌍을 만든 후, 공개키는 워커에 등록했다.

  • 젠킨스에서 워커 인스턴스로 배포하도록 설정해서 워커 인스턴스에서 도커 이미지를
    pull 받아서 run 시키도록 했다.

자동화한 부분은 인스턴스에 접속 → docker image pull → docker run 이 끝이다.
처음이라 그런지 생각보다 굉장히 복잡했다.. 그래도 큰 그림은 이해가 되서 다행이다.

이후 챕터 4에서 github Webhook과 jenkins로 배포 자동화 하는 과정을 진행하고
내 사이드 프로젝트에 적용해 볼 예정이다.

0개의 댓글