容器内访问宿主机PostgreSQL数据库连接报错排查
故障原因
两个报错属于不同层面的问题:
- 第一次
localhost:5432连接被拒绝:Kafka Connect运行在独立容器中,容器内的localhost指向容器自身的网络命名空间,既不是宿主机也不是其他同网络容器。配置写localhost等于让连接器去访问Kafka Connect容器自身的5432端口,该端口没有PostgreSQL进程监听,自然触发连接拒绝。 - 第二次
role "root" does not exist:host.docker.internal是Docker提供的容器访问宿主机服务的特殊域名,这一步网络已经打通,但数据库身份认证失败。JDBC Sink连接器如果没有读取到自定义的数据库用户名,会默认用运行Kafka Connect进程的系统用户(Kafka Connect容器默认运行用户是root)发起连接,而你的PostgreSQL中没有名为root的登录角色所以报错。读取不到用户名的常见原因有两个:一是部分版本的JDBC Sink连接器只识别标准配置项connection.user,不识别你写的connection.username;二是修改连接地址后没有正确提交全量配置,用户名配置未生效。
解决方法
根据你的PostgreSQL部署位置选择对应方案:
方案1:PostgreSQL部署在同Docker网络的容器内(推荐)
这是容器化部署最稳定的方式,不需要走宿主机转发:
- 先确认PostgreSQL容器已经加入
kafka-sink-connect网络,执行以下命令检查:
如果没有输出,执行命令把PostgreSQL容器加入该网络:docker inspect <postgres容器ID或名称> | grep kafka-sink-connectdocker network connect kafka-sink-connect <postgres容器ID或名称> - 修改连接器配置:
- 把
connection.url改为用PostgreSQL容器名作为访问地址,比如PostgreSQL容器名为postgres,则配置为jdbc:postgresql://postgres:5432/postgres - 把
connection.username改为标准配置项connection.user,确认connection.password配置正确 - 修正冗余的转换器配置:你当前写的
schemas.enable没有加value.converter.前缀,属于无效配置;如果不用Schema Registry就删掉value.converter.schema.registry.url配置项,如果要用就把配置改为"value.converter.schemas.enable": "true"
- 把
- 删除之前创建的失败连接器实例,用修正后的配置重新创建即可。
方案2:PostgreSQL直接运行在宿主机上
- 保留
connection.url里的host.docker.internal地址,注意Linux环境下启动Kafka Connect容器时必须添加--add-host=host.docker.internal:host-gateway参数,否则该域名无法解析。 - 同样把配置里的
connection.username改为connection.user,确认密码正确。 - 修改宿主机上PostgreSQL的
pg_hba.conf文件,添加规则允许Docker网桥网段(默认为172.17.0.0/16)的用户通过密码认证登录,重载PostgreSQL配置生效。 - 重新提交连接器配置即可。
额外注意事项
- 你配置的
table.name.format为test.table,需要确认连接使用的postgres账号拥有testschema的读写、建表权限,否则auto.create和auto.evolve配置会失效。 - 测试连通性阶段可以临时把
batch.size调大,等链路稳定后再根据业务调整,不需要强制设为1。
内容的提问来源于stack exchange,提问作者ABC
相关产品推荐
相关产品推荐

