การใช้ Jenkins ในการพัฒนา DevOps

Sorrasak Phonklad
FLOWACCOUNT TECH BLOG
4 min readMar 23, 2022

นิยาม DevOps, DevOps คืออะไร?

คำว่า “DevOps” นั้นเราได้ยินกันมาหลากหลายความหมาย และหลากหลายนิยาม ขึ้นอยู่กับแต่ละองค์กรเอาไปใช้ในบริบทไหน บางองค์กรนั้นนิยามและกำหนดให้ DevOps คือตำแหน่งหรือแผนกซึ่งคอยจัดการในเรื่องของ Infrastructure, Operations, Code Pipeline และอื่นๆที่ Developer ไม่ได้ทำกัน แต่ในที่นี้เราจะขออธิบายในมุมของการนำไปใช้เพื่อพัฒนาเป็นวัฒนธรรมองค์กร

DevOps คือ วัฒนธรรมองค์กรรูปแบบหนึ่ง อยู่ในสายปฏิบัติเดียวกันกับ Agile

DevOps คือ การลดช่องว่างระหว่างทีมพัฒนา Product กับทีมจัดการ Product หรืออธิบายให้คุ้นเคยก็คือทีม Developer และ Operation นั่นเอง

แล้วก่อนหน้าที่จะมี DevOps การทำงานเป็นอย่างไร?

โดยปกติทีม Developer นั้นจะทำการรับ Requirement และพัฒนา Feature ให้ตอบรับกับความต้องการของ Requirement และจะส่งมอบสิ่งที่พัฒนาแล้วให้ทีม Operation จัดการนำของขึ้นระบบและคอยดูแลให้ระบบสามารถให้บริการให้กับผู้ใช้งานได้อย่างราบรื่น

แต่เมื่อเกิดระบบไม่สามารถใช้งานได้ปกติ สิ่งที่เกิดขึ้นคือ Operation จะเป็น 1st Tier ที่รับผิดชอบในการตรวจสอบก่อน ถ้าหากตรวจสอบแล้วทางทีม Operation เห็นว่าสาเหตุไม่ได้มาจากปัญหา Infrastructure หรือ Resource ที่ไม่เพียงพอ Operation ก็จะส่งมอบต่อให้ทางทีม Developer ตรวจสอบในส่วน Code ต่อไป

กรณีเลวร้ายที่สุดคือ ไม่สามารถวิเคราะห์หาสาเหตุที่ชัดเจนได้ การส่งต่อปัญหาให้ระหว่างสองทีมนี้อาจมีได้กลับไปกลับมาหลายรอบทำให้ระยะเวลาการแก้ไขยาวนานเกินจำเป็น

แล้ว DevOps ที่ดีควรจะเป็นอย่างไร?

DevOps ในความหมายขององค์กรเรา คือ การสร้างวัฒนธรรมองค์กรให้ทุกคนเข้าใจตรงกันว่า Feature หรือ Bug ที่ Team พัฒนา Product สร้างขึ้นมานั้น คนที่เข้าใจที่ดีที่สุดก็คือ Team ที่ทำ Product นั่นเอง ดังนั้นการ พัฒนา, ทดสอบ, ตรวจสอบ, แก้ไข หรือการจัดการ Infrastructure ต่างๆนั้น Team Product ควรต้องสามารถมีอิสระในการจัดการเองได้ เมื่อเกิดปัญหาควรจบที่ทีม Product เลยไม่ควรส่งต่อปัญหาให้ทีมต่อไปรับผิดชอบอีก ซึ่งเครื่องมือที่ตอบโจทย์ในการทำสิ่งต่างๆเหล่านี้ได้เป็นอย่างดีนั่นก็คือ Jenkins

Jenkins คืออะไร?

Jenkins คือเครื่องมือประเภท CI/CD (Continuous Integration/Continuous Delivery) ประเภทหนึ่ง ซึ่งหลายคนอาจคุ้นเคยกับการใช้ Jenkins ทำ Code Pipeline เพื่อ build project และ deploy project ขึ้น stage ต่างๆไม่ว่าจะเป็น platform website, mobile และอื่นๆ จัดว่าเป็นเครื่องมือที่สะดวกมากเครื่องมือหนึ่ง ซึ่ง Developer ก็สามารถใช้งานและเข้าถึงเครื่องมือนี้ได้อย่างเข้าใจไม่ยาก

แต่ความจริงแล้ว Jenkins สามารถทำได้มากกว่าการ build และ deploy project!!!

Jenkins กับสายพานการพัฒนาระบบ

ผมขอใช้คำว่า “สายพาน” เนื่องจากการพัฒนาระบบนั้นก็เปรียบเสมือนการประกอบชิ้นงานในโรงงานอุตสาหกรรม โดยผมจะสรุปเป็น Workflow คร่าวๆดังนี้

จากรูปนั้นผมจะสรุปอย่างง่ายๆสมมติในองค์กรเรามี process การพัฒนาไม่ว่าจะ feature หรือแก้ bug ทุกอย่างย่อมเริ่มต้นที่ Coding ส่วนนี้ Developer เป็นคนทำแน่นอนล่ะ ถ้าหากไม่มีเครื่องมือช่วย การดำเนินการนำระบบขึ้นให้ Tester ทดสอบนั้น Developer ต้องทำด้วยตัวเอง ซึ่งหาก Developer มี Change บ่อยหรือต้องแก้ Bug ตาม Tester แจ้งหลายจุด การนำระบบขึ้นก็เป็นส่วนงานที่ค่อนข้างกินเวลาโดยจำเป็น เพราะเวลาเรานำระบบขึ้นนั้นส่วนใหญ่จะทำด้วยวิธีเดิมๆหลายรอบ เช่นเดียวกันกับ Tester หากทำการทดสอบด้วยมืออย่างเดียว การดำเนินการที่ตามมาคือต้อง Test ตาม Case เดิมซ้ำๆ ถ้าหากเป็น Case ที่ซับซ้อน Developer ต้องแก้บ่อย Tester ก็ต้องทำซ้ำ Case เดิมบ่อยๆแน่นนอน ซึ่ง Human Error ก็อาจเกิดขึ้นได้สูงตามมา แค่เริ่มต้นยังไม่ถึงปลายทางของการเอาระบบขึ้นถึง Production ก็ว่าเยอะแล้ว ในส่วนของการ รวมโค้ด นำโค้ดขึ้น Production และตรวจสอบนั้น ยิ่งยุ่งยากเข้าไปใหญ่ หากทีมเรามีคนที่จำกัด

แต่ปัญหาเหล่านี้จะหายไปเมื่อเราสามารถใช้ Jenkins เป็นพระเอกหลักได้หมด หรืออย่างน้อยก็ใช้เป็นตัวช่วยในการทำให้ชีวิตง่ายขึ้นได้ ซึ่ง Jenkins นั้นสามารถนำปัญหาที่ใช้คนทำงานซ้ำๆมาสร้าง Script คำสั่งให้ทำงานแทนคนได้อย่างมีประสิทธิภาพ เราจะมาดูทีละขั้นกันว่าเป็นอย่างไร

Staging Deployment

ในที่นี้หมายถึงการ Deploy ของขึ้นไปบน Stage สำหรับทดสอบ Change ใหม่ๆของเราอาจเป็น Environment แยกจาก Production หรือ Environment เดียวกับ Production ก็ได้ (บางที่เรียกว่า Pre-Production หรือบางที่เรียก UAT) โดยเราสามารถเขียน Jenkinsfile เข้าไปใน project ที่เราต้องการได้เลย จากนั้นหาก repository เรามีการผูกกับ Jenkins อยู่แล้ว Jenkins จะสามารถ Hook และ build ตาม step ใน Jenkinsfile ที่เราเขียนขึ้นได้ทันที

จากตัวอย่างสมมติให้เป็น web app project ที่รันอยู่บน container orchrestration ของ aws ที่เรียกว่า ECS ดังนั้น step จึงมี

- checkout สั่งให้ Jenkins checkout code project มาใน agent

- docker build สั่งให้ Jenkins run build Dockerfile ใน project

- docker push สั่งให้ Jenkins push image ที่ได้จากการ build ไปยัง container repository บน aws ecr โดยต้อง login docker session ให้สามารถ push ไปยัง aws ecr ได้ซะก่อน

- ecs update สั่งให้ ecs service นั้นมีการ pull image ที่เรา push ขึ้นไปใหม่เพื่อให้ web app ที่รันอยู่บน ecs นั้น update

จะเห็นได้ว่าการเขียน Jenkinsfile เพื่อนำ Code ขึ้น Site Test นั้นค่อนข้างเรียบง่าย กล่าวคือเรานำ app เราขึ้นไป Site Test อย่างไร Command ต่างๆนั้นสามารถนำมาเขียนเป็น Step การขึ้นระบบบน Jenkinsfile ได้อย่างตรงไปตรงมา ซึ่งการทำ Staging Deployment ด้วย Jenkins นั้นช่วยให้ Developer ลดงานการ build และนำขึ้น Site Test ไปทำให้มีเวลาเหลือไปพัฒนาอย่างอื่นได้

Regression Testing

เป็นกระบวนการทดสอบระบบตั้งแต่ระบบหน้าบ้านจนถึงระบบหลังบ้าน กล่าวคือทดสอบการใช้งานจริงตาม Use Case ต่างๆ ซึ่งส่วนใหญ่ Tester จะเป็นคนทำส่วนนี้ แต่เราก็สามารถให้ Jenkins ช่วยทำงานส่วนนี้ได้ เพื่อลดภาระ Tester ในการ Test Use Case ซ้ำๆ ซึ่งคนมีโอกาสผิดพลาดสูงกว่าการใช้เครื่องมือ

ในส่วนนี้เราสามารถเลือกได้ว่าจะทำในกระบวนการเดียวกันกับ Staging Deployment เลยก็ได้ หรือแยกมาทำต่างหาก ซึ่งในส่วนผม แนะนำให้แยกต่างหากเนื่องจากแต่ละ Workflow ไม่ควรผูกกันจนเกินไป อาจทำให้ Workflow เกิดคอขวดได้ โดยตัวอย่างการเขียน Regression Test จาก Jenkinsfile นั้นมีตัวอย่างดังนี้

ตามตัวอย่างจะเป็นการใช้ repository ที่มี code regression test เขียนขึ้นจาก Cypress โดยใช้เครื่องมือ nrwl monorepo เป็นตัวจัดการ project ภายใน repository อีกที ทำให้การรันคำสั่ง build test นั้นเป็นเรื่องง่าย

- checkout สั่งให้ Jenkins checkout code project มาใน agent

- dependencies install สั่งให้ Jenkins ติดตั้ง package ที่จำเป็นต่อการรัน project

- cypress testing สั่งให้ Jenkins run Cypress regression test ผ่าน command ของ nrwl

จะเห็นได้ว่า หากเรามีการนำเครื่องมือมาช่วยในการเขียน regression test บวกกับการใช้ Jenkins นั้นสามารถลดภาระ Tester ได้ดี และสามารถช่วยร่นระยะเวลาในการทดสอบไปได้มากทีเดียว

Code Integration

เป็นกระบวนการรวม Code จาก Change ของ Developer เข้า Branch หลัก อย่าง Master หรือ Main เพราะเมื่อคนอื่นๆนำไปใช้จะได้ทราบว่ามีผลกระทบต่อ Feature ที่ทีมตนทำอย่างไร เพราะในองค์กรใหญ่ๆเป็นไปได้ว่า 1 repository นั้นสามารถมีได้มากกกว่า 1 team ที่ใช้ในการพัฒนา และบ่อยครั้งก็มักจะ conflict กันเอง ดังนั้นการทำ Code Integration ที่ดีนอกจากจะใช้การ Approve ด้วยตาแล้ว การใช้ Jenkins ช่วยทดสอบในแง่ของการ Build หรือ Unit Test ก็มีประโยชน์อย่างมาก ซึ่งช่วยให้ลดความผิดพลาดหรือ Conflict ระหว่างทีมได้ ซึ่งตัวอย่างการเขียน Jenkinsfile เพื่อ Hook จากการทำ Pull Request มีดังนี้

ในการเขียน Jenkinsfile เพื่อทำการรวม Code เข้า Branch หลักนั้น ส่วนใหญ่เราจะทำในจังหวะ Pull Request (หรือบางที่เรียกว่า Merge Request) ซึ่งขั้นตอนนี้ เราต้องเขียน if ครอบในส่วนของ Step Jenkinsfile เพื่อกรองชื่อ TAG ออกมา เนื่องจาก Pull Request นั้นจะมี format ขึ้นต้นด้วย PR จึงสามารถเขียน regex check ได้ดังนี้ `/^PR-\d+$/` จากนั้นภายในจะเป็นการ checkout project มาทำการ build และ test ภายใต้ command nrwl ซึ่งช่วยให้การเขียน command สั่ง step แต่ละส่วนง่ายขึ้น

Production Deployment

การ Deployment Production นั้นค่อนข้างเป็นส่วนที่สำคัญ หากเราทำการ Deploy ขึ้น Production ด้วยมือนั้นความผิดพลาดย่อมสูง และเสี่ยงผิดพลาดสูงด้วย แต่การเปลี่ยน Script การ Deploy จากมือไปใช้เครื่องมือช่วย ความกดดันจากการขึ้นระบบจะหายไป

ในส่วนนี้การขึ้นระบบจะไม่ขออธิบาย เนื่องจาก Script การเขียน Jenkinsfile นั้นจะเหมือนกันกับ Staging Deployment (แค่เปลี่ยนที่ขึ้นนั่นเอง) เพียงแต่ในการนำระบบขึ้นนั้น ข้อแนะนำควรมีการ tag release ที่ branch หรือ commit ที่นำขึ้นด้วย เพื่อสะดวกต่อการ revert กลับในกรณี change มีปัญหา

Health Check

สุดท้ายส่วนสำคัญคือการทำ Health Check ระบบที่เราทำขึ้นไปจะไม่มีความหมาย ถ้าตรวจวัดไม่ได้ว่ามันยังทำงานปกติหรือไม่ เครื่องมือหนึ่งที่ช่วยตอบโจทย์นี้ได้คือเครื่องมือง่ายๆอย่าง Postman หรือเราอาจใช้ Cypress อย่างตอนทำ Regression Test มาช่วยก็ได้เหมือนกัน ทั้งนี้ Jenkins สามารถตั้งค่าการทำงานให้เป็น Cron Job ให้สามารถรัน Script ได้เป็นช่วงเวลา ซึ่งเราสามารถสั่งให้รันตรวจสอบระบบเราบน Production ได้ถี่ตามที่เราต้องการ

นอกจากที่กล่าวมา Jenkins สามารถทำอย่างอื่นได้ไหม?

จากที่กล่าวข้างต้น Jenkins นั้นสามารถทำได้ทุกอย่างที่เราสามารถ run based on cli หรือ command line ดังนั้น process อะไรก็ตาม เราสามารถใช้ Jenkins เป็นตัวช่วยได้หมด เช่น

- การสร้าง Infrastructure Pipeline ให้สามารถ Generate Stack คล้ายๆกันได้ตามต้องการ

- การสร้าง Script ตรวจสอบสถานะเครื่องและรายงานผ่าน Email

- การสร้างระบบแจ้งเตือนผ่าน Line กรณีพบปัญหาจากการ Health Check ระบบ

และอื่นๆอีกมาก ขึ้นอยู่กับ Workflow ของแต่ละที่และการนำไปประยุกต์ใช้ ข้อดีของ Jenkins ที่เหนือกว่าจ้าวอื่นๆคือ Community ที่แข็งแกร่งและ Plugin ที่หลากหลาย ดังนั้น ไม่ว่าคุณจะทำอะไร และพบว่างานนั้นมีการทำงานที่ซ้ำซาก ลองใช้ Jenkins ช่วยทำงานเหล่านั้นแทนดูครับ

หากชอบบทความของ FlowAccount Tech Blog อย่าลืมกด Follow นะครับ ติดตามบทความอื่นจาก FlowAccount Tech Blog ได้ที่ https://medium.com/flowaccount-tech

Open Positions jobs available on FlowAccount > https://flowaccount.com/en/jobs

--

--