sql >> データベース >  >> RDS >> MariaDB

Puppetを使用したデータベース自動化:MySQLとMariaDBレプリケーションのデプロイ

    Puppetは、構成管理を一元化および自動化するためのオープンソースシステム管理ツールです。自動化ツールは、手動および反復的なタスクを最小限に抑えるのに役立ち、時間を大幅に節約できます。

    Puppetは、サーバー/エージェントモデルでデフォルトで機能します。エージェントは、マスターから「カタログ」(最終的に望ましい状態)をフェッチし、ローカルに適用します。次に、サーバーに報告します。カタログは、マシンがサーバーに送信する「ファクト」、ユーザー入力(パラメーター)、およびモジュール(ソースコード)に基づいて計算されます。

    このブログでは、Puppetを介してMySQL/MariaDBインスタンスをデプロイおよび管理する方法を紹介します。 MySQL / MariaDBには、レプリケーション(マスタースレーブ、Galera、またはMySQLのグループレプリケーション)、ProxySQLやMariaDB MaxScaleなどのSQL対応ロードバランサー、バックアップおよびリカバリツールなど、多数のテクノロジーがあります。ブログシリーズ。コミュニティによって構築および保守されているPuppetForgeには、コードを簡素化し、車輪の再発明を回避するのに役立つ多くのモジュールもあります。このブログでは、MySQLレプリケーションに焦点を当てます。

    puppetlabs / mysql

    これは、MySQLおよびMariaDBで最も人気のあるPuppetモジュールです(おそらく市場で最高です)。このモジュールは、MySQLのインストールと構成の両方を管理し、データベース、ユーザー、助成金などのMySQLリソースを管理できるようにPuppetを拡張します。

    モジュールはPuppetチームによって(puppetlabs Githubリポジトリを介して)公式に保守されており、RedHat、Ubuntu、Puppet Enterprise 2019.1.x、2019.0.x、2018.1.x、Puppet> =5.5.10<7.0.0のすべてのメジャーバージョンをサポートしています。 Debian、SLES、Scientific、CentOS、OracleLinuxプラットフォーム。ユーザーは、パッケージリポジトリをカスタマイズして、MySQL、MariaDB、およびPerconaServerをインストールするオプションがあります

    次の例は、MySQLサーバーをデプロイする方法を示しています。 puppetマスターにMySQLモジュールをインストールし、マニフェストファイルを作成します。

    (puppet-master)$ puppet module install puppetlabs/mysql
    (puppet-master)$ vim /etc/puppetlabs/code/environments/production/manifests/mysql.pp

    次の行を追加します:

    node "db1.local" {
      class { '::mysql::server':
        root_password => 't5[sb^D[+rt8bBYu',
        remove_default_accounts => true,
        override_options => {
          'mysqld' => {
            'log_error' => '/var/log/mysql.log',
            'innodb_buffer_pool_size' => '512M'
          }
          'mysqld_safe' => {
            'log_error' => '/var/log/mysql.log'
          }
        }
      }
    }

    次に、パペットエージェントノードで、次のコマンドを実行して構成カタログを適用します。

    (db1.local)$ puppet agent -t

    最初の実行時に、次のエラーが発生する可能性があります:

    Info: Certificate for db1.local has not been signed yet

    Puppetマスターで次のコマンドを実行して、証明書に署名するだけです。

    (puppet-master)$ puppetserver ca sign --certname=db1.local
    Successfully signed certificate request for db1.local

    「puppetagent-t」コマンドを使用して再試行し、署名付き証明書との接続を再開します。

    上記の定義により、OSディストリビューションリポジトリで利用可能な標準のMySQL関連パッケージがインストールされます。たとえば、Ubuntu 18.04(Bionic)では、MySQL5.7.26パッケージがインストールされます。

    (db1.local) $ dpkg --list | grep -i mysql
    ii  mysql-client-5.7                5.7.26-0ubuntu0.18.04.1           amd64        MySQL database client binaries
    ii  mysql-client-core-5.7           5.7.26-0ubuntu0.18.04.1           amd64        MySQL database core client binaries
    ii  mysql-common                    5.8+1.0.4                         all          MySQL database common files, e.g. /etc/mysql/my.cnf
    ii  mysql-server                    5.7.26-0ubuntu0.18.04.1           all          MySQL database server (metapackage depending on the latest version)
    ii  mysql-server-5.7                5.7.26-0ubuntu0.18.04.1           amd64        MySQL database server binaries and system database setup
    ii  mysql-server-core-5.7           5.7.26-0ubuntu0.18.04.1           amd64        MySQL database server binaries

    Oracle、Percona、MariaDBなど、リポジトリに追加の構成を備えた他のベンダーを選択できます(詳細については、READMEセクションを参照してください)。次の定義は、MariaDB aptリポジトリからMariaDBパッケージをインストールします(apt Puppetモジュールが必要です):

    $ puppet module install puppetlabs/apt
    $ vim /etc/puppetlabs/code/environments/production/manifests/mariadb.pp
    # include puppetlabs/apt module
    include apt
    
    # apt definition for MariaDB 10.3
    apt::source { 'mariadb':
      location => 'http://sgp1.mirrors.digitalocean.com/mariadb/repo/10.3/ubuntu/',
      release  => $::lsbdistcodename,
      repos    => 'main',
      key      => {
        id     => 'A6E773A1812E4B8FD94024AAC0F47944DE8F6914',
        server => 'hkp://keyserver.ubuntu.com:80',
      },
      include => {
        src   => false,
        deb   => true,
      },
    }
    
    # MariaDB configuration
    class {'::mysql::server':
      package_name     => 'mariadb-server',
      service_name     => 'mysql',
      root_password    => 't5[sb^D[+rt8bBYu',
      override_options => {
        mysqld => {
          'log-error' => '/var/log/mysql/mariadb.log',
          'pid-file'  => '/var/run/mysqld/mysqld.pid',
        },
        mysqld_safe => {
          'log-error' => '/var/log/mysql/mariadb.log',
        },
      }
    }
    
    # Deploy on db2.local
    node "db2.local" {
    Apt::Source['mariadb'] ->
    Class['apt::update'] ->
    Class['::mysql::server']
    }

    key-> id値に注意してください。この記事に示すように、40文字のIDを取得する特別な方法があります:

    $ sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
    $ apt-key adv --list-public-keys --with-fingerprint --with-colons
    uid:-::::1459359915::6DC53DD92B7A8C298D5E54F950371E2B8950D2F2::MariaDB Signing Key <[email protected]>::::::::::0:
    sub:-:4096:1:C0F47944DE8F6914:1459359915::::::e::::::23:
    fpr:::::::::A6E773A1812E4B8FD94024AAC0F47944DE8F6914:

    id値が「fpr」で始まる行にある場合、これは「A6E773A1812E4B8FD94024AAC0F47944DE8F6914」です。

    Puppetカタログが適用された後、モジュールが〜/ .my.cnfを自動的に構成および管理するため、明示的なパスワードなしでrootとしてMySQLコンソールに直接アクセスできます。ルートパスワードを別のパスワードにリセットする場合は、Puppet定義のroot_password値を変更し、エージェントノードにカタログを適用するだけです。

    MySQLレプリケーションの展開

    MySQLレプリケーションのセットアップを展開するには、マスター構成とスレーブ構成を分離するために、少なくとも2つのタイプの構成を作成する必要があります。マスターは読み取り/書き込みを許可するために読み取り専用を無効にし、スレーブは読み取り専用を有効にして構成します。この例では、GTIDベースのレプリケーションを使用して構成を簡素化します(すべてのノードの構成が非常に似ているため)。スレーブが起動した直後にマスターへのレプリケーションリンクを開始する必要があります。

    3つのノードのMySQLマスタースレーブレプリケーションがあると仮定します:

    • db1.local-マスター
    • db2.local-スレーブ#1
    • db3.local-スレーブ#2

    上記の要件を満たすために、マニフェストを次のように書き留めることができます。

    # Puppet manifest for MySQL GTID-based replication MySQL 5.7 on Ubuntu 18.04 (Puppet v6.4.2) 
    # /etc/puppetlabs/code/environments/production/manifests/replication.pp
    
    # node's configuration
    class mysql {
      class {'::mysql::server':
        root_password           => '[email protected]#',
        create_root_my_cnf      => true,
        remove_default_accounts => true,
        manage_config_file      => true,
        override_options        => {
          'mysqld' => {
            'datadir'                 => '/var/lib/mysql',
            'bind_address'            => '0.0.0.0',
            'server-id'               => $mysql_server_id,
            'read_only'               => $mysql_read_only,
            'gtid-mode'               => 'ON',
            'enforce_gtid_consistency'=> 'ON',
            'log-slave-updates'       => 'ON',
            'sync_binlog'             => 1,
            'log-bin'                 => '/var/log/mysql-bin',
            'read_only'               => 'OFF',
            'binlog-format'           => 'ROW',
            'log-error'               => '/var/log/mysql/error.log',
            'report_host'             => ${fqdn},
            'innodb_buffer_pool_size' => '512M'
          },
          'mysqld_safe' => {
            'log-error'               => '/var/log/mysql/error.log'
          }
        }
      }
      
      # create slave user
      mysql_user { "${slave_user}@192.168.0.%":
          ensure        => 'present',
          password_hash => mysql_password("${slave_password}")
      }
    
      # grant privileges for slave user
      mysql_grant { "${slave_user}@192.168.0.%/*.*":
          ensure        => 'present',
          privileges    => ['REPLICATION SLAVE'],
          table         => '*.*',
          user          => "${slave_user}@192.168.0.%"
      }
    
      # /etc/hosts definition
      host {
        'db1.local': ip => '192.168.0.161';
        'db2.local': ip => '192.169.0.162';
        'db3.local': ip => '192.168.0.163';
      }
    
      # executes change master only if $master_host is defined
      if $master_host {
        exec { 'change master':
          path    => '/usr/bin:/usr/sbin:/bin',
          command => "mysql --defaults-extra-file=/root/.my.cnf -e \"CHANGE MASTER TO MASTER_HOST = '$master_host', MASTER_USER = '$slave_user', MASTER_PASSWORD = '$slave_password', MASTER_AUTO_POSITION = 1; START SLAVE;\"",
          unless  => "mysql --defaults-extra-file=/root/.my.cnf -e 'SHOW SLAVE STATUS\G' | grep 'Slave_SQL_Running: Yes'"
        }
      }
    }
    
    ## node assignment
    
    # global vars
    $master_host = undef
    $slave_user = 'slave'
    $slave_password = 'Replicas123'
    
    # master
    node "db1.local" {
      $mysql_server_id = '1'
      $mysql_read_only = 'OFF'
      include mysql
    }
    
    # slave1
    node "db2.local" {
      $mysql_server_id = '2'
      $mysql_read_only = 'ON'
      $master_host = 'db1.local'
      include mysql
    }
    
    # slave2
    node "db3.local" {
      $mysql_server_id = '3'
      $mysql_read_only = 'ON'
      $master_host = 'db1.local'
      include mysql
    }

    エージェントにカタログの適用を強制します:

    (all-mysql-nodes)$ puppet agent -t

    マスター(db1.local)では、接続されているすべてのスレーブを確認できます。

    mysql> SHOW SLAVE HOSTS;
    +-----------+-----------+------+-----------+--------------------------------------+
    | Server_id | Host      | Port | Master_id | Slave_UUID                           |
    +-----------+-----------+------+-----------+--------------------------------------+
    |         3 | db3.local | 3306 |         1 | 2d0b14b6-8174-11e9-8bac-0273c38be33b |
    |         2 | db2.local | 3306 |         1 | a9dfa4c7-8172-11e9-8000-0273c38be33b |
    +-----------+-----------+------+-----------+--------------------------------------+

    「exec{'changemaster':」セクションに特に注意してください。これは、条件が満たされた場合にMySQLコマンドが実行されてレプリケーションリンクが開始されることを意味します。 Puppetによって実行されるすべての「exec」リソースはべき等である必要があります。つまり、1回実行しても10,001回実行しても同じ効果を持つ操作です。正しい状態を保護し、Puppetがセットアップを台無しにするのを防ぐために、「unless」、「onlyif」、「create」など、使用できる条件属性がいくつかあります。レプリケーションリンクを手動で開始する場合は、そのセクションを削除/コメントすることができます。

    MySQL管理

    このモジュールは、いくつかのMySQL管理タスクを実行するために使用できます。

    • 構成オプション(変更、適用、カスタム構成)
    • データベースリソース(データベース、ユーザー、助成金)
    • バックアップ(作成、スケジュール、ユーザーのバックアップ、ストレージ)
    • 単純な復元(mysqldumpのみ)
    • プラグインのインストール/アクティベーション

    データベースリソース

    上記のマニフェストの例でわかるように、2つのMySQLリソース(mysql_userとmysql_grant)を定義して、それぞれユーザーを作成し、ユーザーに特権を付与しています。 mysql ::dbクラスを使用して、関連付けられたユーザーと権限を持つデータベースが存在することを確認することもできます。例:

      # make sure the database and user exist with proper grant
      mysql::db { 'mynewdb':
        user          => 'mynewuser',
        password      => 'passw0rd',
        host          => '192.168.0.%',
        grant         => ['SELECT', 'UPDATE']
      } 

    MySQLレプリケーションでは、すべての書き込みはマスターでのみ実行する必要があることに注意してください。したがって、上記のリソースがマスターに割り当てられていることを確認してください。そうしないと、誤った取引が発生する可能性があります。

    バックアップと復元

    通常、クラスター全体に必要なバックアップホストは1つだけです(データのサブセットを複製する場合を除く)。 mysql ::server ::backupクラスを使用して、バックアップリソースを準備できます。マニフェストに次の宣言があるとします。

      # Prepare the backup script, /usr/local/sbin/mysqlbackup.sh
      class { 'mysql::server::backup':
        backupuser     => 'backup',
        backuppassword => 'passw0rd',
        backupdir      => '/home/backup',
        backupdirowner => 'mysql',
        backupdirgroup => 'mysql',
        backupdirmode  => '755',
        backuprotate   => 15,
        time           => ['23','30'],   #backup starts at 11:30PM everyday
        include_routines  => true,
        include_triggers  => true,
        ignore_events     => false,
        maxallowedpacket  => '64M',
        optional_args     => ['--set-gtid-purged=OFF'] #extra argument if GTID is enabled
      }

    Puppetは、バックアップを実行する前にすべての前提条件を構成します-バックアップユーザーの作成、宛先パスの準備、所有権と権限の割り当て、cronジョブの設定、および/ usr/localにある提供されたバックアップスクリプトで使用するバックアップコマンドオプションの設定/sbin/mysqlbackup.sh。その後、スクリプトを実行またはスケジュールするのはユーザーの責任です。すぐにバックアップを作成するには、次を呼び出すだけです。

    $ mysqlbackup.sh

    上記に基づいて実際のmysqldumpコマンドを抽出すると、次のようになります。

    $ mysqldump --defaults-extra-file=/tmp/backup.NYg0TR --opt --flush-logs --single-transaction --events --set-gtid-purged=OFF --all-databases

    Percona Xtrabackup、MariaDB Backup(MariaDBのみ)、MySQL Enterprise Backupなどの他のバックアップツールを使用したい場合、モジュールは次のプライベートクラスを提供します。

    • mysql ::backup ::xtrabackup(PerconaXtrabackupおよびMariaDBBackup)
    • mysql ::backup ::mysqlbackup(MySQL Enterprise Backup)

    Percona Xtrabackupを使用した宣言の例:

      class { 'mysql::backup::xtrabackup':
        xtrabackup_package_name => 'percona-xtrabackup',
        backupuser     => 'xtrabackup',
        backuppassword => 'passw0rd',
        backupdir      => '/home/xtrabackup',
        backupdirowner => 'mysql',
        backupdirgroup => 'mysql',
        backupdirmode  => '755',
        backupcompress => true,
        backuprotate   => 15,
        include_routines  => true,
        time              => ['23','30'], #backup starts at 11:30PM
        include_triggers  => true,
        maxallowedpacket  => '64M',
        incremental_backups => true
      }

    上記のマニフェストが適用された後のcronジョブ出力に示されているように、上記は2つのバックアップをスケジュールします。1つは毎週日曜日の午後11時30分に完全バックアップ、もう1つは日曜日を除く毎日の増分バックアップです。

    (db1.local)$ crontab -l
    # Puppet Name: xtrabackup-weekly
    30 23 * * 0 /usr/local/sbin/xtrabackup.sh --target-dir=/home/backup/mysql/xtrabackup --backup
    # Puppet Name: xtrabackup-daily
    30 23 * * 1-6 /usr/local/sbin/xtrabackup.sh --incremental-basedir=/home/backup/mysql/xtrabackup --target-dir=/home/backup/mysql/xtrabackup/`date +%F_%H-%M-%S` --backup

    このクラス(および他のクラス)で利用できる詳細とオプションについては、こちらのオプションリファレンスをご覧ください。

    復元の側面では、モジュールはmysql::dbクラスを使用してSQLファイルをデータベースに直接インポートすることにより、mysqldumpバックアップメソッドを使用した復元のみをサポートします。例:

    mysql::db { 'mydb':
      user     => 'myuser',
      password => 'mypass',
      host     => 'localhost',
      grant    => ['ALL PRIVILEGES'],
      sql      => '/home/backup/mysql/mydb/backup.gz',
      import_cat_cmd => 'zcat',
      import_timeout => 900
    }

    SQLファイルは、enforce_sql => trueが使用されていない限り、実行ごとではなく1回だけロードされます。

    構成オプション

    この例では、manage_config_file => trueとoverride_optionsを使用して、後でPuppetによってプッシュされる構成行を構造化しました。マニフェストファイルへの変更は、ターゲットのMySQL構成ファイルの内容のみを反映します。このモジュールは、構成をランタイムにロードせず、変更を構成ファイルにプッシュした後にMySQLサービスを再起動しません。変更をアクティブ化するためにサービスを再起動するのは、システム管理者の責任です。

    カスタムMySQL構成を追加するために、追加のファイルを「includedir」(デフォルトは/etc/mysql/conf.d)に配置できます。これにより、設定を上書きしたり、設定を追加したりできます。これは、mysql::serverクラスでoverride_optionsを使用しない場合に役立ちます。ここでは、Puppetテンプレートを使用することを強くお勧めします。カスタム構成ファイルをモジュールテンプレートディレクトリ(デフォルトは/ etc / puppetlabs / code / environment / product / modules / mysql / templates)に配置し、マニフェストに次の行を追加します。

    # Loads /etc/puppetlabs/code/environments/production/modules/mysql/templates/my-custom-config.cnf.erb into /etc/mysql/conf.d/my-custom-config.cnf
    
    file { '/etc/mysql/conf.d/my-custom-config.cnf':
      ensure  => file,
      content => template('mysql/my-custom-config.cnf.erb')
    }

    バージョン固有のパラメータを実装するには、バージョンディレクティブ([mysqld-5.5]など)を使用します。これにより、MySQLの異なるバージョンに対して1つの構成が可能になります。

    Puppet vs ClusterControl

    ClusterControlを使用してMySQLまたはMariaDBレプリケーションのデプロイを自動化することもできることをご存知ですか? ClusterControl Puppetモジュールを使用してインストールするか、当社のWebサイトからダウンロードするだけです。

    ClusterControlと比較すると、次の違いが予想されます。

    • マニフェストを作成する前に、Puppetの構文、フォーマット、構造を理解するための少しの学習曲線。
    • マニフェストは定期的にテストする必要があります。特にカタログを初めて適用する場合は、コードでコンパイルエラーが発生することがよくあります。
    • Puppetは、コードがべき等であると想定しています。テスト/チェック/検証の条件は、実行中のシステムを台無しにしないようにする作成者の責任になります。
    • Puppetには管理対象ノードにエージェントが必要です。
    • 後方互換性。一部の古いモジュールは、新しいバージョンでは正しく実行されませんでした。
    • データベース/ホストの監視は個別に設定する必要があります。

    ClusterControlのデプロイメントウィザードは、デプロイメントプロセスをガイドします:

    または、「s9s」と呼ばれるClusterControlコマンドラインインターフェイスを使用して、同様の結果を得ることができます。次のコマンドは、3ノードのMySQLレプリケーションクラスターを作成します(すべてのノードにパスワードなしで事前に構成されている場合):

    $ s9s cluster --create \
      --cluster-type=mysqlreplication \
          --nodes=192.168.0.41?master;192.168.0.42?slave;192.168.0.43?slave;192.168.0.44?master; \
      --vendor=oracle \
      --cluster-name='MySQL Replication 8.0' \
      --provider-version=8.0 \
      --db-admin='root' \
      --db-admin-passwd='$ecR3t^word' \
      --log
    関連リソースClusterControlのPuppetモジュール-既存のデータベースクラスターへの管理と監視の追加s9sCLIとChefを使用してMySQLGaleraクラスターのデプロイを自動化する方法eコマースのデータベースインフラストラクチャ自動化に関するDevOpsガイド-リプレイとスライド

    次のMySQL/MariaDBレプリケーション設定がサポートされています。

    • マスタースレーブレプリケーション(ファイル/位置ベース)
    • GTID(MySQL / Percona)を使用したマスタースレーブレプリケーション
    • MariaDBGTIDを使用したマスタースレーブレプリケーション
    • マスター-マスターレプリケーション(半同期/非同期)
    • マスター/スレーブチェーンレプリケーション(半同期/非同期)

    展開後、ノード/クラスターは、自動障害検出、マスターフェイルオーバー、スレーブプロモーション、自動リカバリ、バックアップ管理、構成管理などを含め、ClusterControlによって監視および完全に管理できます。これらはすべて1つの製品にまとめられています。コミュニティエディション(永久に無料です!)は、展開と監視を提供します。平均して、データベースクラスターは30分以内に稼働します。必要なのは、ターゲットノードへのパスワードなしのSSHだけです。

    次のパートでは、同じPuppetモジュールを使用したGaleraClusterのデプロイについて説明します。しばらくお待ちください!


    1. ユーザーアカウントの管理、役割、権限、認証PHPおよびMySQL-パート5

    2. SQLServerデータベースからのすべてのデータをスクリプト化する

    3. 動的ファイル名でコピー

    4. SQLを使用して例外のあるORDERBY句を作成する方法