Подключение к базе данных в кластере MySQL
К хостам кластера Managed Service for MySQL можно подключиться:
- Через интернет, если вы настроили публичный доступ для нужного хоста. К таким хостам подключиться можно только используя SSL-соединение.
- С виртуальных машин Yandex.Cloud, расположенных в той же виртуальной сети. Если к хосту нет публичного доступа, для подключения с таких ВМ SSL-соединение использовать необязательно.
Примечание
Если публичный доступ в вашем кластере настроен только для некоторых хостов, автоматическая смена мастера может привести к тому, что вы не сможете подключиться к мастеру из интернета.
Настройка SSL-сертификата
MySQL-хосты с публичным доступом поддерживают только соединения с SSL-сертификатом. Подготовить сертификат можно так:
mkdir ~/.mysql && \
wget "https://storage.yandexcloud.net/cloud-certs/CA.pem" -O ~/.mysql/root.crt && \
chmod 0600 ~/.mysql/root.crt
Примеры строк подключения
Примеры проверялись в следующем окружении:
- Виртуальная машина в Облаке c Ubuntu 20.04 LTS.
- Bash:
5.0.16
. - Python:
3.8.2
; pip3:20.0.2
. - PHP:
7.4.3
. - OpenJDK:
11.0.8
; Maven:3.6.3
. - Node.JS:
10.19.0
, npm:6.14.4
. - Go:
1.13.8
. - Ruby:
2.7.0p0
. - unixODBC:
2.3.6
.
Вы можете подключаться к MySQL-хостам в публичном доступе только с использованием SSL-сертификата. Перед подключением к таким хостам подготовьте сертификат.
В этих примерах предполагается, что сертификат root.crt
расположен в директории /home/<домашняя директория>/.mysql/
.
Подключение без использования SSL-сертификата поддерживается только для хостов, находящихся не в публичном доступе. В этом случае трафик внутри виртуальной сети при подключении к БД шифроваться не будет.
Пример команды с заполненным FQDN хоста вы можете посмотреть в консоли управления, нажав на кнопку Подключиться на странице кластера.
Перед подключением установите утилиту mysql
:
sudo apt update && sudo apt install -y mysql-client
Подключение с использованием SSL-соединения:
mysql --host=<FQDN хоста MySQL> \
--port=3306 \
--ssl-ca=~/.mysql/root.crt \
--ssl-mode=VERIFY_IDENTITY \
--user=<имя пользователя> \
--password \
<имя БД>
Подключение без использования SSL-соединения:
mysql --host=<FQDN хоста MySQL> \
--port=3306 \
--ssl-mode=DISABLED \
--user=<имя пользователя> \
--password \
<имя БД>
После выполнения любой из команд введите пароль пользователя для завершения процедуры подключения.
После подключения к СУБД выполните команду SELECT version();
.
Перед подключением установите зависимости:
sudo apt update && sudo apt install -y python3 python3-pip libmysqlclient-dev && \
pip3 install mysqlclient
Пример кода для подключения с использованием SSL-соединения:
connect.py
import MySQLdb
conn = MySQLdb.connect(
host="<FQDN хоста MySQL>",
port=3306,
db="<имя БД>",
user="<имя пользователя>",
passwd="<пароль пользователя>",
ssl={'ca': '~/.mysql/root.crt'})
cur = conn.cursor()
cur.execute('SELECT version()')
print(cur.fetchone()[0])
conn.close()
Пример кода для подключения без использования SSL-соединения:
connect.py
import MySQLdb
conn = MySQLdb.connect(
host="<FQDN хоста MySQL>",
port=3306,
db="<имя БД>",
user="<имя пользователя>",
passwd="<пароль пользователя>")
cur = conn.cursor()
cur.execute('SELECT version()')
print(cur.fetchone()[0])
conn.close()
Подключение:
python3 connect.py
Перед подключением установите зависимости:
sudo apt update && apt install -y php php-mysql
Пример кода для подключения с использованием SSL-соединения:
connect.php
<?php
$conn = mysqli_init();
$conn->options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true);
$conn->ssl_set(NULL, NULL, '/home/<домашняя директория>/.mysql/root.crt', NULL, NULL);
$conn->real_connect('<FQDN хоста-мастера MySQL>', '<имя пользователя>', '<пароль пользователя>', '<имя БД>', 3306, NULL, MYSQLI_CLIENT_SSL);
$q = $conn->query('SELECT version()');
$result = $q->fetch_row();
echo($result[0]);
$q->close();
$conn->close();
?>
В отличие от других способов подключения, в этом коде необходимо указывать полный путь к сертификату root.crt
для MySQL в методе ssl_set
.
Пример кода для подключения без использования SSL-соединения:
connect.php
<?php
$conn = mysqli_init();
$conn->options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, false);
$conn->real_connect('<FQDN хоста MySQL>', '<имя пользователя>', '<пароль пользователя>', '<имя БД>', 3306, NULL, NULL);
$q = $conn->query('SELECT version()');
$result = $q->fetch_row();
echo($result[0]);
$q->close();
$conn->close();
?>
Подключение:
php connect.php
Перед подключением:
-
Установите зависимости:
sudo apt update && sudo apt install -y default-jdk maven
-
Добавьте SSL-сертификат в хранилище доверенных сертификатов Java (Java Key Store), чтобы драйвер MySQL мог использовать этот сертификат при защищенном подключении к хостам кластера. При этом задайте пароль в параметре
-storepass
для дополнительной защиты хранилища:cd ~/.mysql && \ keytool -importcert -alias YARootCrt -file root.crt \ -keystore YATrustStore -storepass <пароль хранилища сертификатов> \ --noprompt
-
Создайте директорию для проекта Maven:
cd ~/ && mkdir -p project/src/java/com/example && cd project/
-
Создайте конфигурационный файл для Maven:
pom.xml<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>app</artifactId> <packaging>jar</packaging> <version>0.1.0</version> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version> </dependency> </dependencies> <build> <finalName>${project.artifactId}-${project.version}</finalName> <sourceDirectory>src</sourceDirectory> <resources> <resource> <directory>src</directory> </resource> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <executions> <execution> <goals> <goal>attached</goal> </goals> <phase>package</phase> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>com.example.App</mainClass> </manifest> </archive> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.1.0</version> <configuration> <archive> <manifest> <mainClass>com.example.App</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build> </project>
Актуальная версия зависимости для Maven: mysql-connector-java.
Пример кода для подключения с использованием SSL-соединения:
src/java/com/example/App.java
package com.example;
import java.sql.*;
public class App {
public static void main(String[] args) {
String DB_URL = "jdbc:mysql://<FQDN хоста MySQL>:3306/<имя БД>?useSSL=true";
String DB_USER = "<имя пользователя>";
String DB_PASS = "<пароль пользователя>";
System.setProperty("javax.net.ssl.trustStore", "/home/<домашняя директория>/.mysql/YATrustStore");
System.setProperty("javax.net.ssl.trustStorePassword", "<пароль хранилища сертификатов>");
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
ResultSet q = conn.createStatement().executeQuery("SELECT version()");
if(q.next()) {System.out.println(q.getString(1));}
conn.close();
}
catch(Exception ex) {ex.printStackTrace();}
}
}
В этом коде необходимо указывать полный путь к хранилищу сертификатов YATrustStore
для драйвера MySQL в свойстве javax.net.ssl.trustStore
.
Пример кода для подключения без использования SSL-соединения:
src/java/com/example/App.java
package com.example;
import java.sql.*;
public class App {
public static void main(String[] args) {
String DB_URL = "jdbc:mysql://<FQDN хоста MySQL>:3306/<имя БД>?useSSL=false";
String DB_USER = "<имя пользователя>";
String DB_PASS = "<пароль пользователя>";
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
ResultSet q = conn.createStatement().executeQuery("SELECT version()");
if(q.next()) {System.out.println(q.getString(1));}
conn.close();
}
catch(Exception ex) {ex.printStackTrace();}
}
}
Подключение:
mvn clean package && \
java -jar target/app-0.1.0-jar-with-dependencies.jar
Перед подключением установите зависимости:
sudo apt update && sudo apt install -y nodejs npm && \
npm install mysql2
Пример кода для подключения с использованием SSL-соединения:
app.js
"use strict"
const fs = require('fs');
const mysql = require('mysql2');
const config = {
host : '<FQDN хоста MySQL>',
port : 3306,
user : '<имя пользователя>',
password : '<пароль пользователя>',
database : '<имя БД>',
ssl: {
rejectUnauthorized: true,
ca: fs.readFileSync('/home/<домашняя директория>/.mysql/root.crt').toString(),
},
}
const conn = mysql.createConnection(config)
conn.connect(err => {if (err) throw err})
conn.query('SELECT version()', (err, result, fields) => {
if (err) throw err
console.log(result[0])
conn.end()
})
В отличие от других способов подключения, в этом коде необходимо указывать полный путь к сертификату root.crt
для MySQL в переменной ca
.
Пример кода для подключения без использования SSL-соединения:
app.js
"use strict"
const mysql = require('mysql2');
const config = {
host : '<FQDN хоста MySQL>',
port : 3306,
user : '<имя пользователя>',
password : '<пароль пользователя>',
database : '<имя БД>',
}
const conn = mysql.createConnection(config)
conn.connect(err => {if (err) throw err})
conn.query('SELECT version()', (err, result, fields) => {
if (err) throw err
console.log(result[0])
conn.end()
})
Подключение:
node app.js
Перед подключением установите зависимости:
sudo apt update && sudo apt install -y golang git && \
go get github.com/go-sql-driver/mysql
Пример кода для подключения с использованием SSL-соединения:
connect.go
package main
import (
"io/ioutil"
"crypto/tls"
"crypto/x509"
"database/sql"
"fmt"
"github.com/go-sql-driver/mysql"
)
const (
host = "<FQDN хоста MySQL>"
port = 3306
user = "<имя пользователя>"
password = "<пароль пользователя>"
dbname = "<имя БД>"
)
func main() {
rootCertPool := x509.NewCertPool()
pem, err := ioutil.ReadFile("/home/<домашняя директория>/.mysql/root.crt")
if err != nil {
panic(err)
}
if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
panic("Failed to append PEM.")
}
mysql.RegisterTLSConfig("custom", &tls.Config{
RootCAs: rootCertPool,
})
mysqlInfo := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=custom",
user, password, host, port, dbname)
conn, err := sql.Open("mysql", mysqlInfo)
if err != nil {
panic(err)
}
defer conn.Close()
q, err := conn.Query("SELECT version()")
if err != nil {
panic(err)
}
var result string
for q.Next() {
q.Scan(&result)
fmt.Println(result)
}
}
В отличие от других способов подключения, в этом коде необходимо указывать полный путь к сертификату root.crt
для MySQL в переменной ca
.
Пример кода для подключения без использования SSL-соединения:
connect.go
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
const (
host = "<FQDN хоста MySQL>"
port = 3306
user = "<имя пользователя>"
password = "<пароль пользователя>"
dbname = "<имя БД>"
)
func main() {
mysqlInfo := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s",
user, password, host, port, dbname)
conn, err := sql.Open("mysql", mysqlInfo)
if err != nil {
panic(err)
}
defer conn.Close()
q, err := conn.Query("SELECT version()")
if err != nil {
panic(err)
}
var result string
for q.Next() {
q.Scan(&result)
fmt.Println(result)
}
}
Подключение:
go run connect.go
Перед подключением установите зависимости:
sudo apt update && sudo apt install -y ruby ruby-mysql2
Пример кода для подключения с использованием SSL-соединения:
connect.rb
require "mysql2"
conn = Mysql2::Client.new(
:host => "<FQDN хоста MySQL>",
:port => 3306,
:database => "<имя БД>",
:username => "<имя пользователя>",
:password => "<пароль пользователя>",
:ssl_mode => "verify_identity",
:sslca => "~/.mysql/root.crt")
q = conn.query("SELECT version()")
q.each do |result|
puts result["version()"]
end
conn.close()
Пример кода для подключения без использования SSL-соединения:
connect.rb
require "mysql2"
conn = Mysql2::Client.new(
:host => "<FQDN хоста MySQL>",
:port => 3306,
:database => "<имя БД>",
:username => "<имя пользователя>",
:password => "<пароль пользователя>")
q = conn.query("SELECT version()")
q.each do |result|
puts result["version()"]
end
conn.close()
Подключение:
ruby connect.rb
Перед подключением установите зависимости:
sudo apt update && sudo apt install -y unixodbc && \
wget https://dev.mysql.com/get/Downloads/Connector-ODBC/8.0/mysql-connector-odbc_8.0.21-1ubuntu20.04_amd64.deb && \
sudo dpkg -i mysql-connector-odbc_8.0.21-1ubuntu20.04_amd64.deb
Драйвер MySQL Connector/ODBC будет автоматически зарегистрирован в файле /etc/odbcinst.ini
. Актуальная версия драйвера: mysql-connector-odbc.
Пример настроек в файле /etc/odbc.ini
для подключения с использованием SSL-соединения:
odbc.ini
[mysql]
Driver=MySQL ODBC 8.0 Unicode Driver
SERVER=<FQDN хоста MySQL>
UID=<имя пользователя>
PWD=<пароль пользователя>
DATABASE=<имя БД>
PORT=3306
SSLCA=/home/<домашняя директория>/.mysql/root.crt
SSLVERIFY=1
В отличие от других способов подключения, в этом файле необходимо указывать полный путь к сертификату root.crt
для MySQL в параметре SSLCA
.
Пример настроек в файле /etc/odbc.ini
для подключения без использования SSL-соединения:
odbc.ini
[mysql]
Driver=MySQL ODBC 8.0 Unicode Driver
SERVER=<FQDN хоста MySQL>
UID=<имя пользователя>
PWD=<пароль пользователя>
DATABASE=<имя БД>
PORT=3306
Подключение:
isql -v mysql
После подключения к СУБД выполните команду SELECT version();
.
При успешном подключении к кластеру и выполнении тестового запроса будет выведена версия MySQL.
Подключение к мастеру
На текущий мастер в кластере всегда указывает хост вида c-<идентификатор кластера>.rw.mdb.yandexcloud.net
. Например, для кластера с идентификатором c9qash3nb1v9ulc8j9nm
к мастеру можно подключиться так:
mysql --host=c-c9qash3nb1v9ulc8j9nm.rw.mdb.yandexcloud.net
--port=3306
--ssl-ca=~/.mysql/root.crt
--ssl-mode=REQUIRED
--user=<имя пользователя базы данных>
--password <имя базы данных>