読者です 読者をやめる 読者になる 読者になる

カメニッキ

カメとインコと釣りの人です

Puppetつかってみた

小ネタと独り言

Puppetとは?

サーバの状態を定義し、適用し、維持する Puppetのススメ

用語

puppet-server

puppetmasterd。管理サーバ

puppet-client

管理される側

XMLRPC over https

RPC(remote procedure call)は他のコンピュータ上の手続きを実行することを可能にする技術 その際のエンコードXMLを採用して、転送にはHTTPSを使用する

manifest

システムのあるべき状態が定義されたファイル。puppet-server上で一元管理され、puppet-clientから取得し、システムに適用する

resource

manifest内で扱うオブジェクトやファイル、パッケージを指す

処理の流れ

パターン1

  1. clientがserverへmanifestをとりに行く(defaultは30分ごと)
  2. client上でmanifestが適用される
  3. 適用した結果がserverへレポートされる

パターン2

  1. serverでpuppetrunを実行し、clientのpuppetdをキック
  2. clientがserverへmanifestをとりに行く
  3. client上でmanifestが適用される
  4. 適用した結果がserverへレポートされる

使用したゲスト

# PackerでBOX作成
$ ghq get git@github.com:momijiame/packer-vanilla-box.git
$ pwd
~/src/github.com/momijiame/packer-vanilla-box/centos/6
$ packer build -only=virtualbox-iso centos6.json

# vagrantfileは以下を使用
4 VAGRANTFILE_API_VERSION = "2"
5
6 Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
7   config.vm.box = "CentOS6.6_Packer"
8
9   config.vm.define :puppetserver do |puppetserver|
10     puppetserver.vm.hostname = "puppetserver"
11     puppetserver.vm.network :private_network, ip: "192.168.50.2", virtualbox__intnet: "pupnet"
12   end
13
14   config.vm.define :puppetagent do |puppetagent|
15     puppetagent.vm.hostname = "puppetagent"
16     puppetagent.vm.network :private_network, ip: "192.168.50.3", virtualbox__intnet: "pupnet"
17   end
18 end

参考URL

Installing Puppet: Pre-Install Tasks — Documentation — Puppet Labs

インストール

puppetlabsのリポジトリ有効化

[vagrant@puppetserver ~]$ sudo rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm
http://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm を取得中
警告: /var/tmp/rpm-tmp.tgqVqX: ヘッダ V4 RSA/SHA1 Signature, key ID 4bd6ec30: NOKEY
準備中...                ########################################### [100%]
   1:puppetlabs-release     ########################################### [100%]

※serverとclient両方へ

serverへpuppet-serverのインストール

[vagrant@puppetserver ~]$ sudo yum install puppet-server

※ここではまだ起動してはいけない

agentへpuppetのインストール

[vagrant@puppetagent ~]$ sudo yum install puppet

※同じくここではまだ起動してはいけない

masterの設定

hostsの設定

DNSサーバを使ってもよいが、今回はhostsでやる

[vagrant@puppetserver ~]$ sudo vi /etc/sysconfig/network
# master
HOSTNAME=puppetserver.com
# agent
HOSTNAME=puppetagent.com
[vagrant@puppetserver ~]$ sudo vi /etc/hosts
# master
192.168.50.3    puppetagent.com
# agent
192.168.50.2    puppetserver.com

master側でdns_alt_nameの設定

[vagrant@puppetserver ~]$ sudo vi /etc/puppet/puppet.conf
# 以下を追記
dns_alt_names = puppetserver.com,puppetagent.com

自動署名の設定

masterはagentからの接続が世紀のホストであるか認証する。agentから初回接続する際にmasterが署名し、接続可能となるが、署名はコマンド実行し行う必要がある。常に許可するよう設定する

[vagrant@puppetserver ~]$ sudo vi /etc/puppet/autosign.conf
# 以下を追記
*(あすたりすく)
[vagrant@puppetserver ~]$ sudo service puppetmaster start

その他細かい設定

今回はデフォルト設定のままとし、割愛 Configuration: Short List of Important Settings — Documentation — Puppet Labs

manifest配置

すでにファイルがあれば、チェックアウトして配置する

agentの設定

masterの指定

細かいことは以下参照 Configuration: Short List of Important Settings — Documentation — Puppet Labs

[vagrant@puppetagent ~]$ sudo vi /etc/puppet/puppet.conf
agent sectionに以下追記
server = puppetserver.com

agentからの接続確認

# iptablesが有効のままだと失敗
[vagrant@puppetagent ~]$ sudo puppet agent -t --verbose
Error: Could not request certificate: No route to host - connect(2)
Exiting; failed to retrieve certificate and waitforcert is disabled

# とめる
[vagrant@puppetagent ~]$ sudo service iptables stop
iptables: Setting chains to policy ACCEPT: filter          [  OK  ]
iptables: Flushing firewall rules:                         [  OK  ]
iptables: Unloading modules:                               [  OK  ]

# 初回は署名がうごく
[vagrant@puppetagent ~]$ sudo puppet agent -t --verbose
Info: Caching certificate for ca
Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for puppetagent.com
Info: Certificate Request fingerprint (SHA256): F5:72:9B:DE:3F:29:8E:4A:EC:5E:80:E8:05:CE:1E:CD:34:15:30:CD:A1:C1:84:60:08:42:16:E3:7B:A0:0D:7A
Info: Caching certificate for puppetagent.com
Info: Caching certificate_revocation_list for ca
Info: Caching certificate for ca
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppetagent.com
Info: Applying configuration version '1432690989'
Info: Creating state file /var/lib/puppet/state/state.yaml
Notice: Finished catalog run in 0.01 seconds

# 二回目以降
[vagrant@puppetagent ~]$ sudo puppet agent -t --verbose
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppetagent.com
Info: Applying configuration version '1432691205'
Notice: Finished catalog run in 0.02 seconds

認証済みagent確認

[vagrant@puppetserver ~]$ sudo puppet cert list --all
+ "puppetagent.com"  (SHA256) B8:4F:99:11:52:A9:2B:F5:D2:55:91:97:2C:B9:DE:A5:F8:9F:DF:2C:BE:1A:10:70:C9:78:05:E5:07:A1:ED:BB
+ "puppetserver.com" (SHA256) F5:67:F2:48:93:0B:B6:2C:98:64:96:42:CA:D0:E7:53:FE:A1:DB:F6:2A:6A:2F:2D:AE:40:96:33:31:03:8A:8A (alt names: "DNS:puppetagent.com", "DNS:puppetserver.com")

# 認証取り消し
[vagrant@puppetserver ~]$ sudo puppet cert clean puppetagent.com
Notice: Revoked certificate with serial 3
Notice: Removing file Puppet::SSL::Certificate puppetagent.com at '/var/lib/puppet/ssl/ca/signed/puppetagent.com.pem'
Notice: Removing file Puppet::SSL::Certificate puppetagent.com at '/var/lib/puppet/ssl/certs/puppetagent.com.pem'

Error: Could not request certificate: The certificate retrieved from the master does not match the agent's private key.」対処

[vagrant@puppetagent ~]$ sudo rm -rf /var/lib/puppet/ssl/*

試す(テキストファイルを作成する)

puppet agent Man Page — Documentation — Puppet Labs

manifest作成

[vagrant@puppetserver ~]$ cd /etc/puppet/manifests/
[vagrant@puppetserver manifests]$ sudo vi site.pp
file { '/tmp/sample.txt':
        mode => '0600',
        owner => 'root',
        group => 'root',
        content => 'hello puppet world!!!!',
        require => Package['httpd'],
}
↑はパーミッション600で所有者root、内容はcontentのとおり、実行にあたってhttpdパッケージを必要とする
# apply
[vagrant@puppetserver manifests]$ sudo puppet apply site.pp

--no-daemonize --onetimeと--no-daemonizeだけの違いが不明

バックグラウンドプロセスを作成しないためのオプションだが、意味がかぶっているような気がして両方設定する意味がわからなかったが

[vagrant@puppetagent ~]$ sudo puppet agent --no-daemonize
→処理がいつまでたっても終わらない
[vagrant@puppetagent ~]$ sudo puppet agent --no-daemonize --onetime
→おわる

となるので、「--no-daemonize --onetime」はセットにしてつかう

--verbose単品だと動かない

[vagrant@puppetagent ~]$ sudo puppet agent --verbose
Error: Could not run: Could not create PID file: /var/run/puppet/agent.pid

# --testを追加すると動く
[vagrant@puppetagent ~]$ sudo puppet agent --verbose --test
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppetagent.com
Info: Applying configuration version '1432695189'
Notice: /Stage[main]/Main/File[/tmp/sample.txt]/ensure: defined content as '{md5}a4c6a810001c3d93c6e121f054bc8066'
Notice: Finished catalog run in 0.02 seconds

# --testだけでも結果は一緒?→ではなく、でなくなるものがあるので、やはり「--test --verbose」とすべき
[vagrant@puppetagent ~]$ sudo puppet agent --test
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppetagent.com
Info: Applying configuration version '1432695189'
Notice: Finished catalog run in 0.01 seconds

なので以下のようにしたら良さそう

ドライラン

[vagrant@puppetagent ~]$ sudo puppet agent --test --verbose --onetime --no-daemonize --noop
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppetagent.com
Info: Applying configuration version '1432695189'
Notice: /Stage[main]/Main/File[/tmp/sample.txt]/ensure: current_value absent, should be file (noop)
Notice: Class[Main]: Would have triggered 'refresh' from 1 events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.02 seconds

あてる

[vagrant@puppetagent ~]$ sudo puppet agent --test --verbose --onetime --no-daemonize
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppetagent.com
Info: Applying configuration version '1432695189'
Notice: /Stage[main]/Main/File[/tmp/sample.txt]/ensure: defined content as '{md5}a4c6a810001c3d93c6e121f054bc8066'
Notice: Finished catalog run in 0.02 seconds

manifestを色々書いてみる

Manifests ~ マニフェスト — Documentation — Puppet Labs

resourceに指定できるもの確認

[root@puppetserver manifests]# puppet describe -l
These are the types known to puppet:
augeas          - Apply a change or an array of changes to the  ...
computer        - Computer object management using DirectorySer ...
cron            - Installs and manages cron jobs
exec            - Executes external commands
file            - Manages files, including their content, owner ...
filebucket      - A repository for storing and retrieving file  ...
group           - Manage groups
(略)

ファイルを分けて書くのであらかじめマスタ(site.pp)にインポートさせておく

[root@puppetserver manifests]# vi site.pp
import 'nodes/*.pp'

manifestにかいていく

ファイルの作成

[root@puppetserver nodes]# pwd
/etc/puppet/manifests/nodes
[root@puppetserver nodes]# vi file-add.pp
file {'testfile':
      path    => '/tmp/testfile',
      ensure  => present,
      mode    => 0640,
      content => "I'm a test file.",
}

user/group作成

[root@puppetserver nodes]# vi user-add.pp
# グループを作成する
group { "taro":
  gid => 1000,
  ensure => present
}
# ユーザーを作成する
user { "taro":
  ensure => present,
  home => "/home/taro",
  managehome => true,
  uid => 1000,
  gid => 1000,
  shell => "/bin/bash",
  comment => "Taro Yamada",
  password => ‘$6$OmC3KootOURrqOaP$63rwQ2bSE8op8wXa.ZWzgxm/iGvePTzEL5lOntmkPyYh5Qwh4lWs2DtyoEHcvsbYV5Q6a2ezzrZueb2ydrkhz0′
}

パッケージを入れて設定

# httpdパッケージをインストール
package { "httpd":
  provider => "yum",
  ensure => "installed"
}
# httpdサービスを起動する
service { "httpd":
  name => "httpd",
  ensure => running,
  require => Package["httpd"]
}
# /var/www/testディレクトリを作成する
file { "/var/www/test":
  ensure => directory,
  owner => "root",
  group => "root",
  require => Package["httpd"]
}
# httpd用の設定ファイルを作成する
file { "/etc/httpd/conf.d/mysite.conf" :
  content => "
  NameVirtualHost *:8000
  <VirtualHost *:8000>
  ServerName $hostname
  DocumentRoot /var/www/test
  ErrorLog logs/test-error_log
  CustomLog logs/test-access_log common
  </VirtualHost>",
  mode => "0644″,
  owner => "root",
  group => "root",
  subscribe => Service["httpd"]
}

コマンド実行

[root@puppetserver nodes]# vi command.pp
exec { 'find /home > /tmp/findhome.txt':
group => "root",
user => "root",
}

実行

[root@puppetagent puppet]# sudo puppet agent --test --verbose --onetime --no-daemonize
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppetagent.com
Info: Applying configuration version '1432709898'
Notice: /Stage[main]/Main/Group[taro]/ensure: created
Notice: /Stage[main]/Main/Package[httpd]/ensure: created
Notice: /Stage[main]/Main/File[/var/www/test]/ensure: created
Notice: /Stage[main]/Main/Service[httpd]/ensure: ensure changed 'stopped' to 'running'
Info: /Stage[main]/Main/Service[httpd]: Unscheduling refresh on Service[httpd]
Notice: /Stage[main]/Main/File[/etc/httpd/conf.d/mysite.conf]/ensure: defined content as '{md5}1b42c4fb21b00bc5f0f28a3f0d3495b6'
Notice: /Stage[main]/Main/User[taro]/ensure: created
Notice: Finished catalog run in 5.23 seconds
[root@puppetagent puppet]# ll /tmp/
total 12
-rw-r--r-- 1 root    root    1034 May 27 16:02 findhome.txt
-rwxrwxrwx 1 vagrant vagrant   62 May 26 19:40 script.sh
-rw-r----- 1 root    root      16 May 27 15:41 testfile
[root@puppetagent puppet]# service httpd status
httpd (pid  7485) is running...
[root@puppetagent puppet]# ll /var/www/test/
total 0
[root@puppetagent puppet]# cat /etc/httpd/conf.d/mysite.conf

  NameVirtualHost *:8000
  <VirtualHost *:8000>
  ServerName puppetagent
  DocumentRoot /var/www/test
  ErrorLog logs/test-error_log
  CustomLog logs/test-access_log common
  </VirtualHost>
広告を非表示にする