でんかのブログ

テクニカル系ネタをメインに、つれづれなるままに書いていきます。

USBのドライバインストールでのトラブル

USB周りの配線を整理していたら、UVC対応のWebCAMがどうしても認識しなくなってしまいました…。゚(ノД`)゚。

いろいろ悩んだのですが、結果として以下のページにある情報で解決しました!(゚∀゚) 【Tips】Windows 7でUSBデバイスがどうしても認識しないときは「usb.inf」を復活させると良い

このtipsは知らなかったので、はてなを久々に更新する意味もあり載せてみます(笑)

PuppetでOracleを自動インストール(Client編)

前回Databseの自動インストールと、Create Database後にサンプルスキーマ“scott/tiger”の作成までの自動化を紹介しました。今回は前回作ったスキーマへの接続テストとOracle Clientの自動インストールを紹介します!(`・ω・´)

マニフェストの実行

前回は実際にマニフェストを実行するところまで紹介していませんでしたが、あのままで問題なく実行できます。失敗すると面倒なので、まずはnoopオプション付けて実行します。

# puppet agent -t --noop
Info: Creating a new SSL key for cent65
Info: Caching certificate for ca
Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for cent65
Info: Certificate Request fingerprint (SHA256): 81:6A:FD:5C:1F:C7:99:02:67:0C:E5:70:45:50:A7:30:3C:B4:C9:1C:6C:C6:95:2E:DE:B1:81:20:7D:59:F2:E1
Info: Caching certificate for cent65
Info: Caching certificate_revocation_list for ca
Info: Caching certificate for ca
Info: Retrieving pluginfacts
Info: Retrieving plugin
Notice: /File[/var/lib/puppet/lib/puppet]/ensure: created
Notice: /File[/var/lib/puppet/lib/puppet/provider]/ensure: created
Notice: /File[/var/lib/puppet/lib/puppet/provider/db_rcu]/ensure: created
Notice: /File[/var/lib/puppet/lib/puppet/provider/db_directory_structure]/ensure: created
Notice: /File[/var/lib/puppet/lib/puppet/provider/file_line]/ensure: created
Notice: /File[/var/lib/puppet/lib/puppet/provider/sysctl]/ensure: created
Notice: /File[/var/lib/puppet/lib/puppet/provider/sysctl/darwin.rb]/ensure: defined content as '{md5}78e050af31aa8eefdca19d62c4fb4a3b'
   :
(すごく長いので中略)
   :
Notice: Node[cent65]: Would have triggered 'refresh' from 52 events
Notice: Class[Main]: Would have triggered 'refresh' from 1 events
Notice: Stage[main]: Would have triggered 'refresh' from 3 events
Info: Creating state file /var/lib/puppet/state/state.yaml
Notice: Finished catalog run in 43.59 seconds

エラーは出ませんでしたか?問題無ければnoopオプション無しで実行しましょう!(゚∀゚)

# puppet agent -t --noop

Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Loading facts
Info: Caching catalog for cent65
Info: Applying configuration version '1432794309'
Notice: /Stage[main]/Main/Node[cent65]/Package[libstdc++-devel.x86_64]/ensure: created
Notice: /Stage[main]/Main/Node[cent65]/Sysctl[net.ipv4.tcp_fin_timeout]/value: value changed '60' to '30'
Notice: /Stage[main]/Main/Node[cent65]/Sysctl[net.ipv4.tcp_fin_timeout]/permanent: permanent changed 'false' to 'true'
Notice: /Stage[main]/Main/Node[cent65]/Package[libXtst.x86_64]/ensure: created
Notice: /Stage[main]/Main/Node[cent65]/Group[dba]/ensure: created
Notice: /Stage[main]/Main/Node[cent65]/Sysctl[fs.file-max]/value: value changed '97938' to '6815744'
Notice: /Stage[main]/Main/Node[cent65]/Sysctl[fs.file-max]/permanent: permanent changed 'false' to 'true'
Notice: /Stage[main]/Oradb::Prepareautostart/File[/etc/init.d/dbora]/ensure: created
Notice: /Stage[main]/Main/Node[cent65]/Package[unixODBC-devel]/ensure: created
Notice: /Stage[main]/Main/Node[cent65]/Group[oinstall]/ensure: created
Notice: /Stage[main]/Main/Node[cent65]/Package[gcc.x86_64]/ensure: created
Notice: /Stage[main]/Main/Node[cent65]/Package[compat-libcap1.x86_64]/ensure: created
Notice: /Stage[main]/Main/Node[cent65]/Sysctl[kernel.shmmni]/permanent: permanent changed 'false' to 'true'
Notice: /Stage[main]/Main/Node[cent65]/Sysctl[net.core.rmem_default]/value: value changed '124928' to '262144'
Notice: /Stage[main]/Main/Node[cent65]/Sysctl[net.core.rmem_default]/permanent: permanent changed 'false' to 'true'
Notice: /Stage[main]/Main/Node[cent65]/Package[glibc.i686]/ensure: created
Notice: /Stage[main]/Main/Node[cent65]/Sysctl[kernel.shmall]/value: value changed '4294967296' to '2097152'
Notice: /Stage[main]/Main/Node[cent65]/Sysctl[net.ipv4.tcp_keepalive_intvl]/value: value changed '75' to '30'
Notice: /Stage[main]/Main/Node[cent65]/Sysctl[net.ipv4.tcp_keepalive_intvl]/permanent: permanent changed 'false' to 'true'
   :
(やっぱりすごく長いので中略)
   :
Notice: /Stage[main]/Main/Node[cent65]/Oradb::Tnsnames[db01]/Concat[/oracle/product/11.2/db/network/admin/tnsnames.ora]/File[/oracle/product/11.2/db/network/admin/tnsnames.ora]/content: content changed '{md5}41e548fe965599806003592864c9b5d1' to '{md5}0e249f21b702a27c2e779902a848b396'
Notice: /Stage[main]/Main/Node[cent65]/Oradb::Tnsnames[db01]/Concat[/oracle/product/11.2/db/network/admin/tnsnames.ora]/File[/oracle/product/11.2/db/network/admin/tnsnames.ora]/mode: mode changed '0640' to '0774'
Notice: /Stage[main]/Main/Node[cent65]/Exec[install sample]/returns: executed successfully
Notice: Finished catalog run in 1447.18 seconds

問題なく実行できましたか?今回はcreate databaseまで実行されるので、そこそこの時間を要すると思います。不幸にしてエラーが発生した時はエラーメッセージをよく読んで対処してください。(´・ω・`)

サンプルスキーマへの接続

それではサンプルスキーマ“scott/tiger”に接続してみましょう!(`・ω・´)

# sudo su - oracle

-bash-4.1$ sqexport ORACLE_SID=db01 ; sqlplus scott/tiger

SQL*Plus: Release 11.2.0.1.0 Production on Thu May 28 15:51:05 2015
Copyright (c) 1982, 2009, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Release 11.2.0.1.0 - 64bit Production

SQL> select table_name from user_tables;

TABLE_NAME
------------------------------
SALGRADE
BONUS
EMP
DEPT

SQL> select * from EMP;

     EMPNO ENAME      JOB          MGR HIREDATE     SAL       COMM
---------- ---------- --------- ---------- --------- ---------- ----------
    DEPTNO
----------
      7369 SMITH      CLERK       7902 17-DEC-80        800
    20

      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300
    30

      7521 WARD       SALESMAN        7698 22-FEB-81       1250        500
    30
   :
(長いので中略)
   :
14 rows selected.

SQL> quit
Disconnected from Oracle Database 11g Release 11.2.0.1.0 - 64bit Production

このように実行できましたか?無事実行できていればデータベースは問題なくインストールできています!(゚∀゚)

Oracle Clientの自動インストール

Oracle Databaseのインストールができていれば、Oracle Clientのインストールは簡単です!(゚∀゚)

マニフェストですが、グループとユーザ作成、必須パッケージのインストール、tnsnames.oraの設定はDatabaseと同じなので説明は省略します。あ、もちろん名前解決は適切にできるようにしておくのはDatabaseの場合と同じですので、マニフェストの中ではあえて触れませんが空気を読んでhostsなりdnsなり設定しておいてくださいね。(´・ω・`)

Client固有の部分は以下の“oradb::client”を呼び出すところです。

oradb::client{ '11.2.0.1_Linux-x86-64':
  version                => '11.2.0.1',
  file                   => 'linux.x64_11gR2_client.zip',
  oracleBase             => '/oracle',
  oracleHome             => '/oracle/product/11.2/client',
  user                   => 'oracle',
  group                  => 'dba',
  group_install          => 'oinstall',
  downloadDir            => '/install',
  puppetDownloadMntPoint => $puppetDownloadMntPoint,
  logoutput              => true,
  require                => [ User['oracle'],Package[$install] ],
}

属性値はDatabaseで説明したものと変わりはありませんね。ホントにこれだけなんです。ではその他必要な処理も加えてマニフェストを完成させましょう!(`・ω・´)

$all_groups = ['oinstall','dba' ,'oper']
 group { $all_groups :
  ensure      => present,
}

user { 'oracle' :
  ensure      => present,
  uid         => 500,
  gid         => 'oinstall',
  groups      => ['oinstall','dba','oper'],
  shell       => '/bin/bash',
  password    => 'xxxxxxxxxx', # openssl passwd -1で生成した値を記入
  home        => "/home/oracle",
  comment     => "This user oracle was created by Puppet",
  require     => Group[$all_groups],
  managehome  => true,
}

$install = [ 'binutils.x86_64', 'compat-libstdc++-33.x86_64', 'glibc.x86_64','ksh.x86_64','libaio.x86_64',
             'libgcc.x86_64', 'libstdc++.x86_64', 'make.x86_64','compat-libcap1.x86_64', 'gcc.x86_64',
             'gcc-c++.x86_64','glibc-devel.x86_64','libaio-devel.x86_64','libstdc++-devel.x86_64',
             'sysstat.x86_64','unixODBC-devel','glibc.i686','libXext.x86_64','libXtst.x86_64']
package { $install:
  ensure  => present,
}

oradb::client{ '11.2.0.1_Linux-x86-64':
  version                => '11.2.0.1',
  file                   => 'linux.x64_11gR2_client.zip',
  oracleBase             => '/oracle',
  oracleHome             => '/oracle/product/11.2/client',
  user                   => 'oracle',
  group                  => 'dba',
  group_install          => 'oinstall',
  downloadDir            => '/install',
  puppetDownloadMntPoint => $puppetDownloadMntPoint,
  logoutput              => true,
  require                => [ User['oracle'],Package[$install] ],
}

oradb::tnsnames{'cent65':
  oracleHome         => '/oracle/product/11.2/client',
  user               => 'oracle',
  group              => 'dba',
  server             => { myserver => { host => cent65, port => '1521', protocol => 'TCP' }},
  connectServiceName => 'db01.denka.orz.hm',
  connectServer      => 'DEDICATED',
  require            => Oradb::Client['11.2.0.1_Linux-x86-64'],
}

Client用マニフェストの実行

先のDatabaseの場合と同様に、最初はnoopで試しましょう。

# puppet agent -t --noop
Info: Creating a new SSL key for client
Info: Caching certificate for ca
Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for client
Info: Certificate Request fingerprint (SHA256): 7F:A8:A1:DB:DA:82:F8:2F:0C:A4:CF:69:36:22:BE:B1:52:57:CF:30:04:BE:92:7C:6A:78:4C:FF:06:ED:58:B8
Info: Caching certificate for client
Info: Caching certificate_revocation_list for ca
Info: Caching certificate for ca
Info: Retrieving pluginfacts
Info: Retrieving plugin
Notice: /File[/var/lib/puppet/lib/puppet]/ensure: created
Notice: /File[/var/lib/puppet/lib/puppet/provider]/ensure: created
Notice: /File[/var/lib/puppet/lib/puppet/provider/db_rcu]/ensure: created
Notice: /File[/var/lib/puppet/lib/puppet/provider/db_directory_structure]/ensure: created
Notice: /File[/var/lib/puppet/lib/puppet/provider/file_line]/ensure: created
Notice: /File[/var/lib/puppet/lib/puppet/provider/sysctl]/ensure: created
Notice: /File[/var/lib/puppet/lib/puppet/provider/sysctl/darwin.rb]/ensure: defined content as '{md5}78e050af31aa8eefdca   :
(やっぱりすごく長いので中略)
   :
Notice: /oracle/product/11.2/client/network/admin/tnsnames.ora: Would have triggered 'refresh' from 1 events
Notice: Concat[/oracle/product/11.2/client/network/admin/tnsnames.ora]: Would have triggered 'refresh' from 1 events
Notice: Oradb::Tnsnames[test]: Would have triggered 'refresh' from 1 events
Notice: Node[client]: Would have triggered 'refresh' from 17 events
Notice: Class[Main]: Would have triggered 'refresh' from 1 events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Info: Creating state file /var/lib/puppet/state/state.yaml
Notice: Finished catalog run in 12.73 seconds

問題無ければnoop無しで実行です!(`・ω・´)

# puppet agent -t --noop
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Loading facts
Info: Caching catalog for client
Info: Applying configuration version '1432796188'
Notice: /Stage[main]/Main/Node[client]/Package[libstdc++-devel.x86_64]/ensure: created
Notice: /Stage[main]/Main/Node[client]/Package[libXtst.x86_64]/ensure: created
Notice: /Stage[main]/Main/Node[client]/Group[dba]/ensure: created
Notice: /Stage[main]/Main/Node[client]/Package[unixODBC-devel]/ensure: created
Notice: /Stage[main]/Main/Node[client]/Group[oinstall]/ensure: created
Notice: /Stage[main]/Main/Node[client]/Package[gcc.x86_64]/ensure: created
Notice: /Stage[main]/Main/Node[client]/Package[compat-libcap1.x86_64]/ensure: created
   :
(やっぱりすごく長いので中略)
   :
Notice: /Stage[main]/Main/Node[client]/Oradb::Client[11.2.0.1_Linux-x86-64]/Exec[install oracle net 11.2.0.1_Linux-x86-64]/returns: Oracle Net Servicesの構成に成功しました。終了コードは次のとおりです。0
Notice: /Stage[main]/Main/Node[client]/Oradb::Client[11.2.0.1_Linux-x86-64]/Exec[install oracle net 11.2.0.1_Linux-x86-64]/returns: executed successfully
Notice: /Stage[main]/Main/Node[client]/Oradb::Client[11.2.0.1_Linux-x86-64]/Exec[remove oracle client file linux.x64_11gR2_client.zip 11.2.0.1_Linux-x86-64]/returns: executed successfully
Notice: /Stage[main]/Main/Node[client]/Oradb::Client[11.2.0.1_Linux-x86-64]/Exec[remove oracle client extract folder 11.2.0.1_Linux-x86-64]/returns: executed successfully
Notice: /Stage[main]/Main/Node[client]/Oradb::Tnsnames[test]/Concat[/oracle/product/11.2/client/network/admin/tnsnames.ora]/File[/oracle/product/11.2/client/network/admin/tnsnames.ora]/ensure: defined content as '{md5}b96d773e98aa6ab946c1fac0a5703208'
Notice: Finished catalog run in 358.49 seconds

無事実行できましたか?これだけでClientのインストールも完了です!(゚∀゚)

Oracle Clientからデータベースに接続

tnsnamaes.oraの設定さえ適切ならば、前述のサンプルスキーマでの手順と全く同じです。ただしsqlplusの接続文字列でtnsnames.oraに設定した名称を@に続けて記述する必要がありますので注意してください。

$ sqlplus scott/tiger@cent65

SQL*Plus: Release 11.2.0.1.0 Production on Mon Jun 8 00:12:18 2015
Copyright (c) 1982, 2009, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Release 11.2.0.1.0 - 64bit Production

SQL> select table_name from user_tables;

TABLE_NAME
------------------------------
DEPT
EMP
BONUS
SALGRADE

SQL> select ename from emp;

ENAME
----------
SMITH
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS

ENAME
----------
JAMES
FORD
MILLER

14 rows selected.

SQL> quit

Disconnected from Oracle Database 11g Release 11.2.0.1.0 - 64bit Production

おわりに

駆け足ではありましたが、PuppetによるOracleの自動インストールを紹介しました。Puppetを使うと、あの面倒なOracleインストールが、ものすごく簡単にできる事がお分かりいただけた事でしょう。(゚∀゚)

今回使ったbiemond/oradb”モジュールは、Grid Infrastructureなどにも対応しているので、ぜひお試しくださいね!(゚∀゚)

そしてサポート入ってないとモノが手に入らないため、試せず淋しい思いしている僕にレポートください(´・ω・`)

ArduinoでHTTP Server

GW前にArduinoを購入して以来、書籍「Arduinoで電子工作をはじめよう!」に載ってるサンプルを見ながらいろいろ実験してましたが、最初はちょっと値段が高い(と言っても3000円ちょいですが)ので躊躇してた、DFRduino Ethernet Shield V2.1を思い切って購入、HTTP Serverなサンプルスケッチをちょこっと改造して遊んでみました。(゚∀゚)

キャラクタ液晶と連携したおもちゃの製作を目論んでるので、サンプルスケッチにLCDのロジックを組み込んだモノを作ってみましたが、本当に簡単!30分も掛からず自宅LANに接続してメインPCのブラウザからアクセスできるようになりました!(゚∀゚)

f:id:denkas:20150607232659j:plain f:id:denkas:20150607232702j:plain f:id:denkas:20150607232704j:plain

画面のキャプチャはアナログポートからの入力値を表示するようになってますが、アナログポートには何も接続してないので、オープン状態の不定値です。でもちゃんと読み取って表示できてるし、それがこんなあっさりできるのはすごい!(゚∀゚)

これからちまちまアイディアを煮詰めておもちゃの製作を進めていこうと思います!(゚∀゚)

「Windows10を入手する」を消す

先月中ごろから「Windows10を入手する」アイコンがタスクトレイに現れて、無視してても表示しないように設定してても、しつこくしつこく出てくるので、どーしてくれようかと思ってましたが…(´・ω・`)

やっぱり同じコト思う人は多いようで、解決策が紹介されてました。(゚∀゚)

"Windows10を入手する"のアレをキレイに削除する方法 - 素敵なおひげですね

記事にも書いてありますが…ホント、こんなツールやめてほしいですよね…(;´∀`) WindowsUpdateで「推奨の更新」ってのも…どこが重要なんだと小一時間(ry

PuppetでOracleを自動インストール

Oracleのインストール、経験者ならわかると思いますが、ものすご~~~く面倒ですよね。(´・ω・`)

僕もはるか昔にSolarisOracleをインストールして以来、「Oracleインストールしてー(はぁと)」という言葉には身構えてしまいます。と、こ、ろ、が!今は昔と違うんですよ、奥さん!なんと!今ならPuppet使ってOracleが自動インストールできるんです!(゚∀゚)

え?どーせ自分でモジュール作ればってオチだろって?いえいえ違います!なんとORACLE ACEな方が作成されたPuppetモジュールを、今ならなんと、無料でご提供して貰えちゃうんですよー奥さん!今すぐお電話を!(ってドコにだ…)

…とまぁ、ヘタクソな通販番組ノリはここまでにしておいて(´・ω・`)、話の中身は本当です。“biemond/oradb”モジュールを使うと本当に本当に簡単ラクラクでOracleがインストールできちゃうんです。僕も最初は実は面倒なんぢゃね?って半信半疑だったのですが、使い方がわかれば本当に簡単。そんなワケで今回の記事は“biemond/oradb”モジュールでOracleインストールのお話です。(゚∀゚)

ちなみに“Puppetってナニ?(´・ω・`)”な方は「新人インフラ技術者のためのサーバー構築/運用自動化入門」最新記事一覧 - ITmedia Keywordsを先にご一読くださいませ。(゚∀゚)

“biemond/oradb”モジュールを使う準備

Puppet Labsが運営する“Puppet Forge”というモジュール共有サイトがあって、そこでは世界中のPuppetユーザが作成したPuppetのモジュールを公開しており、自由に入手できます。GitHubのPuppet専用版みたいなものですね。PuppetにはこのPuppet Forgeからモジュールを入手したり、キーワードで検索したりする機能があります。

Puppet Forgeへアクセスするには“puppet module”コマンドを使います。ここで“search”サブコマンドを使う事により、指定したキーワードにマッチするモジュールを表示できます。早速動かしてみましょう。ここではキーワードとして“oradb”を指定します。

# puppet module search oradb

Notice: Searching https://forgeapi.puppetlabs.com ...
NAME           DESCRIPTION                        AUTHOR        KEYWORDS
biemond-oradb  Oracle Database 11.2 / 12.1 li...  @biemond      fmw 11g 12c rcu

どうでしょう。このような結果になりましたか?もしここでキーワードに“oracle”とか指定するとすごい数のモジュールが出てきます。え?たくさん表示されたらどれ選べば良いかわからないですって?もっともです。そんな時はPuppet Forgeにアクセスして、画面上にある検索ボックスで検索しましょう。そうするとダウンロード数とスコアランキングが出てきます。ほとんどの場合はダウンロード数が多くてスコアが高いモノを選んで試してみるとよいでしょう。

今回は使うモジュールが“biemond/oradb”モジュールと決めています。これはBiemondさんが作られたoradbモジュールってコトなんですよね。まぁどうでもいいですか…。Biemondさんの経歴を見たらまさにOracleの神のような方で、さらに今はOracle社に居られるようですし、このモジュール使っておけば問題無いでしょう、たぶん。(´・ω・`)

では前置きが長くなりましたので、早速モジュールをダウンロードしちゃいましょう。“install”サブコマンドになります。

# puppet module install biemond-oradb

Notice: Preparing to install into /etc/puppet/modules ...
Notice: Downloading from https://forgeapi.puppetlabs.com ...
Notice: Installing -- do not interrupt ...
/etc/puppet/modules
mqw biemond-oradb (v1.0.33)
  tqq puppetlabs-concat (v2.0.0)
  mqq puppetlabs-stdlib (v4.6.0)

“biemond”と“oradb”の間はハイフンでもスラッシュでも、どちらでも大丈夫です。あとついでにモジュールを使う時にあると便利だと推奨されているモジュールも入れちゃいましょう。“fiddyspence-sysctl”モジュールと“erwbgy-limits”モジュールです。

# puppet module install fiddyspence-sysctl
Notice: Preparing to install into /etc/puppet/modules ...
Notice: Downloading from https://forgeapi.puppetlabs.com ...
Notice: Installing -- do not interrupt ...
/etc/puppet/modules
mqq fiddyspence-sysctl (v1.1.0)

# puppet module install erwbgy-limits
Notice: Preparing to install into /etc/puppet/modules ...
Notice: Downloading from https://forgeapi.puppetlabs.com ...
Notice: Installing -- do not interrupt ...
/etc/puppet/modules
mqq erwbgy-limits (v0.3.1)

まぁ名前のまんまの機能なモジュールですけど一応説明すると、fiddyspence-sysctl”モジュールはsysctl.confの編集機能で、“erwbgy-limits”モジュールがlimits.confの編集機能なモジュールです。

さて、残るは当たり前ですけどOracle本体をゲットしましょう。以下のURLからダウンロードできます。

Oracle Database Software Downloads | Oracle Technology Network | Oracle

必要なモノはdabtabaseとclientです。初期版はOTNに入っていればゲットできるのですが、パッチリリースはOracle Support必須で落とせないので、涙を呑んで11.2.0.1のx86_64をダウンロードしました。ただこの後ご紹介する11.2.0.1のマニフェストから、バージョンを指定する箇所やインストールファイル名の指定を変更するだけでそのまま使えるそうなので、どなたか11.2.0.4をお持ちの方、もし試されたら結果を教えてください…。m(_ _)m

ファイルのダウンロードが完了しましたら、/etc/puppet/modules/oradb/files に配置します。ファイル名はそのままで置いてくださいね。モジュールが気を利かせて1of2なファイルと2of2なファイルそれぞれダウンロードしてマージしてくれますので(最初わからなくてハマりました(´・ω・`))。以上で準備は完了です!(゚∀゚)

マニフェストの準備

ここからは一度だけでもOracleを手作業でインストールした経験があるのが望ましいです。内容がOracleのインストール手順を知っているのが前提になるってのもありますが、一度手作業で経験しておけば、いかにこのモジュールが偉大かわかりますしね。( ̄ー ̄)ニヤリ

でも一応「そんな面倒なコトやってられっかー!(#゚ロ゚#)」という気が短いOracle未経験な方向けに、簡単にOracleインストールの流れを説明しますね。流れはざっと以下のようなカンジです。

  1. oinstall、dba、operグループの作成とoracleユーザの作成

  2. kernelパラメータの設定とlimitsの設定

  3. 必須パッケージのインストール

  4. Oracle Universal Installerで本体のインストール

  5. 必要に応じてパッチの適用

  6. Net8の設定とリスナーの設定

  7. データベースインスタンスの作成

  8. インスタンスの起動設定

  9. tnsnames.oraの設定

かな~り端折って書いてもざっとこれだけの手順があります。そして3以降は大体ハマりどころがあるというオマケ付きです。はい、考えるのもイヤになりましたね。僕もイヤです。(;´∀`)ハァ…

そんなイヤな作業はPuppetさんにやって貰っちゃいましょう!Puppetさん、ステキ!(゚∀゚

事前準備(1~3)

先ほどの流れで1~3が事前準備フェーズです。ここのマニフェストをサクっと作っちゃいましょう。最初に注意点がひとつあります。後半の手順でNet8の設定がありますが、ここは自分自身のホスト名が名前解決できないとエラーになっちゃいます。なので忘れないようにマニフェストに書いておきましょう。こんなカンジです。

host {'cent65': ip => $::ipaddress, }

ウチの試験環境のホスト名は“cent65”なんでこの記述ですが、、皆さんは皆さんのホスト名を書いてくださいね、当たり前ですが。あとIPアドレスはfacter変数から取得するので、複数NIC搭載の環境でない限りはこのままで大丈夫ですが、複数NIC搭載されてるマシンの方は直接IPアドレス書いちゃうほうが良いかもです。あ、あとDNSなどで名前解決できる環境だったり、hostsの設定は確実にされている環境な方は別にこの行はいらないですので、念のため。(´・ω・`)

さて本題です。最初にグループ作っちゃいましょう。

$all_groups = ['oinstall','dba' ,'oper']
group { $all_groups :
    ensure      => present,
}

Puppetではリソース定義の際に配列を渡すと複数の定義をまとめて書けるんです。この記述、便利なんで覚えておきましょう。(゚∀゚)

さて、お次はoracleユーザですね。(`・ω・´)

user { 'oracle' :
  ensure      => present,
  uid         => 500,
  gid         => 'oinstall',
  groups      => ['oinstall','dba','oper'],
  shell       => '/bin/bash',
  password    => 'xxxxxxxxxx', # openssl passwd -1で生成した値を記入
  home        => "/home/oracle",
  comment     => "This user oracle was created by Puppet",
  require     => Group[$all_groups],
  managehome  => true,
}

簡単ですね!余談ですが、ここのrequire文は無くても問題無く動くんです。って言うとPuppet知ってる方は「実行順が不定なんだからダメじゃん」って言うかもですね。そうです、Puppetでは設定変えない限りはマニフェストの実行順はPuppetのみぞ知るなのです。なのでgroupリソースの次にuserリソース書いたからと言って、userリソースが実行されるときにグループが作成済とは限らない、つまりエラーになっちゃうんですよね。なのでrequireが入ってるワケです。「あれ?さっきいらないって言ったじゃん?」って思った人スルドイ!実はPuppetさん、このようなリソースの依存関係を暗黙で解決しちゃうんです。この機能、原文で“Implicit Dependencies(暗黙の依存)”となってるので、まさにそのまんまですね(笑)。でも書いたほうがわかりやすいのも事実なので、そういう機能もあるんだーくらいに思っておいて頂ければ。って、これじゃ何が言いたかったかわからないですね…ついでなんでPuppetの機能を紹介したまでです、はい。(´・ω・`)

気を取り直して、kernelパラメータとlimitsの設定しちゃいましょう。先ほどダウンロードしたモジュールで簡単にできちゃいます!(゚∀゚)

最初にkernelパラメータ(`・ω・´)

sysctl { 'kernel.msgmnb':                 ensure => 'present', permanent => 'yes', value => '65536',}
sysctl { 'kernel.msgmax':                 ensure => 'present', permanent => 'yes', value => '65536',}
sysctl { 'kernel.shmmax':                 ensure => 'present', permanent => 'yes', value => '2588483584',}
sysctl { 'kernel.shmall':                 ensure => 'present', permanent => 'yes', value => '2097152',}
sysctl { 'fs.file-max':                   ensure => 'present', permanent => 'yes', value => '6815744',}
sysctl { 'net.ipv4.tcp_keepalive_time':   ensure => 'present', permanent => 'yes', value => '1800',}
sysctl { 'net.ipv4.tcp_keepalive_intvl':  ensure => 'present', permanent => 'yes', value => '30',}
sysctl { 'net.ipv4.tcp_keepalive_probes': ensure => 'present', permanent => 'yes', value => '5',}
sysctl { 'net.ipv4.tcp_fin_timeout':      ensure => 'present', permanent => 'yes', value => '30',}
sysctl { 'kernel.shmmni':                 ensure => 'present', permanent => 'yes', value => '4096', }
sysctl { 'fs.aio-max-nr':                 ensure => 'present', permanent => 'yes', value => '1048576',}
sysctl { 'kernel.sem':                    ensure => 'present', permanent => 'yes', value => '250 32000 100 128',}
sysctl { 'net.ipv4.ip_local_port_range':  ensure => 'present', permanent => 'yes', value => '9000 65500',}
sysctl { 'net.core.rmem_default':         ensure => 'present', permanent => 'yes', value => '262144',}
sysctl { 'net.core.rmem_max':             ensure => 'present', permanent => 'yes', value => '4194304', }
sysctl { 'net.core.wmem_default':         ensure => 'present', permanent => 'yes', value => '262144',}
sysctl { 'net.core.wmem_max':             ensure => 'present', permanent => 'yes', value => '1048576',}

次にlimits.conf!(`・ω・´)

class { 'limits':
  config => {
             '*'       => { 'nofile'  => { soft => '2048'   , hard => '8192',   },},
             'oracle'  => { 'nofile'  => { soft => '65536'  , hard => '65536',  },
                             'nproc'  => { soft => '2048'   , hard => '16384',  },
                             'stack'  => { soft => '10240'  ,},},
             },
  use_hiera => false,
}

ちなみにこの設定値はサンプルの値そのまま引っ張ってるんで、実際に使う時はマニュアル見て設定してくださいね。(´・ω・`)

事前準備フェーズ最後の作業は依存パッケージのインストールです。これも配列使って簡潔に表現しちゃいましょう。(`・ω・´)

$install = [ 'binutils.x86_64', 'compat-libstdc++-33.x86_64', 'glibc.x86_64','ksh.x86_64','libaio.x86_64',
             'libgcc.x86_64', 'libstdc++.x86_64', 'make.x86_64','compat-libcap1.x86_64', 'gcc.x86_64',
             'gcc-c++.x86_64','glibc-devel.x86_64','libaio-devel.x86_64','libstdc++-devel.x86_64',
             'sysstat.x86_64','unixODBC-devel','glibc.i686','libXext.x86_64','libXtst.x86_64']
package { $install:
  ensure  => present,
}

これで事前準備フェーズのマニフェストは完成です!(゚∀゚)

Oracleインストール

それではメインディッシュ、Oracle本体のインストールです!(`・ω・´)

マニフェストとしては以下の内容です。

$puppetDownloadMntPoint = "puppet:///modules/oradb/"
oradb::installdb{ '112010_Linux-x86-64':
  version       => '11.2.0.1',
  file          => 'linux.x64_11gR2_database',
  databaseType  => 'SE',
  oracleBase    => '/oracle',
  oracleHome    => '/oracle/product/11.2/db',
  user          => 'oracle',
  group         => 'dba',
  group_install => 'oinstall',
  group_oper    => 'oper',
  downloadDir   => '/install',
  zipExtract    => true,
  puppetDownloadMntPoint => $puppetDownloadMntPoint,
  require       => Package[$install],
}

ここで設定すべき属性値は以下の通りです。

  • version

    バージョン番号を記述します。モジュールはこのバージョンを参照して動作を変えているようなので、適切な値を記述してください。

  • databaseType

    データベースのエディションです。EEもしくはSEを設定します。

  • file

    インストールイメージのファイル名を記述します。注意点としてはダウンロードしたファイルのファイル名は“linux.x64_11gR2_database_1of2.zip”と“~2of2.zip”となっていますが、“1of2.zip”な部分を省いたファイル名を記述します。つまり記述すべきファイル名は“linux.x64_11gR2_database_1of2.zip”と“~_2of2.zip”なら“linux.x64_11gR2_database”となるワケです。「2つあるのに、それでいいん?(´・ω・`)」と思われたかも知れませんが、いいんです。モジュールの中で気を利かせて(?)補完して処理してるので。(゚∀゚)

  • oracleBase、oracleHome

    通常のOracleインストールのORACLE_BASE、ORACLE_HOMEと同様の意味です。え?ちゃんと説明しろって?インストールマニュアルに詳しく書いてありますよん。(゚∀゚)ウケケ

  • user、group、group_install、group_oper

    これも通常のOracleインストールと同じなワケですが、最初に実施したユーザ作成とグループ作成で個性(?)を出してない限りは、基本この例のままで大丈夫です。

  • downloadDir

    インストールイメージをダウンロードして展開する場所です。2GB以上あるので、それなりに容量確保できるディレクトリを指定しましょう。

  • zipExtract

    インストールイメージを展開済みの場合はfalseにすればunzipしないようになりますが、まぁ通常はダウンロードしたままにしておいた方が管理も入れ替えもラクだと思います。(´・ω・`)

  • puppetDownloadMntPoint

    インストールイメージの取得先です。モジュールではインストールイメージの取得に、Puppetのfileリソースのsource属性でPuppet URLを使ってダウンロードしています。そのためインストールイメージを配置した場所をPuppet URL形式で記述しておきます。前に説明した通り、/etc/puppet/modules/oradb/filesにファイルを配置したのでしたら、この例にあるように“puppet:///modules/oradb/”になります。意味がわからないですって?そんなあなた!まずはPuppetを学ぶ — 序文 — Documentation — Puppet Labsを読みましょう!今なら日本語訳もあります!!(゚∀゚)

Net8、リスナーの設定

次はNet8とリスナーの設定です!(`・ω・´)

マニフェストとしては以下の内容です。

oradb::net{ 'config net8':
  oracleHome   => '/oracle/product/11.2/db',
  version      => '11.2',
  user         => 'oracle',
  group        => 'dba',
  downloadDir  => '/install',
  dbPort       => '1521',
  require      => Oradb::Installdb['112010_Linux-x86-64'],
}

db_listener{ 'startlistener':
  ensure          => 'running',
  oracle_base_dir => '/oracle',
  oracle_home_dir => '/oracle/product/11.2/db',
  os_user         => 'oracle',
  listener_name   => 'listener',
  require         => Oradb::Net['config net8'],
}

oradb::listener{'start listener':
  action       => 'start',  # running|start|abort|stop
  oracleBase   => '/oracle',
  oracleHome   => '/oracle/product/11.2/db',
  user         => 'oracle',
  group        => 'dba',
  listenername => 'listener',
  require      => Db_listener['startlistener'],
}

基本、この例のまま記述で問題ないかと思います。あ、もちろんディレクトリや名称など変更されたのなら、ちゃんと空気を読んで変更してくださいね。(´・ω・`)

データベースインスタンスの作成

残る大物、データベースインスタンスの作成です!(`・ω・´)

マニフェストとしては以下の内容です。

oradb::database{ 'testDb_Create':
  oracleBase              => '/oracle',
  oracleHome              => '/oracle/product/11.2/db',
  version                 => '11.2',
  user                    => 'oracle',
  group                   => 'dba',
  downloadDir             => '/install',
  action                  => 'create',
  dbName                  => 'db01',
  dbDomain                => 'denka.orz.hm',
  dbPort                  => '1521',
  sysPassword             => 'Welcome01',
  systemPassword          => 'Welcome01',
  dataFileDestination     => "/oracle/oradata",
  recoveryAreaDestination => "/oracle/flash_recovery_area",
  characterSet            => "AL32UTF8",
  nationalCharacterSet    => "UTF8",
  initParams              => {'open_cursors'        => '1000',
                              'processes'           => '600',
                              'job_queue_processes' => '4' },
  sampleSchema            => 'TRUE',
  memoryPercentage        => "40",
  memoryTotal             => "800",
  databaseType            => "MULTIPURPOSE",
  emConfiguration         => "NONE",
  require                 => Oradb::Listener['start listener'],
}

ここで設定すべき属性値は………と思ったのですが、Oracleはあまり詳しくない僕が書くよりもインストールマニュアルというものがありますので、そちらを参照してくださいませ。とりあえずインストールマニュアルに出てくる名称と属性名が同じモノは同じモノと考えて大丈夫です。(^-^;

一応この例で変更したところは、DB名を“db01”、DBドメインを“denka.orz.hm”としました。あとは面倒なんでサンプルのままにしてます…。(´・ω・`)

あ、それと依存関係としてリスナーの起動が終わった後になるように設定するのを忘れないでくださいね!

インスタンスの起動設定

最後の仕上げです!作成したデータベースインスタンスを起動しましょう!(`・ω・´)

マニフェストとしては以下の内容です。

oradb::dbactions{ 'start testDb':
  oracleHome              => '/oracle/product/11.2/db',
  user                    => 'oracle',
  group                   => 'dba',
  action                  => 'start',
  dbName                  => 'db01',
  require                 => Oradb::Database['testDb_Create'],
}

oradb::autostartdatabase{ 'autostart oracle':
  oracleHome              => '/oracle/product/11.2/db',
  user                    => 'oracle',
  dbName                  => 'db01',
  require                 => Oradb::Dbactions['start testDb'],
}

まぁ今回も特筆すべきコトは無いのですが。(´・ω・`)

とりあえず先ほど作成したDB名を入れるコトと依存関係に注意してください。一応Oracle知らない人向けに書くと、oradb::dbactionsでデータベースインスタンスを起動しています。「じゃあoradb::autostartdatabaseはナニ?」となると思いますが、こちらはデータベースが起動した時にインスタンス自動起動するための設定です。デフォルトでは自動起動しないのでこの設定が必要になるのです。(´・ω・`)

tnsnames.oraの設定

これでフィニッシュです!tnsnames.oraを設定しましょう!(`・ω・´)

え?「tnsnames.oraってナニ?」ですって?マニュアル読んでくださいませ。簡単に且つ乱暴な例えを言うとOracle専用のhostsファイルみたいなもんです。(´・ω・`)

マニフェストとしては以下の内容です。

oradb::tnsnames{'db01':
  oracleHome         => '/oracle/product/11.2/db',
  user               => 'oracle',
  group              => 'dba',
  server             => { myserver => { host => cent65, port => '1521', protocol => 'TCP' }},
  connectServiceName => 'db01.denka.orz.hm',
  connectServer      => 'DEDICATED',
  require            => Oradb::Dbactions['start testDb'],
}

ここで設定すべき属性値は以下の通りです。

  • connectServiceName

    ネットサービス名を設定します。ネットサービス名はデフォルトで“DB名.DBドメイン名”です。変更するには以下のようにします。

      ALTER SYSTEM SET SERVICE_NAMES = service_name;
      ALTER SYSTEM SET SERVICE_NAMES = ( service_name1, ... , service_name2 );
    

    あとは例のままで良いかと思います。その他の詳細はマニュアルへ(そればっか)。(´・ω・`)

サンプルスキーマの作成

ここまででOracleインストールのマニフェストは完成ですが、これだけだと器は作ったけど中身が無い状態で、何も面白くありません。昔のバージョンだと“scott/tiger”というサンプルスキーマがデフォルトで入っていたのですが今は入りません。でも伝統的なサンプルなので作成用のSQLは入っています。この後の動作確認でも必要ですし、せっかくなのでPuppetさんにインストールして貰いましょう!(゚∀゚)

マニフェストは以下のようになります。

exec {'install sample':
  command => '/oracle/product/11.2/db/bin/sqlplus sys/oracle as sysdba @/oracle/product/11.2/db/rdbms/admin/utlsampl.sql',
  environment => ['ORACLE_SID=db01','ORACLE_HOME=/oracle/product/11.2/db'],
  user    => 'oracle',
  require           => Oradb::Tnsnames['db01'],
}

特筆すべき点としては、execリソースを使う際にoracleユーザでなければならないコトと、環境変数としてORACLE_SIDとORACLE_HOMEが必須であることです。具体的には属性値environmentとuserになります。あとは全ての作業が終わった後にこの作業を実施するよう、依存関係は入れておきましょう。

マニフェスト作成作業は以上になります。

長くなりましたし、一旦ここで切ります。次回はこのマニフェストを実際に動作させてインストールを実行し、sqlplusでSQLを発行します!(`・ω・´)

Oracle Clientのインストールも紹介しますのでお楽しみに!(゚∀゚)

以下、コピペ用マニフェストまとめ。(´・ω・`)

$all_groups = ['oinstall','dba' ,'oper']
 group { $all_groups :
  ensure      => present,
}

host {'cent65': ip => $::ipaddress, }

user { 'oracle' :
  ensure      => present,
  uid         => 500,
  gid         => 'oinstall',
  groups      => ['oinstall','dba','oper'],
  shell       => '/bin/bash',
  password    => 'xxxxxxxx',
  home        => "/home/oracle",
  comment     => "This user oracle was created by Puppet",
  require     => Group[$all_groups],
  managehome  => true,
}

sysctl { 'kernel.msgmnb':                 ensure => 'present', permanent => 'yes', value => '65536',}
sysctl { 'kernel.msgmax':                 ensure => 'present', permanent => 'yes', value => '65536',}
sysctl { 'kernel.shmmax':                 ensure => 'present', permanent => 'yes', value => '2588483584',}
sysctl { 'kernel.shmall':                 ensure => 'present', permanent => 'yes', value => '2097152',}
sysctl { 'fs.file-max':                   ensure => 'present', permanent => 'yes', value => '6815744',}
sysctl { 'net.ipv4.tcp_keepalive_time':   ensure => 'present', permanent => 'yes', value => '1800',}
sysctl { 'net.ipv4.tcp_keepalive_intvl':  ensure => 'present', permanent => 'yes', value => '30',}
sysctl { 'net.ipv4.tcp_keepalive_probes': ensure => 'present', permanent => 'yes', value => '5',}
sysctl { 'net.ipv4.tcp_fin_timeout':      ensure => 'present', permanent => 'yes', value => '30',}
sysctl { 'kernel.shmmni':                 ensure => 'present', permanent => 'yes', value => '4096', }
sysctl { 'fs.aio-max-nr':                 ensure => 'present', permanent => 'yes', value => '1048576',}
sysctl { 'kernel.sem':                    ensure => 'present', permanent => 'yes', value => '250 32000 100 128',}
sysctl { 'net.ipv4.ip_local_port_range':  ensure => 'present', permanent => 'yes', value => '9000 65500',}
sysctl { 'net.core.rmem_default':         ensure => 'present', permanent => 'yes', value => '262144',}
sysctl { 'net.core.rmem_max':             ensure => 'present', permanent => 'yes', value => '4194304', }
sysctl { 'net.core.wmem_default':         ensure => 'present', permanent => 'yes', value => '262144',}
sysctl { 'net.core.wmem_max':             ensure => 'present', permanent => 'yes', value => '1048576',}

class { 'limits':
  config => {
             '*'       => { 'nofile'  => { soft => '2048'   , hard => '8192',   },},
             'oracle'  => { 'nofile'  => { soft => '65536'  , hard => '65536',  },
                             'nproc'  => { soft => '2048'   , hard => '16384',  },
                             'stack'  => { soft => '10240'  ,},},
             },
  use_hiera => false,
}

$install = [ 'binutils.x86_64', 'compat-libstdc++-33.x86_64', 'glibc.x86_64','ksh.x86_64','libaio.x86_64',
             'libgcc.x86_64', 'libstdc++.x86_64', 'make.x86_64','compat-libcap1.x86_64', 'gcc.x86_64',
             'gcc-c++.x86_64','glibc-devel.x86_64','libaio-devel.x86_64','libstdc++-devel.x86_64',
             'sysstat.x86_64','unixODBC-devel','glibc.i686','libXext.x86_64','libXtst.x86_64']
package { $install:
  ensure  => present,
}

$puppetDownloadMntPoint = "puppet:///modules/oradb/"
oradb::installdb{ '112010_Linux-x86-64':
  version       => '11.2.0.1',
  file          => 'linux.x64_11gR2_database',
  databaseType  => 'SE',
  oracleBase    => '/oracle',
  oracleHome    => '/oracle/product/11.2/db',
  user          => 'oracle',
  group         => 'dba',
  group_install => 'oinstall',
  group_oper    => 'oper',
  downloadDir   => '/install',
  zipExtract    => true,
  puppetDownloadMntPoint => $puppetDownloadMntPoint,
  require       => Package[$install],
}

oradb::net{ 'config net8':
  oracleHome   => '/oracle/product/11.2/db',
  version      => '11.2',
  user         => 'oracle',
  group        => 'dba',
  downloadDir  => '/install',
  dbPort       => '1521', #optional
  require      => Oradb::Installdb['112010_Linux-x86-64'],
}

db_listener{ 'startlistener':
  ensure          => 'running',  # running|start|abort|stop
  oracle_base_dir => '/oracle',
  oracle_home_dir => '/oracle/product/11.2/db',
  os_user         => 'oracle',
  listener_name   => 'listener', # which is the default and optional
  require         => Oradb::Net['config net8'],
}

oradb::listener{'start listener':
  action       => 'start',  # running|start|abort|stop
  oracleBase   => '/oracle',
  oracleHome   => '/oracle/product/11.2/db',
  user         => 'oracle',
  group        => 'dba',
  listenername => 'listener', # which is the default and optional
  require      => Db_listener['startlistener'],
}

oradb::database{ 'testDb_Create':
  oracleBase              => '/oracle',
  oracleHome              => '/oracle/product/11.2/db',
  version                 => '11.2',
  user                    => 'oracle',
  group                   => 'dba',
  downloadDir             => '/install',
  action                  => 'create',
  dbName                  => 'db01',
  dbDomain                => 'denka.orz.hm',
  dbPort                  => '1521',
  sysPassword             => 'Welcome01',
  systemPassword          => 'Welcome01',
  dataFileDestination     => "/oracle/oradata",
  recoveryAreaDestination => "/oracle/flash_recovery_area",
  characterSet            => "AL32UTF8",
  nationalCharacterSet    => "UTF8",
  initParams              => {'open_cursors'        => '1000',
                              'processes'           => '600',
                              'job_queue_processes' => '4' },
  sampleSchema            => 'TRUE',
  memoryPercentage        => "40",
  memoryTotal             => "800",
  databaseType            => "MULTIPURPOSE",
  emConfiguration         => "NONE",
  require                 => Oradb::Listener['start listener'],
}

oradb::dbactions{ 'start testDb':
  oracleHome              => '/oracle/product/11.2/db',
  user                    => 'oracle',
  group                   => 'dba',
  action                  => 'start',
  dbName                  => 'db01',
  require                 => Oradb::Database['testDb_Create'],
}

oradb::autostartdatabase{ 'autostart oracle':
  oracleHome              => '/oracle/product/11.2/db',
  user                    => 'oracle',
  dbName                  => 'db01',
  require                 => Oradb::Dbactions['start testDb'],
}

oradb::tnsnames{'db01':
  oracleHome         => '/oracle/product/11.2/db',
  user               => 'oracle',
  group              => 'dba',
  server             => { myserver => { host => cent65, port => '1521', protocol => 'TCP' }},
  connectServiceName => 'db01.denka.orz.hm',
  connectServer      => 'DEDICATED',
  require            => Oradb::Dbactions['start testDb'],
}

exec {'install sample':
  command => '/oracle/product/11.2/db/bin/sqlplus sys/oracle as sysdba @/oracle/product/11.2/db/rdbms/admin/utlsampl.sql',
  environment => ['ORACLE_SID=db01','ORACLE_HOME=/oracle/product/11.2/db'],
  user    => 'oracle',
  require           => Oradb::Tnsnames['db01'],
}

MCollectiveまとめ(コマンド解説編)

それではお待ちかね、MCollectiveを実際に使ってみましょう。(゚∀゚)

MCollectiveの基本

MCollectiveクライアントをインストールしたノードで“mco”コマンドを実行する事でMCollectiveにコマンドを投げる事ができます。何もせずにコマンドを実行するとMCollectveが動作している全ノードが対象となります。もちろんそういうシチュエーションも少なからずありますが、特定の条件のノードだけど対象にしたいシチュエーションの方が多いですよね。そんな時は“フィルター”を使います。

フィルターの条件にはホスト名、factsの値、適用されているPuppetのクラスなどが使えます。以下に公式ドキュメントに載っているフィルター指定の例を抜粋して紹介します。

    serviceエージェントが動作しているノード
    # mco ping -A service

    Puppetのapacheクラスが適用されたノード
    # mco ping -C apache

    適用されたPuppetのクラス名を正規表現で指定する例
    # mco ping -C /service/

    Factsの値による条件指定する例
    # mco ping -F country=uk

    正規表現でFactsの値を指定する例
    # mco ping -F "country=/uk|us/"

    ホスト名で指定する例
    # mco ping -I dev1 -I dev2

    ホスト名を正規表現で指定する例
    # mco ping -I /foo.com$/

ヘルプは“mco help [コマンド名]”で表示できます。プラグインのヘルプは“mco plugin doc [プラグイン名]”で表示できます。なおプラグインのヘルプで“Duplicate plugin name found, please specify a full path like agent/rpcutil”というエラーが出る時は“agent/puppet”のように指定すれば表示できます。

MCollectiveでサービスを制御

まずは軽いところからいってみましょう。普段止めているけど、特定のタイミングでだけサービスを起動、もしくは停止させたい、はたまた再起動させたいというシチュエーションは必ずあるでしょう。そんな時、数台ならsshで接続してserviceコマンドを実行すればよいでしょうけど、これがもし100台とかあったらどうでしょう。はい、イヤになってきましたね(笑)。サービスの制御は“mco service [サービス名] [サブコマンド]”になります。

  • サービスの起動/停止/再起動

    サービスを起動/停止/再起動するには“start”“stop”“restart”サブコマンドを使います。もしpuppetサービスを再起動するなら以下のようになります。

      # mco service puppet restart
      Do you really want to operate on services unfiltered? (y/n): y
    
       * [ ==========================================================> ] 1 / 1
    
      Summary of Service Status:
         running = 1
    
      Finished processing 1 / 1 hosts in 4568.99 ms
    

    フィルターを使わないと全ノードが対象になるため“Do you really want to operate on services unfiltered? (y/n):”と聞かれますが、問題なければ“y”を入力してください。

    tail -f /var/log/messagesでログを流していればわかると思いますが、コマンドを実行するとすぐにサービスが再起動されています。特定ノードでだけサービスの再起動したい場合は前述のようにフィルターを使います。例えば“cent65”というホスト名のノードにだけ実行させたいなら“mco service puppet restart -I /cent.*/”という具合に指定します。詳細は前述の説明を確認してください。

  • サービスの状態確認

    サービスの状態を確認するには“status”サブコマンドを使います。

      # mco service puppet status
    
       * [ ==========================================================> ] 2 / 2
    
         cent65: running
           vcol: running
    
      Summary of Service Status:
         running = 2
    

MCollectiveでパッケージの管理

たくさんのサーバを運用していると、「特定のサーバだけ必要なパッケージが入ってない!」とか「特定のサーバだけパッケージのバージョンが古いよぉ(涙)」なんて事、よくありますよね。えぇ、構築時や運用時のミスだというコトは重々承知しておりますが、数台ならともかく数十数百台規模でこんな事あったら…はい、何日おうちに帰れなくなるでしょう(涙)。Puppetのマニフェストだけで対応しようとしても対象サーバがわからないと限界があります。そんな時、MCollectiveは強い味方になるでしょう。パッケージの制御は“mco package [パッケージ名] [サブコマンド]”になります。ここで注意点ですが、packageコマンドはシステムのパッケージ管理コマンドを呼び出します。本記事のようにRHEL系であればyumコマンドを呼び出しますので、該当するコマンドは正しく動作するよう予め設定しておいてください。え?最初から設定されてりゃ苦労しないですって(汗)?そんな時はPuppetのマニフェストで対応しましょう。RHEL系ならyumrepoリソースが使えます。:)

  • パッケージの状態取得

    パッケージの状態を取得するには“status”サブコマンドを使います。もしhttpdパッケージの状態を調べるなら以下のようになります。

      # mco package httpd status
    
       * [ ==========================================================> ] 2 / 2
    
         cent65: absent
           vcol: httpd-2.2.15-39.el6.centos.x86_64
    
      Summary of Arch:
         x86_64 = 1
    
      Summary of Ensure:
                       absent = 1
         2.2.15-39.el6.centos = 1
    
      Finished processing 2 / 2 hosts in 175.24 ms
    

    この結果を見ると、cent65にhttpdパッケージは入っておらず、vcolにはhttpd-2.2.15-39が入っている事がわかります。

  • パッケージのアップデート

    次は特定のサーバでパッケージのアップデートが必要だと判明した場合を想定してみましょう。検証で使ってるvcolでyum updateしてみるとnssパッケージで更新が出ていましたので、これを題材にしてみます。:)

    まずはstatusサブコマンドでvcolのnssの状態を調べてみます。

      # mco package status nss -I vcol
    
      * [ ==========================================================> ] 1 / 1
    
         vcol: nss-3.15.1-15.el6.x86_64
    
      Summary of Arch:
         x86_64 = 2
    
      Summary of Ensure:
           3.15.1-15.el6 = 1
    

    yum updateで調べた結果では3.18.0が出ているようです。アップデートしてみましょう。パッケージのアップデートは“update”サブコマンドを使います。

      # mco package update nss -I vcol
    
       * [ ==========================================================> ] 1 / 1
    
      Summary of Ensure:
         3.18.0-5.3.el6_6 = 1
    
      Finished processing 1 / 1 hosts in 6263.40 ms
    

    アップデートできたようです。正しくアップデートできているか/var/log/messageを見て確認してみましょう。

      May  9 13:10:43 vcol yum[18832]: Updated: nspr-4.10.8-1.el6_6.x86_64
      May  9 13:10:43 vcol yum[18832]: Updated: nss-util-3.18.0-1.el6_6.x86_64
      May  9 13:10:43 vcol yum[18832]: Updated: nss-sysinit-3.18.0-5.3.el6_6.x86_64
      May  9 13:10:43 vcol yum[18832]: Updated: nss-3.18.0-5.3.el6_6.x86_64
      May  9 13:10:44 vcol yum[18832]: Updated: nss-tools-3.18.0-5.3.el6_6.x86_64
    

    依存パッケージも含めてアップデートできた事がyumのログから確認できました。それでは再度statusサブコマンドで確認してみましょう。

      # mco package status nss
    
       * [ ==========================================================> ] 2 / 2
    
         cent65: nss-3.15.1-15.el6.x86_64
           vcol: nss-3.18.0-5.3.el6_6.x86_64
    
      Summary of Arch:
         x86_64 = 2
    
      Summary of Ensure:
            3.15.1-15.el6 = 1
         3.18.0-5.3.el6_6 = 1
    
      Finished processing 2 / 2 hosts in 170.12 ms
    

    ちなみにここではわざと“-I vcol”を外してみました。まだアップデートしていないcent65との対比もちゃんと確認できますね。:)

  • パッケージのインストール

    急遽パッケージのインストールが必要になる場面、ありますよね、たぶん。まぁ永続的にインストールするならPuppetのマニフェストで対応すべきですが、暫定対応などで個別対応する必要な場面もあるかもしれません、たぶん。そんな時“install”サブコマンドでインストールできます。本来は他のコマンド同様にサブコマンドから指定すればよいのでしょうけど、installサブコマンドだけはバグがあるのかエラーになりますので、以下のように“rpc package install [パッケージ名]”で指定します。ここでの例はtelnetパッケージをインストールしています。telnet、トラブルシューティングには結構使いますものね(笑)。

      # mco rpc package install package=telnet -I cent65
    
       * [ ==========================================================> ] 1 / 1
    
      Summary of Ensure:
         0.17-48.el6 = 1
    
      Finished processing 1 / 1 hosts in 1438.56 ms
    
  • パッケージのアンインストール

    最後に一時的に入れた調査用のパッケージをアンインストールする場合を想定しましょう。アンインストールは“uninstall”もしくは“purge”サブコマンドになります。違いは“purge”サブコマンドの場合は依存パッケージも同時に削除するところです。つまりrpm -eとyum eraseの違いになります(実際呼び出すコマンドもコレのようですし:))

      # mco package purge telnet -I cent65
    
       * [ ==========================================================> ] 1 / 1
    
      Summary of Ensure:
         absent = 1
    
      Finished processing 1 / 1 hosts in 645.05 ms
    

MCollectiveでファイルの操作

数十数百台のサーバにある特定のファイルの情報を集めたり、削除したり、touchしたりといった操作が必要な場面、多くは無いかも知れませんがありますよね?いちいち手作業でやってたら日が暮れます。そんな時もMCollectiveはあなたの味方です。ファイルの操作は“mco filemgr [サービス名] [サブコマンド]”になります。:)

  • ファイルの操作

    ファイルにtouchしたり削除するにはそれぞれ“touch”“remove”サブコマンドを使います。ファイルの存在を確認するのは“status”サブコマンドを使います。以下はtouchして作成したファイルを削除する例です。

      # mco filemgr --file /tmp/testfile touch
    
       * [ ==========================================================> ] 2 / 2
    
      Finished processing 2 / 2 hosts in 31.64 ms
    
      # mco filemgr --file /tmp/testfile status
    
       * [ ==========================================================> ] 2 / 2
    
      cent65                                  : present
      vcol                                    : present
    
      Finished processing 2 / 2 hosts in 38.43 ms
    
      # mco filemgr --file /tmp/testfile remove
    
       * [ ==========================================================> ] 2 / 2
    
      Finished processing 2 / 2 hosts in 31.43 ms
    
      # mco filemgr --file /tmp/testfile status
    
       * [ ==========================================================> ] 2 / 2
    
      vcol                                    : not present
      cent65                                  : not present
    

MCollectiveでサーバの検索

条件に合うサーバを検索したり、特定の条件の状態を調べる事ができます。MCollectiveが使えるサーバを調べるには“mco ping”を投げも良いのですけど、もうちょっとイケてる調べ方を紹介します。:)

  • サーバ名の検索

    今まで“-I”オプションなどフィルターを使って特定のサーバだけコマンドを実行する事をしていましたが、“find”コマンドで条件に合致するサーバ名を表示だけする事もできます。

      # mco find -I /v.*/
      vcol
    
  • factsの検索

    冒頭で紹介したfactsの値を表示するには“facts [facts名]”コマンドを使います。以下は“mcollective”の値を表示する例です。でもまぁこの例はデフォルトで入っている値で使いましたが、“1”しかないので面白くないですね。ご自身で定義したfactsを指定して実行するとこのコマンドの使い道が自ずとわかるでしょう。:)

      # mco facts mcollective
    
      Report for fact: mcollective
              1                                        found 2 times
    
      Finished processing 2 / 2 hosts in 31.80 ms
    

MCollectiveでPuppetを制御

多分これがメインディッシュかも知れません。:)

  • Puppet agentを一度だけ実行

    普段Puppet agentを停止させておいて。必要に応じて“puppet agent -t”を実行する方法、意外と多く使われています。まぁagentが動作していると30分に1回ポーリング動作するので都合が悪い場合もあるかも知れません。そんな時にコマンドを実行するためパラレルsshのような並列実行ツールを使うケースが多いですが、当然MCollectiveでもできます。“mco puppet runonce”コマンドを使います。:)

      # mco puppet runonce
    
       * [ ==========================================================> ] 2 / 2
    
      Finished processing 2 / 2 hosts in 238.57 ms
    

    ちなみにもちろん“mco puppet runonce -I /cent*/”のようにフィルタを指定する事もできます。:)

    もう一つの方法として“runall [同時実行agent数]”サブコマンドがあります。この場合はmasterを過負荷にしないよう同時実行するagent数を指定しないとなりません。今回は2ノードしかないので、同時実行数で1を指定してみます。:)

      # mco puppet runall 1
      2015-05-09 15:14:39: Running all nodes with a concurrency of 1
      2015-05-09 15:14:39: Discovering enabled Puppet nodes to manage
      2015-05-09 15:14:42: Found 2 enabled nodes
      2015-05-09 15:14:42: cent65 schedule status: Started a Puppet run using the 'puppet agent --onetime --no-daemonize --color=false --show_diff --verbose --no-splay' command
      2015-05-09 15:14:44: vcol schedule status: Started a Puppet run using the 'puppet agent --onetime --no-daemonize --color=false --show_diff --verbose --no-splay' command
      2015-05-09 15:14:44: Iteration complete. Initiated a Puppet run on 2 nodes.
    

    ログの時間を見ると順番に実行されているのが一応確認できるでしょうか(汗)?適用するマニフェストが無いので数秒の差しかないので微妙ですが…。「えぇ~?本当~?」って思われた方は同時実行数を2にして試してみてください。:)

  • マニフェスト適用の抑止と再開

    Puppetのマニフェストが適用されると都合が悪い時もあるでしょう。例えばトラブルが発生して現状を維持したいなどなど。そんな時はagentサービスを停止しなくても“disable”サブコマンドを使うとPuppet側で適用を抑止する事ができます。再開は“enable”サブコマンドになります。実態はpuppet agentコマンドの--disableと--enableになります。

    以下の例は適用抑止した後にマニフェストを適用し、適用できない事を確認後に抑止を解いてマニフェスト適用する一連の流れになります。

      # mco puppet disable -I cent65
    
       * [ ==========================================================> ] 1 / 1
    
      Summary of Enabled:
         disabled = 1
    
      Finished processing 1 / 1 hosts in 33.55 ms
    
      # mco puppet runonce -I /cent*/
    
       * [ ==========================================================> ] 1 / 1
    
      cent65                                   Request Aborted
         Puppet is disabled: 'Disabled via MCollective by uid=0 at 2015-05-09 15:22'
    
      Finished processing 1 / 1 hosts in 21.50 ms
    
      # mco puppet enable -I cent65
    
       * [ ==========================================================> ] 1 / 1
    
      Summary of Enabled:
         enabled = 1
    
      Finished processing 1 / 1 hosts in 26.47 ms
    
      # mco puppet runonce -I /cent*/
    
       * [ ==========================================================> ] 1 / 1
    
      Finished processing 1 / 1 hosts in 83.42 ms
    
  • agentの状態取得

    Puppet agentの状態を“count”“status”コマンドの双方で確認できます。実行すると以下のようになります。内容はあんまり変わらないですね…まぁcountは単なる集計、statusがより詳しい情報と考えればまぁ大丈夫ではないかと。(´・ω・`)

      # mco puppet count
    
      Total Puppet nodes: 2
                Nodes currently enabled: 2
               Nodes currently disabled: 0
    
      Nodes currently doing puppet runs: 0
                Nodes currently stopped: 2
    
             Nodes with daemons started: 1
          Nodes without daemons started: 1
             Daemons started but idling: 1
    
      # mco puppet status
    
       * [ ==========================================================> ] 2 / 2
    
           vcol: Currently stopped; last completed run 7 minutes 48 seconds ago
         cent65: Currently idling; last completed run 58 seconds ago
    
      Summary of Applying:
         false = 2
    
      Summary of Daemon Running:
         running = 1
         stopped = 1
    
      Summary of Enabled:
         enabled = 2
    
      Summary of Idling:
          true = 1
         false = 1
    
      Summary of Status:
          idling = 1
         stopped = 1
    
  • MCollective経由でのリソース管理

    最後にちょっとトリッキー(?)な技です。(´・ω・`)

    MCollectiveのコマンドラインからPuppetリソースを直接操作できます。本来はマニフェストに書くべきなのでしょうけど、ワンショットで使いたいものだとマニフェストに起こすのもアレですし、そんな時に役立つかも知れません。

    MCollectiveからのリソース操作はデフォルトで無効になっていますので、使う時は/etc/mcollective/server.cfgに以下のようなエントリを追加します。

      plugin.puppet.resource_allow_managed_resources = true
      plugin.puppet.resource_type_whitelist = host
    

    記述後はmcollectiveの再起動をお忘れなく。2行目のwhitelistにはPuppetのリソース名を記述します。これがMCollectiveから呼び出せるリソースになります。それ以外の呼び出しは禁止されています。逆に禁止したいリソース名を記述したい場合はwhitelistの代わりに以下のようにblacklistを作成します。

      plugin.puppet.resource_type_blacklist = exec,service,package
    

    この場合はexec、service、package以外のリソースは呼び出し可能になります。なお、whiltelistとblacklistは排他利用になりますのでご注意を。両方同時に指定するとエラーになります。

    それでは試にhostリソースを使ってみましょう。コマンドラインは“mco puppet resource [リソース名] [リソースタイトル] [属性1]=[属性1の値] ...”です。つまりhostリソースの場合はリソース名に“host”、リソースタイトルがhostsに記載するホスト名、属性としてip属性を指定しますので“ip=[IPアドレス]”になります。以下の例では“gw”というエントリを作成した後、削除するものです。

      # mco puppet resource host gw ip="192.168.1.1" -I cent65
    
       * [ ==========================================================> ] 1 / 1
    
      cent65
         Changed: true
          Result: created
    
      Summary of Changed:
         Changed = 1
    
      Finished processing 1 / 1 hosts in 73.26 ms
    
      # mco puppet resource host gw ip="192.168.1.1" ensure="absent" -I cent65
    
       * [ ==========================================================> ] 1 / 1
    
      cent65
         Changed: true
          Result: removed
    
      Summary of Changed:
         Changed = 1
    
      Finished processing 1 / 1 hosts in 48.27 ms
    

終わりに

MCollective、どんなものかご理解いただけたでしょうか。たくさんのサーバがある環境ではなかなか便利なモノだと思います。この記事では環境の問題(RHEL6系のRubyが古くてnet-pingのgemが使えない)で紹介できなかった“nettest”なんてコマンドもあり、ネットワークの疎通確認なんかもできます。Ruby 1.9以降をお使いであれば試してみてください。僕は入れ替えが面倒であきらめてますが…(´・ω・`)

それではよきMCollectiveライフを。(≧∀≦)

MCollectiveまとめ(セットアップ編)

MCollectiveとは

MCollective(正式名称はMarionette Collectiveのようです)はPuppet Labsが開発した複数のサーバに対してジョブを実行するための仕組みです。原文の説明では“統合的なサーバ構築のフレームワーク、もしくは並列ジョブ実行のためのシステムである”とされています。多くの方がサーバ管理タスクをまとめて、プログラムから実行するのに使っているようです。MCollectiveはApache 2ライセンスで配布されています。

MCollectiveの特徴

MCollectiveは多数のサーバ群で動作するのに都合がよい特徴を備えています。

  • ホストのリストを使わない

    代わりにPuppetDBのようなデータソースや、ネットワーク上でリアルタイムにホストを探す仕組みを持っています。

  • それぞれのホストが直接接続しない

    代わりにミドルウェアをホスト間のコミュニケーションの手段として用いています。

    またMCollectiveにより、以下のような事を実現できるとされています。

  • 小規模から大規模までサーバ群を制御

  • サーバ群に対するコマンドをブロードキャスト

    パラレルsshなどを使っても比較的難しい、全サーバ群に対して完全に同じタイミングでコマンドを投げるといった事ができます。また条件を指定し、マッチするサーバだけがコマンドを実行するといった事も可能です。そのためのデータベースも不要でネットワークだけがつながっていれば良いのです。

  • シンプルなコマンドラインツール

    制御するためのコマンドラインツールはとてもシンプルです。

  • 簡易なインベントリ管理

    各サーバに予めYAML形式で情報を記載しておけば簡易なインベントリレポート作成ツールとしても使えます。

  • SSLベースのセキュリティ

    利用するミドルウェアが持つセキュリティ機構を使えます。

MCollectiveのインストール

MCollectiveの仕組みですが、ざっと以下の図のようになります。

f:id:denkas:20150509183212j:plain

中心にActiveMQなどのメッセージを配信するミドルウェア(以下、本記事ではActiveMQ前提で書きます)が居ます。MCollectiveにコマンドを投げるクライアントはこのActiveMQに対してメッセージを投げ、MCollectiveによりコマンドを受けるサーバはActiveMQをポーリングし、メッセージが来たら受け取り解釈し、必要ならコマンドを実行して結果を返すというとてもシンプルな仕組みです。

前準備としてとしてhostsファイルに自身とActiveMQが動作するホストのホスト名が記載されている必要がありますので記述しておきます。Puppetのマニフェストだと以下のようになります。

    host {
        $::fqdn: ip=>$::ipaddress, ;
        [ActiveMQのホスト名]: ip=>[ActiveMQのIPアドレス],
    }

次にパッケージをインストールします。本記事ではCentOS6系について書きますので、他のディストリビュージョンについては以下のURLを参照してください。

MCollective » Deploy » Standard Deployment — Documentation — Puppet Labs

  • 共通作業

    MCollectiveのパッケージはPuppet LabsのYumリポジトリから取得しますので、以下のコマンドを実行してPuppet Lasのリポジトリを登録しておきます。

      rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm
    

    インターネットに接続できない環境の場合は、yumdownloaderなどを使ってダウンロードして配置しましょう。あとトラブルを避けるためにSELinuxiptablesは無効にしておきましょう。これらが有効になっていると間違いなく動きません。iptablesを使いたい場合でも一度無効の状態で動作確認してからルールを追加するようにしたほうが身のためです…。

  • ActiveMQ

    以下のコマンドラインでパッケージをインストールします。

      yum install activemq activemq-info-provider java-1.7.0-openjdk
    

    ここで注意が必要なのですが、RHEL6系でJDK8を使うとエラーが発生して上手く動作しない現象を確認しています。恐らくパッケージ間のバージョン依存の問題だとは思うのですが、結局解決できませんでしたのでJDK7の利用をお勧めします。ちなみにCentOS7で試した時にはJDK8でも問題なく動作したのですが…なぜなんでしょう。。。(´・ω・`)

  • MCollectiveクライアント(MCollectiveの操作をする端末)

    以下のコマンドラインでパッケージをインストールします。

      yum install mcollective mcollective-client mcollective-common rubygem-stomp
    

    次に追加するエージェントをインストールします。本来は必要なものを入れればよいのでしょうけど、面倒なので“全部入り”にしちゃいます。

      yum install mcollective-actionpolicy-auth mcollective-client mcollective-common mcollective-facter-facts mcollective-filemgr-agent mcollective-filemgr-client mcollective-filemgr-common mcollective-iptables-client mcollective-iptables-common mcollective-logstash-audit mcollective-nettest-client mcollective-nettest-common mcollective-nrpe-client mcollective-nrpe-common mcollective-package-client mcollective-package-common mcollective-puppet-client mcollective-puppet-common mcollective-service-client mcollective-service-common mcollective-sshkey-security mcollective-sysctl-data
    

    ちなみにパッケージ名は“○○○-common”が全共通、“○○○-client”がクライアント専用のパッケージ、“○○○-agent”がエージェント専用のパッケージという命名規則になっているそうです。

  • MCollectiveサーバ(MCollectiveにより操作されるサーバ)

    以下のコマンドラインでパッケージをインストールします。

      yum install mcollective mcollective-common rubygem-stomp
    

    次に必要なエージェントをインストールします。ここでも“全部入り”にしちゃいます。

      yum install mcollective-actionpolicy-auth mcollective-common mcollective-facter-facts mcollective-filemgr-agent mcollective-filemgr-common mcollective-iptables-agent mcollective-iptables-common mcollective-logstash-audit mcollective-nettest-agent mcollective-nettest-common mcollective-nrpe-agent mcollective-nrpe-common mcollective-package-agent  mcollective-package-common mcollective-puppet-agent mcollective-puppet-common mcollective-service-agent mcollective-service-common mcollective-sshkey-security mcollective-sysctl-data
    
  • 本記事の検証環境インストール

    面倒なのでVMを二つ用意して、一つをクライアント兼サーバ兼ActiveMQ、もう一つをサーバのみとしています。前者のインストールコマンドを以下のようになります。

      yum install mcollective mcollective-client mcollective-common rubygem-stomp
      yum install activemq activemq-info-provider java-1.7.0-openjdk
      yum install mcollective-actionpolicy-auth mcollective-client mcollective-common mcollective-facter-facts mcollective-filemgr-agent mcollective-filemgr-client mcollective-filemgr-common mcollective-iptables-agent mcollective-iptables-client mcollective-iptables-common mcollective-logstash-audit mcollective-nettest-agent mcollective-nettest-client mcollective-nettest-common mcollective-nrpe-agent mcollective-nrpe-client mcollective-nrpe-common mcollective-package-agent mcollective-package-client mcollective-package-common mcollective-puppet-agent mcollective-puppet-client mcollective-puppet-common mcollective-service-agent mcollective-service-client mcollective-service-common mcollective-sshkey-security mcollective-sysctl-data
    

    後者は以下のようになります。

      yum install mcollective mcollective-service-agent
      yum install mcollective-actionpolicy-auth mcollective-facter-facts mcollective-filemgr-agent mcollective-iptables-agent mcollective-logstash-audit mcollective-nettest-agent mcollective-nrpe-agent mc[f:id:denkas:20150506140245j:plain]ollective-package-agent mcollective-puppet-agent mcollective-sshkey-security mcollective-sysctl-data
    

設定

  • ActiveMQ

    MCollectiveはActiveMQが無いと使えません。というワケでまずはActiveMQの設定です。/etc/activemq/activemq.xmlに設定を追加します。場所は64行目辺りの以下のブロックの間に挿入します。

      <managementContext>
          <managementContext createConnector="false"/>
      </managementContext>
    
      !!!!!ここに追加!!!!!
    
      <!--
          Configure message persistence for the broker. The default persistence
          mechanism is the KahaDB store (identified by the kahaDB tag).
          For more information, see:
    
          http://activemq.apache.org/persistence.html
      -->
    

    追加するブロックは以下の内容です。

      <plugins>
        <statisticsBrokerPlugin/>
    
        <!--
          This configures the users and groups used by this broker. Groups
          are referenced below, in the write/read/admin attributes
          of each authorizationEntry element.
        -->
        <simpleAuthenticationPlugin>
          <users>
            <authenticationUser username="mcollective" password="marionette" groups="mcollective,everyone"/>
            <authenticationUser username="admin" password="secret" groups="mcollective,admins,everyone"/>
          </users>
        </simpleAuthenticationPlugin>
    
        <!--
          Configure which users are allowed to read and write where. Permissions
          are organized by group; groups are configured above, in the
          authentication plugin.
    
          With the rules below, both servers and admin users belong to group
          mcollective, which can both issue and respond to commands. For an
          example that splits permissions and doesn't allow servers to issue
          commands, see:
          http://docs.puppetlabs.com/mcollective/deploy/middleware/activemq.html#detailed-restrictions
        -->
        <authorizationPlugin>
          <map>
            <authorizationMap>
              <authorizationEntries>
                <authorizationEntry queue=">" write="admins" read="admins" admin="admins" />
                <authorizationEntry topic=">" write="admins" read="admins" admin="admins" />
                <authorizationEntry topic="mcollective.>" write="mcollective" read="mcollective" admin="mcollective" />
                <authorizationEntry queue="mcollective.>" write="mcollective" read="mcollective" admin="mcollective" />
                <!--
                  The advisory topics are part of ActiveMQ, and all users need access to them.
                  The "everyone" group is not special; you need to ensure every user is a member.
                -->
                <authorizationEntry topic="ActiveMQ.Advisory.>" read="everyone" write="everyone" admin="everyone"/>
              </authorizationEntries>
            </authorizationMap>
          </map>
        </authorizationPlugin>
      </plugins>
    

    ユーザ名やパスワードを変更したい場合はauthenticationUserの属性を適当に変更します。設定が完了したら以下のコマンドを実行してサービスを開始しましょう。

      chkconfig activemq on
      service activemq start
    

    netstat -lを実行してみて、61613番、61614番、61616番ポートをLISTENしていればOKです。LISTENしていない場合は/var/log/activemq/activemq.logを確認の上、設定を見直してください。

  • MCollectiveの設定

    設定ファイルはサーバが/etc/mcollective/server.cfg、クライアントが/etc/mcollective/client.cfgですが、基本的にそのままで問題ありません。ただしActiveMQのホスト名だけは適切に設定してください。plugin.activemq.pool.1.hostにActiveMQのホスト名を記述します。またもしActiveMQのユーザ名やパスワードを変更した場合は適切に変更してください。

    本記事ではSSLを使わない簡易な設定にしたのでこれだけで済みますが、もしActiveMQとの通信路をSSL暗号化するのであれば以下のURLを参考にしてください。その場合ポート番号が61614になるので注意してください。ちなみに僕は証明書の問題解決が難しすぎて挫折しましたが…。(´・ω・`)

    MCollective » Deploy » Standard Deployment — Documentation — Puppet Labs

MCollectiveの動作確認

お待ちかねMCollectiveの動作確認です。MCollectiveが動作する各ノードと疎通できるかはmco pingコマンドで確認できます。

# mco ping
vcol                                     time=21.90 ms
cent65                                   time=60.96 ms

---- ping statistics ----
2 replies max: 60.96 min: 21.90 avg: 41.43

このようになりましたか?ここではvcolがActiveMQ兼サーバ兼クライアント、cent65がサーバとしてセットアップしています。コマンドはクライアントがインストールされているvcolから実行しています。もし特定のホストが抜けているなどありましたら設定を見直してください。次はインベントリ情報を確認してみましょう。cent65のインベントリ情報を確認する場合は以下のように実行します。

# mco inventory cent65
Inventory for cent65:

   Server Statistics:
                      Version: 2.8.1
                   Start Time: Wed May 06 11:50:38 +0900 2015
                  Config File: /etc/mcollective/server.cfg
                  Collectives: mcollective
              Main Collective: mcollective
                   Process ID: 953
               Total Messages: 3
      Messages Passed Filters: 3
            Messages Filtered: 0
             Expired Messages: 0
                     Replies Sent: 2
         Total Processor Time: 13.25 seconds
                  System Time: 21.94 seconds

   Agents:
      discovery       filemgr         nrpe
      package         puppet          rpcutil
      service

   Data Plugins:
      agent           collective      fact
      fstat           nrpe            puppet
      resource        service         sysctl

   Configuration Management Classes:
    settings

   Facts:
      mcollective => 1

なんかいっぱい情報が出てきました。最初の“Server Statistics”はそのまんまの意味でサーバの統計情報です。“Agents”と“Data Plugins”はインストールされているエージェントやプラグインの情報です。

“Configuration Management Classes”はPuppetで適用したクラスの情報です。デフォルトでは/var/lib/puppet/classes.txtにファイルがあります。

“Facts”はPuppetのFacterみたいなものですが、facterの情報を取れる訳ではなく、/etc/mcollective/facts.yamlに記載された情報を出力しています。もしfacterの情報を出力したいのであれば、cronなどでfacterの出力をリダイレクトすれば実現できますが、一部フォーマットに互換性がありませんので若干の整形は必要です。ではちょっと実験してみます。cent65側の/etc/mcollective/facts.yamlに以下のように行を追加してみます。

---
mcollective: 1
test_flag: 1234
---

デフォルトではmcollectiveの行だけでしたが、test_flagの行を追加しました。mco inventory cent65を再実行してみましょう。結果は以下のようになりましたか。

Facts:
   mcollective => 1
   test_flag => 1234

これを使って後で紹介する“特定の条件に当てはまるサーバでだけ実行”のような際の条件としてこのFactsを使う事ができます。

長くなったのでここで一旦切ります。次回はMCollectiveのコマンドや便利な使い方を紹介します。(`・ω・´)