PerlのNet::FTPでログインチェック
★設定が同じ構成のサーバを大量に構築した際、作成したユーザーがFTPでログイン可能かテストするスクリプト
#!/usr/bin/perl use strict; use warnings; use Net::FTP; ################################################### # SET VALIABLE ################################################### my $pass_file = $ARGV[0]; my $host_file = $ARGV[1]; my %hash; my @hostname; ################################################### # SET SUBROUTINES ################################################### sub ftp_connect { my ($hostname) = @_; my $ftp = Net::FTP->new($hostname) or die; } sub ftp_login { my ($hostname,$user,$pass) = @_; my $ftp = Net::FTP->new($hostname); $ftp->login($user,$pass) or die; $ftp->quit; } ################################################### # MAIN ################################################### if (@ARGV != 2) { die "Usage: perl FtpLoginCheck.pl <passward.list> <hostname.list>\n" } open(FH, "<", $pass_file); while (my $file = <FH>) { chomp $file; my ($_user, $_pass) = split /,/, $file; $hash{$_user} = $_pass; } close(FH); open(FH, "<", $host_file); @hostname = <FH>; close(FH); foreach my $host (@hostname) { chomp $host; printf "%-15s %-25s %-20s\n","==============","$host: [START]","=============="; foreach my $user (sort keys %hash) { eval { &ftp_connect($host); }; if ($@) { print "Connect [Failure] $host\n"; last; } eval { &ftp_login($host,$user,$hash{$user}); }; if ($@) { print "Login [Failure] $user\n"; } else { print "Login [Success] $user\n"; } } printf "%-15s %-25s %-20s\n\n","==============","$host: [END]","=============="; }
1.FTPでログインが許可されているユーザー、パスワードのリストを作成。
[root@ha-01 tmp]# cat passwd.lst root,xxxxxxxx abcd,xxxxxxxx masatoshi,xxxxxxxx [root@ha-01 tmp]#
2.対象サーバのホストリストを作成。
[root@ha-01 tmp]# cat host.lst hadoop-slave1 hadoop-slave2 hadoop-slave3 [root@ha-01 tmp]#
3.実行結果
[root@ha-01 tmp]# ./FtpLoginCheck.pl passwd.lst host.lst ============== hadoop-slave1: [START] ============== Login [Failure] abcd Login [Success] masatoshi Login [Success] root ============== hadoop-slave1: [END] ============== ============== hadoop-slave2: [START] ============== Login [Failure] abcd Login [Success] masathoshi Login [Success] root ============== hadoop-slave2: [END] ============== ============== hadoop-slave3: [START] ============== Connect [Failure] hadoop-slave3 ============== hadoop-slave3: [END] ============== [root@ha-01 tmp]#
puppetマニフェストメモ
★puppetマニフェストで使う変数の定義方法がいまいちわかってなかったのでメモ
■puppetの構成
[root@ha-01 puppet]# tree . |-- auth.conf |-- autosign.conf |-- fileserver.conf |-- manifests | `-- site.pp |-- modules | |-- hadoop | | `-- manifests | | `-- init.pp | `-- os | `-- manifests | `-- init.pp |-- namespaceauth.conf `-- puppet.conf 6 directories, 8 files [root@ha-01 puppet]#
■/etc/puppet/manifests/site.pp
[root@ha-01 puppet]# cat manifests/site.pp case $operatingsystemrelease { #facterコマンドで表示されるから定義する必要なし 5.6: { include common include hadoop_create_dir } 5.7: { include common } } class hadoop_create_dir { hadoop::create_dir{test:} } class common { os::etc{test: resolv => "192.168.11.1", # facterコマンドで表示されない変数は定義してあげる com => COMMON, # ↑ と同じ } } [root@ha-01 puppet]#
■/etc/puppet/modules/os/manifests/init.pp
[root@ha-01 puppet]# cat modules/os/manifests/init.pp define os::etc($resolv,$com) { # ← site.ppで定義した変数は「()」の中に「$」をつけて記述しておく file { "/etc/hosts": owner => root, group => root, mode => 644, content => template("/test/templates/$com/etc/hosts"), # ←「$com」はsite.ppで定義した「COMMON」になる } file { "/etc/resolv.conf": owner => root, group => root, mode => 644, content => template("/test/templates/$com/etc/resolv.conf"), # ←「$com」はsite.ppで定義した「COMMON」になる } case $network_eth0 { # ← facterコマンドで表示されるからそのまま使える "192.168.11.0" : { file { "/tmp/sample.txt": owner => root, group => root, mode => 755, content => template("/test/templates/$operatingsystemrelease/sample.txt"), } # ↑ facterコマンドで表示されるからそのまま使える } "192.168.100.0" : { file { "/tmp/sample.txt": owner => root, group => root, mode => 755, content => template("/test/templates/$operatingsystemrelease/sample.txt"), } # ↑ facterコマンドで表示されるからそのまま使える } } file { "/tmp/hostname.txt": owner => root, group => root, mode => 644, content => template("/test/templates/$hostname/hostname.txt"), } # ↑ facterコマンドで表示されるからそのまま使える } [root@ha-01 puppet]#
■site.ppで定義した変数「resolv => "192.168.11.1",」を配布する設定ファイル内に定義する時
例)
[root@ha-01 test]# cat templates/COMMON/etc/resolv.conf nameserver <%= resolv %> # ← <%= %> で囲むことで参照できる。「$」は付ける必要なし [root@ha-01 test]#
※配布するファイルは「content => template()」の「()」内のパスに配置してあげる。
デフォルトは「/var/puppet/templates」配下だけど、フルパスで書けばどこでもOK
★メモ
■puppetのver0.25以降だと正規表現が使える。「/」で囲んであげるとOK
例)
/^hadoop-slave[1-17]$/
■puppetマスターとpuppetクライアントで時刻が一致していないと認証に失敗してしまうので注意
■puppetmasterへの接続は、↓のコマンドラインだったらどっちでもOK
1. puppetd --no-daemonize --onetime --server ha-01 --verbose
2. puppetd --test --server ha-01
NETWORKアドレスとBROADCASTアドレスを取得するスクリプト
★「IPアドレス」と「サブネットマスク」の情報から「NETWORKアドレス」と「BROADCASTアドレス」を取得するスクリプト
#!/bin/sh ###################################################### # SET VARIABLE ###################################################### SHELL_NAME=`basename $0` HOSTLIST=$1 NET_LST=$2 LOG=./log/GET_NWADDR.$$ ###################################################### # SET ARGUMENT ###################################################### if [ $# -ne 2 ]; then echo "Usage : sh ${SHELL_NAME} <hostlist> <net.lst>" exit 1 fi if [ ! -f ${HOSTLIST} ]; then echo "Error : File not found [${HOSTLIST}]" exit 1 fi if [ ! -f ${NET_LST} ]; then echo "Error : File not found [${NET_LST}]" exit 1 fi ###################################################### # MAIN ###################################################### for HOST in `cat ${HOSTLIST}` do echo --------------------------- ${HOST} --------------------------- | tee -a ${LOG} ################################ # CHECK HOSTNAME ################################ grep -q ${HOST} ${NET_LST} if [ $? -ne 0 ]; then echo "Host is not found ${HOST}" | tee -a ${LOG} echo | tee -a ${LOG} continue fi ################################ # SET IPADDR & NETMASK ################################ IPADDR=`grep ${HOST} ${NET_LST} | awk -F, '{print $2}'` NETMASK=`grep ${HOST} ${NET_LST} | awk -F, '{print $3}'` ################################ # GET NETWORK & BROADCAST ################################ NETWORK=`ipcalc -n ${IPADDR} ${NETMASK} | awk -F= '{print $2}'` BROADCAST=`ipcalc -b ${IPADDR} ${NETMASK} | awk -F= '{print $2}'` printf "%s\n%s\n%s\n%s\n" IPADDR=${IPADDR} NETMASK=${NETMASK} NETWORK=${NETWORK} BROADCAST=${BROADCAST} | tee -a ${LOG} echo | tee -a ${LOG} done
1.ホストリストを作成
[root@ha-01 SHELL]# cat host.lst hadoop-slave1 hadoop-slave2 hadoop-slave3 [root@ha-01 SHELL]#
2.ホスト名、IPアドレス、サブネットマスクをコンマで区切ったリストを作成
[root@ha-01 SHELL]# cat net.lst hadoop-slave1,172.16.11.151,255.255.252.0 hadoop-slave2,192.168.11.152,255.255.255.0 hadoop-slave3,10.16.11.123,255.255.255.224 [root@ha-01 SHELL]#
3.実行結果
[root@ha-01 SHELL]# sh GET_NWADDR.sh host.lst net.lst --------------------------- hadoop-slave1 --------------------------- IPADDR=172.16.11.151 NETMASK=255.255.252.0 NETWORK=172.16.8.0 BROADCAST=172.16.11.255 --------------------------- hadoop-slave2 --------------------------- IPADDR=192.168.11.152 NETMASK=255.255.255.0 NETWORK=192.168.11.0 BROADCAST=192.168.11.255 --------------------------- hadoop-slave3 --------------------------- IPADDR=10.16.11.123 NETMASK=255.255.255.224 NETWORK=10.16.11.96 BROADCAST=10.16.11.127 [root@ha-01 SHELL]#
ssh-keygen自動化スクリプト
★ssh-keygenコマンドで対話形式の部分を自動化し、パスフレーズなしの「authorized_keys」を作るスクリプト
#!/bin/sh ################################# # SET VARIABLE ################################# DSA_PUB="${HOME}/.ssh/id_dsa.pub" KEYS="${HOME}/.ssh/authorized_keys" ################################# # MAIN ################################# ssh-keygen -t dsa -P "" << EOF EOF if [ ! -f ${DSA_PUB} ]; then echo "ERROR : File not found [${DSA_PUB}]" else cat ${DSA_PUB} >> ${KEYS} chmod 600 ${KEYS} fi
リモートホストに対してロケールでShift-JISを設定する
#!/bin/sh ########################################################## # SET VARIABLE ########################################################## CURDIR=`dirname $0` LOG=${CURDIR}/log/check_rsh.$$ HOSTLIST=$1 SHELL_NAME=`basename $0` RSH="/usr/bin/rsh" LOCALE="/usr/bin/locale -a" LOCALEDEF="/usr/bin/localedef -f SHIFT_JIS -i ja_JP ja_JP.SJIS" SJIS="ja_JP.sjis" DATE=`date | awk '{print $5}'` COUNT=1 ########################################################## # CHECK ARGUMENT ########################################################## if [ $# -ne 1 ]; then echo "USAGE : ${SHELL_NAME} <hostlist>" exit 1 fi if [ ! -f ${HOSTLIST} ]; then echo "ERROR : File not found [${HOSTLIST}]" exit 1 fi ########################################################## # MAIN ########################################################## for HOST in `cat ${HOSTLIST}` do ################################################## # CHECK HOSTNAME ################################################## grep -q ${HOST} /etc/hosts if [ $? -ne 0 ]; then echo "[Host not found] ${HOST}" echo continue fi ${RSH} ${HOST} "${LOCALE} | grep -q ${SJIS} ; echo \$?" > ${LOG} STAT=`cat ${LOG}` if [ ${STAT} -ne 0 ]; then ${RSH} ${HOST} "${LOCALEDEF} > /dev/null 2>&1" ${RSH} ${HOST} "${LOCALE} | grep -q ${SJIS} ; echo \$?" > ${LOG} _STAT=`cat ${LOG}` if [ ${_STAT} -ne 0 ]; then echo "[${COUNT}] ${DATE} [FAILURE] ${HOST} " echo else echo "[${COUNT}] ${DATE} [SUCCESS] ${HOST}" echo fi else echo "[${COUNT}] ${DATE} [SUCCESS] ${HOST}" echo fi rm -f ${LOG} COUNT=`expr ${COUNT} + 1` done
LVMでディスク管理
★fdiskでLVM用のパーティション作成して、PV、VG、LVの作成&削除はなにかと忘れやすいのでメモ。
1.LVM用パーティションの作成
[root@ha-01 ~]# fdisk /dev/vdb
2.パーティションの確認
コマンド (m でヘルプ): p Disk /dev/vdb: 10.4 GB, 10485760000 bytes 16 heads, 63 sectors/track, 20317 cylinders Units = シリンダ数 of 1008 * 512 = 516096 bytes デバイス Boot Start End Blocks Id System
3.新規パーティションの作成
コマンド (m でヘルプ): n コマンドアクション e 拡張 p 基本領域 (1-4) p 領域番号 (1-4): 1 最初 シリンダ (1-20317, default 1): Using default value 1 終点 シリンダ または +サイズ または +サイズM または +サイズK (1-20317, default 20317): +5000M
4.システムIDをLVMへ変更
コマンド (m でヘルプ): t Selected partition 1 16進数コード (L コマンドでコードリスト表示): 8e 領域のシステムタイプを 1 から 8e (Linux LVM) に変更しました
5.パーティションの確認
コマンド (m でヘルプ): p Disk /dev/vdb: 10.4 GB, 10485760000 bytes 16 heads, 63 sectors/track, 20317 cylinders Units = シリンダ数 of 1008 * 512 = 516096 bytes デバイス Boot Start End Blocks Id System /dev/vdb1 1 9689 4883224+ 8e Linux LVM
6.書き込み
コマンド (m でヘルプ): w 領域テーブルは交換されました! ioctl() を呼び出して領域テーブルを再読込みします。 警告: 領域テーブルの再読込みがエラー 16 で失敗しました: デバイスもしくはリソースがビジー状態です。 カーネルはまだ古いテーブルを使っています。 新しいテーブルは次回リブート時に使えるようになるでしょう。 ディスクを同期させます。
7.パーティションテーブルの再読み込み
[root@ha-01 ~]# partprobe
8.物理ボリュームの初期化
[root@ha-01 ~]# pvcreate /dev/vdb1 Physical volume "/dev/vdb1" successfully created
9.物理ボリュームの情報を表示
[root@ha-01 ~]# pvdisplay /dev/vdb1 "/dev/vdb1" is a new physical volume of "4.66 GB" --- NEW Physical volume --- PV Name /dev/vdb1 VG Name PV Size 4.66 GB Allocatable NO PE Size (KByte) 0 Total PE 0 Free PE 0 Allocated PE 0 PV UUID kKfHKQ-KaDD-ANpQ-K2ZA-a0Zn-heEA-lPWpgd
10.ボリュームグループの作成
[root@ha-01 ~]# vgcreate vg01 /dev/vdb1 Volume group "vg01" successfully created
11.ボリュームグループの情報を表示
[root@ha-01 ~]# vgdisplay vg01 --- Volume group --- VG Name vg01 System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 1 VG Access read/write VG Status resizable MAX LV 0 Cur LV 0 Open LV 0 Max PV 0 Cur PV 1 Act PV 1 VG Size 4.66 GB PE Size 4.00 MB Total PE 1192 Alloc PE / Size 0 / 0 Free PE / Size 1192 / 4.66 GB VG UUID c1lgvu-z7j9-zem3-Ygk9-Mp3J-hPt0-Sz6RkG
12.論理ボリュームの作成
[root@ha-01 ~]# lvcreate -L128M -n drbdmeta vg01 Logical volume "drbdmeta" created [root@ha-01 ~]# lvcreate -L4000M -n drbddata vg01 Logical volume "drbddata" created
13.論理ボリュームの情報を表示
[root@ha-01 ~]# lvdisplay /dev/vg01/drbdmeta --- Logical volume --- LV Name /dev/vg01/drbdmeta VG Name vg01 LV UUID ETpJdU-dcNF-fdwW-bwhd-eoDt-A8hL-bcLTCK LV Write Access read/write LV Status available # open 0 LV Size 128.00 MB Current LE 32 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 252:5 [root@ha-01 ~]# lvdisplay /dev/vg01/drbddata --- Logical volume --- LV Name /dev/vg01/drbddata VG Name vg01 LV UUID eSTz28-anPp-zTG3-o7da-B7LH-NtC0-cRBmtT LV Write Access read/write LV Status available # open 0 LV Size 3.91 GB Current LE 1000 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 252:6
★LVMの削除の流れは、作成の時とは逆でLV、VG、PVの順に削除する
1.論理ボリュームの削除
[root@ha-01 ~]# lvremove /dev/vg01/drbdmeta Do you really want to remove active logical volume drbdmeta? [y/n]: y Logical volume "drbdmeta" successfully removed [root@ha-01 ~]# lvremove /dev/vg01/drbddata Do you really want to remove active logical volume drbddata? [y/n]: y Logical volume "drbddata" successfully removed
2.ボリュームグループの削除
[root@ha-01 ~]# vgremove vg01 Volume group "vg01" successfully removed
3.物理ボリュームの削除
[root@ha-01 ~]# pvremove /dev/vdb1 Labels on physical volume "/dev/vdb1" successfully wiped
Bondingドライバの設定
★2つの物理NIC「eth1」と「eth2」の上に論理デバイス「bond0」を設定し、NICの冗長化を行う手順
1.「/etc/modprobe.conf」に対象のBondingデバイスを定義する。
論理デバイス「bond0」のaliasを追加し、デバイス・ドライバ「bonding」を指定
■「/etc/modprobe.conf」の設定 alias eth1 8139cp alias eth2 8139cp alias bond0 bonding
2.ネットワーク設定ファイル「eth1」と「eth2」の設定ファイルを編集
各設定ファイルで、bond0をマスターとし自身をスレイブ・アダプタとして指定
■「/etc/sysconfig/network-scripts/ifcfg-eth1」の設定 DEVICE=eth1 MASTER=bond0 SLAVE=yes BOOTPROTO=none HWADDR=54:52:00:1a:9d:de
■「/etc/sysconfig/network-scripts/ifcfg-eth2」の設定 DEVICE=eth2 MASTER=bond0 SLAVE=yes BOOTPROTO=none HWADDR=54:52:00:40:d5:f7
3.論理アダプター「bond0」の設定ファイルを作成
■「/etc/sysconfig/network-scripts/ifcfg-bond0」の設定 DEVICE=bond0 IPADDR=192.168.11.155 NETMASK=255.255.255.0 GATEWAY=192.168.11.1 ONBOOT=yes BOOTPROTO=static BONDING_OPTS="mode=1 primary=eth1 miimon=100 updelay=5000"
4.networkサービスの再起動
[root@ha-01 ~]# service network restart
5.Bondingデバイスの稼働状況確認。
[root@ha-01 ~]# cat /proc/net/bonding/bond0 Ethernet Channel Bonding Driver: v3.4.0-1 (October 7, 2008) Bonding Mode: fault-tolerance (active-backup) Primary Slave: eth1 (primary_reselect always) Currently Active Slave: eth1 MII Status: up MII Polling Interval (ms): 100 Up Delay (ms): 5000 Down Delay (ms): 0 Slave Interface: eth1 MII Status: up Speed: 100 Mbps Duplex: full Link Failure Count: 0 Permanent HW addr: 54:52:00:1a:9d:de Slave Interface: eth2 MII Status: up Speed: 100 Mbps Duplex: full Link Failure Count: 0 Permanent HW addr: 54:52:00:40:d5:f7 [root@ha-01 ~]#
★アクティブ・アダプタを手動で切り替える場合は、ifenslaveコマンドを使用する
例)eth2をbond0のアクティブに変更
[root@ha-01 ~]# ifenslave -c bond0 eth2
★メモ
「ifcfg-bondX」の設定で「BONDING_OPTS」の「primary」を指定している場合、
対象の「ethX」が優先的にアクティブになる。アクティブの「ethX」の障害後、復旧すると自動的にアクティブに戻る。
自動切り戻しを行いたくない場合は、「primary」パラメータを指定しないようにする。
この場合、サーバ起動時にアクティブのethファイルがどちらになるかはわからない。
起動時にアクティブに指定したい場合は、「/etc/rc.local」に「ifenslave -c bondX ethX」を記載し、
明示的に切り替えるよう指定する。