웹훅
웹훅 (Webhooks)
canary 분석은 웹훅으로 확장할 수 있습니다. Flagger는 각 웹훅 URL을 호출하고 응답 상태 코드(HTTP 2xx)로 canary가 실패했는지 여부를 판단합니다. 다양한 훅 유형과 부하 테스트, 통합 테스트, 수동 게이팅 방법을 이 문서에서 알려드릴게요.
출처: 문서
본문
canary 분석은 웹훅으로 확장할 수 있습니다. Flagger는 각 웹훅 URL을 호출하고 응답 상태 코드(HTTP 2xx)로 canary가 실패하는지 여부를 결정합니다.
여러 유형의 훅이 있습니다:
- confirm-rollout 훅은 canary 배포를 스케일 업하기 전에 실행되며 수동 승인에 사용할 수 있습니다. 훅이 성공적인 HTTP 상태 코드를 반환할 때까지 롤아웃은 일시 중지됩니다.
- pre-rollout 훅은 canary로 트래픽을 라우팅하기 전에 실행됩니다. pre-rollout 훅이 실패하면 canary 진행이 일시 중지되고, 실패 횟수가 임계값에 도달하면 canary가 롤백됩니다.
- rollout 훅은 분석 중 매 반복마다 메트릭 검사 전에 실행됩니다. rollout 훅 호출이 실패하면 canary 진행이 일시 중지되고 결국 롤백됩니다.
- confirm-traffic-increase 훅은 canary의 가중치가 증가되기 바로 직전에 실행됩니다. 이 훅이 HTTP 200을 반환할 때까지 canary 진행이 일시 중지됩니다.
- confirm-promotion 훅은 승격 단계 전에 실행됩니다. 훅이 HTTP 200을 반환할 때까지 canary 승격이 일시 중지됩니다. 승격이 일시 중지되는 동안 Flagger는 메트릭 검사와 rollout 훅을 계속 실행합니다.
- post-rollout 훅은 canary가 승격되거나 롤백된 후에 실행됩니다. post-rollout 훅이 실패하면 오류가 기록됩니다.
- rollback 훅은 canary 배포가 Progressing 또는 Waiting 상태일 때 실행됩니다. 이는 분석 중 또는 확인 대기 중에 롤백할 수 있는 기능을 제공합니다. rollback 훅이 성공적인 HTTP 상태 코드를 반환하면 Flagger는 분석을 중지하고 canary 릴리스를 실패로 표시합니다.
- event 훅은 Flagger가 Kubernetes 이벤트를 방출할 때마다 실행됩니다. 구성되면 canary 배포 중 Flagger가 취하는 모든 동작이 HTTP POST 요청으로 JSON으로 전송됩니다.
스펙:
analysis:
webhooks:
- name: "start gate"
type: confirm-rollout
url: http://flagger-loadtester.test/gate/approve
retries: 5
- name: "helm test"
type: pre-rollout
url: http://flagger-helmtester.flagger/
timeout: 3m
metadata:
type: "helmv3"
cmd: "test podinfo -n test"
- name: "load test"
type: rollout
url: http://flagger-loadtester.test/
timeout: 15s
metadata:
cmd: "hey -z 1m -q 5 -c 2 http://podinfo-canary.test:9898/"
- name: "traffic increase gate"
type: confirm-traffic-increase
url: http://flagger-loadtester.test/gate/approve
- name: "promotion gate"
type: confirm-promotion
url: http://flagger-loadtester.test/gate/approve
- name: "notify"
type: post-rollout
url: http://telegram.bot:8080/
timeout: 5s
metadata:
some: "message"
- name: "rollback gate"
type: rollback
url: http://flagger-loadtester.test/rollback/check
- name: "send to Slack"
type: event
url: http://event-recevier.notifications/slack
retries: 3
metadata:
environment: "test"
cluster: "flagger-test"
참고 모든 rollout 웹훅 타임아웃의 합은 분석 interval보다 낮아야 합니다.
웹훅 페이로드 (HTTP POST):
{
"name": "podinfo",
"namespace": "test",
"phase": "Progressing",
"checksum": "85d557f47b",
"metadata": {
"test": "all",
"token": "16688eb5e9f289f1991c"
}
}
checksum 필드는 Canary의 TrackedConfigs와 LastAppliedSpec에서 해시되며, 배포된 리소스의 특정 구성에 대한 Canary를 식별하는 데 사용할 수 있습니다.
응답 상태 코드:
- 200-202 - 트래픽 가중치를 증가시켜 canary 진행
- timeout 또는 non-2xx - 진행 중지 및 실패 검사 증가
non-2xx 응답 시 Flagger는 응답 본문(있는 경우)을 실패 검사 로그와 Kubernetes 이벤트에 포함합니다.
이벤트 페이로드 (HTTP POST):
{
"name": "string (canary name)",
"namespace": "string (canary namespace)",
"phase": "string (canary phase)",
"checksum": "string (canary checksum"),
"metadata": {
"eventMessage": "string (canary event message)",
"eventType": "string (canary event type)",
"timestamp": "string (unix timestamp ms)"
}
}
이벤트 수신자는 받은 phase(Initialized, Waiting, Progressing, Promoting, Finalising, Succeeded 또는 Failed 가능 값)를 기반으로 알림을 만들 수 있습니다.
옵션:
- retries:
retries필드에 양의 정수를 지정해 웹훅 요청을 재시도할 수 있습니다. 이는 일시적인 네트워크 문제로 웹훅이 실패하는 경우 신뢰성을 보장하는 데 도움이 됩니다. - disable TLS: 웹훅 스펙에서
disableTLS를true로 설정해 TLS 검증을 우회합니다. 대상 서비스가 자체 서명 인증서를 사용하거나 테스트 목적으로 안전하지 않은 서비스에 연결해야 하는 경우 유용합니다.
부하 테스트 (Load Testing)
지속적으로 트래픽을 받지 않는 워크로드의 경우 Flagger를 웹훅으로 구성할 수 있으며, 호출되면 대상 워크로드에 대한 부하 테스트가 시작됩니다. 카나리아 분석 중 대상 워크로드가 어떤 트래픽도 받지 않으면 Flagger 메트릭 검사는 "no values found for metric request-success-rate"로 실패합니다.
Flagger에는 웹훅으로 구성될 때 분석 중 트래픽을 생성하는 rakyll/hey 기반의 부하 테스트 서비스가 함께 제공됩니다.

먼저 사이드카 주입이 활성화된 네임스페이스에 부하 테스트 러너를 배포해야 합니다:
kubectl apply -k https://github.com/fluxcd/flagger//kustomize/tester?ref=main
또는 Helm으로:
helm repo add flagger https://flagger.app
helm upgrade -i flagger-loadtester flagger/loadtester \
--namespace=test \
--set cmd.timeout=1h \
--set cmd.namespaceRegexp=''
배포되면 부하 테스터 API는 http://flagger-loadtester.test/에서 사용할 수 있습니다.
이제 canary 분석 스펙에 웹훅을 추가할 수 있습니다:
webhooks:
- name: load-test-get
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 1m -q 10 -c 2 http://podinfo-canary.test:9898/"
- name: load-test-post
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 1m -q 10 -c 2 -m POST -d '{test: 2}' http://podinfo-canary.test:9898/echo"
카나리아 분석이 시작되면 Flagger는 웹훅을 호출하고, 부하 테스터는 이미 실행 중이지 않다면 백그라운드에서 hey 명령을 실행합니다. 이렇게 하면 분석 중 podinfo-canary.test 서비스가 꾸준한 GET과 POST 요청 스트림을 받게 됩니다.
워크로드가 메시 외부에 노출되어 있다면 hey를 공개 URL로 지정하고 HTTP2를 사용할 수 있습니다.
webhooks:
- name: load-test-get
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 1m -q 10 -c 2 -h2 https://podinfo.example.com/"
gRPC 서비스에는 Hey와 유사하지만 gRPC용인 bojand/ghz를 사용할 수 있습니다:
webhooks:
- name: grpc-load-test
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "ghz -z 1m -q 10 -c 2 --insecure podinfo.test:9898"
ghz는 리플렉션을 사용해 호출할 gRPC 메서드를 식별합니다. gRPC 서비스에 리플렉션을 활성화하고 싶지 않다면 grpc-proto 라이브러리의 표준화된 헬스 체크를 구현할 수 있습니다. 리플렉션 없이 이 헬스 체크 스키마를 사용하려면 다음과 같이 ghz에 파라미터를 전달합니다:
webhooks:
- name: grpc-load-test-no-reflection
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "ghz --insecure --proto=/tmp/ghz/health.proto --call=grpc.health.v1.Health/Check podinfo.test:9898"
부하 테스터는 바이너리가 컨테이너 이미지에 있는 한 임의의 명령을 실행할 수 있습니다. 예를 들어 hey를 다른 CLI로 바꾸려면 자신만의 Docker 이미지를 만들 수 있습니다:
FROM weaveworks/flagger-loadtester:<VER>
RUN curl -Lo /usr/local/bin/my-cli https://github.com/user/repo/releases/download/ver/my-cli \
&& chmod +x /usr/local/bin/my-cli
부하 테스트 위임 (Load Testing Delegation)
부하 테스터는 테스트 작업을 외부 도구에 전달할 수도 있으며, 현재는 nGrinder가 지원됩니다.
이 기능을 사용하려면 canary 분석 스펙에 'ngrinder' 유형의 부하 테스트 작업을 추가합니다:
webhooks:
- name: load-test-post
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
# type of this load test task, cmd or ngrinder
type: ngrinder
# base url of your nGrinder controller server
server: http://ngrinder-server:port
# id of the test to clone from, the test must have been defined.
clone: 100
# user name and base64 encoded password to authenticate against the nGrinder server
username: admin
passwd: YWRtaW4=
# the interval between between nGrinder test status polling, default to 1s
pollInterval: 5s
카나리아 분석이 시작되면 부하 테스터는 nGrinder 서버에 clone_and_start 요청을 시작하고 새 성능 테스트를 시작합니다. 부하 테스터는 주기적으로 nGrinder 서버를 폴링해 테스트 상태를 확인하고, 이후 분석 루프에서 중복 요청이 전송되는 것을 방지합니다.
K6 부하 테스터 (K6 Load Tester)
부하 테스트를 타사 웹훅에 위임할 수도 있습니다. 그 예가 k6 webhook입니다. 이 웹훅은 매우 다양한 기능을 가진 부하 테스터인 k6를 사용해 canary에 부하 또는 스모크 테스트를 실행합니다. 사용 가능한 모든 기능은 소스 저장소를 참고하세요.
이 웹훅을 pre-rollout 단계로 통합해 서비스에 어떤 트래픽도 보내지기 전에 부하 테스트하는 예시입니다:
webhooks:
- name: k6-load-test
timeout: 5m
type: pre-rollout
url: http://k6-loadtester.flagger/launch-test
metadata:
script: |
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
vus: 2,
duration: '30s',
thresholds: {
http_req_duration: ['p(95)<50']
},
ext: {
loadimpact: {
name: '<cluster>/<your_service>',
projectID: <project id>,
},
},
};
export default function () {
http.get('http://<your_service>-canary.<namespace>:80/');
sleep(0.10);
}
통합 테스트 (Integration Testing)
Flagger에는 웹훅으로 구성될 때 Helm 테스트, Bats 테스트 또는 Concord 테스트를 실행할 수 있는 테스트 서비스가 함께 제공됩니다.
tiller 서비스 계정을 사용해 kube-system 네임스페이스에 Helm 테스트 러너를 배포합니다:
helm repo add flagger https://flagger.app
helm upgrade -i flagger-helmtester flagger/loadtester \
--namespace=kube-system \
--set serviceAccountName=tiller
배포되면 Helm 테스터 API는 http://flagger-helmtester.kube-system/에서 사용할 수 있습니다.
이제 canary 분석 스펙에 pre-rollout 웹훅을 추가할 수 있습니다:
analysis:
webhooks:
- name: "smoke test"
type: pre-rollout
url: http://flagger-helmtester.kube-system/
timeout: 3m
metadata:
type: "helm"
cmd: "test {{ .Release.Name }} --cleanup"
카나리아 분석이 시작되면 Flagger는 트래픽을 canary로 라우팅하기 전에 pre-rollout 웹훅을 호출합니다. helm 테스트가 실패하면 Flagger는 분석 임계값에 도달해 canary가 롤백될 때까지 재시도합니다.
Helm v3를 사용한다면 전용 서비스 계정을 만들고 테스트 명령에 릴리스 네임스페이스를 추가해야 합니다:
analysis:
webhooks:
- name: "smoke test"
type: pre-rollout
url: http://flagger-helmtester.kube-system/
timeout: 3m
metadata:
type: "helmv3"
cmd: "test {{ .Release.Name }} --timeout 3m -n {{ .Release.Namespace }}"
테스트가 멈추거나 권한 부족을 암시하는 오류 메시지를 기록한다면 RBAC와 관련된 것일 수 있습니다. 예시 구성은 Troubleshooting 섹션을 확인하세요.
Helm의 대안으로 Bash Automated Testing System을 사용해 테스트를 실행할 수 있습니다.
analysis:
webhooks:
- name: "acceptance tests"
type: pre-rollout
url: http://flagger-batstester.default/
timeout: 5m
metadata:
type: "bash"
cmd: "bats /tests/acceptance.bats"
Bats 테스트가 담긴 ConfigMap을 만들고 테스터 컨테이너 안에 마운트해야 한다는 점에 유의하세요.
테스트 러너가 Concord 프로세스를 시작하도록 구성할 수도 있습니다.
analysis:
webhooks:
- name: "concord integration test"
type: pre-rollout
url: http://flagger-concordtester.default/
timeout: 60s
metadata:
type: "concord"
org: "your-concord-org"
project: "your-concord-project"
repo: "your-concord-repo"
entrypoint: "your-concord-entrypoint"
apiKeyPath: "/tmp/concord-api-key"
endpoint: "https://canary-endpoint/"
pollInterval: "5"
pollTimeout: "60"
org, project, repo, entrypoint는 테스트 프로세스가 Concord에서 실행되는 위치를 나타냅니다. Concord에 인증하려면 apiKeyPath를 flagger-helmtester 컨테이너의 유효한 Concord API 키가 담긴 파일 경로로 설정해야 합니다. 이는 테스터의 Deployment에 Kubernetes 시크릿을 마운트하는 방식으로 할 수 있습니다. pollInterval은 웹훅이 프로세스 완료 여부를 확인하기 위해 Concord를 호출하는 간격(초)을 나타냅니다 (기본값 5s). pollTimeout은 웹훅이 타임아웃되기 전에 Concord를 호출하려 시도하는 시간(초)을 나타냅니다 (기본값 30s).
테스트를 실행하기 위해 Pod/Job을 시작해야 한다면 kubectl로 시작할 수 있습니다.
analysis:
webhooks:
- name: "smoke test"
type: pre-rollout
url: http://flagger-kubectltester.kube-system/
timeout: 3m
metadata:
type: "kubectl"
cmd: "run test --image=alpine --overrides='{ "spec": { "serviceAccount": "default:default" } }'"
kubectl과 helm 명령을 실행하려면 부하 테스터 서비스 계정에 대한 RBAC를 설정해야 한다는 점에 유의하세요.
수동 게이팅 (Manual Gating)
canary 배포의 수동 승인에는 confirm-rollout과 confirm-promotion 웹훅을 사용할 수 있습니다. confirm rollout 훅은 pre-rollout 훅 전에 실행됩니다. 트래픽 가중치 증가를 수동으로 승인하려면 confirm-traffic-increase 웹훅을 사용할 수 있습니다. Flagger는 confirm 웹훅이 HTTP 상태 200을 반환할 때까지 canary 트래픽 전환과 분석을 중지합니다.
canary 배포의 수동 롤백에는 rollback 웹훅을 사용할 수 있습니다. rollback 훅은 분석 및 확인 상태 동안 호출됩니다. rollback 웹훅이 성공적인 HTTP 상태 코드를 반환하면 Flagger는 모든 트래픽을 primary 인스턴스로 전환하고 canary를 실패시킵니다.
Flagger의 테스터로 수동 게이팅:
analysis:
webhooks:
- name: "gate"
type: confirm-rollout
url: http://flagger-loadtester.test/gate/halt
/gate/halt는 HTTP 403을 반환하므로 롤아웃을 차단합니다.
알림이 활성화되어 있다면 canary 롤아웃이 승인을 기다릴 때 Flagger가 Slack 또는 MS Teams에 메시지를 게시합니다.
알림은 다음으로 비활성화할 수 있습니다:
analysis:
webhooks:
- name: "gate"
type: confirm-rollout
url: http://flagger-loadtester.test/gate/halt
muteAlert: true
canary 분석을 시작하려면 URL을 /gate/approve로 바꿉니다:
analysis:
webhooks:
- name: "gate"
type: confirm-rollout
url: http://flagger-loadtester.test/gate/approve
수동 게이팅은 Flagger의 테스터 API로 구동할 수 있습니다. 확인 URL을 /gate/check로 설정합니다:
analysis:
webhooks:
- name: "ask for confirmation"
type: confirm-rollout
url: http://flagger-loadtester.test/gate/check
기본적으로 게이트는 닫혀 있으며, canary 롤아웃을 시작하거나 재개하려면:
kubectl -n test exec -it flagger-loadtester-xxxx-xxxx sh
curl -d '{"name": "podinfo","namespace":"test"}' http://localhost:8080/gate/open
언제든 롤아웃을 일시 중지할 수 있습니다:
curl -d '{"name": "podinfo","namespace":"test"}' http://localhost:8080/gate/close
canary 분석이 일시 중지되면 상태가 waiting으로 변경됩니다:
kubectl get canary/podinfo
NAME STATUS WEIGHT
podinfo Waiting 0
confirm-promotion 훅 유형은 canary 승격을 수동으로 승인하는 데 사용할 수 있습니다. 승격이 일시 중지되는 동안 Flagger는 메트릭 검사와 부하 테스트를 계속 실행합니다.
analysis:
webhooks:
- name: "promotion gate"
type: confirm-promotion
url: http://flagger-loadtester.test/gate/halt
rollback 훅 유형은 canary 승격을 수동으로 롤백하는 데 사용할 수 있습니다. 게이팅과 마찬가지로, 롤백 URL을 /rollback/check로 설정해 Flagger의 테스터 API로 롤백을 구동할 수 있습니다:
analysis:
webhooks:
- name: "rollback"
type: rollback
url: http://flagger-loadtester.test/rollback/check
기본적으로 롤백은 닫혀 있으며, canary 롤아웃을 롤백하려면:
kubectl -n test exec -it flagger-loadtester-xxxx-xxxx sh
curl -d '{"name": "podinfo","namespace":"test"}' http://localhost:8080/rollback/open
롤백을 닫을 수 있습니다:
curl -d '{"name": "podinfo","namespace":"test"}' http://localhost:8080/rollback/close
알림이 활성화되어 있다면 canary가 롤백되었을 때 Flagger가 Slack 또는 MS Teams에 메시지를 게시합니다.
문제 해결 (Troubleshooting)
helm 테스트가 실행 중인지 수동으로 확인 (Manually check if helm test is running)
helm 테스트와 관련된 문제를 깊이 디버깅하려면 flagger-loadtester 파드에서 명령을 실행할 수 있습니다.
kubectl exec -it deploy/flagger-loadtester -- bash
helmv3 test <release> -n <namespace> --debug
canary 배포 중 Helm 테스트가 멈춤 (Helm tests hang during canary deployment)
테스트 실행이 멈추거나 권한 부족이 표시되면 RBAC 설정을 확인하세요.
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: helm-smoke-tester
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list", "update"]
# choose the permission based on helm test type (Pod or Job)
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["create", "list", "delete", "watch"]
- apiGroups: ["batch"]
resources: ["jobs", "jobs/log"]
verbs: ["create", "list", "delete", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: helm-smoke-tester
# Don't forget to update accordingly
namespace: namespace-of-the-tested-release
subjects:
- kind: User
name: system:serviceaccount:linkerd:default
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: helm-smoke-tester
apiGroup: rbac.authorization.k8s.io