DAY74. [Deploy] CI/CD

Davina·2022년 12월 7일
0

개발 프로세스

소프트웨어 시스템이나 애플리케이션 개발 및 유지보수할 목적으로 수행되는 활동의 절차

개발 프로세스, 즉 소프트웨어 개발 프로세스 모델은 소프트웨어 개발 생명주기(SDLC, Software Develpment Life Cycle)을 기반으로 만들어졌습니다.

https://user-images.githubusercontent.com/58800295/195041210-e75ad4e3-3676-4306-83c0-e444465a9f85.png

  • 요구분석 및 시스템 명세 작성
    • 문제분석 단계라고도 하며, 개발할 소프트웨어의 기능과 제약조건, 목표 등을 사용자와 함께 정확히 정의하는 단계입니다. 개발하고자 하는 소프트웨어의 성격을 정확히 이해하여 이를 토대로 개발 방법과 필요한 자원 및 예산 예측 후 요구명세를 작성합니다.
  • 설계
    • 앞서 정의한 기능을 실제로 수행하기 위한 방법을 논리적으로 결정합니다. 크게 시스템, 프로그램, UI(User Interface) 설계로 나뉜다.
      • 시스템 구조설계 : 시스템을 구성하는 내부 프로그램이나 모듈 간의 관계와 구조를 설계
      • 프로그램설계 : 프로그램 내의 각 모듈에서의 처리 절차나 알고리즘을 설계
      • UI(User Interface) 설계 : 사용자 인터페이스 설계로, 사용자가 시스템을 사용하기 위해 보이는 부분을 설계
  • 구현 (실제 개발에 착수하는 단계)
    • 설계 단계에서 논리적으로 결정한 문제 해결 방법을 프로그래밍언어를 사용하여 실제 프로그램을 작성합니다. 이때 프로그래밍 기법은 구조화 프로그래밍과 모듈러 프로그래밍 두 개로 나뉩니다.
      • 구조화 프로그래밍 : 조건문, 반복문을 사용하여 프로그램을 작성하고, 순차구조, 선택구조, 반복구조의 세 가지 제어구조로 표현하며, 구조가 명확하여 정확성 검증과 테스트 및 유지보수가 쉬운 장점이 있습니다.
      • 모듈러 프로그래밍 : 프로그램을 여러 개의 작은 모듈로 나누어 계층 관계로 구성하는 프로그래밍 기법으로, 모듈별로 개발과 테스트 및 유지보수 가능하며, 모듈의 재사용 가능하다는 장점이 있습니다.
  • 테스트
    • 개발한 시스템이 요구사항을 만족하는지, 실행 결과가 예상한 결과와 정확하게 맞는지를 검사하고 평가하는 일련의 과정입니다. 미처 발견하지 못한 오류를 발견할 수 있기 때문에 매우 중요한 과정
  • 배포 및 유지보수
    • 시스템이 인수되고 설치된 후(배포) 일어나는 모든 활동을 지칭합니다. 이후 일어나는 커스터마이징, 구현, 테스트 등 모두 이 단계에 포함되므로 소프트웨어 생명주기에서 가장 긴 기간을 차지합니다. 유지보수의 유형에는 수정형, 적응형, 완전형, 예방형 총 네 가지가 있습니다.
      • 수정형 유지보수 : 사용 중에 발견한 프로그램의 오류 수정 작업을 진행합니다.
      • 적응형 유지보수 : 시스템과 관련한 환경적 변화에 적응하기 위한 재조정 작업을 합니다.
      • 완전형 유지보수 : 시스템의 성능을 향상하기 위한 개선 작업을 합니다.
      • 예방형 유지보수 : 앞으로 발생할지 모를 변경 사항을 수용하기 위한 대비 작업을 수행합니다.

전통적인 개발 프로세스

  • 워터폴(Waterfall) 방식 - 폭포와 같이 한 방향으로만 프로세스가 진행되는 개발 과정

    유지보수가 끝나면 다시 처음의 단계로 돌아감

    유지보수가 끝나면 다시 처음의 단계로 돌아감

    해당 방식은 출시 기한을 정해놓고 순차적으로 프로세스를 진행시켜 애플리케이션(소프트웨어)를 완성해 배포하기 때문에 유저에게 전달되는 시간이 오래 걸린다. 버그나 수정 사항이 생기면 다시 처음으로 돌아가 수정되기 때문에 일정과 비용 등 많은 부분에서 에로 사항 발생. 따라서, 소프트웨어의 신뢰성 및 안정성을 보장 받기 힘들며, 버그 발생 가능성 높음.

    그래서 “테스트” 단계에 다양한 테스트 도입

    • 시스템 테스트 : 모든 모듈을 통합한 후 최종적으로 완성된 시스템이 요구사항을 만족하는지 확인합니다. 요구사항을 만족하지 않는다면 다시 요구분석 단계로 돌아가 새로 개발을 하기도 합니다.
    • 알파 테스트 : 완전히 개발된 시스템을 개발 현장에서 비공개로 테스트하는 것으로, 주문형 제품의 경우 개발진과 클라이언트 사이에서 동의가 이루어질 때까지 수행됩니다. 대기업의 경우 이 업무를 주로 하는 전문 QA팀이 존재합니다.
    • 베타 테스트 : 고객의 실제 사용 환경에서 수행되는 테스트로, 미리 선별된 유저들이 해당 제품을 사용해 봅니다. 이 과정에서 에러나 버그가 발견되면 수정하는 식으로 진행됩니다.

모던 개발 프로세스

  • 애자일(Agile) 방식 - “스프린트”라고 불리는 짧은 주기의 개발 사이클을 반복함 https://user-images.githubusercontent.com/58800295/195042876-a8f98f2d-d647-451c-b6cc-4ae20f4c63b9.png 계획에 의존하여 형식적인 절차를 끝까지 따라야 하고 중간에 뒤로 회귀할 수 없는 전통적인 개발 프로세스보다는 훨씬 효율적으로 개발에 착수 가능. 적절히 사용하면 빠르게 문제를 해결해 하루에도 여러 번의 배포가 가능. 이러한 방식은 SaaS(Software as a Service, 서비스형 소프트웨어)를 개발하는 데에 적합

    SaaS란?

    https://user-images.githubusercontent.com/58800295/195043042-c1f9a16f-159b-44b6-be46-086ca5521dfe.png

    클라우드 서비스의 한 방식으로, 브라우저에 접속만 해도 새 버전을 즉시 사용할 수 있는 서비스 방식. 애플리케이션부터 서버, 가상화, 스토리지, 네트워킹까지 전부 공급자 쪽에서 관리하기 때문에 고객이 제어하거나 관리할 부분이 거의 없게 됩니다. 따라서 사용자 업데이트에 대한 걱정에서 벗어나며, 하루에 여러 번의 배포도 가능합니다. 또한 빠른 배포 속도도 보장 받을 수 있습니다.

전통적인 개발 프로세스 VS 모던 개발 프로세스

DevOps

전통적인 IT 조직 구조로는 개발팀(Dev)과 운영팀(Ops)이 소프트웨어의 개발과 관리 및 유지보수를 담당해왔습니다.

개발팀이 잦은 업데이트를 통해 제품에 변화를 만들어야 한다면, 운영팀은 이런 서비스의 구성의 변경을 최소화해 안정성을 확보하는데, 이 부분은 꽤 상충이 되는 부분이기 때문에 갈등을 야기

⇒ DevOps라는 개념 탄생! DevOps = 소프트웨어 개발(Development) + IT 운영(Operations)

소프트웨어를 자주, 빨리 그리고 안전하게 배포하는 것을 목표로 하며, 그렇기 때문에 애자일 개발 프로세스를 기반

https://user-images.githubusercontent.com/58800295/195049472-d35fe54b-10bf-4f07-b893-1bab3e059556.png

만약 서비스가 중단된다면, 누구든지 문제점을 진단하고 시스템을 복구하여 운영할 수 있는 절차를 알고 있어야 합니다. 이를 위한 기술과 지식이 제공되기 위해서 훈련과 효과적인 협업체계를 마련하는 것이 매우 중요

DevOps 특징

DevOps는 개발에서 운영까지 하나의 통합된 프로세스로 묶어내고 사용하는 툴과 시스템을 표준화하여 의사소통의 효율성을 확보하고 일련의 작업들을 자동화합니다. 즉 코드 통합, 테스트, 배포 과정을 자동화 시키는 것입니다. 이 부분은 지속적으로 유지되어야 할 필요가 있는데, 지속적 통합 및 배포(CI/CD)라고 하며 DevOps의 핵심 원칙! 잘 구축된 CI/CD는 애플리케이션의 배포 시간을 크게 단축시킵니다.


CI/CD

https://user-images.githubusercontent.com/58800295/195052068-4de8c5cd-3b51-4eb2-8bec-2eb0e33905e0.png

지속적 통합(Continuous Integration, CI)

개발자를 위한 자동화 프로세스라고 볼 수 있으며, Code - Build - Test 단계에서 꾀할 수 있습니다.

  • Code : 개발자가 코드를 원격 코드 저장소 (Ex. github repository)에 push하는 단계입니다.
  • Build : 원격 코드 저장소로부터 코드를 가져와 유닛 테스트 후 빌드하는 단계입니다.
  • Test : 코드 빌드의 결과물이 다른 컴포넌트와 잘 통합되는 지 확인하는 과정입니다.

이 지속적인 통합 과정을 통해 개발자는 버그를 일찍 발견할 수 있고, 테스트가 완료된 코드에 대해 빠른 전달이 가능해지며 지속적인 배포가 가능해집니다.

지속적 통합은 모든 코드 변화를 하나의 리포지토리에서 관리하는 것 부터 시작합니다. 모든 개발팀이 코드의 변화를 확인할 수 있기 때문에, 투명하게 문제점을 파악할 수 있습니다. 지속적 통합을 통해 개발팀은 각자 개발한 코드를 이른 시점에 자주 합치고 자주 테스트 해볼 수 있습니다.

지속적 통합으로 보안 이슈, 에러 등을 쉽게 파악할 수 있어 해당 이슈를 빠르게 개선할 수 있습니다. 이전에는 각자 개발자가 작성한 코드를 합치고 난 후, 모두 모여서 빌드를 시작하고 나서야 문제점을 파악할 수 있었습니다. 지속적 통합이 적용된 개발팀은 코드를 머지하기 전, 이미 빌드 오류나 테스트 오류를 확인하여 훨씬 더 효율적인 개발을 할 수 있게 됩니다. 새로운 코드 변경 사항이 정기적으로 빌드 및 테스트되어 공유 리포지토리에 통합되므로 개발자들간의 코드 작업 중 충돌 문제 해결 가능

지속적 배포(Continuous Delivery/Deployment, CD)

지속적인 서비스 제공 (Continuous Delivery) 및 지속적인 배포(Continuous Deployment)를 의미하며 이 두 용어는 상호 교환적으로 사용됩니다. 이 부분은 Release - Deploy - Operate 단계에서 꾀할 수 있습니다.

  • Release : 배포 가능한 소프트웨어 패키지를 작성합니다.
  • Deploy : 프로비저닝을 실행하고 서비스를 사용자에게 노출합니다. 실질적인 배포 부분입니다.
  • Operate : 서비스 현황을 파악하고 생길 수 있는 문제를 감지합니다.

지속적 배포의 경우, 코드 변경 사항의 병합부터 프로덕션에 적합한 빌드 제공에 이르는 모든 단계로, 테스트 자동화와 코드 배포 자동화가 포함됩니다.

이 프로세스를 완료하면 프로덕션 준비가 완료된 빌드를 코드 리포지토리에 자동으로 배포할 수 있기 때문에 운영팀이 보다 빠르고 손쉽게 애플리케이션을 프로덕션으로 배포할 수 있게 됩니다.

CI/CD 파이프라

배포 자동화란?
한번의 클릭 혹은 명령어 입력을 통해 전체 배포 과정을 자동으로 진행하는 것을 뜻함

  • 수동적이고 반복적인 배포 과정을 자동화함으로써 시간 절약
  • 휴먼 에러(Human Error)를 방지

    휴먼 에러란 사람이 수동적으로 배포 과정을 진행하는 중에 생기는 실수들을 뜻합니다. 그 전에 했던 배포 과정과 비교하여 특정 과정을 생략하거나 다르게 진행하여 오류가 발생하는 것이 휴먼 에러의 예로 볼 수 있습니다.

수없이 진행되는 배포 과정을 자동화시키는 방법

자동화를 꾀하는 부분은 보통 코드가 빌드되면서 최종적으로 배포가 되는 단계까지. 이 부분을 지속적인 통합 및 배포를 위하여 일련의 자동화 단계로 만드는데, 이것을 파이프라인을 구축한다고 표현합니다.

https://user-images.githubusercontent.com/58800295/195053601-3fbd0363-c47e-4bb8-821d-f47205b12021.png

CI/CD 파이프라인을 구성하는 기본 단계와 수행 작업

배포에서 파이프라인(Pipeline)이란, 소스 코드의 관리부터 실제 서비스로의 배포 과정을 연결하는 구조를 뜻합니다. 파이프라인은 전체 배포 과정을 여러 단계(Stages)로 분리합니다. 각 단계는 파이프라인 안에서 순차적으로 실행되며, 각 단계마다 주어진 작업(Actions)들을 수행합니다.

  1. Source 단계: Source 단계에서는 원격 저장소에 관리되고 있는 소스 코드에 변경 사항이 일어날 경우, 이를 감지하고 다음 단계로 전달하는 작업을 수행합니다.
  2. Build 단계: Build 단계에서는 Source 단계에서 전달받은 코드를 컴파일, 빌드, 테스트하여 가공합니다. 또한 Build 단계를 거쳐 생성된 결과물을 다음 단계로 전달하는 작업을 수행합니다.
  3. Deploy 단계: Deploy 단계에서는 Build 단계로부터 전달받은 결과물을 실제 서비스에 반영하는 작업을 수행합니다.

CI/CD 파이프라인 구성 요소 및 장점

  • 빌드 (소프트웨어 컴파일)
  • 테스트 (호환성 및 오류 검사)
  • 릴리스 (버전 제어 저장소의 애플리케이션 업데이트)
  • 배포 (개발에서 프로덕션 환경으로의 변환)
  • 규정 준수 및 유효성 검사

로 이루어져 있으며, 이 과정이 반복적인 프로세스이기 때문에 이 부분을 일련의 자동화 단계로 만든다고 볼 수 있습니다.

이렇게 구축된 파이프라인은 최신 버전의 소프트웨어 애플리케이션을 업데이트하고 제공하려는 일련의 처리 단계에 걸리는 시간을 수동으로 하는 것보다 더 빠르고 안정적이며 CI/CD 인프라와의 호환성과 효율성을 높여줍니다.


Github Action

Github가 공식적으로 제공하는 빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 CI/CD 플랫폼

레포지토리에서 Pull Requestpush 같은 이벤트를 트리거로 GitHub 작업 워크플로(Workflow)를 구성할 수 있습니다. 워크플로는 하나 이상의 작업이 실행되는 자동화 프로세스로, 각 작업은 자체 가상 머신 또는 컨테이너 내부에서 실행됩니다.

워크플로는 .yml (혹은 .yaml ) 파일에 의해 구성되며, 테스트, 배포 등 기능에 따라 여러 개의 워크플로도 만들 수 있습니다. 생성된 워크플로는 .github/workflows 디렉토리 이하에 위치합니다.

비공개 레포지토리의 경우 Github Actions가 작동할 때의 용량과 시간이 제한되어있으며 공개 레포지토리는 무료로 사용 가능합니다.

Github Actions 공식문서 : https://docs.github.com/en/actions

  1. 자신의 깃허브 계정에 새로운 리포지토리 만들기 (public으로 만들어야 Github Action 무료로 이용 가능)

  2. 새로운 리포지토리에 다른 코드 불러오기

    # 기존 나만의 아고라 스테이츠 서버 레퍼런스 클론
    git clone git@github.com:codestates-seb/fe-sprint-my-agora-states-server-reference.git
    
    # 디렉터리 이동
    cd fe-sprint-my-agora-states-server-reference
    
    # 새로운 리포지토리를 원격 리포지토리로 등록
    git remote add myRepo git@github.com:{여러분의 아이디}/{새로운 리포지토리 이름}.git
    
    # 기존 레퍼런스 코드를 새로운 리포지토리로 push
    git push myRepo reference
  3. Actions 탭에서 확인 가능

왜 리포지토리를 push만 했는데 작동할까?

./.github/workflows/pullRequest.yml 파일에서 확인 가능

  • npm install은 빌드를 위한 준비과정으로 볼 수 있습니다. Node.js로 만든 서버 애플리케이션은 npm으로 관련 오픈소스를 모두 깔끔하게 설치해야 작동하기 때문입니다.
  • npm test는 유닛 테스트 과정입니다. 작성한 코드가 요구사항 충족을 위한 최소한의 조건을 만족했는지 확인하고 있습니다.
name: Bare Minimum Requirements

# 언제 job을 작동시킬지
on: [push, pull_request]

# 어떤 job을 할지
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Bare Minimum Requirements
        uses: actions/setup-node@v1
        with:
          node-version: '16'
      - run: npm install
      - run: npm test

YAML

Yet Another Markup Language의 약자로, 사람이 읽을 수 있는 데이터 직렬화 언어를 의미

.yaml 혹은 .yml 확장자를 가짐

**JSON vs YAML**

//MDN의 JSON 파일
{
  "squadName": "Super hero squad",
  "homeTown": "Metro City",
  "formed": 2016,
  "secretBase": "Super tower",
  "active": true,
  "members": [
    {
      "name": "Molecule Man",
      "age": 29,
      "secretIdentity": "Dan Jukes",
      "powers": [
        "Radiation resistance",
        "Turning tiny",
        "Radiation blast"
      ]
    }
  ]
}
//Github actions 설정을 위해 작성된 YAML 파일
name: Bare Minimum Requirements
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Bare Minimum Requirements
        uses: actions/setup-node@v1
        with:
          node-version: '16'
      - run: npm install
      - run: npm test

JSON 파일과 YAML 파일은 key-value 형태로 작성된 파일이며, 계층 구조를 가지는 것에는 동일합니다.

YAML 파일은 "" (큰따옴표, double quotation marks) 없이 문자열 작성이 가능해, 설정을 위한 스펙이나 프로퍼티 값 등이 JSON 파일에 비해 한 눈에 들어온다는 점입니다. 또한 JSON 파일처럼 {} 형태로 감싸줄 필요도 없기 때문에 스코프의 압박(잘못 쓰면 일일이 어디가 처음이고 끝인지 찾아야 하는 등)에서 벗어날 수도 있습니다.

게다가 YAML 파일은 JSON 파일과 다르게 주석을 작성할 수 있다는 점도 굉장한 이점으로 작용합니다. JSON 파일은 주석을 작성할 수 없기 때문에 해당 파일 하나만 두고 커뮤니케이션 하기가 까다롭지만, YAML 파일은 애초에 파일 내에 주석을 작성할 수 있기 때문에 커뮤니케이션 하기가 훨씬 수월합니다.

그리고 YAML은 JSON의 상위 호환 격이므로, 기존 json문서를 그대로 yaml파일로 사용하거나 원하는 부분만 손볼 수 있습니다. 반대로 yaml을 json으로 변환해 사용할 수도 있다는 점이 장점으로 작용합니다.

YAML 문법

  • 주석, 문서의 시작과 끝

#  : 주석

--- : 문서의 시작 (선택사항)

...  : 문서의  (선택사항)

#이런 식으로 주석을 작성할 수 있습니다.

--- #문서 시작

#이 사이에 내용이 들어갑니다.

... #문서 끝

들여쓰기 : 들여쓰기는 기본적으로 2칸 또는 4칸을 지원합니다. 보통 2칸씩 들여쓰는 것을 추천합니다. 탭 키가 아닌 스페이스 키로 들여써야 합니다.

  • 기본 표현

key: value 이며, : 다음에는 무조건 공백 문자가 와야합니다.

key: value
  • 자료형

int, string, boolean, 리스트, 매핑을 지원합니다.

여기서 intstring 타입은 스칼라(Scalar)라 부르고, 배열 혹은 리스트는 시퀀스(Sequence)라 부릅니다. 매핑에는 기본 표현인 key-value 쌍 및 hash, dictionary가 포함됩니다.

#int(숫자)
int_type: 1

#string(문자열)
string_type: "1"

#blooean(참/거짓)
boolean_true_type: true
boolean_false_type: false

#이외에 yes, no로 작성하기도 합니다.
yaml_easy: yes
yaml_difficult: no

#리스트(배열 형태)
person:
  name: Chungsub Kim
  job: Developer
  skills: 
    - docker
    - kubernetes
  # JSON 형식의 "skill" : [docker, kubernetes]와 같습니다.
  • 객체

객체 표현은 key 작성 후 두 칸을 들여써서 key-value 형태로 작성을 해주거나, key를 작성 후 중괄호({})로 한 번 묶고 key-value 형태로 작성합니다.

key: 
  key: value
  key: value

#또는 이렇게도 작성합니다. 가독성을 위해 사용합니다.
key: {
  key: value,
  key: value
}
  • Text

줄바꿈 표현(|)과 줄바꿈 무시 표현(>)이 있습니다.

# |는 줄바꿈 표현입니다.
# JSON 형식의 "comment_line_break": "Hello codestates.\nIm kimcoding.\n"과 같습니다.
comment_line_break: |
  Hello codestates.
  Im kimcoding.

# >는 줄바꿈 무시 표현입니다.
# JSON 형식의 "comment_single_line": "Hello world my first coding."과 같습니다.
comment_single_line: >
  Hello world
  my first coding.
  • 문자열 따옴표

key-value 쌍에서 value에 :가 들어간 경우는 반드시 따옴표가 필요합니다.

# error가 납니다.
windows_drive: c:

# 이렇게 써야 합니다.
windows_drive: "c:"
windows_drive: 'c:'

실습

Github Actions를 통한 배포 Flow (클라이언트)

  • Source: Github reference 브랜치에 코드가 커밋되면
  • Build: github acitons의 YAML 파일에 적힌 명령어를 토대로 Webpack을 이용해 빌드를 하고
  • Deploy: github acitons의 YAML 파일에 적힌 명령어를 토대로 s3로 빌드 결과를 업로드합니다.

1. client.yml 파일 생성

# .github/workflows/client.yml 생성하기 

name: client
on:
  push:
    branches:
      - reference #내 레포지토리 branch 확인하기
jobs:
  build:
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout source code.
        uses: actions/checkout@v2
      - name: Install dependencies
        run: npm install #작성
        working-directory: ./my-agora-states-client
      - name: Build
        run: npm run build #작성
        working-directory: ./my-agora-states-client
      - name: SHOW AWS CLI VERSION
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_EC2_METADATA_DISABLED: true
        run: |
          aws --version
      - name: Sync Bucket
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_EC2_METADATA_DISABLED: true
        run: |
          aws s3 sync \ 
            --region ap-northeast-2 \
            build s3://fe-68-davina708-s3 \
            --delete
        working-directory: ./my-agora-states-client #작성

2. github에 push해주기

git add .
git commit -m "message~~"

git remote add myRepo git@github.com:davina708/my-agora-states-practice.git
git push myRepo reference

3. 깃헙 액션 시크릿 정하기

Encrypted secrets - GitHub Docs

name은 client.yml에 있는 코드로, value는 aws의 값으로(이메일 받음)

🚫 “process completed with exit code 1” Error 계속 발생!!
시크릿 키를 둘 다 설정을 안해주고 secret key만 등록해서 발생됐음.. access key id, secret access key 둘 다 설정해주니 해결됨…..

S3 버킷 확인

자동으로 잘 배포된 것 확인 가능

profile
[많을 (다) 빛날 (빈)] 빛이나는 사람이 되고 싶습니다

0개의 댓글