Invalid method name: 'PingImpalaService'
이 오류는 로드밸런서 문제가 아니라 포트와 프로토콜이 어긋난 것이다. impalad 의 클라이언트 포트는 용도가 나뉜다.
| 포트 | 프로토콜 |
|---|---|
| 21000 | Beeswax (구형 impala-shell 기본) |
| 21050 | HiveServer2 (JDBC · ODBC · 최신 impala-shell) |
| 28000 | HiveServer2 over HTTP |
21050 에 --protocol=beeswax 로 붙으면 서버가 Beeswax 메서드를 모른다며 위 메시지를 낸다.
impala-shell -i impala-lb.example.internal:21050 --protocol=hs2 -k --ssl
로드밸런서 주소로 실제 인증서가 나오는지부터 본다.
LB=impala-lb.example.internal
openssl s_client -connect ${LB}:21050 -servername ${LB} </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates -ext subjectAltName
subject 와 subjectAltName 에 접속에 쓰는 이름이 들어 있어야 한다. 없으면 hostname 검증에서 실패한다.
Impala 는 TLS 를 자기가 끝낸다. NLB 에서 TLS 리스너를 쓰면 로드밸런서가 복호화하므로 구성이 어긋난다. TCP 리스너로 통과(passthrough) 시키는 것이 맞다.
클라이언트 / Hue
| TLS + Kerberos + HS2
v
NLB : TCP 21050 (복호화하지 않음)
|
v
impalad : 21050 (SSL enabled)
이 구성에서는 클라이언트가 보는 인증서가 NLB 의 것이 아니라 뒤쪽 impalad 의 것이다. 그래서 다음 오류가 난다.
hostname 'impala-lb.example.internal' doesn't match 'ip-10-14-52-13.ap-northeast-2.compute.internal'
해결은 두 갈래다. 제대로 하려면 impalad 인증서의 SAN 에 로드밸런서 DNS 이름을 넣는다. Cloudera Auto-TLS 환경에서는 CM 이 자체 CA 로 발급한 인증서에 임의의 SAN 을 넣을 수 없으므로, 사용자 인증서를 만들어 Auto-TLS 에 등록하는 방식으로 가야 한다.
급한 대로 검증만 끄는 방법도 있다. 암호화는 유지되고 상대 신원 확인만 생략된다.
ssl=true, validate=true : 암호화 + 인증서가 신뢰할 수 있는지, 이름이 맞는지 확인
ssl=true, validate=false : 암호화만. 상대가 진짜 그 서버인지 확인하지 않음
ssl=false : 평문
validate=false 는 중간자 공격을 막지 못하므로 임시 조치로만 쓴다. 사설망 안이라도 정상 구성으로 되돌리는 계획을 함께 세운다.
Hue 의 Impala TLS 설정은 [impala] 아래 [[ssl]] 블록이다. 키 이름을 잘못 쓰면 값이 무시되고 계속 hostname mismatch 가 난다.
[impala]
server_host=impala-lb.example.internal
server_port=21050
[[ssl]]
enabled=true
validate=false
## cacerts=/etc/hue/certs/impala-ca.pem
CA 를 지정해도 이름이 맞지 않으면 실패한다. cacerts 는 신뢰 사슬 문제를 푸는 것이지 이름 불일치를 푸는 것이 아니다.
Cloudera Impala JDBC 드라이버에서 같은 동작은 URL 옵션으로 만든다.
jdbc:impala://impala-lb.example.internal:21050/default;AuthMech=3;SSL=1;AllowSelfSignedCerts=1;CAIssuedCertNamesMismatch=1
AllowSelfSignedCerts=1 은 신뢰 검증을, CAIssuedCertNamesMismatch=1 은 이름 검증을 우회한다. NiFi 에서는 DBCPConnectionPool 컨트롤러 서비스에 위 URL 과 드라이버 클래스(com.cloudera.impala.jdbc.Driver), 드라이버 jar 경로를 넣는다. 운영 중인 서비스를 건드리지 말고 테스트용 컨트롤러를 따로 만들어 확인한 뒤 옮긴다.
AuthMech 값은 인증 방식이다. 3 은 사용자·비밀번호(LDAP), 1 은 Kerberos 다.