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

note
이 문서는 GitLab 제품 개발에 기여하는 방법을 설명합니다.
자신의 응용 프로그램에서 기능을 표시 및 숨기기 위해 기능 플래그를 사용하고자 하는 경우,
이 기능 플래그 정보를 참조하세요.

기능 플래그 뒤에 있는 기능을 활성화/비활성화하려면
GitLab에서 제공하는 환경(예: 스테이징 및 프로덕션)에 대한 액세스 권한이 필요합니다.
ChatOps 봇에 접근해야 합니다.
현재 ChatOps 봇은 ops 인스턴스에서 실행되고 있으며, 이는
GitLab.com 또는 dev.gitlab.org와 다릅니다.

ChatOps 문서를 따라 액세스 요청을 하세요.

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

/chatops run feature --help

변경 사항 롤아웃

변경 사항이 환경에 배포되면 사용자에게 기능 롤아웃을 시작할 때입니다.
변경 사항을 롤아웃하는 정확한 절차는 명시되어 있지 않으며, 이는 변경마다 다를 수 있습니다.
그러나 일반적으로 모든 사용자에게 바로 활성화하기보다 점진적으로 변경 사항을 롤아웃할 것을 권장합니다.
또한 코드를 배포하기 전에 기능을 활성화하지 않을 것을 권장합니다.
이렇게 하면 기능 롤아웃과 배포를 분리할 수 있어 두 가지의 영향을 별도로 측정하기가 더 쉬워집니다.

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

최신 기능 플래그 명령 목록은 소스 코드를 참조하세요.
해당 파일의 모든 예제는 /chatops run으로 시작해야 합니다.

“Whoops! 이 작업은 허용되지 않습니다. 이 사건은 보고됩니다.”라는 오류가 발생하면
당신의 Slack 계정이 기능 플래그를 변경할 수 없거나 접근 권한이 없음을 의미합니다.

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

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

이 두 환경은 서로 다른 범위를 가지고 있습니다.
dev.gitlab.org는 내부 GitLab Inc. 트래픽이 있는 프로덕션 CE 환경으로,
일부 개발 및 기타 관련 작업에 사용됩니다.
staging.gitlab.com은 GitLab.com 데이터베이스와 리포지토리의 더 작은 하위 집합을 가지고 있으며,
정기적인 트래픽이 없습니다. 스테이징은 EE 인스턴스이며, 귀하의 기능이 GitLab.com에서
어떻게 보이고 작동할지에 대한 대략적인 추정치를 제공할 수 있습니다.
이 두 인스턴스는 Sentry에 연결되어 있으므로 기능 플래그를 활성화한 후
기능을 테스트할 때 거기에서 예외를 확인하는 것이 좋습니다.

이 사전 프로덕션 환경에서는 가시성을 높이기 위하여
#staging, #production 또는 #chatops-ops-test에서 명령을 실행하는 것이 강력히 권장됩니다.

시간 비율을 가진 기능 플래그 활성화

기능을 시간의 25% 동안 활성화하려면 Slack에서 다음을 실행하세요:

/chatops run feature set new_navigation_bar 25 --random --dev
/chatops run feature set new_navigation_bar 25 --random --staging
note
시간 비율 기능 플래그는 행동자 기반 비율을 위해 더 이상 사용되지 않습니다.
시간 비율 기능 플래그를 사용할 경우의 결과를 이해하고 있다면
--ignore-random-deprecation-check를 사용하여 강제로 실행할 수 있습니다.

GitLab.com에서 기능 활성화하기

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

기능이 사용 중단(deprecated) 되었을 경우, 플래그를 활성화하지 마십시오.

변경 사항 전달하기

GitLab.com의 일부 기능 플래그 변경 사항은 회사의 일부와 전달되어야 합니다. 책임 개발자가 이것이 필요하며 적절한 전달 수준을 결정해야 합니다. 이는 기능과 영향에 따라 달라집니다.

지침:

  • #support_gitlab-com에 미리 알립니다. 그렇게 하면 기능이 사용자 경험에 부작용이 발생할 경우 이를 완화하고 영향을 줄이기 위해 기능 플래그를 비활성화할 수 있습니다.
  • 기능이 변경 관리 이슈를 만들기 위한 요구 사항을 충족하는 경우, 중요도 지침에 따라 변경 관리 이슈를 만듭니다.
  • 간단하고 위험이 낮으며 쉽게 되돌릴 수 있는 기능의 경우, 진행하여 #production에서 기능을 활성화합니다.
  • 특정 그룹 또는 프로젝트에 대한 기능 플래그 전환 요청 시 지원 워크플로우에 설명된 절차를 따릅니다.

롤아웃 중 선택할 비율에 대한 지침

기능 플래그를 롤아웃할 때 선택할 비율은 여러 요인에 따라 달라집니다. 예를 들어:

  • 기능 플래그가 자주 체크되어 계속 롤아웃을 진행하는 것이 안전한지 결정하기에 충분한 정보를 수집할 수 있습니까?
  • 기능에 문제가 발생하면 얼마나 많은 요청이나 고객이 영향을 받을까요?
  • 문제가 발생했을 때, 롤아웃으로 인해 영향을 받을 GitLab의 공개 기능이 있습니까?
  • 기능 플래그를 롤아웃함으로써 성능 저하가 발생할 가능성이 있습니까?

다양한 유형의 기능 플래그와 이러한 경우 롤아웃을 고려할 수 있는 예제를 살펴보겠습니다:

A. 하루에 몇 번 실행되는 작업을 위한 기능 플래그

하루에 몇 번 실행되는, 예를 들어, 매일 또는 매시간 크론 작업에서 새로운 기능을 출시한다고 가정해 보겠습니다. 이 새로운 기능은 새로 도입된 기능 플래그에 의해 제어됩니다. 예를 들어, 크론 작업을 위한 데이터베이스 쿼리 리라이트입니다. 이 경우, 25% 미만의 비율로 기능 플래그를 출시하면 롤아웃을 진행할지 여부에 대한 피드백이 느리게 올 수 있습니다. 또한, 크론 작업이 실패할 경우 재시도됩니다. 따라서 문제가 발생하더라도 그 결과는 크지 않을 것입니다. 이 경우 25% 또는 50%의 비율로 출시하는 것이 수용 가능한 선택이 될 것입니다.

하지만 반드시 기능 플래그 체크 결과를 작업자의 로그에 기록해야 합니다. 여기에서 로깅 모범 사례에 대한 지침을 확인하십시오.

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

새로 도입된 기능이나 변경 사항은 Sidekiq 작업에서 실행되는 것보다 고객과의 연관성이 더 클 수 있습니다. 하지만 빈번하게 실행되지 않을 수도 있습니다. 이 경우, 진행 여부를 결정하기 위해 충분한 결과를 수집하기에 충분한 높은 비율을 선택해야 합니다. 이 경우 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 run feature set gitaly_lfs_pointers_pipeline true

- 프로덕션 검사 실패!
- 활성 사고

  2021-06-29 카나리 배포가 QA 테스트 실패

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

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

롤아웃 시간 비율

기능을 25%의 시간 동안 활성화하려면, Slack에서 다음을 실행하세요:

/chatops run feature set new_navigation_bar 25 --random

참고: 시간 비율 기능 플래그는 액터 비율을 선호하여 더 이상 사용되지 않습니다. 시간 비율 기능 플래그 사용의 결과를 이해하고 있다면 --ignore-random-deprecation-check를 사용하여 강제로 활성화할 수 있습니다.

이 명령은 다음 공식을 기반으로 기능 플래그를 true로 설정합니다:

feature_flag_state = rand < (25 / 100.0)

이렇게 하면 GitLab.com에서 new_navigation_bar라는 기능 이름을 가진 기능이 활성화됩니다. 이 명령은 전체 사용자 중 25%를 위한 기능을 활성화하지 않습니다.

대신 기능이 enabled?로 확인될 때 25%의 시간 동안 true를 반환하게 됩니다.

배우 롤아웃 비율

사용자, 프로젝트 또는 그룹과 같은 25%의 배우에게 기능을 활성화하려면, 다음을 Slack에서 실행하십시오:

/chatops run feature set some_feature 25 --actors

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

feature_flag_state = Zlib.crc32("some_feature<Actor>:#{actor.id}") % (100 * 1_000) < 25 * 1_000
# 여기서 <Actor>:는 `User`, `Group`, `Project`이며 actor는 인스턴스입니다.

개발 중에는 기능의 특성에 따라 배우 선택이 이루어져야 합니다.

사용자 중심 기능의 경우:

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 프로젝트에 대해서만 활성화될 수 있습니다. 프로젝트는 --project 플래그를 통해 전달됩니다:

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

특정 사용자에 대해 기능 플래그를 활성화하려면 --user 옵션을 사용할 수 있습니다:

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

먼저 내부 피드백을 수집하려는 경우, 사용자에게 제한된 기능 플래그도 gitlab_team_members 기능 그룹으로 GitLab 팀 구성원에게 활성화할 수 있습니다:

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

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

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

--group은 사용자 네임스페이스와 함께 작동하지 않는 점에 유의하십시오. 일반 네임스페이스(그룹 포함)에 대해 기능 플래그를 활성화하려면 --namespace를 사용하십시오:

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

배우 기반 게이트는 비율 전에 적용됩니다. 예를 들어, group/projectgitlab-org/gitlab으로 하고 주어진 예시 기능을 some_feature로 고려할 때, 다음 2개의 명령을 실행하면:

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

그런 다음 some_feature는 25%의 배우에 대해 활성화되며, 항상 gitlab-org/gitlab과 상호 작용할 때 활성화됩니다. 이는 기능 플래그 개발이 그룹 배우를 사용할 때 좋은 아이디어입니다.

Feature.enabled?(:some_feature, group)

여러 배우는 쉼표로 구분된 형식으로 함께 전달될 수 있습니다:

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

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

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

마지막으로, 가능한 많은 경우에 기능이 안정적이라고 간주되도록 확인하기 위해, 다음을 실행하여 기능 플래그를 전역적으로 활성화해야 합니다:

/chatops run feature set some_feature true

이것은 기능 플래그 상태를 항상 활성화됨으로 변경하며, 위 프로세스의 기존 게이트(예: --group=gitlab-org)를 무시합니다.

배우 기반 기능 게이트가 존재하는 경우, YAML 정의의 default_enabled 속성을 false에서 true로 변경해도 효과가 없습니다. 기능 게이트를 먼저 삭제해야 합니다.

예를 들어, 기능 플래그는 ChatOps를 통해 설정됩니다:

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

YAML 정의의 default_enabled 속성이 true로 전환될 때, 원하는 효과를 얻으려면 기능 게이트를 삭제해야 합니다:

/chatops run feature delete some_feature
배우의 비율 대 시간 롤아웃 비율

사용자에게 기능을 항상 켜거나 끌 수 있도록 하려면 배우의 비율 롤아웃을 사용하세요. 이 경우 시간 롤아웃 비율을 사용하는 것은 피하세요.

시간 롤아웃 비율은 Feature.enabled?가 코드에서 여러 번 사용될 때 일관성 없는 동작을 도입할 수 있습니다. 이는 Feature.enabled?가 호출될 때마다 기능 플래그 값이 무작위로 변경되기 때문입니다.

기능 플래그 비활성화

전역적으로 활성화된 기능 플래그를 비활성화하려면 다음을 실행할 수 있습니다:

/chatops run feature set some_feature false

특정 프로젝트에 대해 활성화된 기능 플래그를 비활성화하려면 다음을 실행할 수 있습니다:

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

특정 프로젝트/그룹/사용자에 대해 선택적으로 기능 플래그를 비활성화할 수 없으며, 기능 플래그를 구현하는 특정 방법을 적용해야 합니다.

기능 플래그가 ChatOps를 통해 비활성화되면, 이는 YAML의 default_enabled 값을 우선합니다. 즉, 온프레미스 설치에는 기능이 활성화되어 있지만 GitLab.com에는 활성화되어 있지 않을 수 있습니다.

배우에 의해 선택적으로 비활성화

기본적으로 배우에 의해 기능 플래그를 선택적으로 비활성화할 수 없습니다.

# 기대하는 대로 작동하지 않습니다.
/chatops run feature set some_feature true
/chatops run feature set --project=gitlab-org/gitlab some_feature false

그러나 두 개의 기능 플래그를 추가하면, 조건 문을 작성하여 동등한 선택적 비활성화가 가능하도록 할 수 있습니다.

Feature.enabled?(:a_feature, project) && Feature.disabled?(:a_feature_override, project)
# 이는 gitlab-org/gitlab를 제외한 전역적으로 기능 플래그를 활성화합니다.
(chatops run feature set a_feature true
/chatops run feature set --project=gitlab-org/gitlab a_feature_override true

비율 기반 배우 선택

여러 기능 플래그에 대해 배우의 비율 롤아웃을 사용할 때, 각 기능 플래그에 대해 배우가 별도로 선택됩니다.

예를 들어, 다음 기능 플래그는 특정 비율의 배우에 대해 활성화됩니다:

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

프로젝트 A가 :feature-set-1이 활성화된 경우, 프로젝트 A가 :feature-set-2도 활성화되었다는 보장은 없습니다.

자세한 내용은 Flipper에서 비율이 작동하는 방식을 참조하세요.

기능 플래그 활성화 후 메트릭 확인

기능 플래그를 활성화한 후, 각 단계 간에 관련 그래프를 모니터링해야 합니다:

  1. dashboards.gitlab.net으로 이동합니다.
  2. feature-flag를 활성화합니다.
  3. 변경에 의해 영향을 받을 수 있는 서비스의 Latency: Apdex를 확인합니다 (예: sidekiq service, api service 또는 web service). 그런 다음 Service Overview Dashboards를 선택하고 변경과 관련이 있을 수 있는 대시보드를 선택하여 더 심층적으로 확인합니다.

이 그림에서는 09:46에 기능 플래그가 활성화된 후 Apdex 점수가 하락하기 시작했음을 볼 수 있습니다. 기능 플래그는 10:31에 비활성화되었고, 서비스는 원래 값으로 되돌아갔습니다:

기능 플래그 메트릭스

특정 기능은 비즈니스 운영에 위험하고 중요한 기능으로, 여러 날에 걸쳐 광범위한 모니터링이 필요합니다. 반면에 다른 기능은 롤아웃을 계속하기 전에 24시간 모니터링 기간만 필요합니다.

롤아웃을 시작하기 전에 필요한 모니터링 범위를 결정하는 것이 좋습니다.

기능 플래그 변경 로깅

ChatOps 수준

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

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

그 후 이 이슈는 GitLab 내부 Grafana 대시보드에 주석 마커로 게시되어 변경 사항을 더욱 잘 볼 수 있게 합니다.

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

인스턴스 수준

모든 GitLab 인스턴스에 영향을 미치는 기능 플래그 변경은 features_json.log에 자동으로 기록됩니다.

변경 이력을 Kibana에서 검색할 수 있습니다.

GitLab.com에 대한 기능 플래그 변경 이력도 Kibana에서 접근할 수 있습니다.

정리

기능 플래그는 더 이상 필요하지 않게 되면 즉시 제거해야 합니다. 코드베이스에 추가된 각 기능 플래그는 애플리케이션의 복잡성을 증가시키고 모든 가능한 조합을 포괄하는 우리의 테스트 스위트에 대한 신뢰도를 감소시킵니다.

게다가, 일부 환경에서 덮어쓴 기능 플래그는 정의되지 않거나 테스트되지 않은 시스템 동작을 초래할 수 있습니다.

development 유형의 기능 플래그는 지속적인 변경을 롤아웃하는 것이 목적이므로 짧은 생명 주기를 가져야 합니다. 2개의 마일스톤을 초과한 development 기능 플래그는 엔지니어링 관리자에게 보고됩니다.

보고서 도구는 매월 실행됩니다. 예를 들어, 2021년 12월 보고서를 참조하세요.

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

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

기능 플래그를 제거하기 위해 하나의 병합 요청을 열어 변경 사항을 적용합니다. MR에서는:

  1. 제거를 알리기 위해 ~"feature flag" 레이블을 추가합니다.
  2. 병합 요청이 현재 버전으로 백포팅되어야 하는 경우 패치 릴리즈 실행 책 프로세스를 따릅니다. 더 자세한 내용은 기능 플래그 프로세스를 참조하세요.
  3. 코드베이스에서 기능 플래그와 관련된 모든 참조를 제거합니다. 테스트도 포함됩니다.
  4. 저장소에서 기능에 대한 YAML 정의를 제거합니다.

위의 MR이 병합된 후에는:

  1. /chatops run feature delete some_feature를 사용하여 모든 환경에서 기능 플래그를 정리합니다.
  2. 코드베이스에서 기능 플래그가 제거된 후 기능 플래그에 대한 롤아웃 이슈를 닫습니다.

ChatOps 정리

기능 게이트가 코드베이스에서 제거되면, 플래그가 배포된 데이터베이스에는 기능 기록이 여전히 존재합니다.

기록은 MR이 모든 환경에 배포된 후 삭제할 수 있습니다:

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