无法连接到在 Docker 容器中运行的 Cassandra

问题描述 投票:0回答:2

对于我的应用程序,有一个运行 Cassandra 的 Docker 容器

database
。我向主机公开了端口
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
只需通过运行脚本并分别安装一些软件包来初始化数据库。

使用上述设置,我只需在

cqlsh
容器中调用
frontend
即可使用 cqlsh。但是,如果我从
network_mode: service:database
中删除线
frontend
,并尝试使用
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
。主机是运行 macOS Monterey 12.3.1 的 2020 iMac。:

> 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

我花了几个小时寻找解决方案,并查看了 StackOverflow 和其他网站上关于此主题的几乎所有可能的帖子,但没有一个解决方案适合我。我将非常感谢一些帮助。

docker cassandra
2个回答
1
投票

该问题是由设置入口点引起的:

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"

0
投票

解决方案

命令 “docker pull cassandra:latest” 正在利用容器化平台 Docker 从官方 Docker Hub 存储库下载最新版本的 Cassandra 数据库管理系统 (DBMS) 映像。用技术术语来说:

Docker: 一个平台,使开发人员能够将应用程序及其依赖项打包到轻量级、可移植的容器中。容器在不同环境中提供一致的环境,使部署和扩展应用程序变得更加容易。

pull: 此 Docker 命令用于从容器注册表中获取容器映像。在本例中,它正在拉取 Cassandra 映像。

cassandra:latest: 指定要拉取的镜像。 “cassandra”是 Cassandra DBMS 的 Docker 映像的名称,“:latest”表示应检索映像的最新可用版本。

Docker Hub:基于云的注册表服务,Docker 用户可以在其中共享和访问容器映像。官方 Cassandra 镜像托管在 Docker Hub 上。

因此,当您运行 “docker pull cassandra:latest”时, Docker 将从 Docker Hub 下载最新版本的 Cassandra 映像,使其可在您的计算机上本地使用。 docker pull cassandra:最新

现在命令:

docker run --name cassandra -p 127.0.0.1:9042:9042 -p 127.0.0.1:9160:9160 -d cassandra

您提供的命令是用于运行 Cassandra 容器的 Docker 命令。让我们用技术术语来分解一下:

docker run:该命令用于根据指定镜像创建并启动一个新的容器。

--name cassandra: 为新创建的容器分配名称“cassandra”。这对于在后续 Docker 命令中引用容器很有帮助。

-p 127.0.0.1:9042:9042: 将容器的端口 9042(Cassandra 的本机传输端口)映射到主机的端口 9042。这意味着您可以在主机上通过 127.0.0.1:9042 访问 Cassandra。

-p 127.0.0.1:9160:9160: 将容器的端口 9160(用于 Thrift 通信)映射到主机的端口 9160。这允许您在主机上使用 Thrift 与 Cassandra 交互(地址为 127.0.0.1:9160) .

-d: 在后台运行容器(分离模式),允许您继续使用终端。

cassandra:指定用于创建容器的 Docker 映像的名称。在本例中,它是 Cassandra 图像。

因此,当您运行命令 “docker run --name cassandra -p 127.0.0.1:9042:9042 -p 127.0.0.1:9160:9160 -d cassandra”时,它会启动一个具有指定端口映射的新 Cassandra 容器,使 Cassandra 在主机上提供的端口上可访问。

使用此命令将导致 (com.datastax.driver.core.exceptions.TransportException: [/127.0.0.1:9042] Cannot connect))

异常像魔法一样消失!

© www.soinside.com 2019 - 2024. All rights reserved.