Github Actions 부터 CI/CD 실습까지

hyeongjun Jo·2023년 5월 19일
1

DevOps

목록 보기
7/11
post-thumbnail

목차

  • Gihub Actions?
    • Github Actions의 구성요소
    • Github Actions의 Workflow 문법
  • 실습
    • Github Actions을 이용해 docker hub에 이미지 자동 push
    • Server instance 생성
    • CD
  • Github Actions의 장점

Github Actions?

GitHub Actions는 코드 저장소(repository)로 유명한 GitHub에서 제공하는 CI(Continuous Integration, 지속 통합)와 CD(Continuous Deployment, 지속 배포)를 위한 비교적 최근에 추가된 서비스입니다. 당연히 GitHub에서 코드를 관리하고 있는 소프트웨어 프로젝트에서 사용할 수 있으며 개인은 누구나 GitHub에서 코드 저장소를 무료로 만들 수 있기 때문에 다른 CI/CD 서비스 대비 진입장벽이 낮은 편입니다.

GitHub Actions를 사용하면 자동으로 코드 저장소에서 어떤 이벤트(event)가 발생했을 때 특정 작업이 일어나게 하거나 주기적으로 어떤 작업들을 반복해서 실행시킬 수도 있습니다. 예를 들어, 누군가가 코드 저장소에 Pull Request를 생성하게 되면 GitHub Actions를 통해 해당 코드 변경분에 문제가 없는지 각종 검사를 진행할 수 있고요. 어떤 새로운 코드가 메인(main) 브랜치에 유입(push)되면 GitHub Actions를 통해 소프트웨어를 빌드(build)하고 상용 서버에 배포(deploy)할 수도 있습니다. 뿐만 아니라 매일 밤 특정 시각에 그날 하루에 대한 통계 데이터를 수집시킬 수도 있습니다.

이렇게 소프트웨어 프로젝트에서 지속적으로 수행해야하는 반복 작업들을 업계에서는 소위 CI/CD라고 많이 줄여서 부르는데요. 사람이 매번 직접 하기에는 비효율적인데다가 실수할 위험도 있기 때문에 GitHub Actions와 같은 자동화시키는 것이 유리합니다.

Github Actions의 구성요소

  • Workflow
    • 최상위 개념
    • 여러 Job으로 구성되고, Event에 의해 트리거될 수 있는 자동화된 프로세스입니다.
    • Workflow 파일은 YAML로 작성되고, .github/workflows 폴더 아래에 저장됩니다.
  • Event
    • Workflow를 트리거하는 특정 활동이나 규칙입니다.
      • 특정 브랜치로 Push하거나
      • 특정 브랜치로 Pull Request하거나
      • 특정 시간대에 반복(Cron)
      • Webhook을 사용해 외부 이벤트를 통해 실행
  • Job
    • Job은 여러 Step으로 구성되고 가상 환경의 인스턴스에서 실행됩니다.
    • 여러 Job 간 의존 관계를 가질 수 있고 기본적으로 병렬 실행됩니다.
  • Step
    • Task들의 집합으로 커맨드를 실행하거나 action을 실행할 수 있습니다.
  • Action
    • Workflow의 가장 작은 블럭
    • Job을 만들기 위해 Step 들을 연결할 수 있습니다.
    • 재사용이 가능한 컴포넌트입니다.
    • 개인적으로 만든 Action을 사용할 수도 있고 Marketplace에 있는 공용 Action을 사용할 수도 있습니다.
  • Runner
    • Github Action Runner 어플리케이션이 설치된 머신으로 Workflow가 실행될 인스턴스입니다.
    • Github에서 호스팅해주는 Github-hosted runner와 직접 호스팅하는 Self-hosted runner로 나뉩니다.
    • Github-hosted runner는 Azure의 Standard_DS2_v2로 vCPU 2, 메모리 7GB, 임시 스토리지 14GB의 사양입니다.

Github Actions의 Workflow 문법

아래는 예제에 쓰인 docker image를 push하는 yaml 파일입니다.


name: Docker Image CI

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  build-and-push-image:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v3

    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v1

    - name: Login to DockerHub
      uses: docker/login-action@v1
      with:
        username: chogudwns
        password: ${{ secrets.DOCKER_HUB_PW }}

    - name: Build and push
      id: docker_build
      uses: docker/build-push-action@v2
      with:
        push: true
        tags: chogudwns/saramin

가장 처음의 name은 workflow의 이름입니다.

그 다음의 on 은 해당 workflow가 수행될 trigger인 Event를 의미합니다. push - branches - main 은 main branch 에 push 가 일어나면 수행된다는 의미입니다. 그렇기 때문에 요청된 PR 을 merge 하거나 main branch 에 직접 push 하면 해당 workflow가 trigger 됩니다.

jobs 는 pipeline을 구성하는 부분입니다. steps 처음을 보면 "name: Checkout" 부분에 uses: actions/checkout@v3 로 되어 있는데 미리 정의된 action입니다. 실체 소스는 https://github.com/actions/checkout 으로 접속하면 볼 수 있으며 해당 기능은 디폴트로 workflow가 수행되는 github repository 의 소스 (현재 project 의 소스)를 내려받는 기능입니다. 내려 받을 repository 를 바꿀려면 변경 가능합니다.

stebs는 여러개로 이루어져 job을 구성합니다. "name: Set up Docker Buildx" 의 steb은 builder driver 나 platform 등을 세팅하는 부분입니다. 역시 자세한 부분은 https://github.com/docker/setup-buildx-action 에서 확인 가능합니다.

"name: Login to DockerHub" 는 docker hub 에 접근하기 위해서 id 와 password 를 지정하고 docker hub에 로그인하는 부분입니다. 이를 위해서는 github repository 의 settings 로 들어가서 좌측 하단의 secrets >> Actions 에서 Action 용 secret 을 만들어줘야 합니다.

실습

실습에 사용한 github repository는 제가 이전에 생성했던 검색어를 입력하면 사람인 채용공고 사이트에서 채용공고를 크롤링하는 코드가 있는 repository를 사용했습니다.

github repository 링크

스크린샷

csv 파일 예시

Github Actions을 이용해 docker hub에 이미지 자동 push

name: Docker Image CI

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  build-and-push-image:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v3

    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v1

    - name: Login to DockerHub
      uses: docker/login-action@v1
      with:
        username: chogudwns
        password: ${{ secrets.DOCKER_HUB_PW }}

    - name: Build and push
      id: docker_build
      uses: docker/build-push-action@v2
      with:
        push: true
        tags: chogudwns/saramin

자동 image push 성공

Server instace 생성

aws의 EC2 인스턴스를 server instance로 이용했습니다.
인스턴스가 docker hub에 접근해 이미지를 pull 하고 해당 이미지를 run 할 수 있게 하였습니다.

docker를 다운받습니다.

$ sudo su
$ yum install -y docker
$ systemctl start docker
$ systemctl enable docker

외부에서도 docker를 접근 가능하게 권한을 변경합니다.
chmod 666 /var/run/docker.sock

CD

이제 파이프라인에 방금 만든 인스턴스에 접근하여 image를 pull하고 실행하는 코드를 작성해야 합니다.

먼저 github에 secret으로 EC2의 호스트명과 EC2 key를 저장합니다.

yaml 파일에 코드를 추가합니다.

 - name: EC2 Docker Run
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ubuntu
          key: ${{ secrets.EC2_KEY }}
          script: |
            sudo su
            docker rm -f $(docker ps -qa)
            docker rmi chogudwns/saramin
            docker pull chogudwns/saramin 
            docker run -p -d 80:1323 -t saramin chogudwns/saramin
            

container stop 과 remove를 한번에 하기 위해 -f 옵션을 줬습니다.
workflow가 docker run에서 멈추지 않기 위해 -d 옵션으로 백단에서 실행했습니다.

workflow가 성공했음을 확인했습니다.

이제는 소스코드를 변경하고 push를 해보겠습니다.
전체적인 흐름은
1. source code 변경
2. github action workflow 실행
3. docker image 생성
4. docker image push
5. ec2 instance에서 docker image pull
6. ec2 instance에서 docker container 실행
순서 입니다.

페이지의 header를 변경해보겠습니다.

성공적으로 변경된 것을 확인가능합니다.

Github Actions의 장점

저는 Jenkins와 Travis CI, 그리고 이번에 github actions를 사용해 보았는데 github actions의 장점은 public repository에 대해 2,000분까지 무료이고 github 레포지토리와의 연동이 매우 쉽다는 것입니다.
또한 github actions는 안전합니다. GitHub Actions는 GitHub의 보안 인프라를 기반으로 구축되므로 코드와 리소스가 안전하게 유지됩니다.
뿐만 아니라 따로 설치할 종속성이 없다는 것이 장점입니다. Jenkins는 Java로 만들어졌기 때문에 JDK가 필요하고 만약 Container로 실행하면 노드에 Docker도 포함되어야 합니다.


Reference

profile
DevOps Engineer

0개의 댓글