尝试访问在远程机器上的 Docker 容器中运行的 MariaDB

尝试访问在远程机器上的 Docker 容器中运行的 MariaDB

我似乎无法通过 SSH 隧道远程连接到我的数据库。我对这些都比较陌生,所以我希望有人能给我一些指点。

我有一台安装了 Docker 的云服务器,并且正在运行一个数据库容器(用于另一项服务 Wordpress):

撰写.yaml

services:

  db:
    image: mariadb:latest
    container_name: database
    restart: always
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_root_password
      - db_password
    ports:
      - '3306:3306'
    expose:
      - 3306

数据库容器运行良好,并且我的其余 Docker 服务与数据库交互没有任何问题。

如果我通过 SSH 连接到远程机器,我可以通过主机上的 MariaDB 客户端访问 Docker 环境中的数据库,因为端口 3306 从 Docker 容器转发到主机:

➜  ssh -i mykey user@hostname

➜  docker compose up -d

➜  nc -vz localhost 3306
Connection to localhost (::1) 3306 port [tcp/mysql] succeeded!

➜  mariadb -h 127.0.0.1 -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 15
Server version: 11.2.2-MariaDB-1:11.2.2+maria~ubu2204 mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

但是我无法使用本地数据库客户端 (DBeaver)。我已在客户端中设置了 SSH 隧道,使用的凭据与通过 CLI 连接到主机时使用的凭据相同。

在我的数据库客户端中测试 SSH 连接成功。但是,一旦建立 SSH 隧道,与数据库的连接就会失败:

Could not connect to 127.0.0.1:31987 : unexpected end of stream, read 0 bytes from 4 (socket was closed by server)

有人能指点我哪里做错了吗?这是远程访问数据库的正确方法吗?

我是否对 SSH 隧道的工作原理做出了一些错误的假设?我假设一旦建立隧道,它就会连接到我的远程主机上的端口 3306,就好像客户端实际上在远程主机上一样。我也不确定端口“31987”来自哪里,但我猜它是客户端用于连接端口 3306 的临时端口,但也许我也错了?

我不希望数据库端口公开访问,因此对远程主机上端口 3306 的远程访问受到防火墙的保护。

我知道我可以安装一个新的 docker 服务、sshtunnel,然后直接通过隧道进入该服务,但我不明白为什么在通过隧道进入主机时无法连接...

提前感谢任何提示!

答案1

我建议在 docker-compose 中使用 network_mode host。因为默认情况下,docker 会创建一个很难建立隧道的单独网络。

    services:
    
      db:
        image: mariadb:latest
        container_name: database
        restart: always
        volumes:
          - db_data:/var/lib/mysql
        environment:
          MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
          MYSQL_DATABASE: wordpress
          MYSQL_USER: wordpress
          MYSQL_PASSWORD_FILE: /run/secrets/db_password
        secrets:
          - db_root_password
          - db_password
networks:
      proxy:
        aliases:
          - test.mysql.docker


sshtunnel:
    restart: always
    image: ghcr.io/linuxserver/openssh-server
    container_name: sshtunnel
    ports:
      - 2222:2222
    volumes:
      - ~/.ssh/id_rsa.pub:/etc/tunnel/id_rsa.pub
      - ./openssh/sshd_config:/config/ssh_host_keys/sshd_config
    environment:
      - PUBLIC_KEY_FILE=/etc/tunnel/id_rsa.pub
      - USER_NAME=proxy
      - SUDO_ACCESS=true
    networks:
      - proxy

networks:
  proxy:
    driver: bridge
    name: proxy

看这里: https://madewithlove.com/blog/using-an-ssh-tunnel-to-connect-to-your-dev-mysql-with-docker/

相关内容