无法连接到 Docker 容器中的 Cassandra 运行
Cannot connect to Cassandra running in a Docker container
对于我的应用程序,有一个 Docker 容器 database
,其中 运行 是 Cassandra。我将端口 9160
和 9042
暴露给主机,但由于某种原因,我无法从我的主机连接到 Cassandra。我可以使用 cqlsh
从其他 Docker 容器连接到它,只有当 我将另一个容器放在同一个网络中时。
我的 docker-compose
文件(我 运行 和 docker-compose up
):
database:
image: cassandra
container_name: database
depends_on:
- kafka
ports:
- 9042:9042
- 9160:9160
volumes:
- ./:/code
environment:
- CASSANDRA_START_RPC=true
- CASSANDRA_BROADCAST_ADDRESS=database
entrypoint: "/code/scripts/cassandra.sh"
frontend:
container_name: frontend
build:
context: driver/
volumes:
- ./:/code
network_mode: service:database
environment:
- BOOTSTRAP_SERVER=kafka:9092
- CASSANDRA_HOST=localhost
entrypoint: "/code/scripts/frontend.sh"
其中 cassandra.sh
和 frontend.sh
只需通过 运行 脚本初始化数据库,并分别安装一些软件包。
使用上述设置,我只需在 frontend
容器中调用 cqlsh
即可使用 cqlsh。但是,如果我从 frontend
中删除行 network_mode: service:database
,并尝试使用 cqlsh database
或 cqlsh $CASSANDRA_HOST
进行连接,即使在我设置 CASSANDRA_HOST=database
之后也是如此。执行上述任何命令都会给我:
Connection error: ('Unable to connect to any servers', {'172.27.0.5:9042': ConnectionRefusedError(111, "Tried connecting to [('172.27.0.5', 9042)]. Last error: Connection refused")})
.
因此,即使我公开了端口 9042,我也无法从我的主机 运行 cqlsh
。主机是 2020 iMac 运行正在使用 macOS Monterey 12.3.1.:
> netstat -anvp tcp | awk 'NR<3 || /LISTEN/'
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address Foreign Address (state) rhiwat shiwat pid epid state options
tcp46 0 0 *.29092 *.* LISTEN 131072 131072 911 0 0x0100 0x00000006
tcp4 0 0 127.0.0.1.9042 *.* LISTEN 131072 131072 7099 0 0x0100 0x00000006
tcp4 0 0 127.0.0.1.7000 *.* LISTEN 131072 131072 7099 0 0x0100 0x00000006
tcp4 0 0 127.0.0.1.54196 *.* LISTEN 131072 131072 7099 0 0x0100 0x00000006
tcp4 0 0 127.0.0.1.7199 *.* LISTEN 131072 131072 7099 0 0x0100 0x00000006
tcp46 0 0 *.8080 *.* LISTEN 131072 131072 911 0 0x0100 0x00000006
tcp46 0 0 *.7077 *.* LISTEN 131072 131072 911 0 0x0100 0x00000006
tcp46 0 0 *.4040 *.* LISTEN 131072 131072 911 0 0x0100 0x00000006
tcp46 0 0 *.9160 *.* LISTEN 131072 131072 911 0 0x0100 0x00000006
tcp46 0 0 *.9042 *.* LISTEN 131072 131072 911 0 0x0100 0x00000006
tcp46 0 0 *.2181 *.* LISTEN 131072 131072 911 0 0x0100 0x00000006
tcp4 0 0 127.0.0.1.6463 *.* LISTEN 131072 131072 1241 0 0x0100 0x00000106
tcp4 0 0 127.0.0.1.49390 *.* LISTEN 131072 131072 826 0 0x0100 0x00000106
tcp4 0 0 127.0.0.1.45623 *.* LISTEN 131072 131072 826 0 0x0100 0x00000106
tcp4 0 0 127.0.0.1.49380 *.* LISTEN 131072 131072 826 0 0x0100 0x00000106
tcp4 0 0 127.0.0.1.49379 *.* LISTEN 131072 131072 826 0 0x0100 0x00000106
tcp4 0 0 127.0.0.1.15292 *.* LISTEN 131072 131072 770 0 0x0000 0x0000020f
tcp6 0 0 *.5000 *.* LISTEN 131072 131072 465 0 0x0100 0x00000006
tcp4 0 0 *.5000 *.* LISTEN 131072 131072 465 0 0x0100 0x00000006
tcp6 0 0 *.7000 *.* LISTEN 131072 131072 465 0 0x0100 0x00000006
tcp4 0 0 *.7000 *.* LISTEN 131072 131072 465 0 0x0100 0x00000006
tcp6 0 0 *.49198 *.* LISTEN 131072 131072 494 0 0x0100 0x00000006
tcp4 0 0 *.49198 *.* LISTEN 131072 131072 494 0 0x0100 0x00000006
我花了几个小时为此寻找解决方案,并在 Whosebug 和其他网站上查看了几乎所有可能的 post 关于此主题的解决方案,但 none 的解决方案对我有用。非常感谢您的帮助。
问题是由设置入口点引起的:
entrypoint: "/code/scripts/cassandra.sh"
事实证明,如果没有提供入口点,某些 Cassandra 设置仅由图像初始化。如果提供了,您必须自己设置这些设置,我没有这样做。我添加了入口点 cassandra.sh
因为我想通过 运行 文件 create.cql
:
初始化数据库
#!/bin/sh
cassandra -R
# Wait for Cassandra to start up
while ! cqlsh -e 'describe cluster' ; do
sleep 1
done
echo "Cassandra has started"
cqlsh --file '/code/scripts/create.cql'
echo "Cassandra has been initialised"
tail -f /dev/null
我最终创建了另一个 Docker 容器,它在数据库启动后简单地初始化数据库:
database:
image: cassandra
container_name: database
depends_on:
- kafka
ports:
- 9042:9042
- 9160:9160
volumes:
- ./:/code
db_seeder:
container_name: db_seeder
build:
context: db_seeder/
depends_on:
- database
volumes:
- ./:/code
environment:
- CASSANDRA_HOST=database
entrypoint: "/code/scripts/cassandra.sh"
对于我的应用程序,有一个 Docker 容器 database
,其中 运行 是 Cassandra。我将端口 9160
和 9042
暴露给主机,但由于某种原因,我无法从我的主机连接到 Cassandra。我可以使用 cqlsh
从其他 Docker 容器连接到它,只有当 我将另一个容器放在同一个网络中时。
我的 docker-compose
文件(我 运行 和 docker-compose up
):
database:
image: cassandra
container_name: database
depends_on:
- kafka
ports:
- 9042:9042
- 9160:9160
volumes:
- ./:/code
environment:
- CASSANDRA_START_RPC=true
- CASSANDRA_BROADCAST_ADDRESS=database
entrypoint: "/code/scripts/cassandra.sh"
frontend:
container_name: frontend
build:
context: driver/
volumes:
- ./:/code
network_mode: service:database
environment:
- BOOTSTRAP_SERVER=kafka:9092
- CASSANDRA_HOST=localhost
entrypoint: "/code/scripts/frontend.sh"
其中 cassandra.sh
和 frontend.sh
只需通过 运行 脚本初始化数据库,并分别安装一些软件包。
使用上述设置,我只需在 frontend
容器中调用 cqlsh
即可使用 cqlsh。但是,如果我从 frontend
中删除行 network_mode: service:database
,并尝试使用 cqlsh database
或 cqlsh $CASSANDRA_HOST
进行连接,即使在我设置 CASSANDRA_HOST=database
之后也是如此。执行上述任何命令都会给我:
Connection error: ('Unable to connect to any servers', {'172.27.0.5:9042': ConnectionRefusedError(111, "Tried connecting to [('172.27.0.5', 9042)]. Last error: Connection refused")})
.
因此,即使我公开了端口 9042,我也无法从我的主机 运行 cqlsh
。主机是 2020 iMac 运行正在使用 macOS Monterey 12.3.1.:
> netstat -anvp tcp | awk 'NR<3 || /LISTEN/'
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address Foreign Address (state) rhiwat shiwat pid epid state options
tcp46 0 0 *.29092 *.* LISTEN 131072 131072 911 0 0x0100 0x00000006
tcp4 0 0 127.0.0.1.9042 *.* LISTEN 131072 131072 7099 0 0x0100 0x00000006
tcp4 0 0 127.0.0.1.7000 *.* LISTEN 131072 131072 7099 0 0x0100 0x00000006
tcp4 0 0 127.0.0.1.54196 *.* LISTEN 131072 131072 7099 0 0x0100 0x00000006
tcp4 0 0 127.0.0.1.7199 *.* LISTEN 131072 131072 7099 0 0x0100 0x00000006
tcp46 0 0 *.8080 *.* LISTEN 131072 131072 911 0 0x0100 0x00000006
tcp46 0 0 *.7077 *.* LISTEN 131072 131072 911 0 0x0100 0x00000006
tcp46 0 0 *.4040 *.* LISTEN 131072 131072 911 0 0x0100 0x00000006
tcp46 0 0 *.9160 *.* LISTEN 131072 131072 911 0 0x0100 0x00000006
tcp46 0 0 *.9042 *.* LISTEN 131072 131072 911 0 0x0100 0x00000006
tcp46 0 0 *.2181 *.* LISTEN 131072 131072 911 0 0x0100 0x00000006
tcp4 0 0 127.0.0.1.6463 *.* LISTEN 131072 131072 1241 0 0x0100 0x00000106
tcp4 0 0 127.0.0.1.49390 *.* LISTEN 131072 131072 826 0 0x0100 0x00000106
tcp4 0 0 127.0.0.1.45623 *.* LISTEN 131072 131072 826 0 0x0100 0x00000106
tcp4 0 0 127.0.0.1.49380 *.* LISTEN 131072 131072 826 0 0x0100 0x00000106
tcp4 0 0 127.0.0.1.49379 *.* LISTEN 131072 131072 826 0 0x0100 0x00000106
tcp4 0 0 127.0.0.1.15292 *.* LISTEN 131072 131072 770 0 0x0000 0x0000020f
tcp6 0 0 *.5000 *.* LISTEN 131072 131072 465 0 0x0100 0x00000006
tcp4 0 0 *.5000 *.* LISTEN 131072 131072 465 0 0x0100 0x00000006
tcp6 0 0 *.7000 *.* LISTEN 131072 131072 465 0 0x0100 0x00000006
tcp4 0 0 *.7000 *.* LISTEN 131072 131072 465 0 0x0100 0x00000006
tcp6 0 0 *.49198 *.* LISTEN 131072 131072 494 0 0x0100 0x00000006
tcp4 0 0 *.49198 *.* LISTEN 131072 131072 494 0 0x0100 0x00000006
我花了几个小时为此寻找解决方案,并在 Whosebug 和其他网站上查看了几乎所有可能的 post 关于此主题的解决方案,但 none 的解决方案对我有用。非常感谢您的帮助。
问题是由设置入口点引起的:
entrypoint: "/code/scripts/cassandra.sh"
事实证明,如果没有提供入口点,某些 Cassandra 设置仅由图像初始化。如果提供了,您必须自己设置这些设置,我没有这样做。我添加了入口点 cassandra.sh
因为我想通过 运行 文件 create.cql
:
#!/bin/sh
cassandra -R
# Wait for Cassandra to start up
while ! cqlsh -e 'describe cluster' ; do
sleep 1
done
echo "Cassandra has started"
cqlsh --file '/code/scripts/create.cql'
echo "Cassandra has been initialised"
tail -f /dev/null
我最终创建了另一个 Docker 容器,它在数据库启动后简单地初始化数据库:
database:
image: cassandra
container_name: database
depends_on:
- kafka
ports:
- 9042:9042
- 9160:9160
volumes:
- ./:/code
db_seeder:
container_name: db_seeder
build:
context: db_seeder/
depends_on:
- database
volumes:
- ./:/code
environment:
- CASSANDRA_HOST=database
entrypoint: "/code/scripts/cassandra.sh"