詳細検索

Chef-Solo에서 레시피를 작성하기 전 환경에 대해 (Vagrantfile, role, node, data_bags)

아바타
글쓴이 komi

Chef-Solo에서 레시피를 작성하기 전 환경에 대해 (Vagrantfile, role, node, data_bags)
日本語에서 번역 • 원문 보기

안녕하세요. 코미야입니다.
올해 상반기가 어느새 끝났다. 우지 긴토키는 맛있는 계절이 된 것 같다.
어쨌든, 이것은 이전 글의 연장선입니다. 이번에는 Chef-Solo 레시피를 쓰기 전에 환경의 정의에 대해 먼저 쓰겠습니다.

셰프 용어를 가볍게 설명해 주는 '셰프'를 보는 게 더 빠르고, 아니면 표준 소개용 '셰프 솔로'를 보는 게 더 낫다고 생각해요.
자동화된 인프라도 영어로 되어 있지만 이해하기 쉽습니다.
제가 하고 싶은 일들은 다음과 같습니다.
 가상 인스턴스를 생성하기 위해 vagrantfile을 작성하세요
 chef 저장소를 만드세요
 셰프 요리책을 만들어 보세요
 노드를 정의하세요
 역할 정의
 데이터의 정의_bags
  ★ 이번에는 여기까지★입니다
 레시피를 작성해 보세요
 노드에 레시피를 적용하기
 서버스펙 테스트 작성
 실제 환경에서 테스트를 실행하세요

테스트 구성:
 chef-solo original admserver: 10.0.0.93
 Knife-solo application client webserver: 10.0.0.240
 Knife-solo application client dbserver: 10.0.0.241
 모두 CentOS 5.8입니다.

  • AWS 환경 변수 정의

AWS VPC에 등록되어 있으니 그에 맞게 정의됩니다
[shell]# CD # vi .ec2 export AWS_ACCESS_KEY_ID=*** 내보내기 AWS_SECRET_ACCESS_KEY=***내보내기 AWS_KEYPAIR_NAME=xxx-key 내보내기 AWS_PRIVATE_KEY_PATH=/root/.ssh/xxx-key # 소스 .ec2[/shell]

・부랑자 파일 작성

vagrant init을 실행하면 vagrantfile을 만들 수 있으니 편집하고
VPC에서 가상 인스턴스를 실행하는 설정을 작성하세요.

주석
프로비저닝 설정 (Chef Solo)
  *설정 파일 작성 방식이 Vagrant 1.1과 다를 수 있으니, v2 매뉴얼을 꼭 확인해야 합니다.
셸 스크립트를 실행하는 방법

[shell]# vagrant init # cp -p Vagrantfile{,.org} # vi Vagrantfile ----------------------- Vagrant.configure("2") do |config| # 공통 구성 config.vm.box = "더미"

#---- 여기서 웹 서버를 생성하세요 config.vm.define :web do |web| web.vm.box = "더미" web.vm.provider :aws do |aws| aws.access_key_id = ENV['AWS_ACCESS_KEY_ID'] aws.secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] aws.keypair_name = ENV['AWS_KEYPAIR_NAME'] aws.ssh_private_key_path = ENV['AWS_PRIVATE_KEY_PATH']

#---- VPC 전용 구성 ----# aws.private_ip_address = "10.0.0.240" aws.subnet_id = "subnet-80bxxxx9" aws.security_groups = ["sg-6ebxxxx", "sg-fa81xxxx"] #---- VPC 전용 설정 ----#

aws.ssh_username = "루트" aws.. ssh_private_key_path = "~/.ssh/komi-test.pem" aws.instance_type = "t1.micro" aws.tags = ["xxx-web03"] aws.region = "AP-Northeast-1" aws.ami = "AMI-D7Bxxxx6" 끝 ## 프로비저닝 설정 #web.vm.provision :CHEF_solo Do |chef| # chef.cookbooks_path = ["cookbooks", "site-cookbooks"] # chef.roles_path = "roles" # chef.add_role("웹서버") # chef.data_bags_path = "data_bags" # chef.node_name = "xxx-web03" # chef.log_level = "디버그" #end 끝

#---- 여기서 DB 서버를 생성하세요 config.vm.define :d b do |db| db.vm.provider :aws do |aws| aws.access_key_id = ENV['AWS_ACCESS_KEY_ID'] aws.secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] aws.keypair_name = ENV['AWS_KEYPAIR_NAME'] aws.ssh_username = 'root' #aws.ssh_private_key_path = ENV['AWS_PRIVATE_KEY_PATH']

#---- VPC 전용 설정 ----# aws.private_ip_address = "10.0.0.241" aws.subnet_id = "subnet-80bxxxx9" aws.security_groups = ["SG-6ebdxxxx", "sg-fa81xxxx"] #---- 지금까지 VPC 전용 설정 ----#

aws.ssh_username = "root" aws.ssh_private_key_path = "/.ssh/komi-test.pem" #aws.ssh_private_key_path = "/.ssh/id_dsa" aws.instance_type\ = "t1.micro" aws.tags = ["xxx-db03"] aws.region = "AP-Northeast-1" aws.ami = "ami-d7bxxxx6" end ## 프로비저닝 구성 #db.vm.provision :chef_solo do |chef| # chef.cookbooks_path = ["요리책", "사이트-요리책"] # chef.roles_path = "roles" # chef.add_role("dbserver") # chef.data_bags_path = "data_bags" # chef.json = { # "mysqld" => { # "server_id" => "103" # } # # chef.node_name = "xxx-db03" # chef.log_level = "디버그" #end 엔드 엔드 -----------------------[/shell] 편의상 프로비저닝 설정에 주석이 추가되었습니다 (*)
(*데이터_bags 키 편의성 등, 칼 명령 같은 게 아니면 잘 작동하지 않습니다.)

다음 오류는 SecurityGroup이 ID가 아니라 VPC 내에서 이름이나 다른 서브넷으로 기록될 때 발생합니다.

[shell][web] -- 보안 그룹: ["default,nat-test-grp"] AWS와 통신하는 오류가 발생했습니다. 오류 메시지는 아래에 표시됩니다:

InvalidParameterCombination => 매개변수 groupName은 매개변수 서브넷과 함께 사용할 수 없습니다

[웹] -- 보안 그룹: ["sg-6815xxxx", "sg-6ebdxxxx"] AWS와 통신하는 오류가 발생했습니다. 오류 메시지는 아래에 나와 있습니다:

InvalidParameter => 보안 그룹 sg-6815xxxx와 서브넷 서브넷-80bfxxxx는 서로 다른 네트워크에 속합니다.[/shell]

・AMI 변환 전 최소 설정

한 번 시작하면 중간에 멈추므로, 다음 설정을 수행하고 AMI를 다시 지정하겠습니다.

[shell]# ssh 10.0.0.240 # cd /root/.ssh # vi authorized_keys[/shell] vagrant의 루트 키를 등록하세요

로그인 후 SSH에 대한 권한 설정 [shell]# visudo #Defaults 요구사항[/shell]

전환기 동안 VPC 환경 때문에 밖에 나갈 수 없었고, 컬도 실패했으며, 칼 단독 준비도 작동하지 않았고, 셰프도 설치하지 못했습니다.
stg와 동등한 chef-solo 소스를 NAT 인스턴스로 설정하고, knife solo 클라이언트의 기본 게이트웨이를 NAT로 지정하세요

[shell]# vi /etc/sysconfig/network GATEWAY=10.0.0.93[/shell]

AWS 관리 콘솔에서 노드용 AMI를 생성하고 vagrant로 인스턴스를 다시 실행하세요

  • vagrant와 함께 인스턴스를 시작한다

[shell]# vagrant up --provider=aws 생략 [db] 예시가 "준비"될 때까지 기다리고 있습니다... [db] SSH가 사용 가능해지길 기다리고 있습니다... [db] 기계가 부팅되어 사용 준비가 완료되었습니다! [db] 동기화 폴더: /root/ => /vagrant[/shell]

지금까지 여러 VPC 인스턴스가 잘 실행된 것 같습니다.
다음으로, 저장소를 만들고, 역할과 같은 환경을 정의하며, 레시피를 작성하고 프로비저닝합니다. 프로비저닝은 레시피를 인스턴스에 적용하는 것입니다.

  • 새로운 Chef 저장소 생성
    [shell]# 칼 솔로 init chef-repo # tree -L 1 chef-repo chef-repo |-- cookbooks #サードパーティレシピ置き場 |-- data_bags #ユーザ等データ管理機能使用時に使う |-- 노드용 JSON 파일 저장소 #各サーバ (node) |-- 역할 #Roleを使うとき用ディレクトリ |-- 사이트-쿡북 #自作レシピ置き場 '-- solo.rb #cookbookのパスなどを設定[/shell]

vagrantfile을 chef 저장소 바로 아래로 옮기세요(요리책 경로가 통과하도록 )
[shell]# mv Vagrantfile chef-repo/[/shell]
・필요한 요리책 만들기
Knife cookbook으로 만들 수 있어요. create cookbook-name -o create-directory-path.
[shell]# CD chef-repo # i에 대해 base_setting 로그인 사용자 httpd mysqld munin zabbix ; Do Knife, Cookbook $i -o 사이트-쿡북; 완료 # tree -L 1 site-cookbooks/munin site-cookbooks/munin |-- CHANGELOG.md |-- README.md |-- 속성 #Attributesはtemplateで指定した変数のデフォルト値置き場 |-- 정의 |-- 파일 #定数のみの設定ファイルやパッケージファイル置き場 |-- 라이브러리 |-- metadata.rb |-- 제공자 |-- 레시피 #レシピ置き場 |-- 리소스 '-- 템플릿 #変数を用いる設定ファイル置き場[/shell]

  • 역할 생성

역할을 정의하면, 각 서버에 적용할 때(node용 json 파일을 편집할 때),
매번 레시피 이름이나 속성을 나열할 필요는 없고, 역할 이름만 정의하면 됩니다
웹서버나 데이터베이스서버 같은 역할을 정의하고, 그 역할에 따라 레시피를 열거한 느낌이 듭니다. 노드에 대한 역할을 정의하세요.

 템플릿과 속성은 역할이나 노드에서도 정의할 수 있습니다.
  템플릿 리소스를 작성하고 템플릿 디렉터리에 변수가 포함된 구성 파일을 배치합니다.
  기본 값을 가진 레시피를 attributes 디렉터리에 넣고, 고유 값은 역할이나 노드로 덮어쓰세요.
 *Ohai가 수집한 정보를 사용하려면 attributes 디렉터리에 기본값을 설정하거나 노드나 역할 값이 없을 필요가 없습니다.

각 롤마다 쓸 레시피를 정의하세요
[shell]# CD CHEF-REPO/ROLES # VI webserver.json { "name":"webserver", "chef_type": "role", "json_class":"Chef::Role", "default_attributes":{ "base_setting": { "swappiness": "30", "tcp_tw_reuse": "0", "tcp_tw_recycle": "0", "tcp_fin_timeout": "60", "tcp_max_syn_backlog": "4096", "somaxconn": "4096" } }, "override_attributes": {}, "description":"웹서버 역할", "run_list": [ "recipe[base_setting:::BKUP_dir]", "recipe[login_users]", "recipe[base_setting::hosts], "recipe[base_setting:::sysctl], "recipe[base_setting::d isable]", "recipe[base_setting:::ntpdate]", "recipe[base_setting: Mail-client], "recipe[base_setting::logrotation], "recipe[httpd::httpd-server]", "recipe[httpd::basic_auth]", "recipe[httpd::wordpress]", "recipe[httpd::wordpress]", "recipe[httpd::s3mount]", "recipe[munin::munin-node]", "recipe[munin::munin-node]", "recipe[zabbix:::zabbix-agent]" ] }

# vi dbserver.json { "name":"dbserver", "json_class":"Chef::Role", "chef_type": "role", "description":"", "default_attributes":{ "base_setting": { "swappiness": "0", "tcp_tw_reuse": "1", "tcp_tw_recycle": "1", "tcp_fin_timeout": "10", "tcp_max_syn_backlog": "8192", "somaxconn": "8192" } }, "override_attributes":{}, "run_list": [ "recipe[base_setting::: BKUP_dir], "레시피[로그인_users]", "레시피[베이스_setting::호스트]", "레시피[베이스_setting:::sysctl]", "레시피[베이스_setting::d isable]", "레시피[베이스_setting:::NTPDit], "레시피[베이스_setting::메일-클라이언트]", "레시피[베이스_setting::로그로테이트]", "레시피[mySQLd::MySQLd]", "레시피[mySQLd::MySQL-사용자]", "레시피[Munin::Munin-Node]", "레시피[munin::munin-node]", "레시피[zabbix::Zabbix-agent]" ] }

# vi admserver.json { "name":"admserver", "json_class":"Chef::Role", "description":", "chef_type": "role", "default_attributes":{ "base_setting": { "swappiness": "0", "tcp_tw_reuse": "0", "tcp_tw_recycle": "0", "tcp_fin_timeout": "60", "tcp_max_syn_backlog": "8192", "somaxconn": "8192" } }, "override_attributes": {}, "run_list": [ "레시피[base_setting:::BKUP_dir]", "recipe[login_users], "recipe[base_setting::hosts], "recipe[base_setting:::sysctl]", "recipe[base_setting::d isable]", "recipe[base_setting:::ntpd], "recipe[base_setting:::ntpdate], "recipe[base_setting:::Mail-Postfix], "recipe[base_setting:::Mail-Dovecot], "recipe[base_setting:", "recipe[base::" logRotate], "레시피[httpd::HTTPD-서버]", "레시피[HTTPD::WordPress]", "레시피[mySQLd::mysqld-서버]", "레시피[mysqld::mysql-users]", "레시피[munin::munin-node]", "레시피[munin::munin-node-web], "레시피[munin::munin-node-db]", "레시피[munin::munin-server]", "레시피[zabbix::Zabbix-agent]", "레시피[Zabbix::Zabbix-프록시]" ] }[/shell]
*초보자 셰프 안티패턴에 따르면, 역할은 버전 설정이 불가능합니다.
 런리스트는 역할별로 관리해서는 안 되는 것 같습니다(리팩토링 가능).

*sysctl.conf가 각 역할에 대해 다른 값을 갖길 원해서, 템플릿에 변수를 삽입하고 속성을 사용해 이를 덮어쓰기로 했습니다.
다음에 템플릿과 속성에 대해 자세히 설명하겠지만, [chef] 속성은 이해합니다. 는 이해하기 쉬웠습니다.
이 이야기가 셰프와는 전혀 관련이 없다는 점 죄송하지만, 여기 적힌 내용이라면,
경우에 따라서는 "net.ipv4.tcp_tw_recycle" 활성화를 중단해야 합니다.
공용 무선 LAN 환경에서 스마트폰 등으로 같은 회선을 사용하는 경우도 있습니다.
여러 단말기에서 동시에 접속할 경우 통신이 불가능할 수 있습니다.
즉, 0은 프론트 WEB과 MTA 서버의 권장 값입니다.
만약 항상 다른 IP에서 연결된 백엔드 DB라면 1번으로는 문제가 없을 겁니다. 아마도요.

・node용 JSON 파일 생성
[shell]# CD CHEF-REPO/NODES # VI localhost.json { "run_list":[ "role[admserver]" ] }

# vi 10.0.0.240.json { "run_list":[ "role[웹서버]" ] }

# vi 10.0.0.241.json { "mysqld" : { "server_id" : 103 }, "run_list":[ "role[dbserver]" ] }[/shell]

*역할과 레시피는 함께 작성할 수 있습니다.
*role을 사용하지 않으면 모든 것을 node에 작성해야 하므로, 30개의 웹 서버가 있다면 꽤 번거롭습니다.
*각 노드별로 분리해야 할 MySQL의 서버_id 매개변수 속성을 지정합니다.
*vagrant로 프로비저닝을 원한다면 node JSON 파일이 많이 필요하지 않을 수도 있습니다.

·데이터로 사용자 관리 준비_bags

data_bags는 LDAP와 유사한 기능으로 데이터 검색과 같이 관리할 수 있는 도구입니다.
chef-server를 사용하면 서버와 통신하여 데이터를 가져오고 반영할 수 있습니다.
이번이 Chef-sol로이기 때문에, 데이터를 로컬 파일에 준비하고 반영할 예정입니다.

참고문헌:
사용자가 많고 계정을 자주 추가하고 변경한다면, 아래 링크에 나와 있는 것처럼 data_bags를 사용해 활성화 및 비활성화를 관리하는 것이 좋습니다.
chef-data-bag 사용법

[shell]# cd ; cd chef-repo/data_bags # mkdir 사용자; CD 사용자 # vi xxx-op.json // xxx-op.json { "id" : "xxx-op", "groups": [ "xxx-op","wheel" ], "uid": 1000, "username" : "xxx-op", "home" : "/home/xxx-op", "shell" : "/bin/bash", "password" : "$1$Ka.Mw69U$TT5HRfSe7xxxxx" }

# vi yyy-op.json // yyy-op.json { "id" : "yyy-op", "groups": [ "yyy-op","wheel" ], "uid": 500, "username" : "yyy-op", "home" : "/home/yyy-op", "shell" : "/bin/bash", "password" : "$1$Ka.Mw69U$TT5HRfSe78Pxxxxx" }

# vi dev.json // dev.json { "id" : "dev", "groups": [ "dev","wheel" ], "uid": 501, "username" : "dev", "home" : "\/home\/dev", "shell" : "\/bin\/bash", "password" : "$1$S/q25RbR$oO7pCoAjBWxxxxx" }[/shell]

다음 명령어로 비밀번호를 생성합니다
[shell]# openssl passwd -1[/shell]

[shell]# 칼 단독 데이터 가방 표시 사용자[/shell] 데이터가 표시되는지 확인해 주세요

  • MySQL에서 사용자 정의를 암호화하기

*노드와 역할에 대해 비밀번호를 일반 텍스트로 정의하는 것은 안전하지 않으며, 각 노드별로 기록하는 것은 현명하지 않습니다.
 그럼 키로 암호화할 수 있는 데이터백을 사용해 봅시다
 암호화는 knife-sol로만 사용할 수 없는 것 같지만, knife-solo_data\\를 _bag 설치하면 사용할 수 있을 거예요.

[shell]# openssl rand -base64 512 | tr -d '\r\n' > /etc/chef/encrypted_data_bag_secret # chmod 400 encrypted_data_bag_secret # CD /ROOT/CHEF-REPO # 칼 솔로 데이터 가방 MySQLUsers root 생성 --secret-file ./encrypted_data_bag_secret 편집기가 열리면 다음 입력이 있습니다 { "id": "root", "user": "root", "pass": "xxxxxxx", "host": "localhost", "privileges": "all" }

# Knife Solo Data Bag 생성 mySQLUsers repl --secret-file ./encrypted_data_bag_secret 편집기가 열리면 다음 입력이 있습니다 { "id": "repl", "user": "repl", "pass":"xxxxxxx", "host":"10.0.0.%", "privileges": ["\\:replication slave", "\\:replication client"] }

# 나이프 솔로 데이터 가방 작성 mysqlusers xxx_admin --secret-file ./encrypted_data_bag_secret 편집기가 열리면 다음 { "id": "xxx_admin", "user": "xxx_admin", "pass": "xxxxxxx", "host":"10.0.0.%" "privileges": "all" }

# 나이프 솔로 데이터 가방 생성 mysqlusers zabbix --secret-file ./encrypted_data_bag_secret 편집기가 열리면 다음 입력이 있습니다 { "id": "zabbix", "user": "zabbix", "pass": "xxxxxxx", "host": "localhost", "privileges": "all" }

체크 # 나이프 솔로 데이터 가방 표시 mysqlusers 표시 # 나이프 솔로 데이터 가방 표시 mysqlusers repl --secret-file ./encrypted_data_bag_secret # 나이프 솔로 데이터 가방 표시 mysqlusers root 표시 --secret-file ./encrypted_data_bag_secret # 나이프 솔로 데이터 가방 표시 mysqlusers xxx_admin --secret-file ./encrypted_data_bag_secret # 나이프 솔로 데이터 가방 표시 mysqlusers zabbix --secret-file ./encrypted_data_bag_secret[/shell] 데이터가 표시되는지 확인해 주세요
다른 명령어들은 아래에서 확인할 수 있습니다.
[shell]# 칼 솔로 데이터 가방 --도와줘[/shell]
chef-server를 이용한 부트스트랩 파일에서 데이터백 키를 클라이언트 호스트에 전달하는 것이 가능한 것으로 보입니다.
아마도 knife-solo_data_bag 때문에 knife solo cook 호스트네임을 사용할 때 부트스트랩 파일을 지정할 필요가 없어 보였습니다.
방랑자 쪽에서는 어떻게 해야 할지 잘 모르겠어요.

나중에 레시피에서 어떻게 부르는지 레시피를 올릴 예정이지만, 다음 내용이 도움이 될 것입니다.
참고문헌:
Chef에 게시하고 싶지 않은 JSON 데이터를 암호화하기 위해 DataBags를 사용한 기록 MySQL 비밀번호 Chef 내 처리

Chef-Server는 프로덕션 환경과 테스트 환경을 환경별로 분리할 수 있는 것 같지만, 이 기능이 Chef-Solo에 포함되어 있지 않아 다소 아쉽습니다.
조금 더 큰 환경(20유닛 이상)의 경우에는 Chef-Server가 더 나은 것 같아서, 그런 이야기가 있다면 사용할 수도 있을 것 같습니다、、、
저도 그렇게 생각했는데, 찾아보니 11.6부터 쓸 수 있는 것 같더라고요. 아, 기쁘네요. 나중에 저장해볼게요.

이번에는 여기까지입니다. 시청해 주셔서 감사합니다.
다음 단계는 레시피에 관한 것입니다.

Related Articles