AWS EC2メモ

August 03, 2016

インスタンスタイプごとのネットワーク帯域

iperfなどで計測する。

iperf -c %LOCAL_IP_ADDRESS% -t 60

EC2 – EC2 間 は5bps程度 参考 水門は開いた – EC2 インスタンスのネットワーク帯域幅が増大

起動時、パッケージのセットアップがうまく行かない場合

/etc/sysconfig/cloud-init の package_setupの項目をnoにする。

参考 VPC内にEC2を立ち上げようとしてcloud-initのpackage_setupでハマる

チェックポイント

EC2
  • 余計なセキュリティグループがついてないか、つまり余計なポートが空いてないか

  • opsに余計なのがついてたり( port 22 が、まだ空いていたり )

  • AZ分散しているか?

  • たまに「サブネットを作ってなかった」というミスがあり、この場合、サブネットが寄ってしまっている。

  • opsにはEIPが割り当てられているか

  • パラメータストアにSLACKの値は設定しているか

ロードバランサー
  • port 443 でリスナーが立っているか?

  • 『CloudFront障害』のケースを考えると、オリジン側もHTTPではなくSSLで受ける必要がある。

  • Deletion Protection をonにする。削除されなくするやつか

ターゲットグループ

ELBのtarget groupにおける stickness が無効になってたので30秒で有効に変更する

EC2 上に Nginx + PHP + Phalcon 構築手順

EC2インスタンスパラメータの選択

  • EBSボリュームサイズは8GBそのまま
  • EBS最適化インスタンスを起動する -> オン
  • IAMインスタンスプロフィール -> webfront
  • セキュリティグループ -> webfront

nginxの UID:GIDを揃える

下記のファイルで必要になる。 UID:GID統一の方法としては

  1. NIS or LDAP 導入
  2. 追加するアプリのUID:GID全て統一
  3. 必要なアプリのUID:GID統一

があるが、今回は3にした。基本的には『サーバ間でファイルをコピーする場合』にUID:GIDが揃ってないと、動作しないので。 ( 上場してパスワード更新が求められるようになったらldap導入するか検討しても良いかもしれない )

/var/www/apiの下記のファイルがec2-userではなかった。

sudo vi /etc/passwd

nginx:x:498:498:Nginx web server:/var/lib/nginx:/sbin/nologin
td-agent:x:495:494:td-agent:/var/lib/td-agent:/sbin/nologin

sudo vi /etc/group

nginx:x:498:
td-agent:x:494:
/etc/shadowに反映

sudo pwconv

パッケージインストール

git インストール
yum -y install git gcc make libtool

カーネルパラメータ追加

sudo vi /etc/sysctl.conf

下記を追記

## fluentd向け
net.ipv4.ip_local_port_range = 11000 65500
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 10

## 極力swapしないようにする
vm.swappiness = 10

fluentdインストール

sudo vi /etc/security/limits.conf
root soft nofile 65536
root hard nofile 65536
* soft nofile 65536
* hard nofile 65536
curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh
vi /etc/sysconfig/td-agent

下記を追記。 起動ユーザをrootにする。これはnginxのログをfluentdで確認できるようにするため。

TD_AGENT_USER=root
TD_AGENT_GROUP=root

sudo chkconfig —add td-agent

mackerelエージェントインストール

https://mackerel.io/ja/docs/entry/howto/install-agent/amazon-linux

curl -fsSL https://mackerel.io/file/script/amznlinux/setup-yum.sh | sh
sudo yum -y install mackerel-agent mackerel-agent-plugins mackerel-check-plugins

## git pullするエージェント

chkconfig mackerel-agent on

APIキーを入力( ここ https://mackerel.io/orgs/AoiZemi からAPIキーを確認できる )

sudo mackerel-agent init -apikey="<YOUR_API_KEY>"

確認

cat /etc/mackerel-agent/mackerel-agent.conf | grep key

td-agent(fluentd)とmackerelの起動順序を調整する

cd /etc/rc3.d

S50td-agent S95mackerel-agent の状態になっている事を確認した

papertrailインストール

参考

pemファイルをダウンロード

$ sudo wget https://papertrailapp.com/tools/papertrail-bundle.pem -O /etc/papertrail-bundle.pem

ログ転送暗号に必要なTLSパッケージを追加

$ sudo yum -y install rsyslog-gnutls

/etc/rsyslog.confに下記を追加

sudo vi /etc/rsyslog.conf

/etc/rsyslog.confに下記を追加

$DefaultNetstreamDriverCAFile /etc/papertrail-bundle.pem # trust these CAs
$ActionSendStreamDriver gtls # use gtls netstream driver
$ActionSendStreamDriverMode 1 # require TLS
$ActionSendStreamDriverAuthMode x509/name # authenticate by hostname
$ActionSendStreamDriverPermittedPeer *.papertrailapp.com
*.* @@logs4.papertrailapp.com:25817

rsyslogを再起動

$ sudo service rsyslog restart

エラー出ていないか確認

$ sudo tail -f /var/log/messages

paper trail側確認

ここからログインして [ Dachbord ] => [ All systems ] と遷移して、目的のホストあるか、 あればクリックして、対象ホストであることを確認( ホストは自動的に追加される )

php-fpmインストール

php-pecl-memcached が fastlzを必要とするのでインストール、これはamazon linuxのレポジトリには存在しない(2017/08/23)
Error: Package: php-pecl-memcached-3.0.3-1.el6.remi.7.1.x86_64 (remi-php71)
  Requires: libfastlz.so.0()(64bit)

phpのgd用モジュールがwebpを必要とする様になった。このため追加する。このパッケージはAmazon Linuxに存在する。

Error: Package: gd-last-2.2.4-1.el6.remi.x86_64 (remi-safe)
  Requires: libwebp.so.5()(64bit)

このパッケージはAmazonLinux, epelに存在する、がAmazonLinuxが提供するライブラリが古く、remi-php71の求めるバージョンに届いていない( AmazonLinuxが提供するのは libwebp.so.4 と一つ古い ) epelのモジュールを利用する。

sudo yum -y install --disablerepo=amzn-main  --enablerepo=epel libwebp fastlz

remiを有効にする必要がある

sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

remiレポジトリの優先度を上げる

sudo vi /etc/yum.repos.d/remi-php71.repo

[remi-php71] に priority=1 を追加

sudo yum -y --enablerepo=remi-php71  install php libwebp php-pdo php-pear php-pecl-zip \
  php-common php-devel php-pecl-memcached php-xml php-mysqlnd php-fpm php-cli php-pecl \
  php-process php-mbstring php-mcrypt newrelic-php5 ImageMagick-devel

Image Magic / php-gd インストール。この工程は peclが必要なので、上記のphp-peclインストール後に行う

image magicのモジュールはrpmからインストールは結構ハードルが高そう ( CentOSのレポジトリを混ぜる、という方法が紹介されてる。 http://og732.hatenadiary.com/entry/2015/06/17/231904 が、 CentOSのレポジトリとremiのアプデがずれるケースが発生すると危険な場合がある、必要な関数が見つからないよ的な )

sudo pecl install imagick

sudo yum --enablerepo=remi-php71 install php-gd php-pecl-jsond php-opcache 

newlelicのパッケージ名は変わらない( https://discuss.newrelic.com/t/where-to-download-php7-agent/35807/2 )

sudo rpm -Uvh http://yum.newrelic.com/pub/newrelic/el5/x86_64/newrelic-repo-5-3.noarch.rpm
sudo yum install -y newrelic-sysmond newrelic-php5
sudo nrsysmond-config --set license_key=5abff686e6d07b3fdb9add2686f996f9fa638d61   # こちらの方がシンプル
# sudo newrelic-install install

でインストール、下記はインストール結果

[root@hoge yum.repos.d]# sudo newrelic-install install
New Relic PHP Agent Installation (interactive mode)
===================================================

   Enter New Relic license key (or leave blank):
Found a valid PHP in : /usr/bin
         PHP Version : 7.1.8
  Module API version : 20160303
    Module directory : /usr/lib64/php/modules
  Zend Thread Safety : no
   CLI ini directory : /etc/php.d
      Install Status : OK


New Relic is now installed on your system. Congratulations!


1. Set newrelic.appname in your newrelic.ini file.

2. Restart your web server. This will fix most reporting issues and
   load the agent's new features and bug fixes.

If you have questions or comments, go to http://support.newrelic.com.

newrelic-php5 newrelic-php5-common-7.4.0.198-1.noarch

php regisモジュールインストール

cd /usr/local/src && sudo git clone git://github.com/nicolasff/phpredis.git && cd phpredis/
sudo phpize && sudo ./configure && sudo make && sudo make install

phalconインストール

cd /tmp \
curl -O https://codeload.github.com/phalcon/cphalcon/tar.gz/v3.2.1 \
tar xzf v3.2.1 \
cd cphalcon-3.2.1/build \
sudo ./install \

php-fpmの自動起動

sudo chkconfig php-fpm on

php.iniコピー

scp ec2-user@IPアドレス:/etc/php.ini /var/tmp/
diff <(cat /var/tmp/php.ini|grep -vE '^;') <(cat /etc/php.ini|grep -vE '^;') | less     # 差分を確認する
sudo cp /var/tmp/php.ini /etc/php.ini

php-fpm.confコピー

sudo scp ec2-user@IPアドレス:/etc/php-fpm.conf /var/tmp/
diff /var/tmp/php-fpm.conf /etc/php-fpm.conf   # 差分を確認する
cp /var/tmp/php-fpm.conf /etc/php-fpm.conf # 設定を入れる

/etc/php-fpm.dのコピー

sudo rsync -avz -e 'ssh --rsync-path="/usr/local/bin/rsync.sh" ec2 -user@IPアドレス:/etc/php-fpm.d/ /etc/php-fpm.d/

/etc/php-zts.dのコピー

sudo rsync -avz -e 'ssh --rsync-path="/usr/local/bin/rsync.sh" ec2-user@IPアドレス:/etc/php-zts.d/ /etc/php-zts.d/

時刻設定

sudo cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
sudo sh -c "echo -e 'Asia/Tokyo\nUTC=false' > /etc/sysconfig/clock" && cat /etc/sysconfig/clock

nginxパッケージインストール

既存サーバでは関連パッケージ全てインストールされていた。

[root@ip-IPアドレス ec2-user]# rpm -qa |grep nginx
nginx-all-modules-1.10.3-1.31.amzn1.x86_64
nginx-mod-http-xslt-filter-1.10.3-1.31.amzn1.x86_64
nginx-mod-stream-1.10.3-1.31.amzn1.x86_64
nginx-mod-mail-1.10.3-1.31.amzn1.x86_64
nginx-1.10.3-1.31.amzn1.x86_64
nginx-mod-http-geoip-1.10.3-1.31.amzn1.x86_64
nginx-mod-http-image-filter-1.10.3-1.31.amzn1.x86_64
nginx-mod-http-perl-1.10.3-1.31.amzn1.x86_64

が、

  • 少ないモジュールの方が高速化するのではないか
  • 意図しないセキュリティーホールが残る可能性 ( 定期的にアップデートしているので、可能性は低いが、自分が使うモジュールのみにしておいた方がセキュリティホールを認識しやすい )
  • 将来的に「このモジュールは本当に必要なのか」と悩まずにすむ

どれも強い欲求ではないが、一旦少ないパッケージで設定が可能か確認する( まずければ、動作テストの際に検出されるはず )

sudo yum -y install nginx
sudo chkconfig nginx on

設定ファイルをproduction環境からコピーする /etc/nginx/nginx.conf /etc/nginx/conf.d/api.conf /etc/nginx/conf.d/www.conf

sudo chkconfig nginx on && chkconfig —list |grep nginx sudo tail /var/log/nginx/error.log sudo service nginx start

設定ファイル同期

sudo rsync -avz -e 'ssh --rsync-path="/usr/local/bin/rsync.sh" ec2-user@IPアドレス:/etc/nginx/conf.d/ /etc/nginx/conf.d/

php composer.phar install

cd /var/www/アプリのパス
rm -rf vendor/*
php composer.phar install
curl http://localhost:10081/v2/

json周りのモジュールインストール

http://d.hatena.ne.jp/hnw/20150419 php7系の pecl-json-c は存在しない、ので、jsondをインストール

yum --enablerepo=remi-php71 install php-pecl-jsond

あらかじめ必要な scl-utilsをインストール

yum --enablerepo=epel install scl-utils

rpmインストール後のUID:GIDの調整

rpmパッケージは『既にUID:GIDが設定したらインクリメントしてUID:GIDを設定する』ような振る舞いをしない。 ので、nginx, td-agentのUID:GIDと被る場合があるので確認する

cat /etc/passwd |grep -E '494|498'
cat /etc/group |grep -E '494|498'

php7で消えたモジュールの設定を削除

sudo rm /etc/php.d/30-mysql.ini
sudo rm /etc/php.d/40-json.ini # 20-json.iniになった

vi /etc/php.d/40-igbinary.ini コメントアウトされている行を有効にする。これはmemcache用のモジュールから利用される。

extension=igbinary.so

このモジュールが有効になっていないと、下記のエラーが出る

Starting php-fpm: [30-Aug-2017 15:55:08] NOTICE: PHP message: PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/memcached.so' - /usr/lib64/php/modules/memcached.so: undefined symbol: igbinary_unserialize in Unknown on line 0

mackerelの起動順序を早める

fluentd 経由でmackerelに送信している情報がいくつかある( nginxのログの情報など ) このため、fluentdが起動する前にmackerelが起動している必要があるため、 mackerelの起動順序を早める。

cd /etc/rc3.d mv S95mackerel-agent S14mackerel-agent

newrelicのファイルの所有者権限

chown root:newrelic /etc/newrelic/nrsysmond.cfg

newrelic自動起動

chkconfig newrelic-daemon on

ホスト名を設定する

作業のミスを防ぐためにプロンプトの表示を切り替えたい

http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/set-hostname.html の [ シェルプロンプトをホストニックネームに変更するには ]を行う

bashの環境変数でホスト名を入れる

sudo sh -c 'echo "export NICKNAME=production-php7-stresstest" > /etc/profile.d/prompt.sh'

bashのプロンプトを変更する。 /etc/bashrc の

  # [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ "

を、下記のようにする

  [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@$NICKNAME \W]\\$ "

ログインし直して確認する

newrelicで表示されるホスト名を変える

下記の環境変数で表示されるホスト名を変更している

./conf.d/www.conf:        fastcgi_param  PHP_VALUE       "newrelic.appname=www.example.com";

Profile picture

Written by tin-machine 技術関連のメモ Twitter