2015年4月30日木曜日

cannot send list of active checks to [$IP]: host [$HOSTNAME] not found

概要

Zabbix Proxy で監視設定をしている際にタイトルのエラーがずっと発生していつまで経ってもホストの監視が有効にならなかった

環境

  • CentOS 6.6 64bit
  • Zabbix Server 2.0.5
  • Zabbix Proxy 2.0.14
  • Zabbix Agent 2.0.14

エラーの詳細

エージェント側とプロキシ側で以下のログがずっと出続けいる状態が発生しました

  • プロキシ側
    cannot send list of active checks to …
  • エージェント側
    no active checks on server …

監視対象のZabbix Agentの設定、分散監視するZabbix Proxyの設定はすでに完了しているものとします
設定とは具体的にはzabbix_agentd.confやzabbix_proxy.confの記載が完了していてプロセスも起動している状態です
またACL等も問題なく設定されている状態です

この状態で当該エラーが発生してホストの監視がずっと行われていませんでした

原因調査

Zabbix Agent側の設定やZabbix Proxy側の設定を散々変更してみたのですが、一向に解消されませんでした
原点に立ち返って再度ログを眺めてみると/var/log/zabbix/zabbix_proxy.logに以下のようなログが出ていました

failed to update local proxy configuration copy: invalid field name "items.filter"

このログを頼りに調査を続けるとどうやらZabbix Proxyに必要なMySQLのスキーマがおかしいことがわかりました

Zabbix ProxyはZabbix Serverとデータの同期を行っています
具体的にはホストの監視設定(アイテム等)になります
このときにZabbix Proxy側のスキーマがZabbix Server側のスキーマとあわずにうまくのデータが同期できていなかったようです

ここまで来てピンと来たのですが、Zabbix Serverは古くから使われているサーバでバージョンが古く「2.0.5」でした
対してZabbix ProxyとZabbix Agentは最近構築したサーバでここには最新のZabbix ProxyとZabbix Agentをインストールしていました
最新バージョンは2.4.5になります

対応方法

結論は

2.4.5のZabbix ProxyとZabbix Agentを一旦アンインストールして2.0.14のProxyとAgentを再インストールしました

になります
すべてyumで管理していたので

yum erase zabbix_proxy
yum erase zabbix_agent
yum erase zabbix

で最新バージョンのパッケージを削除し

rpm -ivh http://repo.zabbix.com/zabbix/2.0/rhel/6/x86_64/zabbix-release-2.0-1.el6.noarch.rpm
yum clean all
yum install zabbix-proxy
yum install zabbix-agent

で再度インストールしたあとに

mysql -u user -p zabbix < /usr/share/doc/zabbix-proxy-mysql-2.0.14/create/schema.sql

という感じで2.0系のDBスキーマをZabbix Proxy用に当ててあげれば問題なく動作しました

最後に

今回学んだ教訓は

Zabbix Serverのバージョンに合わせてZabbix ProxyとZabbix Agentのバージョンも合わせよう
そうしないとDBのスキーマが異なりうまく監視データをZabbix Proxy上に登録することができない

ということです
本当はセキュリティの関係とかもあって最新版を使いたいところなのですが、どうやらDBのスキーマの関係で無理なようです
マイナーバージョンは異なっていても問題ないようです

  • Zabbix Server 2.0.5 <–> Zabbix Proxy 2.0.14 の組み合わせでは問題なく動作した

新規でZabbix Serverも構築する場合は今回のような問題に遭遇することは少ないと思いますが
Zabbix Proxyを使って監視対象の新規サービスを増やす場合などに陥りそうです

2015年4月28日火曜日

CentOS に公式の MySQL の最新版を yum でインストールする方法

概要

CentOSにMySQLの最新版をyumコマンドでインストールしてみました
備忘録として残しておきます

環境

  • CentOS 6.6 64bit
  • MySQL 5.6.24

インストール

  • MySQL公式のリポジトリをインストール
rpm -ivh http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
  • clean 後にインストール
yum clean all
yum -y install mysql-community-server

mysql-community-client, mysql-community-common, mysql-community-libs, mysql-community-libs-compat も同時にインストールされます

  • 動作確認
service mysqld start

mysql -u root
  • 自動起動
chkconfig mysqld on
  • アドミンのパスワード設定
/usr/bin/mysqladmin -u root password 'new-password'
  • 任意のユーザ作成
select password('hogehoge');

でハッシュ化されたパスワードを作成して

grant select on test.* to 'test_r'@'localhost' IDENTIFIED BY PASSWORD 'ハッシュ化されたパスワードを入力';

2015年4月24日金曜日

CentOS でsupervisor を使ってシェルスクリプトとデーモン化してみた

概要

Supervisor は launchd, daemontools, runit のようなプロセスをデーモン化するためのツールです
デーモン化をプログラム上で実装するのが面倒くさい場合に使えるツールです
今回はCentOS上で supervisor を使ってシェルスクリプトをデーモン化してみました

環境

  • CentOS 6.3 64bit
  • supervisor 2.1.9

Supervisorのインストール

今回はepelリポジトリを追加してyumでsupervisorをインストールします
理由はインストールが簡単なのと起動スクリプトなど必要なリソースが揃っているからです
ただ、最新版のsupervisorをインストールしたい場合はyumではなくpythonのパッケージ管理の仕組みであるpiporeasy_installを使ってインストールすることをおすすめします
もしくはCentOSの6.6以上を使えばepelでも3系がインストールできるかもしれません
supervisorの2系はバージョン的にはかなり古く特にconfigファイルの書き方が3系とは全然違うのでご注意ください

rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum clean all
yum -y install supervisor

バージョンを確認してみます

rpm -qa | grep supervisor

supervisor-2.1-9.el6.noarch

デーモン化するシェルスクリプトの準備

基本は何でもOKです

今回は自分がGistで公開しているシェルスクリプトを使ってみます
何をするシェルスクリプトか説明すると

  • 指定したディレクトリ配下にあるファイルを別の指定したディレクトリに1ファイルずつ移行するシェルスクリプト

になります
以下一応、実行するためのインストール用のコマンドを記載しておきます

mkdir /opt/supervisor
cd /opt/supervisor
wget https://gist.githubusercontent.com/kakakikikeke/10dc7dc6dca2f0675989/raw/342f9defd96862a97573a3e08a2ac6737ce9ee6b/dir2dir.sh
wget http://www.mitchy-world.jp/itmemo/shell/download/06.zip
unzip 06.zip
mv 06/common1.sh .
sed -i -e 's/LOG_DIR=\/home\/mitchy\/log\//LOG_DIR=`pwd`"\/"/' common1.sh
sed -i -e 's/SYSTEM_LOG_LEVEL=INFO/SYSTEM_LOG_LEVEL=DEBUG/' common1.sh
sed -i -e 's/.\/common1.sh/\/opt\/supervisor\/common1.sh/' dir2dir.sh

デーモン化するためのsupervisorスクリプトを作成

supervisor.confという設定ファイルがあるのでこれに直接記載します
[include]という仕組みがありこれを使って別ファイルに設定を切り出すことも可能です

  • vim /etc/supervisord.conf
[program:dir2dir]
command=sh /opt/supervisor/dir2dir.sh /opt/supervisor/target_dir/ /path/to/source_dir/
autostart=true
autorestart=true
logfile=/var/log/supervisor/dir2dir.log

commandはそのまんまでsupervisor上で動作させるコマンドを記述します
シェル内でファイルの参照などで相対パスを記載している場合にうまく動作しない場合があるので絶対パスで記載しておくといいです
autostartはsupervisorの起動と同時にプログラムを起動するかのオプションです
trueの場合は自動で起動します
autorestartは起動しているプログラムがハングしたり何かしたらの影響で停止したときに自動で再起動させるかどうかを指定します
trueの場合はsupervisorが自動で再起動してくれます

他にもいろいろとオプションが存在しています
Webで検索するか/etc/supervisord.conf内にサンプルもあるので参考にするといいと思います

Supervisorを起動

ではsupervisorを起動してみましょう

service supervisord start

でOKです
supervisorには管理用のコマンドが用意されておりsupervisorctlを使うと現在supervisor上で動作しているプロセスの状態を確認することができます

supervisorctl で状態の確認

まずsupervisorctlを実行してみましょう
するとsupervisor>というプロンプトに変更すると思います
この状態でsupervisorctl用のコマンドを発行するができます

主に使用するのは以下の通りです

  • status
    動作中のプラグラムの一覧を表示します
    起動中のプログラムはRUNNINGになっています、FATALはプログラム自体が壊れている可能性があるのでプラグラムの修正が必要です
  • start
    指定したプログラムを起動します
  • stop
    指定したプログラムを停止します
  • reload
    supervisor.confを書き換えた場合にgracefulに設定を反映することができます

上記以外のコマンドはhelpというコマンドで確認できます
更に詳細にコマンドを確認したい場合はhelpのあとに確認したいコマンドを付与して実行すればOKです

ログを確認してみる

ログはプログラム本体が吐くログはもちろん出力されます
それとは別にsupervisorが各プログラムごとにログを出力してくれています
今回の場合はsupervisor.confに記載したlogfileという項目のパスに出力してくれています
基本的には何も出力されませんが、supervisorがプログラムを再起動した場合や開始、終了時にログを残してくれます

最後に

今回はバージョン2で実施しました
冒頭も記載しましたがバージョン3ではconfigファイルの書き方が変わっているのでご注意ください
また、今回のシェルもそうですがシェル自体が終了してしまうシェルの場合リトライを何度か実施して最終的にはFATALのステータスになります
supervisorの使いどころとしてはnohupや&でバックグラウンド実行していたプログラムをsupervisorに移行する感じでだと思います

2015年4月23日木曜日

Graphviz 各種 Tips

概要

GraphvizのTipsをメモ

環境

  • CentOS 6.6 64bit
  • Graphviz 2.26.0-10

Tips

画像を埋め込む方法

jenkins [label = <<TABLE><TR><TD><IMG SRC="jenkins.png"/></TD></TR></TABLE>>, shape = plaintext];

HTMLライクな構文を使用すると埋め込むことができる
上記の場合はdotファイルと同じディレクトリにpngファイルを配置すればOK
shape=plaintextを画像のオブジェクトを枠線を削除するために利用

複数のclusterに所属させる方法

複数のsubgraphに所属される方法とも言うと思います

subgraph cluster_one {
  label = "one";
  subgraph cluster_two {
    host001;
    label = "two";
    color = blue;
  }
}

subgraphの宣言の中にsubgraphを書けばOK
上記の場合はこんな感じになります
test.png

cluster内のオブジェクトがエッジで接続されている場合にオブジェクトを並列にする方法

subgraph cluster_one {
  label = "one";
  subgraph cluster_two {
    rank = same {
      host001 -> host002;
    }
    label = "two";
    color = blue;
  }
}

rank = sameを使います
host001とhost002は横に並びます
rankdir=LRにすると縦に並びます
test2.png
rank = sameを使わないと以下の通り
test2-2.png

2015年4月22日水曜日

Jenkins の Workflow Plugin を使ってみた

概要

JenkinsのWorkflow Pluginを使ってみました
ビルドをchainするプラグインは他にもBuild Pipelineなどがあります
今回使うWorkflowプラグインも同じような種類のプラグインですがBuild Pipelineで問題だった点をいろいろ解決してくれているプラグインになります
インストールから簡単なサンプルの動作まで紹介します

環境

  • CentOS 6.6 64bit
  • Jenkins 1.6.10
  • Workflow Plugin 1.5

各種インストール

  • Jenkins
    ここを参考にyumでインストールしました
    Workflowプラグインを動かすためには1.580.1以上のバージョンが必要です

  • Workflowプラグインのインストール

Jenkinsの管理 -> プラグインの管理 -> Workflow: Aggregator

をインストールします
依存するプラグインも一緒にインストールされます
プラグインをインストールしたらJenkinsを一旦再起動しましょう

Workflowジョブを作成する

普通にジョブを作成する手順と同じです
Build Pipelineの場合はジョブを「下流」「上流」でchainすることで実現し、ビューでBuild Pipelineビューを作りましたが、Workflowプラグインはビューを作成しません

ジョブの種類を選択する部分で「Workflow」という項目が増えているのでこれを選択することでWorkflow用のジョブを作成することができます
create_workflow_job.png
これを選択して適当なWorkflowジョブを作成してください

Groovy でジョブのフローを記述する

ここがWorkflowプラグインの一番の肝になると思います
ジョブの設定を開くと「Definition Groovy CPS DSL」という項目でフリーのテキストエリアでScriptを記載する部分があると思います
ここにGroovyスクリプトを記載していきます

Workflowプラグインはジョブの流れや処理をGroovyのスクリプトで制御できるプラグインになります

とりあえずHello world

まずはジョブを成功させてみましょう
以下のScriptを記述してジョブを保存してください

echo 'hello from Workflow'

hello_world_workflow.png

そしてジョブを実行してみましょう
ビルド結果を確認するとechoした文章が出力されていると思います
result_hello_world_workflow.png

またScriptは以下のように記載することもできます

echo("hello from Workflow");

書きやすい方で書いてみましょう

複数のジョブを実行してみる

今回は既存の複数のジョブをWorkflow用のジョブから順番に実行できるようにしてみます
既存のジョブ名はそれぞれ「test1_job」「test2_job」とします
以下のようのScriptを記載しましょう

build 'test1_job'
build 'test2_job'

保存してジョブを実行してみます

実行結果をみると指定したジョブが上から順に実行されましたというログだけが出ています
なのでWorkflowから実行したジョブのビルド結果は各ジョブのビルド結果を見る必要があります

とりあえず既存のジョブをchainするだけならWorkflow Pluginでも簡単にできました

最後に

今回はBuild Pipelineのようにジョブをchainすることが目的だったので紹介は以上ですが、Workflow Pluguinで用意されている機能はもっとたくさんあります
SCMからリソースを取得したり、分散ビルドしたり、成果物を保存したりといったビルドの基本的な機能も実装されているので、これらをGroovyで書くことができます

感想も

かなりちょっとしか使っていませんが使ってみた感想としてはまだまだ発展の余地はあるかなと思いました
Build Pipelineに比べて優れているのは、それぞれのジョブ同士が疎結合のままchainすることができるので、ジョブを単体で実行することができる状態を保つことができます
もう少し言うとBuild Pipelineを使うと必ず下流、上流が結びついているので単体で実行すると勝手に下流のジョブも流れてしまいます
また上流のビルドパラメータを下流に引き継ぐようなジョブを作成していると、必ず上流から実行しないとパラメータの値がないので下流のジョブを単体で実行することができません
この辺のジョブの疎結合はWorkflow Pluginのほうが優れている点だと思います

ただ、Workflow Pluginではフローの可視化ができなかったり、ビルド結果の詳細を確認するには実行したジョブ側を見なければいけなかったりといろいろと改善してほしいポイントはあると思いました
ジョブの一覧でも、どのジョブがWorkflowジョブなのか一見するとわからないので命名規則でカバーしなければいけないのか、、とかも感じまいsた

なので今のところは各自のユースケースにあったプラグインを選択すればいいと思いますが、個人的には今後はWorkflow Pluginが来ると思います
理由としてはやはりビルドの内容をGroovyで完全にコード化できる点かなと思います
Infrastructure as a Codeではないですが、ジョブの状態がコードがされていれば見える化もしやすいですし、git で管理することもできるのでジョブの内容自体をCIすることもできるようになると思います

えー、いろいろ書きましたがとりあえず好感触を得ることができました
今後の発展も期待して使い続けたいと思います

参考サイト

2015年4月16日木曜日

CentOS 6.6 に yum でJenkins をインストールする方法

概要

専用のリポジトリを追加すればyumでインストールおよびパッケージ管理できるみたいなので試してみました
過去に紹介した記事だとTomcat+warファイル方式でやっています
yum でインストールすれば起動スクリプトも作ってくれるので便利です

環境

  • CentOS 6.6 64bit
  • Jenkins
  • Java 1.8.0_31 (OpenJDK)

インストール

リポジトリ追加

wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key

で完了です
/etc/yum.repos.dにJenkins専用のリポジトリファイルを作成して検証のために公開鍵をrpmにインポートしています
インポートした鍵情報を確認した場合は

rpm -qa | grep gpg-pubkey

で表示される鍵情報のRPMに対して詳細情報を表示するオプションを付与して実行すればOKです

rpm -qli gpg-pubkey-xxxxxxxx-yyyyyy

xxxxxxxx-yyyyyy はランダムな文字列が入っているはずです

yum インストール

yum -y install jenkins

でOKです
2015/04/16 時点では1.609-1.1という最新版のJenkinsがインストールされました

インストールされたものを確認

  • JENKINS_HOME
    デフォルトでは/var/lib/jenkinsになっていました
    起動オプションで指定するだけなので変更したい場合はJenkinsの起動スクリプトを変更すればOKだと思います

  • warファイルの場所
    /usr/lib/jenkins/jenkins.war

  • Jenkinsのログ
    /var/log/jenkins/jenkins.log

  • その他一覧

インストールされた全資材を確認したい場合は-qliオプションで確認できます

rpm -qli jenkins-1.609-1.1.noarch

一応自分が確認した段階では以下の通りでした

/etc/init.d/jenkins
/etc/logrotate.d/jenkins
/etc/sysconfig/jenkins
/usr/lib/jenkins
/usr/lib/jenkins/jenkins.war
/usr/sbin/rcjenkins
/var/cache/jenkins
/var/lib/jenkins
/var/log/jenkins

動作確認

  • 起動と停止
service jenkins start
service jenkins stop

起動すると8080でLISTENします
既存のプロセス(Tomcatとか)が8080を使っている場合は停止してから実行してください
親プロセス配下に50個ほど子プロセスができるようです

java,28629 -Dcom.sun.akuma.Daemon=daemonized -Djava.awt.headless=true -DJENKINS_HOME=/var/lib/jenkins -jar /usr/lib/jenkins/jenkins.war --logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon--httpPo
  {java},28632
  {java},28635
  {java},28638
  ・・・
  この配下に更に50個ほどの子プロセスがあった
  • UIにアクセス

http://hostname:8080/
でJenkinsのホームにアクセスできます
デフォルトではID/PWは設定されていません

  • 自動起動設定
chkconfig jenkins on

service起動できるのでもちろんchkconfig も使うことができます

最後に

アップデートの検証までは実施していないのですがおそらくyumでupdateできると思います
できない場合はJenkinsの画面から実施する感じだと思います

2015年4月15日水曜日

Capistrano 3.4 を触ったのでメモ

概要

ようやくバージョン3を触ったので忘れないようにメモしておきます
インストールから簡単なレシピ作成まで実施してみました

環境

  • CentOS 6.6 64bit
  • Ruby 2.2.1
  • Gem 2.4.6
  • Capistrano 3.4.0

インストール

事前にRubyおよびGemのインストールは完了しておいてください

gem install capistrano

でインストールは完了です

初期化

cap install

適当なディレクトリに移動した上で上記のコマンドを実行しましょう
Capistranoの実行に必要なファイル群を自動で生成してくれます
Capistrano2ではcapifyというコマンドが使われていたのですが、それは使えなくなったようです

ファイル確認

cap install後に作成されるファイルは以下の通りでした

合計 12
drwxr-xr-x 3 root root 4096  4月 15 20:17 2015 config
drwxr-xr-x 3 root root 4096  4月 15 20:17 2015 lib
-rw-r--r-- 1 root root  837  4月 15 20:17 2015 Capfile

動作確認

cap console

指定したホストに任意のコマンドを発行できるようにしてみます

  • vim Capfile
require 'capistrano/console'

上記を追記します

  • vim config/deploy/production.rb
role :web, %w{host1 host2}

host1, host2 にはアクセスしたいサーバを指定します
IPでもOKです
host1, host2 にノンパスでSSHアクセスできるのであれば設定はこれでOKです
SSHに認証がある場合は以下も実施します

  • vim config/deploy/production.rb
set :ssh_options, {
  user: 'root',
  keys: %w(/path/to/key.pem),
  forward_agent: false,
  auth_methods: %w(publickey),
  passphrase: 'password'
}

上記はユーザがrootで公開鍵/path/to/key.pemを使ってパスワードに「password」を使って認証する場合の設定です
ポートは指定していないので22番になります
また上記の設定はすべてのサーバの認証に使われる情報なので今回の場合はhost1とhost2の両方で同じ認証である必要があります

設定は以上です
では実行してみましょう

cap production console ROLES=web

とするとproduction>というプロンプトになるのでコマンドを何か実行してみましょう
role :webで指定したhost1とhost2に同じコマンドが発行されてその結果が返ってくると思います

実行時に指定しているproductionを指定しないとconfig/deploy/staging.rbというファイルが読み込まれて実行されます
Capistrano3ではマルチ環境に対応しているため、サービス環境に対して実行したい場合はproductionを付与する必要があります

対話的ではありますがcap consoleだけでもできるようになっていればかなりオペレーションがかなり簡易になると思います

レシピを作成する

せっかくなので独自のレシピも作成してみましょう

  • vim config/deploy.rb
namespace :test do

  desc 'Show hostname'
  task :show_hostname do
    on roles :web do
      execute 'hostname'
    end
  end

end

上記を最下部に追記します
タスク自体は非常に単純でロール:webに属するサーバ郡に対してhostnameコマンドを実行するだけです
追記したらタスクを実行してみます

cap -T

でタスクの一覧が確認できます

cap production test:show_hostname

でタスクを実行することができます

今回はconfig/deploy.rbにレシピを追加しましたがどうやらlib/capistrano/tasks配下に.rakeファイルを作成していくのがCapistrano3では普通のようです

最後に

Capistrano2に慣れているとだいぶ使い勝手変わっているので初めは困惑するかもしれません
タスクの書き方は基本的には変わりませんが、duplicatedになっているメソッド等もありそうなので、ドキュメントを見ながら作成したほうがいいかと思います

Tips

デフォルトで用意してあるデプロイタスクが邪魔という場合にはCapfileに記載してあるrequire 'capistrano/deploy'をコメントアウトすればOKです
ただそうするとrestartというメソッドが使えなくなるのでconfig/deploy.rbに記載してあるdeployタスクも削除しないとエラーで怒られてしまいます