InfoGrab DocsInfoGrab Docs

ChatOps를 사용하여 기능 플래그 활성화 및 비활성화

요약

이 문서는 GitLab 제품 개발에 기여하는 방법을 설명합니다. 스테이징과 프로덕션처럼 GitLab 이 제공하는 환경에서 기능 플래그 뒤에 있는 기능을 켜거나 끄려면 ChatOps 봇에 대한 액세스 권한이 필요합니다.

Note

이 문서는 GitLab 제품 개발에 기여하는 방법을 설명합니다. 자체 애플리케이션에서 기능을 표시하거나 숨기는 데 기능 플래그를 사용하려면 대신 이 기능 플래그 정보를 확인합니다.

스테이징과 프로덕션처럼 GitLab 이 제공하는 환경에서 기능 플래그 뒤에 있는 기능을 켜거나 끄려면 ChatOps 봇에 대한 액세스 권한이 필요합니다. ChatOps 봇은 현재 ops 인스턴스에서 실행되며, 이는 GitLab.com 이나 dev.gitlab.org 와 다릅니다.

ChatOps 문서를 따라 액세스를 요청합니다.

프로젝트에 추가된 뒤 액세스 권한이 전파되었는지 테스트하려면 다음을 실행합니다.

/chatops gitlab run feature --help

변경 사항 롤아웃#

변경 사항이 환경에 배포되면 사용자에게 기능을 롤아웃할 시점입니다. 변경을 롤아웃하는 정확한 절차는 변경마다 다를 수 있으므로 규정하지 않습니다. 다만 일반적으로는 모두에게 한 번에 활성화하는 대신 변경 사항을 점진적으로 롤아웃하기를 권장합니다. 또한 코드가 배포되기 전에 기능을 활성화하지 않기를 권장합니다. 이렇게 하면 기능 롤아웃과 배포를 분리할 수 있어 각각의 영향을 측정하기가 더 쉬워집니다.

GitLab 기능 라이브러리는 (Flipper를 사용하며 기능 플래그 프로세스 가이드에서 다룹니다) 사용자에게 일정 비율의 시간 동안 변경 사항을 롤아웃하는 것을 지원합니다. 이는 GitLab ChatOps로 제어할 수 있습니다.

최신 기능 플래그 명령 목록은 소스 코드를 참고합니다. 그 파일의 모든 예시 앞에는 /chatops gitlab run 을 붙여야 합니다.

"Whoops! This action is not allowed. This incident will be reported." 오류가 발생하면 Slack 계정에 기능 플래그를 변경할 권한이 없거나 액세스 권한이 없다는 뜻입니다.

사전 프로덕션 테스트를 위한 기능 활성화#

기능 롤아웃의 첫 단계로 staging.gitlab.com 과 dev.gitlab.org 에서 기능을 활성화해야 합니다.

이 두 환경은 범위가 다릅니다. dev.gitlab.org 은 GitLab Inc. 내부 트래픽이 있는 프로덕션 CE 환경이며 일부 개발과 관련 작업에 사용됩니다. staging.gitlab.com 은 GitLab.com 데이터베이스와 리포지터리의 더 작은 일부를 가지고 있고 정기적인 트래픽이 없습니다. 스테이징은 EE 인스턴스이며, 기능이 GitLab.com 에서 어떻게 보이고 동작할지 (매우) 대략적으로 가늠하게 해 줍니다. 두 인스턴스 모두 Sentry 에 연결되어 있으므로, 기능 플래그를 활성화한 뒤 기능을 테스트하는 동안 예외가 있는지 그곳의 프로젝트를 확인합니다.

이러한 사전 프로덕션 환경에서는 가시성을 높이기 위해 #staging, #production, #chat-ops-test 에서 명령을 실행하기를 강력히 권장합니다.

특정 비율의 액터에 대해 기능 플래그 활성화#

지정된 액터에 대해 25% 의 확률로 기능을 활성화하려면 Slack 에서 다음을 실행합니다.

/chatops gitlab run feature set new_navigation_bar 25 --actors --dev
/chatops gitlab run feature set new_navigation_bar 25 --actors --staging

롤아웃을 무작위화할 액터 선택지는 액터 비율을 참고합니다.

GitLab.com 에 대한 기능 활성화#

기능이 사전 프로덕션 환경에서 성공적으로 활성화되고 안전하며 정상 동작하는 것으로 확인되면 변경 사항을 GitLab.com(프로덕션)에 롤아웃할 수 있습니다.

기능이 지원 중단된 경우에는 플래그를 활성화하지 않습니다.

변경 사항 공지#

GitLab.com 의 일부 기능 플래그 변경은 회사의 일부 조직에 알려야 합니다. 담당 개발자는 이것이 필요한지와 적절한 커뮤니케이션 수준을 판단해야 합니다. 이는 기능과 그 기능이 미칠 영향의 종류에 따라 달라집니다.

가이드라인:

  • 미리 #support_gitlab-com 에 알립니다. 기능이 사용자 경험에 부작용을 일으키는 경우 그들이 영향을 완화하고 기능 플래그를 비활성화해 영향을 줄일 수 있습니다.
    • 기능 플래그가 무엇을 하는지 간단히 설명합니다. GitLab Duo Agentic Chat 에 다음과 같이 물어보는 것으로 시작할 수 있습니다: Explain the feature flag <feature-flag-name> in the gitlab-org/gitlab project.
  • 기능이 변경 관리 이슈를 만들 요건을 충족하면 중요도 가이드라인에 따라 변경 관리 이슈를 만듭니다.
  • 특정 그룹이나 프로젝트의 기능 플래그를 전환해 달라는 지원 요청은 지원 워크플로에 설명된 절차를 따릅니다.

롤아웃 중 선택할 비율 가이드라인#

기능 플래그를 롤아웃할 때 비율을 선택하는 일은 여러 요인에 따라 달라집니다. 예를 들면 다음과 같습니다.

  • 롤아웃을 계속해도 안전한지 판단할 정보를 충분히 모을 수 있을 만큼 기능 플래그가 자주 확인되는지 검토합니다.
  • 기능에 문제가 생기면 얼마나 많은 요청이나 고객이 영향을 받는지 검토합니다.
  • 문제가 생기면 롤아웃으로 영향을 받는 다른 GitLab 공개 기능이 있는지 검토합니다.
  • 기능 플래그 롤아웃으로 성능이 저하될 가능성이 있는지 검토합니다.

서로 다른 유형의 기능 플래그에 대한 예시와 그런 경우에 롤아웃을 어떻게 고려할 수 있는지 살펴봅니다.

A. 하루에 몇 번만 실행되는 작업의 기능 플래그#

예를 들어 cron job 에서 하루에 몇 번 실행되는 새 기능을 릴리스하고, 그 기능이 새로 도입한 기능 플래그로 제어된다고 가정합니다. 예를 들면 cron job 의 데이터베이스 쿼리 재작성이 그렇습니다. 이 경우 25% 미만의 비율로 기능 플래그를 릴리스하면 롤아웃을 계속할지 판단하는 피드백이 느리게 올 수 있습니다. 또한 cron job 이 실패하면 재시도합니다. 따라서 문제가 생겼을 때의 결과가 그리 크지 않습니다. 이 경우 25% 또는 50% 로 릴리스하는 것이 받아들일 만한 선택입니다.

다만 워커의 로그에 기능 플래그 확인 결과를 반드시 기록해야 합니다. 로깅 모범 사례에 관한 자세한 안내는 로깅 컨텍스트 메타데이터(Rails 또는 Grape 요청을 통해)를 참고합니다.

B. 하루에 수백 또는 수천 번 실행되는 작업의 기능 플래그#

새로 도입한 기능이나 변경은 Sidekiq job 에서 실행되는 것보다 고객에게 더 많이 노출될 수 있습니다. 다만 자주 실행되지는 않을 수 있습니다. 이 경우 계속 진행할지 판단할 결과를 어느 정도 모을 수 있을 만큼 충분히 높은 비율을 선택합니다. 이 경우 5% 나 10% 로 시작하면서 오류나 사용자에게 반환되는 500 상태가 있는지 로그를 모니터링하는 방안을 고려할 수 있습니다.

다만 롤아웃을 계속하면서 비율을 높일 때는 기능의 성능 영향을 살펴봐야 합니다. Grafana 의 Latency: Apdex and error ratios 대시보드를 모니터링하는 방안을 고려할 수 있습니다.

C. 앱의 핵심 부분에서 실행되는 작업의 기능 플래그#

새 변경이 GitLab 애플리케이션의 모든 측면에 영향을 줄 때도 있습니다. 예를 들어 User, Project, Namespace 같은 핵심 모델 중 하나의 데이터베이스 쿼리를 변경하는 경우입니다. 이런 경우 사고를 피하기 위해 요청의 1%, 또는 그보다 더 적은 비율로(변경 요청을 통해) 기능을 릴리스하기를 강력히 권장합니다. 변경의 영향이 커서 요청의 약 0.1% 에 릴리스한 기능 플래그의 이 변경 요청 예시를 참고합니다.

롤아웃이 많은 고객에게 영향을 주지 않도록 다음 단계를 따르는 방안을 고려합니다.

  1. 기능 플래그를 100% 롤아웃했을 때 분당 몇 개의 요청이 영향을 받을 수 있는지 추정합니다. 이는 데이터베이스 쿼리를 추적해 확인할 수 있습니다. 여기의 안내를 참고합니다.
  2. 롤아웃이 예상대로 진행되지 않을 경우 영향을 받아도 괜찮은 요청 수나 사용자 수를 계산합니다.
  3. (1)과 (2)에서 수집한 수치를 바탕으로 기능 플래그 롤아웃을 시작할 합리적인 비율을 계산합니다. 그러한 계산의 예시가 있습니다.
  4. 기능 플래그의 롤아웃 이슈에 확인한 내용을 반드시 공유합니다.
D. 기능 플래그 릴리스의 알 수 없는 영향#

어떤 비율을 사용할지 확실하지 않다면 안전한 권장 옵션을 선택하고 다음 비율을 사용합니다.

  1. 1%
  2. 10%
  3. 25%
  4. 50%
  5. 75%
  6. 100%

각 단계 사이에는 잠시 기다리면서 https://dashboards.gitlab.net 의 적절한 그래프를 모니터링합니다. 기다려야 하는 정확한 시간은 다를 수 있습니다. 어떤 기능은 몇 분으로 충분하지만, 어떤 기능은 몇 시간 또는 며칠을 기다려야 할 수도 있습니다. 이는 전적으로 판단에 달려 있습니다. 잠재적인 문제가 예상된다면 팀과 프로덕션 팀에 명확히 전달해야 합니다.

프로세스#

기능 플래그 롤아웃을 활성화할 때 활성 "severity::1" 또는 ~"severity::2" 사고나 진행 중인 변경 이슈가 있으면 시스템이 ChatOps 명령이 성공하지 못하도록 자동으로 차단합니다. 예를 들면 다음과 같습니다.

/chatops gitlab run feature set gitaly_lfs_pointers_pipeline true

- Production checks fail!
- active incidents

  2021-06-29 Canary deployment failing QA tests

기능 플래그를 활성화하기 전에 프로덕션 변경 잠금(PCL) 기간을 위반하지 않는지, 기능 플래그와 변경 관리 프로세스를 준수하는지 확인합니다.

다음 /chatops 명령은 Slack #production 채널에서 실행해야 합니다.

액터 비율 롤아웃#

사용자, 프로젝트, 그룹, 현재 요청 또는 job 같은 액터의 25% 에 대해 기능을 활성화하려면 Slack 에서 다음을 실행합니다.

/chatops gitlab run feature set some_feature 25 --actors

이는 다음 공식을 기준으로 기능 플래그를 true 로 설정합니다.

feature_flag_state = Zlib.crc32("some_feature:#{actor.id}") % (100 * 1_000) < 25 * 1_000
# where : is a `User`, `Group`, `Project` and actor is an instance

개발 중에는 기능의 성격에 따라 액터를 선택해야 합니다.

사용자 중심 기능:

Feature.enabled?(:feature_cool_avatars, current_user)

그룹 또는 네임스페이스 수준 기능:

Feature.enabled?(:feature_cooler_groups, group)

프로젝트 수준 기능:

Feature.enabled?(:feature_ice_cold_projects, project)

현재 요청:

Feature.enabled?(:feature_ice_cold_projects, Feature.current_request)

기능 게이트는 액터 기반일 수도 있습니다. 예를 들어 기능을 먼저 gitlab 프로젝트에만 활성화할 수 있습니다. 프로젝트는 전체 프로젝트 경로나 숫자 프로젝트 ID 와 함께 --project 플래그를 제공해 전달합니다.

/chatops gitlab run feature set --project=gitlab-org/gitlab some_feature true
/chatops gitlab run feature set --project=278964 some_feature true

--user 옵션을 사용해 특정 사용자에게 기능 플래그를 활성화할 수 있습니다.

/chatops gitlab run feature set --user=myusername some_feature true

먼저 내부적으로 피드백을 모으려면 사용자 범위로 지정된 기능 플래그를 gitlab_team_members 기능 그룹으로 GitLab 팀 멤버에게 활성화할 수도 있습니다.

/chatops gitlab run feature set --feature-group=gitlab_team_members some_feature true

--group 플래그를 사용해 특정 그룹에 기능 플래그를 활성화할 수 있습니다.

/chatops gitlab run feature set --group=gitlab-org some_feature true

--group 은 사용자 네임스페이스에서는 동작하지 않습니다. 그룹을 포함한 일반 네임스페이스에 기능 플래그를 활성화하려면 --namespace 를 사용합니다.

/chatops gitlab run feature set --namespace=gitlab-org some_feature true
/chatops gitlab run feature set --namespace=myusername some_feature true

--organization 플래그를 사용해 경로나 숫자 ID 로 특정 조직에 기능 플래그를 활성화할 수 있습니다.

/chatops gitlab run feature set --organization=my-org some_feature true
/chatops gitlab run feature set --organization=1 some_feature true

액터 기반 게이트는 비율보다 먼저 적용됩니다. 예를 들어 group/project 를 gitlab-org/gitlab 로, 예시 기능을 some_feature 로 두고 다음 두 명령을 실행하는 경우입니다.

/chatops gitlab run feature set --project=gitlab-org/gitlab some_feature true
/chatops gitlab run feature set some_feature 25 --actors

그러면 some_feature 는 액터의 25% 에 대해 활성화되고, gitlab-org/gitlab 와 상호작용할 때는 항상 활성화됩니다. 기능 플래그 개발에서 그룹 액터를 사용한다면 좋은 방법입니다.

Feature.enabled?(:some_feature, group)

여러 액터를 쉼표로 구분해 함께 전달할 수 있습니다. 프로젝트 경로와 숫자 프로젝트 ID 를 섞어 쓸 수 있습니다.

/chatops gitlab run feature set --project=gitlab-org/gitlab,12345 some_feature true

/chatops gitlab run feature set --group=gitlab-org,example-org some_feature true

/chatops gitlab run feature set --namespace=gitlab-org,example-org some_feature true

/chatops gitlab run feature set --organization=my-org,other-org some_feature true

마지막으로 가능한 한 많은 경우에 기능이 안정적이라고 판단되는지 확인하려면 다음을 실행해 플래그를 전역으로 활성화해 기능을 완전히 롤아웃해야 합니다.

/chatops gitlab run feature set some_feature true

이렇게 하면 기능 플래그 상태가 항상 활성화로 바뀌며, 위 절차의 기존 게이트(예: --group=gitlab-org)를 재정의합니다.

액터 기반 기능 게이트가 있으면 YAML 정의의 default_enabled 속성을 false 에서 true 로 바꿔도 아무 효과가 없다는 점에 유의합니다. 기능 게이트를 먼저 삭제해야 합니다.

예를 들어 ChatOps 로 기능 플래그를 설정합니다.

/chatops gitlab run feature set --project=gitlab-org/gitlab some_feature true

YAML 정의의 default_enabled 속성을 true 로 바꿀 때 원하는 효과를 얻으려면 기능 게이트를 삭제해야 합니다.

/chatops gitlab run feature delete some_feature
시간 비율 롤아웃 (더 이상 사용되지 않음)#

이전에는 기능을 25% 의 시간 동안 활성화하려면 Slack 에서 다음을 실행했습니다.

/chatops gitlab run feature set new_navigation_bar 25 --random

이 명령은 GitLab.com 에 new_navigation_bar 기능을 활성화합니다. 다만 이 명령은 전체 사용자의 25% 에게 기능을 활성화하지 않습니다. 대신 enabled? 로 기능을 확인할 때 25% 의 확률로 true 를 반환합니다.

시간 비율 기능 플래그는 이제 Feature.current_request 액터를 사용하는 액터 비율 방식으로 대체되어 더 이상 사용되지 않습니다. 액터를 사용하지 않으면 무작위 선택이 요청이나 job 실행마다 한 번이 아니라 Feature.enabled? 호출마다 평가되어 상태가 오락가락할 수 있다는 문제가 있습니다. 예를 들면 다음과 같습니다.

feature_flag_state = rand < (25 / 100.0)

당분간은 시간 비율 기능 플래그 사용을 계속 허용합니다. 롤아웃 중에는 ChatOps 의 --ignore-random-deprecation-check 스위치로 강제할 수 있습니다.

기능 플래그 비활성화#

전역으로 활성화된 기능 플래그를 비활성화하려면 다음을 실행합니다.

/chatops gitlab run feature set some_feature false

특정 프로젝트에 활성화된 기능 플래그를 비활성화하려면 다음을 실행합니다.

/chatops gitlab run feature set --project=gitlab-org/gitlab some_feature false

기능 플래그의 특정 구현 방법을 적용하지 않으면 특정 프로젝트·그룹·사용자에 대해 기능 플래그를 선택적으로 비활성화할 수 없습니다.

ChatOps 로 기능 플래그를 비활성화하면 YAML 의 default_enabled 값보다 우선합니다. 즉 온프레미스 설치에서는 기능을 활성화하고 GitLab.com 에서는 활성화하지 않을 수 있습니다.

액터별 선택적 비활성화#

기본적으로 액터별로 기능 플래그를 선택적으로 비활성화할 수 없습니다.

# This will not work how you would expect.
/chatops gitlab run feature set some_feature true
/chatops gitlab run feature set --project=gitlab-org/gitlab some_feature false

다만 기능 플래그를 두 개 추가하면 동등한 선택적 비활성화가 가능한 방식으로 조건문을 작성할 수 있습니다.

Feature.enabled?(:a_feature, project) && Feature.disabled?(:a_feature_override, project)
# This will enable a feature flag globally, except for gitlab-org/gitlab
/chatops gitlab run feature set a_feature true
/chatops gitlab run feature set --project=gitlab-org/gitlab a_feature_override true

비율 기반 액터 선택#

여러 기능 플래그에 액터 비율 롤아웃을 사용할 때 각 기능 플래그의 액터는 별도로 선택됩니다.

예를 들어 다음 기능 플래그는 일정 비율의 액터에 대해 활성화되어 있습니다.

/chatops gitlab run feature set feature-set-1 25 --actors
/chatops gitlab run feature set feature-set-2 25 --actors

프로젝트 A 에 :feature-set-1 이 활성화되어 있다고 해서 프로젝트 A 에 :feature-set-2 도 활성화되어 있다는 보장은 없습니다.

자세한 내용은 This is how percentages work in Flipper를 참고합니다.

기능 플래그 활성화 후 메트릭 검증#

기능 플래그를 켠 뒤에는 각 단계 사이에 관련 그래프를 모니터링해야 합니다.

  1. dashboards.gitlab.net 으로 이동합니다.
  2. feature-flag 를 켭니다.
  3. 변경으로 영향을 받을 수 있는 서비스(sidekiq service, api service, web service 등)의 Latency: Apdex 를 지켜봅니다. 그다음 Service Overview Dashboards 를 선택하고 변경과 관련이 있을 만한 대시보드를 골라 더 자세한 대시보드를 확인합니다.

이 그림에서는 09:46 에 기능 플래그를 활성화한 뒤 Apdex 점수가 하락하기 시작한 것을 볼 수 있습니다. 이후 10:31 에 기능 플래그를 비활성화하자 서비스가 원래 값으로 돌아왔습니다.

Apdex 점수의 하락과 회복을 보여 주는 선 그래프

특히 위험이 크고 비즈니스 운영에 중요한 일부 기능은 여러 날에 걸쳐 광범위하게 모니터링해야 합니다. 반면 다른 기능은 롤아웃을 계속하기 전에 24시간만 모니터링하면 되는 경우도 있습니다.

롤아웃을 시작하기 전에 필요한 모니터링 범위를 정하기를 권장합니다.

기능 플래그 변경 로깅#

ChatOps 수준#

ChatOps를 통해 GitLab.com(프로덕션)에 영향을 주는 모든 기능 플래그 변경은 자동으로 이슈에 기록됩니다.

이슈는 gl-infra/feature-flag-log 프로젝트에 생성되며, 최소한 기능 플래그를 활성화한 사람의 Slack 핸들, 시각, 변경되는 플래그의 이름을 기록합니다.

그 이슈는 변경을 더 잘 드러내기 위해 GitLab 내부 Grafana 대시보드에 주석 마커로도 게시됩니다.

이슈 형식 변경은 ChatOps 프로젝트에 제출할 수 있습니다.

인스턴스 수준#

GitLab 인스턴스에 영향을 주는 모든 기능 플래그 변경은 features_json.log에 자동으로 기록됩니다. Kibana에서 변경 이력을 검색할 수 있습니다. GitLab.com 의 기능 플래그 변경 이력도 Kibana 에서 확인할 수 있습니다.

정리#

기능 플래그는 더 이상 필요하지 않게 되면 곧바로 제거해야 합니다. 코드베이스에 기능 플래그가 하나 더 늘어날 때마다 애플리케이션의 복잡성이 커지고 테스트 스위트가 가능한 모든 조합을 다룬다는 확신이 줄어듭니다. 또한 일부 환경에서 덮어쓴 기능 플래그는 정의되지 않고 테스트되지 않은 시스템 동작으로 이어질 수 있습니다.

development 유형 기능 플래그는 영구적인 변경을 롤아웃하는 것이 목적이므로 수명 주기가 짧아야 합니다. 2 개 마일스톤보다 오래된 development 기능 플래그는 엔지니어링 매니저에게 보고됩니다. 보고 도구는 매월 실행됩니다. 예를 들어 2021년 12월 보고서를 참고합니다.

development 기능 플래그가 6 개월이 지나도 코드베이스에 남아 있으면 다음 중 하나를 수행해야 합니다.

  • 기능 플래그를 기본적으로 활성화하고 제거합니다.
  • 인스턴스, 그룹 또는 프로젝트 설정으로 전환합니다.
  • 여전히 비활성화되어 있고 더 이상 필요하지 않으면 변경을 되돌립니다.

제로 다운타임 업그레이드 호환성#

기능 플래그를 제거하기 전에 그 플래그가 보호하는 코드가 GitLab Self-Managed 인스턴스의 제로 다운타임 업그레이드 중 혼합 버전 노드에서 실행해도 안전한지 검토합니다.

제로 다운타임 업그레이드 중에는 여러 컴포넌트(Rails, Sidekiq 등)가 서로 다른 버전의 코드를 동시에 실행합니다. 기능 플래그가 쓰기 경로, 캐시 키, 또는 컴포넌트 간에 공유되는 상태 전이를 제어한다면, 새 버전 컴포넌트에서 플래그가 제거된 상태에서도 이전 버전 컴포넌트가 여전히 올바르게 동작해야 합니다. 실제 예시는 사고 #562149를 참고합니다.

Warning

기능 플래그는 호환성 경계가 아닙니다. 플래그를 제거하거나 default_enabled: true 로 설정한다고 해서 그 뒤의 코드가 혼합 버전 노드에서 실행해도 안전해지지는 않습니다. 롤링 업그레이드 중에는 이전 버전 컴포넌트가 여전히 플래그가 비활성화된 상태로 실행됩니다.

올바른 접근 방식은 확장 및 축소 패턴입니다. 기능 플래그에 특화된 안내는 그 문서의 기능 플래그 섹션도 참고합니다.

데이터 쓰기, 캐시 키, 상태 전이를 제어하는 플래그는 세 개 마일스톤에 걸쳐 이 패턴을 적용합니다.

  1. 마일스톤 N(확장): 기존 동작을 그대로 유지하면서 새 동작을 도입합니다. 보호되는 코드가 혼합 버전 노드에서 안전하도록 만듭니다. 예를 들어 플래그가 Redis 캐시 쓰기를 제어한다면, 이전 버전 컴포넌트의 정리 경로가 플래그 활성화 여부에 의존하지 않도록 합니다. 이전 코드 경로와 새 코드 경로가 모두 안전하게 공존해야 합니다.
  2. 마일스톤 N+1(마이그레이션): 모든 소비자가 새 코드 경로를 사용하도록 갱신합니다. 확장 단계가 완료되었고 어떤 컴포넌트도 이전 경로에 의존하지 않는지 확인합니다.
  3. 마일스톤 N+2(축소): 플래그와 이전 코드 경로에 대한 모든 참조를 제거합니다.

데이터 쓰기, 캐시 키, 상태 전이를 제어하지 않는 플래그(예: 순수 UI 또는 동작 토글)에는 이 여러 마일스톤 패턴이 필요하지 않지만, 좋은 관행으로 여전히 권장합니다.

기능 플래그를 제거하려면 머지 리퀘스트 하나를 열어 변경합니다. 해당 MR 에서 다음을 수행합니다.

  1. 릴리스 매니저가 제거를 인지할 수 있도록 ~"feature flag" 레이블을 추가합니다.
  2. 머지 리퀘스트를 현재 버전으로 백포트해야 한다면 패치 릴리스 런북 절차를 따릅니다. 자세한 내용은 기능 플래그 프로세스를 참고합니다.
  3. 테스트를 포함해 코드베이스에서 기능 플래그에 대한 모든 참조를 제거합니다.
  4. 리포지터리에서 기능의 YAML 정의를 제거합니다.

위 MR 이 머지되면 다음을 수행해야 합니다.

  1. /chatops gitlab run feature delete some_feature 로 모든 환경에서 기능 플래그를 정리합니다.
  2. 기능 플래그가 코드베이스에서 제거된 뒤 해당 기능 플래그의 롤아웃 이슈를 닫습니다.

정리 ChatOps#

기능 게이트가 코드베이스에서 제거되어도 플래그가 배포된 데이터베이스에는 기능 레코드가 여전히 남아 있습니다. 이 레코드는 MR 이 모든 환경에 배포된 뒤에 삭제할 수 있습니다.

/chatops gitlab run feature delete <feature-flag-name> --dev --pre --staging --staging-ref --production

기능 플래그 상태 확인#

다음 ChatOps 명령으로 기능 플래그의 현재 상태를 확인할 수 있습니다.

/chatops gitlab run feature get <feature-flag-name>

이는 읽기 전용 명령이므로 다음 방법으로 프로덕션 채널을 어지럽히지 않을 수 있습니다.

  • #chat-ops-test Slack 채널에서 실행합니다
  • ChatOps 봇에 다이렉트 메시지로 보냅니다

이 명령의 결과에는 다음이 표시됩니다.

  • 기능 플래그가 존재하는지 여부
  • 현재 상태(활성화/비활성화)
  • 구성된 비율 롤아웃이나 액터 기반 게이트

ChatOps를 사용하여 기능 플래그 활성화 및 비활성화

GitLab v19.4
원문 보기

요약

이 문서는 GitLab 제품 개발에 기여하는 방법을 설명합니다. 스테이징과 프로덕션처럼 GitLab 이 제공하는 환경에서 기능 플래그 뒤에 있는 기능을 켜거나 끄려면 ChatOps 봇에 대한 액세스 권한이 필요합니다.

Note

이 문서는 GitLab 제품 개발에 기여하는 방법을 설명합니다. 자체 애플리케이션에서 기능을 표시하거나 숨기는 데 기능 플래그를 사용하려면 대신 이 기능 플래그 정보를 확인합니다.

스테이징과 프로덕션처럼 GitLab 이 제공하는 환경에서 기능 플래그 뒤에 있는 기능을 켜거나 끄려면 ChatOps 봇에 대한 액세스 권한이 필요합니다. ChatOps 봇은 현재 ops 인스턴스에서 실행되며, 이는 GitLab.com 이나 dev.gitlab.org 와 다릅니다.

ChatOps 문서를 따라 액세스를 요청합니다.

프로젝트에 추가된 뒤 액세스 권한이 전파되었는지 테스트하려면 다음을 실행합니다.

/chatops gitlab run feature --help

변경 사항 롤아웃#

변경 사항이 환경에 배포되면 사용자에게 기능을 롤아웃할 시점입니다. 변경을 롤아웃하는 정확한 절차는 변경마다 다를 수 있으므로 규정하지 않습니다. 다만 일반적으로는 모두에게 한 번에 활성화하는 대신 변경 사항을 점진적으로 롤아웃하기를 권장합니다. 또한 코드가 배포되기 전에 기능을 활성화하지 않기를 권장합니다. 이렇게 하면 기능 롤아웃과 배포를 분리할 수 있어 각각의 영향을 측정하기가 더 쉬워집니다.

GitLab 기능 라이브러리는 (Flipper를 사용하며 기능 플래그 프로세스 가이드에서 다룹니다) 사용자에게 일정 비율의 시간 동안 변경 사항을 롤아웃하는 것을 지원합니다. 이는 GitLab ChatOps로 제어할 수 있습니다.

최신 기능 플래그 명령 목록은 소스 코드를 참고합니다. 그 파일의 모든 예시 앞에는 /chatops gitlab run 을 붙여야 합니다.

"Whoops! This action is not allowed. This incident will be reported." 오류가 발생하면 Slack 계정에 기능 플래그를 변경할 권한이 없거나 액세스 권한이 없다는 뜻입니다.

사전 프로덕션 테스트를 위한 기능 활성화#

기능 롤아웃의 첫 단계로 staging.gitlab.com 과 dev.gitlab.org 에서 기능을 활성화해야 합니다.

이 두 환경은 범위가 다릅니다. dev.gitlab.org 은 GitLab Inc. 내부 트래픽이 있는 프로덕션 CE 환경이며 일부 개발과 관련 작업에 사용됩니다. staging.gitlab.com 은 GitLab.com 데이터베이스와 리포지터리의 더 작은 일부를 가지고 있고 정기적인 트래픽이 없습니다. 스테이징은 EE 인스턴스이며, 기능이 GitLab.com 에서 어떻게 보이고 동작할지 (매우) 대략적으로 가늠하게 해 줍니다. 두 인스턴스 모두 Sentry 에 연결되어 있으므로, 기능 플래그를 활성화한 뒤 기능을 테스트하는 동안 예외가 있는지 그곳의 프로젝트를 확인합니다.

이러한 사전 프로덕션 환경에서는 가시성을 높이기 위해 #staging, #production, #chat-ops-test 에서 명령을 실행하기를 강력히 권장합니다.

특정 비율의 액터에 대해 기능 플래그 활성화#

지정된 액터에 대해 25% 의 확률로 기능을 활성화하려면 Slack 에서 다음을 실행합니다.

/chatops gitlab run feature set new_navigation_bar 25 --actors --dev
/chatops gitlab run feature set new_navigation_bar 25 --actors --staging

롤아웃을 무작위화할 액터 선택지는 액터 비율을 참고합니다.

GitLab.com 에 대한 기능 활성화#

기능이 사전 프로덕션 환경에서 성공적으로 활성화되고 안전하며 정상 동작하는 것으로 확인되면 변경 사항을 GitLab.com(프로덕션)에 롤아웃할 수 있습니다.

기능이 지원 중단된 경우에는 플래그를 활성화하지 않습니다.

변경 사항 공지#

GitLab.com 의 일부 기능 플래그 변경은 회사의 일부 조직에 알려야 합니다. 담당 개발자는 이것이 필요한지와 적절한 커뮤니케이션 수준을 판단해야 합니다. 이는 기능과 그 기능이 미칠 영향의 종류에 따라 달라집니다.

가이드라인:

  • 미리 #support_gitlab-com 에 알립니다. 기능이 사용자 경험에 부작용을 일으키는 경우 그들이 영향을 완화하고 기능 플래그를 비활성화해 영향을 줄일 수 있습니다.
    • 기능 플래그가 무엇을 하는지 간단히 설명합니다. GitLab Duo Agentic Chat 에 다음과 같이 물어보는 것으로 시작할 수 있습니다: Explain the feature flag <feature-flag-name> in the gitlab-org/gitlab project.
  • 기능이 변경 관리 이슈를 만들 요건을 충족하면 중요도 가이드라인에 따라 변경 관리 이슈를 만듭니다.
  • 특정 그룹이나 프로젝트의 기능 플래그를 전환해 달라는 지원 요청은 지원 워크플로에 설명된 절차를 따릅니다.

롤아웃 중 선택할 비율 가이드라인#

기능 플래그를 롤아웃할 때 비율을 선택하는 일은 여러 요인에 따라 달라집니다. 예를 들면 다음과 같습니다.

  • 롤아웃을 계속해도 안전한지 판단할 정보를 충분히 모을 수 있을 만큼 기능 플래그가 자주 확인되는지 검토합니다.
  • 기능에 문제가 생기면 얼마나 많은 요청이나 고객이 영향을 받는지 검토합니다.
  • 문제가 생기면 롤아웃으로 영향을 받는 다른 GitLab 공개 기능이 있는지 검토합니다.
  • 기능 플래그 롤아웃으로 성능이 저하될 가능성이 있는지 검토합니다.

서로 다른 유형의 기능 플래그에 대한 예시와 그런 경우에 롤아웃을 어떻게 고려할 수 있는지 살펴봅니다.

A. 하루에 몇 번만 실행되는 작업의 기능 플래그#

예를 들어 cron job 에서 하루에 몇 번 실행되는 새 기능을 릴리스하고, 그 기능이 새로 도입한 기능 플래그로 제어된다고 가정합니다. 예를 들면 cron job 의 데이터베이스 쿼리 재작성이 그렇습니다. 이 경우 25% 미만의 비율로 기능 플래그를 릴리스하면 롤아웃을 계속할지 판단하는 피드백이 느리게 올 수 있습니다. 또한 cron job 이 실패하면 재시도합니다. 따라서 문제가 생겼을 때의 결과가 그리 크지 않습니다. 이 경우 25% 또는 50% 로 릴리스하는 것이 받아들일 만한 선택입니다.

다만 워커의 로그에 기능 플래그 확인 결과를 반드시 기록해야 합니다. 로깅 모범 사례에 관한 자세한 안내는 로깅 컨텍스트 메타데이터(Rails 또는 Grape 요청을 통해)를 참고합니다.

B. 하루에 수백 또는 수천 번 실행되는 작업의 기능 플래그#

새로 도입한 기능이나 변경은 Sidekiq job 에서 실행되는 것보다 고객에게 더 많이 노출될 수 있습니다. 다만 자주 실행되지는 않을 수 있습니다. 이 경우 계속 진행할지 판단할 결과를 어느 정도 모을 수 있을 만큼 충분히 높은 비율을 선택합니다. 이 경우 5% 나 10% 로 시작하면서 오류나 사용자에게 반환되는 500 상태가 있는지 로그를 모니터링하는 방안을 고려할 수 있습니다.

다만 롤아웃을 계속하면서 비율을 높일 때는 기능의 성능 영향을 살펴봐야 합니다. Grafana 의 Latency: Apdex and error ratios 대시보드를 모니터링하는 방안을 고려할 수 있습니다.

C. 앱의 핵심 부분에서 실행되는 작업의 기능 플래그#

새 변경이 GitLab 애플리케이션의 모든 측면에 영향을 줄 때도 있습니다. 예를 들어 User, Project, Namespace 같은 핵심 모델 중 하나의 데이터베이스 쿼리를 변경하는 경우입니다. 이런 경우 사고를 피하기 위해 요청의 1%, 또는 그보다 더 적은 비율로(변경 요청을 통해) 기능을 릴리스하기를 강력히 권장합니다. 변경의 영향이 커서 요청의 약 0.1% 에 릴리스한 기능 플래그의 이 변경 요청 예시를 참고합니다.

롤아웃이 많은 고객에게 영향을 주지 않도록 다음 단계를 따르는 방안을 고려합니다.

  1. 기능 플래그를 100% 롤아웃했을 때 분당 몇 개의 요청이 영향을 받을 수 있는지 추정합니다. 이는 데이터베이스 쿼리를 추적해 확인할 수 있습니다. 여기의 안내를 참고합니다.
  2. 롤아웃이 예상대로 진행되지 않을 경우 영향을 받아도 괜찮은 요청 수나 사용자 수를 계산합니다.
  3. (1)과 (2)에서 수집한 수치를 바탕으로 기능 플래그 롤아웃을 시작할 합리적인 비율을 계산합니다. 그러한 계산의 예시가 있습니다.
  4. 기능 플래그의 롤아웃 이슈에 확인한 내용을 반드시 공유합니다.
D. 기능 플래그 릴리스의 알 수 없는 영향#

어떤 비율을 사용할지 확실하지 않다면 안전한 권장 옵션을 선택하고 다음 비율을 사용합니다.

  1. 1%
  2. 10%
  3. 25%
  4. 50%
  5. 75%
  6. 100%

각 단계 사이에는 잠시 기다리면서 https://dashboards.gitlab.net 의 적절한 그래프를 모니터링합니다. 기다려야 하는 정확한 시간은 다를 수 있습니다. 어떤 기능은 몇 분으로 충분하지만, 어떤 기능은 몇 시간 또는 며칠을 기다려야 할 수도 있습니다. 이는 전적으로 판단에 달려 있습니다. 잠재적인 문제가 예상된다면 팀과 프로덕션 팀에 명확히 전달해야 합니다.

프로세스#

기능 플래그 롤아웃을 활성화할 때 활성 "severity::1" 또는 ~"severity::2" 사고나 진행 중인 변경 이슈가 있으면 시스템이 ChatOps 명령이 성공하지 못하도록 자동으로 차단합니다. 예를 들면 다음과 같습니다.

/chatops gitlab run feature set gitaly_lfs_pointers_pipeline true

- Production checks fail!
- active incidents

  2021-06-29 Canary deployment failing QA tests

기능 플래그를 활성화하기 전에 프로덕션 변경 잠금(PCL) 기간을 위반하지 않는지, 기능 플래그와 변경 관리 프로세스를 준수하는지 확인합니다.

다음 /chatops 명령은 Slack #production 채널에서 실행해야 합니다.

액터 비율 롤아웃#

사용자, 프로젝트, 그룹, 현재 요청 또는 job 같은 액터의 25% 에 대해 기능을 활성화하려면 Slack 에서 다음을 실행합니다.

/chatops gitlab run feature set some_feature 25 --actors

이는 다음 공식을 기준으로 기능 플래그를 true 로 설정합니다.

feature_flag_state = Zlib.crc32("some_feature:#{actor.id}") % (100 * 1_000) < 25 * 1_000
# where : is a `User`, `Group`, `Project` and actor is an instance

개발 중에는 기능의 성격에 따라 액터를 선택해야 합니다.

사용자 중심 기능:

Feature.enabled?(:feature_cool_avatars, current_user)

그룹 또는 네임스페이스 수준 기능:

Feature.enabled?(:feature_cooler_groups, group)

프로젝트 수준 기능:

Feature.enabled?(:feature_ice_cold_projects, project)

현재 요청:

Feature.enabled?(:feature_ice_cold_projects, Feature.current_request)

기능 게이트는 액터 기반일 수도 있습니다. 예를 들어 기능을 먼저 gitlab 프로젝트에만 활성화할 수 있습니다. 프로젝트는 전체 프로젝트 경로나 숫자 프로젝트 ID 와 함께 --project 플래그를 제공해 전달합니다.

/chatops gitlab run feature set --project=gitlab-org/gitlab some_feature true
/chatops gitlab run feature set --project=278964 some_feature true

--user 옵션을 사용해 특정 사용자에게 기능 플래그를 활성화할 수 있습니다.

/chatops gitlab run feature set --user=myusername some_feature true

먼저 내부적으로 피드백을 모으려면 사용자 범위로 지정된 기능 플래그를 gitlab_team_members 기능 그룹으로 GitLab 팀 멤버에게 활성화할 수도 있습니다.

/chatops gitlab run feature set --feature-group=gitlab_team_members some_feature true

--group 플래그를 사용해 특정 그룹에 기능 플래그를 활성화할 수 있습니다.

/chatops gitlab run feature set --group=gitlab-org some_feature true

--group 은 사용자 네임스페이스에서는 동작하지 않습니다. 그룹을 포함한 일반 네임스페이스에 기능 플래그를 활성화하려면 --namespace 를 사용합니다.

/chatops gitlab run feature set --namespace=gitlab-org some_feature true
/chatops gitlab run feature set --namespace=myusername some_feature true

--organization 플래그를 사용해 경로나 숫자 ID 로 특정 조직에 기능 플래그를 활성화할 수 있습니다.

/chatops gitlab run feature set --organization=my-org some_feature true
/chatops gitlab run feature set --organization=1 some_feature true

액터 기반 게이트는 비율보다 먼저 적용됩니다. 예를 들어 group/project 를 gitlab-org/gitlab 로, 예시 기능을 some_feature 로 두고 다음 두 명령을 실행하는 경우입니다.

/chatops gitlab run feature set --project=gitlab-org/gitlab some_feature true
/chatops gitlab run feature set some_feature 25 --actors

그러면 some_feature 는 액터의 25% 에 대해 활성화되고, gitlab-org/gitlab 와 상호작용할 때는 항상 활성화됩니다. 기능 플래그 개발에서 그룹 액터를 사용한다면 좋은 방법입니다.

Feature.enabled?(:some_feature, group)

여러 액터를 쉼표로 구분해 함께 전달할 수 있습니다. 프로젝트 경로와 숫자 프로젝트 ID 를 섞어 쓸 수 있습니다.

/chatops gitlab run feature set --project=gitlab-org/gitlab,12345 some_feature true

/chatops gitlab run feature set --group=gitlab-org,example-org some_feature true

/chatops gitlab run feature set --namespace=gitlab-org,example-org some_feature true

/chatops gitlab run feature set --organization=my-org,other-org some_feature true

마지막으로 가능한 한 많은 경우에 기능이 안정적이라고 판단되는지 확인하려면 다음을 실행해 플래그를 전역으로 활성화해 기능을 완전히 롤아웃해야 합니다.

/chatops gitlab run feature set some_feature true

이렇게 하면 기능 플래그 상태가 항상 활성화로 바뀌며, 위 절차의 기존 게이트(예: --group=gitlab-org)를 재정의합니다.

액터 기반 기능 게이트가 있으면 YAML 정의의 default_enabled 속성을 false 에서 true 로 바꿔도 아무 효과가 없다는 점에 유의합니다. 기능 게이트를 먼저 삭제해야 합니다.

예를 들어 ChatOps 로 기능 플래그를 설정합니다.

/chatops gitlab run feature set --project=gitlab-org/gitlab some_feature true

YAML 정의의 default_enabled 속성을 true 로 바꿀 때 원하는 효과를 얻으려면 기능 게이트를 삭제해야 합니다.

/chatops gitlab run feature delete some_feature
시간 비율 롤아웃 (더 이상 사용되지 않음)#

이전에는 기능을 25% 의 시간 동안 활성화하려면 Slack 에서 다음을 실행했습니다.

/chatops gitlab run feature set new_navigation_bar 25 --random

이 명령은 GitLab.com 에 new_navigation_bar 기능을 활성화합니다. 다만 이 명령은 전체 사용자의 25% 에게 기능을 활성화하지 않습니다. 대신 enabled? 로 기능을 확인할 때 25% 의 확률로 true 를 반환합니다.

시간 비율 기능 플래그는 이제 Feature.current_request 액터를 사용하는 액터 비율 방식으로 대체되어 더 이상 사용되지 않습니다. 액터를 사용하지 않으면 무작위 선택이 요청이나 job 실행마다 한 번이 아니라 Feature.enabled? 호출마다 평가되어 상태가 오락가락할 수 있다는 문제가 있습니다. 예를 들면 다음과 같습니다.

feature_flag_state = rand < (25 / 100.0)

당분간은 시간 비율 기능 플래그 사용을 계속 허용합니다. 롤아웃 중에는 ChatOps 의 --ignore-random-deprecation-check 스위치로 강제할 수 있습니다.

기능 플래그 비활성화#

전역으로 활성화된 기능 플래그를 비활성화하려면 다음을 실행합니다.

/chatops gitlab run feature set some_feature false

특정 프로젝트에 활성화된 기능 플래그를 비활성화하려면 다음을 실행합니다.

/chatops gitlab run feature set --project=gitlab-org/gitlab some_feature false

기능 플래그의 특정 구현 방법을 적용하지 않으면 특정 프로젝트·그룹·사용자에 대해 기능 플래그를 선택적으로 비활성화할 수 없습니다.

ChatOps 로 기능 플래그를 비활성화하면 YAML 의 default_enabled 값보다 우선합니다. 즉 온프레미스 설치에서는 기능을 활성화하고 GitLab.com 에서는 활성화하지 않을 수 있습니다.

액터별 선택적 비활성화#

기본적으로 액터별로 기능 플래그를 선택적으로 비활성화할 수 없습니다.

# This will not work how you would expect.
/chatops gitlab run feature set some_feature true
/chatops gitlab run feature set --project=gitlab-org/gitlab some_feature false

다만 기능 플래그를 두 개 추가하면 동등한 선택적 비활성화가 가능한 방식으로 조건문을 작성할 수 있습니다.

Feature.enabled?(:a_feature, project) && Feature.disabled?(:a_feature_override, project)
# This will enable a feature flag globally, except for gitlab-org/gitlab
/chatops gitlab run feature set a_feature true
/chatops gitlab run feature set --project=gitlab-org/gitlab a_feature_override true

비율 기반 액터 선택#

여러 기능 플래그에 액터 비율 롤아웃을 사용할 때 각 기능 플래그의 액터는 별도로 선택됩니다.

예를 들어 다음 기능 플래그는 일정 비율의 액터에 대해 활성화되어 있습니다.

/chatops gitlab run feature set feature-set-1 25 --actors
/chatops gitlab run feature set feature-set-2 25 --actors

프로젝트 A 에 :feature-set-1 이 활성화되어 있다고 해서 프로젝트 A 에 :feature-set-2 도 활성화되어 있다는 보장은 없습니다.

자세한 내용은 This is how percentages work in Flipper를 참고합니다.

기능 플래그 활성화 후 메트릭 검증#

기능 플래그를 켠 뒤에는 각 단계 사이에 관련 그래프를 모니터링해야 합니다.

  1. dashboards.gitlab.net 으로 이동합니다.
  2. feature-flag 를 켭니다.
  3. 변경으로 영향을 받을 수 있는 서비스(sidekiq service, api service, web service 등)의 Latency: Apdex 를 지켜봅니다. 그다음 Service Overview Dashboards 를 선택하고 변경과 관련이 있을 만한 대시보드를 골라 더 자세한 대시보드를 확인합니다.

이 그림에서는 09:46 에 기능 플래그를 활성화한 뒤 Apdex 점수가 하락하기 시작한 것을 볼 수 있습니다. 이후 10:31 에 기능 플래그를 비활성화하자 서비스가 원래 값으로 돌아왔습니다.

Apdex 점수의 하락과 회복을 보여 주는 선 그래프

특히 위험이 크고 비즈니스 운영에 중요한 일부 기능은 여러 날에 걸쳐 광범위하게 모니터링해야 합니다. 반면 다른 기능은 롤아웃을 계속하기 전에 24시간만 모니터링하면 되는 경우도 있습니다.

롤아웃을 시작하기 전에 필요한 모니터링 범위를 정하기를 권장합니다.

기능 플래그 변경 로깅#

ChatOps 수준#

ChatOps를 통해 GitLab.com(프로덕션)에 영향을 주는 모든 기능 플래그 변경은 자동으로 이슈에 기록됩니다.

이슈는 gl-infra/feature-flag-log 프로젝트에 생성되며, 최소한 기능 플래그를 활성화한 사람의 Slack 핸들, 시각, 변경되는 플래그의 이름을 기록합니다.

그 이슈는 변경을 더 잘 드러내기 위해 GitLab 내부 Grafana 대시보드에 주석 마커로도 게시됩니다.

이슈 형식 변경은 ChatOps 프로젝트에 제출할 수 있습니다.

인스턴스 수준#

GitLab 인스턴스에 영향을 주는 모든 기능 플래그 변경은 features_json.log에 자동으로 기록됩니다. Kibana에서 변경 이력을 검색할 수 있습니다. GitLab.com 의 기능 플래그 변경 이력도 Kibana 에서 확인할 수 있습니다.

정리#

기능 플래그는 더 이상 필요하지 않게 되면 곧바로 제거해야 합니다. 코드베이스에 기능 플래그가 하나 더 늘어날 때마다 애플리케이션의 복잡성이 커지고 테스트 스위트가 가능한 모든 조합을 다룬다는 확신이 줄어듭니다. 또한 일부 환경에서 덮어쓴 기능 플래그는 정의되지 않고 테스트되지 않은 시스템 동작으로 이어질 수 있습니다.

development 유형 기능 플래그는 영구적인 변경을 롤아웃하는 것이 목적이므로 수명 주기가 짧아야 합니다. 2 개 마일스톤보다 오래된 development 기능 플래그는 엔지니어링 매니저에게 보고됩니다. 보고 도구는 매월 실행됩니다. 예를 들어 2021년 12월 보고서를 참고합니다.

development 기능 플래그가 6 개월이 지나도 코드베이스에 남아 있으면 다음 중 하나를 수행해야 합니다.

  • 기능 플래그를 기본적으로 활성화하고 제거합니다.
  • 인스턴스, 그룹 또는 프로젝트 설정으로 전환합니다.
  • 여전히 비활성화되어 있고 더 이상 필요하지 않으면 변경을 되돌립니다.

제로 다운타임 업그레이드 호환성#

기능 플래그를 제거하기 전에 그 플래그가 보호하는 코드가 GitLab Self-Managed 인스턴스의 제로 다운타임 업그레이드 중 혼합 버전 노드에서 실행해도 안전한지 검토합니다.

제로 다운타임 업그레이드 중에는 여러 컴포넌트(Rails, Sidekiq 등)가 서로 다른 버전의 코드를 동시에 실행합니다. 기능 플래그가 쓰기 경로, 캐시 키, 또는 컴포넌트 간에 공유되는 상태 전이를 제어한다면, 새 버전 컴포넌트에서 플래그가 제거된 상태에서도 이전 버전 컴포넌트가 여전히 올바르게 동작해야 합니다. 실제 예시는 사고 #562149를 참고합니다.

Warning

기능 플래그는 호환성 경계가 아닙니다. 플래그를 제거하거나 default_enabled: true 로 설정한다고 해서 그 뒤의 코드가 혼합 버전 노드에서 실행해도 안전해지지는 않습니다. 롤링 업그레이드 중에는 이전 버전 컴포넌트가 여전히 플래그가 비활성화된 상태로 실행됩니다.

올바른 접근 방식은 확장 및 축소 패턴입니다. 기능 플래그에 특화된 안내는 그 문서의 기능 플래그 섹션도 참고합니다.

데이터 쓰기, 캐시 키, 상태 전이를 제어하는 플래그는 세 개 마일스톤에 걸쳐 이 패턴을 적용합니다.

  1. 마일스톤 N(확장): 기존 동작을 그대로 유지하면서 새 동작을 도입합니다. 보호되는 코드가 혼합 버전 노드에서 안전하도록 만듭니다. 예를 들어 플래그가 Redis 캐시 쓰기를 제어한다면, 이전 버전 컴포넌트의 정리 경로가 플래그 활성화 여부에 의존하지 않도록 합니다. 이전 코드 경로와 새 코드 경로가 모두 안전하게 공존해야 합니다.
  2. 마일스톤 N+1(마이그레이션): 모든 소비자가 새 코드 경로를 사용하도록 갱신합니다. 확장 단계가 완료되었고 어떤 컴포넌트도 이전 경로에 의존하지 않는지 확인합니다.
  3. 마일스톤 N+2(축소): 플래그와 이전 코드 경로에 대한 모든 참조를 제거합니다.

데이터 쓰기, 캐시 키, 상태 전이를 제어하지 않는 플래그(예: 순수 UI 또는 동작 토글)에는 이 여러 마일스톤 패턴이 필요하지 않지만, 좋은 관행으로 여전히 권장합니다.

기능 플래그를 제거하려면 머지 리퀘스트 하나를 열어 변경합니다. 해당 MR 에서 다음을 수행합니다.

  1. 릴리스 매니저가 제거를 인지할 수 있도록 ~"feature flag" 레이블을 추가합니다.
  2. 머지 리퀘스트를 현재 버전으로 백포트해야 한다면 패치 릴리스 런북 절차를 따릅니다. 자세한 내용은 기능 플래그 프로세스를 참고합니다.
  3. 테스트를 포함해 코드베이스에서 기능 플래그에 대한 모든 참조를 제거합니다.
  4. 리포지터리에서 기능의 YAML 정의를 제거합니다.

위 MR 이 머지되면 다음을 수행해야 합니다.

  1. /chatops gitlab run feature delete some_feature 로 모든 환경에서 기능 플래그를 정리합니다.
  2. 기능 플래그가 코드베이스에서 제거된 뒤 해당 기능 플래그의 롤아웃 이슈를 닫습니다.

정리 ChatOps#

기능 게이트가 코드베이스에서 제거되어도 플래그가 배포된 데이터베이스에는 기능 레코드가 여전히 남아 있습니다. 이 레코드는 MR 이 모든 환경에 배포된 뒤에 삭제할 수 있습니다.

/chatops gitlab run feature delete <feature-flag-name> --dev --pre --staging --staging-ref --production

기능 플래그 상태 확인#

다음 ChatOps 명령으로 기능 플래그의 현재 상태를 확인할 수 있습니다.

/chatops gitlab run feature get <feature-flag-name>

이는 읽기 전용 명령이므로 다음 방법으로 프로덕션 채널을 어지럽히지 않을 수 있습니다.

  • #chat-ops-test Slack 채널에서 실행합니다
  • ChatOps 봇에 다이렉트 메시지로 보냅니다

이 명령의 결과에는 다음이 표시됩니다.

  • 기능 플래그가 존재하는지 여부
  • 현재 상태(활성화/비활성화)
  • 구성된 비율 롤아웃이나 액터 기반 게이트