でんかのブログ

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

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ライフを。(≧∀≦)