詳細検索

셰프-솔로 레시피 커스터마이징 기록

아바타
글쓴이 komi

셰프-솔로 레시피 커스터마이징 기록
日本語에서 번역 • 원문 보기

안녕하세요. 코미야입니다.
덕분에 커스터마이즈할 기회를 가졌고, 몇 가지 인용을 하고 소개하고자 합니다.

기본적인 것들 등,
아래 링크와 "Introductory chef-sol"그 방울들도 꼭 확인해 보시길 권합니다.
셰프 솔로와 나이프 솔로와 함께 니코 니코 서버 구축 (2) - 소개 - :d 완고 엔지니어 브로마가
셰프-솔로 - 읽고 운영할 모든 지식 셰프 - 키이타
DevOps를 위한 셰프 기법 // 스피커 덱
또한, Engine Yard(이 회사는 Chef가 나오기 약 8년 전부터 이 책을 사용해온 회사)에서 GW에서 셰프 실습에 관한 입문서가 출간된다는 소식을 듣는 것이 매우 기대됩니다.

이것은 Chef의 노드, 역할, 환경, 속성, 데이터_bags에 대한 설명입니다.
이 글은 기본적인 설명과 간단한 맞춤화 정보를 제공할 것이라고 생각합니다.
아래에 설명된 레시피를 실제로 사용한 유일한 환경은 CentOS 6.4이며, 안타깝게도 다른 환경에서 작동할지 보장할 수는 없습니다.
서로 다른 운영체제 간 작동을 보장하는 범용(복잡한) 레시피는 opscode 커뮤니티의 ** 요리책에서 활용될 수 있는 것 같습니다.
(불필요한 것을 최대한 적게 추가하거나 기존 환경이나 절차에 맞는 레시피를 만드는 것은 수요에 적합하지 않다고 생각합니다.) )

다음은 chef 저장소 바로 아래에 있는 디렉터리에 대한 설명입니다.
요리책: 서드파티 요리책 보관
Data_bags :d ata_bags data storage
환경 : 환경설정 파일 저장
노드: 노드(호스트/서버) 구성 파일 저장
역할: 역할 구성 파일 저장
사이트-쿡북: 자신의 요리책을 보관할 수 있는 공간입니다(요리책에는 레시피, 유인물 등이 포함됩니다).

각 용어는 아래에서 간략히 설명되어 있습니다.
・오하이
이 명령어는 chef에 포함된 레시피를 적용하는 호스트의 정보를 가져옵니다.
오하이가 얻은 값을 기반으로 속성을 정의할 수 있습니다.
예를 들어, 설치된 OS의 메모리, CPU 코어 수, 또는 호스트명에 따라 설정 값을 변경하고 싶을 때,
IP 주소와 같은 고유한 정보를 설정 파일에 넣고 싶을 때 유용합니다.

・노드
nodes 디렉터리를 지정하고, hostname.json 또는 ipaddress.json이라는 파일을 바로 아래에 배치합니다.
서버별 속성과 할당할 역할을 정의하세요.

・역할
DB와 웹 같은 같은 역할을 가진 서버를 하나의 역할로 결합하고, 같은 역할을 가진 여러 서버에 적용하는 레시피입니다.
그리고 매개변수들이 함께 합쳐집니다.

・주변
테스트 환경, 운영 환경, 개발 환경 등 각 환경에서 변경해야 할 아트트리뷰어를 정의하세요.
(요리책 버전은 Chef-Server에서 수정할 수 있지만, Chef-Solo에서는 안 되는 것 같습니다)

·속성
이 매개변수는 각 노드, 역할, 환경별로 변경해야 할 매개변수입니다.
템플릿 리소스에서 호출하는 파일에 <%= %>와 같은 변수를 정의하세요.
각 역할별로 설정 파일의 값을 변경하고 싶을 때 사용됩니다.
각 요리책의 attributes/default.rb에서 기본값을 정의할 수도 있고,
템플릿 리소스의 변수로 설정할 수도 있습니다. 오하이 값도 그대로 설정할 수 있습니다.

・데이터_bags
요리책에는 포함하고 싶지 않은 글로벌 데이터가 포함되어 있습니다.
여기에는 사용자 정보도 포함됩니다.
역할마다 변하는 속성 같은 데이터가 아니라, 한 곳에만 작성합니다.
로드하고 싶은 데이터를 넣기에 좋은 장소인 것 같습니다.

・레시피 적용법
호스트에게 레시피를 적용하고 싶다면, 호스트 뒤에 있는 나이프 명령어에서 레시피를 지정할 수 있습니다.
노드나 역할의 실행/_list에서 레시피나 역할을 명시해야 합니다.

역할이나 노드를 설정하지 않고 직접 칼 명령어에 인수로 부여하는 방법:
나이프 솔로 쿡 -o <요리책>::<레시피>【,<요리책>::<레시피>】
*이 방법은 해당 저장소에서 어떤 레시피가 어떤 호스트에 적용되었는지 관리할 수 없습니다.
추천하지는 않지만, 이미 실행 중인 환경에 영향을 주고 싶지 않다면 사용할 수 있을 것 같습니다.

노드에서 실행_list 지정하는 예시:
[셸]비

/nodes/localhost.json ---------------- "run_list":[ "recipe[base_setting::common-pkgs]", "recipe[base_setting::sysctl]", "role[API-ext]" ] ----------------[/shell]

 

실행할 역할 지정의 예시_list: [shell]$ vi roles/API-ext.json ---------------- { "name":"API-ext", "chef_type": "role", "json_class":"Chef::Role", "default_attributes":{ "base_setting": { "swappiness": "0", "tcp_tw_reuse": "0", "tcp_tw_recycle": "0", "tcp_fin_timeout": "10", "tcp_max_syn_backlog": "8192", "somaxconn": "8192" } }, "override_attributes": {}, "description":"API 역할", "run_list": [ "recipe[roles::API-ext]" ] } ---------------- $ cat 사이트-쿡북/롤스/레시피/API-ext.rb ---------------- 포함_recipe "base_setting:::common-pkgs" include_recipe "base_setting::sysctl" include_recipe "base_setting::ntpd" include_recipe "base_setting::rps_cpus" include_recipe "login-users::create_user" include_recipe "login-users::key_copy" include_recipe "login-users::" include\ "login-users:: :" api_user" include_recipe "java::java" include_recipe "nginx::nginx" include_recipe "nginx::nginx_virtual" include_recipe "play::p lay" include_recipe "mysqld::mysql-client" include_recipe "git:git" include_recipe "Flydata::Flydata" include_recipe "munin::munin-node" include_recipe "munin::munin-node-API-PVP-robi" include_recipe "zabbix::zabbix-agent" ----------------[/shell] *위 섹션에서는 역할 쿡북에 필요한 API-ext.rb 레시피가 포함되어 있지만 레시피는 파일 파일에 나열되지 않습니다.
*node와 role의 JSON 파일 run_list에서는 쉼표 구분으로 recipe와 role을 작성할 수 있습니다.
[[일본어 번역] 초급 셰프 안티패턴 줄리안 던 #opschef_ja] (http://www.creationline.com/lab/3080)
이제는 요리책에서 역할을 관리하는 것이 권장됩니다.
역할, 노드 설정이 제대로 되어 있고, 호스트명을 요리책이나 레시피를 -o로 지정하지 않아도 가능합니다.
Knife Solo Cook을 실행하면 설정하는 대로 레시피가 적용됩니다.

레시피 적용 순서는 기본적으로 지정되어 있지만, Notifys에서 지정된 서비스 재시작은 다음과 같습니다.
모든 레시피가 적용(수렴)된 후에. 이해하기 쉬운 다음 내용을 참고해 주세요.
셰프 레시피가 처음부터 끝까지 이루어진다는 오해

‧시험 방법에 대하여
나중에 덧붙일 수 있겠지만, 요리책의 문법은 다음 명령어로 확인할 수 있습니다:
[셸]칼 요리책 테스트

Serverspec은 [/shell] 레시피를 적용한 후 실제 환경을 테스트하는 좋은 방법이라고 생각합니다.

 

·속성과 데이터의 사용 사례 및 구현 절차_bags
예시를 나열하겠지만, 아래 링크도 참고해 주세요.
[chef] 속성 이해하기 | IT 인프라 잡다한 노트북

・오하이 데이터를 사용해 OS 메모리와 CPU 코어 수에 따라 설정하세요.
ohai를 사용할 때는 레시피에서 템플릿 리소스를 정의하고 구성 파일에서 변수만 정의하면 됩니다.
역할이나 노드 속성을 정의할 필요는 없습니다.
오하이 명령어를 직접 입력하면 어떤 값이 나올지 알 수 있습니다.
[shell]$ 오하이 IP 주소 [ "192.168.1.133" ][/shell]

OS 온보드 메모리의 75%를 innodb_buffer_pool_size [shell]$ vi site-cookbooks/mysqld/recipes/mysqld-server.rb 템플릿 '/etc/my.cnf' do owner 'root' 그룹 'root' 소스 'etc/my.cnf.erb' 알림 :restart, 'service[mysql]' end $ vi site-cookbooks/mysqld/templates/default/etc/my.cnf.erb innodb_buffer_pool_size = <%= ("#{node[:memory][:total]}"[/\d+/].to_f * 1024 * 0.75 ).to_i %>[/shell]

운영체제에 설치된 CPU 코어 수에 해당하는 값을 worker_processes로 설정하세요. [shell]$ vi site-cookbooks/nginx/recipes/nginx.rb template "nginx.conf" do path "etc/nginx/nginx.conf" 소스 "etc/nginx/nginx.conf.erb" 소유자 "root" 그룹 "root" 모드 0644 알림 :reload, 'service[nginx]' end $ vi site-cookbooks/nginx/templates/default/etc/nginx/nginx.conf.erb worker_processes <%= node[:cpu][:total] %>;[/shell]

・ohai 데이터를 이용해 호스트명과 IP 주소 설정 [shell]$ vi site-cookbooks/zabbix/recipes/zabbix-agent.rb 템플릿 '/etc/zabbix/zabbix_agentd.conf' do owner 'root' 그룹 'root' 소스 'etc/zabbix/zabbix_agentd.conf' 끝

$ vi site-cookbooks/zabbix/templates/default/etc/zabbix/zabbix_agentd.conf Hostname=<%= node['hostname'] %> $ cat site-cookbooks/mysqld/templates/default/etc/my.cnf.erb|grep IP주소 server-ID = <%= node[:ipaddress].split("."). 마지막 %> report-host = <%= node[:ipaddress] %>[/shell]

각 노드마다 자동으로 다른 값을 설정할 수 있기 때문에,
로그인 후 미리 준비하거나 수정할 필요가 없고 하나씩 다시 불러올 필요가 없어서 매우 편리하다고 생각합니다.

  • 템플릿 리소스 내 각 역할에 대해 서로 다른 속성을 호출하여 구성 파일에 반영합니다.
    기본 요리책에 있는 sysctl 레시피_setting 그렇습니다.

[shell]$ cat site-cookbooks/base_setting/recipes/sysctl.rb template "/etc/sysctl.conf" do owner 'root' group 'root' source 'etc/sysctl.conf.erb' mode 0644 end $ cat site-cookbooks/base_setting/templates/default/etc/sysctl.conf.erb vm.swappiness = <%= node['base_setting']['swappiness'] %> net.ipv4.tcp_tw_reuse = <%= node['base_setting']['tcp_tw_reuse'] %> net.ipv4.tcp_tw_recycle = <%= node['base_setting']['tcp_tw_recycle'] %> net.ipv4.tcp_fin_timeout = <%= node['base_setting']['tcp_fin_timeout'] %> net.ipv4.tcp_max_syn_backlog = <%= node['base_setting']['tcp_max_syn_backlog'] %> net.core.somaxconn = <%= node['base_setting']['somaxconn'] %> $ cat roles/db.json ~略~ "base_setting": { "swappiness": "0", "tcp_tw_reuse": "1", #バックエンドのdbはtcp接続をリサイクルする "tcp_tw_recycle": "1", #バックエンドのdbはtcp接続をリサイクルする "tcp_fin_timeout": "10", "tcp_max_syn_backlog": "8192", "somaxconn": "8192", "ntpserver1": "ntp.nict.jp" } ~略~ $ cat roles/API.json ~略~ "base_setting": { "swappiness": "0", "tcp_tw_reuse": "0", #フロントエンドのAPIはtcp接続をリサイクルしない "tcp_tw_recycle": "0", #フロントエンドのAPIはtcp接続をリサイクルしない "tcp_fin_timeout": "10", "tcp_max_syn_backlog": "8192", "somaxconn": "8192", "ntpserver1": "ntp.nict.jp" } ~略~[/shell] ※role毎に変えてる意味合い的にはスマホからwifi接続の接続元IPが同じになってる
여러 터미널이 동시에 접속할 경우, TCP 연결을 재활용하면 한 패킷이
버려진 IP이기 때문에 다른 IP에서 연결된 백엔드에서 재활용되어야 합니다
이는 이를 활성화하고 부하를 줄이는 것입니다.

MHA 매니저의 경우, 매니저를 위해 RPM을 도입하고, 그렇지 않으면 도입하지 않는 식으로 합니다.
[shell]$ cat site-cookbooks/mysqld/recipes/mysql-mha.rb if node[:mysqld][:mha] == 'manager' %W{perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Params-Validate perl-Time-HiRes}.each do |pkg| 패키지 PKG 하지 않음_if "RPM -QA|grep #{pkg}" 작업 :설치 종료 끝_file "/usr/local/src/#{mhamanager}" 하지 마세요_if "ls /usr/local/src/#{mhamanager}" 출처 "usr/local/src/#{mhamanager}" 끝 생략 끝 $ CAT 역할/mhamanager.json 생략 "default_attributes":{ "mysqld": { "mha":"manager" }, 생략[/shell]

  • 각 노드마다 리소스를 실행하는 if를 사용하여 다른 속성을 호출합니다.
    여기에는 구성 파일의 내용 변경과 크론 등록 여부가 포함됩니다.

DB 마스터로 전환해야 하는 슬레이브는 설정 파일에서 read_only을 활성화하지 않습니다.
스위칭을 하지 않는 두 번째 슬레이브는 읽기 기능을 활성화합니다_only
[shell]$ cat site-cookbooks/mysqld/recipes/mysqld-server.. rb 생략 만약 node[:mysqld][:MHA_nomaster] == 'true' 템플릿 '/etc/my.cnf' do owner 'root' 그룹 'root' 소스 'etc/my.cnf_ro.erb'가 :restart, 'service[mysql]' end else 템플릿 '/etc/my.cnf' do owner 'root' 그룹 'root' 소스 'etc/my.cnf.erb'가 알림 :restart, 'service[mysql]' 종료 생략 $ cat nodes/db3.hoge.jp.json { "mysqld" : { "master" : "false", "only_mysql" : "true", "only_innodb":"true", "mha_nomaster" : "true" }, 생략[/shell]

슬레이브에서만 등록하고 실행할 수 있는 cron 리소스
[shell]생략 만약 node[:mysqld][:master] == 'false' cron "mysql_replication_check" 하지 않아요_if "crontab -l|grep rep_fail_mail.sh" 분 "0-59/15" 시간 "*" 일 "*" 월 "*" 평일 "*" 명령어 "/opt/bin/rep_fail_mail.sh > /dev/null 2>&1" action :create end 생략 $ cat nodes/db1.hoge.jp.json { "mysqld" : { "master" : "true", 생략 $ cat nodes/db2.hoge.jp.json { "mysqld" : { "master" : "false", 생략[/shell]

  • 각 환경별로 if를 가진 다른 구성 파일을 호출하여 자원을 실행합니다.
    API의 nginx 구성 파일을 배포하는 데 사용됩니다. [shell]$ cat site-cookbooks/nginx/recipes/nginx_virtual.rb if node[:environment] == 'huka' 템플릿 "/etc/nginx/conf.d/virtual.conf" do source "etc/nginx/conf.d/huka/virtual.conf.erb" 소유자 "root" 그룹 "root" 모드 0644가 알림 : reload, 'service[nginx]' end elsif node[:environment] == 'prd' 템플릿 "/etc/nginx/conf.d/virtual.conf" do source "etc/nginx/conf.d/prd/virtual.conf.erb" 소유자 "root" 그룹 "root" 모드 0644 알림 :reload, 'service[nginx]' end elsif node[:environment] == 'stg' 템플릿 "/etc/nginx/conf.d/virtual.conf" do source "etc/nginx/conf.d/stg/virtual.conf.erb" 소유자 "root" 그룹 "root" 모드 0644 알림 :reload, 'service[nginx]' 종료[/shell] 같은 구성 파일로 내용 URL 같은 속성 값을 바꾸는 것이 일반적인 것 같은데, 이는 제가 미리 매개변수를 알지 못하기 때문입니다.
    참고: 셰프 솔로의 환경 - 나오야의 하테나 일기

data_bags에서 버전 데이터를 불러오고 패키지 이름을 정의하세요
저는 대부분의 요리책에서 이 제품을 사용합니다.
[shell]$ cat site-cookbooks/nginx/recipes/nginx.rb 버전 = data_bag_item('pkg_versions','nginx')['version'] nginx_pkg="nginx-#{version}.ngx.x86_64.rpm" 생략

$ 나이프 솔로 데이터 가방 생성 pkg_versions nginx $ 나이프 솔로 데이터 가방 편집 pkg_versions nginx $ 나이프 솔로 데이터 가방 표시 PKG_versions nginx ID: nginx 버전: 1.4.4-1.el6[/shell]

·데이터_bags에서 사용자 데이터를 불러오고 사용자 생성
로그인_users 요리책 만들기_user 레시피 [shell]$ cat 사이트-cookbooks/로그인-users/recipes/create_user.rb 데이터_ids = 데이터_bag('사용자') 데이터_ids.각각은 |id| u = 데이터_bag_item('사용자', ID) 이름 = u[''사용자 이름'] 사용자 u['username'] 하지 마세요_if "ID #{name}" 홈 u['home'] shell u['shell'] uid u['uid'] gid u['gid'] 비밀번호 u[''password'] 끝[/shell]

mysqld 요리책의 mysqld-server 레시피에서 암호화된 데이터를 불러오고 사용하는 레시피입니다.
[shell]$ cat site-cookbooks/mysqld/recipes/mysqld-server.rb 생략 ## 데이터를 로드_bag. root = Chef::EncryptedDataBagItem.load("mysqlusers","root") repl = Chef::EncryptedDataBagItem.load("mysqlusers","repl") suuser = root["user"] supass = root["pass"] repluser = repl["user"] replpass = repl["pass"] ### 보안 설치 등. mysqlconn = "/usr/bin/mysql -u root" if #{version} == '5.6' 패키지 'expect' do :install not_if "rpm -qa|grep expect" 엔드 템플릿 "/tmp/setpass.sh" do only_if 'ls /root/.. mysql_secret' 소스 "setpass.sh" end bash "set_password" do only_if "ls /root/.mysql_secret" 코드 <<-EOC chmod +x /tmp/setpass.sh & & /tmp/setpass.sh && rm -f /tmp/setpass.sh EOC end end bash "secure_installation" do ignore_failure true only_if "#{mysqlconn} -e 'show databases;'" 코드 <<-EOC #{mysqlconn} << EOF on *.* 모든 부여 대상은 #{suuser}@'%'로 식별됨; *.* 위의 모든 것을 "#{supass}"로 식별하는 #{suuser}@'localhost'에게 부여; "#{supass}"로 식별되는 *.* 모든 것을 #{suuser}@'::1'에게 부여; *.* 에 있는 모든 것을 #{suuser}@'127.0.0.1' "#{supass}"로 식별하는 사람에게 부여; 복제 슬레이브, 복제 클라이언트를 #{repluser}@'%'로 식별하는 "#{replpass}"에게 부여; 데이터베이스 테스트 삭제; mysql.user에서 password='' 삭제; 플러시 권한; EOF EOC end pfile="/root/.my.". CNF" bash "create-pfile" do not_if "ls #{pfile}" 코드 <<-EOC 에코 '[mysqladmin]' >> #{pfile} 에코 "user= #{suuser}" >> #{pfile} 에코 "비밀번호 = #{SUPASS}" >> #{pfile} 에코 "" >> #{pfile} 에코 '[mysql]' >> #{pfile} 에코 "user= #{suuser}" >> #{pfile} 에코 "비밀번호 = #{supass}" >> #{pfile} chmod 400 #{pfile} 에코 "#{supass}" >> /root/.. rootmysql_pwd chmod 400 /root/.mysql_pwd EOC end 약어[/shell] 5.6 시리즈 초기 비밀번호를 expect with bash로 재설정하고, mysql에 연결한 후 부여하세요.
불필요한 항목은 삭제되고 비밀번호 파일은 다른 스크립트에 의해 생성됩니다.
저는 chef - qiita를 참조로 mysql을 사용해 만들 었습니다.
*암호화 키는 데이터를 _bag생성하고 .chef/knife.rb _key _bag_path 파일을 chef 저장소 바로 아래에 설정해야 합니다.
데이터를 생성_bag_key
[shell]$ openssl rand -base64 512 |tr -d '\r\n' > ~/.chef/encrypted_data_bag_secret $ chmod 400 ~/.chef/encrypted_data_bag_secret $ vi .chef/knife.rb[/shell]
- data_bags에서 배열 데이터를 로드하여 여러 행에 반영
이는 기본_bags 쿡북의 NTPD 레시피 템플릿 리소스에서 데이터를 _setting 데이터를 로드하는 것입니다. [shell]$ cat site-cookbooks/base_setting/recipes/ntpd.rb ntpservers = data_bag_item('base_setting','ntpserver')['ntpservers'] 템플릿 "/etc/ntp.conf" do path "/etc/ntp.conf" 소스 "etc/ntp.conf.erb" 소유자 "root" 그룹 "root" 모드 0644 알림 :restart, 'service[ntpd]' 변수({ :ntpservers => ntpservers }) 종료

$ cat site-cookbooks/base_setting/templates/default/etc/ntp.conf.erb driftfile /var/lib/ntp/drift #server -4 <%= node['base_setting']['ntpserver1'] %> iburst <% ntpserver에 @ntpservers % > 서버 -4 <%= ntpserver["server"] %> iburst <% end %>

데이터의 정의_bags $ 나이프 솔로 데이터 가방 베이스 생성_setting ntpserver $ 나이프 솔로 데이터 가방 edit base_setting ntpserver { "id": "ntpserver", "ntpservers": [ { "server" : "ntp.nict.jp" }, { "server" : "ntp.nict.jp" }, { "server" : "ntp.nict.jp" } } } [/shell] 이 세 가지 모두 ntp.nict.jp 이유는 dig가 DNS 라운드로빈에서 여러 서버에 적합하기 때문입니다.

data_bags에서 배열 데이터를 가져오는 방법에 대한 자세한 내용은 이해하기 쉬운 아래 URL을 참고해 주세요.
데이터백 사용의 전체 이야기 (1)

또한, 다음 내용들이 맞춤화에 도움이 될 수 있습니다.
Chef Recipes로 환경 맞춤화 : 개발자 센터
중요한 점이 단순한 지시점이라고 생각하신다면 죄송합니다.

위 글을 오랜 시간 읽어주셔서 감사합니다.

Related Articles