Ansibleは、最もよく知られ、広く使用されているIT自動化ツールの1つであり、次のようなIT運用タスクの自動化に役立ちます...
- ホスト(VMまたはベアメタルマシン)を最初からブートストラップする
- ホストとサービスの構成
- ソフトウェアの展開とアップグレードの管理
- Ansibleは、パブリッククラウド(AWS、GCP、Azure)上のアプリケーション用に一連のEC2およびRDSインスタンスを作成するなど、クラウドインフラストラクチャの調整もサポートしています。クラウドプロビジョニングの詳細については、こちらをご覧ください
このブログは主にAnsibleを使用したPostgreSQLの管理に関するものであるため、Ansibleの使用法の詳細については説明しませんが、Ansibleの基本について説明します。詳細については、Ansibleドキュメントのリンクを参照することをお勧めします。
Ansibleの基本
AnsibleはPythonで記述されたオープンソースプロジェクトであり、そのソースコードはGitHubで入手できます。 Pythonパッケージなので、pipを使用してAnsibleを簡単にインストールできます。
Ansibleは、Ansibleコマンド(Ansible、Ansible-playbook)を使用して運用タスクを調整する1つのホストにのみインストールする必要があります。このオーケストレーションホストをコントロールノードと呼びます。
Ansibleコマンドは、OpenSSHライブラリを使用して、運用タスクを実行するためにターゲットホストにログインします。これらのターゲットホストを管理対象ノードと呼びます。管理対象ノードのホスト名またはIPは、インベントリと呼ばれるファイルに記載されています。このインベントリファイル名は、Ansibleコマンドへの入力として指定されます。
インベントリファイルでは、1つのグループの下に複数のホストを一覧表示できます。これにより、異なるホストに対して同じタスクを複数回繰り返す必要がなくなります。インベントリファイルの使用法の詳細については、こちらをご覧ください。
AnsibleコマンドはSSHを使用してログインするため、すべてのホストにAnsibleをインストールする必要はなく、コントロールノードにインストールするだけで済みます。ただし、すべてのコントロールノードとマネージドノードには、Pythonと必要なPythonライブラリがインストールされている必要があります。 Ansibleのインストールの詳細については、こちらをご覧ください。
デモでは、ラップトップを制御ノードとして使用し、ゲストCentOS-7VMを管理対象ノードとして使用します。 CentOS-7 VMは、プロバイダーVirtualBoxでVagrantを使用してプロビジョニングされました。
コントロールノードへのAnsibleのインストール
Ansibleドキュメントページで参照されているように、pipを使用してAnsibleをインストールします。次のコマンドは「Ansible」ユーザーとして実行されました。
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python get-pip.py --user
--userオプションを使用すると、pipコマンドとAnsibleコマンドがHOMEディレクトリにインストールされるようになり、PATH環境変数にbinパスを追加する必要があります。
$ echo 'export PATH=$HOME/Library/Python/2.7/bin:$PATH' >> ~/.bash_profile
$ source ~/.bash_profile
次のpipコマンドは、Ansibleバージョン2.8.0(このブログを書いている時点での最新の安定バージョンです)をインストールしています。
$ pip install --user ansible
$ which ansible
/Users/Ansible/Library/Python/2.7/bin/Ansible
$ ansible --version
Ansible 2.8.0
...
...
制御ノードと管理対象ノードの事前チェック
制御ノードと管理対象ノードの間に適切なネットワーク接続があることを確認してください。
SSHポートでのインバウンド接続とアウトバウンド接続をブロックする可能性のあるルールがないかファイアウォールを確認します。ブロックしている場合は、SSHポートを開いて、制御ノードと管理対象ノードの両方にアクセスできるようにします。
まず、SSH経由で管理対象ノードに接続してみます。コントロールノードから管理対象ノードにログインできるはずです。
組織のセキュリティポリシーに従って、管理対象ノードへのパスワードなしのSSHアクセスを設定できます。このデモでは、ユーザー「vagrant」の管理対象ノード「pg01」(CentOS-7)へのSSH用にパスワードなしで構成しました。これにより、管理対象ノードにsudoパワーが与えられ、インストールおよびホスト構成タスクのほとんどは、「sudo」を使用する「vagrant」ユーザーとして実行されます。
制御ノードには、Ansibleコマンドで使用される構成ファイルansible.cfgがあります。以下は、構成ファイルで定義されているいくつかの構成オプションです。利用可能な他の構成オプションの詳細については、サンプル構成ファイルを確認してください。
- remote_port-管理対象ノードのSSHサーバーがデフォルトのポート22以外の別のポートで実行されている場合は、変更できます
- remote_user-タスクを実行するためにAnsibleが管理対象ノードに接続するために使用するログインユーザー名
- private_key_file-Ansibleがログインするために使用されるSSH秘密鍵
上記の構成はすべての管理対象ノードにグローバルに適用されるため、特定のホストまたはホストグループに異なる構成を設定する場合は、インベントリファイルでそれらを指定できます。この例は、以下の「development.yaml」インベントリファイルで確認できます。
Ansibleドライランの実行
以下に示すように、インベントリファイル「development.yaml」を作成します。
$ pwd
/Users/Ansible/postgres-setup
$ cat development.yaml
all:
hosts:
children:
postgres_clusters:
hosts:
pg01:
vars:
ansible_port: 22
ansible_user: "vagrant"
ansible_private_key_file: "/Users/Ansible/postgres-setup/private_key"
上記のインベントリファイルでは、ホストpg01はホストグループpostgres_clustersのメンバーの1つです。変数ansible_port、ansible_user、およびansible_private_key_fileは、グループpostgres_clustersの下のホストにのみ適用されます。
次に、Ansibleが管理対象ノードでタスクを実行できるかどうかを確認します。以下の例では、ansibleコマンドが管理対象ノードpg01でモジュールpingを実行します。Ansibleがモジュールpingを実行できた場合は、応答としてSUCCESSが表示されます。
$ ansible -i development.yaml -m ping pg01
pg01 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
管理対象ノードでAnsibleを最初のタスクとして実行すると、ホスト名、IPアドレス、管理対象ノードのメモリなどの情報が収集されます。これらを確認するために、大きなJSONを返すモジュールセットアップを呼び出すことができます。 Ansibleプレイブックでこれらのいずれかを利用できます。
$ ansible -i development.yaml -m setup pg01
pg01 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.100.4",
"10.0.2.15"
],
"ansible_all_ipv6_addresses": [
"fe80::a00:27ff:fe29:ac89",
"fe80::5054:ff:fe26:1060"
],
Ansible Role
Ansible Roleは、特定のホストまたはホストグループに役割を割り当てるだけで、関連するタスクと構成設定の特定のセットを1つのユニットにバンドルする方法です。 Ansibleは、関連するすべての構成とタスクを適用します。これにより、異なるホストまたはホストグループごとにタスクを複数回繰り返す必要がなくなります。
各ロールはディレクトリとして表され、ロールディレクトリ内には、デフォルトファイル、ハンドラー、メタ、タスク、テンプレート、テスト、変数などのサブディレクトリがあります。これらのディレクトリの目的はここにあります。
Ansibleコマンドは、デフォルトで、DEFAULT_ROLES_PATHに記載されているパスの下でロールディレクトリを検索します。
$ ansible-config list | grep -A2 '^DEFAULT_ROLES_PATH'
DEFAULT_ROLES_PATH:
default: ~/.Ansible/roles:/usr/share/Ansible/roles:/etc/Ansible/roles
description: Colon separated paths in which Ansible will search for Roles.
Ansible Galaxy
Ansible Galaxyは、コミュニティの人々がAnsibleの役割のGitHubリポジトリを共有するポータルです。銀河ポータルを閲覧して、必要なAnsibleの役割を探すことができます。コマンドansible-galaxyを使用して、ロールをダウンロードして再利用できます。ロールを使用する前に、デフォルト、変数、タスク、テンプレート、ハンドラーのディレクトリにあるすべてのAnsible YAMLファイルを詳しく調べ、ロールがどのように機能するかを確認してください。
PostgreSQLのデプロイでは、作成者のANXSとGitHubリポジトリによって開発された「postgresql」の役割を使用します。
Ansibleロール「anxs.postgresql」のインストール
$ ansible-galaxy install anxs.postgresql
- downloading role 'postgresql', owned by anxs
- downloading role from https://github.com/ANXS/postgresql/archive/v1.10.1.tar.gz
- extracting anxs.postgresql to /Users/ansible/.Ansible/roles/anxs.postgresql
- anxs.postgresql (v1.10.1) was installed successfully
上記のコマンドは、ディレクトリ「/Users/ansible/.Ansible/roles」の下にロールディレクトリ「anxs.postgresql」をインストールします。これはDEFAULT_ROLES_PATH内のディレクトリの1つであり、ansibleコマンドはこのディレクトリで任意のロールを検索します。
Ansible Playbook
Ansible PlaybookはYAMLファイルであり、特定のホストまたはホストグループで実行する必要のあるタスクまたはロールを一覧表示します。プレイブックの開発の詳細を読んだり、ホスト、タスク、ロール、変数などのタグの定義をここで学ぶことができます。
デフォルトでは、すべてのタスクはログインしたansibleユーザーとして実行されます。別のユーザー(または「root」権限)で特定のタスクを実行するために、becomeを利用できます。このコマンドの使用方法はここにあります。
以下のプレイブック(postgres-play.yaml)では、ホストグループ「postgres_clusters」の下にロール「anxs.postgresql」をリストしているため、ロールanxs.postgresqlのすべてのタスクは、グループ内のすべてのホストに対して実行されます。 「postgres_clusters」。
$ cat postgres-play.yaml
---
- hosts: postgres_clusters
become: yes
roles:
- role: anxs.postgresql
なる:yes in YAMLは、DEFAULT_BECOME_METHOD“ sudo”
を使用して、このロールがより高い特権で実行されることを定義しています。$ ansible-config list | grep -A2 '^DEFAULT_BECOME_METHOD'
DEFAULT_BECOME_METHOD:
default: sudo
description: Privilege escalation method to use when `become` is enabled.
このプレイブックはユーザー「浮浪者」として実行され、ユーザーにはすでにsudopowerがプロビジョニングされています。
[[email protected] ~]$ sudo cat /etc/sudoers.d/vagrant
%vagrant ALL=(ALL) NOPASSWD: ALL
データベース管理に関するSevereninesDevOpsガイドオープンソースデータベースを自動化および管理するために知っておくべきことを学ぶ無料でダウンロード Ansibleを使用したPostgreSQLのデプロイ
次に、プレイブック「postgres-play.yaml」を実行します。これにより、すべてのPostgreSQL関連パッケージがインストールされ、デフォルト設定を使用して構成されます。
この例では、Ansibleはpostgresmax_connectionsを100に設定してPostgreSQL9.6をポート5432にインストールします。すべてのデフォルト設定はファイル/Users/ansible/.Ansible/roles/anxs.postgresql/defaults/main.ymlにあります。 。
$ grep -E '^postgresql_(version|port|max_connections):' ~/.Ansible/roles/anxs.postgresql/defaults/main.yml
postgresql_version: 9.6
postgresql_port: 5432
postgresql_max_connections: 100
プレイブックの実行
$ ansible-playbook -i development.yaml postgres-play.yaml
PLAY [postgres_clusters] ***************************************************************************************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************************************************************************************************
ok: [pg01]
...
...
PLAY RECAP *****************************************************************************************************************************************************************************************************
pg01 : ok=21 changed=14 unreachable=0 failed=0 skipped=32 rescued=0 ignored=0
Ansibleがすべてのタスクを実行すると、タスク実行の概要がPLAYRECAPの下に表示されます。
- ok =21、21のタスクが変更なしで実行されました。
- changed =14、14のタスクがホストに変更を加えました。たとえば、postgresのインストール、ディレクトリ、ファイルの作成、postgresの開始などです。
- skipped =32、32のタスクがスキップされました。これは、一部の機能が有効になっていないことが原因である可能性があります。 entOSにインストールしているため、Ubuntu関連のタスクはスキップされました。
PostgreSQLサービスのステータスと構成を確認してください。
[[email protected] ~]$ systemctl status postgresql-9.6
● postgresql-9.6.service - PostgreSQL 9.6 database server
Loaded: loaded (/usr/lib/systemd/system/postgresql-9.6.service; enabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/postgresql-9.6.service.d
└─custom.conf
Active: active (running) since Wed 2019-05-29 07:15:25 UTC; 24min ago
Docs: https://www.postgresql.org/docs/9.6/static/
Process: 7559 ExecStartPre=/usr/pgsql-9.6/bin/postgresql96-check-db-dir /var/lib/pgsql/9.6/data (code=exited, status=0/SUCCESS)
Main PID: 7564 (postmaster)
CGroup: /system.slice/postgresql-9.6.service
├─7564 /usr/pgsql-9.6/bin/postmaster -D /etc/postgresql/9.6/data
├─7567 postgres: checkpointer process
├─7568 postgres: writer process
├─7569 postgres: wal writer process
├─7570 postgres: autovacuum launcher process
└─7571 postgres: stats collector process
[[email protected] ~]$ psql -U postgres
psql (9.6.13)
Type "help" for help.
postgres=# show max_connections ;
max_connections
-----------------
100
(1 row)
postgres=# show statement_timeout ;
statement_timeout
-------------------
(1 row)
postgres=# show log_min_duration_statement ;
log_min_duration_statement
----------------------------
-1
(1 row)
これで、デフォルト構成を使用して管理対象ホスト「pg01」にPostgreSQLがインストールされました。
PostgreSQL構成の変更
次に、カスタム設定を使用してPostgreSQLインスタンスを再構成します。
listen_addresses、max_connections、wal_level、hot_standby、statement_timeout、log_checkpoint、log_lock_waits、log_destination、log_min_duration_statementなどのPostgreSQL設定を変更するために定義された変数のリストを含むcustom.yamlファイルを作成しました(以下を参照)。
$ pwd
/Users/ansible/postgres-setup
$ cat custom.yaml
postgresql_listen_addresses: "*"
postgresql_max_connections: 300
postgresql_wal_level: "hot_standby"
postgresql_hot_standby: "on"
postgresql_statement_timeout: 60000
postgresql_log_lock_waits: "on"
postgresql_log_destination: "csvlog"
postgresql_log_min_duration_statement: 0
このcustom.yamlを使用するようにプレイブックpostgres-play.yamlを変更します。
$ cat postgres-play.yaml
---
- hosts: postgres_clusters
become: yes
vars_files:
- ./custom.yaml
roles:
- role: anxs.postgresql
vars_filesタグを使用して、カスタム構成ファイルcustom.yamlを指定しました。これは、ロールanxs.postgresqlで指定されたデフォルト構成をオーバーライドします。変数の優先順位の詳細については、こちらをご覧ください。
これで、以前に実行したものと同じansible-playbookコマンドを再実行できますが、これにより、PostgreSQLのインストール、構成、ユーザーおよびデータベースの作成などのすべてのタスクが実行されます。このため、-tags
サポートされているタグのリストを知るために、-list-tagsを指定してコマンドを実行できます。
$ ansible-playbook -i development.yaml postgres-play.yaml --list-tags
playbook: postgres-play.yaml
play #1 (postgres_clusters): postgres_clusters TAGS: []
TASK TAGS: [always, postgresql, postgresql-configure, postgresql-databases, postgresql-extensions, postgresql-install, postgresql-monit, postgresql-users]
上記のタグから、postgresql設定を変更するためにpostgresql-configureタグのみを指定します。
$ ansible-playbook -i development.yaml postgres-play.yaml --tags postgresql-configure
PLAY [postgres_clusters] ***************************************************************************************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************************************************************************************************
ok: [pg01]
...
...
TASK [anxs.postgresql : PostgreSQL | Update configuration - pt. 2 (postgresql.conf)] ***************************************************************************************************************************
changed: [pg01]
...
...
TASK [anxs.postgresql : PostgreSQL | Reload all conf files] ****************************************************************************************************************************************************
changed: [pg01]
PLAY RECAP *****************************************************************************************************************************************************************************************************
pg01 : ok=13 changed=2 unreachable=0 failed=0 skipped=6 rescued=0 ignored=0
PLAY RECAPに表示されているように、管理対象ノードpg01に伝播された変更は2つだけです。 1つ目は構成の更新で、2つ目は構成の再読み込みです。
構成の変更が管理対象ノードで有効になっていることを確認します。
postgres=# show listen_addresses ;
listen_addresses
------------------
localhost
(1 row)
postgres=# show max_connections ;
max_connections
-----------------
100
(1 row)
postgres=# show wal_level ;
wal_level
-----------
minimal
(1 row)
postgres=# show hot_standby ;
hot_standby
-------------
off
(1 row)
postgres=# show statement_timeout;
statement_timeout
-------------------
1min
(1 row)
postgres=# show log_lock_waits ;
log_lock_waits
----------------
on
(1 row)
postgres=# show log_destination ;
log_destination
-----------------
csvlog
(1 row)
postgres=# show log_min_duration_statement;
log_min_duration_statement
----------------------------
(1 row)
ご覧のとおり、listen_addresses、max_connections、wal_level、hot_standbyなどの一部の構成変更はまだ有効になっていません。これらの構成変更にはPostgreSQLの再起動が必要であり、ロールanxs.postgresqlはサービス自体をリロードしただけです。
実稼働時間中のPostgreSQLの突然の再起動を回避するために、元の作成者が再起動タスクをロールに追加していない可能性があります。スケジュールされたダウンタイム中に、postgresqlサービスを手動で再起動できます。
[[email protected] ~]$ sudo systemctl restart postgresql-9.6
[[email protected] ~]$ psql -U postgres
psql (9.6.13)
postgres=# show listen_addresses ;
listen_addresses
------------------
(1 row)
postgres=# show max_connections ;
max_connections
-----------------
300
(1 row)
postgres=# show wal_level;
wal_level
-----------
replica
(1 row)
postgres=# show hot_standby;
hot_standby
-------------
on
(1 row)
PostgreSQLユーザーとデータベースの作成
次に、ユーザー「app1」と「app2」、およびユーザー「app1」と「app2」がそれぞれ所有するデータベース「app1_db」と「app2_db」を作成します。
2つの新しい変数postgresql_usersとpostgresql_databaseをcustom.yamlに追加しました。これには、作成する必要のあるユーザーとデータベースのリストがあります。ロールanxs.postgresqlは、Ansibleモジュールpostgresql_usersとpostgresql_dbを使用してユーザーとデータベースを作成します。これらのドキュメントを参照して、変数を追加できます。
$ cat custom.yaml
...
...
postgresql_users:
- name: app1
pass: md5bb0592c05941d14c231da96950c71b60
encrypted: yes
- name: app2
pass: md5bbb1e4d09b64ca54a237727af46cba7c
encrypted: yes
postgresql_databases:
- name: app1_db
owner: app1
- name: app2_db
owner: app2
ここでは、postgresql-usersタグとpostgresql-databasesタグに関連付けられているタスクのみを実行します。
$ ansible-playbook -i development.yaml postgres-play.yaml --tags postgresql-users,postgresql-databases
PLAY [postgres_clusters] ***************************************************************************************************************************************************************************************
...
...
TASK [anxs.postgresql : PostgreSQL | Make sure the PostgreSQL users are present] *******************************************************************************************************************************
changed: [pg01] => (item=None)
changed: [pg01] => (item=None)
changed: [pg01]
...
...
TASK [anxs.postgresql : PostgreSQL | Make sure the PostgreSQL databases are present] ***************************************************************************************************************************
changed: [pg01] => (item={u'owner': u'app1', u'name': u'app1_db'})
changed: [pg01] => (item={u'owner': u'app2', u'name': u'app2_db'})
...
...
PLAY RECAP *****************************************************************************************************************************************************************************************************
pg01 : ok=6 changed=2 unreachable=0 failed=0 skipped=9 rescued=0 ignored=0
ユーザーとデータベースが管理対象ホスト上に作成されていることを確認します。
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
app1 | | {}
app2 | | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
app1_db | app1 | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
app2_db | app2 | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(5 rows)
外部ホストがPostgreSQLサーバーに接続できるようにする
これで、変数postgresql_pg_hba_customをcustom.yamlに追加することで、外部ホストがPostgreSQLサービスに接続できるようになります
$ cat custom.yaml
...
...
postgresql_pg_hba_custom:
- {type: "host", database: "all", user: "all", address: "0.0.0.0/0", method: "md5" }
postgresql-configureでタグ付けされたタスクを実行して、構成を適用します。
$ ansible-playbook -i development.yaml postgres-play.yaml --tags postgresql-configure
コントロールノードからPostgreSQLサーバーに接続できるかどうかを確認します。
$ PGPASSWORD=password psql -h pg01 -U app1 -d app1_db -c 'Select true'
bool
------
(1 row)
結論
このブログでは、PostgreSQLのデプロイと管理にAnsibleを使用するために知っておく必要のある基本事項を説明する必要があります。ただし、ここではPostgreSQLの管理タスクについてのみ説明しました。組織のインフラストラクチャによっては、デフォルト構成のいくつかをオーバーライドし、Ansibleロールにさらにタスクを追加する必要がある場合があります。