listeners vs advertised.listeners — 바인딩 주소와 광고 주소는 다르다
Kafka listeners/advertised.listeners 및 Sticky Partitioner(KIP-480) 공식 문서·기술 블로그 종합 (웹 리서치, 2026) — Confluent 공식 블로그(Kafka Listeners Explained), Apache Kafka KIP-480: Sticky Partitioner Confluent 공식 블로그 Kafka Listeners – Explained
이 모듈을 다 읽으면
- listeners(바인딩 주소)와 advertised.listeners(클라이언트에 알려주는 주소)의 역할 차이를 설명할 수 있다
- 이 둘의 혼동이 왜 Docker/K8s 환경에서 특히 흔한 연결 실패 원인이 되는지 설명할 수 있다
kafka-learn-10에서 다룬 브로커의 요청 처리 파이프라인(acceptor가 소켓을 열고 받는다는 것)을 전제로, '브로커가 실제로 어디서 듣는가'와 '브로커가 클라이언트에게 어디로 연결하라고 알려주는가'가 서로 다른 개념이라는 것을 정리한다.
listeners — 브로커가 실제로 바인딩하는 인터페이스/포트
listeners는 브로커가 트래픽을 받기 위해 실제로 바인딩하는 네트워크 인터페이스와 포트를 지정한다 — kafka-learn-10에서 다룬 acceptor 스레드가 리스닝하는 그 주소다. Docker 컨테이너 안에서 흔히 listeners=PLAINTEXT://0.0.0.0:9092처럼 모든 인터페이스에 바인딩하도록 설정한다.
핵심 포인트
- listeners: 브로커가 실제로 트래픽을 받기 위해 바인딩하는 네트워크 인터페이스·포트(kafka-learn-10의 acceptor가 여는 그 주소)
advertised.listeners — 클라이언트에게 '여기로 연결하라'고 알려주는 주소
advertised.listeners는 초기 부트스트랩 연결 이후 브로커가 클라이언트에게 '실제로 이 주소로 접속하라'고 알려주는 주소다 — 클라이언트는 클러스터 메타데이터를 통해 각 브로커의 주소를 얻는데, 이때 반환되는 주소는 listeners가 아니라 advertised.listeners에서 나온다. 이 주소는 클라이언트가 있는 위치에서 실제로 도달 가능해야 한다는 게 핵심 조건이다. Kafka 0.9.0부터 리스너를 여러 개 동시에 구성할 수 있어(예: 내부용 PLAINTEXT, 외부용 SSL), 컨테이너 내부 통신용 주소와 외부 클라이언트용 주소를 서로 다르게 광고하는 것이 가능해졌다.
핵심 포인트
- advertised.listeners: 클라이언트가 클러스터 메타데이터로 받는, 실제 연결에 쓸 주소 — 클라이언트가 있는 곳에서 도달 가능해야 함
- 0.9.0부터 다중 리스너 지원(예: 컨테이너 내부용/외부 클라이언트용을 서로 다르게 광고) — listener.security.protocol.map으로 각 리스너 이름에 보안 프로토콜을 매핑
왜 Docker/K8s에서 특히 자주 문제가 되는가
Docker 환경에서 잘못 설정된 advertised listener는 연결 실패의 가장 흔한 원인으로 꼽힌다 — 브로커의 listeners 설정과 advertised.listeners 값은 서로 독립적으로 맞춰야 하는데, 컨테이너 내부에서 브로커가 자기 자신을 컨테이너 이름(예: kafka:9092)으로 광고해버리면, 컨테이너 밖(호스트 머신이나 다른 네트워크)의 클라이언트는 그 이름을 못 찾아 연결에 실패한다. 부트스트랩 연결 자체는 성공했더라도, 이후 클라이언트가 메타데이터로 받은 advertised.listeners 주소로 재연결을 시도하다 실패하는 형태로 이 문제가 나타나는 경우가 많다.
핵심 포인트
- Docker 환경에서 잘못된 advertised listener가 연결 실패의 가장 흔한 원인
- 컨테이너 내부 이름으로 광고하면 컨테이너 밖 클라이언트가 그 주소를 못 찾음 — 부트스트랩은 성공해도 메타데이터로 받은 advertised 주소로 재연결 시 실패하는 형태로 나타남