rsyslogとtelegraf
何となく syslog をイケイケに監視してオレカッケーをしたかった.
構成としては, 以下の通り.
- rsyslog でインフラのログを受信
- ローカルのtelegrafにTCPでぶん投げる
- telegraf が InfluxDBに保存
- Chronograf で眺める
rsyslogの設定
Fedora では /etc/rsyslog.d/
配下の設定を読み込む形になっていたので,
そこに telegraf.conf
を作成して以下の内容を記述する.
$ModLoad imudp $UDPServerRun 514 *.notice action(type="omfwd" Target="127.0.0.1" Port="6514" Protocol="tcp" TCP_Framing="octet-counted" template="RSYSLOG_SyslogProtocol23Format" queue.type="LinkedList" queue.filename="telegraf_fwd" queue.saveonshutdown="on" action.resumeRetryCount="-1" KeepAlive="on" KeepAlive.Probes="5" KeepAlive.Interval="10" KeepAlive.Time="10" ResendLastMSGOnReconnect="off")
TCP_Framing
がデフォルトだと traditional
なのだが, Telegraf 側が octet-counted
なので, これに合わせる.
合わせないと上手く Telegraf側で受信しない.
KeepAliveの設定はなくても良いかもしれない.
Telegraf の設定
/etc/telegraf/telegraf.con
の inputs.syslog
セクションを編集する.
[[inputs.syslog]] server="tcp://127.0.0.1:6514" keep_alive_period = "10s" read_timeout = "0"
read_timeout
がデフォルトで5秒となっているのだが,
これが有効だと, 1つのTCPコネクションで5秒が経過すると問答無用で対向にFIN ACK を送ってクローズしてしまう.
rsyslog 側では destruct TCP Connection
なんてログが大量に出力されて気付いた.
Telegraf がセッションをクローズした後に送られたメッセージはロストするため, 注意が必要.
omfwd: TCPSendBuf error -2027, destruct TCP Connection to 127.0.0.1:6514 [v8.1907.0 try https://www.rsyslog.com/e/2027 ]
最初はTCPキープアライブの設定を疑ったが, パケットキャプチャを眺めた感じ変わりがなかった.
今回は localhost でやり取りをする設定になっているので, これでよしとする.
PacemakerでPrometheusを冗長化する(Pacemaker編)
はじめに
せっかくLPIC304を取ったのに何もそれらしいことに活用できていないので, 監視ソフトのPrometheusの冗長化とかやってみようと思った次第である.
前提条件
- 2台のLinuxマシンがIP疎通可能な状態で準備できていること
今回は以下の2台を利用する.
Prometheus の簡易インストール
ダウンロードするバイナリのプロセッサタイプを間違えないよう注意.
# curl -O https://github.com/prometheus/prometheus/releases/download/v2.10.0/prometheus-2.10.0.linux-amd64.tar.gz -L # mkdir /opt/prometheus # tar xvf prometheus-2.10.0.linux-amd64.tar.gz -C /opt/prometheus/
それぞれのホストで, systemd 用のサービスファイルを以下の具合に作成
# /etc/systemd/system/prometheus.service # [Unit] Description=Prometheus server daemon After=network.target [Service] ExecStart=/opt/prometheus/prometheus-2.10.0.linux-amd64/prometheus --config.file=/opt/prometheus/prometheus-2.10.0.linux-amd64/prometheus.yml [Install] WantedBy=multi-user.target
# systemctl daemon-reload # systemctl start prometheus # systemctl status prometheus
http://<ノードアドレス>:9090
にアクセスしてそれっぽい画面が出力されたらインストールは完了である.
これを2台分実施する. クラスタに外れてる状態で勝手に起動すると困るので, enable にはしない方が良い.
Pacemaker によるクラスタの構築
基本は Linux-HA プロジェクトのクイックスタートガイド通りに実行する.
clusterlabs.org
パッケージのインストール
# apt-get install pacemaker pcs または # yum install pacemakr pcs
クラスタサービスの有効化
本環境では pacemaker
, corosync
, pcsd
がクラスタの動作に必要なデーモンであるので,
これらの enable と start を実施する.
/etc/corosync/corosync.conf
が存在しない場合は空ファイルを touch
しておく.
(ファイルが無いと pcs デーモンの起動の際に怒られて失敗する(場合がある))
# touch /etc/corosync/corosync.conf # systemctl start pcsd # systemctl enable pcsd # systemctl enable corosync # systemctl enable pacemaker
pcsd用ユーザの設定
pcs がクラスタ管理に利用するユーザ hacluster
について, ログインパスワードを設定する.
必ず両ノードで実施すること.
# passwd hacluster
設定後, どちらかのノード以下のコマンドを実行し, pcs にノード認証を行わせる.
Authorized と出力されれば問題なく認証が行なわれている.
# pcs host auth node1 addr=<ノード#1のアドレス> node2 addr=<ノード#2のアドレス> -u hacluster -p "<ユーザパスワード>" node1: Authorized node2: Authorized
クラスタ初期化
pcs cluster setup
で指定ノードでクラスタを構築する.
ここで動作している各デーモンのバージョンに差分があると死ぬ.
Error: node2: Old version of pcsd is running on the node, therefore it is unable to perform the action
なんて親切に出力してくれる.
ちなみに, マイナーバージョンまで合ってれば誤魔化せた.
# pcs cluster setup Prometheus-Cluster node1 node2 --force ... Cluster has been successfully set up.
空ファイルだった /etc/corosync/corosync.conf
に色々書き込まれていることが確認できる.
クラスタの初期セットアップが完了したので, クラスタを開始させる.
# pcs cluster start --all # pcs cluster status
クラスタ開始後にクラスタに関するプロパティの変更が行えるようになる.
- STONITH の無効化
# pcs property set stonith-enabled=false
- 2ノードで自動フェイルオーバが実行されるようにする(クォーラムを無視する)
# pcs property set no-quorum-policy=ignore
クラスタへのリソース登録
VIP
クライアントが Prometheus にアクセスする際のIPアドレスを登録する.
# pcs resource create VIP ocf:heartbeat:IPaddr2 \ > ip=192.168.16.35 cidr_netmask=24 \ > op monitor interval=15s
Prometheus
Prometheus もデフォルトで RA の定義があるので, これをクラスタに登録する.
# pcs resource create Prometheus service:prometheus
リソースのコロケーション制約の設定
VIPが設定されているノードでPrometheusが動作するように colocation 制約を設定する.
# pcs constraint colocation add Prometheus with VIP
この辺りまで実施すれば, 他問題がなければクラスタが稼動を初める.
他の問題とは, prometheus を片ノードでサービス登録していなかったり,
ルート領域が pacemaker のログで溢れていたりである.
正常に動作していればどちらのノードから pcs status
を発行しても以下のような出力が得られる.
# pcs status 抜粋 Online: [ node1 node2 ] Full list of resources: VIP (ocf::heartbeat:IPaddr2): Started node1 Prometheus (service:prometheus): Started node1
おまけ
確認系コマンド
- クラスタステータスの確認(
pcs cluster status
)
# pcs cluster status Cluster Status: Stack: corosync Current DC: NONE Last updated: Sun Jun 30 15:03:11 2019 Last change: Sun Jun 30 15:02:04 2019 by root via cibadmin on node1 2 nodes configured 2 resources configured PCSD Status: node1: Online node2: Online
- クラスタステータスの確認#2(
pcs status
)
# pcs status Cluster name: Prometheus-Cluster Stack: corosync Current DC: NONE Last updated: Sun Jun 30 15:03:43 2019 Last change: Sun Jun 30 15:02:04 2019 by root via cibadmin on node1 2 nodes configured 2 resources configured OFFLINE: [ node1 node2 ] Full list of resources: VIP (ocf::heartbeat:IPaddr2): Stopped Prometheus (service:prometheus): Stopped Daemon Status: corosync: active/disabled pacemaker: active/disabled pcsd: active/enabled
- クラスタの一般プロパティの参照
# pcs property Cluster Properties: cluster-infrastructure: corosync cluster-name: Prometheus-Cluster dc-version: 2.0.1-9e909a5bdd have-watchdog: false no-quorum-policy: ignore stonith-enabled: false
- 利用可能なリソースエージェントの一覧
出力に時間がかかる
# pcs resource list ocf:heartbeat:aliyun-vpc-move-ip - Move IP within a VPC of the Aliyun ECS ocf:heartbeat:anything - Manages an arbitrary service ocf:heartbeat:AoEtarget - Manages ATA-over-Ethernet (AoE) target exports ocf:heartbeat:apache - Manages an Apache Web server instance ocf:heartbeat:asterisk - Manages an Asterisk PBX ocf:heartbeat:AudibleAlarm - Emits audible beeps at a configurable interval ...
トラブル
Debian側のpcsコマンドが pycurl 云々のエラーで動作しない
libcurl
系がエラー出力に記載のバージョンと合うように調整する(libcurl3-gnutlsかな).
crm_mon
コマンドがないって言われる
yum なら pacemaker-cli
, apt なら pacemaker-cli-util
がパッケージとして入っている必要がある.
crm_mon
コマンドがインストールされていない場合 pcs status
コマンドなどを打った際に以下のエラーが出る.
Error: unable to run command crm_mon --one-shot --inactive: No such file or directory: 'crm_mon'
ノード再起動後に既存クラスタに再認識されない.
pacemaker サービスを再起動させようとするとハングする
CIBがノード間で正常に同期されない
上の3つの事象は結論として CIB の設定がノード間で異なっていたことに起因するものであった.
pcs cluster stop
を行おうとすると以下のようなログを出力し続けて pacemaker の停止が終わらない.
これのせいでログが膨れ上がってルート領域が溢れた.
こうなるとシステムの再起動も正常に実施できない状態になって大惨事である.
- ノード1
pacemaker-based [732] (cib_file_backup) info: Archived previous version as /var/lib/pacemaker/cib/cib-71.raw pacemaker-controld [737] (election_count_vote) info: election-DC round 170944 (owner node ID 2) lost: vote from node2 (Uptime) pacemaker-controld [737] (update_dc) info: Unset DC. Was node2 pacemaker-controld [737] (do_log) info: Input I_PENDING received in state S_PENDING from do_election_count_vote pacemaker-controld [737] (update_dc) info: Set DC to node2 (3.1.0) pacemaker-based [732] (cib_process_replace) info: Digest matched on replace from node1: ac2adcc396bcf584915ad51e4ef426ad pacemaker-based [732] (cib_process_replace) info: Replaced 0.34.4 with 0.34.4 from node1 pacemaker-based [732] (cib_file_write_with_digest) info: Wrote version 0.34.0 of the CIB to disk (digest: 621d39f18d6f54be5f4c900d543c5c00) pacemaker-based [732] (cib_process_request) info: Completed cib_replace operation for section 'all': OK (rc=0, origin=node1/crmd/341932, version=0.34.4)
- ノード2
pacemaker-based[14088]: error: Completed cib_replace operation for section 'all': Update does not conform to the configured schema ... pacemaker-controld[14093]: error: Sync from node1 failed: Update does not conform to the configured schema
pcs cluster cib
で両ノードの CIB を diff ってみると, 1行目にそれらしい差分があることが分かる.
どう見ても validate-with
プロパティのpacemakerのバージョンに差異が発生している.
恐らく pacemaker のバージョンが違う状態でクラスタを組もうとしたのが原因と考えられる.
# node1 CIB <cib crm_feature_set="3.1.0" validate-with="pacemaker-3.2" epoch="46" //* num_updates="2" admin_epoch="0" cib-last-written="Sat Jul 6 20:24:51 2019" update-origin="node2" update-client="crmd" update-user="hacluster" have-quorum="1" dc-uuid="1">
# node2 CIB <cib crm_feature_set="3.1.0" validate-with="pacemaker-2.6" epoch="19" //* num_updates="29" admin_epoch="0" have-quorum="1" cib-last-written="Tue Jul 2 14:30:52 2019" update-origin="node1" update-client="cibadmin" update-user="root" dc-uuid="2">
一旦この値をノード間で合わせて, クラスタが正常化するかを試してみる.
# cibadmin --modify --xml-text '<cib validate-with="pacemaker-2.0"/>'
直すと, クラスタが正常化したのでこれでヨシとする.
pacemaker を再起動したり, pcs cluster stop --all
も正常に動作するようになった.
- 参考
さいごに
見れば分かるが, Prometheus のデータ共有などは全く行っていないため, クラスタとしては不完全な状態である.
Pacemaker でどはまりして体力を使ったので, Prometheusについては別記事を書くこととする.
KVM ゲストとして Container-Linux を導入する
はじめに
以前の記事で構築した KVM on Gentoo で色々遊ぼうと思う.
今回は手始めに Container-Linux をゲストとして導入する.
なんで Container Linux のインストールをしようと思ったのかは分からない.
でもKVMで構築する上でハマる落とし穴1つずつにハマっていた感じだったので勉強になった.
Container-Linux の管理や, KVMホストの管理については別記事を用意する.
手順
1.OSイメージのダウンロード
この辺りのリリースノート を確認して,
この辺り から stable image をダウンロードする.
ダウンロードしたらチェックサムを確認して bzcat
で展開して適当な場所に置いておく.
2.ファイルシステム作成
以下のコマンドでファイルシステムを作成する.
qcow2形式でベースイメージに CoreOS のイメージを利用したファイルシステムを作成したことになる.
いわゆる差分イメージとして作成され, ベースイメージに対する差分が記録されるイメージとなる.
> sudo qemu-img create -f qcow2 -b /osimage/coreos_production_qemu_image.img container-linux00.qcow2
この時作成するイメージの場所は libvirt
のプールに登録されている場所が望ましい.
ちなみに差分を破棄したい場合は同じコマンドを打てば良い(再フォーマットされる).
3.ドメイン設定ファイルの作成
virt-install
コマンドによってドメインの設定ファイルを作成する.
普段は virt-install
と OS のインストールイメージを用いて,
ファイルシステムにOSをインストールする必要がある.
Container OS のイメージはインストールイメージではないため, インストール操作を実施する必要はない.
--import
オプションを利用することでインストールプロセスをスキップし,
指定したファイルシステムから起動するような設定をすることが可能となっている.
Container OS では後の手順でドメイン設定ファイルを編集する必要があるため,
libvirt に直接登録せずに, XML設定ファイルを出力する動作を指定している(print-xml
).
ちなみに, 完全なシミュレーション動作ではないため, ストレージの作成などは行われる点に注意.
必要に応じて --dry-run
オプションを付与すると良いと考えられる.
sudo virt-install --connect qemu:///system --virt-type kvm --import \ --name container-linux00 \ --ram 2048 --vcpus 2 \ --os-type linux \ --disk path=/var/lib/libvirt/images/container-linux00.qcow2,format=qcow2 \ --nographics --network bridge=privbr \ --accelerate \ --print-xml | sudo tee /var/lib/libvirt/container-linux/container-linux00/domain.xml
4.ignitionファイルの作成
公式ドキュメント を参考に Ignition config を作成する.
ネットワークの設定とユーザ設定をしておかないと救い用のないホストとなってしまうため注意.
ネットワーク設定
公式ドキュメント通りに設定しておくのが無難. 静的IPを設定する場合は下記のように記述しておく.
"networkd": { "units" : [ { "contents" : "[Match]\nMACAddress=XX:XX:XX:XX:XX:XX\n\n[Network]\nAddress=192.168.101.2/25\nGateway=192.168.101.126\n", "name": "10-ens3.network" } ] },
[Match]
項で何らかの条件を設定しておかないとループバックインターフェイスにアドレスが付与されて酷い目に会う(経験済み).
前の手順で domain.xml
を作成した時点でインターフェイスの物理アドレスは分かるので, それを条件に設定しておくと良い.
ユーザパスワードを設定しておきたい
Container OSはデフォルトではユーザに対してのログインを一切許容していない鬼畜仕様である.
公開鍵を登録してSSHログインする方法は幾つか紹介されているのを見かけるが, コンソールログインする設定はなかなか見かけない.
KVMでゲストに対してコンソール接続はできるけどネットワーク疎通が取れないというケースがある.
こういった時にコンソールログインできると便利なので設定しておきたい場合の手順を示す.
passwordHash
項を passwd.users
内のオブジェクトに挿入すれば良い.
抜粋すると以下のような設定となる.
"passwd": { "users": [ { "name": "core", "passwordHash": "$6$rXw/hoge$60wal<省略>ZAr1", "sshAuthorizedKeys": [ "ssh-ed25519 AAAA<省略>PI6fS alice@Lab_A" ] } ] },
問題は passwordHash
に渡す文字列の作成の仕方である.
これは /etc/shadow
内の暗号化パスワードの表記と全く同じもので,
平文パスワードにソルト値を追加したものをハッシュ化して得られる文字列である.
これを自前で作るのは Perl を使えばワンライナーで作成できる.
# perl -e 'print crypt("password", "\$6\$hogehoge");'
以下の文献を参考にしている.
http://www.unknownengineer.net/entry/2017/08/16/184537
上記のコマンドで得た値をそのまま貼り付ければ,
コンソールで接続した際に設定したパスワードで core
ユーザにログインできるようになる.
SSHの認証鍵の設定は ssh-keygen
によって得られた公開鍵をそのまま貼り付ければ問題ない.
今回は ssh-keygen -t ed25519
の出力を利用した.
5.ドメイン設定ファイルの編集
Container-OS は初回起動自に先の手順で作成した Ignition Config を利用して設定のプロビジョニングを行う.
そのために, 作成した Ignition Config を起動時にゲストのファイルシステムへ転送する必要がある.
qemu はゲスト起動時にファイルを転送する -fwd_cfg
オプションがあり, libvirt もこれを利用することができる.
公式ドキュメント通りに下記のコマンドを実行すれば良い.
domain=/var/lib/libvirt/container-linux/container-linux1/domain.xml ignition_file=/var/lib/libvirt/container-linux/container-linux1/provision.ign sed -i 's|type="kvm"|type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0"|' "${domain}" sed -i "/<\/devices>/a <qemu:commandline>\n <qemu:arg value='-fw_cfg'/>\n <qemu:arg value='name=opt/com.coreos/config,file=${ignition_file}'/>\n</qemu:commandline>" "${domain}"
1回目の sed によって, ドメインファイルで qemu のオプションを利用できるように設定する.
これを省くと後の libvirt へのドメイン登録時に怒られる.
2回目の sed によって具体的に qemu 実行の際のオプションを設定する.
これにより Ignition Config がゲストの /sys/firmware/qemu_fw_cfg/by_name/opt/com.coreos/config
に転送される設定で起動処理が行われる.
-fwd_cfg
オプションについての詳しい説明はこの辺りが参考になる.
6.ドメインの登録とゲストの起動及び動作確認
virsh define domain.xml
を実行すると libvirt の管理下に置かれる.
virsh start <ドメイン名>
で起動可能となる.
ドメイン名は virsh list --allP
で確認できる.
起動確認として, 以下を確認すると良いだろう.
いずれかが失敗した場合は Ignition ファイルか ドメイン設定ファイルを再確認する.
ignitionファイルを変更した時
マシンをリセットするだけだと変更は適用されない.
ファイルシステムを作り直すと適用されたのを確認したが, めんどくさい...
既に差分イメージが存在する場合でも下記を実行することでフォーマットされる.
> sudo qemu-img create -f qcow2 -b /osimage/coreos_production_qemu_image.img container-linux00.qcow2