既存のdiskをソフトウェアRAIDに組み込む

子供のいたずらでPCの強制停止が頻繁に行われる昨今、いつHDDがお亡くなりになるかわからないので、自作PCソフトウェアRAIDを組んで、冗長化することにしました。

そのときのメモ。

まず、いま動いているHDDと同じ型のディスクを買ってきて、自作PCに組み込む。 (どうでもよいけれど、同じ型の2TBのディスクが2年前と同じ値段でした。)

partedで現状のディスクと同じパーティションを新しいディスクで区切る

[root@sv01 ~]# parted /dev/sda
GNU Parted 2.1
/dev/sda を使用
GNU Parted へようこそ! コマンド一覧を見るには 'help' と入力してください。
(parted) print
モデル: ATA WDC WD20EZRX-00D (scsi)
ディスク /dev/sda: 2000GB
セクタサイズ (論理/物理): 512B/4096B
パーティションテーブル: gpt

番号  開始  終了  サイズ  ファイルシステム  名前  フラグ

(parted)
(parted) mkpart primary 1049kB 600GB
(parted)
(parted) mkpart primary 600GB 1200GB
(parted)
(parted) mkpart primary 1200GB 2000GB

raidフラグをONに。

(parted) set 1 raid on
(parted) set 2 raid on
(parted) set 3 raid on
(parted)
(parted) print
モデル: ATA WDC WD20EZRX-00D (scsi)
ディスク /dev/sda: 2000GB
セクタサイズ (論理/物理): 512B/4096B
パーティションテーブル: gpt

番号  開始    終了    サイズ  ファイルシステム  名前     フラグ
 1    1049kB  600GB   600GB                     primary  raid
 2    600GB   1200GB  600GB                     primary  raid
 3    1200GB  2000GB  800GB                     primary  raid

(parted)

raidを組む。

※ここでは既存のディスクを組み込む準備をするため、初期をfault状態とする。 missingオプションがそれに当たるのだと思う。RAIDは1。デバイス数は2。

[root@sv01 ~]# mdadm --create /dev/md1 --level=1 --raid-devices=2 missing /dev/sda1
mdadm: Note: this array has metadata at the start and
    may not be suitable as a boot device.  If you plan to
    store '/boot' on this device please ensure that
    your boot-loader understands md/v1.x metadata, or use
    --metadata=0.90
Continue creating array?
Continue creating array? (y/n) y
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md1 started.
[root@sv01 ~]#
[root@sv01 ~]#
[root@sv01 ~]# mdadm --create /dev/md2 --level=1 --raid-devices=2 missing /dev/sda2
mdadm: Note: this array has metadata at the start and
    may not be suitable as a boot device.  If you plan to
    store '/boot' on this device please ensure that
    your boot-loader understands md/v1.x metadata, or use
    --metadata=0.90
Continue creating array?
Continue creating array? (y/n) y
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md2 started.
[root@sv01 ~]#
[root@sv01 ~]# mdadm --create /dev/md3 --level=1 --raid-devices=2 missing /dev/sda3
mdadm: Note: this array has metadata at the start and
    may not be suitable as a boot device.  If you plan to
    store '/boot' on this device please ensure that
    your boot-loader understands md/v1.x metadata, or use
    --metadata=0.90
Continue creating array?
Continue creating array? (y/n) y
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md3 started.

RAIDの状態表示(片方faultした状態になっている。)

[root@sv01 ~]# cat /proc/mdstat
Personalities : [raid1]
md3 : active raid1 sda3[1]
      781508416 blocks super 1.2 [2/1] [_U]

md2 : active raid1 sda2[1]
      585805632 blocks super 1.2 [2/1] [_U]

md1 : active raid1 sda1[1]
      585805632 blocks super 1.2 [2/1] [_U]

unused devices: <none>

RAIDを組んだディスクをフォーマットする。

mkfs -t ext4 /dev/md1
mkfs -t ext4 /dev/md2
mkfs -t ext4 /dev/md3

先ほどRAIDを組んだ新しいディスクと古いディスクの両方をmountして古いディスクからデータをコピーする

# 新しいディスク(RAID)のmount
mount /dev/md1 /mnt/hdd1
mount /dev/md2 /mnt/hdd2
mount /dev/md3 /mnt/hdd3
# 現行のディスクのmount
mount /dev/sdb1 /mnt/hdd11
mount /dev/sdb2 /mnt/hdd12
mount /dev/sdb3 /mnt/hdd13
# 現行のディスクからデータをコピーする
cp -rvp /mnt/hdd11/* /mnt/hdd1/.
cp -rvp /mnt/hdd12/* /mnt/hdd2/.
cp -rvp /mnt/hdd13/* /mnt/hdd3/.

現行のディスクをRAIDに組み込む

[root@sv01 ~]# mdadm --manage /dev/md1 -a /dev/sdb1
mdadm: added /dev/sdb1
[root@sv01 ~]#
[root@sv01 ~]#
[root@sv01 ~]# cat /proc/mdstat
Personalities : [raid1]
md3 : active raid1 sda3[1]
      781508416 blocks super 1.2 [2/1] [_U]

md2 : active raid1 sda2[1]
      585805632 blocks super 1.2 [2/1] [_U]

md1 : active raid1 sdb1[2] sda1[1]
      585805632 blocks super 1.2 [2/1] [_U]
      [>....................]  recovery =  0.0% (508992/585805632) finish=95.8min speed=101798K/sec

unused devices: <none>
[root@sv01 ~]#
[root@sv01 ~]#
[root@sv01 ~]# mdadm --manage /dev/md2 -a /dev/sdb2
mdadm: added /dev/sdb2
[root@sv01 ~]#
[root@sv01 ~]#
[root@sv01 ~]# mdadm --manage /dev/md3 -a /dev/sdb3
mdadm: added /dev/sdb3

リビルドが終わったらこんな感じ。放置して寝てたからわからないけれど、数時間かかった模様。

# 完成
[root@sv01 ~]# cat /proc/mdstat
Personalities : [raid1]
md3 : active raid1 sdb3[2] sda3[1]
      781508416 blocks super 1.2 [2/2] [UU]

md2 : active raid1 sdb2[2] sda2[1]
      585805632 blocks super 1.2 [2/2] [UU]

md1 : active raid1 sdb1[2] sda1[1]
      585805632 blocks super 1.2 [2/2] [UU]

unused devices: <none>

以上!

iptablesのnatテーブルとはなんぞや

やっとiptablesのnatテーブルがわかった。
いままで、名前の通り、nat的なことをしているんだろうってことはわかっていたし、 書かれている内容もsnatなら送信元アドレスの書き換えかとか、単語から意味を理解してた。 google先生に聞いて、真似すれば書けるし、読みもできる。ただ、漠然としていた。
言うなれば、英単語を知っているから、英文法を知らなくても、英語の文章が何となく理解できる感じ。

それが以下の記事の一言をみて、すっと腑に落ちた。

「NATとはパケット中のIPアドレスを書き換える技術です」
習うより慣れろ! iptablesテンプレート集(2):natテーブルを利用したLinuxルータの作成 (1/6) - @IT
当たり前やろって思われる方もいるかもしれないけれど、この一言でなんか納得がいった。
送信元のアドレスや送信先アドレス、はたまた送信先ポートとか、なんか通信をいじろうと思ったら、NATテーブルに書けばいいのかと。

-j のターゲットオプションのところで、送信元アドレスを書き換えたければSNATを指定、送信先ならDNAT、送信元ポートなら--sportという風に指定してあげればよい。

アドレスとポートの両方同時も以下のように書けばいけそう。

iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.0.1:8080

POSTROUTINGとかPREROUTINGとかの-Aオプションは理解にちょっと癖があるけど、L3スイッチのACLとかと同じ感じかな。
iptablesを一つのスイッチとみなして、通り抜ける前ならPREROUTING。通り抜けた後ならPOSTROUTINGだし、ホストから自発的に発生した通信がOUTPUTかな。

そのほか、iptablesへの書き方とは、以下のサイトがわかりやすかったと思うので、メモ!

ゼロから始めるLinuxセキュリティ(4):Linuxで作るファイアウォール[NAT設定編] (1/2) - @IT

gdb で Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6.x86_64 のエラー

珍しく、Cでちょっとしたプログラムを書いて、gdbデバッグしようとしたら、以下のエラー

Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6.x86_64

gdbから抜けて、rootで「debuginfo-install glibc-2.12-1.149.el6.x86_64」を実行すればよいと記事があったので、実行してみるも以下のエラー。

Could not find debuginfo for main pkg: glibc-2.12-1.149.el6.x86_64
Could not find debuginfo pkg for dependency package glibc-2.12-1.149.el6.x86_64

このエラーが出た時は、/etc/yum.repos.d/CentOS-Debuginfo.repo の enbledを0から1 ( 無効から有効 )にしてあげればよいらしい。

[root@dev001 C]# cat /etc/yum.repos.d/CentOS-Debuginfo.repo | grep enable
enabled=1

このあと、再度「debuginfo-install glibc-2.12-1.149.el6.x86_64」を実行すれば、無事にパッケージがインストールされ、gdbが通るようになりました。 私はCentOS-Debuginfo.repo自体を消していたので、他のサーバから持ってきました。。 同じような方のためにメモ

[root@dev001 C]# cat /etc/yum.repos.d/CentOS-Debuginfo.repo
[debug]
name=CentOS-6 - Debuginfo
baseurl=http://debuginfo.centos.org/6/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Debug-6
enabled=1

yum の エラー

ローカル環境をいじっているときに何気なくyum updateしてみたら、エラーが。。。 yumの設定はdefaultのcentのリポジトリ

Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=6&arch=x86_64&repo=os error was
14: PYCURL ERROR 7 - "couldn't connect to host"

あれ?なんか変な風にいじったままだったかなぁと思い、rikenのリポジトリに変更してみてもエラー。

http://ftp.riken.jp/Linux/centos/6/os/x86_64/repodata/repomd.xml: [Errno 12] Timeout on http://ftp.riken.jp/Linux/centos/6/os/x86_64/repodata/repomd.xml: (28, 'connect() timed out!')
Trying other mirror.
Error: Cannot retrieve repository metadata (repomd.xml) for repository: base. Please verify its path and try again

rikenもダメだったので、クライアント側がおかしいと判明。 ダメ元でiptablesを落としてみたら、yum listが通った。。 ログを確認するとがっつり弾いていたみたい。

Apr 18 18:08:36 vm01 kernel: IPTABLES_INPUT_LOG : IN=br0 OUT= MAC= SRC=134.160.38.1 DST=192.168.1.10 LEN=60 TOS=0x00 PREC=0x00 TTL=52 ID=0 DF PROTO=TCP SPT=80 DPT=36410 WINDOW=5792 RES=0x00 ACK SYN URGP=0
Apr 18 18:08:44 vm01 kernel: IPTABLES_INPUT_LOG : IN=br0 OUT= MAC= SRC=134.160.38.1 DST=192.168.1.10 LEN=60 TOS=0x00 PREC=0x00 TTL=52 ID=0 DF PROTO=TCP SPT=80 DPT=36410 WINDOW=5792 RES=0x00 ACK SYN URGP=0

たしかにping以外はローカルしか通してないけど、応答はOKだと思っていたんだけどなぁ。。。 iptablesの設定かな。

ググったら以下のような記事が。

iptablesを有効にすると「yum」や「dig」が利用できなくなります… - 人力検索はてな

確かにudpだからわからないのか。いやiptablesのログにはtcpって書いてあるけど。。。
よくわからない。

デーモンごとにulimitで設定した値を確認する

忘れないようにメモ。

あるデーモンにulimitを設定したい場合、起動スクリプトにulimitを記載する。

これでデーモン起動時にどうしたら値が設定されたことを確認できるかなーって話。

ユーザだったらulimit -nとか叩けば値が返ってくるのだろうけど。

 

答えは/proc/pid/limitsをcatすればわかった。

 

/etc/init.d/mysqlにulimit -n xxxとか追記。

どの場所に追記すれば良いか試してないけど、startとかする前でよいと思われ。

 

ちなみにulimitの参考は以下から。

Linuxコマンド集 - 【 ulimit 】 コマンドに割り当てる資源を制限する:ITpro

 

★あげる前

[root@mysql001 user]# cat /proc/1088/limits | grep "open files"
Max open files 5000 5000 files

 

★結構先頭のほうに追記してみた

 

[root@mysql001 user]# grep -n -C 3 ulimit /etc/init.d/mysql
42-
43-# If you change base dir, you must also change datadir. These may get
44-# overwritten by settings in the MySQL configuration files.
45:ulimit -n 10240
46-
47-basedir=
48-datadir=

 

 

★あげた後

 [root@mysql001 user]# /etc/init.d/mysql restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
[root@mysql001 user]#
[root@mysql001 user]# ps axuf | grep mysql
root 1431 0.0 0.0 107456 912 pts/0 S+ 23:57 0:00 \_ grep mysql
root 1294 0.0 0.1 106192 1504 pts/0 S 23:57 0:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --pid-file=/var/lib/mysql/mysql001.pid
mysql 1407 2.0 44.4 1077948 453928 pts/0 Sl 23:57 0:00 \_ /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/lib/mysql/mysql001.err --pid-file=/var/lib/mysql/mysql001.pid
[root@mysql001 user]#
[root@mysql001 user]# cat /proc/1407/limits | grep "open file"
Max open files 10240 10240 files

 

反映されたことが確認できたよー!

Macでansible sshできない解決編

ansible.cfgの書き方がわかった。

以下のサイトを参考。

https://raw.githubusercontent.com/ansible/ansible/devel/examples/ansible.cfg

 

[default] を頭につければよいみたい。

よし、実行。

 

ansible -i inventory vm001.example.local -m ping

vm001.example.local | FAILED => SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue

 

あれ?やっぱり鍵認証をしているみたい。。。

よくよく調べると以下のオプションをつければ、パスワード認証になるみたい。

 

--ask-pass

 

よし!再実行!

 

ansible -i inventory vm001.example.local -m ping --ask-pass --ask-sudo-pass
SSH password:
vm001.example.local | FAILED => to use the 'ssh' connection type with passwords, you must install the sshpass program

 

むーおかしい。

さらに調べると以下のような記事が。

 

Ansible OS X Mavericks You Must Install the sshpass Program

 

OS X だと、sshpassがないんだね。

ブログにそって、sshpassをインストールし、実行するとようやくできた〜。

疲れた。。。

 

ansible -i inventory vm001.example.local -m ping --ask-pass
SSH password:
vm001.example.local | success >> {
"changed": false,
"ping": "pong"
}