Puppet beginner guide (korean)
Puppet 초보자를 위한 설명서입니다.
"시스템관리자를 위한 Puppet3" 자료를 기초로 만들었습니다.
퍼펫 소개
형상관리 : 형상 관리 자동화. 패키지나 파일 같은 자원에 대한 설정을 기술한 명세서를 메니페스트라고 부름
퍼펫이 하는 일 : 현재의 설정과 매니페스트 비교하여 필요한 액션만 수행. 광범위한 플랫폼과 운영체제 지원.
퍼펫의 장점
- 매니페스트를 한 번만 작성하면 여러 장치에 중복 작업 없이 적용 가능
- 모든 서버가 매니페스트를 기준으로 서로 동기화 가능
- 매니페스트를 문서로 사용 가능
- 다양한 운영체제, 플랫폼, 명령어 문법 등에 유연
- 매니페스트는 코드이기 때문에 버전 및 다른 코드 관리 방식이 적용 가능
확장성
퍼펫의 언어 : 선언적인 프로그래밍 언어.
- 자원(Resource), 속성(Attribute) 이해
- https://docs.puppetlabs.com/references/stable/type.html
퍼펫 시작
테스팅 환경 준비하기
원하는 리눅스 배포판을 설치한 컴퓨터를 준비한다. 가상머신, Vagrant, 물리적 서버 상관없다. 여기에서는 주로 CentOS 5/CentOS 6 를 기준으로 설명한다.
적절하게 hostname 을 설정한다. (필요하면 /etc/hosts에 등록)
Puppet 설치
Puppet 최신버전은 3.7이다. 2014.11.27 현재 EPEL에 있는 Puppet 은 2.7 이다. "시스템관리자를 위한 Puppet3 자료"에서는 Puppet 3 를 기준으로 설명을 하고 있지만 이 문서에서는 Puppet 2.7 를 기준으로 설명한다.
Puppet 은 CentOS5, CentOS6 에 기본 들어있지 않으며 EPEL 에 있는 패키지 또는 Puppet 에서 제공하는 rpm을 이용하여 설치할 수 있다.
EPEL 를 이용하여 설치. CentOS에서 epel 의 yum repo를 이용하려면 epel-release rpm 을 설치하면 되며 이 rpm은 CentOS Extras 레포지토리에 이미 포함이 되어 있으므로 간단히 설치를 할 수 있다.
참고로 CentOS6 에서는 epel-release rpm 을 설치하고 yum 을 실행하면 "
Error : Cannot retrieve metalink for repositroy: epel. Please verify its path and try again.
" 에러가 난다. CentOS5로 CentOS6 으로 넘어가면서 /etc/yum.repos.d/epel.repo 파일의 mirrorlist 가 http에서 https로 바뀐 것과 연관이 있는데 일단 https로 되어 있는 부분을 http로 변경하면 사용은 가능하다. 이게 좋은 방법인지는?puppet rpm 뿐만 아니라 연관된 rpm을 함께 설치한다.
# cat /etc/redhat-release CentOS release 6.3 (Final) # yum install epel-release # yum install puppet .... ==================================================================================================================== Package Arch Version Repository Size ==================================================================================================================== Installing: puppet noarch 2.7.25-2.el6 epel 1.1 M Installing for dependencies: augeas-libs x86_64 1.0.0-7.el6 base 313 k compat-readline5 x86_64 5.2-17.1.el6 base 130 k dmidecode x86_64 1:2.12-5.el6_5 base 73 k facter x86_64 1.6.18-7.el6 epel 62 k libselinux-ruby x86_64 2.0.94-5.8.el6 base 100 k pciutils x86_64 3.1.10-4.el6 base 85 k ruby x86_64 1.8.7.374-2.el6 base 538 k ruby-augeas x86_64 0.4.1-1.el6 epel 21 k ruby-libs x86_64 1.8.7.374-2.el6 base 1.7 M ruby-shadow x86_64 1.4.1-13.el6 epel 11 k virt-what x86_64 1.11-1.2.el6 base 24 k Updating for dependencies: libselinux x86_64 2.0.94-5.8.el6 base 108 k libselinux-devel x86_64 2.0.94-5.8.el6 base 137 k libselinux-utils x86_64 2.0.94-5.8.el6 base 82 k pciutils-libs x86_64 3.1.10-4.el6 base 34 k .... Is this ok [y/N]:
- Puppetlabs 에서 제공한 패키지를 이용하여 설치하는 경우에는 https://docs.puppetlabs.com/guides/install_puppet/install_el.html 문서를 참고한다.
- CentOS6 의 경우
sudo rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm
를 이용하여 yum repo 를 설정하고 yum 으로 puppet 을 설치한다.
- CentOS6 의 경우
매니페스트 작성하기
처음 작성하는 manifests
manifests 구조화
- nodes.pp 생성
- 노드 선언
manifests 파일을 만들어 실습해 보기.
site.pp 파일에 file 속성을 이용해서 생성을 하고 puppet apply 명령을 이용 실행을 해봄.
그러고 나서 manifests 디렉토리 밑에 site.pp, nodes.pp 로 구조화를 함.
테스팅을 위해서 github에 샘플 puppet manifests 를 만들었음. git clone https://github.com/taejoonmoon/puppet-training.git
site.pp 가 메인 매니케스트 파일임. 아주 작은 site.pp 를 만들고 nodes.pp 처럼 다른 매니페스트 파일을 불러오도록 만든다.
[vagrant@vagrant-centos64 ~]$ mkdir puppet-training [vagrant@vagrant-centos64 ~]$ cd puppet-training/ (or git clone https://github.com/taejoonmoon/puppet-training.git) [vagrant@vagrant-centos64 puppet-training]$ tree . |-- README.md `-- manifests |-- nodes.pp `-- site.pp 1 directory, 3 files [vagrant@vagrant-centos64 puppet-training]$ cat manifests/site.pp import 'nodes.pp' [vagrant@vagrant-centos64 puppet-training]$ cat manifests/nodes.pp node 'vagrant-centos64.vagrantup.com' { file { '/tmp/hello': content => "Hello, world\n", } } [vagrant@vagrant-centos64 puppet-training]$ puppet apply manifests/site.pp notice: /Stage[main]//Node[vagrant-centos64.vagrantup.com]/File[/tmp/hello]/ensure: defined content as '{md5}a7966bf58e23583c9a5a4059383ff850' notice: Finished catalog run in 0.04 seconds [vagrant@vagrant-centos64 puppet-training]$ cat /tmp/hello Hello, world
패키지, 파일, 서비스
패키지
$ vim apache.pp package { 'httpd': ensure => installed, } $ sudo puppet apply apache.pp
- 특정 버전 설치 : ensure => 'httpd-2.2.15-39.el6.centos.x86_64'
패키지 삭제 : ensure => absent
패키지 업데이트 : ensure => latest
모듈
- 퍼핏 매니페스트를 모듈로 관리하면 해석과 유비 보수가 매우 용이함. 퍼핏 모듈은 연관된 패키지들을 그룹으로 관리함.
- 모듈을 사용할 때에는 puppet 에게 모듈 위치를 알려주어야 함. (modulepath)
$ cd puppet-training $ mkdir -p modules/apache $ cd modules/apache $ mkdir files manifests $ tree ~/puppet-training . |-- README.md |-- manifests | |-- nodes.pp | `-- site.pp `-- modules `-- apache |-- files `-- manifests `-- init.pp $ cat modules/apache/manifests/init.pp class apache { package { 'httpd': ensure => installed, } } $ cat manifests/nodes.pp node 'vagrant-centos64.vagrantup.com' { include apache } $ sudo puppet apply /home/vagrant/puppet-training/manifests/site.pp --modulepath=/home/vagrant/puppet-training/modules
- 자주 사용하는 puppet apply 명령어 생성
$ sudo vim /usr/local/bin/papply $ sudo chmod a+x /usr/local/bin/papply $ cat /usr/local/bin/papply #!/bin/bash sudo puppet apply /home/vagrant/puppet-training/manifests/site.pp --modulepath=/home/vagrant/puppet-training/modules $* $ papply
서비스
- apache/manifests/init.pp 수정
service { 'httpd': ensure => running, require => Package['httpd'], } $ papply
- require 속성 : 자원들 간의 연관성을 정의. Package 에서 P가 대문자임. 이는 puppet 에세 대괄호 뒤에 오는 이름을 가진 패키지 자원의 인스턴스를 이용한다는 것을 알려줌.
- enable 속성 : 부팅 할 때 서비스 시작 여부 제어
- 상태 확인이 어려운 서비스의 경우 hasstatus, pattern 등의 속성 등을 이용할 수 있음. 또는 status 속성을 이용하아여 직접 명령어를 지정해 줄 수 있음.
- start, stop, restart 등도 다른 명령어로 지정이 가능함.
파일
apache/manifests/init.pp 수정
$ vim apache/manifests/init.pp file { '/etc/httpd/conf.d/default.conf': source => 'puppet:///modules/apache/default.conf', notify => Service['httpd'], } file { '/var/www/html/index.html': source => 'puppet:///modules/apache/index.html', } $ cat apache/files/default.conf <VirtualHost *:80> DocumentRoot /var/www/html ServerName dummy-host.example.com </VirtualHost> $ cat apache/files/index.html welcome to puppet! $ papply $ curl localhost
- source 지정 : puppet:///modules 에서 /// 세개가 들어감. files 는 생략해야 함.
- notify : 다른 자원 호출.
GIT 으로 Puppet 관리하기
git vs puppet master 장단점
git 사용시 장점
사용자 관리
user & ssh_authorized_key
# user test user { 'art': ensure => present, comment => 'my art', home => '/home/art', managehome => true, } ssh_authorized_key { 'art_ssh': user => 'art', type => 'rsa', key => 'AAAAB3NzaC1yc2EA.....sYguH8xtSS/34I2NQ==', }
- User : 계정 상세하려면 ensure 를 absent 로 변경
- 새로운 ssh 키를 생성하기 위해서는 ssh-keygen 명령어를 사용.
exec, cron, file, templates
exec, cron
# exec test exec { 'Run my arbitray command': command => '/bin/echo I ran this command on `/bin/date` > /tmp/command.output.txt', creates => '/tmp/command.output.txt', #unless => '/usr/bin/test -f /tmp/command.output.txt', #onlyif => '/usr/bin/test -f /tmp/command.output.txt', #path => ['bin','/usr/bin'], } exec { 'command-1': command => '/bin/touch /tmp/step1 && /bin/echo Step 1', #creates => '/tmp/step1', unless => '/usr/bin/test -f /tmp/step1', } exec { 'command-2': command => '/bin/echo Step 2', require => Exec['command-1'], } # cron test cron { 'test cron': command => 'touch /tmp/testcron', hour => '04', minute => '00', }
템플릿
템플릿 함수 : 약간만 다른 여러 파일을 가지고 있거나, 동적으로 변하는 정보를 포함한 파일이 있을 때 템플릿을 사용할 수 있음.
- <%= %> 설명
- Puppet 에서 변수는 $ 를 사용하지만 템플릿에서는 @ 를 이용함. (템플릿이 퍼핏이 아린 루비로 쓰여져 있기 때문임)
- facter 를 이용하여 각종 시스템값을 이용할 수 있음.
$ cat apache/manifests/init.pp # template test $vhost_port = "8080" $site_name = 'example.com' file { '/etc/httpd/conf.d/example.com.conf': content => template('apache/vhost.conf.erb'), notify => Service['httpd'], } $ cat apache/templates/vhost.conf.erb Listen <%= @vhost_port %> <VirtualHost *:<%= @vhost_port %>> DocumentRoot /var/www/html ServerName <%= @site_name %> </VirtualHost> # <%= @ipaddress %> # <%= @fqdn %> # <%= @memorysize %> # <%= @operatingsystem %> $ facter | less architecture => x86_64 augeasversion => 1.0.0 domain => vagrantup.com facterversion => 1.6.18 fqdn => vagrant-centos64.vagrantup.com hardwareisa => x86_64 hardwaremodel => x86_64 hostname => vagrant-centos64 id => vagrant ....
definition 과 class
배열
# array test package { ['lynx','mc','traceroute']: ensure => installed, }
정의(definition)
- 다른 유형의 자원들을 그룹화 할 때 define 사용.
- 매개변수를 줄 수 있음. 매개변수를 줄 때는 기본값을 지정하여 사용할 수 있음.
$ cat modules/base/manifests/script_job.pp # define test define base::script_job ( $hour = '00' ) { include base file { "/usr/local/bin/${name}": source => "puppet:///modules/base/${name}", mode => '0755', } cron { "Run ${name}": command => "/usr/local/bin/${name}", hour => $hour, minute => '00', user => 'vagrant', } } $ cat manifests/nodes.pp node 'vagrant-centos64.vagrantup.com' { include base base::script_job { 'backup_database1': hour => '05', } }
클래스(class)
- 특정 서비스를 구현하는 퍼펫 자원을 그룹화 하기 위해서 사용
- 클래스도 definition 과 마찬가지로 몇 개의 매개변수를 지정할 수 있음. 또한 매개변수는 기본값을 가질 수 있음.
매개변수를 잘 이용하면 중복된 코드를 만들지 않고 코드의 재활용성을 높일 수 있음.
class appserver($domain,$databse) { .... } class hadoop($role = 'node') { }
- 클래스는 모듈로 구성하는 것이 좋음. 각 클래스는 modules/MODULE_NAME/manifests 디렉토리에 저장해야 하고 하나의 클래스를 포함하는 각 파일은 클래스의 이름을 따서 파일 이름을 생성해야 함. (예외는 init.pp)
- 클래스 선언은 include MODULE_NAME 또는 require MODULE_NAME 또는 매개변수를 주어서 선언하는 방법이 있음.
- 클래스와 definition 의 차이점 : 클래스는 단독 개체임. 오직 한 시점에 하나의 노드에 하나의 클래스의 인스턴스만 존재함.
- 하나의 노드에 여러 인스턴스가 필요한 경우 definition
- 웹서버처럼 지정한 노드에 같은 용도의 다른 인스턴스끼리 충돌이 발생할 것 같으면 클래스 사용함.
표현식과 로직
조건문 : if, unless, case, 셀렉터
if EXPRESSION { OPTIONAL_SOMETHING } elsif ANOTHER_EXPRESSION { OPTIONAL_SOMETHING_ELSE } else { OPTIONAL_OTHER_THING } case EXPRESSION { CASE1 { BLOCK1 } CASE2 { BLOCK2 } CASE3 { BLOCK3 } ... default : { ... } } $result = EXPRESSION ? { CASE1 => VALUE1, CASE2 => VALUE2, CASE3 => VALUE3, default => DEFAULT_VALUE, }
표현식 : 비교문, boolean 연산자, 산술 연산자
- 비교 연산자 : == , !=, < , <= , > , >=
- Boolean 연산자 : and , or , !
- 문자열, 배열 또는 해쉬 멤버쉽 연산자 : in
- 산술 연사자 : + , - , * , / , << , >>
정규표현식
if $::hostname =~ /app.*staging/ { if $uname =~ /(\d+)\.\d+\.\d+/ { notify { "I have kernel version ${0}, major version ${1}": } }
텍스트 대체
문자열을 대체하기 위해서는 regsubst 함수를 이용함.
$output = regsubst('Look at my cat picture','my (.*) picture','this adorable \1') notify { $output: } 출력결과 Notice: Look at this adorable cat
배열
['jerry', 'george', 'elaine'] package { [ 'php5-cli', 'php5-fpm', 'php-pear' ]: $developers[0]
해쉬
$interfaces = { 'lo0' => '127.0.0.1', 'eth0' => '192.168.0.1', } $interfaces = { 'lo0' => { 'address' => '127.0.0.1', 'netmask' => '255.0.0.0', }, 'eth0' => { 'address' => '192.168.0.1', 'netmask' => '255.255.255.0', } }
리포팅 및 문제 해결
리포팅
디버그
- --debug 옵션
$ papply --debug
Noop 실행
- Noop은 no-operation을 뜻하며 실제 시스템에 적용하지 않으면서 모든 일을 수행함. 어떤 변경사항을 적용하기 전에 테스팅이 가능함.
$ papply --noop
구문 오류 검사
- 매니페스트의 구문 오류가 없는지 확인하기 위해서 parser validate 명령어를 이용.
$ puppet parser validate nodes.pp
디버그 출력
- notify, exec
모니터링
에러
컴파일 에러, 명령어 옵션 오타
퍼펏과 관련해 알아두면 좋은 내용
퍼펫 스타일
- 코드를 모듈로 분리
- 공통 코드를 definition 으로 리팩토링
- 노드 선언은 간단하게 한다
- 퍼펫 린트 사용
- 주석이 필요 없는 코드 제작
퍼펫 관련 학습 자료
- 참조문서
- Puppet resource type : https://docs.puppetlabs.com/references/latest/type.html
- Puppet forge : puppet code 커뮤니티 저장소. https://forge.puppetlabs.com/
$ puppet module search httpd Searching http://forge.puppetlabs.com ... NAME DESCRIPTION AUTHOR KEYWORDS .... puppetlabs-apache Puppet module for Apache @puppetlabs web httpd centos rhel ubuntu ssl wsgi proxy [vagrant@vagrant-centos64 ~]$ mkdir .puppet/modules [vagrant@vagrant-centos64 ~]$ puppet module install puppetlabs-apache Preparing to install into /home/vagrant/.puppet/modules ... Downloading from http://forge.puppetlabs.com ... Installing -- do not interrupt ... /home/vagrant/.puppet/modules └─┬ puppetlabs-apache (v1.2.0) ├── puppetlabs-concat (v1.1.2) └── puppetlabs-stdlib (v4.5.1)
더 나아가기
- Pro Puppet 책을 먼저 볼 것을 추천합니다. 그러고 나서 각종 다양한 팁을
- Pro Puppet 주요 부분 요약
- Beginner's Guide to Puppet Modules : http://docs.puppetlabs.com/guides/module_guides/bgtm.html
The Puppet Language Style Guide : http://docs.puppetlabs.com/guides/style_guide.html
- https://puppetlabs.com/learn/roles-profiles-introduction Roles & Profiles - An Introduction
- Puppet 연관 프로그램
- PuppetDB : Puppet 의 인벤토리 정보를 API 이용 실시간 조회가 가능한 프로그램.
- Puppet beginner guide (korean) : Puppet GUI 임
- Mcollective : RabbitMQ/ActiveMQ 등의 미들웨어와 결합하여 대량의 시스템을 orchestration (command & control) 할 수 있는 프로그램임.