配置ECI连接RDS

如果您的容器应用需要连接数据库(以RDS MySQL实例为例),您需要设置RDS白名单,并在创建ECI Pod时传入数据库连接信息。本文介绍在ACK Serverless集群中创建ECI Pod时,如何连接RDS。

背景信息

阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务。基于阿里云分布式文件系统和SSD盘高性能存储,RDS支持MySQL、SQL Server、PostgreSQL等多种数据库引擎,本文使用RDS MySQL实例为例。您可以根据业务需求来选择。更多信息,请参见数据库引擎介绍

前提条件

  • 已创建RDS MySQL实例,并且在实例上配置数据库用户账号。具体操作,请参见创建RDS MySQL实例创建数据库和账号

  • 已创建ACK Serverless集群。具体操作,请参见创建集群

    说明

    本文以ACK Serverless集群为例,如果您使用其他类型的Kubernetes集群,请确保集群中已部署虚拟节点来对接ECI。

  • 确保DS实例与Kubernetes集群的网络互通。

    建议RDS实例与Kubernetes集群属于同一VPC网络下,可以直接使用内网进行通信;如果跨VPC创建RDS实例和Kubernetes集群,则需要配置公网。

设置RDS白名单并获取数据库访问地址

通过内网访问RDS

如果您的Kubernetes集群和RDS实例在同一VPC下,则集群中的应用可以通过内网访问RDS,您需要设置RDS白名单并获取数据库内网访问地址。

  1. 设置RDS白名单。

    内网访问时,白名单可以设置IP地址或安全组:

    • IP地址

      在RDS白名单中添加IP地址网段(VPC或交换机网段),属于该网段的ECI实例均可访问该RDS实例。具体操作,请参见设置IP白名单

    • 安全组

      在RDS白名单中添加安全组后,该安全组中的ECI实例均可以访问该RDS实例。具体操作,请参见设置安全组

  2. 在RDS实例的数据库连接页面,记录数据库内网访问地址。

通过公网访问RDS

如果您的Kubernetes集群和RDS实例在不同的VPC下,则集群中的应用需要通过公网访问RDS。您需要设置RDS白名单并申请数据库外网访问地址。

重要
  • 外网地址会降低实例的安全性,请谨慎使用。

  • 为了获得更快的传输速率和更高的安全性,建议您将应用迁移到与您的RDS实例在同一地域且网络类型相同的ECI实例,然后使用内网地址。

  1. 设置RDS白名单。

    公网访问时,需要设置IP白名单,具体操作,请参见设置IP白名单

    • 如果ECI实例使用NAT网关访问公网,则IP白名单中需添加NAT网关绑定的EIP地址。

    • 如果ECI实例使用EIP访问公网,则IP白名单中需添加该ECI实例绑定的EIP地址。

  2. 申请并记录数据库外网访问地址。具体操作,请参见申请或释放外网地址

配置应用连接RDS实例

ACK Serverless集群使用内网连接RDS实例为例,操作如下:

  1. 登录容器服务管理控制台

  2. 集群页面,找到目标集群,单击集群名称,进入集群管理页面。

  3. 创建ConfigMap,配置RDS连接信息。

    说明

    ConfigMap可以将您的环境配置信息和容器镜像解耦,便于应用配置的修改。

    1. 在左侧导航栏,选择配置管理>配置项

    2. 单击创建

    3. 填写ConfigMap配置,然后单击确定

      名称为rds-config,要添加的配置如下:

      名称

      示例值

      说明

      host

      rm-2zem97a62s9******.mysql.rds.aliyuncs.com

      数据库连接地址,在RDS实例的数据库连接页面可以获取。

      port

      3306

      数据库连接端口,在RDS实例的数据库连接页面可以获取。

      database

      test-db

      数据库名称,在RDS实例的数据库管理页面可以获取。

  4. 创建Secret,添加数据库用户名和密码。

    说明

    使用Secret可以将数据库用户名和密码等机密信息安全地传递给应用。

    1. 在左侧导航栏,选择配置管理>保密字典

    2. 单击创建

    3. 填写Secret配置,然后单击确定

      名称为rds-secret,要添加的配置如下:

      名称

      示例值

      说明

      username

      test

      数据库用户名称。在RDS实例的账号管理页面可以获取。

      password

      pwd******

      数据库密码。如果您忘记了密码,在RDS实例的账号管理页面可以进行重置。

  5. 创建ECI Pod,测试能否连接RDS。

    1. 在左侧导航栏,选择工作负载>容器组

    2. 单击使用YAML创建资源

    3. 填写YAML,单击创建

      由于RDS与原生的数据库服务完全兼容,因此您可以使用任何通用的数据库客户端连接到RDS实例,且连接方法类似。配置示例如下:

      说明

      如果采用配置示例进行测试,请先在RDS实例中创建username表,表中增加一个user列。

      如下YAML示例通过环境变量传入数据库连接信息(包括数据库连接地址、端口、名称,以及用户名和密码),使用的镜像包含了一个Python脚本,可以连接数据库并插入数据。

      apiVersion: v1
      kind: Pod
      metadata:
        labels:
          name: rds-test
        name: rds-test
      spec:
        containers:
        - name: test-rds
          image: registry.cn-hangzhou.aliyuncs.com/eci_open/sqlclient:1.0.1  #一个Python Job用来连接云数据库的镜像
          imagePullPolicy: IfNotPresent
          command: ["/bin/bash","-c","python3 /testapp/mysqlclient.py"]
          env:
          - name: MYSQL_HOST 
            valueFrom:
              configMapKeyRef:
                name: rds-config  #ConfigMap的名称
                key: host  #ConfigMap中的Key
          - name: MYSQL_PORT
            valueFrom:
              configMapKeyRef:
                name: rds-config #ConfigMap的名称
                key: port #ConfigMap中的Key
          - name: MYSQL_DB
            valueFrom:
              configMapKeyRef:
                name: rds-config  #ConfigMap的名称
                key: database #ConfigMap中的Key
          - name: MYSQL_USERNAME
            valueFrom:
              secretKeyRef:
                name: rds-secret #Secret的名称
                key: username  #Secret中的Key
          - name: MYSQL_PWD
            valueFrom:
              secretKeyRef:
                name: rds-secret #Secret的名称
                key: password #Secret中的Key
        restartPolicy: Never

      上述示例的镜像包含的Python脚本(mysqlclient.py)可以在username表的user列中插入一条数据。脚本内容如下:

      import pymysql
      import os
      import time
      
      config = {
          'host': str(os.getenv('MYSQL_HOST')),
          'port': int(os.getenv('MYSQL_PORT')),
          'user': str(os.getenv('MYSQL_USERNAME')),
          'password': str(os.getenv('MYSQL_PWD')),
          'database': str(os.getenv('MYSQL_DB')),
      }
      
      def mysqlClient():
          print("connecting database ......")
          db = pymysql.connect(**config)
          try:
              cursor = db.cursor()
              cursor.execute("INSERT INTO username(user) VALUES('Mrs')")
              cursor.close()
              db.commit()
      
              cursor = db.cursor()
              cursor.execute("SELECT user FROM username")
              result = cursor.fetchall()
              cursor.close()
              if result != None:
                  print(result)
                  time.sleep(99999)
          except Exception as e:
              print('System Error: ', e)
          finally:
              db.close()
      
      
      if __name__ == '__main__':
          mysqlClient()
  6. 登录数据库,查看结果。

    1. 登录云数据库RDS控制台

    2. 在左侧导航栏选择实例列表,在上方选择地域,然后单击目标实例ID。

    3. 在左侧导航栏单击数据库管理

    4. 找到目标数据库。单击对应的SQL查询

    5. 在弹出的对话框中,输入数据库用户名和密码,单击登录

    6. 输入SQL命令查询结果。

      执行SELECT * FROM `username` 命令,可以看到username表的user列已新增一条数据。

      对接RDS

常见问题

数据库无法连接的常见场景包括:

  • 网络类型不同

  • 专有网络不同

  • 域名解析失败或错误

  • 地域不同

  • IP白名单设置有误

  • 只读实例未设置白名单

  • 内外网地址使用错误

  • 连接数已满

  • 用户名或密码错误

  • 无法解析地址

请根据当前环境的实际情况(内网或外网),选择对应的排查方法。更多信息,请参见解决无法连接RDS实例问题