구리의 창고

AWS Opsworks Chef11 - Custom Cookbook Debugging 본문

AWS

AWS Opsworks Chef11 - Custom Cookbook Debugging

구리z 2017. 9. 2. 00:09

소개

 AWS Opsworks(이하 Opsworks)의 많은 부분을 이미 안다고 가정하고 설명 할 것이다. Opsworks는 2017년 9월 1일 기준으로 Chef11과 Chef12가 함께 운영되고 있다. 두 버전 모두 Custom Cookbook을 사용 할 수 있다. Custom Cookbook을 작성하다보면 실제 Opsworks에서 생성한 Instance에서 테스트 및 디버깅을 해보고 싶은 욕구가 많이 생기는데 생각처럼 쉽지가 않다. 기본적으로 Ospworks는 opsworks-agent-cli가 내부적으로 설정 값을 읽어 chef-client를 실행하는 구조로 되어있다. Chef11과 Chef12는 그 구조가 다르므로 이 글에서는 Chef11 Custom Cookbook 디버깅 방법을 설명한다.

opsworks-agent-cli

 Opsworks가 내부적으로 사용하는 프로그램이다. 이 녀석으로 마지막으로 실행된 명령어, node attribute등을 알아 낼 수 있다. 자세한 문서는 여기를 참조하고 디버깅에 필요한 명령어만 몇 개 설명한다.

  • run_command: 인스턴스가 마지막으로 실행한 command를 다시 실행한다.
  • get_json: 인스턴스가 마지막으로 실행한 node attribute를 출력한다.
보통 디버깅을 하게되는 경우는 작성한 Cookbook이 실패한 경우이다. 위 두 명령어를 통해 마지막으로 실행한 환경과 명령어를 알아낸다.

run_command

Opsworks Chef11은 기본적으로 두 번 chef-client를 실행한다. opsworks-agent-cli를 통해 run_command를 실행해보면 두 번 chef-client가 실행되는 것을 볼 수 있다. 첫 번째 실행은 Custom cookbook을 받아와 Merge해주는 과정이고, 두 번째 실행하는 부분이 각 Layer에서 설정한 Lifecycle에 맞는 Cookbook이 실행된다. 이 내용은 아래와 같이 로그를 보면 확인 할 수 있다.
[Fri 01 Sep 2017 02:42:49 PM UTC] About to execute: RUBYOPT="-E utf-8" /opt/aws/opsworks/current/bin/chef-client -j /var/lib/aws/opsworks/chef/2017-09-01-14-42-49-01.json -c /var/lib/aws/opsworks/client.stage1.rb -o opsworks_custom_cookbooks::load,opsworks_custom_cookbooks::execute 2>&1
[Fri 01 Sep 2017 02:43:02 PM UTC] About to execute: RUBYOPT="-E utf-8" /opt/aws/opsworks/current/bin/chef-client -j /var/lib/aws/opsworks/chef/2017-09-01-14-42-49-01.json -c /var/lib/aws/opsworks/client.stage2.rb -o opsworks_initial_setup,ssh_host_keys,ssh_users,mysql::client,dependencies,ebs,opsworks_ganglia::client,opsworks_stack_state_sync,opsworks_cloudwatchlogs,deploy::default,test_suite,opsworks_cleanup 2>&1
opswork-agent-cli가 실행해주는 위 명령줄을 이용해서 run_list만 변경해 특정 Cookbook을 수동으로 실행시키고 디버깅 할 수 있다.

Cookbook 경로 찾기

Opsworks에서 어떤 파일을 사용하고 있는지 알아야 어디서 Cookbook을 수정하고 실행 할지 알 수 있다. 

1. /var/lib/aws/opsworks

대부분의 실행에 필요한 정보가 담겨져있는 폴더이다. 내부를 살짝 살펴보면 client.stage1, client.stage2로 나눠진 루비파일과 폴더를 볼 수 있다. 이는 각각 위에서 말한 두 번 chef-client를 실행하면서 사용되는 chef-client 설정 파일들이다. 실제로 위에 있는 명령줄을 자세히보면 config 파일로 각 client.stage*.rb 파일을 넘기는 것을 볼 수 있다.

2. /var/lib/aws/client.stage2.rb

# encoding: UTF-8
Ohai::Config[:plugin_path] << "/opt/aws/opsworks/current/plugins"

local_mode true
cookbook_path ["/opt/aws/opsworks/current/merged-cookbooks"]
file_cache_path "/var/lib/aws/opsworks/cache.stage2"
node_path "/var/lib/aws/opsworks/data/nodes"
data_bag_path "/var/lib/aws/opsworks/data/data_bags"
log_level :info

%w{BUNDLE_GEMFILE GEM_HOME GEM_PATH RUBYLIB RUBYOPT}.each do |env|
  ENV[env] = nil
end

ENV['PATH'] = "/usr/local/bin:/usr/local/sbin:#{ENV['PATH']}"

File.umask 022
실제 우리가 설정한 run_list를 갖고 실행되는 두 번째 설정파일로 중요하다. 이 설정 파일을 살펴보면 어느 경로로 찾아가 Cookbook을 수정하고 수동 실행해야 하는지 알 수 있다. 그 경로가 cookbook_path에 적혀있다. 

3. /opt/aws/opsworks/current/merged-cookbooks

드디어 어느 경로에 있는 Cookbook이 실행되는지 찾아냈다. 이 경로를 따라 들어가면 Custom cookbook으로 올렸던 녀석이 보이고 원하는 Cookbook을 직접 수정 할 수 있다. 이 Cookbook은 client.stage1.rb로 인해 cookbooks와 site-cookbooks가 합쳐진 결과물이다. 그러므로 opswork-agent-cli가 실행되면 merged-cookbooks에서 작업하던 변경내역을 언제든 잃어 버릴 수 있다.

수동실행

원하는 Cookbook을 수정했으면 run_command로 얻은 정보에 아래 처럼 client.stage2 명령어에서 run_list만 수정하여 실행해보자. 내가 아는 방법 중, Opsworks Instance에서 chef-client를 가장 빠르게 실행하고 결과물을 볼 수 있는 방법이다.
RUBYOPT="-E utf-8" /opt/aws/opsworks/current/bin/chef-client -j /var/lib/aws/opsworks/chef/2017-09-01-14-42-49-01.json -c /var/lib/aws/opsworks/client.stage2.rb -o my_cookbook::default


Comments