Omnibus GitLab에 새로운 서비스 추가하기

GitLab에 새로운 서비스를 추가하려면 다음 단계를 따르어야 합니다:

  1. 빌드 중 소프트웨어 가져오고 컴파일하기
  2. 서비스를 위한 최상위 구성 객체 추가
  3. 서비스를 서비스 디렉터리에 포함하기
  4. 서비스를 위한 활성화 및 비활성화 레시피 만들기
  5. 로그 회전을 처리하는 방법 결정하고 문서화하기

옵션으로 다른 공통 작업은 서비스를 위한 추가 구성 구문 분석입니다.

빌드 중 소프트웨어 가져오고 컴파일하기

프로젝트에 이미 포함되어 있지 않은 경우, 서비스에 대한 새로운 소프트웨어 정의를 추가해야 합니다.

서비스를 위한 최상위 구성 객체 추가

files/gitlab-cookbooks에 위치한 레시피와 쿡북은 Omnibus GitLab 패키지가 설치된 인스턴스에서 gitlab-ctl reconfigure 중에 실행됩니다. 새로운 서비스에 대한 설정을 추가해야 하는 위치입니다.

기본 속성 정의

기존 쿡북 중 하나를 선택하여 서비스를 구성하거나, 서비스가 독자적인 경우에는 새로운 쿡북을 만들어야 합니다.

쿡북 내에는 attributes/default.rb 파일이 있어야 합니다. 여기에는 서비스에 대한 기본 속성을 정의해야 합니다. 서비스에 대해 기본적으로 enable 옵션을 정의해야 합니다.

default['gitlab']['best_service']['enable'] = false
default['gitlab']['best_service']['dir'] = '/var/opt/gitlab/best-service'
default['gitlab']['best_service']['log_directory'] = '/var/log/gitlab/best-service'
  • default는 기본 쿡북 속성을 정의하는 방법입니다.
  • ['gitlab']은 쿡북 이름을 포함합니다.
  • ['best_service']는 서비스의 이름입니다.
  • enable, dir, log_directory는 설정입니다.
  • /var/opt/gitlab은 서비스의 작업 디렉터리 및 구성 파일이 위치한 곳입니다.
  • /var/log/gitlab은 GitLab 패키지의 로그가 기록되는 곳입니다.

패키지에서 다른 설정을 기반으로 기본 값을 계산해야 하는 경우 일단 nil로 설정하세요.

명명 규칙

서비스는 주로 다음과 같은 세 가지 시나리오에서 언급됩니다:

  1. 서비스에 해당하는 Chef 속성에 액세스하는 경우
  2. 사용자, 그룹 및 서비스에 해당하는 항목을 참조하는 경우
  3. 서비스 이름을 메소드에 전달하여 다음과 유사한 서비스 속성을 찾는 경우:
    • “서비스가 활성화되어 있나요?”
    • “이 서비스에 해당하는 로그 소유권 세부 정보 가져오기”
    • “이 서비스에 대한 runit 구성 생성”

위에서 언급한 첫 번째 경우, 서비스 이름 내의 단어를 구분하기 위해 밑줄을 사용합니다. 나머지 두 경우에는 하이픈을 사용합니다. 구성이 주로 Ruby 객체로 사용되므로 밑줄을 사용하는 것이 더 유연합니다(예: 밑줄을 사용하면 구성 해시에서 심볼을 더 깔끔하게 사용할 수 있음).

예를 들어 GitLab Pages를 살펴보면, 속성은 Gitlab['gitlab_pages']node['gitlab_pages']로 사용되며, 기본 디렉터리 및 경로는 /var/log/gitlab/gitlab-pages/var/opt/gitlab/gitlab-pages와 같을 것입니다. 비슷하게 메소드 호출은 service_enabled?("gitlab-pages")와 같이 보일 것입니다.

서비스를 위한 구성 Mash 생성

사용자가 /etc/gitlab/gitlab.rb에서 서비스를 구성할 수 있도록 하려면 서비스를 위한 최상위 Mash를 추가해야 합니다.

files/gitlab-cookbooks/package/libraries/config/gitlab.rb에서는 attribute 메소드 디렉터리이 있습니다.

만약 서비스가 GitLab 쿡북 속성 내에 있는 경우, attribute_block('gitlab') 블록 내에 속성으로 추가해야 합니다. 그렇지 않고 서비스가 독자적인 쿡북을 가지고 있는 경우, 위에 추가하세요.

attribute('best_service')

EE 전용 속성의 경우 ee_attribute를 사용하세요.

ee_attribute('best_service')

서비스 구성을 설정 템플릿에 추가

여기에서 서비스를 설정하는 방법에 대한 예제가 주석 처리되어 있는 전역 구성 템플릿을 유지합니다.

이 파일은 패키지의 새로운 설치에서 /etc/gitlab/gitlab.rb가 됩니다.

서비스의 구성을 변경할 수 있도록 사용자에게 노출시키고 싶을 때 이 파일에 추가하세요. files/gitlab-config-template/gitlab.rb.template

### Best Service configuration
# best_service['enable'] = true
# best_service['dir'] = '/var/opt/gitlab/best-service'
# best_service['log_directory'] = '/var/log/gitlab/best-service'

제공된 값은 기본값을 반영하는 것이 아니라, 서비스를 사용하기 위해 주석을 해제하는 것을 쉽게 만들어주는 것입니다. 그런 경우 YOURSECRET과 같이 교체해야 할 값 또는 가장 말이 되는 상황에서 기본값을 사용하세요.

서비스를 서비스 디렉터리에 포함하기

레시피 내에서 서비스를 쉽게 활성화/비활성화할 수 있도록 하려면 해당 서비스를 서비스 디렉터리에 추가하고 적절한 그룹을 추가해야 합니다.

files/gitlab-cookbooks/package/libraries/config/services.rb 파일에서, 서비스를 Base 또는 EE에 추가할 수 있는 Config 클래스에 서비스를 추가하세요.

service 'best_service', groups: ['bestest']

그룹을 지정하면 한꺼번에 여러 관련 서비스를 비활성화/활성화하는 것이 더 쉬워집니다.

기존 그룹 중 어느 것도 서비스와 일치하지 않는 경우이고, 그룹을 사용하여 서비스를 활성화/비활성화할 필요가 없는 경우 현재 추가할 필요가 없습니다.

사용할 수 있는 일부 기존 그룹의 예:

  • 서비스가 Omnibus에서 기본적으로 활성화된 경우 DEFAULT_GROUP 그룹을 추가해야 합니다.
  • 서비스가 거의 모든 시나리오에서 비활성화되어서는 안 되는 경우 SYSTEM_GROUP를 추가하세요.
  • 서비스가 GitLab Rails에 구성되어 있어야 하는 경우 rails 그룹을 추가하세요.
  • 서비스가 새로운 프로메테우스 익스포터인 경우 prometheus 그룹을 추가하세요.

서비스용 활성 및 비활성 레시피 생성

활성 레시피

활성 레시피는 이미 존재하는 쿡북에 추가되는 경우 files/gitlab-cookbooks/<쿡북-이름>/recipes/<서비스-이름>.rb에 생성되어야 합니다. 서비스가 자체 쿡북을 가지고 있는 경우, 활성 레시피는 files/gitlab-cookbooks/<쿡북-이름>/recipes/enable.rb로 생성될 수 있습니다.

레시피에서는 서비스를 위해 /var/opt/gitlab에 작업 디렉터리를 생성해야 합니다. 서비스를 실행하는 시스템 사용자를 생성해야 합니다. 서비스에 필요한 구성 파일을 작업 디렉터리에 렌더링해야 합니다.

레시피 맨 끝 부분에는 레시피를 정의하기 위해 runit 서비스 정의에 요청을 수행해야 합니다. 이를 위해 쿡북의 templates/default 디렉터리에 run 파일을 생성해야 합니다. 이 파일 이름은 서비스 이름으로 시작하고, runit 액션 이름이 뒤에 옵니다.

서비스에는 일반적으로 run, log-run, log-config이 필요합니다.

sv-best-service-log-config.erb:

<%= "@svlogd_size를 추가" if @svlogd_size %>
<%= "@svlogd_num를 추가" if @svlogd_num %>
<%= "@svlogd_timeout를 추가" if @svlogd_timeout %>
<%= "@svlogd_filter를 추가" if @svlogd_filter %>
<%= "@svlogd_udp를 추가" if @svlogd_udp %>
<%= "@svlogd_prefix를 추가" if @svlogd_prefix %>

sv-best-service-log-run.erb:

#!/bin/sh
exec chpst -P \
  -U root:<%= @options[:log_group] || 'root' %> \
  -u root:<%= @options[:log_group] || 'root' %> \
  svlogd -tt <%= @options[:log_directory] %>

sv-best-service-run.erb:

#!/bin/sh
exec 2>&1
<%= render("mount_point_check.erb") %>
cd <%= node['gitlab']['best-service']['dir'] %>
exec chpst -P /opt/gitlab/embedded/bin/best-service -config-flags -etc

실행 중인 내용 및 해당 사용자에 따라 run 파일을 구성해야 합니다. 예제를 보려면 다른 -run.erb를 참조하세요.

레시피 내에서 runit 서비스를 호출하고 시작해야 합니다:

runit_service "best-service" do
  options({
    configItem: 'value',
    [...]
    log_directory: logging_settings[:log_directory],
    log_user: logging_settings[:runit_owner],
    log_group: logging_settings[:runit_group],
  }.merge(params))
  log_options logging_settings[:options]
end

if node['gitlab']['bootstrap']['enable']
  execute "/opt/gitlab/bin/gitlab-ctl start best-service" do
    retries 20
  end
end

로그 디렉터리

상기된 예제 설정에서 사용된 logging_settings은 서비스 로그 디렉터리, 로그 디렉터리에 할당된 로그 그룹 및 svlogd 실행에 사용되는 그룹에 대한 구성 설정의 일관된 참조를 제공하기 위해 LogfilesHelper 클래스를 사용합니다.

이러한 설정을 활용하려면 예를 들어 서비스용 enable.rbLogfilesHelper 클래스를 포함해야 합니다.

[...]
logfiles_helper = LogfilesHelper.new(node)
logging_settings = logfiles_helper.logging_settings('best-service')
[...]

기본 로그 디렉터리 사용자/그룹에 대한 디렉터리에 default_logdir_ownership 클래스 메서드에서 사용할 서비스에 best-service를 추가하세요. 특정한 사용자/그룹이 없는 경우에는 기본값으로 { username: gitlab_user, group: gitlab_group }를 사용하세요.

비활성 레시피

비활성 레시피는 이미 존재하는 쿡북에 추가되는 경우 files/gitlab-cookbooks/<쿡북-이름>/recipes/<서비스-이름>_disable.rb에 생성되어야 합니다. 서비스가 자체 쿡북을 가지고 있는 경우, 비활성 레시피는 files/gitlab-cookbooks/<쿡북-이름>/recipes/disable.rb로 생성될 수 있습니다.

레시피에는 서비스를 비활성화할 때 수행할 모든 정리를 포함해야 하며, runit 서비스를 비활성화하기 위한 호출이 있어야 합니다.

runit_service "best-service" do
  action :disable
end

로그 회전 처리 방법 결정 및 문서화

Omnibus에서 특정 서비스에 대한 로그 회전logrotate, svlogd, 양쪽 또는 둘 다로 처리할 수 있습니다. Omnibus GitLab에 서비스를 추가할 때 다음을 수행해야 합니다:

  • 새 서비스에 대해 로그 회전이 제대로 작동하는지 확인하세요.
  • 새 서비스가 로그 회전 테이블에 추가되도록 합병 요청을 엽니다.

runit(svlogd)를 사용하지 않는 새로운 로그가 추가된 경우 해당 로그를 매뉴얼으로 logrotate 구성에 추가해야 합니다. 더 많은 정보는 Improve logrotate handling 이슈에서 확인할 수 있습니다.

서비스용 추가 구성 구문 구문 분석

사용자가 설정한 다른 옵션에 따라 특정 구성 옵션을 채우고자 하는 경우, 사용자 정의 구문 분석을 위한 서비스용 라이브러리를 추가해야 합니다.

라이브러리는 files/gitlab-cookbooks/<쿡북 이름>/libraries/<서비스 이름>.rb에 추가되어야 합니다.

라이브러리는 서비스 이름을 따라 지정된 모듈이어야 하며 parse_variables 메서드를 가져아합니다.

module BestService
  class << self
    def parse_variables
      # 사용자가 제공한 구성 값에 기반한 일부 추가 구성을 설정합니다.
    end
  end
end

그런 다음 GitLab 구성이 귀하의 parse_variables 메서드를 호출하도록 해야 합니다.

files/gitlab-cookbooks/package/libraries/config/gitlab.rb로 이동하여 귀하의 속성을 라이브러리로 업데이트하세요.

attribute('best_service').use { BestService }

변수 처리 순서가 중요합니다. 따라서 라이브러리가 다른 서비스의 라이브러리 이후에 분석되기를 원하는 경우, 나중에 오는 우선 순위 값을 가진 값을 사용하여 속성을 업데이트해야 합니다. (기본 우선 순위 값은 20입니다)

attribute('expected_service').use { ExpectedService }
attribute('best_service', sequence: 25).use { BestService }