Vault UI 503 — 서비스 등록 endpoints 비어 있음

보안3분조회 –

애플리케이션이 쓰는 DB 비밀번호나 API 키를 매니페스트에 박아 두지 않으려고 Vault 에 모아 두고, 파드가 뜰 때 받아 가게 했습니다. 여기가 멈추면 시크릿을 받아야 하는 파드가 전부 못 뜨니 한 대로 둘 수는 없어서, Helm 차트로 파드 셋을 띄우고 Raft 로 상태를 복제하는 HA 구성으로 올렸습니다.

Raft 는 셋 중 하나를 Active(리더)로 뽑고 나머지는 Standby 로 둡니다. 쓰기는 Active 에서만 처리되고, UI 처럼 Active 에 바로 붙는 게 확실한 편이 나은 자리도 있습니다. 그래서 차트가 Active 전용 Service 를 따로 만들어 줍니다.

시크릿 엔진을 새로 붙이거나 정책을 손보는 건 웹 UI 에서 하는 편이라, 설치가 끝나고 제일 먼저 여는 것도 UI 입니다. 그런데 열었더니 503 이 떨어졌고, 정작 파드는 전부 정상이었습니다.

vault-0   1/1   Running   (Standby)
vault-1   1/1   Running   (Standby)
vault-2   1/1   Running   (Active - Leader)

vault status 도 정상(Sealed: false)이고 Ingress 와 Service 도 다 있었습니다.

Endpoints가 비어 있음

Ingress 부터 따라갔습니다.

Host: vault.example.com
    → Backend: vault-active:8200
        → Endpoints: <none>   ← 여기

vault-active Service 가 어떤 파드도 못 물고 있었고, Endpoints 가 <none> 이면 트래픽을 보낼 곳이 없으니 503 이 나옵니다.

vault-active 서비스의 라벨 기반 Active 파드 탐색

Vault Helm 차트는 여러 Service 를 만들고, 그중 vault-active 는 셀렉터가 vault-active: "true" 라서 이 라벨이 붙은 파드로만 트래픽을 보냅니다.

UI 도 Active 에 붙어야 정상 동작하니, “지금 누가 Active 냐” 를 vault-active 라벨로 표시하고 Service 가 그 라벨로 리더를 찾아가는 구조입니다.

문제는 파드에 그 라벨이 하나도 안 붙어 있었다는 겁니다. 리더는 있지만(vault-2 가 Active) 아무도 vault-active: "true" 라벨이 안 붙어 있으니 Service 셀렉터가 매칭에 실패하고 Endpoints 가 빕니다.

라벨을 붙이는 건 service_registration

이 라벨은 사람이 붙이는 게 아니라 Vault 가 자동으로 붙이고, 그 동작을 켜는 설정이 service_registration "kubernetes" {} 입니다.

storage "raft" {
  path = "/vault/data"
}

service_registration "kubernetes" {}   # 이게 빠져 있었다

이 설정이 있으면 Vault 파드가 Raft 리더 선출로 Active/Standby 가 정해질 때마다 Kubernetes API 를 호출해 자기 파드 라벨을 갱신합니다 — Active 는 vault-active: "true", Standby 는 false 입니다.

이게 빠져 있으면 Vault 자체는 멀쩡히 돌아가서 리더 선출도 되고 리더도 뽑힙니다. 다만 그 사실이 파드 라벨에 안 적히니, 라벨로 리더를 찾는 vault-active Service 만 대상 파드를 찾지 못합니다. 파드가 다 Running 인데도 503 이 나는 이유입니다.

Helm values 에서 config 에 넣습니다.

server:
  ha:
    enabled: true
    raft:
      enabled: true
      config: |
        ui = true
        storage "raft" { path = "/vault/data" }
        service_registration "kubernetes" {}

넣고 파드를 다시 띄우면 Active 파드에 vault-active: "true" 라벨이 붙고, Endpoints 가 그 파드로 채워집니다.

같은 증상을 구분하는 신호

파드는 정상인데도 503 이면 Service 의 Endpoints 부터 봅니다.

kubectl get endpoints vault-active -n vault

<none> 이면 파드가 죽어서가 아니라 Service 가 파드를 못 찾고 있는 것이라, 셀렉터와 파드 라벨을 맞춰 보면 됩니다. 파드가 죽은 것과 Service 가 못 찾는 것은 밖에서 보면 똑같이 503 이지만 확인할 자리가 다릅니다.

참고

  1. 불러오는 중