カテゴリー別アーカイブ: サーバ設定

出先や移動中にsshで作業する場合にはscreenを使う

 お名前.com VPSとかのVPSを仕事やら個人やらで使っていると管理にssh使うよね。

 Windows化していればRDPでの管理とかになるけど、その場合途中切断してもセッションが生き残ってて、再接続するとコンティニューできるけど、ssh管理の場合に途中で通信が切れるとプロセスが止まっちゃって処理が中途半端になったり色々不便。

 例えば、出先でsshでコマンド実行したけどやたら時間かかっちゃってなかなか離れられないとか、スマホとかで移動中に作業していて通信が途切れちゃって作業が完了できないとかで困る。

 で、そんなときはscreenを使うと便利。

 RedHat系ならyum install screenで入れられる。

 こいつは、マルチスクリーンのサービスとでもいうか、まぁ、コマンドラインでscreenと実行すると、そのままシェルが沸いてくるんだけど、シェルの管理がターミナルじゃなくてサービス側にあるのでターミナルが終了してもスクリーンが生き続ける。
 screen上で実行しておけば、sshを切断しても処理継続したりスリープさせておいたり出来る。 なので、出先のsshで繋いだときに
screen
mysqldump …
C+a d
みたいな動きをしておくと、screenで新規スクリーンを立てて、そこで時間のかかる処理(この場合mysqldump)をして、C+a dのコードでスクリーンを動かしたまま離れられる。 手動でデタッチせずにsshが切れるとデタッチ扱いになる。

 再度ssh等で接続した時、
screen -ls
すると、生きているスクリーン一覧が見られるので、必要なスクリーン名に対して
screen -r 1234.my.server
みたいに実行すると、そのスクリーンに再接続できる。

 スクリーンを終了する場合は、C+dのコード送信かスクリーン上のシェルをexitすればOK。

 接続したら毎回screenを実行するようにしておけば、不意な切断などでも処理継続させられるので、是非活用したい。

(1132)


カテゴリー: LAMP[Linux, Apache, MySQL, PHP], サーバ設定 | コメントをどうぞ

Linux上の特定ユーザで動いているプロセスを全て止める

 Linux環境上で特定のユーザで動いているプロセスが暴走したりしてLoadAverageが上がったりしたとき、まとめて殺す方法。

 sudo -u ユーザ名 kill -SIGKILL -1

 killコマンドの対象を-1にすると、実行ユーザの全てのプロセスになる。
 で、sudo -uで対象ユーザ権限で実行すれば、そのユーザの全てのプロセスに送れる。
 SIGHUPとかでも良いけど、やばいときはSIGKILLかな?

(31)


カテゴリー: LAMP[Linux, Apache, MySQL, PHP], サーバ設定 | コメントをどうぞ

mondorescue – Linuxシステムのフルバックアップとハード変更

 MondoRescueと言うツールがある。
 Linuxシステムのフルバックアップを行ってDVD等のメディアに保存して、DVDブートでフルリカバリしたり、あるいはファイル単位で復元も出来る便利なツールである。

 今回、開発に利用していたサーバの不調から、新しいサーバにシステム丸ごと移行するためにこのツールを使った。
 同一構成でのリストアでは何も気にすることなく、mondoarchiveコマンドで取ったバックアップをDVDに焼いて、DVDブートして全自動モードを選べばほぼ何も気にすることなく復元されるのだが、今回は、ハードウェアがだいぶ新しい物に変わったのと、非冗長ディスク構成だった環境からRAID1ミラーリング環境へと移行するため、色々と手順が必要だったので記録しておく。

旧環境
HP Proliant ML350 G5
HDD 250GBx2(LVMにより単一ボリューム化[JBOD]) IDE Native
/dev/sda1がブートパーティション
/dev/sda2, /dev/sdb2がVolGroup00のメンバーで、LogVol00がルート、LogVol01がスワップ。
CentOS 5.5 x86_64

新環境
HP Proliant ML110 G7
HDD 2TBx2(ソフトウェアRAID1構成) AHCI
CentOS 5.5 x86_64

 旧環境にてフルバックアップを実施した。
事前準備
MondoRescue導入
wget ftp://ftp.mondorescue.org/rhel/5/x86_64/mondorescue.repo
mv mondorescue.repo /etc/yum.repos.d/
yum install mondo
#バックアップ前にmdadmを入れておかないと、リカバリ時に使えなくて困る
yum install mdadm

バックアップメディアの準備(今回は2TBのHDDを接続して利用、/dev/sdcになった)
fdisk /dev/sdc
#全体をLinuxタイプのパーティションにした
mke2fs /dev/sdc1
mount /dev/sdc1 /mnt/backup

バックアップ実行
mondoarchive -Oi -g -L -N -s 4G -d /mnt/backup -E /mnt

・mondorescue-1.isoをDVDに焼く
・バックアップデータの入ったディスク(/dev/sdc)を新環境に接続

・新環境の構成を実施
新環境を先のDVD(mondorescue-1.isoのもの)からブートする。
 ブート時の選択でexpertで起動する。
 ハードディスクは/dev/sda, /dev/sdbにアレイ構築用、/dev/sdcにバックアップデータの入ったディスクが存在する状態。

fdisk /dev/sda
fdisk /dev/sdb
#/dev/sda1, /dev/sdb1を100MのLinux RAID Autodetect(type:fd)として作成、アクティブマークする。
#/dev/sda2, /dev/sdb2に残りを割り当て、同じくLinux RAID Autodetectにする。

mdadm –create –level=1 –metadata=0.9 –raid-devices=2 /dev/md0 /dev/sd[ab]1
mdadm –create –level=1 –metadata=0.9 –raid-devices=2 /dev/md1 /dev/sd[ab]2
#metadata1.2だとブートできなかった

lvm pvcreate /dev/md1
lvm vgcreate VolGroup00 /dev/md1
lvm lvcreate -L 1.8T -n LogVol00 VolGroup00
lvm lvcreate -L 8G -n LogVol01 VolGroup00
mke2fs -j /dev/md0
mke2fs -j /dev/VolGroup00/LogVol00
mkswap /dev/VolGroup00/LogVol01

#fstabを修正する
vi /etc/fstab
/dev/VolGroup00/LogVol00 / ext3 defaults,noatime
/dev/VolGroup00/LogVol01 swap swap defaults
/dev/md0 /boot ext3 defaults
#LABEL=boot /boot だったのを /dev/md0に変更

#mondoが使うマウントリストを修正
vi /tmp/mountlist.txt
/dev/md0 /boot ext3 0 /boot
/dev/md1 lvm lvm
/dev/VolGroup00/LogVol00 / ext3 lvm
/dev/VolGroup00/LogVol01 swap swap lvm

#リストアプログラムを起動する
mondorestore
モード選択>Interactive
ソース選択>Hard disk
プレフィクス設定>mondorescue
ディスクの場所の入力>/dev/sdc1
ディスクタイプの入力>ext3
External…? > Yes
ISO Mode – path > /
#プログラムがバックアップデータをマウントする
#マウントリストの編集画面やディスク構成関連の情報が出るが、先の手順で事前設定済みなので以下の通り進める
SaveMount List? > Yes
Do you want erase and partition your hard drives? No
Do you want format your hard drives? No
Do you want me to restore all of your data? Yes
#ファイルリストア処理が行われる(400GBで10時間程度かかった)
Initialize bootloader? No
#ブートローダを再構築しないといけないが、手動で実行するのでNo
#コマンドラインに落ちる

mkdir /mnt/root
mount /dev/VolGroup00/LogVol00 /mnt/root
mount /dev/md0 /mnt/root/boot
mdadm –examine –scan > /mnt/root/etc/mdadm.conf
#mdadm.confが無いとブート時にmdを見失う
chroot /mnt/root
mount /proc
#/proc/mdstatが無いとraid関係モジュールがmkinitrdで入ってこないので、必ず/procをマウントする
cd /boot
vi grub/device.map
#デバイスマッピングで/bootデバイスを指定しておく
(hd0) /dev/md0

vi grub/grub.conf
#grub設定のrootデバイス kernelオプションでrd_NO_DMやrd_NO_MDがある場合は削除する
#rootオプションを確認する(root=/dev/mapper/VolGroup00-LogVol00)、LVMがうまくいかないときは、rd_LVM_LV=VolGroup00/LogVol00とrd_LVM_LV=VolGroup00/LogVol01を追記する。

古い初期ファイルをリネームする
#grub.confにあったinitrdのファイル
#…はカーネルバージョン、2.6.el5.x86_64とか
mv initrd-…img initrd-…img.old
同名で新しい初期ファイルを構築する
mkinitrd -v -f initrd-…img …

ブートセクタを仕込む
grub
device (hd0) /dev/sda
root (hd0,0)
install /grub/stage1 (hd0) /grub/stage2 p /grub/grub.conf

device (hd0) /dev/sdb
root (hd0,0)
install /grub/stage1 (hd0) /grub/stage2 p /grub/grub.conf
quit

ctrl+dでchrootを抜けて、shutdown -hする。
 ブートに使ったDVDや、バックアップデータのドライブを外して起動できることを祈りつつ電源On。

 まとめると簡単だが、諸々、設定しなきゃいけない項目、しなくても良い項目があったりして難しかった印象だ。
 この手順をベースにすれば、非RAIDからRAID、RAIDから非RAIDへの移動も出来る。
 お名前.com VPS(KVM)等、VPSでは基盤側が冗長化されているから、VPS上では単純ディスク構成であるが、そこで構築した環境を物理サーバに持ってきたいみたいな場合、非RAIDtoRAID構成のV2P(仮想から物理へ)変換を行わなければならないので、この手順をメモっておく。

(738)


カテゴリー: LAMP[Linux, Apache, MySQL, PHP], サーバ設定 | コメントをどうぞ

nginxでクライアントの接続調整をする

 リスティング広告を出していたりすると、出稿時に大量のアクセス(確認クローラ)が来てサイトの負荷が急上昇することがあるよね。

 さくらVPSお名前.com VPS(KVM)の2GBプランくらいでWordpress位の重さのページを素のまま表示させると、毎秒20アクセスとかで一杯一杯になる。

 そんな時は、nginxのリクエスト制御を使うと裏側の負荷上昇を穏やかにできる。

map $http_user_agent $ualimited{
    default ”;
    ~*googlebot 1;
    ~*msnbot 2;
    ~*bingbot 2;
    ~*slurp 3;
    …
}
limit_req_zone $ualimited zone=uazone:10m rate=10r/s;
server {
    …
    location / {
        …
        limit_req zone=uazone burst=200;
    }
}

 limit_req_zoneで、$ualmitedをキーにして、uazoneゾーンを毎秒10リクエストに制限する定義を作っている。
 で、ロケーション / に、limit_reqで定義したuazone制限を適用している。
※burstは、待ち行列の設定。 これが設定されていないと、リミットに達した時点で503エラーとなる。 burstが設定されていると、その値までのリクエストを待ち行列に突っ込んで、逐次処理することができる(burstを超えれば503になる) クローラが来た時にエラーを表示させると評価に問題が出るので、エラーではなく処理を遅延させて、正しく応答させる。
 limit_req_zoneの第一引数の値ごとにカウントするので、通常は$binary_remote_addrとかにして、リモートIPごとに制限するわけだけど、クローラは複数IPでガンガン来るので、ユーザエージェントで判別したいので、mapを使っている。
 if文で制限を直接設定できなかったので、UserAgent文字列から数値型にマッピングして、定義されているUAの場合に数値を与えて、それ以外の時は空にしてある。

 Wordpressであれば、/wp-content以下のファイルはスタティックで処理負荷が軽いので

    location / {
        …
        limit_req zone=uazone burst=200;
    }
    location /wp-content {
        …
    }

のように、wp-contentのロケーションを切れば、wp-content以下には要求制限がかからなくなる。

 前回のプロクシキャッシュを有効化して、

proxy_cache_path /dev/shm/c levels=1:2 keys_zone=cachezone:512m;
server{
    location / {
        …
        limit_req zone=uazone burst=200;
    }
    location /wp-content {
        …
        proxy_cache cachezone;
    }
}

のようにすれば、wp-content以下のスタティックファイルだけキャッシュすることができる。

(103)


カテゴリー: サーバ設定 | コメントをどうぞ

nginxのプロクシの裏側キャッシュを制御する

 nginxと裏のサーバ間のキャッシュを設定する。
 nginxのproxyでキャッシュする場合は、proxy_cacheを設定する。

proxy_cache_path /dev/shm/c levels=1:2 keys_zone=cachezone:512m;
server {
    location / {
        proxy_cache cachezone;
        proxy_pass http://appservers;
    }
}

 proxy_cache_pathでキャッシュの置き場所、置き方等を定義して、proxy_cacheでキャッシュ領域を割り当てる。
 で、この場合、プロクシを通過したデータを512Mまでキャッシュする。

 nginxでは細かい設定ができるのがイイね。

proxy_cache_path /dev/shm/c levels=1:2 keys_zone=cachezone:512m;
server {
    location / {
        set $dontcache 1;
        if ($request_filename ~* ".*\.jpg$"){
            set $dontcache 0;
        }
        if ($request_filename ~* ".*\.png$"){
            set $dontcache 0;
        }
        proxy_cache_bypass $dontcache;
        proxy_cache cachezone;
        proxy_pass http://appservers;
    }
}

 こうすると、要求されたファイル名がjpg, pngで終わるときしかキャッシュしない(proxy_cache_bypassに与えた値が0以外であるとき、キャッシュ機構をバイパスする)
 if文なので、$http_user_agent を使えばBOTと通常クライアントで異なる制御をしたりできる。
 また、特定のクッキーを持っている時だけバイパスするということも可能なので、開発ユーザにクッキーを食べさせておいて、該当クッキーをチェックするようにすると便利。

if ($cookie_author ~ “true”){
    set $dontcache 1;
}

みたいなこともできるし、そもそも、$cookie_author を 1/0 で制御するなら

proxy_cache_bypass $dontcache $cookie_author;

でも大丈夫。

(26)


カテゴリー: サーバ設定 | コメントをどうぞ

nginxで、入り口でまとめて認証をかける

 リリース前のサイトを本番環境でテストするとき、認証をかけたりするよね。
 DNSラウンドロビンとかLVSでバランシングしているときは、各ホストに.htaccessと.htpasswd書いたりするわけだけど、nginxでバランシングしている場合は、nginxの設定ファイルにまとめてかける。

server {
listen 80;
server_name hoge.tld;

location / {
auth_basic “auth”;
auth_basic_user_file “/usr/share/nginx/.htpasswd”;
proxy …
}
}

みたいな感じ。

nginxで認証を要求せず、裏のサーバが認証要求した場合には裏の認証要求が通る。
両方で認証を要求すると同じユーザ名:パスワードのセットで認証出来れば通るけど、それ以外の時は認証不能になる。

(37)


カテゴリー: サーバ設定 | コメントをどうぞ

NGINXをProxy利用 = UpstreamでKeepaliveを使う

 バランシングのテストにお名前.com VPS(KVM)を3台契約して、1台をバランサ、2台をアプリケーションサーバ(Apace)として構築して試験中。

 デフォルト設定でNGINXを通すと、NGINX-Apache間がHTTP 1.0 Closeコネクションになるため、abとかで叩くとApacheのスレッドが大量に立ち上がる。 この状態だと、リクエストのたびに新しい通信が立ち上がってくるし、Apacheのプロセスが切り替わりまくるからパフォーマンス的に美味しくない。
 調べてみると、最近のNGINXではupstream.keepaliveのディレクティブを使うことで、裏の通信をKeepAlive接続にできるようになるので、早速導入して評価。

と、設定前に負荷試験。

abで同時接続100、10000回のGETを実行(400KBのHTML、GZIPで60KBになるファイル)
NGINXでGZIP/SSL処理してAPACHEにつなぐと、200requests/sec程度のスループットだった。

#nginx.conf

upstream appservers {
server 192.168.10.10:80;
server 192.168.10.11:80;
keepalive 1000;
}

server {
listen 443;
server_name _;

location / {
proxy_http_version 1.1;
proxy_set_header Connection “”;
proxy_pass http://appservers;
}
}

 upstream.keepaliveをセットするのと、proxy_http_versionを1.1に(KeepAlive実装)、proxy_set_headerでConnectionを空にする(デフォルトでは、Connection: closeを送信してしまうため)

 Apache側は

KeepAlive On
MaxKeepAliveRequests 1000
KeepAliveTimeout 15

としてみた。

 先と同じようにabを実行してみた結果、210requests/sec程度になった。 もともと、ネットワーク転送量がワイヤースピード近くに達していたため、速度的にはそれほど改善していない。
 しかし、サーバのリソース的には相当改善が見られた。 CPU使用率のSys値(ユーザプログラム以外の部分で消費される無駄)が低下した。
 重いアプリケーションを動作させている場合には、オーバーヘッドが低下する分だけ応答速度の向上が期待できそうだ。

(338)


カテゴリー: サーバ設定 | コメントをどうぞ