ロックオン開発チームブログ -Lockon Knowledge Repositories-

Categoryサーバ

仮想化は便利です

ロックオンの看板オジサン、EBiSくんは、結構大がかりな構成でして、数十台のサーバー群で成り立っています。

開発後のテストも、環境を再現するのに苦労するのです。
が、最近はXenによる仮想化を使って楽にサーバー構成を再現できています。

構成は色々試しましたが、一番楽だなーと思った、Domain-0にCentOS4.4。Domain-UにはDebianを使っています。

 構築の仕方は色んなところにあるので、調べてもらうとして、ちょっとわかりにくかったのが、このエラー。

 

could not be connected. Backend device not found.

 

と出て、突然Domain-Uをcreate出来なくなります。

 

これは、ループバックデバイスが足りなくなってるとのこと。 

 

標準は8なので、倍にしてやりたければ 

# vi /boot/grub/menu.lst

に以下を追加すればOKです。 

 

 title Xen 3.0.3
        root(hd0,0)
        kernel /boot/xen-3.gz dom0=32768
        module /boot/vmlinuz-2.6.16.29-xen_3.0.3.0 ro root=LABEL=/max_loop=16
        module /boot/initrd-2.6.16.29-xen_3.0.3.0.img

 

 

ちょっと調べればわかるのですが、同じように「なんじゃこりゃ?」と思った人がエラーメッセージでググってたどり着いたらいいなぁと思って載せておきました。 

CVSUPサーバーの検索

FreeBSDのサーバーを構築するときにいつも決まったシェルスクリプトを用いていますが、 portsのアップデート時に接続先のCVSUPサーバーが落ちていることが最近よくあります。

その時、設定ファイルをいちいち書きなおして再実行してと、かなり面倒です。 それから自分は、システムユーティリティのfastest_cvsupを使うようになりました。

# cd /usr/ports/sysutils/fastest_cvsup
# make
# make install
# /usr/local/bin/fastest_cvsup -c jp
>> Querying servers in countries: jp
--> Connecting to cvsup.jp.freebsd.org [210.224.172.75]...
- server replied: OK 17 0 SNAP_16_1h CVSup server ready
- time taken: 3.43 ms
--> Connecting to cvsup2.jp.freebsd.org [203.216.196.85]...
- server replied: OK 17 0 SNAP_16_1h CVSup server ready
- time taken: 11.53 ms
--> Connecting to cvsup3.jp.freebsd.org [210.188.224.44]...
- server replied: OK 17 0 SNAP_16_1h CVSup server ready
- time taken: 10.53 ms
--> Connecting to cvsup4.jp.freebsd.org [133.1.44.1]...
- server replied: OK 17 0 SNAP_16_1f CVSup server ready
- time taken: 16.60 ms
--> Connecting to cvsup5.jp.freebsd.org [210.161.150.4]...
- server replied: OK 17 0 SNAP_16_1h CVSup server ready
- time taken: 23.17 ms
--> Connecting to cvsup6.jp.freebsd.org [210.188.224.44]...
- server replied: OK 17 0 SNAP_16_1h CVSup server ready
- time taken: 10.55 ms
>> Speed Daemons:
- 1st: cvsup.jp.freebsd.org
- 2nd: cvsup3.jp.freebsd.org
- 3rd: cvsup6.jp.freebsd.org

この結果から、日本の一番近いCVSUPサーバーは、cvsup.jp.freebsd.org ということがわかります。

また、サーバーに何らかの原因でつなぎにいけないときは、以下のメッセージが出ます。

* error: connect: timeout

この結果をシェルに組み込んでやることで、正常かつ一番近いサーバーに接続することができ、確実にportsをアップデートしてやることができます。

DebianにMRTGを入れてみよう!!

DebianにMRTGをインストールしてdisc I/Oを取得しようとしてちょっと躓いたことを書きたいと思います。


とりあえず簡単にインストールできるapt-getを使用。


$ apt-get install mrtg
$ apt-get install net-snmp


無事インストールを完了。


snmpd.confの設定も終え、snmpwalk動作確認をおこなったところ・・・

$ snmpwalk -v 2c -c private localhost .1.3.6.1.4.1.2021.13.15


・・・むむむ、なぜか取得できない!!


調べてみるとdisk I/OをONにしてインストールする必要があるとのこと。

という訳でtarボールを取ってきて手動でビルドしてやる事に。


$ tar zxf net-snmp-5.2.1.tar.gz
$ cd net-snmp-5.2.1
$ ./configure--with-mib-modules="ucd-snmp/diskio"
# umask 022
# make install


インストール完了!こんどはうまくいくかな?

$ snmpwalk -v 2c -c private localhost .1.3.6.1.4.1.2021.13.15

無事、取得できましたとさ。

mrtg.jpg

rsyncのバックアップと送信を自動化するスクリプト

Web開発において、コンテンツの同期にrsyncが使われるケースは多いと思います。
でも、いきなり実行するのはなんか怖いですよね。
バックアップもとらなきゃいけないし。

そういうときに、こんなスクリプトはいかがでしょう。
急ごしらえなのでツッコミ所があると思いますが。
./rsync.sh check
で、実行前にチェックしてくれます。
いわゆるdry-run。

./rsync.sh commit
で、 バックアップと送信。
バックアップはハードリンクなので、差分容量しか増えません。

#!/bin/sh

#rsyncへのパス
RSYNC=/usr/local/bin/rsync

#適当なシステム名
SYSNAME="hoge-system"

# 送信元ディレクトリ名
DIR_FROM="/home/hoge/hogehoge/"

# ローカルのバックアップディレクトリ名
BK_DIR="/home/backup/${SYSNAME}"

# 除外リストのパス
EX_FILE=/home/hoge/script/exclude.lst

# 通知メールの送信先
MAIL=hoge@example.com

# 送信先接続ユーザー
USER_TO="usernamae"

# 送信先ホスト
HOST_TO="127.0.0.1"

# 送信先ディレクトリ
DIR_TO="/home/hoge/"

backup()
{
  if [ `find ${BK_DIR} -name "${SYSNAME}-*" | wc -l` -eq 0 ]; then
    cp -R ${DIR_FROM}/ ${BK_DIR}/${SYSNAME}-0
  else
    for name in `ls -cr "${BK_DIR}" | grep "${SYSNAME}"`; do
      break;
    done
    echo $name
    VERSION=`echo $name | sed -e "s/${SYSNAME}-//"`
    NEWVERSION=`expr ${VERSION} + 1`
    NEW_BK_DIR=${BK_DIR}/${SYSNAME}-${NEWVERSION}
    mkdir ${NEW_BK_DIR}
    ${RSYNC} -avzp --delete --link-dest=${BK_DIR}/${name}/ ${DIR_FROM}/ ${NEW_BK_DIR}
  fi
}

rsync_copy()
{
    case $1 in
      commit)
            MODE="UPDATE "
            OPTS=""
            ;;
      check)
            MODE="CHECK MODE"
            OPTS=" -n "
            ;;
    esac

    echo ""
    echo "-------------------------------------------------"
    echo "** ${MODE} ${HOST_TO} server **"
    echo "-------------------------------------------------"

    ${RSYNC} -avzp ${OPTS} -e ssh --exclude-from=$EX_FILE $DIR_FROM $USER_TO@${HOST_TO}:${DIR_TO} | tee /tmp/${HOST_TO}.log
    cat /tmp/${HOST_TO}.log | mail -s "${MODE} ${HOST_TO}" $MAIL
}

# Parse command line parameters.
case $1 in
  commit)
        backup
        rsync_copy commit
        ;;
  check)
        rsync_copy check
        ;;
  *)
        # Print help
        echo "Usage: $0 {check|commit}"
        exit 1
        ;;
esac

rmにゴミ箱を!!

rmで誤ってファイルを消去しまうときがあります。
そこで、rmに仮想ゴミ箱機能を追加しましょう。

基本はゴミ箱へ移動されますが、容量をオーバーしたファイルは、古いものから自動で削除される仕組みです。

▼/var/alias/rm.sh(ファイルパスは任意です)
#!/bin/sh
#### config ####
BACKUP_DIR=/home/rm_backup     # ごみ箱の場所
BACKUP_DIR_DISK_SIZE_PER=1      # 指定パーティションの残容量に対するゴミ箱の容量の割合(1~100)%
#### error check ####
[ $BACKUP_DIR_DISK_SIZE_PER -eq 0 ] 2>/dev/null
if [ $? -ge 2 ]; then
   echo "\"BACKUP_DIR_DISK_SIZE_PER\" value is not integer." 
   exit
fi
if [ $BACKUP_DIR_DISK_SIZE_PER -lt 1 -o $BACKUP_DIR_DISK_SIZE_PER -gt 100 ]; then
   echo "\"BACKUP_DIR_DISK_SIZE_PER\" value is out of range (1~100)."
   exit
fi

df | awk '{ print $6}' | grep "/" > /tmp/partlist.txt

PARTLIST=`sed -e "s/\n/\s/" /tmp/partlist.txt`
BACKUP_ROOT_DIR=`echo $BACKUP_DIR | awk -F "/" '{ print $2; }'`

EXEC_FLAG=false

for p in $PARTLIST
do
if [ "/$BACKUP_ROOT_DIR" = "$p" ]; then
   EXEC_FLAG=true
   break
else
   EXEC_FLAG=false
fi
done

if [ $EXEC_FLAG = "false" ]; then
   echo "It must be set partision name to backup root dir."
   exit
fi

### alias exec ###


if [ ! -d $RM_BACKUP ]; then
   mkdir -p $RM_BACKUP
   chmod 777 $RM_BACKUP
fi
for param
do
   touch $param || exit 1
   mv $param $BACKUP_DIR/ || exit 2
done
### over size file in backup_dir delete ###
fnDelFile()
{
PERTISION_AVAIL_SIZE=`df | grep "$BACKUP_ROOT_DIR" | awk '{ print $4 }'`
BACKUP_DIR_TOTAL_DISK_SIZE=`expr $PERTISION_AVAIL_SIZE \* $BACKUP_DIR_DISK_SIZE_PER / 100`
BACKUP_DIR_CURRENT_DISK_SIZE=`du -s $BACKUP_DIR | awk '{ print $1}'`
if [ $BACKUP_DIR_CURRENT_DISK_SIZE -gt $BACKUP_DIR_TOTAL_DISK_SIZE ]; then
   DEL_FILE=`ls -tr $BACKUP_DIR | awk '{ print $1}'`
   rm -rf $BACKUP_DIR/$DEL_FILE || exit 3
fnDelFile
fi
}
fnDelFile
exit

そして、シェルスクリプトに実行権限を付与します。

------------------------
# chmod 755 /var/alias/rm.sh
------------------------
次に、シェル起動時の自動読み込みファイル(FreeBSDであれば、/etc/csh.cshrcなど)に以下のように記述してエイリアスを仕込めば、ゴミ箱つきrmの完成です。
--------------------
alias rm /var/alias/rm.sh
--------------------

screenでサーバー作業を共有

こんにちは。
最近、使う機会が多くなった、screenというコマンドをご紹介します。
まずはインストール、以下のコマンドで完了です。


▼Linux(RedHat)
# yum install screen
▼FreeBSD
# portinstall screen

それでは、早速使ってみましょう。
以下のコマンドで、セッションという名の新規スクリーンを作成します。

# screen -S <セッション名>

そして、作成したセッションに入ります。

# screen -r <セッション名>

例えば、リモートからsshなどで接続し、実行時間の長いシェルスクリプトを実行するとします。
通常、その接続した端末から接続を切断すると、実行が途中で終わってしまいます。
私はターミナルにpoderosaを使っていますが、複数画面を開いているときに、あ!知らない間に間違えて消してしまった!ということがよくありました。
あとは、実行終了までどうしても待てない、という時など。
しかし、スクリーン上から実行すると、いつでもそのスクリーンから抜けることができ、かつ次回そのスクリーンに入った時でも、実行は継続されています。
たとえば、データセンターでの作業の続きを、会社に帰ってもできるわけです。
以下で、いつでもスクリーンから抜けることができます。

Ctrlを押しながらad(aを押したあとd)

スクリーンから抜けることをデタッチといいます。
逆にスクリーンに入ることをアタッチといいます。
あと、上記のコマンドは、シングルユーザーモードなので、一端末しかそのスクリーンにアタッチすることができません。
スクリーンを複数の端末で共有するマルチユーザーモードも存在します。

# screen -x <セッション名>

例えば、端末Aと端末Bで、それぞれ上記のコマンドでアタッチすると、端末Aで入力した内容が端末Bでもリアルタイムに反映されます(その逆も然り)。
最近あったのが、サーバーメンテナンスで、私がデータセンター担当でもう一人が社内担当の2人で作業を行っていて、作業連絡中に私の携帯電話の電池がきれたのです。
そこでscreenを利用して、echoコマンドで対話のための用途に使ったりしていました。
ローマ字チャットです。
あとは、サーバー教育などの導入にももってこいだと思います。

と、今回は基本的な使い方について紹介しました。
とっても簡単なので、是非一度試してみてください。

次回は、このscreenを自分流にカスタマイズする方法について述べたいと思います。

ログローテーション

どうもこんにちは中川です。

Linux付属のログローテーション機能が、プロセスにシグナルを送らないと、
うまく動作しなかったりと挙動が気になったので、
ログローテーションスクリプトを自作しました。

logrotate.sh /var/log/php.log 10
のような感じで、ローテンションしたいログファイル名と、世代数を指定して、
定期的に実行するとgz圧縮されたログが蓄積していきます。
#!/bin/sh

if [ $# -lt 2 ]; then
        echo "Usage: $0 logfile maxcnt"
        exit 1
fi 

# initial
LOGFILE=$1
OUTDIR=`dirname $LOGFILE`
MAXCNT=$2
FILENAME=`basename $LOGFILE`
OUTPATH=${OUTDIR}/${FILENAME}

# move old log
rm -rf $OUTPATH.$MAXCNT.gz
CNT=$MAXCNT
while [ $CNT -gt 0 ]; do
        CNT=`expr $CNT - 1`
        if [ -f $OUTPATH.$CNT.gz ]; then
                mv $OUTPATH.$CNT.gz $OUTPATH.`expr $CNT + 1`.gz
        fi
done

# copy new log
cp $LOGFILE $OUTPATH.0  
gzip $OUTPATH.0

# clear new log
if [ -f $OUTPATH.0.gz ]; then
        echo -n "" > $LOGFILE
fi
Copyright(c) LOCKON CO.,LTD. All Rights Reserved.