Consul 배포 — 구성 파일·5 서버 클러스터

2026-05-03확률과 통계 마스터 노트

HashiCorp Consul 마스터 노트 시리즈 2편. 단일 데이터센터 배포 — HCL 구성 파일 핵심 파라미터, 5 서버 부트스트랩 흐름, retry_join과 클라우드 자동 조인, systemd 서비스 통합, UI 활성화, 헬스 체크 권장 설정까지 — Objective 2의 실제 운영 흐름을 한 흐름으로.

이 글은 HashiCorp Consul 마스터 노트 시리즈의 두 번째 편입니다. 1편(아키텍처)에서 모델을 잡았다면, 이번엔 단일 데이터센터를 실제로 배포 — Objective 2.

5 서버 클러스터 부트스트랩, 클라이언트 합류, systemd 등록, UI 활성화까지 운영 환경 표준 흐름.

처음 배포가 어렵게 느껴지는 이유

이유는 두 가지예요.

첫째, HCL 구성 파라미터가 많습니다. bootstrap_expect, retry_join, client_addr, bind_addr, advertise_addr — 비슷비슷한 주소 관련 파라미터가 한꺼번에 들어와 어느 자리에 어느 걸 써야 하는지 안 보여요.

둘째, 첫 클러스터 부트스트랩의 순서가 미묘합니다. 5 서버 동시 시작? 1대 먼저? bootstrapbootstrap_expect의 차이?

해결법은 한 가지예요. 운영 표준 = bootstrap_expect = 5 + retry_join 동일 설정으로 5대 동시 시작. 한 줄만 외우면 충분.

설치

바이너리 설치

# HashiCorp 공식 저장소
sudo apt update && sudo apt install gpg
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install consul

# 버전 확인
consul --version

사용자·디렉토리

# 전용 사용자
sudo useradd --system --home /etc/consul.d --shell /bin/false consul

# 디렉토리
sudo mkdir -p /opt/consul
sudo chown -R consul:consul /opt/consul

sudo mkdir -p /etc/consul.d
sudo chown -R consul:consul /etc/consul.d
sudo chmod 640 /etc/consul.d/*

HCL 구성 파일

서버 구성 (consul.hcl)

# /etc/consul.d/consul.hcl

datacenter        = "dc1"
data_dir          = "/opt/consul"
server            = true
bootstrap_expect  = 5

# 네트워크 바인딩
bind_addr         = "10.0.1.10"     # Gossip·RPC 바인드
client_addr       = "0.0.0.0"        # HTTP/DNS 수신 (LB·UI 위해)
advertise_addr    = "10.0.1.10"     # 다른 노드에 알릴 주소

# 클러스터 자동 조인
retry_join        = ["10.0.1.10", "10.0.1.11", "10.0.1.12", "10.0.1.13", "10.0.1.14"]

# UI 활성화
ui_config {
  enabled = true
}

# 로그
log_level = "INFO"

클라이언트 구성

# /etc/consul.d/consul.hcl (클라이언트)

datacenter        = "dc1"
data_dir          = "/opt/consul"
server            = false           # 클라이언트는 false
bind_addr         = "10.0.1.20"
client_addr       = "127.0.0.1"     # 로컬만
retry_join        = ["10.0.1.10", "10.0.1.11", "10.0.1.12"]
log_level         = "INFO"

여기서 시험 함정이 하나 있어요. bind_addr vs client_addr vs advertise_addr 차이:

  • bind_addr — Gossip/RPC 듣는 주소 (보통 사설 IP)
  • client_addr — HTTP/DNS API 듣는 주소 (UI 노출이면 0.0.0.0, 로컬만이면 127.0.0.1)
  • advertise_addr — 다른 노드에 알릴 주소 (NAT 환경에서 다를 수 있음)

bootstrap_expect — 클러스터 형성

bootstrap_expect = 5

N대 서버가 모이면 자동으로 부트스트랩 시작. 5대 모두 동일 값.

여기서 정말 중요한 시험 함정 — bootstrap_expect = N모든 서버 노드에 동일하게 설정해야 합니다. 5대 중 한 대가 3으로 설정 = 클러스터 형성 충돌.

bootstrap (구식, 권장 X)

bootstrap = true   # 비권장

한 대만 강제 부트스트랩. 단순 테스트용. 운영은 항상 bootstrap_expect.

retry_join — 자동 조인

retry_join = ["10.0.1.10", "10.0.1.11", "10.0.1.12"]

시작 시 지정한 IP에 자동 합류 시도. 실패해도 계속 재시도.

클라우드 자동 조인

retry_join = ["provider=aws tag_key=consul tag_value=server region=us-east-1"]

AWS·Azure·GCP 태그 기반 자동 디스커버리. IP 하드코딩 없이 클라우드 환경에서 동적 조인.

systemd 서비스

서비스 유닛 파일

# /etc/systemd/system/consul.service

[Unit]
Description=Consul
Documentation=https://www.consul.io/
Requires=network-online.target
After=network-online.target
ConditionFileNotEmpty=/etc/consul.d/consul.hcl

[Service]
Type=notify
User=consul
Group=consul
ExecStart=/usr/bin/consul agent -config-dir=/etc/consul.d/
ExecReload=/bin/kill --signal HUP $MAINPID
KillMode=process
KillSignal=SIGTERM
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

서비스 관리

sudo systemctl daemon-reload
sudo systemctl enable consul
sudo systemctl start consul
sudo systemctl status consul

# 로그
sudo journalctl -u consul -f

클러스터 부트스트랩 시나리오

5 서버 동시 시작

1. 5대 모두 동일 consul.hcl (bootstrap_expect=5, retry_join=5IPs)
2. 5대 동시 시작
3. retry_join으로 서로 발견
4. 5대 모두 도달 → bootstrap_expect=5 충족 → Raft 부트스트랩
5. Leader 선출 → 클러스터 ready

시작 검증

# 멤버 목록 (LAN Gossip)
consul members
# Node     Address          Status   Type    Build  ...
# server1  10.0.1.10:8301   alive    server  ...
# server2  10.0.1.11:8301   alive    server  ...
# ...

# Raft 피어
consul operator raft list-peers
# Node     ID     Address          State     Voter
# server1  ...    10.0.1.10:8300   leader    true
# server2  ...    10.0.1.11:8300   follower  true

# 클러스터 정보
consul info

여기서 정말 중요한 시험 함정 — consul members는 LAN Gossip 멤버, consul operator raft list-peers는 Raft 참여자(서버). 다른 명령. 시험에서 자주.

클라이언트 합류

# 클라이언트 노드에서
sudo systemctl start consul

# 검증
consul members
# (서버 + 새 클라이언트 모두 표시)

UI 활성화

ui_config {
  enabled = true
}

client_addr = "0.0.0.0"   # UI 외부 접근 위해
http://<server-ip>:8500/ui

여기서 시험 함정이 하나 있어요. client_addr = 0.0.0.0 안 하면 UI 외부 접근 X. 기본값 127.0.0.1은 localhost만.

헬스 체크 권장 설정

performance {
  raft_multiplier = 1   # 1=가장 공격적 (저지연)
                        # 5=느림 (개발 환경)
}

raft_multiplier:

  • 1 = 빠른 리더 선거, 저지연 운영 환경
  • 5 = 부하 적은 환경, 개발

로그 레벨

log_level = "INFO"   # ERROR, WARN, INFO, DEBUG, TRACE
log_file  = "/var/log/consul/consul.log"
log_rotate_duration = "24h"
log_rotate_max_files = 7

다중 데이터센터 (Federation)

# DC1 서버
datacenter = "dc1"
retry_join_wan = ["10.0.2.10"]   # DC2 서버

# DC2 서버
datacenter = "dc2"
retry_join_wan = ["10.0.1.10"]   # DC1 서버

WAN Gossip으로 서로 발견. 한 DC 클라이언트가 service.dc2.consul DNS 형식으로 다른 DC 서비스 조회.

흔한 실수

bootstrap_expect 불일치

5대 중 한 대만 다른 값 → 클러스터 형성 실패. 모두 동일하게.

retry_join에 자기 IP 포함

OK입니다 — 자기 자신은 무시되고 다른 노드만 시도. 모든 노드 동일 IP 리스트로 두면 단순.

Single Server (bootstrap_expect=1) 운영

테스트만. 서버 1대 = 장애 허용 0. 운영은 최소 3대.

클라이언트도 bootstrap_expect 박음

X — bootstrap_expect는 서버만. 클라이언트엔 박지 마세요.

시험 직전 한 번 더 — 자주 헷갈리는 함정 모음

여기까지가 2편의 핵심입니다. 시험 직전 또는 실무에서 헷갈릴 때 다시 펼쳐 볼 수 있게 압축 노트로 마무리할게요.

  • HCL 구성 파일 = /etc/consul.d/consul.hcl
  • 핵심 파라미터 — datacenter / data_dir / server / bootstrap_expect / retry_join
  • bind_addr (Gossip·RPC 듣기) / client_addr (HTTP·DNS 듣기) / advertise_addr (다른 노드에 알림)
  • client_addr = 0.0.0.0 = UI 외부 접근
  • client_addr = 127.0.0.1 = 로컬만
  • bootstrap_expect = N — 모든 서버 동일하게
  • 한 대라도 다르면 클러스터 형성 실패
  • bootstrap = true = 단일 강제 (테스트만)
  • retry_join = 자동 조인 IP 리스트
  • 클라우드 자동 조인 = provider=aws tag_key=...
  • systemd 서비스 — Type=notify, User=consul
  • 5 서버 동시 시작 = 표준 부트스트랩
  • consul members = LAN Gossip 멤버
  • consul operator raft list-peers = Raft 참여자
  • 두 명령 결과 차이 시험 단골
  • UI 활성 = ui_config { enabled = true } + client_addr = 0.0.0.0
  • raft_multiplier — 1 (빠름) / 5 (느림, 개발)
  • 로그 — INFO / DEBUG / TRACE
  • WAN Federation = retry_join_wan
  • 다른 DC 서비스 조회 = service.dc2.consul
  • bootstrap_expect는 서버만 (클라이언트엔 X)

시리즈 다른 편

공식 문서: Consul Configuration Reference에서 모든 파라미터 확인.

다음 글(3편)에서는 서비스 등록 — HCL/JSON 정의 방식, DNS 인터페이스, 헬스 체크 7종(Script·HTTP·TCP·gRPC·Docker·TTL·Alias), 태그·메타데이터까지 풀어 갑니다.

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

답글 남기기

error: Content is protected !!