vagrant의 sandbox 플러그인

너무 글을 안써서 글을 좀 써야겠다는 마음으로 짧지만 삶에 도움되는
vagrant sandbox 명령어를 사용할 수 있게 해주는
sahara라는 플러그인을 소개하려고 한다.

해당 플러그인의 소스 저장소는 다음의 링크를 참고하시라.

sahara

sahara가 뭐하는 녀석인가?

사하라 하면 사막!
사막하면 모래!
모래 하면 sandbox 이다! (말도안되지만..그냥 넘어가자..ㅎ)
vagrant에서 사용하는 virtualbox를 sandbox 처럼 사용할 수 있게 해주는 플러그인이다.

주의

  • sahara는 Vagrant 1.0 이하에서는 제대로 동작하지 않는다.

설치

리눅스 계열은 요렇게 하면된다. (윈도우즈는….ㅠㅠ)

[code lang=text]
$ git clone https://github.com/ryuzee/sahara.git
$ cd sahara
$ bundle install
$ vagrant plugin install sahara
[/code]

설치 잘됐는지 확인

아래와 같이 나오면 잘되는 것이다.

[code lang=text]
$vagrant plugin list
sahara (0.0.17)
[/code]

사용법

이름은 sahara 인데 설치하면 사용할 수 있는 명령어는 sandbox 이다. 그냥 이름이 sandbox 였으면 안헷갈렸을것 같다.
명령어는 달랑 5개 밖에 없긴 한데, 그걸로도 충분하다.

[code lang=text]
### 샌드박스 모드 활성화
$ vagrant sandbox on

### 스냅샷 저장하기
$ vagrant sandbox commit

### 롤백하기
$ vagrant sandbox rollback

### 샌드박스 모드 끄기
$ vagrant sandbox off

### 샌드박스 상태 확인
$ vagrant sandbox status
[/code]

sandbox commit은 겁나 느리다

이걸 빠르게 하려면 가상머신을 끄고 하면 빠르다
~~근데 다시 켜는 시간은..읍읍..~~

[code lang=text]
$ vagrant halt
$ vagrant sandbox commit
[/code]

이제 이걸로 좀 더 편하게 chef질을 할 수 있게 됐다~! 예이!

참고로 virtualbox 뿐 아니라 VMware fusion, libvirt, parallels 도 지원한다~!

Chef Server 12으로 인프라 자동화하기

Chef Server 12를 사용해보기

 

2년전에 chef-server로 게임서버들을 잘 구성해서 사용했었다.
knife-solo로 하면 10대 정도까지는 그냥 관리가 가능하긴 한데,
role이나 databag같은 메타데이터를 다루게 되면,
그때부터는 chef-server를 사용하는 것도 좋은 것 같다.

2년 전에도 쉐프 서버 구축할 때 이리저리 고생을 했던 기억이 나는데,
정리를 제대로 안해놨더니, 했던 삽질을 다시하면서 나의 멍청함을 뇌로 되새기고 있다.

아무튼 다시는 그런일이 벌어지지 않게 하기 위해서,
좀 정성들여서 정리를 하는중이고, 특히 에러가 나는 포인트를 계속해서 정리중이다.

chef서버와 client는 virtual box를 사용해서 2대를 실행했고,
workstation은 mac에 chefdk를 설치해서 돌리고 있다.

사실 chef server 이외에는 chef client & knife가 깔리면 되는거라서, 뭘 어떻게 하든 크게 관계는 없을 것 같다.

기본지식

  • chef-server-core만 인스톨한 후에는 chef-server-ctl커맨드로 reconfigure을 실행해주어야한다. 설정파일이 변경되면 reconfigure를 실행해야한다.
  • chef-server-core관련 파일은 /etc/opscode에 있다.
  • 로그는 /var/log/opscode에 있다
  • chef서버의 로그를 실시간으로 보려면 chef-server-ctl tail 명령어를 사용하면 된다.

chef server 12에서는 여러가지 기능이 추가된 것 같긴한데, 기본만 설치하자.
– chef-server-core
– manage ui

chef-server-core 설치

아래 링크에서 chef-server-core_12.x.x-x_amd64.deb를 받는다. (버전은 그때 그때 다르다. RHEL은 패스)
2016년 10월의 최신버전은 12.9.1이다.

우분투 16.04
https://packages.chef.io/stable/ubuntu/16.04/chef-server-core_12.9.1-1_amd64.deb

우분투 14.04
https://packages.chef.io/stable/ubuntu/14.04/chef-server-core_12.9.1-1_amd64.deb

우분투 12.04
https://packages.chef.io/stable/ubuntu/12.04/chef-server-core_12.9.1-1_amd64.deb

아래 명령어를 실행

[code lang=text]
$ sudo dpkg -i chef-server-core_12.x.x-x_amd64.deb
$ sudo chef-server-ctl reconfigure
[/code]

reconfigure 실행시의 에러 처리

reconfigure를 실행시에 아래와 같은 에러가 날 수 있는데, 이는 nginx cookbook의 이슈이다.

[code lang=text]
Chef::Exceptions::ValidationFailed
———————————-
common_name is required
[/code]

이를 해결하려면 /etc/hosts에 유효한 호스트명을 뭐라도 넣어줘야된다.
에는 hostname 이라는 명령어를 치면 나오는 녀석으로 변경해야한다.

sudo echo "127.0.0.1 localhost localhost.localdomain <hostname>" | sudo tee -a /etc/hosts

이게 오픈소스가 되서그런지 버그가 은근 있는데, reconfigure 시에 아래와 같은 에러가 나올 수도 있다.

[code lang=text]
ubuntu@chef-server:~$ sudo chef-server-ctl reconfigure
Starting Chef Client, version 12.14.98
resolving cookbooks for run list: [“private-chef::default”]
Synchronizing Cookbooks:
– enterprise (0.10.1)
– yum (3.13.0)
– runit (1.6.0)
– packagecloud (0.2.5)
– apt (2.9.2)
– openssl (6.0.0)
– private-chef (0.1.0)
Installing Cookbook Gems:
Compiling Cookbooks…
[2016-10-21T03:00:43+00:00] WARN: Chef::Provider::AptRepository already exists! Cannot create deprecation class for LWRP provider apt_repository from cookbook apt
[2016-10-21T03:00:43+00:00] WARN: AptRepository already exists! Deprecation class overwrites Custom resource apt_repository from cookbook apt
[2016-10-21T03:00:43+00:00] WARN: Chef::Provider::YumRepository already exists! Cannot create deprecation class for LWRP provider yum_repository from cookbook yum
[2016-10-21T03:00:43+00:00] WARN: YumRepository already exists! Deprecation class overwrites Custom resource yum_repository from cookbook yum
Recipe: private-chef::default
* directory[/etc/opscode] action create (up to date)
* directory[/etc/opscode/logrotate.d] action create (up to date)
[2016-10-21T03:00:43+00:00] FATAL:

———————————————————————–
BOOT007: The secrets file (/etc/opscode/private-chef-secrets.json) is present
but the file /etc/opscode/pivotal.pem is missing.

Ensure that private-chef-secrets.json is copied into /etc/opscode from the
first Chef Server node that you brought online, then run
‘chef-server-ctl reconfigure’ again.
———————————————————————–
[/code]

이 경우에는 /etc/opscode/private-chef-secrets.json 파일을 삭제하고
다시 sudo chef-server-ctl reconfigure를 해주면 된다.

user/org를 생성

[code lang=text]
### user생성
chef-server-ctl user-create user_name first_name last_name email password –filename ADMIN_PEM_FILE_NAME

### org생성
chef-server-ctl org-create short_name full_organization_name –association_user user_name –filename ORG_VALIDATION_KEY_FILE_NAME
[/code]

/etc/opscode/admin.pem
/etc/opscode/orgname-validator.pem
등의 이름이 뭘하는 파일인지 알아보기 쉽다.

chef manage ui 설치

이번 버전부터 ui가 엄청 이뿌게 변했다.
소스를 대충 보니 bootstrap을 사용한것 같은데, 개발자스럽긴하지만, 이쁜 UI이다.

[code lang=text]
$ sudo chef-server-ctl install opscode-manage
$ sudo opscode-manage-ctl reconfigure
[/code]

12.9 버전에서 opscode-manage가 chef-manage로 변경되었다. 최신버전을 쓰는 사람은 chef-manage로 설치하자

[code lang=text]
$ sudo chef-server-ctl install chef-manage
$ sudo chef-server-ctl reconfigure
$ sudo chef-manage-ctl reconfigure
[/code]

workstation 구축

chef를 설치

[code lang=text]
$ sudo curl -L https://www.opscode.com/chef/install.sh | sudo bash
[/code]

chefdk(chef development kit) 라는 녀석을 설치해도 된다.

chefdk에는 chef, Test Kitchen, ChefSpec, Foodcritic, Chef Client, Knife, Ohai, Chef Zero 등이 함께 들어 있어서 쉐프 레시피개발 및 테스트에 좋다.

knife 설정

[code lang=text]
$ knife configure
Where should I put the config file? [/home/USER/.chef/knife.rb]
Please enter the chef server URL: [https://xxx:443] https://chef-server/organizations/org
Please enter an existing username or clientname for the API: [user] <USER>
Please enter the validation clientname: [chef-validator] <ORG>-validator
Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem] /Users/wapj/chef/.chef/<ORG>-validator.pem
Please enter the path to a chef repository (or leave blank): <CHEF-REPO-PATH>
[/code]

위와 같이 하면 .chef 디렉토리 아래에 knife.rb 파일이 생긴다.
해당 파일은 아래와 같이 생겼다.

[code lang=text]
### knife.rb
log_level :info
log_location STDOUT
node_name ‘wapj’
client_key ‘/Users/wapj/chef/.chef/admin.pem’
validation_client_name ‘company-validator’
validation_key ‘/Users/wapj/chef/.chef/org-validator.pem’
chef_server_url ‘https://wapj-VirtualBox/organizations/wapj’
syntax_check_cache_path ‘/Users/wapj/chef/.chef/syntax_check_cache’
cookbook_path [“/Users/wapj/chef/site-cookbooks”]
[/code]

admin.pem파일과 org-validator.pem 파일은 쉐프 서버에서 scp 명령어 등으로 잘 가져와서 해당디렉토리에 복사하자.

chef서버와 잘 통신되는지 확인

아래와 같은 명령어로 확인이 가능하다.

[code lang=text]
$ knife ssl check
[/code]

trouble shooting

knife.rb의 chef_server_url설정에 아이피를 넣은 경우

아래와 같은 에러가 난다.

[code lang=text]
Connecting to host 192.168.10.111:443
ERROR: The SSL cert is signed by a trusted authority but is not valid for the given hostname
ERROR: You are attempting to connect to: ‘192.168.10.111’
ERROR: The server’s certificate belongs to ‘wapj-VirtualBox’

TO FIX THIS ERROR:

The solution for this issue depends on your networking configuration. If you
are able to connect to this server using the hostname wapj-VirtualBox
instead of 192.168.10.111, then you can resolve this issue by updating chef_server_url
in your configuration file.

If you are not able to connect to the server using the hostname wapj-VirtualBox
you will have to update the certificate on the server to use the correct hostname.
[/code]

이 경우 /etc/hosts에 server의 domain혹은 QFDN을 아래와 같은 식으로 넣어주어야 한다.

[code lang=text]
# hosts
192.168.10.111 wapj-VirtualBox
[/code]

chef server에서 받은 인증서가 localhost로 되어 있을 때

로컬에서만 테스트하다가 실제로 서버를 올리면 이런 일이 생기곤 한다.
workstation 에서 아래의 명령어를 실행했는데

[code lang=text]
$ knife ssl check
[/code]

아래와 같은 에러가 나는경우

[code lang=text]
Connecting to host chef.gyus.me:443
ERROR: The SSL cert is signed by a trusted authority but is not valid for the given hostname
ERROR: You are attempting to connect to: ‘chef.gyus.me’
ERROR: The server’s certificate belongs to ‘localhost’

TO FIX THIS ERROR:

The solution for this issue depends on your networking configuration. If you
are able to connect to this server using the hostname localhost
instead of chef.gyus.me, then you can resolve this issue by updating chef_server_url
in your configuration file.

If you are not able to connect to the server using the hostname localhost
you will have to update the certificate on the server to use the correct hostname.
[/code]

이 경우는 chef server의 /etc/opscode/chef-server.rb 파일에 설정을 추가해주어야한다.
chef server의 도메인이 chef.gyus.me라고 한다면, 아래와 같이 수정해 주면 된다.

[code lang=text]
### /etc/opscode/chef-server.rb
api_fqdn “chef.gyus.me”
[/code]

설정 파일이 수정되었으므로 서버에서 chef-server-ctl reconfigure를 한번더 실행해준다.

그리고 workstation으로 돌아와서 인증서를 받아오는 작업을 다시 해주자.

[code lang=text]
$ knife ssl fetch
$ knife ssl check
[/code]

아래와 같이 나오면 성공이다.

[code lang=text]
Connecting to host chef.gyus.me:443
Successfully verified certificates from `chef.gyus.me’
[/code]

아래와 같은 에러가 날 때

[code lang=text]
$knife status
ERROR: The object you are looking for could not be found
Response: <!DOCTYPE html>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<meta http-equiv=”X-UA-Compatible” content=”IE=EmulateIE7″ />
<title>Chef – 404 Not Found</title>
<link media=”all” rel=”stylesheet” type=”text/css” href=”/css/all.css” />
<!–[if lt IE 7]><link rel=”stylesheet” type=”text/css” href=”/css/lt7.css” /><![endif]–>
</head>
<body>
<div class=”header-block”>
<div id=”header”>
<strong class=”logo”><a href=”http://www.getchef.com”>Chef</a></strong>
</div>
</div>
<div id=”wrapper”>
<div id=”main”>
<div class=”mybox”>
<div id=”content”>
<h1>404 – Not Found</h1>
<p>Sorry, I can’t find what you are looking for.</p>
</div>
</div>
</div>
</div>
<div class=”footer-block”>
<div id=”footer”>
<div class=”mybox”>
</div>
<div class=”footer-bottom”>
<span>© 2010 – 2014 Chef Software, Inc. All Rights Reserved</span>
</div>
</div>
</div>
</body>
</html>
[/code]

knife.rb 설정의 chef_server_url에 정말로 serverURL만 넣은 경우에 나는 에러이다.

아래와 같은 식으로 되어있다면,

[code lang=text]
chef_server_url https://wapj-VirtualBox/
[/code]

뒤에 organizations/<ORGANIGATION>을 붙여주자.

[code lang=text]
chef_server_url https://wapj-VirtualBox/organizations/wapj
[/code]

쿡북 만들기

아래 명령어로 hello라는 쿡북을 site-cookbooks에 만들었다.
레시피

[code lang=text]
$ knife cookbook create hello -o site-cookbooks
[/code]

간단히 아래 파일을 변경하자.

[code lang=text]
site-cookbooks/hello/recipes/defau1t.rb
[/code]

[code lang=text]
### default.rb
log “Hello , Chef!”
[/code]

쿡북을 서버로 업로드하기

아래의 커맨드를 사용하면 모든 쿡북이 서버로 업로드 된다.

[code lang=text]
$ knife cookbook upload -a
[/code]

하나의 쿡북만 업로드 하고 싶은 경우는 아래의 커맨드를 사용하자.

[code lang=text]
$ knife cookbook upload <쿡북이름> -o <해당쿡북의 폴더가 있는 경로>
$ knife cookbook upload hello -o ./site-cookbooks/
[/code]

쿡북 업로드시에 SSL 에러가 나는 경우

[code lang=text]
WARN: Found a directory hello in the cookbook path, but it contains no cookbook files. skipping.
ERROR: SSL Validation failure connecting to host: 192.168.10.111 – hostname “192.168.10.111” does not match the server certificate
[/code]

자가 인증서로 검증하기 때문에 나는 당연한 에러(?!) 라서, 검증하지 말라고 하면 된다..;;

아래 한줄을 knife.rb에 추가해주자

[code lang=text]
ssl_verify_mode :verify_none
[/code]

chef-client

chef 설치

  • 서버와의 인증에는 비밀키를 사용한다.
  • chef server는 client별로 비밀키를 발행하고, 공개키를 chef-server에 등록한다.
  • client별로 비밀키를 발행해야 하기 때문에, 미리 준비된 validator-key를 사용한다.
  • client는 처음에는 validator-key로 통신해서 chef server에 client로 등록한후 이후의 통신에 필요한 비밀키가 발행된다.
  • workstation에서 삽질했던것 처럼 hosts에 chef server의 ip를 등록해야한다.

knife bootstrap으로 client 등록하기

전제 조건
1. chef server에서 client서버로 비밀번호 없이 root계정으로 로그인을 할 수 있어야한다.
2. bootstrap 을 실행할 서버의 /etc/hosts에 chef server의 ip를 등록한다.

1번 조건은 root의 홈디렉토리에 chef server의 퍼블릭키를 authorized_keys파일에 등록하면 된다.
2번은 위의 workstation 설정시에 보았던, /etc/hostschef server의 ip를 등록하면 된다.

chef server가 만약에 해킹당하게 되면, 모든 서버에 접속 할 수 있으므로 이 방법을 사용할 때에는,
chef server의 보안에 특히 주의 해야한다.
나 같은 경우는 chef server를 사용할 때만 켰다가 끄는 방식으로 사용했다.

위의 조건이 만족되면, 아래의 커맨드로 바로 노드를 등록할 수 있다.

[code lang=text]
$ knife bootstrap <client server ip> -x <user> -N <node name>
[/code]

성공하게 되면 아래와 같은 메세지가 나오게 된다.

[code lang=text]
### workstation의 chef repo 디렉토리에서 실행하면 된다.

$knife bootstrap 192.168.10.101 -x root -N node1
Doing old-style registration with the validation key at /Users/wapj/chef/my-chef/.chef/company-validator.pem…
Delete your validation key in order to use your user credentials instead

Connecting to 192.168.10.101
192.168.10.101 —–> Existing Chef installation detected
192.168.10.101 Starting the first Chef Client run…
192.168.10.101 Starting Chef Client, version 12.7.2
192.168.10.101 Creating a new client identity for node1 using the validator key.
192.168.10.101 resolving cookbooks for run list: []
192.168.10.101 Synchronizing Cookbooks:
192.168.10.101 Compiling Cookbooks…
192.168.10.101 [2016-02-16T21:02:32+09:00] WARN: Node node1 has an empty run list.
192.168.10.101 Converging 0 resources
192.168.10.101
192.168.10.101 Running handlers:
192.168.10.101 Running handlers complete
192.168.10.101 Chef Client finished, 0/0 resources updated in 02 seconds
[/code]

node가 등록되었는지 확인

[code lang=text]
### workstation의 chef repo에서 실행
$ knife node list
[/code]

잘 등록되었다면 아래와 같이 나올 것이다.

[code lang=text]
node1
[/code]

node에 레시피 등록 하기

노드는 등록되었지만, 레시피가 아무것도 없으므로 실행해봐야 아무것도 안나온다.
레시피를 등록해보자.

해당 작업은 chef server의 WEB UI에서도 가능하므로, 웹사이트에 들어가서 해도 된다.

[code lang=text]
### workstation의 chef repo에서 실행
$ knife node run_list add <노드명> ‘recipe[레시피명]’
$ knife node run_list add node1 ‘recipe[hello]’
[/code]

node에서 레시피 실행하기

레시피의 실행은 각 노드 서버에 들어가서 $ sudo chef-client 를 실행해주면 되지만,
귀찮게 일일이 들어가면 굳이 서버를 설치한 이유가 없으니 서버에서 실행할 수 있는 방법을 찾아보자.

바로 knife search node를 이용하는 방법인데,

아래의 명령어를 실행하면, 조건을 줘서 chef client를 찾을 수 있다.

[code lang=text]
$ knife search node “fqdn:*”
[/code]

그리고 조건은 knife ssh에도 동일하게 사용가능 한데, 조건과 조합하여 여러서버에 커맨드를 날릴수있다.
예를 들어 아래와 같이 실행하게 되면, 모든 서버에 echo "hello" 명령을 날리게 된다.

[code lang=text]
$ knife ssh “fqdn:*” ‘echo “hello”‘
[/code]

이를 응용하여 아래와 같이 실행하게 되면, 모든 클라이언트에 sudo chef-client를 실행 할 수 있게 된다.

[code lang=text]
$ knife ssh “fqdn:*” “sudo chef-client”
[/code]

hosts에 정보가 없는 경우

아래와 같은 에러가 난다.

[code lang=text]
WARNING: Failed to connect to node1 — SocketError: getaddrinfo: nodename nor servname provided, or not known
[/code]

이 경우는 workstation의 /etc/hosts에 node1의 ip를 등록해야한다.

[code lang=text]
### workstaions의 /etc/hosts
192.168.10.101 node1
[/code]

다시 실행해보면~

[code lang=text]
$ knife ssh “fqdn:*” “sudo chef-client”
[/code]

아직도 에러가 난다;;;

[code lang=text]
node1
node1 Starting Chef Client, version 12.7.2
node1 resolving cookbooks for run list: [“hello”]
node1 Synchronizing Cookbooks:
node1 [2016-02-16T21:45:15+09:00] ERROR: SSL Validation failure connecting to host: wapj-virtualbox – hostname “wapj-virtualbox” does not match the server certificate
node1 [2016-02-16T21:45:15+09:00] ERROR: SSL Validation failure connecting to host: wapj-virtualbox – hostname “wapj-virtualbox” does not match the server certificate
node1 [2016-02-16T21:45:15+09:00] ERROR: SSL Validation failure connecting to host: wapj-virtualbox – hostname “wapj-virtualbox” does not match the server certificate
node1 ================================================================================
node1 Error Syncing Cookbooks:
node1 ================================================================================
node1
node1 Unexpected Error:
node1 —————–
node1 OpenSSL::SSL::SSLError: SSL Error connecting to https://wapj-virtualbox/bookshelf/organization-7479a4a25da1226f99983095c54052ba/checksum-40dcaffc3a2cdc8968a18f61672dab63?AWSAccessKeyId=49472f43a12b78c05ea083a9e82ac20de4ca4463&Expires=1455655515&Signature=ftp5IYQKkyvjyXYPG%2BlPltfh/18%3D – hostname “wapj-virtualbox” does not match the server certificate
node1 Running handlers complete
node1 [2016-02-16T21:45:40+09:00] ERROR: Exception handlers complete
node1 Chef Client failed. 0 resources updated in 27 seconds
node1 [2016-02-16T21:45:40+09:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
node1 [2016-02-16T21:45:40+09:00] ERROR: SSL Validation failure connecting to host: wapj-virtualbox – hostname “wapj-virtualbox” does not match the server certificate
node1 [2016-02-16T21:45:40+09:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
node1 [2016-02-16T21:45:40+09:00] ERROR: SSL Error connecting to https://wapj-virtualbox/bookshelf/organization-7479a4a25da1226f99983095c54052ba/checksum-40dcaffc3a2cdc8968a18f61672dab63?AWSAccessKeyId=49472f43a12b78c05ea083a9e82ac20de4ca4463&Expires=1455655515&Signature=ftp5IYQKkyvjyXYPG%2BlPltfh/18%3D – hostname “wapj-virtualbox” does not match the server certificate
node1 [2016-02-16T21:45:40+09:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
[/code]

에러는 인증서가 매치가 안된다는 말인데, 자가 인증서이기 때문에 안되는 문제이다.

/etc/chef/client.rbssl_verify_mode :verify_none을 또 추가해주자.

아래와 같은 형태로 client.rb가 되어 있으면 된다.

[code lang=text]
### node1 서버 client.rb
log_location STDOUT
chef_server_url “https://chef-server/organizations/company”
validation_client_name “company-validator”
node_name “node1”
trusted_certs_dir “/etc/chef/trusted_certs”
ssl_verify_mode :verify_none
[/code]

다시 실행해보자

[code lang=text]
$ knife ssh “fqdn:*” “sudo chef-client”
[/code]

아래와 같이 실행된다.

[code lang=text]
node1
node1 Starting Chef Client, version 12.7.2
node1 resolving cookbooks for run list: [“hello”]
node1 Synchronizing Cookbooks:
node1 – hello (0.1.0)
node1 Compiling Cookbooks…
node1 Converging 1 resources
node1 Recipe: hello::default
node1 * log[Hello Chef!] action write
node1
node1
node1 Running handlers:
node1 Running handlers complete
node1 Chef Client finished, 1/1 resources updated in 01 seconds
[/code]

개발PC에서 cookbook을 만들어서 올리고, chef의 API를 사용해서 실행하는 것을 보여주기위해
workstation이라는 것을 예로 들었지만, workstation을 굳이 만들지 않아도 되고, chef serverchef를 설치해서 하는 것이 더 간단한 방법일 수도 있다.
개념을 파악하고 구조를 파악해서, 각자의 환경에 맞게 잘 사용하면 될 것 같다.

좀 길었지만, chef server 설치중에 내가 만난 문제들은 다 정리가 된것 같다.
몇가지 수동으로 했던 부분들을 자동화하게 되면, 훌륭한 인프라 툴이 될 것이다.

TIPS

여기서 부터는 꼭 안봐도 되고, 약간씩 도움이 되는 팁을 정리하려고 한다.
알면 좋고 모르면, 그냥 손이 수고하면 되는(?) 그런 부분이다. 귀찮으면 과감히 패스~

knife.rb 설정에 변수 사용하기

팁이라고 하기도 뭐한 팁인데,
쉐프의 소스가 git 같은 소스 관리 프로그램으로 관리되는 경우,
키의 경로를 절대 경로로 잡아주게 되면,
다른 pc나 인스턴스에서 쉐프 소스를 받게 되면, 매번 수정해야 하는 번거로움이 생긴다.
이 때에 각 키의 경로를 그냥 knife.rb와 같은 경로로 변수를 사용하는 팁이 되시겠다.

knife.rb 파일은 말 그대로 루비 스크립트 이므로 루비의 문법을 사용하면 되는데,
File.dirname(__FILE__) 이라는 녀석이랑 erb의 문법을 사용할 것이다.

[code lang=text]
### knife.rb
urrent_dir = File.dirname(__FILE__)
log_level :info
log_location STDOUT
node_name “company”
client_key “#{current_dir}/admin.pem”
validation_client_name “company-validator”
validation_key “#{current_dir}/gyus-validator.pem”
chef_server_url “https://deploy.gyus.me/organizations/gyus”
syntax_check_cache_path “#{current_dir}/syntax_check_cache”
ssl_verify_mode :verify_mode
[/code]

위의 파일에서 중요한 것은 홑따옴표 ' 가 아니라 쌍따옴표 "를 써야 변수를 루비가 인식하고 변환해준다는 점이다.

업데이트 (2016.10.21)

자가 인증서가 아닌 comodo등의 기관에서 발급받은 인증서를 적용하고 싶은경우.

/var/opt/opscode/nginx/ca 아래에 있는 chef-server.crt, chef-server.key 를 자신이 가지고 있는 인증서로 바꿔치기 하면된다.

파일명을 같게한다음(확장자는 맞춰줘야함) 덮어쓰자.

그 후 설정을 변경하기위해 sudo chef-server-ctl reconfigure 를 실행하고 sudo chef-server-ctl restart를 실행해주자.

이렇게 하면 끝난다. 파일명을 다르게 적용하고 싶다면, /var/opt/opscode/nginx/etc/chef_https_lb.conf 안에 있는 설정을 변경해야한다.

아래와 같은 설정이 있는데, 파일명도 바꿔주면 된다.

[code lang=text]
ssl_certificate /var/opt/opscode/nginx/ca/chef-server.crt;
ssl_certificate_key /var/opt/opscode/nginx/ca/chef-server.key;
[/code]

어려울 줄 알았는데, 생각보다 너무 쉬웠음.

Role – 노드를 역활별로 그루핑 해서 관리하고 싶을 때

Node Object

chef solo로 관리하는 서버가 늘면, Node Object를 정의하는 JSON파일 수가 서버수만큼 늘게 되는데, Node Object에 정의한 run_list에 실행할 레시피를 일일이 JSON파일에 적어주는게 귀찮아진다.

예를 들어 같은 레시피를 적용할 5개의 노드가 있는 경우 새로운 레시피를 추가하고 싶은경우 5번을 복사 붙이기를 하는건 DRY법칙에 어긋나고 귀찮기도 하다. 그래서 run_list와 Attribute를 노드의 역활별로 그루핑 할 수 있는 Role을 사용하면 된다.

Chef solo의 경우 Role은 roles디렉토리의 아래에 Role별로 파일을 만들고, 그안에 Rolo에 필요한 내용을 JSON으로 적는다.

웹서버용 노드의 Role을 rolos/webserver.json으로 작성해보자.

json
{
"name":"webserver",
"default_attributes": {},
"override_attributes": {},
"json_class":"Chef::Role",
"description":"",
"chef_type":"role",
"run_list":[
"recipe[yum::epel]",
"recipe[nginx]",
"recipe[sysstat]"
]
}

배포하려는 서버의 Node Object에는 아래와 같이 적으면 됨

json
{
"run_list":[
"role[webserver]"
]
}

여러개 섞어서 적는것도 가능

“`json
{
“run_list”:[
“recipe[nginx]”,
“role[webserver]”,
“role[db]”
]

}
“`

Role에 어트리뷰트를 정의하는 것도 가능

json
default_attributes "apache2" => {
"listen_ports" => ["80", "443"]
}

chef정리

chef 정리

knife가지고 놀기

cookbook 만들기

shell
$ knife cookbook craete [쿡북이름] -o [디렉토리명]
$ knife cookbook craete hello -o site-cookbooks

knife solo

knife-solo의 설치

knife-solo는 rubygem이므로 아래의 커맨드로 설치가능
shell
$ gem install knife-solo

설치하는 것 만으로도 knife커맨드에 chef-solo를 위한 커맨드가 추가 됨.

knife solo를 파라메터 없이 실행해 보면 사용가능한 커맨드의 리스트가 출력 됨.

knife-solo의 문서

https://github.com/matschaffer/knife-solo/blob/master/README.rdoc

레시피 전송 & 실행 knife solo cook

shell
$ knife solo cook 유저@호스트명

cook 커맨드는 키친(리포지토리)를 대상 서버에 업로드하고, chef-solo를 실행시킨다.

knife-solo를 이용한 chef-solo 실행환경 준비

shell
$ knife solo prepare 유저@호스트
$ knife solo prepare -p 포트 유저@호스트

리포지토리 작성

shell
$ knife solo init 리포지토리 명

디렉토리 구성은 아래와 같다.

├── .chef
│ └── knife.rb
├── cookbooks #다운로드한 쿡북을 저장
├── data_bags #노드간에 공유할 수 있는 변수 저장
├── nodes #노드별로 JSON파일을 저장
├── roles
└── site-cookbooks #자신이 만든 쿡북을 저장

prepare + cook = bootstrap

shell
knife solo bootstrap 유저@호스트

knife solo prepare 를 호출하고 나서 knife solo cook을 호출.

clean

shell
$ knife solo clean 유저@호스트

대상 호스트에 있는 키친(레포지토리)을 완전히 삭제

Chef의 테스트 환경을 만드는데 매우 적합한 툴 – Vagrant

Vagrant : 가상머신을 간단히 만들고, 부수고 할 수 있는 VirtualBox의 프론트 엔드툴.

Chef Solo로 만든 레시피를 실험해보기엔 최적이다.

공식 사이트

http://www.vagrantup.com/

문서

  • 당연한 말이지만, 문서에 읽어볼 만한게 많다. 기본적인건 아래의 글을 참고하고, 좀 더 추가적인 기능들은 문서를 참고하길!

http://docs.vagrantup.com/v2/

Vagrant 도입하기

http://downloads.vagrantup.com/ 에서 다운 받을 수 있는데, 나는
http://downloads.vagrantup.com/tags/v1.2.7 에서 Mac용 dmg파일을 받아서 설치했다. 설치는 매우 쉬우니 생략.

가상서버 올리기

서버 올리는거는 커맨드라인에서 vagrant명령어를 실행하는 걸로 됨. 처음에는 Vagrant Box라는 OS 이미지를 다운로드 해야함.

http://www.vagrantbox.es 에 Vagrant용 OS이미지가 종류별로 공개되어 있음.

vagrant box add {title} {url}

요거 실행하면, ~/.vagrant.d/boxes라는 디렉토리아래에 {title}이라는 디렉토리가 생기고,
그 아래에 virtualbox라는 폴더 아래에 버추얼 머신 관련 파일이 다 들어 있음.

을 실행하는 것으로 가능.

적당한 디렉토리를 만들고 거기에 들어간다음

$ vagrant init {title}

을 실행하면 해당 디렉토리 내에 Vagrantfile이라는 ruby로 된 설정파일이 만들어진다.

그리고 나서 기동

$ vagrant up

실제로 내가 테스트해본 커맨드는 아래와 같다.

$ vagrant box add ubuntu http://dl.dropbox.com/u/1537815/precise64.box
(실행후 이미지 다운받느라 시간 좀 걸림)
$ mkdir virtualEnv
$ cd virtualEnv
$ vagrant init ubuntu
$ vagrant up

ssh로 로그인 하려면(1)

$ vagrant ssh

와 같은 명령어를 실행해 주면 된다.

vagrant ssh말고 ssh 커맨드로 가상머신에 들어가고 싶을 때에는 Vagrantfile의 네트워크 설정을 조금 수정해야한다.

아래와 같은 코드가 주석 처리 되어 있는데, 주석을 풀어주면 된다.
config.vm.network :private_network, ip: "192.168.33.10"

그러면 ssh로도 들어갈 수는 있지만, 암호를 물어보는데, 이렇게 말고 Vagrant의 비밀키를 디폴트로 사용하게끔 설정 가능하다.

ssh로 로그인 하려면(2)

$ vagrant ssh-config --host [호스트 명]
이렇게 하면, 가상머신 서버에 관한 ssh설정이 나오는데,

$ vagrant ssh-config --host [호스트 명] >> ~/.ssh/config
이렇게 해두면

$ ssh [호스트 명]
으로 접속 가능하다.

※ ssh 커맨드는 knife-solo같은 툴에서 기본적으로 사용하니 ssh로 로그인 할 수 있게 해두는게 좋다.

정지 / 부수기

$ vagrant halt #정지
$ vagrant destory #부수기

일단 이렇게 해서 한번 설정을 해두면, 2번째 부터는 VagrantFile이 있는 디렉토리에 들어가서 vagrant up만 해주면 된다.

다른 가상 머신을 만들어 보려면

  1. 임의로 폴더를 만들고
  2. vagrant init를 실행하고
  3. Vagrantfile의 네트워크 설정을 변경해주고
  4. vagrant up
  5. vagrant ssh-config --host [별칭] >> ~/.ssh/config 로 ssh설정해주기
  6. vagrant sshssh [별칭]으로 게스트OS에 접속 가능.

$ mkdir sandbox
$ cd sandbox
$ vagrant init
$ vi Vagrantfile #네트워크 쪽 설정 수정하기.
$ vagrant up
$ vagrant ssh-config --host box >> ~/.ssh/config