RLB

Just sharing knowledge

tmuxやbashでターミナル画面が固まった時の対処法

Ctrl-Qすればだいたい直る

よくターミナル画面を操作してると、固まったりする。「通信エラーか」と思っていた。そして、静かに毎回ウインドウを閉じていた。

実は、その現象の殆どは「Ctrl-S」による出力ストップ(stop tty)。

意外と単純ですが、知らないとハマるので注意が必要です。

余談ですが光のように早いログを見るときなども、結構「Ctrl-S」は便利なので、割りと活用しています。

sedコマンドで改行(LF)に変換したいと思ったら、trコマンド

ついついテキスト処理で置換を思い浮かべると、sedが思いつきますが、意外と改行をまたぐ処理の場合がうまく動作しない。改行から変換はOKだが、逆パターン(文字列→改行コード)が意外と上手くいかない。他の言語のように簡単に\nで動いて欲しい。

実はそんな人のためにtrコマンド(translate characters)という便利なコマンドがあるので活用する。

#trは標準入力のみ受け付けるコマンドのためパイプで利用する
cat some.txt | tr "\n" ","

#逆も簡単
cat some.txt | tr "," "\n"

sedで改行を取り扱えなくもないが割りと不便だったりする。

#コマンドライン上から以下を入力する
sed some.txt 's/,/\
/g'

ワンラインで実行する場合は、切り替え後の文字列にエスケープとCtrl-V &Ctrl-J(=LF)を流し込めばOK。

ただ基本的にsedはあくまでも「行単位」の処理がメインで、改行をまたぐテキスト置換はawkやtrも組み合わせてやっていこう。

CentOS6にrbenv + ruby + rails + passengerを高速で環境構築(2013年度版)

f:id:rksz:20130217145457j:plain

よく手順書引き出しているのでブログに記載。変更あればこちらの記事を随時アップデート予定です。

インストール

(1) yum

yum -y install zlib zlib-devel readline readline-devel openssl openssl-devel curl curl-devel

zlibなどパッケージが無い状態でrubyインストールすると、no such file to load --zlibなど出て面倒なので、予め全部インストールしておく。

(2) rbenv & ruby (rubyバージョン管理)

cd /usr/local
git clone git://github.com/sstephenson/rbenv.git rbenv
mkdir rbenv/shims rbenv/versions
chgrp -R groupname rbenv
chmod -R g+rwxXs rbenv
git clone git://github.com/sstephenson/ruby-build.git ruby-build
cd ruby-build
./install.sh

/etc/profileの追記

export RBENV_ROOT="/usr/local/rbenv"
export PATH="/usr/local/rbenv/bin:$PATH"
eval "$(rbenv init -)"

rubyバージョン設定

rbenv install -v
rbenv install 1.9.2-p290
rbenv global 1.9.2-p290

(3) rails

gem install bundler rails

(4) passenger (apache起動用モジュール)

#インストール
gem install passenger
passenger-install-apache2-module
passenger-install-apache2-module --snippet

#出力後以下のようなメッセージが出るのでメモ
#----------------------------------------
#LoadModule passenger_module /usr/local/rvm/gems/ruby-1.9.2-p290/gems/passenger-
#3.0.18/ext/apache2/mod_passenger.so
#PassengerRoot /usr/local/rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.18
#PassengerRuby /usr/local/rvm/wrappers/ruby-1.9.2-p290/ruby
#----------------------------------------

vim /etc/httpd/conf.d/passnger.conf

# Passengerの基本設定。
# passenger-install-apache2-module --snippet を実行して表示される設定を使用。
LoadModule passenger_module /usr/lib64/ruby/gems/1.9.1/gems/passenger-3.0.19/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib64/ruby/gems/1.9.1/gems/passenger-3.0.19
PassengerRuby /usr/bin/ruby
# Passengerが追加するHTTPヘッダを削除するための設定。
Header always unset "X-Powered-By"
Header always unset "X-Rack-Cache"
Header always unset "X-Content-Digest"
Header always unset "X-Runtime"

# 必要に応じてPassengerのチューニングのための設定を追加。
PassengerMaxPoolSize 20
PassengerMaxInstancesPerApp 4
PassengerPoolIdleTime 3600
PassengerUseGlobalQueue on
PassengerHighPerformance on
PassengerStatThrottleRate 10
RailsSpawnMethod smart
RailsAppSpawnerIdleTime 86400
RailsFrameworkSpawnerIdleTime 0

参考

さくらVPS/CentOS 6.3 Passengerのインストール手順[Apache][Railsサーバへの道] http://morizyun.github.com/blog/passenger-install-apache-ruby-rails/

TmuxでWindow(Pane)のコマンドプリセットを用意する

Window分割〜コマンド実行のプリセットってだいたい同じだったりするので、用意する。

tmux_perspective_my_local_servers

#!/bin/sh
pane 11
tmux set-window-option synchronize-panes off 1>/dev/null
tmux rename-window 'my_local_servers'
tmux send-keys -t :.0  "ssh 192.168.1.1" C-m
tmux send-keys -t :.1  "ssh 192.168.1.2" C-m
tmux send-keys -t :.2  "ssh 192.168.1.3" C-m
tmux send-keys -t :.3  "ssh 192.168.1.4" C-m
tmux send-keys -t :.4  "ssh 192.168.1.5" C-m
tmux send-keys -t :.5  "ssh 192.168.1.6" C-m
tmux send-keys -t :.6  "ssh 192.168.1.7" C-m
tmux send-keys -t :.7  "ssh 192.168.1.8" C-m
tmux send-keys -t :.8  "ssh 192.168.1.9" C-m
tmux send-keys -t :.9  "ssh 192.168.1.10" C-m
tmux send-keys -t :.10 "ssh 192.168.1.11" C-m
tmux set-window-option synchronize-panes on 1>/dev/null

こちらの例でいえば、現在居るWindowを10分割して、それぞれ任意のサーバへSSHを同時接続を試みます。

上記を応用すれば、それぞれのpaneに対してローカルにcdだったり、リモート先でcdさせた状態でssh接続(ssh root@192.168.1.1 -t "cd /some/directory/; bash --login"')と色々出来ると思うので試してみて下さい。

どこからでも呼び出す

上記であれば、tmux_perspective_my_local_serversという長い名前ですが、これを適当にPATHが通っているところに、配置します。私の場合は、さらにそれに対するシンボリックリンクを作成し、そちら経由で利用しています。

ln -s tmux_perspective_my_local_servers tpmls

#実際に利用するときはtpmlsで呼び出す
tpmls

このtmuxのプリセットシリーズは増える傾向にあるので、混乱しないように正式名称を記載し、「tpXXコマンドはtmuxの画面プリセットを呼び出すシリーズだ」という流れで覚えて使っています。

画面分割コマンドPane

こちらは以下の記事に記載した画面分割コマンドなのでご参照下さい。これも合わせてPathを通せばOKです。 http://rksz.hateblo.jp/entry/2012/11/18_tmux_pane_command

IP変更のときはservice network restartはやめよう

自分への戒めをこめて。

IP変更

回線変更などでIPを変更する際、ifcfg-eth0等を編集したのちに、反映させるためにネットワークリスタートかけると思います、が

#設定
vim /etc/sysconfig/network-scripts/ifcfg-eth0

#リスタートでIP変更適応!
service network restart

あんまりにも切り替えてない(or 触ってない)マシンだと、たまに関係ないnicまでコケることがある。 これがVPNのプライベート側IPとかだと悲惨。というよりは・・・・実際に先日データセンタマシンが引き込まれてアクセス不能になった笑。

ただ、こういったケースの場合は「ハードウェアリブート」すれば大体直るので、そんなに心配することはなし。

こうする

必要最低限のnicのみリスタートにする。

ifdown eth0
ifup eth0

・・・何事も必要最低限が重要ですな。

GangliaをCentOS5とCentOS6で同期させる

f:id:rksz:20130211175828p:plain

RHEL5のyumで入るGangliaは3.0系のため、RHEL6の3.1系と全く互換性がない。そのため、残念ながら3.1.7のgmetadを使っても待てど暮らせど対象クライアントが追加されない・・・yummerにとってまさに痛手。今回は3.1.7(RHEL6系)をベースとして、CentOS5で同一バージョンのRPM作成する際の導入手順を記載します。

手順

とりあえず古いgangliaは削除

yum remove ganglia-gmetad ganglia-gmond

RPM作成のためにライブラリ以下ダウンロード

yum install libconfuse-devel libconfuse rrdtool rrdtool-devel perl-rrdtool pcre-devel apr-devel expat-devel freetype-devel gcc-c++ libart_lgpl-devel libpng-devel python-devel rpm-build
#不足があれば、rpmbuildでコケるので、適宜追加

Gangliaのソースファイルを取得(Sourceforge)

http://sourceforge.net/projects/ganglia/files/ganglia%20monitoring%20core/

なお、3.1.7を推奨。それより新しい場合だと、libexpat.1.soが必要となり、RHEL5系ではさらにインストールが面倒なため、スキップ。

RPM作成

rpmbuild -ta --target noarch /root/ganglia-3.1.7.tar.gz
rpmbuild -ta --target x86_64 /root/ganglia-3.1.7.tar.gz

以下にRPM作成されているはず。

ll /usr/src/redhat/RPMS/x86_64
-rw-r--r-- 1 root root 479370  211 17:00 ganglia-debuginfo-3.1.7-1.x86_64.rpm
-rw-r--r-- 1 root root  52208  211 17:00 ganglia-devel-3.1.7-1.x86_64.rpm
-rw-r--r-- 1 root root  38093  211 17:00 ganglia-gmetad-3.1.7-1.x86_64.rpm
-rw-r--r-- 1 root root 158903  211 17:00 ganglia-gmond-3.1.7-1.x86_64.rpm
-rw-r--r-- 1 root root  28552  211 17:00 ganglia-gmond-modules-python-3.1.7-1.x86_64.rpm
-rw-r--r-- 1 root root  45405  211 17:00 libganglia-3_1_0-3.1.7-1.x86_64.rpm

ll /usr/src/redhat/RPMS/noarch
-rw-r--r-- 1 root root 119222  211 17:02 ganglia-web-3.1.7-1.noarch.rpm

あとはrpmコマンドでインストール

rpm -ivh libganglia-3_1_0-3.1.7-1.x86_64.rpm
rpm -ivh ganglia-gmond*

これで無事に同期できます。手順にすると簡単ですな。

余談:Gangliaで図が出てこない(画像なしになる) [※追記: 2013/02/16]

1)network restart -> gmond restart

service network restart
service gmond restart

一回この方法をやってみて、直った。

2)初回のみ読み込みクライアント数を減らしてみる

大量に新クライアントを作成するとグラフが出来ないことがあった。

その場合、既に稼働している他のGmondクライアントを減らしてみて、一回単体で起動させたりすると・・・グラフが表示されるようになった(経験)。最初にちゃんとグラフ作成されると、ちゃんとグラフが読み込まれるようになった。こちら詳細は不明。アプリケーション内部を読む必要あり。

sshコマンドで手軽にログイン

前置き

1にssh、2にssh.... とりあえずリモートログインコマンドであるsshを実行する機会は非常に多いかと思います。 個人的にはインフラやバックエンド寄りの仕事が多いため、とにかく使用頻度が高い。 それを簡単に手軽にログインできる方法をまとめてみました。

つい最近lvsを組むことがあったので、以下を具体例として解説します。

hostname : lvs
対象DIR  : /etc/keepalived
接続先IP : 192.168.1.123
username : rksz

1. 公開鍵でsshパスワードなしログイン

まずは定番テクニック。 接続元ローカルマシンで以下のコマンドを発行して、全部Enterしておきましょう。

$ ssh-keygen

すると~/.ssh配下に以下のようはファイルができるはず

Ricky@localhost $ ll ~/.ssh
-rw-------  1 Ricky  staff  1675  6 29  2008 id_rsa
-rw-r--r--  1 Ricky  staff   401  6 29  2008 id_rsa.pub

中身はハッシュ文字列とhosts名などが記載されています。 id_rsa.pubに書かれている内容を接続したいサーバのknown_hostsに登録しましょう。

ローカルPC

$ scp id_rsa.pub rksz@192.168.101.1:/var/tmp

リモート先(rksz@192.168.101.1)

$ cat /var/tmp/id_rsa.pub >>~/.ssh/authorized_keys

~/.ssh/authorized_keysがない場合は、ディレクトリ含めて自分で作成します。(ssh-keyegenコマンドを発行すると.sshフォルダが出来るので良いとおもいます) あと、authorized_keysファイルのパーミッションは必ず600に設定します。

こうすれば、公開鍵を登録した先のマシンに対して晴れてパスワードなしログインができます。

$ ssh rksz@192.168.101.1

余談: いちいち鍵の設定するのが、面倒なあなたに朗報です。FreeBSD系, Fedora系(CentOSなど)※追加訂正(2013/05/17)ではssh-copy-idコマンドが用意されてるので、活用しちゃいましょう。

ssh-copy-id -i ~/.ssh/id_rsa.pub rksz@192.168.1.123

これで勝手にauthorized_keysの末尾に自分のpubkeyを追加してくれます。

まぁ特に上のコマンドが無ければ普通に以下でも実は可能です。

$ cat ~/.ssh/id_rsa.pub | ssh rksz@192.168.1.123 'cat >>~/.ssh/authorized_keys'

2. ssh configを活用

こちらを利用することで、host名を省略することができます。

$ ~/.ssh/config

その中に以下のファイルを作りましょう

Host p.123 p.lvs
  HostName 192.168.1.123
  User rksz
  Port 22

これでsshに絡むコマンドの際は以下だけで接続出来ます。

ssh p.lvs
ssh p.123

個人的に、Host名の所はp.s.などで統一しています。理由としてproductionサーバとstagingサーバを明確に区別するためです。p.(IPの末尾)やp.(HOSTNAME)という風にして追加しています。

3. zsh/bashのaliasを活用

基本的には上のssh configでも結構便利ですが、よく接続するサーバには"ssh ~"とコマンド打つこと自体無駄だと思いますので、bash aliasでショートカットを設定しましょう。

~/.bashrcに以下を追加します。

alias 'lvs'='ssh root@192.168.1.123'

こうすることで、lvsと文字を叩きこむだけで、sshコマンドが実行可能になります。 鍵を設定しておけば、それだけでログイン可能です。

私はログイン先で256系TERMが使えるところは利用したいとおもってるので、以下までalias設定しています。

alias 'lvs'='TERM=xterm-256color ssh root@192.168.1.123'

これでlvsと文字を打てば、自動でカラフルな接続先の誕生です!

もちろんここのalias指定の所で(2)で実施したssh aliasの設定も利用可能です。ただし、個人的にはconfig同士の結合度が高まってしまうため、独立して取り扱うようにしています。

4. sshしたあとにcdまで同時にやる

実際それぞれのサーバに対する用途って決まっていたりします。 dbであれば、/var/lib/mysql行きたかったりなど。 毎回ssh終わったあとにcdするのは無駄なので、これも勿論組み込んでしまいましょう。

.zshrcか.bashrcに以下のaliasを設定します。

alias 'lvs'='ssh root@192.168.1.123 -t "cd /etc/keepalived; bash --login"'

cdコマンドを発行した結果をbashでログインシェルとして利用しています。その結果を擬似端末(pseudo tty)利用できるようにsshの-tオプションを付加します。 tオプションを付けないと、ログインはしてるけど端末が割り当てられていない暗闇ダンジョン状態になるので、ヒマな時のみにしておきましょう。

5. mobile-shellを利用する

テスト環境などではmobile-shellもよくつかってます。かなり便利です。sshの代わりにmoshと打ってサーバに接続します。

#接続先サーバとローカルの両方にインストール
yum -y install mosh

「ローミングができる」「接続が切れても平気」「高速なローカルエコー」といった割りと至れりつくせりです。moshに関してはUDPのport60000周辺が必要なので、共用サーバに勝手にインストール・・・という訳にはいきませんが、自分の環境であれば全部入れてしまってよいと思います。ターミナルもデフォルトで地味に256color対応になっていたりと、ssh人であれば嬉しくなる機能満載です。

さらに

mysqlで本番サーバ直接参照できないから不便だなあ・・・sshでトンネル作れば余裕です。

#-N:リモートコマンド実行しない、-f:Background移行、-L:トンネル作成
ssh -N -f -L 9999:localhost:3306 rksz@192.168.1.124

#これでlocal port9999を指定するとリモートの3306に接続してくれる。
mysql -uroot --port 9999 -h 127.0.0.1

もちろんmysql(3306)じゃなくてもOK。ほかにもProxyCommandなど便利なものがあり、踏み台にして多段ログインなどもできます。

逆にいえば、ssh connectionさえ確立出来ればなんでも出来てしまうということです。もしネットワーク管理者で自社にVPNでリモートログイン出来るようにする際には、リモートデスクトップ(3389)系のポートのみ開放して、それ経由でsshなどしてもらうといいと思います。(さらに言えば、適当にグローバルからSSH出来るサーバを用意して、逆にリモート側から逆ポートフォワーディング(-Rオプション)をするとLAN同士をトンネル出来るので、結局、詳しい人には気休め程度にしかならない可能性はあり)

最後に

もっとssh力を付けたい場合は以下の資料がおすすめです。

さらにSSH力をつけねば。