アプリケーションサーバー、データベースサーバー、およびいくつかのDNSラウンドロビンロードバランサーがあるとします。これはすべて、 Packer で作成され、デプロイメントが Terraform で管理されたイメージによって強化されています。インスタンスが破棄されて再作成されたときに、データを削除せずにデータベースサーバーのイメージを変更するにはどうすればよいですか?
私が考えることができる最も簡単なことは、書き込みをオフにし、データベースのスナップショットを作成してから、スナップショットを新しいサーバーに復元することです。しかし、そのような手動のいじりに頼るのは本当に間違っていると感じます。また、単純なアップグレードのためにサービスを停止するのも間違っていると感じます。よりクリーンでより良い方法がありますよね?
単純この質問への答えはありません。
イメージを中心に設計されたアーキテクチャ(一般に「不変インフラストラクチャ」と呼ばれる)を使用すると、アプリケーションサーバーなどのステートレスサービスで非常にうまく機能します。
適切なツール、フェイルオーバーシステム、アップグレードパスを使用して、ステートフルサービスに拡張することは間違いなく可能ですが、これらは通常、単純なシステム(説明したシステム)ではやり過ぎです。
これらのツールを使用する際に留意すべきことの1つは、「オールイン」する必要がないということです。 PackerとTerraformは、必要な場所でのみ機能するように設計されています。意図的にすべてのシステムにパターンを適用するわけではありません。
実際には、この問題を処理する最善の方法は、Packerの外部でデータベースサーバーを別の方法で保守するか(初期イメージを構築します。ただし、ステートレスWebサーバーと同じ方法でアップグレードする必要はありません)、状態の管理を誰かにアウトソーシングすることです。そうしないと。注目すべきオプションには、HerokuPostgresまたはAWSRDSが含まれます。
締めくくりに–はい、それは可能ですが、現在のツールでは、小規模または単純なアーキテクチャでの価値よりも、おそらくより厄介です。
PackerとTerraformは、まったく同じインフラストラクチャの他の側面で大きな恩恵をもたらす可能性があります。たとえば、Terraformは、非常に簡単な方法でDigitalOceanアプリケーションサーバーで使用するHerokuデータベースをプロビジョニングできます。 Packerは、アプリケーションサーバーイメージのアップグレードとリリース、および同様に開発を処理できます。
Terraformには、ここで必要な機能が備わっていると思います。基本的なパターンは、データボリュームを個別に定義し、それらをインスタンスにアタッチすることです。これにより、インスタンスが破棄されて新しいインスタンスが作成されたときに(たとえば、Packerによって構築された新しいAMIから)、既存のボリュームを新しいインスタンスにアタッチできます。
したがって、Terraformの詳細な手順は次のようになります。
aws_ebs_volume
リソースを定義するaws_volume_attachment
でインスタンスに添付します(ここではdevice_name = "/dev/xvdh"
を使用しました)aws_ebs_volume
リソースにライフサイクルルールが含まれていることを確認してください prevent_destroy = true
(したがって、は決してありませんterraformによって削除されます)aws_volume_attachment
リソースに skip_destroy = true
が含まれていることを確認してください(アップグレード時に、ボリュームがマウントされている間、テラフォームはこれらを破棄できません。インスタンスを停止すると、とにかくアタッチメントが破棄されるため、テラフォームは必要ありません。それを試みるために)最後のステップは、起動時にインスタンスがボリュームをマウントすることを確認することです。これは、user_data
リソースのaws_instance
で次の方法で実現できます。
#!/bin/bash
mkdir /data #create mount point
mount /dev/xvdh /data #mount it
上記を機能させるには、ファイルシステムを作成してボリュームを準備する必要がありますが、これは1回だけ必要です。
mkfs -t ext4 /dev/xvdh
詳細については、 Terraform issue#274 を参照してください。