GitLab CI (Continuous integration)

leesjpr·2021년 10월 7일
0

MLOps

목록 보기
8/12

GitLab 을 통한 CI 설정

  • https://docs.gitlab.com/ee/ci/quick_start/
  • 본래 GitLab 을 통해 CI/CD 를 모두 구현 가능 하지만 금번 구성에는 Rancher 에서 Fleet 을 기반으로 CD 를 구현 할 것이기 때문에 CI 만 GitLab 에서 구현하는 것으로 진행

CI/CD process overview

Gitlab CI 를 위한 사전 준비사항
1) 동작 가능한 GitLab Runner. GitLab 에 Runner 등록 되어 있을 것.
2) GitLab project root 에 .gitlab-ci.yml 파일 생성 - CI 와 CD job 을 정의하게 되는 파일(CI 만 구현하는것으로 진행)

Create .gitlab-ci.yml

  • Side bar > Project information > Details
  • CI 구성 할 브랜치를 선택하여 .gitlab-ci.yml 을 Create
  • 다음과 같은 Sample code 를 추가하여 Commit
stages:
  - build
  - test

build-code-job:
  stage: build
  script:
    - echo "Check the ruby version, then build some Ruby project files:"
    - ruby -v
    - rake

test-code-job1:
  stage: test
  script:
    - echo "If the files are built successfully, test some files with one command:"
    - rake test1

test-code-job2:
  stage: test
  script:
    - echo "If the files are built successfully, test other files with a different command:"
    - rake test2

위 CI 예제는 build, test(2개 job), deploy stage 로 이루어진 단순히 메시지를 출력하는 문구로 이루어져 있는 CI 구성 파일(당연히 CI 는 성공한다..)

TIP1) GitLab 에서 적용 가능한 Template 를 제공함

TIP2) 러너가 Docker 컨테이너를 사용하여 작업을 실행하도록 하려면 이미지 이름을 포함하도록 .gitlab-ci.yml 파일을 편집한다.

// 아래와 같이 입력하면 도커 허브로부터 Ruby image 를 사용하고 이미지로부터 생성된 컨테이너에서 jobs 을 실행한다.
default:
  image: ruby:2.7.4

TIP3) .gitlab-ci.yml 파일의 유효성을 검증하려면 모든 Project 에서 Lint tool 을 사용한다.
https://docs.gitlab.com/ee/ci/lint.html

View the status of your pipeline and jobs

  • Side bar > CI/CD > Pipelines

GitLab CI/CD 의 용어 및 구성

Pipelines

CI/CD 의 최상위 구성 요소이며 수행할 작업을 정의하는 Jobs(예를 들어, 코드를 컴파일하거나 테스트하는 Job) 과 작업을 실행할 시기를 정의하는 Stages(예를 들어, 코드를 컴파일하는 단계 후에 테스트를 실행하는 단계) 로 구성

한 단계의 모든 Job이 성공하면, 파이프라인은 다음 단계로 넘어갑니다.
한 단계의 어떤 Job이 실패하면, 다음 단계는 (일반적으로) 실행되지 않고 파이프라인이 일찍 종료됩니다.

Jobs

Job은 .gitlab-ci.yml 파일의 가장 기본적인 요소
Job은 Runner가 실행해야 하는 명령 모음입니다. Job의 결과물(Output)이 무엇인지 실시간으로 볼 수 있으므로, 개발자는 Job이 실패한 이유를 이해할 수 있다.

  • 임의의 이름을 가진 최상위 요소이며 최소한 script 절을 포함해야 한다.
test:
  script:
    - python setup.py test
run:
  script:
    - python setup.py bdist_wheel

Variables

CI/CD 변수는 환경 변수의 한 유형. 다음의 역할을 수행.

  • Jobs 및 파이프라인의 동작을 제어
  • 재사용하려는 값을 저장
  • .gitlab-ci.yml 파일에 값을 하드 코딩하는 것을 방지

사전 정의된 기본 변수 세트를 사용하며, 변수에 대한 정보를 아래 링크에서 참고함.

  • 현재 작업의 디버깅 로그를 출력하는등의 작업시 활용 가능
test_variable:
  stage: test
  script:
    - echo "$CI_JOB_STAGE"
  • 추가적인 선언을 통한 사용
variables:
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"

Environments

환경은 코드가 배포되는 위치를 설명. 프로젝트와 연결된 Kubernetes와 같은 배포 서비스가 있는 경우, 이를 사용하여 배포를 지원 가능.

Runners

러너는 GitLab CI/CD의 코디네이터 API를 통해 CI Job을 선택하고, Job을 실행한 다음, 결과를 GitLab 인스턴스로 다시 보내는 경량의 확장성이 뛰어난 에이전트.

Runner 의 유형

  • 공유 러너(Shared runners)는 GitLab 인스턴스의 모든 그룹 및 프로젝트에서 사용할 수 있습니다.
  • 그룹 러너(Group runners)는 그룹의 모든 프로젝트와 하위 그룹에서 사용할 수 있습니다.
  • 특정 러너(Specific runners)는 특정 프로젝트와 연결됩니다. 일반적으로 특정 러너는 한 번에 하나의 프로젝트에 사용됩니다.

Artifacts

단계(Stages) 간에 전달되는 단계 결과에 사용합니다.

아티팩트는 저장 및 업로드할 수 있도록 Job에 의해 생성되는 파일입니다. 동일한 파이프라인의 이후 단계의 Job에서 아티팩트를 가져와 사용할 수 있습니다. 한 단계의 Job에서 아티팩트를 생성하여 동일한 단계의 다른 Job에서 이 아티팩트를 사용할 수 없습니다. 이 데이터는 다른 파이프라인에서 사용할 수 없지만 UI에서 다운로드할 수 있습니다.

애플리케이션을 빌드하는 동안 모듈을 다운로드하는 경우, 이를 아티팩트로 선언하고 후속 단계의 Job에서 이를 사용할 수 있습니다.

Cache

프로젝트 의존성(Dependencies)을 저장하는 데 사용합니다.

캐시는 후속 파이프라인에서 지정된 Job의 속도를 높일 수 있습니다. 인터넷에서 다시 가져올 필요가 없도록 다운로드 한 의존성을 저장할 수 있습니다. 의존성에는 npm 패키지, Go의 vendor 패키지 등이 포함됩니다. 단계 간에 중간 빌드 결과를 전달하도록 캐시를 구성할 수 있지만 대신 아티팩트를 사용해야 합니다.

GitLab CI 의 속도 향상

GitLab CI 파이프라인에서 Cache 를 사용하면 속도를 향상시킬 수 있음

cache:
  paths:
    - .cache/pip
    - venv/

CI Pipeline에 Docker 이미지 빌드 단계 추가

지속적 배포(Continuous Deployment) 파이프라인에서 사용할 애플리케이션의 Docker 이미지를 빌드하여 GitLab Container Registry에 이미지를 Push합니다.

Dockerfile 생성

Docker에는 이미지의 레이어(Layers)을 지정하는 데 사용하는 간단한 Dockerfile 파일 형식이 있습니다.

  • Dockerfile 파일을 작성하고 커밋
    GitLab의 Project overview >
    Details 페이지에서 project slug 오른쪽에 있는 [+] 아이콘을 클릭하고 New file를 선택합니다. > File name 필드에 Dockerfile를 입력하여 내용을 추가 >
    Commit changes 버튼을 클릭합니다.

.gitlab-ci.yml 파일에 Docker 이미지 빌드 단계 추가

.gitlab-ci.yml 파일에 package 단계 및 docker-build Job을 추가

  • stages에 - package을 추가
  • maven-build Job의 script을 수정하고 artifacts을 추가
  • docker-build Job 추가
  • 이미지를 빌드하여 레지스트리에 업로드 하는 간단한 예제
    (이 예제에서는 gitlab 에서 제공하는 컨테이너 레지스트리를 사용하기 때문에 registry.gitlab.com 으로 로그인 수행)
image: docker:stable

build:
  stage: build
  script:
    - docker login -u [계정] -p [패스워드] registry.gitlab.com
    - docker pull $CI_REGISTRY_IMAGE:latest || true
    - docker build --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest .

deploy:
   stage: deploy
   script:
    - docker login -u [계정] -p [패스워드] registry.gitlab.com
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    - docker push $CI_REGISTRY_IMAGE:latest
   only:
    - main

Docker image ci 하는 과정이 매끄럽게 진행되지 않아 트러블 슈팅시 참고했던 자료를 남겨놓음...
Trouble1)
$ docker run my-docker-image /script/to/run/tests
94docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/script/to/run/tests": stat /script/to/run/tests: no such file or directory: unknown.
95time="2021-10-08T15:58:09+09:00" level=error msg="error waiting for container: context canceled"

  • Dockerfile 내의 FROM alpine 이미지를 사용하는경우 bash 를 지원하지 않아 발생하는 오류

Trouble2)
error during connect: Post http://docker:2375/v1.40/auth: dial tcp: lookup docker on … no such host

Trouble3)
HTTP Basic: Access denied
https://codereviewvideos.com/blog/how-i-fixed-error-response-from-daemon-get-https-registry-example-com-v2-unauthorized-http-basic-access-denied/

  • docker login 계정과 이미지의 레포지토리 계정이 달라서 발생
  • 로그인 계정과 레포지토리를 다시한번 확인해보자

GitLab container repo command
docker login registry.gitlab.com
docker build -t registry.gitlab.com/sujisuji/mlops_ci .
docker push registry.gitlab.com/sujisuji/mlops_ci

참고자료

0개의 댓글