GitLab CI/CD 인스턴스 구성

Tier: Free, Premium, Ultimate Offering: Self-Managed

GitLab 관리자는 자체 관리형 인스턴스에서 GitLab CI/CD 구성을 관리할 수 있습니다.

새 프로젝트에서 GitLab CI/CD 비활성화

기본적으로 모든 새 프로젝트에서 GitLab CI/CD가 활성화되어 있습니다. 새 프로젝트에서 CI/CD를 기본적으로 비활성화하려면 다음 설정을 수정할 수 있습니다:

  • 자체 컴파일 설치의 경우 gitlab.yml.
  • Linux 패키지 설치의 경우 gitlab.rb.

이미 CI/CD가 활성화된 기존 프로젝트에는 변경이 없습니다. 또한 이 설정은 프로젝트 기본값만 변경하므로 프로젝트 소유자는 프로젝트 설정에서 CI/CD를 여전히 활성화할 수 있습니다.

자체 컴파일 설치의 경우:

  1. 에디터로 gitlab.yml을 열고 buildsfalse로 설정합니다:

    ## Default project features settings
    default_projects_features:
      issues: true
      merge_requests: true
      wiki: true
      snippets: false
      builds: false
    
  2. gitlab.yml 파일을 저장합니다.

  3. GitLab을 다시 시작합니다:

    sudo service gitlab restart
    

Linux 패키지 설치의 경우:

  1. /etc/gitlab/gitlab.rb를 편집하고 다음 라인을 추가합니다:

    gitlab_rails['gitlab_default_projects_features_builds'] = false
    
  2. /etc/gitlab/gitlab.rb 파일을 저장합니다.

  3. GitLab을 재구성합니다:

    sudo gitlab-ctl reconfigure
    

needs 작업 제한 설정

Tier: Free, Premium, Ultimate Offering: Self-Managed

needs에서 정의할 수 있는 최대 작업 수는 기본적으로 50개로 설정됩니다.

GitLab 레일즈 콘솔에 액세스할 수 있는 GitLab 관리자는 사용자 정의 제한을 선택할 수 있습니다. 예를 들어, 제한을 100으로 설정하려면:

Plan.default.actual_limits.update!(ci_needs_size_limit: 100)

DAG(Directed Acyclic Graphs)를 비활성화하려면 제한을 0으로 설정합니다. needs를 사용하도록 구성된 작업을 포함하는 파이프라인은 이후에 job can only need 0 others라는 오류가 반환됩니다.

최대 예약 파이프라인 빈도 변경

예약된 파이프라인은 임의의 cron 값을 사용하여 구성할 수 있지만 항상 예정된 시간에 정확히 실행되는 것은 아닙니다. 파이프라인 예약 워커 라는 내부 프로세스는 모든 예약된 파이프라인을 대기열에 넣지만 계속해서 실행되지는 않습니다. 이 워커는 자체 일정에 따라 실행되며 시작할 준비가 된 예약된 파이프라인만 다음 번 워커가 실행될 때 대기열에 넣습니다. 예약된 파이프라인은 워커가 실행되는 것보다 더 자주 실행될 수 없습니다.

기본 파이프라인 예약 워커의 기본 빈도는 3-59/10 * * * *입니다(10분마다, 0:03, 0:13, 0:23, 등과 같이 시작). GitLab.com의 기본 빈도는 GitLab.com 설정에 나와 있습니다.

파이프라인 예약 워커의 빈도를 변경하려면:

  1. 인스턴스의 gitlab.rb 파일에서 gitlab_rails['pipeline_schedule_worker_cron'] 값을 편집합니다.
  2. 변경 사항이 적용되려면 GitLab을 재구성합니다.

예를 들어, 파이프라인의 최대 빈도를 하루에 두 번으로 설정하려면 pipeline_schedule_worker_cron0 */12 * * * (매일 00:0012:00)로 설정합니다.

재해 복구

지속적인 다운타임 중 데이터베이스에 가중을 덜어주기 위해 애플리케이션의 중요하지만 계산적으로 비싼 부분을 비활성화할 수 있습니다.

인스턴스 러너에서 공정한 스케줄링 비활성화

작업의 대량 대기열을 지우는 경우 ci_queueing_disaster_recovery_disable_fair_scheduling 기능 플래그를 임시로 활성화할 수 있습니다. 이 플래그는 인스턴스 러너에서 공정한 스케줄링을 비활성화하여 jobs/request 엔드포인트의 시스템 리소스 사용을 줄입니다.

활성화되면 작업은 많은 프로젝트에 고르게 분배되는 대신 시스템에 입력된 순서대로 처리됩니다.

컴퓨팅 할당량 강제 비활성화

인스턴스 러너에서 컴퓨팅 할당량 강제 적용을 비활성화하려면 ci_queueing_disaster_recovery_disable_quota 기능 플래그를 임시로 활성화할 수 있습니다. 이 플래그는 jobs/request 엔드포인트의 시스템 리소스 사용을 줄이고 할당량이 초과된 프로젝트에서 지난 1시간 동안 생성된 작업을 실행할 수 있도록 합니다. 이전 작업은 주기적 백그라운드 워커(StuckCiJobsWorker)에 의해 이미 취소되었습니다.

CI/CD 문제 해결 레일즈 콘솔 명령

다음 명령은 레일즈 콘솔에서 실행됩니다.

경고: 데이터를 직접 변경하는 명령은 올바르게 실행되지 않거나 올바른 조건에서 실행되지 않으면 손상을 초래할 수 있습니다. 가능한 경우 이러한 명령을 실행하기 전에 백업된 인스턴스의 테스트 환경에서 실행하는 것을 강력히 권장합니다.

멈춰있는 대기 중인 파이프라인 취소하기

project = Project.find_by_full_path('<project_path>')
Ci::Pipeline.where(project_id: project.id).where(status: 'pending').count
Ci::Pipeline.where(project_id: project.id).where(status: 'pending').each {|p| p.cancel if p.stuck?}
Ci::Pipeline.where(project_id: project.id).where(status: 'pending').count

병합 요청 통합 시도

project = Project.find_by_full_path('<project_path>')
mr = project.merge_requests.find_by(iid: <merge_request_iid>)
mr.project.try(:ci_integration)

.gitlab-ci.yml 파일 유효성 검사

project = Project.find_by_full_path('<project_path>')
content = p.ci_config_for(project.repository.root_ref_sha)
Gitlab::Ci::Lint.new(project: project,  current_user: User.first).validate(content)

기존 프로젝트에서 AutoDevOps 비활성화

Project.all.each do |p|
  p.auto_devops_attributes={"enabled"=>"0"}
  p.save
end

러너 등록 토큰 획득

Gitlab::CurrentSettings.current_application_settings.runners_registration_token

러너 등록 토큰 생성

appSetting = Gitlab::CurrentSettings.current_application_settings
appSetting.set_runners_registration_token('<new-runners-registration-token>')
appSetting.save!

파이프라인 스케줄 수동으로 실행

때로는 보이지 않는 오류를 확인하기 위해 레일즈 콘솔을 통해 파이프라인 스케줄을 수동으로 실행할 수 있습니다.

# schedule_id는 '파이프라인 스케줄 편집' 페이지에서 얻을 수 있습니다.
schedule = Ci::PipelineSchedule.find_by(id: <schedule_id>)

# 스케줄을 실행할 사용자를 선택합니다.
user = User.find_by_username('<username>')

# 스케줄 실행
ps = Ci::CreatePipelineService.new(schedule.project, user, ref: schedule.ref).execute!(:schedule, ignore_skip_ci: true, save_on_errors: false, schedule: schedule)