在 Compute Engine 上设置客户端对 MySQL 的访问权限(通过专用 IP 地址访问)

本教程将引导您完成在 Google Cloud Platform (GCP) 中的专用网络上运行 MySQL 数据库的过程,以允许使用 Compute Engine 安全地远程访问数据库。

如果要在 Compute Engine 上安装您自己的 MySQL 数据库,但希望只有也在 Compute Engine 上运行的已获授权 MySQL 客户端才能访问,请使用本教程。由于跨地区实例、参数的高级用法以及特定的性能需求,您可能希望亲自管理自己的 MySQL 实例,而不是使用代管式服务

本教程介绍如何配置 MySQL 服务器应用,以接受来自在同一专用网络上的 Compute Engine 实例上安装的 MySQL 客户端的远程流量。

如需了解如何选择正确的 MySQL 部署选项,请参阅如何在 Compute Engine 上安装 MySQL

本教程假定您熟悉以下内容:

  • 基本的 Linux 命令
  • Ubuntu-server 18.04
  • MySQL 5.7
  • Compute Engine

架构

在本教程中,您将部署两个 Compute Engine 实例。其中一个实例是服务器,另一个实例是客户端,如下图所示:

两个已部署实例的架构

目标

  • 创建 Compute Engine 实例并安装 MySQL 服务器。
  • 创建 Compute Engine 实例并安装 MySQL 客户端。
  • 配置 MySQL 服务器以进行远程访问。
  • 移除对 MySQL 服务器的公共访问权限。
  • 远程连接到 MySQL。
  • 创建 VPC Service Controls 防火墙规则。

费用

本教程使用 Google Cloud 的以下收费组件:

  • Compute Engine
  • Cloud Storage

您可使用价格计算器根据您的预计使用量来估算费用。 Google Cloud 新用户可能有资格申请免费试用

准备工作

  1. 登录您的 Google 帐号。

    如果您还没有 Google 帐号,请注册一个新帐号

  2. 在 Cloud Console 的项目选择器页面上,选择或创建 Cloud 项目。

    转到项目选择器页面

  3. 确保您的 Google Cloud 项目已启用结算功能。 了解如何确认您的项目已启用结算功能

  4. 启用 Compute Engine API。

    启用 API

完成本教程后,您可以删除所创建的资源以避免继续计费。如需了解详情,请参阅清理

创建 Compute Engine 实例

为 MySQL 创建两个实例 - 客户端实例和服务器实例。

创建 Compute Engine 客户端实例

  • 创建 Compute Engine 实例。按如下所示的方式配置实例:
    • 将实例命名为 my-client
    • --zone 标志设置为您要在其中创建实例的区域
    • --image-project 标志设置为 ubuntu-os-cloud
    • --image-family 标志设置为 ubuntu-1804-lts
    • --scopes 标志设置为 https://www.googleapis.com/auth/cloud-platform
    gcloud compute instances create my-client --zone [ZONE] --image-project ubuntu-os-cloud --image-family ubuntu-1804-lts --scopes https://www.googleapis.com/auth/cloud-platform
  • 创建 Compute Engine 服务器实例

  • 创建 Compute Engine 实例。按如下所示的方式配置实例:
    • 将实例命名为 my-server
    • --zone 标志设置为您要在其中创建实例的区域
    • --image-project 标志设置为 ubuntu-os-cloud
    • --image-family 标志设置为 ubuntu-1804-lts
    • --scopes 标志设置为 https://www.googleapis.com/auth/cloud-platform
    gcloud compute instances create my-server --zone [ZONE] --image-project ubuntu-os-cloud --image-family ubuntu-1804-lts --scopes https://www.googleapis.com/auth/cloud-platform
  • 安装 MySQL 客户端

    以下步骤介绍了如何在 Compute Engine 实例上安装 MySQL。

    1. 在 Cloud Console 中,转到虚拟机实例页面。

      转到“虚拟机实例”页面

    2. 在虚拟机实例列表中,点击要连接的实例所在行中的 SSH

      实例名称旁边的 SSH 按钮。

    3. 更新 apt-get 软件包管理器。
      sudo apt-get update
      
    4. 安装 MySQL 客户端软件包。
      sudo apt-get -y install mysql-client-5.7

    安装 MySQL 服务器

    以下步骤介绍了如何在 Compute Engine 实例上安装 MySQL。

    1. 在 Cloud Console 中,转到虚拟机实例页面。

      转到“虚拟机实例”页面

    2. 在虚拟机实例列表中,点击要连接的实例所在行中的 SSH

      实例名称旁边的 SSH 按钮。

    3. 更新 apt-get 软件包管理器。
      sudo apt-get update
      
    4. 安装 MySQL 服务器软件包。
      sudo apt-get -y install mysql-server-5.7

    提高 MySQL 安装的安全性

    您必须为 MySQL 设置根密码,并对 MySQL 服务器配置执行基本安全维护。如需了解详情,请参阅有关 mysql_secure_installation 的 MySQL 文档。

    1. 在 Cloud Shell 中,提高 MySQL 安装的安全性。

      sudo mysql_secure_installation
      
    2. enter 键跳过设置 VALIDATE PASSWORD 插件。

    3. 输入两次新的根密码。

    4. 如需移除匿名用户,请输入 Y 并按 enter 键。

    5. 如需阻止远程根登录,请输入 Y 并按 enter 键。

    6. 如需移除测试数据库,请输入 Y 并按 enter 键。

    7. 如需重新加载权限表,请输入 Y 并按 enter 键。

    配置 MySQL 服务器

    在远程连接 MySQL 服务器之前,您需要将 MySQL 服务器配置为侦听其内部 IP 地址。然后,为 MySQL 客户端创建一个非根用户帐号以连接到服务器。

    所有 MySQL 客户端命令都必须包含特定命令行标志(例如,进行身份验证)。本部分的 MySQL 命令包括以下标志:--user(用于用户名)、-p(用于密码)和 -e(用于执行给定的语句并立即退出)。如需了解详情,请参阅 MySQL 5.7 命令选项参考

    1. 在 Cloud Shell 中,使用 SSH 连接到 my-server 实例。

    2. 使用以下信息更新 /etc/mysql/mysql.conf.d/mysqld.cnf 配置文件:

      LOCAL_IP=$(curl  http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip \
          -H "Metadata-Flavor: Google")
      sudo sed -i "s|bind-address.*|bind-address = $LOCAL_IP|" /etc/mysql/mysql.conf.d/mysqld.cnf
      
    3. 重启 MySQL 服务以将更改应用于正在运行的服务器。

      sudo service mysql restart
      
    4. 验证服务器是否在本地运行。将 [ROOT_PASSWORD] 替换为您在上一步中建立的 MySQL 服务器 root 密码。

      sudo mysql --user=root -p[ROOT_PASSWORD] -e "show databases"
      

      输出的结果应类似于以下内容:

      +--------------------+
      | Database           |
      +--------------------+
      | information_schema |
      | mysql              |
      | performance_schema |
      | sys                |
      +--------------------+
      

    创建 MySQL 用户

    使用上述 mysql_secure_installation 命令会停用以根用户身份建立远程连接的功能。您需要创建具有允许建立远程连接所需权限的新用户。

    1. 在 Cloud Shell 中,为 my-client 内部 IP 地址创建环境变量。

      CLIENT_IP=$(gcloud compute instances describe my-client \
          --zone=[ZONE] \
          --format='value(networkInterfaces[0].networkIP)')
      
    2. 创建一个包含密码的新 MySQL 用户。将 [MY_PASSWORD] 替换为您的密码,并且将 [ROOT_PASSWORD] 替换为您的 MySQL 根用户密码。

      sudo mysql -uroot -p[ROOT_PASSWORD] \
          -e "CREATE USER 'TESTUSER'@'${CLIENT_IP}' IDENTIFIED BY '[MY_PASSWORD]';"
      
    3. 授予新的 MySQL 用户权限,以便从 my-client 的内部 IP 地址登录服务器。

      sudo mysql -uroot -p[ROOT_PASSWORD] -e \
          "GRANT ALL PRIVILEGES ON *.* TO 'TESTUSER'@'${CLIENT_IP}' \
          IDENTIFIED BY '[MY_PASSWORD]';"
      

    移除 my-server 的外部 IP 地址

    my-server 实例不需要外部 IP 地址,因为客户端可以通过内部 IP 地址访问 my-server

    • 如需移除外部 IP 地址,请更新 Cloud Shell 中的配置设置。将 [ZONE] 替换为您的 Google Cloud 区域。

      gcloud compute instances delete-access-config my-server \
          --access-config-name "external-nat" \
          --zone="[ZONE]"
      

    验证从客户端到服务器实例的远程访问

    以下步骤介绍了如何从 my-client 实例连接到 my-server 上的 MySQL 服务器。

    1. 在 Cloud Shell 中,使用 SSH 连接到 my-client 实例。
    2. 通过列出数据库来测试您的连接。

      sudo mysql --host=my-server --user=TESTUSER \
          --password=[MY_PASSWORD] -e "SHOW DATABASES;"
      

      输出的结果应类似于以下内容:

      +--------------------+
      | Database           |
      +--------------------+
      | information_schema |
      | mysql              |
      | performance_schema |
      | sys                |
      +--------------------+
      

    这些步骤验证您的 MySQL 客户端是否可以通过内部 IP 地址成功连接到 MySQL 服务器。

    生产环境中的防火墙注意事项

    Google Cloud 中的默认网络配置包括防火墙规则 default-allow-internal,此规则允许各种端口(包括 MySQL 端口 3306)上的 Compute Engine 实例之间的内部流量。在已确定存在安全隐患的非默认环境中,您可能需要创建防火墙规则,以允许 my-client 实例通过网络与您的 my-server 实例进行通信。

    您可以根据 IP 地址范围或标记建立防火墙规则。如果要向各种内部 IP 地址授予访问权限,可以使用 IP 地址范围。或者,如果要向网络上的特定实例授予访问权限,则标记可以提供更灵活的解决方案。使用标记可以更轻松地添加新客户端,而无需向各种 IP 地址授予访问权限。您只需将合适的标记分配给新的 MySQL 客户端实例即可。例如,您可以创建一个新的防火墙规则,允许来自所有标记为 mysql-client 的客户端实例的流量。

    如需支持使用标记的防火墙规则,您可以将适当的标记分配给 Cloud Shell 中的 my-clientmy-server 虚拟机。

    gcloud compute instances add-tags my-client --tags mysql-client --zone=[ZONE]
    
    gcloud compute instances add-tags my-server --tags mysql-server --zone=[ZONE]
    

    添加新的防火墙规则

    以下步骤描述了如何创建新的防火墙规则,以使具有 my-client 标记的实例能够通过端口 3306 与具有 my-server 标记的实例进行通信。

    • 在 Cloud Shell 中,创建防火墙规则以允许从 mysql-clientmysql-server 的通信。

      gcloud compute firewall-rules create "mysql-remote-access" \
          --allow tcp:3306 --source-tags "mysql-client" \
          --target-tags "mysql-server"
      

    您现在可以从 my-client 连接到 MySQL。

    从外部客户端进行访问的注意事项

    本教程介绍了如何从 Compute Engine 上运行的 MySQL 客户端访问也在 Compute Engine 上运行的 MySQL 服务器。本教程不介绍如何允许从不在 Compute Engine 上运行的客户端进行访问。如果您需要允许非 Compute Engine 访问,请修改以下内容:

    • 将外部 IP 地址添加到 my-server 以允许外部连接。
    • 将外部客户端的来源 IP 地址添加到防火墙规则
    • 修改 TESTUSER 帐号,或创建绑定到外部客户端来源 IP 地址的用户帐号。

    清理

    为避免系统因本教程中使用的资源向您的 Google Cloud 帐号收取费用,您可以删除项目删除实例

    删除项目

    为了避免产生费用,最简单的方法是删除您为本教程创建的项目。

    如需删除项目,请执行以下操作:

    1. 在 Cloud Console 中,转到管理资源页面。

      转到“管理资源”页面

    2. 在项目列表中,选择要删除的项目,然后点击删除
    3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

    删除实例

    如需删除 Compute Engine 实例,请执行以下操作:

    1. 在 Cloud Console 中,转到虚拟机实例页面。

      转到“虚拟机实例”页面

    2. 点击您的 my-server 实例对应的复选框。
    3. 点击删除 以删除实例。

    后续步骤