はじめに
どうも皆さんおはこんばんクリスマス。
アイスタイルで爆弾処理インフラまわりを担当しております sugimotorです。
弊社では主にサーバOSとしてCentOS 6~7を多く利用していますが、
今回はやんごとなき事情によりAWS EC2へオンプレのCentOS6.x環境をマイグレーションを行いドツボにはまったお話(主にCodedeployAgent,ElasticFileSystem)をします。
CodeDeploy agentが動かない
今回はEC2へアプリケーションのデプロイにAWS CodeDeployを導入しました。
この際にCentOS6.X環境だとruby 1.8系がOSデフォのrubyバージョンなので、
CodeDeployAgentがサポートしているrubyバージョンが2以上を使うため、rbenvを用いて起動させることにしたのですが、
OS再起動後にCodeDeploy agentが起動されないという事象がありました。
これが立ち上がらないと、AutoScaleのインスタンス起動時にコードがデプロイされず。
ひたすら失敗ループを繰り返すという事になります。
・原因其1
まず、手動でrbenv経由でのCodeDeploy Agent起動を試してみると、下記のエラーが出ました。
[root@hogehoge~]# bash /root/.rbenv/libexec/rbenv-exec ruby /opt/codedeploy-agent/bin/codedeploy-agent start
/root/.rbenv/libexec/rbenv-exec: line 24: rbenv-version-name: コマンドが見つかりません
・回避方法
エラー内容を見てみると、どうやらrbenv-version-name
のコマンド形式がどうやらまずいというのは分かったので、
rbenv-execの内容を修正し無事起動が行えました。
[root@hogehoge ~]# diff -u /root/.rbenv/libexec/rbenv-exec.bkup /root/.rbenv/libexec/rbenv-exec
--- /root/.rbenv/libexec/rbenv-exec.bkup 2018-10-20 18:41:36.804054472 +0900
+++ /root/.rbenv/libexec/rbenv-exec 2018-10-20 18:41:57.414082893 +0900
@@ -21,7 +21,7 @@
exec rbenv-shims --short
fi
-RBENV_VERSION="(rbenv-version-name)"
+RBENV_VERSION="(rbenv version-name)"
RBENV_COMMAND="1"
if [ -z "RBENV_COMMAND" ]; then
@@ -30,11 +30,11 @@
fi
export RBENV_VERSION
-RBENV_COMMAND_PATH="(rbenv-which "RBENV_COMMAND")"
+RBENV_COMMAND_PATH="(rbenv which "RBENV_COMMAND")"
RBENV_BIN_PATH="{RBENV_COMMAND_PATH%/*}"
OLDIFS="IFS"
-IFS='\n' scripts=(`rbenv-hooks exec`)
+IFS='\n' scripts=(`rbenv hooks exec`)
IFS="OLDIFS"
for script in "{scripts[@]}"; do
source "$script"
・原因其2
codedeploy-agentの起動時にCodeDeployユーザを指定していたのですが、
このユーザ指定を行っている場合にOS起動時にCodeDeploy Agentが起動されない事があります。
[root@hogehoge ~]# cat /etc/init.d/codedeploy-agent
#!/bin/bash
# Init file for codedeploy-agent
#
# chkconfig: 2345 98 02
# description: codedeploy-agent processes the deployments created by AWS CodeDeploy and installs \
# the deployment artifacts on to this instance.
### BEGIN INIT INFO
# Provides: codedeploy-agent
# Required-Start: all
# Required-Stop:remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: AWS CodeDeploy Host Agent
# Description: codedeploy-agent processes the deployments created by AWS CodeDeploy and installs
# the deployment artifacts on to this instance.
### END INIT INFO
COMMAND=$1
RETVAL=0
[ -f /etc/profile ] && [ "`stat --format '%U %G' /etc/profile`" == "root root" ] && source /etc/profile
prog="codedeploy-agent"
# Modify the following CODEDEPLOY_USER variable to run the codedeploy process as a non-root user
# Note: You also need to chown /opt/codedeploy /var/log/aws
CODEDEPLOY_USER="hogehoge" ←この部分
OS起動後CodeDeployagentのエラー
sudo: sudo を実行するには tty がなければいけません。
これは単純にsudoへ起動ユーザのrequirettyを無視させる事で回避しました。
[root@hogehoge ~]# visudo
Defaults:hogehoge !requiretty
EFSマウントヘルパーが入らない。
今回、マイグレーションを行ったCentOS6.x系サーバにてEFSを利用し画像ファイルを置く構成をとりました。
EFSをマウントする手段として
1、AWSのEFSマウントヘルパーを使う。
2、通常のNFSマウントを使う
という選択肢があります。
今回はまずパフォーマンス重視の1でやろうとしたときに、Amazone推奨の方法で入れてみたのですが、
[root@hogehoge efs-utils]# sudo yum -y install ./build/amazon-efs-utils*rpm
読み込んだプラグイン:fastestmirror, refresh-packagekit
インストール処理の設定をしています
./build/amazon-efs-utils-1.4-1.el6.noarch.rpm を調べています: amazon-efs-utils-1.4-1.el6.noarch
./build/amazon-efs-utils-1.4-1.el6.noarch.rpm をインストール済みとして設定しています
Loading mirror speeds from cached hostfile
* base: ftp.riken.jp
* extras: ftp.riken.jp
* updates: ftp.riken.jp
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> Package amazon-efs-utils.noarch 0:1.4-1.el6 will be インストール
--> 依存性の処理をしています: stunnel >= 4.56 のパッケージ: amazon-efs-utils-1.4-1.el6.noarch
--> 依存性解決を終了しました。
エラー: パッケージ: amazon-efs-utils-1.4-1.el6.noarch (/amazon-efs-utils-1.4-1.el6.noarch)
要求: stunnel >= 4.56
利用可能: stunnel-4.29-7.el6.x86_64 (base)
stunnel = 4.29-7.el6
問題を回避するために --skip-broken を用いることができません
これらを試行できます: rpm -Va --nofiles --nodigest
このように関連パッケージとして、stunnelのバージョンが4.56以上ではないと入らない且つ、
amazon-efs-utilsがrpmパッケージのみしか配布されておらず、手動でstunnelをビルドしてもrpm側で認識してくれない感じです。また、EFSマウントヘルパーの説明ページを見ると、
とあるようにどうやらCentOS6.x 系では使えなさそうだという事が判明したので、
しぶしぶ通常のNFSマウントで利用を行いました。
EFSのパフォーマンスが出ない。
EFSマウントヘルパーが使えない都合上のNFSマウントでEFSをEC2(CentOS6系)へマウントしたのですが、
rsync経由でEFSへの大量のファイル同期を行うとロードアベレージが急上昇してしまいKernel Blockingが発生してしまうという事象が発生しました。
・topコマンドで確認した際のOS状況
top - 13:54:12 up 21:50, 5 users, load average: 23.99, 23.42, 17.78
・/var/log/messagesに吐かれたdump
Oct 19 13:37:58 localhost kernel: INFO: task rsync:9814 blocked for more than 120 seconds.
Oct 19 13:37:58 localhost kernel: Not tainted 2.6.32-504.12.2.el6.x86_64 #1
Oct 19 13:37:58 localhost kernel: "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
Oct 19 13:37:58 localhost kernel: rsync D 0000000000000000 0 9814 9807 0x00000080
Oct 19 13:37:58 localhost kernel: ffff8800c00d1c78 0000000000000082 ffff8800c00d1bc8 ffffffffa01aa36e
Oct 19 13:37:58 localhost kernel: ffff8800c00d1bf8 ffffffffa01aac10 ffff8800c16bd800 ffff8800c00d1c28
Oct 19 13:37:58 localhost kernel: ffff8800c16bd8b0 ffff88006e16b660 ffff88008e5e9098 ffff8800c00d1fd8
Oct 19 13:37:58 localhost kernel: Call Trace:
更に調べていくと今回マイグレーションを行ったOSのバージョンは2.6.32-504系Kernel(CentOS6 .6)を利用しており、この場合NFSのBugを踏んでいる可能性があるとの情報がありました。
https://forums.aws.amazon.com/thread.jspa?threadID=252851
というわけで
[root@hogehoge ~]# yum update -y
OSアップデートを行った後はOS側は安定して動くようになりました。
結論
どちらの事象も紐解いていくと、CentOS6.x系のSysVinitの問題であったり、
2.6系Kernelの問題が起因していることでした。根本対策としてはsystemdを利用していたり、
Kernelが3以上のCentOS7.x系やAmazone Linux2での利用を推奨かとは思うのですが、
今回の様なやんごとなき事情によるCentOS6環境下で移行をしなければならないシチュエーションでの参考にしていただけると幸いです。(最低限OSのマイナーアップデートはやっておいたほうが良い)