はじめに
Rundeckというジョブ管理ソフトウェアを用いて、IaCツールを運用フェーズでの利用促進を図れないか、検証してみます。本検証はAWS環境を用いて行っております。
何か調査や検証事項に不備・誤りがあれば、X(旧Twitter)などで連絡ください。タイトルの右上の鉛筆マークからPull Request形式で直接依頼も行うことができます。
経緯
システムの構築フェーズではAnsibleやTerraformといったIaC関連のツールを利用したものの、運用フェーズでは生かされないことを、しばしば見てきました。品質管理の重要な要素として5W1H思考が求められますが、インフラ運用での変更はアプリケーションのインシデント(更改、障害など)に基づいて受動的に発生することが多く、そのマインドセットが失われてしまうことがあるように感じます。例えば、変更履歴はアプリケーション変更側で管理されるが、その変更内容がインフラ変更に紐づけられていない、あるいはインシデントへの対応を急ぐあまり、個別のサーバソースに無秩序に直接手を加えてしまうといった対応が挙げられます。
インシデントに対して、いかに早急に対応するかということが最優先のミッションになる。それはインフラ運用管理者としての責任感に基づくものであり否定されるものではありませんが、構成管理上は望ましい結果を生み出さないでしょう。
インフラの運用は比較的少人数で数多くのサーバ管理を行っていることは多いです。数百台のサーバを10人に満たない人数で管理していることがあります。そのためインフラ変更は属人化された変更手法が暗黙に承認されている状況が多々あります。いかにサーバソースを直接の編集を防ぐか、実施履歴、変更内容(変更前、変更後ソース)を残すか。アプリケーション運用でも同様のことが言えますが、アプリケーション運用ではCI/CDにより統制された運用が行われているケースが多く見受けられます。
CI/CDではアプリケーションのデプロイ手法を画一されたワークフローに取り込めており、ソースコードを直接編集・置き換えるといったことがご法度であるというマインドセットが形成されているという部分が大きいと考えてられます。
インフラ構築で利用されたIaCツールは仕様書・手順書といったドキュメントベースので引き継いでいるでしょう。これをCI/CDと同じようにワークフローツールを用い変更手法を具現化したものと合わせて引き継ぐことで運用フェーズでの構成管理(品質均一化、構成管理)が向上するのではないかと考えてみました。
ワークフローツールについて、モノリシックなシステムでは、ジョブ管理システムに商用ソフトウェアを採用することは多いです。安定性もあり、運用主管部門が既知のツールで習熟度が高い場面ではすべからく採用となります。ただしジョブ数も少なく、実装するワークフローも単純な構成が予定されている案件においてはもう少しライトな構成の選択肢(つまり、Rundeck)があってよいとも思われます。
Rundeckとは
- PagerDuty, Inc.によって開発されたジョブ管理ソフトウェア
- Javaで動作
- オープンソース版の「Rundeck Community」と、有償のエンタープライズ版の「Rundeck Enterprise」がある
Community版とEnterprise版の違い
https://www.rundeck.com/community-vs-enterprise
この検証では、Community版のRundeckを利用しています。
- Rundeck Community:BUILD:4.17.0-20230925
構成
Rundeckを構築するにあたりいくつかの構成を試してみました。結果としてCommunity版ではあまり意味のない構成も含まれます。
- シングルインスタンス構成
- シングルインスタンス構成 + 外部データベース
- デュアルインスタンス構成 + 外部データベース + ELB
- シングルコンテナ構成 + 外部データベース
- シングルコンテナ構成 + 外部データベース + シングルノード
- 伝統的なクラスタ構成(クラスタウェア+ミラーディスクによるHAクラスタ)
1. シングルインスタンス構成
最も基本的な構成です。
サポートされているサーバOSにJavaとRundeckをインストールすればすぐに利用でき、データベースにH2DB(H2 Database Engine)が組み込まれているようで、手軽に活用できます。
Rundeckのジョブ管理の使用感などを試したいのであれば最も適しています。
2. シングルインスタンス構成 + 外部データベース
シングルインスタンス構成からデータベースのみを外部のRDBに配置したものです。
検証ではEC2上に作成したmariadbを利用しましたがRDSを用いることも可能です。基本構成からデータベースの堅牢性向上を狙ったものです。
3. デュアルインスタンス構成 + 外部データベース + ELB
Rundeckサービスを冗長構成としたものです。
データベースの他、ジョブズクリプトやログも共有する必要があるためS3を利用してます。ログのS3化はプラグインが利用できます。スクリプトに関してはジョブ定義のスクリプトパスをURLで指定できるので、S3にウェブサイトアクセス許可を設定することで可能となります。
結果としてはCommunity版では可用性の向上は計れませんでした。ジョブ実行に関してはジョブ実行指示を行ったサーバを識別(rundeck.server.uuid)していて特定のインスタンスで実行されてしまうようです。Enterprise版ではクラスタ関連機能(High Availability Clusters、Auto Takeover)が利用でき排他的に複数のサーバで実行可能となるようです。
4. シングルコンテナ構成 + 外部データベース
Rundeckはコンテナ環境でも利用可能です。基本構成としてはシングルインスタンス構成と同等です。
コンテナは揮発性であることからデータは外部に配置しております。
コンテナ化によってRundeckそのものの構成管理が容易になります。
5. シングルコンテナ構成 + 外部データベース + ノード
ジョブ実行環境をノードとして登録しジョブを実行させることが可能です。Jenkinsのslaveノードや商用SWのエージェントと同じような利用方法でしょうか。ノードは先に紹介したいずれの構成でも利用可能です。
ジョブの実行環境をRundeckから排除することでRundeck側のSW構成が簡素化できます。RundeckからノードはSSH接続ができればよいです。
6. 伝統的なクラスタ構成(クラスタウェア+ミラーディスクによるHAクラスタ)
商用ジョブ管理ソフトウェアではしばしば用いられる冗長構成です。
Actinve/StandbyのHAクラスタリング方式。パブリッククラウド環境ではストレージミラーリング機能を用いて実装することは一般的だと思います。クラスタソフトウェアが必要になるためRundeck構成が複雑になりがちです。データベースを同居させるか否かでも構成が変わってきます。
構成検証における考察
- 基本構成
- インストールも容易ですぐに利用できます。Rundeckの利用を検討される場合はまずはこれで十分だと思います
- 開発環境やテスト環境などで本番環境のジョブ管理システムが利用できないケースなど、一時的にジョブワークフローを利用したい場合などでの用途もあると考えます
- 利用できるジョブ管理ツールがなく、複数のサーバ上でcronなどを用いて実行している非ミッションクリティカルなジョブを統制管理するために利用するといった用途にもよいかもしれません
- データ保全性を重視する構成
- Rundeckにおいて一定の耐久性(データ保全性)を必要とするのであればデータベースは外部データベース(RDB)を利用するべきでしょう
- Enterprise版にあるクラスタ関連機能が利用できないため可用性の向上は難しいですが、データベースをRDB化することでデータ保全性は大きく向上させることが可能です
- 可用性を重視する場合
- ミッションクリティカルな業務ジョブを想定する場合は、Enterprise版の検討を行うことがよいと考えます。非ミッションクリティカルな運用であっても可用性を高めたい場合はインスタンス/コンテナのAutorecovery機能をを検討することがよいと思います。そのためにRundeckは常にシンプルな構成を維持する(データ外出し)ことが望まれます
- 非推奨な構成
- 伝統的なHAクラスタアーキテクチャはActive/Standby構成であることが多く、その場合はサーバサイジングを負荷ピークで考えるためオーバースペックが生じたり、Standbyノードのリソースが平常に無駄に課金されることが生じてしまいます。パブリッククラウド環境では個人的にはあまり望ましい構成ではないと考えます。(Rundeckに限らずですが。。。)
- コンテナ化
- システムプラットフォームとしてコンテナアーキテクチャをすでに採用している場面であれば、Rundeckもコンテナ化することで低コストのジョブ管理システムを構成できます。コンテナ化することでRundeck構成の簡素化を維持継続しやすく障害時の回復も高速に実施できるでしょう。コンテナ化によって環境ごと(JT、ST、STG、PRD等)に個別コンテナを作成し、必要時のみ起動するといった運用も低コストで実現可能です
ジョブ定義
Community版での制約
Community版ではEnterprise版で実装されている多くの機能が利用できません。その中でも業務アプリ運用で影響の大きいと思われる機能を紹介します。
- Job Queuing: ジョブキューイング機能が実装されていません。同一ジョブを連続実行する場合などは考慮が必要です
- Failed Job Resume: ジョブズテップでの再実行ができません。ジョブのリカバリポイントをジョブ単位で構成することが必要です
- Workflow Visualization、Ruleset Workflow Strategy Plugin: 商用ソフトウェアでは通常実装されているジョブワークフローのグラフィカルな表示・修正ができません。複雑なジョブ構築・修正は困難です
- Blackout Calendaring: カレンダー設定がありません。祝日など特殊な営業日の対応が難しいです
複雑なジョブワークフロー
前述の制約事項でも記載した通り、RundeckのCommunity版では複雑なジョブワークフローを作成するのは難しいです。
基本的には実行単位はジョブであり、そのなかでステップに分割することで複数のタスクを実行します。ジョブネットという概念が見つけられませんでした。ジョブズテップから別のジョブをトリガーしてつなげることは可能です。
リカバリポイントを加味した並列ジョブワークフローを作成してみました。
もう少しうまいやり方があるかもしれません。ご存知の方がいらっしゃればコメントをいただければです。
ジョブ定義に関する考察
複雑なジョブワークフローが要求される場合、Community版のRundeckを利用することは難しいです。
複雑なジョブフローを実装するためのツールがなく、実装する場合は構築工数のコストが大きくなることが想定されます。またジョブ障害時のリカバリ操作も難しくなります。
Community版を利用する場合のジョブフローとしては、直列に順列で実行するようはワークフローであったり、並列処理においても後続タスクに複数のジョブディペンデンシーを用いないジョブ構成が望ましいものと考えます。
IaCワークフロー
RundeckにはいくつかのIaC関連ツールへのプラグインが実装されており、Community版でも利用できるものがあります。先述したようにIaCツールを運用フェーズで利用促進するにはワークフローが必要と考えておりました。
モノリシックな構成では、システムの変更余地が高く、またそのために変更された内容が検出しづらいです。システム更改などの際、システム規模によっては現状調査に多大な工数が発生します。業務システムとしてはマイクロサービス化が進んでいますが、オンプレミス環境・パブリッククラウド環境で依然モノリシックなシステム環境は多数存在してします。
変更管理がきちんと行われている環境であっても、変更履歴はあるものの、それがサーバ構成管理ときっちり紐づけられている環境は多くはありません。オンプレミスの環境ではサーバ構成管理はHW構成(CPU,RAM,DISK等)のみであったりすることもあります。それをそのままパブリッククラウドに展開してしまうと、インスタンスの管理はインスタンスタイプやEBSサイズといったもののみになってしまいます。そのためサーバ内部の構成管理(SW,各パラメータなど)は疎かになりがちです。
また変更管理のトリガーは業務インシデント(更改、障害など)であることがほとんどであり、その結果としてインシデントのクローズで完了となり、サーバ構成変更として履歴として損なわれる状態になるといったこともあると感じております。
インフラへの変更をジョブワークフローとして生成しログとして残すことで各サーバへの変更履歴を明確化し、かつ、AnsibleやTerraformのコードが変更内容として外部に保存されることがワークフロー管理ツールを用いることで比較的容易に実現できると考えています。
IaCワークフロー検証構成
- RundeckとAnsibleをインストールしたコンテナを作成
- Terraformをインストールしたコンテナを作成
- TerraformコンテナをRundeckのノードとして追加
IaCワークフロー操作
- IaC実行ユーザはS3バケットに実行するスクリプト類を格納(追加・修正)
- Terraformで構築するためのtfファイル、ジョブズクリプト、Ansible-playbookを格納
- Rundeckにジョブを登録
- Terraformでインフラ環境を構築ジョブ
- Ansiblleでサービスパッケージの導入及びコンフィグレーヨンジョブ
IaCワークフロージョブ例
- Terraform
- S3からtfファイル(providers.tf,backend.tf,各種tfファイル)ダウンロード
- Terraform init
- Terraform validate、Terraform apply
- Ansible
- S3からAnsible-playbookファイル(inventory,task,file,template)ダウンロード
- パッケージインストール
- パッケージ設定ファイル配布
- サービス起動
※実運用では、terraform planやAnsible dryrunなどで実行前に検証を行いますが、実行検証のため省略しております。
IaCワークフロー環境でのコンテナ化のメリット
運用コスト
既にコンテナ環境が整備されているのであれば、IaCワークフローで利用する場合はコンテナで運用することがおすすめです。
IaCリクエストは常時必要であることは稀で必要な時だけ起動できればよいことが多いと思われます。かつコンテナ化することでRundeck自体もリポジトリを利用することで低コストで変更管理できます。
ノイズの防止
IaCの運用において実施過程で生じる不用意な修正が品質を大きく損なうケースがあります。
一時的に行ってしまった誤ったtfファイルやAnsible-playbookの修正が既設の構成状態との乖離を発生してしまい、同期した状態に回復することに多大な工数が生じてしまう、あるいは最悪運用が破綻してしまう場合があります。以前に実行したファイルが不要となったにもかかわらず、そのまま配置されていて意図しない修正が発生していまったなどということもありえなくはありません。
ユーザがサーバ上でtfファイルやAnsible-playbookなど設定ファイルの直接変更を防ぐことや、設定ファイルをSCM(S3やSubversionなど)で版管理することはIaCを維持するためには重要だと考えます。
コンテナの揮発性の性質は、ノイズの防止には都合のよいことだと考えます。
セキュリティ
環境ごと(開発環境、テスト環境、ステージング環境、本番環境など)それぞれにコンテナを用意しセキュリティ制限を設けることで環境間での誤った更新を防ぐといった点も便利かと思います。むろんサーバで分離することも可能ですが、コスト面や環境維持の観点でコンテナの方がメリット大きいと思われます。
セキュリティ制限とは、AWS環境でいえば各環境のコンテナごとにIAMロールやセキュリティーグループを設定し意図しない環境へのアクセスをブロックといった制御を指しております。
データベースは各環境ごとに作成するとコストが大きいため、1つのインスタンス上にデータベース・スキーマ等で分離することで十分であると考えます。IaCワークフローではジョブの実行多重度は多くなく、DB負荷は低いものと想定されるため環境ごとにDBインスタンスを用意するのは費用対効果が悪く感じます。
IaCワークフローに関する考察
IaCワークフローでの活用では、Rundeckでなければならないというものではありません。コンテナ化が容易であることやIaC関連のプラグインが存在することなどはRundeckのメリットではありますが、他のツールでも実現は可能かと思います。
Rundeckはそれを比較的容易にIaCワークフロー構築できるツールの1つであるということだと考えます。
まとめ
- ジョブ管理ツールとして、Rundeck Community版はミッションクリティカルな状況下において可用性・運用性の観点から採用は困難。ミッションクリティカル環境でRundeckの特性(豊富な他ツールとのプラグインなど)を利用したい場合はEnterprise版を検討する
- Rundeck Community版は導入が容易であることから、非ミッションクリティカルな状況では利用価値はある。開発・テスト環境でのジョブワークフロー、非ミッションクリティカルなcronジョブの統制、CI/CD、IaCワークフローツールとしてなど
- IaCワークフローにおいてRundeckは有効なツールの1つとなりえる