반응형

 

 

배경


 

Kafka Connect를 이용해 MySQL 데이터를 Kafka로 수집하는 작업을 진행하려고 했다. 

 

Kafka Connect에 MySQL JDBC Driver랑 mysql-connect-j 를 플러그인 경로로 추가해주고 볼륨으로 연결해주고 

Source Connector 설정까지 마쳤는데 연결이 되지 않고 계속 오류가 발생했다. 

 

No suitable driver found for jdbc:mysql://...

 

처음에는 플러그인 경로 문제라고 생각했지만, 결론은 전혀 다르다. 

 

 

 

이슈


 

Caused by: java.sql.SQLException: No suitable driver found for jdbc:mysql://local:3306/users

 

JDBC Driver JAR 파일을 plugins 폴더에 직접 넣었고, 폴더 구조도 정상적이었다. 

 

하지만 계속 문제가 발생을 하는게 JDBC드라이버를 못찾는다는 것이었다. 

 

 

원인


 

1. 잘못된 DB호스트 주소 사용 

 

일단 나는 도커로 올라간 환경이라는 것을 생각해야했다. 

Kafka Connect랑 mysql은 컨테이너가 개별적으로 실행중이었다. 

그런데 Connect 설정에서 DB주소를 다음처럼 넣고 있었다. 

jdbc:mysql://localhost:3306/users

 

문제는 Kafka Connect 컨테이너 입장에서 localhost는 자신의 컨테이너 내부라는 것이다. 

즉 localhost:3306은 Kafka Connect 컨테이너 자신의 3306 포트를 의미하게 된다. 

 

그래서 MySQL에 접근이 불가능했던것이다. 

 

 

2.  Kafka Connect 와 MySQL이 같은 Docker 네트워크에 없었음. 

 

그래서 나는 localhost가 아닌 MySQL컨테이너가 올라간 컨테이너 명으로 이름을 바꿔주었다. 

jdbc:mysql://mysql:3306/users

 

그런데 이번 트러블 슈팅을 겪으면서 도커에 대해 조금이나마 더 알게 되었다. 

도커에서 컨테이너 간 통신은 같은 network 안에서 컨테이너명으로 DNS 접근하는 방식이라고 한다. 

 

MySQL하고 Kafka Connect하고 별도로 실행한 컨테이너 라는 것이 문제이다. 

서로 다른 네트워크라서 컨테이너 이름으로 접근이 불가능했다. 

 

UnknownHostException: mysql-container: Name or service not known

 

 

문제


 

그래서 플러그인 문제가 아니라 네트워크 접근 불가라는 문제라는 것을 늦게 알았다. 

 

 

해결 방안


 

1. MySQL을 같은 컨테이너에 넣기

 

MySQL을 Kafka Connect가 작성되어있는 docker-compose 파일에 내부로 이동시키는 방법이 있다. 

kafka, zookeeper, kafka connect와 동일 compose 내부에 MySQL을 추가하여 모두가 같은 네트워크에 동작하도록 구성했다. 

 

이 방법으로 해결이 되긴 하였으나, 문제점이 있는게 카프카는 디비가 필요하지 않다. 커넥터 연결 해줄때 driver만 필요하지 데이터베이스에 직접 연동되는 것이 아니기에 같은 compose로 작성을 해서 올리게 되면 듣도보도 못한 결합이 생긴다고 생각했다. 

 

그리고 또, 유저 서비스에서 테스트를 한다고 했지만 msa 에서는 서비스가 여러 개가 있을거고, 각 서비스마다 디비가 존재를 하는데 다른 서비스에서도 카프카를 이용하려면 동일하게 compose 파일에 같이 작성해서 올려야 한다는게 말이 안된다고 생각했다. 

 

2. docker network 사용 

 

컨테이너마다 다른 네트워크로 올라가 다른 컨테이너들을 모른다고 하면, 같은 네트워크로 묶어주는 것을 생각했다. 

짧게나마 도커를 공부하여 네트워크라는 개념이 있었다라는 것을 생각해낼 수 있었는데 이 생각을 하게 까지 방해하는 요소 들이 있었다. 

 

msa 환경에서 배포를 하게 되면 도커 컴포즈 파일 이용하여 할텐데, 실 서비스 환경에서도 도커 네트워크로 묶어 두진 않을거 같았다. 

그래서 msa로 배포를 해보지 않아 익숙하지 않았던 것이 문제다. 

 

해결은 이 방법으로 진행했다. 

 

 

결과


 

Kafka Connect와 MySQL이 동일 네트워크에서 통신할 수 있게 되면서 UnknownHostException이 사라졌다. 

 

MySQL JDBC드라이버가 정상 동작하며 Connector 실행 성공했다. 

 

테이블의 변경 사항 감지를 하여 source 가 감지하고, kafka topic으로 가지고 있다가 sink 로 보내는 것이 성공했다. 

 

 

요약


 

문제는 Kafka Connect가 MySQL을 찾지 못하는 것이 문제였다. 

 

원인은 서로 다른 Docker 컨테이너 네트워크라 서로 찾는 것에 실패했고 

 

컨테이너 외부에서 네트워크를 생상하여 모든 컨테이너를 같은 네트워크로 연결하여 해결했다. 

 

Connect가 정상 기동하고 데이터 변경 감지, 수집, 보내주기에 성공했다. 

 

그래서 TIL 19 글에 코드 중 docker-compose.yml에 network가 들어간 이유이다. 

 

728x90
반응형