21 दिनों में बावर्ची। भाग तीन शेफ और AWS

नमस्कार, हब्बर। इसलिए मेरे लेख का तीसरा भाग आ गया, जो शुरुआती लोगों के लिए लेख के चक्र ( भाग 1 और भाग 2 ) को संक्षेप में प्रस्तुत करता है। यह हिस्सा अमेज़ॅन क्लाउड में शेफ का उपयोग करने के एक ठोस उदाहरण पर ध्यान केंद्रित करेगा। जैसा कि मैंने उल्लेख किया है, यह एक काफी लोकप्रिय परिदृश्य है। समझने में आसानी के लिए, हम दो ec2- उदाहरण (अमेज़ॅन वर्चुअल सर्वर) के मामले पर विचार करेंगे, जिनमें से एक बावर्ची सर्वर के रूप में कार्य करेगा, और दूसरा नोड के रूप में।

AWS और बावर्ची


मैं तुरंत स्पष्ट कर दूंगा कि हम AWS CloudFormation का उपयोग करके इंस्टेंस चलाएंगे। आप निश्चित रूप से, उन्हें मैन्युअल रूप से शुरू और प्रबंधित कर सकते हैं, लेकिन ऐसे स्वचालन में क्या बात है?

CloudFormation को 2 अवधारणाओं में विभाजित किया जा सकता है:
- टेम्पलेट , जो एक json फ़ाइल है जो उन सभी संसाधनों का वर्णन करती है जिन्हें हमें उदाहरण के लिए चलाने की आवश्यकता है;
- स्टैक , जो एडब्ल्यूएस संसाधन स्वयं टेम्पलेट में वर्णित है।
जो लोग AWS में नए हैं, उनके लिए Amazon पूर्व-निर्मित नमूना टेम्प्लेट प्रदान करता है जो AWS के अधिकांश पहलुओं को कवर करते हैं। लेख के अंत में टेम्प्लेट का लिंक प्रदान किया जाएगा।
विचार करें कि टेम्पलेट क्या है । मूल मामले में, इसमें 4 ब्लॉक होते हैं: पैरामीटर, मैपिंग, संसाधन, आउटपुट
पैरामीटर्स ब्लॉक चर और उनके मूल्यों का वर्णन करता है जो उस समय बनाए गए स्टैक को पारित किए जाएंगे। संसाधन बनाते समय पैरामीटर मान दर्ज किए जा सकते हैं, या पैरामीटर विवरण में डिफ़ॉल्ट फ़ील्ड का उपयोग करके सेट किया जा सकता है। पैरामीटर कोई भी जानकारी हो सकती है, पासवर्ड से शुरू होकर नेटवर्क पोर्ट या डायरेक्टरी के रास्ते के साथ समाप्त होती है। पैरामीटर मान प्राप्त करने के लिए, टेम्पलेट में Ref फ़ंक्शन का उपयोग किया जाता है।
मैपिंग ब्लॉक में संबंधित मापदंडों और उनके मूल्यों के साथ कुंजियों का एक सेट होता है। अक्सर, आप देख सकते हैं कि AWS क्षेत्रों और उनके संबंधित आभासी चित्रों (उदाहरण) की पहचान करने के लिए मैपिंग का उपयोग कैसे किया जाता है। किसी विशेष मैपिंग का मान प्राप्त करने के लिए, Fn :: FindInMap फ़ंक्शन का उपयोग करें, जो कुंजी और पैरामीटर निर्दिष्ट करता है जिसके द्वारा यह या उस मान को खोजा जाता है।
संसाधन ब्लॉक हमारे ec2- उदाहरण या अन्य AWS संसाधनों का वर्णन करता है। यह इस खंड में है कि शेफ सर्वर और क्लाइंट नोड के लिए चित्र घोषित किए गए हैं। विवरण में, आपको संसाधन के प्रकार को निर्दिष्ट करना होगा (उदाहरण के लिए, AWS :: EC2 :: उदाहरण), मेटाडेटा को निर्दिष्ट करना भी संभव है, जिसमें आप पूर्व-स्थापित प्रक्रिया द्वारा हमारे नोड या निर्देश का विवरण निर्दिष्ट कर सकते हैं (उदाहरण के लिए, यदि आपको छवि शुरू होने पर किसी भी पैकेज को स्थापित करने की आवश्यकता है )। ब्लॉक का मुख्य भाग प्रॉपर्टीज ब्लॉक है, जो स्टार्टअप इमेज के बारे में विस्तार से बताता है। इस ब्लॉक में, आप उस प्रकार की छवि को निर्दिष्ट कर सकते हैं जिसे लॉन्च किया जाएगा (उदाहरण के लिए, अमेज़ॅन लिनक्स 32-बिट), चाहे लॉन्च की गई छवि एक या किसी अन्य सुरक्षा समूह की हो (वास्तव में, यह एक फ़ायरवॉल है , यातायात के लिए परिभाषित नियमों के साथ, जिसमें डिफ़ॉल्ट कार्रवाई से इनकार किया जाता है। )। हालाँकि, गुण ब्लॉक का सबसे महत्वपूर्ण हिस्सा उपयोगकर्ता डेटा है । यह वह जगह है जहां हम उस स्क्रिप्ट का वर्णन करेंगे जो हमारे फेसलेस इंस्टेंस को शेफ सर्वर या शेफ क्लाइंट में बदल देगी।
मेरे द्वारा उपयोग किए जाने वाले टेम्पलेट को बिल्ली के नीचे दिखाया गया है, इस पर विचार करें और मैं इस पर टिप्पणी करूंगा।

खाका
{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "Template for stack", "Parameters" : { "KeyName" : { "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances", "Type" : "String", "MinLength" : "1", "MaxLength" : "255", "AllowedPattern" : "[\\x20-\\x7E]*", "ConstraintDescription" : "can contain only ASCII characters." }, "HostKeys" : { "Description" : "Public Key", "Type" : "String" }, "SecretAccessKey" : { "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances", "Type" : "String" }, "InstanceType" : { "Description" : "Chef Server EC2 instance type", "Type" : "String", "Default" : "m1.small", "AllowedValues" : [ "t1.micro","m1.small"], "ConstraintDescription" : "must be a valid EC2 instance type." }, "SSHLocation" : { "Description" : " The IP address range that can be used to SSH to the EC2 instances", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "0.0.0.0/0", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form xxxx/x." } }, "Mappings" : { "AWSInstanceType2Arch" : { "t1.micro" : { "Arch" : "64" }, "m1.small" : { "Arch" : "64" } }, "AWSRegionArch2AMI" : { "us-east-1" : { "32" : "ami-d7a18dbe", "64" : "ami-bba18dd2", "64HVM" : "ami-0da96764" }, "us-west-2" : { "32" : "ami-def297ee", "64" : "ami-ccf297fc", "64HVM" : "NOT_YET_SUPPORTED" }, "us-west-1" : { "32" : "ami-923909d7", "64" : "ami-a43909e1", "64HVM" : "NOT_YET_SUPPORTED" } } }, "Resources" : { ChefClient" : { "Type" : "AWS::EC2::Instance", "Metadata" : { "Description" : "Chef Client", "AWS::CloudFormation::Init" : { "config" : { "packages" : { "yum" : { "git" : [] } } } } }, "Properties": { "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, "InstanceType" : { "Ref" : "InstanceType" }, "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ], "KeyName" : { "Ref" : "KeyName" }, "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "#!/bin/bash -v\n", "yum update -y aws-cfn-bootstrap\n", "function error_exit\n", "{\n", " cfn-signal -e 1 -r \"$1\" '", { "Ref" : "WaitHandle" }, "'\n", " exit 1\n", "}\n", "yum update -y\n", "yum install git -y\n", "/sbin/service iptables stop\n", "/sbin/service ip6tables stop\n", "/sbin/chkconfig iptables off\n", "/sbin/chkconfig iptables off\n", "yum install git -y\n", "/usr/bin/curl -L https://www.opscode.com/chef/install.sh | bash\n", "cd /root/\n", "/usr/bin/git git://github.com/opscode/chef-repo.git\n", "/bin/mkdir -p /root/chef-repo/.chef\n", "/bin/mkdir -p /etc/chef\n", "/bin/mkdir /root/.aws\n", "/bin/touch /root/.aws/config\n", "/bin/echo '[default]' >> /root/.aws/config\n", "/bin/echo 'region = ", {"Ref" : "AWS::Region" }, "' >> /root/.aws/config\n", "/bin/echo 'aws_access_key_id = ", { "Ref" : "HostKeys" }, "' >> /root/.aws/config\n", "/bin/echo 'aws_secret_access_key = ", { "Ref" : "SecretAccessKey" }, "' >> /root/.aws/config\n", "/usr/bin/aws s3 cp s3://storage/admin.pem /root/chef-repo/.chef\n", "/usr/bin/aws s3 cp s3://storage/chef-validator.pem /root/chef-repo/.chef\n", "/usr/bin/aws s3 cp s3://storage/knife.rb /root/chef-repo/.chef\n", "/usr/bin/aws s3 cp s3://storage/client.rb /etc/chef\n", "/usr/bin/aws s3 cp s3://storage/json_attribs.json /etc/chef\n", "/bin/cp -p /root/chef-repo/.chef/chef-validator.pem /etc/chef/validation.pem\n", "/usr/sbin/ntpdate -q 0.europe.pool.ntp.org\n", "/bin/echo '\nchef_server_url \"", { "Ref" : "ChefServerURL" }, "\"' >> /etc/chef/client.rb\n", "/bin/echo '\nchef_server_url \"", { "Ref" : "ChefServerURL" }, "\"' >> /root/chef-repo/.chef/knife.rb\n", "/usr/bin/chef-client\n", "/opt/aws/bin/cfn-signal -e 0 -r \"ChefClient setup complete\" '", { "Ref" : "WaitHandle" }, "'\n" ]]}} } }, "WaitHandle" : { "Type" : "AWS::CloudFormation::WaitConditionHandle" }, "WaitCondition" : { "Type" : "AWS::CloudFormation::WaitCondition", "DependsOn" : "ChefClient", "Properties" : { "Handle" : {"Ref" : "WaitHandle"}, "Timeout" : "1200" } }, "ChefServer" : { "Type" : "AWS::EC2::Instance", "Metadata" : { "Description" : "Bootstrap ChefServer", "AWS::CloudFormation::Init" : { "config" : { "packages" : { "yum" : { "wget" : [] } } } } }, "Properties": { "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, "InstanceType" : { "Ref" : "InstanceType" }, "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ], "KeyName" : { "Ref" : "KeyName" }, "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "#!/bin/bash\n", "cfn-init --region ", { "Ref" : "AWS::Region" }, " -s ", { "Ref" : "AWS::StackId" }, " -r ChefServer ", " -c orderby ", " --access-key ", { "Ref" : "HostKeys" }, " --secret-key ", {"Ref" : "SecretAccessKey"}, " || error_exit 'Failed to run cfn-init'\n", "yum update -y aws-cfn-bootstrap\n", "function error_exit\n", "{\n", " cfn-signal -e 1 -r \"$1\" '", { "Ref" : "WaitHandle" }, "'\n", " exit 1\n", "}\n", "yum update -y\n", "/sbin/service iptables stop\n", "/sbin/service ip6tables stop\n", "/sbin/chkconfig iptables off\n", "/sbin/chkconfig ip6tables off\n", "#Install ChefServer package\n", "cd /root/\n", "/usr/bin/wget https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-server-11.0.10-1.el6.x86_64.rpm\n", "/bin/rpm -ivh /root/chef-server-11.0.10-1.el6.x86_64.rpm\n", "/usr/bin/wget https://s3.amazonaws.com/storage/default.rb\n", "/bin/cp -f default.rb /opt/chef-server/embedded/cookbooks/runit/recipes/default.rb\n", "#Configure ChefServer\n", "su - -c '/usr/bin/chef-server-ctl reconfigure'\n", "su - -c '/usr/bin/chef-server-ctl restart'\n", "#AWS creds installation\n", "/bin/mkdir /root/.aws\n", "/bin/touch /root/.aws/config\n", "/bin/echo '[default]' >> /root/.aws/config\n", "/bin/echo 'region = ", {"Ref" : "AWS::Region" }, "' >> /root/.aws/config\n", "/bin/echo 'aws_access_key_id = ", { "Ref" : "HostKeys" }, "' >> /root/.aws/config\n", "/bin/echo 'aws_secret_access_key = ", { "Ref" : "SecretAccessKey" }, "' >> /root/.aws/config\n", "#Upload files for client\n", "/usr/bin/aws s3 cp /etc/chef-server/admin.pem s3://storage/\n", "/usr/bin/aws s3 cp /etc/chef-server/chef-validator.pem s3://storage/\n", "#Chef client and dirs for it\n", "/usr/bin/curl -L https://www.opscode.com/chef/install.sh | /bin/bash\n", "/bin/mkdir /root/.chef\n", "/bin/mkdir /etc/chef\n", "/bin/mkdir /etc/chef/cookbooks\n", "/bin/mkdir /etc/chef/roles\n", "#Knife client config files from S3\n", "/bin/cp /etc/chef-server/admin.pem /etc/chef/client.pem\n", "/usr/bin/aws s3 cp s3://storage/knife_admin.rb /root/.chef/knife.rb\n", "#Roles and cookbooks from S3\n", "/usr/bin/aws s3 cp s3://storage/roles/ /etc/chef/roles/ --recursive\n", "/usr/bin/aws s3 cp s3://storage/cookbooks/ /etc/chef/cookbooks/ --recursive\n", "#Cookbooks from community\n", "/usr/bin/knife cookbook site download cron\n", "/usr/bin/knife cookbook site download jenkins\n", "/usr/bin/knife cookbook site download ntp\n", "/usr/sbin/ntpdate -q 0.europe.pool.ntp.org\n", "yum remove ruby -y\n", "yum install ruby19 -y\n", "#Unpack and move cookbooks\n", "/bin/mv /root/*.tar.gz /etc/chef/cookbooks\n", "for i in `/bin/ls /etc/chef/cookbooks/*.tar.gz`; do /bin/tar zxf $i -C /etc/chef/cookbooks/; /bin/rm -f $i; done\n", "for i in `/bin/ls /etc/chef/cookbooks`; do /usr/bin/knife cookbook upload $i; done\n", "#Upload cookbooks and roles\n", "/usr/bin/knife cookbook upload * -c '/root/.chef/knife.rb'\n", "/usr/bin/knife role from file /etc/chef/roles/*.rb\n", "/bin/echo -e \"*/5 * * * * root /usr/bin/knife exec -E 'nodes.find(\\\"!roles:BaseRole\\\") { |n| puts n.run_list.add(\\\"role[BaseRole]\\\"); n.save}' -c '/root/.chef/knife.rb'\" >> /etc/crontab\n", "/bin/echo -e \"*/5 * * * * root /usr/bin/knife exec -E 'nodes.find(\\\"env_role:master AND !roles:master\\\") { |n| puts n.run_list.add(\\\"role[master]\\\"); n.save}' -c '/root/.chef/knife.rb'\" >> /etc/crontab\n", "/bin/echo -e \"*/5 * * * * root /usr/bin/knife exec -E 'nodes.find(\\\"env_role:slave AND !roles:slave\\\") { |n| puts n.run_list.add(\\\"role[slave]\\\"); n.save}' -c '/root/.chef/knife.rb'\" >> /etc/crontab\n", "/opt/aws/bin/cfn-signal -e 0 -r \"ChefServer setup complete\" '", { "Ref" : "WaitHandle" }, "'\n" ]]}} } }, "WaitHandle" : { "Type" : "AWS::CloudFormation::WaitConditionHandle" }, "WaitCondition" : { "Type" : "AWS::CloudFormation::WaitCondition", "DependsOn" : "ChefServer", "Properties" : { "Handle" : {"Ref" : "WaitHandle"}, "Timeout" : "1200" } }, "WebServerSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable HTTP access via port 80 and SSH access", "SecurityGroupIngress" : [ {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"}, {"IpProtocol" : "tcp", "FromPort" : "8080", "ToPort" : "8080", "CidrIp" : "0.0.0.0/0"}, {"IpProtocol" : "tcp", "FromPort" : "443", "ToPort" : "443", "CidrIp" : "0.0.0.0/0"}, {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"}} ] } }, } 



टेम्पलेट से यह देखा जाता है कि हमने पाँच पैरामीटर घोषित किए हैं। उनमें से दो में डिफ़ॉल्ट मान हैं - उदाहरण का प्रकार बनाया जा रहा है (इस मामले में m1.small) और आईपी पते का सबनेट जिसमें से SSH नोड तक पहुंच की अनुमति होगी। स्टैक बनाते समय, आपको 3 पैरामीटर निर्दिष्ट करने की आवश्यकता होगी - नोड के लिए एसएसएच एक्सेस की कुंजी (एडब्ल्यूएस कंसोल में अलग से बनाई गई), एक्सेस कुंजी और गुप्त कुंजी (दोनों एडब्ल्यूएस एक्सेस खाते को पंजीकृत करते समय बनाई जाती हैं)।
मानचित्रण के दो प्रकारों का वर्णन किया गया है, दोनों 64-बिट वास्तुकला के साथ। AWSRegionArch2AMI भी आभासी छवि आईडी का वर्णन करता है जो अमेज़ॅन लिनक्स के साथ अनुरूप है (ये आईडी AWS कंसोल से प्राप्त किए जा सकते हैं)।
अगला, हम शेफ सर्वर और शेफ क्लाइंट के संसाधनों का वर्णन करते हैं। दोनों मामलों में, मेटाडेटा अनुभाग के माध्यम से, उपयोगकर्ता डेटा अनुभाग से कमांड चलाने से पहले, wget स्थापित है (बस मामले में, वास्तव में, अमेज़ॅन लिनक्स छवियों में ऐसे पैकेज होने चाहिए)। बनाए गए संसाधन ImageId और InstanceType चर द्वारा निर्धारित किए जाते हैं (इस मामले में, ये पहले निर्दिष्ट पैरामीटर हैं, इस मामले में Amazon Linux, m1.small और 64-बिट आर्किटेक्चर)। अगला संसाधन का मुख्य निकाय है - उपयोगकर्ता डेटा । यह बैश कॉन्फ़िगरेशन स्क्रिप्ट के शरीर का प्रतिनिधित्व करता है, जिसे हमारे उदाहरण के प्रारंभ होने के बाद चरण दर चरण निष्पादित किया जाता है।
संक्षेप में, शेफ सर्वर होगा नोड के लिए निम्न कदम उठाए गए हैं:

मैं समझता हूं कि यह एक अराजक और समझ से बाहर की व्याख्या की तरह लग सकता है, हालांकि, स्क्रिप्ट के प्रत्येक भाग की एक विस्तृत परीक्षा में बहुत अधिक जगह होगी। इसलिए - यदि आपके कोई प्रश्न हैं - मुझे पीएम या टिप्पणियों में लिखने के लिए स्वतंत्र महसूस करें।
वापस हमारे टेम्पलेट पर। एक नोड के लिए जो बावर्ची ग्राहक होगा , निम्नलिखित कार्य किए जाते हैं:

यह ध्यान देने योग्य है कि json_attribs जैसे विकल्प के लिए धन्यवाद, हम नोड के लिए एक लेबल बना सकते हैं जो बुनियादी ढांचे में अपनी भूमिका निर्धारित करेगा। यह उस मामले के लिए किया जाता है जब बावर्ची-ग्राहकों के बीच विभिन्न बुनियादी ढांचा भूमिकाओं को स्वीकार करने वाले नोड्स हो सकते हैं।
निम्न संसाधन, WaitHandle और WaitCondition , उन परिस्थितियों का वर्णन करते हैं जिनके तहत स्टैक बनाने की प्रक्रिया को रोका जा सकता है। अगर WaitHandle, WaitCondition में निर्दिष्ट टाइमआउट के भीतर प्रक्रिया के सफल समापन के बारे में संकेत प्राप्त करता है - तो स्टैक बनाने की प्रक्रिया जारी रहती है / समाप्त होती है।
अगला विज्ञापित संसाधन सुरक्षा समूह है , जो हमारे नोड्स के लिए एक फ़ायरवॉल है। समूह पैकेट के अग्रेषित पोर्ट और स्रोत पते का वर्णन करता है।
आखिरी ब्लॉक - आउटपुट - यह सुनिश्चित करने के लिए कार्य करता है कि स्टैक और उदाहरण के सफल लॉन्च के बाद, हमें कोई भी चर प्राप्त करने के लिए जो हमारी रुचि है। उदाहरण के लिए, उदाहरण तक पहुँचने के लिए एक डोमेन नाम।
नतीजतन, हमें एक सार्वभौमिक टेम्पलेट और हमारे मामूली बुनियादी ढांचे को "तैनात" करने की क्षमता मिलती है (यदि आप बड़ी संख्या में उदाहरण के लिए इच्छुक हैं - तो ऑटो-स्केलिंग समूह का उपयोग करें) एक एडब्ल्यूएस प्रबंधन कंसोल में एक कमांड निष्पादित करके। लॉन्च का परिणाम CloudFormation अनुभाग में पाया जा सकता है।
आगे क्या है? फिर आपको चाकू, कुकबुक और भूमिकाओं द्वारा नोड्स को नियंत्रित करने का अवसर मिलता है। आप सामुदायिक कुकबुक का उपयोग कर सकते हैं, अपना खुद का लिख ​​सकते हैं, अन्य कुकबुक के लिए रैपर लिख सकते हैं। कई अवसर हैं और यह सब अंतिम कार्य पर निर्भर करता है।
लेखों की इस श्रृंखला में, मैंने कोशिश की, सतही रूप से, पीसी बेड़े प्रबंधन को स्वचालित करने की प्रक्रिया का वर्णन करने और AWS क्लाउड संसाधनों के साथ बातचीत करने के लिए। उम्मीद है, शुरुआती DevOps के लिए ये लेख दिलचस्प होंगे।
अगर मेरे पास प्रश्न और सुझाव हैं - तो अपने लेखों पर संवाद या टिप्पणियों में लिखने के लिए स्वतंत्र महसूस करें। उन सभी को धन्यवाद जिन्होंने लेख पढ़ने के लिए समय लिया।
जल्द मिलते हैं!

संदर्भ :

Source: https://habr.com/ru/post/In211050/


All Articles