Config ทุก servers พร้อมกันง่ายแค่ดีดนิ้ว เพียงใช้ Puppet [Hand-On]
ทำไมถึงว่า Puppet จะมาทำให้การ config ในทุก servers ง่ายขึ้น มาลองคิดสภาพตามนะ สมมติเคสของ docker ถ้าเราต้องการเครื่อง master เครื่องหนึ่ง เครื่อง slave อีกสัก 10 เครื่องเพื่อจะมาทดสอบอะไรสักอย่าง โดยที่ทั้ง 11 เครื่องเนี่ย เราต้องล็อคอินด้วย username เดียวกันแล้วก็ติดตั้งแพคเกจเหมือนๆกัน install docker install database อย่างเราใช้ OS WINDOWS นึกสภาพเปิด Putty ขึ้นมา 11 หน้าต่างแล้วก็นั่งไล่ทีละเครื่อง install docker เอง แล้วก็แพคเกจทีละตัวๆ ดูเหนื่อยเนาะ แล้วถ้าเกิดระบบมันใหญ่มีเป็น 100 เครื่องเชื่อมกันจะทำยังไงดีล่ะ ดังนั้น Puppet ตอบโจทย์ !!!
Puppet คือสิ่งที่จะมาช่วย Automate config. package ซ้ำๆให้ หลายที่เหลือที่เดียว ช่วยลดเวลาการทำงานจากเป็นชั่วโมง มาเหลือแค่ไม่กี่นาที ตามแบบ devops
การทำงานของ Puppet จะเป็นการคุยกันระหว่างเครื่อง master กับ node โดยเครื่อง master เนี่ยต้องใช้ OS Linux นะ (2 vCPU, 1 RAM) แต่เครื่อง node ที่จะทำการ config ใช้ OS อะไรก็ได้ โดย master จะเก็บ config ทั้งหมดเอาไว้ เรามีหน้าที่เขียนสคริปที่ master แล้วให้ master รันตัวเดียวเพื่อไป config install package ต่างๆในเครื่อง node ที่เหลือ
ลักษณะการทำงานของ Puppet
เริ่มต้น puppet agent จะส่ง Facts มาให้ Puppet master โดยภายใน Facts จะเป็นข้อมูลพวก Key, value pair ที่บอกว่าเป็นของ agent เช่น IP Address, hostname , kernel version เป็นต้น
จากนั้น puppet master จะใช้ Fact มา complie catalog ซึ่งภายในไฟล์ catalog จะเปรียบเทียบ config ว่าได้มีการแก้ไขอะไรไหมแล้วส่งไปให้ agent
หลังจากนั้น agent จะส่ง report กลับมา master เพื่อแจ้งว่า config ผ่านแล้วนะ
ขั้นตอนการติดตั้ง Puppet Master บน AWS
- เข้าหน้าเว็บ AWS เลือก EC2 กด Launch instance
2. เลือก centos 7 (อันนี้จะแล้วแต่เลยก็ได้แต่ master ต้อง Linux OS)
3. ข้อบังคับของ puppet master คือสเปคอย่างต่ำต้อง 2 vCPU, 1 RAM
4. ตั้งค่า Network allow all TCP เพื่อให้สามารถเรียกใช้จากภายนอกได้ และ ICMP เพื่อให้สามารถทดสอบ ping IP test ระหว่างเครื่อง Agent กับเครื่อง Master ได้
5. ต่อมากด Lunch instance จะมี popup โชว์ให้ทำการสร้าง key เราก็ create new key แล้วกดดาวน์โหลด ซึ่ง key ที่ได้จะยังเป็น .pem เราต้องไปทำการ convert เป็น .ppk ใน puttygen อีกทีแล้ว save private key เพื่อใช้ในการ connect instance
6. connect instance ด้วย IPv4 Public IP ผ่าน Putty
คลิ๊กมาที่ SSH > Auth แล้ว Browse เลือก key.ppk ที่ทำ conversion แล้ว
7. ทำการ open connection แล้ว login ด้วย user default: centos จากนั้นเปลี่ยนตัวเองเป็น root ด้วยคำสั่ง sudo -i จากนั้นทำการเช็ค IP เครื่องด้วยคำสั่ง ifconfig -a เราจะเอา private ip ในเครื่องมา map hostname เป็น puppet master ไว้สื่อสารกับ puppet agent โดยเข้าไปแก้ไขที่ path /etc/hosts
พอ map hostname กับ private IP เรียบร้อยก็มาเปลี่ยนชื่อ hostname ด้วยคำสั่ง hostnamectl set-hostname ชื่อที่ map ในที่นี้คือ puppetmaster.example.com
ทำการติดตั้ง repository puppet ได้จาก docs ในที่นี้เราใช้ centos จึงใช้คำสั่งนี้
จากนั้นลองเช็คว่า repositoy puppet ถูกลงสมบูรณ์ครบแล้วด้วยคำสั่ง yum repolist
ต่อมา install puppet server เพื่อให้เครื่องนี้เป็น master และลองเช็ค version ที่สามารถลงได้ในเน็ตด้วยคำสั่ง yum list | grep -i puppet จะเห็น puppet server ที่สามารถ install ได้อยู่ชื่อ puppetserver.noarch แล้วก็เริ่ม install กันเลยด้วยคำสั่ง “ yum install puppetserver.noarch ” เมื่อติดตั้งเสร็จจะลองเช็คว่าแพคเกจติดตั้งครบแล้วจริงๆด้วยคำสั่ง rpm -qa | grep -i puppet ก็ได้
ตอนนี้เราก็สั่งให้ puppet master ของเรา run ได้เลยด้วยคำสั่ง
“ systemctl start puppetserver ”
ขั้นตอนการติดตั้ง Puppet Agent บน AWS
- ทำซ้ำขั้นตอน 1–2 ใน Puppet Master
- สเปค cpu, memory ของ Puppet Agent ใช้ค่า default ที่เป็น free tier ได้เลย
- ขั้นตอนการตั้งค่า network สามารถเลือกเป็น security group เดียวกับ Agent Master ก็ได้คือ Allow all TCP เหมือนกันโดยดูชื่อ security group ของ Agent master ได้ที่หน้า instance
อันนี้แล้วแต่ policy ของเราจะใช้ key pair ใหม่หรือ key pair เดียวกับ puppet master ก็ได้ในที่นี้ขอใช้ key pair เดียวกัน
แล้วก็สร้างเครื่อง agent อีกเครื่องแบบเดียวกัน เสร็จแล้วจะได้แบบนี้..
4. open connection ใน putty ด้วย IPv4 public IP ของ puppet-agent พร้อมกับ key ที่ตั้งค่าใน Auth เหมือนเดิม จากนั้นลองทำการ ping private IP puppet master ในเครื่อง agent ว่าเครื่อง master สามารถส่งข้อมูลได้ไหม จากนั้นเรามา mapping private IP ของเครื่อง agent ด้วย alias puppet agent กันและบอก IP mapping ของเครื่อง master ในเครื่อง agent ด้วยที่ไฟล์ /etc/hosts
ถ้าเกิดมี node agent เครื่องอื่นก็ใส่ในลักษณะเดียวกันมีแค่ private IP node เครื่องนั้นกับ private IP master เพราะเราต้องการแค่ให้ node agent ตัวนั้นคุยกับ master
จากนั้นทดสอบ ping ด้วยชื่อ hostname puppet master จากเครื่อง agent ดู
แล้วก็ไปแก้ mapping ip กับ hostname ในเครื่อง master อีกทีโดยเพิ่ม mapping IP hostname ของเครื่อง agent เข้าไป
กลับมาที่เครื่อง agent เพื่อลง repo puppet จาก docs ด้วยคำสั่งเดิม rpm -Uvh https://yum.puppetlabs.com/puppet5/puppet5-release-el-7.noarch.rpm จากนั้นทำการติตดั้ง puppet agent ด้วยคำสั่ง
“ yum install puppet-agent ”
หลังติดตั้งเสร็จ ทำการแก้ไข config puppet ใน path /etc/puppetlabs/puppet/puppet.conf (ทำแบบเดียวกันกับ node agent อื่น โดยเปลี่ยนชื่อ certname เป็นชื่อ hostname ของ node agent นั้น)
มาที่เครื่อง master แล้วทำการ execute cert ด้วยคำสั่ง
ln -s /opt/puppetlabs/bin/puppet /usr/bin/puppet
จากนั้นสั่ง run เครื่อง agent ด้วยคำสั่ง systemctl start puppet แล้ว execute cert ด้วยคำสั่งเดียวกันที่เครื่อง agent คือ ln -s /opt/puppetlabs/bin/puppet /usr/bin/puppet จากนั้นกลับมาลองเช็คที่เครื่อง master ลองรันคำสั่งเดิม puppet cert list — all อีกที จะเห็นว่ามี cert ของ agent เพิ่มขึ้นมา เพราะตัว agent หลังจาก start มันพยายาม register ตัวเองเข้ามายัง master แต่การที่ master จะคุยกับ node agent ได้เราต้อง sign certificate จากเครื่อง master ไปเครื่อง agent ก่อนด้วยคำสั่ง puppet cert sign puppetagent01.example.com
จากนั้น cd /etc/puppetlabs/puppet เข้าไปเพื่อจะทำการ config file [autosign.conf] ให้ auto sign cert ให้กับทุก domain name ที่เป็น .example.com เพราะเราตั้ง hostname ทั้ง master และ node agent ด้วยชื่อนี้
การสื่อสารระหว่าง master กับ slave จะเป็นแบบ ssl มีการร้องขอ certificate ของกันและกันก่อนทำการส่งข้อมูล
ทีนี้เรามาถึงจุดที่เป็นหัวข้อหลักของเราแล้ว ว่าทำยังไงให้ config. package บน servers หลายๆตัวพร้อมกันได้ ด้วยไฟล์ config. เดียวจาก master
ในการรันสคริปไฟล์หลักสำหรับ agent จะไปดึงไฟล์ชื่อ site.pp มารันออกมาเป็น catalog แล้วส่ง report ตอบกลับ master ไปในกรณีที่รัน config ไฟล์ทุกอย่างสำเร็จเราจะสร้างไฟล์สกุล .pp ใน manifest ซึ่งจะถูกเขียนด้วยภาษา puppest
ในรูปเป็นการ install และ run package ที่ชื่อว่า ntp หรือ network time protocol ซึ่งในโครงสร้างการเขียนไฟล์ DSL จะประกอบด้วย 3 ส่วนคือ Package, Configuration และ Service ส่วน class มีไว้อ้างอิงการทำงานทั้งหมดของ module นี้ ถ้าเกิด node agent ไหน จะเอาไปใช้ ก็ต้องทำการ include ชื่อ class เช่น include ntp ซึ่งจะไปเกี่ยวข้องกับเรื่อง node definition ซึ่งจะมีโครงสร้างการเขียนประมาณนี้
node <ชื่อ node agent> {
class <ชื่อ class ที่ต้องการรันเฉพาะ node นี้>
}
node default {
}
กำหนด node default ในกรณีที่มี node agent มากกว่า 1 ตัวแต่เราประกาศ class ให้ node agent ตัวที่ 1 ตัวเดียว เวลาไปรันเพื่อ complie catalog file manifest ใน node agent ที่ไม่ได้ระบุชื่อว่าให้ทำงาน class อะไร มันจะช่วยให้ไม่เกิด error ขึ้น
ไฟล์นี้จะถูกเขียนที่ master และรันที่ agent ด้วยคำสั่ง puppet agent -tv เป็นคำสั่งสำหรับ complie แล้วติดตั้งบน local ทันที แต่ถ้าใช้ puppet agent -tv — noop (noop ย่อจาก no operation) คือทำการ test อย่างเดียวไม่ติดตั้งและ run service อะไรบนเครื่อง agent หรือบางทีเราอาจจะเห็นคำสั่ง puppet apply file.pp เป็นคำสั่งสำหรับ execute code บนเครื่อง local
ในกรณีที่เราต้องการเช็ค path config ทั้งหมดใน puppet เพื่อจะหาว่า path manifest ที่จะใช้สำหรับสร้างไฟล์ site.app อยู่ที่ไหน เราใช้คำสั่ง
puppet config print
เริ่มแรก cd /etc/puppetlabs/code/environments/production/manifests แล้ว vi ntpdemo.pp แล้วทำการสร้างไฟล์ตามนี้
จากนั้น :wq! ทำการ save แล้วออก แล้วทำการสร้างไฟล์ตัว main ที่ชื่อ site.pp
ในรูปเป็นการประกาศให้ class นี้สามารถนำไปใช้ได้กับ node agent ทั้งสองตัว กลับมาที่ node agent ของเรา ลองรันคำสั่ง puppet agent -tv แล้วทำการเช็ค service ntpd ตามชื่อ service ที่เราตั้งในไฟล์ systemctl status ntpd
จะเห็นว่าเราไม่ได้พิมพ์คำสั่งติดตั้ง ntp อะไรบนเครื่อง agent เลยแต่ service สามารถรันได้แค่สั่ง run complie file ที่ agent