WordPressサーバがダウンする原因を調査して改善する(メモリ不足編)

はじめに

本ブログサイトが動作しているEC2インスタンス(Amazon Linux2, t2.micro)が度々ダウンします。

今回はこの原因を調査し、対応した経緯をまとめます。

原因調査

WordPressサーバがダウンする原因を調査するために、インスタンスにアクセスして、psコマンドを実行しました。

上記の通り、php関係のプロセスが多数動いており、全体の80~90%を占めています。

つまり今回のサーバ不調の原因はメモリでした。

対応

php-fpmプロセスの起動数が問題だと思い調べたところ、以下のサイトを拝見しました。

https://www.petitmonte.com/linux/php-fpm-memory.html

具体的には、/etc/php-fpm.d/www.confを以下のように修正します。

  • pm:「static」に変更
  • pm.max_children:「3」に変更

これで子プロセスの数を「3」に固定します。

確認

メモリ不足で困っていたWordPressサーバでphp-fpmの再起動(sudo systemctl restart php-fpm)を実施後、改めてプロセスを確認します。

確かにプロセス数が3に抑えられています。

freeコマンドでメモリの使用量を見ると、20%程度に抑えることができました。

これでしばらく運用してみて、プロセス数は調節していきたいと思います。

AWS CodePipelineを使用したCloudFormationスタックの作成

概要

AWS CodePipelineは、継続的インテグレーションと継続的デリバリー(CI/CD)サービスであり、開発者がアプリケーションの更新を迅速かつ信頼性高くリリースするのに役立ちます。

この記事では、CodeCommitにコードをpushすることを起点に、CodePipelineを使用してCloudFormationスタックを作成する方法について説明します。

構成図

前提条件

  • GitやCloudFormationに基本的な使用方法を認識していると読み進めやすいです。
  • ローカルの開発環境からCodeCommit上にコードをpushする場合、AWS CLIがインストールされ、適切に設定されている必要があります。

https://git-scm.com/about

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html

手順

  1. CodeCommitリポジトリの作成: まず、AWS Management ConsoleからCodeCommitリポジトリを作成します。このリポジトリは、CloudFormationテンプレートを保存するためのものです。
  2. CloudFormationテンプレートの作成: 次に、CloudFormationスタックを作成するためのテンプレートを作成します。このテンプレートはYAMLまたはJSON形式で記述され、AWSリソースの設定を定義します。
  3. CodePipelineの作成: CodePipelineを作成し、ソースステージとして先ほど作成したCodeCommitリポジトリを指定します。また、デプロイステージとしてCloudFormationを指定し、先ほど作成したテンプレートを使用するよう設定します。
  4. パイプラインの実行: 最後に、CodeCommitリポジトリにCloudFormationテンプレートをpushします。これにより、パイプラインが自動的に実行され、CloudFormationスタックが作成されます。

これにより、GUIやCLIで手動でスタックを作成することなく、コードのpushだけでCloudFormationスタックを自動的に作成できます。

これは開発者の生産性向上に寄与し、エラーの可能性を減らすことができます。

注意点

  • CloudFormationテンプレートは正確に記述する必要があります。間違った設定は予期しない結果やエラーを引き起こす可能性があります。
  • CodePipelineはAWSリソースを使用します。そのため、パイプラインの実行は課金対象となります。

これらのサービスを活用することで、開発フローを自動化し、効率化することが可能です。

検証

今回は、以下のCloudFormationテンプレートを用いて、上記の仕組みを構築しましたが、マネジメントコンソールで作成しても問題ありません。

Resources:
  MyCodeCommitRepository:
    Type: AWS::CodeCommit::Repository
    Properties:
      RepositoryName: !Ref MyCodeCommitRepoName

  MyPipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      Name: MyPipeline
      RoleArn: !GetAtt PipelineRole.Arn
      ArtifactStore:
        Type: S3
        Location: my-pipeline-bucket-name
      Stages:
        - Name: Source
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: AWS
                Version: "1"
                Provider: CodeCommit
              Configuration:
                RepositoryName: !Ref MyCodeCommitRepoName
                BranchName: main
              OutputArtifacts:
                - Name: !Ref MySourceArtifact
        - Name: Deploy
          Actions:
            - Name: DeployAction
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Version: "1"
                Provider: CloudFormation
              Configuration:
                StackName: !Sub "${Env}-stack-${ResourceName}"
                ActionMode: CREATE_UPDATE
                Capabilities: CAPABILITY_IAM
                RoleArn: !GetAtt DeployRole.Arn
                TemplatePath: !Sub "${MySourceArtifact}::${MySourceTemplate}"
              InputArtifacts:
                - Name: !Ref MySourceArtifact

実際に、以下のようなS3バケットを作成するCloudFormationテンプレートをCodeCommitにpushします。

Resources:
  tests3bucket:
    Type: AWS::S3::bucket

以下のコマンドでpushします。

$ git push prigin {BranchName}

バケットが作成されました。

コードに以下の変更を加えて、再度pushします。

変更箇所は、Nameタグを付与している点です。

Resources:
  testBucket:
    Type: AWS::S3::Bucket
    Properties:
      Tags:
        - Key: "Name"
          Value: "UpdateComplete"

実際にタグが付与されました。

まとめ

AWS CodePipelineとCloudFormationを使用して、CodeCommitにコードをpushすることを起点にCloudFormationスタックを作成する仕組みの検証が完了しました。

CodeCommitにコードをpushするだけで、CloudFormationスタックが自動的に作成されました。これにより、手動での作業が不要となり、開発者の生産性が向上しました。

また、CodePipelineを使用することで、スタック作成プロセスが一貫性を持ち、エラーが減少しました。これは、開発者が手動で操作するよりも信頼性が高いです。

以上が今回の検証結果のまとめです。AWS CodePipelineとCloudFormationを活用することで、開発フローを自動化し、効率化することが可能であることが確認できました。

AWS勉強会でWeb3層構成を作る前に勉強したこと

筆者:ITI2-1 松本拓

〇本番の構成

詳細はこちらの記事で
https://dis-iti2-tech.net/?p=1

〇筆者のスキルレベル

  • AWSクラウドプラクティショナー取得済み(およそ2年前)
  • AWS業務経験は無し
  • ハンズオンの経験は少々(VPC作成、インスタンスにWebサーバーを設定する程度)

上記の通り業務などではAWSに触れたことのない、さらにサーバーもほとんど触った事のないほぼ初心者の私が実際に上の図のようなWeb3層構成を作成する前に学んだことはWebサーバーとアプリケーションサーバーの連携でした。

〇本番構成作成前の事前練習

大塚係長からの提案で実際の本番環境を構築する前に単一AZにインスタンスを立て、Wordpressをインストールするまでの手順を各メンバーでリハーサルとしてやってみることになりました。

↓この構成です。

大塚係長から参考になるサイトを教えていただき実際に環境を作れましたが、しっかりと理解できたかというと手順通りに進めてできたという感じでした…自分の力というかサイトの手順が分かりやすかったと思います。

※参考サイト

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/hosting-wordpress.html

〇理解を深めるための自習

さらに理解を深めるため自分でWebサーバーとアプリケーションサーバーの連携を実践してみてはとご提案を頂いたので

いろいろと調べて進めようとしましたが、文章だけ読んでもきっと理解できないだろうという自分への不信感から

分かりやすい動画を探すことに…

そしてYouTubeで参考になりそうな動画を見つけました。

本番の構成とは違いますが、AWSでEC2インスタンスを立ち上げてWebアプリケーションサーバーを構築するという内容なので、とりあえず動画を観ながら実際に手を動かしてみることに…

チャンネル

・【いちふくのときたまエンジニア配信】

動画

・【Linux技術動画】Webアプリケーションサーバ構築Part1 (Apache&Tomcat) ※約30分

・【Linux技術動画】Webアプリケーションサーバ構築Part2 (Apache&Tomcat) ※約20分

多少の苦戦はしましたが、想定通りに動く構成ができ達成感に浸ることができました。

この学習によりWebアプリケーションサーバーの構成について理解が深まったと思います。

〇本番のALB作成のための予行練習

本番構成の作成はリソースごとに担当分けされ、私はALB(ロードバランサー)の作成を担当することになりました。

ALBに関しては下記のような構成を作成して予行練習をしました。

Auto Scaling Group、ターゲットグループの作成など苦戦した部分もありましたが、ALBを経由してEC2にアクセスする構成を作成することができました。

Auto Scalingに関しては設定が上手くいっていない部分があったので、また時間のある時に実施してみたいと思います。

〇まとめ

勉強会では自分のレベルにあった勉強法のアドバイスなどをいただき、理解を深め実際のAWS環境でリソースを作成していくので、初心者の方でも気兼ねなく参加できるようになっています。

AWSに少しでも興味がある方は、ご都合が合うときに参加してみてはいかがでしょうか。

AWSを用いたWeb3層構成のWordPress構築

勉強会参加メンバーで、AWSを用いてWordPress環境を構築しましたので、ご紹介します。

背景

いまご覧になっているこのエンジニアブログを作成してみようという会話を発端に、世界中で広く利用されているCMSの1つであるWordPressを利用しようと考えました。
今回は、AWSを利用して、Web3層構成のWordPressを構築する方法について紹介します。

構成

  • VPCのネットワークに6つのサブネット
  • リージョンは、ap-northeast-1
  • AZは、ap-northeast-1aとap-northeast-1c
  • パブリックサブネットにALB
  • プライベートサブネット1つ目にWebAPサーバとしてのEC2
  • プライベートサブネット2つ目にDBサーバとしてのRDS

手順

  1. AWSでVPCを作成する。
  2. VPCの中に6つのサブネットを作成する。その中には、1つのパブリックサブネットと2つのプライベートサブネットがあります。プライベートサブネットの1つには、EC2インスタンスを、もう1つには、RDSを作成します。
  3. ALBを作成して、パブリックサブネットに配置します。
  4. EC2インスタンスにWordPressをインストールし、プライベートサブネットに配置します。
  5. RDSにWordPressのデータベースを作成します。
  6. EC2インスタンスとRDSインスタンスの間に必要なポートを開けます。

詳細手順

以下に、より詳細な手順を紹介します。

1.AWSでVPCを作成する

まず、AWSの管理コンソールにログインし、新しいVPCを作成します。

VPCは、仮想プライベートクラウドを作成するためのサービスであり、AWS上のリソースをグループ化してネットワーク上で独立した環境を作成します。VPCを作成する際には、IPアドレス範囲を指定し、サブネットを作成することができます。今回は、10.0.0.0/16を使用。

以下の通り、VPCが作成されました。

2.VPCの中に6つのサブネットを作成する

VPC内に、6つのサブネットを作成します。

これには、1つのパブリックサブネットと2つのプライベートサブネットが2つのAZ分で計6つあります。
以下の通り作成しました。

パブリックサブネットには、Application Load Balancer(ALB)を配置します。ALBは、Webトラフィックを分散し、ユーザーからのリクエストを適切なEC2インスタンスにルーティングするためのサービスです。

プライベートサブネットの1つには、EC2インスタンスを、もう1つには、RDSを作成します。

3.ALBを作成して、パブリックサブネットに配置する

次に、ALBを作成してパブリックサブネットに配置します。ALBを作成する際には、EC2インスタンスの登録とターゲットグループの作成を行います。

ロードバランサーの作成から、必要な情報を入力し作成します。

ターゲットグループは、ALBからEC2インスタンスにトラフィックを転送するための仕組みです。

4.EC2インスタンスにWordPressをインストールし、プライベートサブネットに配置する

次に、EC2インスタンスにWordPressをインストールしてプライベートサブネットに配置します。EC2インスタンスを起動する際には、AMI(Amazon Machine Image)を指定します。AMIは、EC2インスタンスを起動するために必要なOSやアプリケーションがインストールされた仮想マシンイメージです。EC2インスタンスには、WordPressと必要なプラグインをインストールし、必要に応じてテーマを変更します。

※今回は、AutoScailingを利用するため、起動テンプレートのユーザーデータに以下のように、ワードプレスをインストールするコマンドを設定している(一部抜粋)

yum -y update
amazon-linux-extras install php7.2 -y
yum -y install mysql httpd php-mbstring php-xml gd php-gd
systemctl enable httpd.service
systemctl start httpd.service
systemctl status httpd.service
wget http://ja.wordpress.org/latest-ja.tar.gz ~/
tar zxvf /latest-ja.tar.gz

5.RDSにWordPressのデータベースを作成する

次に、RDSにWordPressのデータベースを作成します。RDSは、AWSが提供するリレーショナルデータベースサービスであり、MySQLやPostgreSQLなどのエンジンをサポートしています。

WordPressのデータベースを作成するには、RDSを作成し、適切なDBエンジンを選択し、必要な設定を行います。RDSインスタンスの作成時には、DBインスタンス名、マスターユーザー名、パスワードなどの設定が必要です。

6.EC2インスタンスとRDSインスタンスを接続する

EC2インスタンスとRDSインスタンスを接続するために、RDSのエンドポイントをEC2インスタンスからアクセスできるようにする必要があります。

これには、セキュリティグループを設定することが必要です。セキュリティグループは、AWS上のリソースに対して、どのIPアドレスからアクセスを許可するかを設定するための仕組みです。

※今回は、AutoScailingでスケールアウトするEC2に設定を適用するため、起動テンプレートのユーザーデータに以下のようにコマンドを設定している(一部抜粋)

# Update wp-config.php file
sed -i -e "s/define( 'DB_NAME', '.*' );/define('DB_NAME', '$DB_NAME');/" $WP_CONFIG
sed -i  -e "s/define( 'DB_USER', '.*' );/define('DB_USER', '$DB_USER');/" $WP_CONFIG
sed -i -e "s/define( 'DB_PASSWORD', '.*' );/define('DB_PASSWORD', '$DB_PASSWORD');/" $WP_CONFIG
sed -i -e "s/define( 'DB_HOST', '.*' );/define('DB_HOST', '$DB_HOST');/" $WP_CONFIG

まとめ

今回は、AWS上にWordPressを構築する方法を簡単に紹介しました。さらに良い構成にできるよう運用していきたいと思います。

また、他の記事では、各機能の詳細な構築方法やトラブルシューティングの内容についても、紹介できればと思います。

最後まで読んでいただきありがとうございました。