หลังจาก Blog ตอนก่อนหน้าทุกคนคงเข้าใจ Concept ของ Jenkins Controller and Agents Architecture และประโยชน์ของมัน คราวนี้มาลอง Setup กันจริงๆครับ
สรุป Step ขั้นตอนคร่าวๆ
- Jenkins Agent
- กำหนดให้เครื่อง Agent (Windows) รองรับการ SSH แบบแลก Key และเตรียม เตรียม Path temp
- ที่เครื่อง Agent (Windows) เอาไว้ ทำหน้าที่เป็น Workspace เวลาที่เครื่อง Controller มาสั่ง Node Agent เข้ามาทำงาน
- Jenkins Controller
- เพิ่ม Agent (Windows) มาเป็น Node หนึ่งของเครื่อง Controller (CentOS Stream)
- แก้ไข Pipeline
- ปรับ Jenkins File ให้รองรับ Jenkins Controller and Agents Architecture
- ทดสอบ Build
Step : Jenkins Agent
- ในที่นี้จะเป็นจะเอา OS อะไรก็ได้ครับ ที่มันลง Jenkins ได้ก็พอ แต่อย่าลืม กำหนด JAVA_HOME ให้เรียบร้อยด้วยครับ ถ้าจำไม่ได้ว่าเคย SET JAVA_HOME ยังลองดูจาก Blog นี้ได้เลยครับ
- จากนั้นกำหนด ssh แบบแลก key เก็บ Private Key ไว้ด้วยนะครับ ต้องไป Add Credential ใน Jenkins Controller ต่อ
- เตรียม Path temp ที่เครื่อง Agent (Windows) เอาไว้ ทำหน้าที่เป็น Workspace เวลาที่เครื่อง Controller มาสั่ง Node Agent เข้ามาทำงาน ในที่นี้เตรียม Folder C:\JENKIN_AGENTS
C:\JENKIN_AGENTS
Step : Jenkins Controller
- เพิ่ม Agent (Windows) มาเป็น Node หนึ่งของเครื่อง Controller
- เพิ่ม Private Key ของเครื่อง Agent ที่ได้จาก (Step : Jenkins Agent)
- เข้าไปที่ Manage Jenkins > Manage Credentials
- เลือก Jenkins เพื่อเข้า System > Global credentials
- จากนั้นกด Add Credentials
- กำหนดค่า ดังนี้
- Kind : SSH Username with Private Key
- ID / Description เป็นชื่อที่เอาไว้ใช้ในตัว Jenkins จะถูกเอาไปใช้ในตอนเพิ่ม Agents ให้ Jenkins Controller
- Username : SSH Username ของเครื่องปลายทาง
- Private Key เลือก Enter Directly และเปิด Private Key ด้วย Text Editor จากนั้น Copy ค่ามาแปะ
- Passphrase : ใส่ก็ต่อเมื่อ Private Key ต้องใช้ด้วยครับ
- จากนั้นกด Create ครับ
- เพิ่ม Agents ให้ Jenkins Controller รู้จัก
- เข้าไปที่ Manage Jenkins > Manage nodes and clouds เลือก New node
- จากนั้นลองมากำหนดค่าที่ละส่วน ดังนี้ครับ
- ส่วนแรก กำหนดชื่อ Node และลักษณะของ Node ของผมจะเลือกเป็น Permanent Agent เพราะต่อกับตัว Controller ตลอดเวลาครับ จดชื่อ Node ไว้นะครับ เผื่อต้องไป Lock ใน JenkinFile ในบางกรณีต่อไปครับ
- ส่วนที่ 2 กำหนดค่าของ Node
- โดยมีการกำหนดค่า ดังนี้
- Number of Executor : จำนวน Task ที่เครื่อง Agents พร้อมรับ ในที่นี้ ผมกำหนดไป 4 เลย
- Usage : ผมเลือกแบบ Use This Node as much as possible ส่วนอีกตัวเลือก เดี๋ยวผมเขียน Blog แยกดีกว่า เริ่มยาวและ 555
- Remote Root Directory : Path ของเครื่อง Agents ที่จะทำหน้าที่เป็น Workspace เวลามีการสั่งงานจาก Controller ครับ ปกติเวลา SSH เข้าไปจะอยู่ที่ home (Windows จะเป็น C:\Users\<<SSH User>>
- ถ้า Windows ที่ต่ำกว่า Windows 11 แนะนำให้กeหนดที่ Drive C นะ อย่างผมใส่ C:\JENKIN_AGENTS เพราะมัน cd ข้าม Drive ไม่ได้ ไม่งั้นตอน Run จะไปเจอ Error Unable to access jarfile remoting.jar - Using Jenkins - Jenkins
- ส่วนที่ 3 กำหนดข้อมูลสำหรับ Authentication เข้าไปยัง Agents โดยเลือกแบบ Lunch Agents via SSH
- โดยมีการกำหนดค่า ดังนี้
- Host : IP หรือ DNS ของเครื่องปลายทาง
- Credential : ข้อมูลการเข้าเครื่อง อันนี้เลือกที่ Add ไว้ตาม Private Key ที่ใส่ใน Step เพิ่ม Private Key ของเครื่อง Agent
- Host Key Verification Strategy : ตอนนี้ ผมจะเลือกแบบ Non Verifying Verification Strategy (แบบนี้จะมีปัญหาด้าน Security เพราะ มีความเสี่ยงที่จะโดน Man-In-Middle Attack ได้ครับ)
- NOTE: แบบที่ดีที่สุด คือ Known Host File Verification Strategy
- จากนั้นเป็น Option อื่นๆ ถ้าเราลง Plugin อื่นๆไว้ มันจะขึ้นมาด้วย อย่าง Node-Base Security
- เพิ่ม Config ที่จำเป็นจาก Agents ที่ Controller
- ตรวจสอบ Plugin / Config พวก Environment Variable จากเครื่อง Agents ว่ามีอะไรที่จำเป็นต้องการใช้งานบ้าง และมาติดตั้งเพิ่มที่เครื่อง Controller ครับ
- สำหรับตัว Environment Variable ถ้ามันใช้งานแค่เฉพาะ Node นั้นๆ สามารถ Config เฉพาะ Node ได้นะครับ ดังรูป
Step : แก้ไข Pipeline กรณีต้องการ Lock Agent มาทำหน้าที่ Build
- ที่ต้องมาปรับ เพราะจุดประสงค์ของเรา คือ Jenkins Controller / Agents เพื่อทำหน้าที่เป็น Single Command Center ครับ เพื่อสั่ง Build C# WindowsApp (.NET 4.7.2 ) / WebAPI (.NET Core 3.1) โดยเฉพาะงานBuild C# WindowsApp (.NET 4.7.2 ) มันทำได้เฉพาะเครื่องที่เป็น Windows ครับ
- ดังนั้น เพื่อป้องกันปัญหาว่าสั่ง Build ไปแล้วตัว Controller มันไปส่งงานที่ Agent นั้นไม่สามารถทำได้ทำ แล้วตี Fail กลับมาครับ
- ของเดิม ใน Jenkinfile ไม่มีการกำหนด Agent เลยครับ
pipeline { agent any stages { stage('s1') { steps{ //your step } } } }
- ของใหม่ Lock ให้งานที่ถูกสั่งจาก Controller ถูก Assign เข้ามาที่ Agent ที่รองรับงานนั้นๆ โดยการเพิ่ม Label เข้าไป
pipeline { agent{ label 'jenkins-dotnet' } stages { stage('s1') { steps{ //your step } } } }
- หลังจากแก้ JenkinFile เรียบร้อยแล้ว ที่เครื่อง Jenkin Controller เรามาสร้าง Task ขึ้นมาครับ โดยกำหนดเป็น Pipeline และกำหนดตั้งค่า Parameter / Repository / JenkinFile ให้เรียบร้อยครับ
Step : ทดสอบ Build
- ทดสอบ Build จากการทดสอบสั่ง Build จาก Controller มาสั่งที่ Agents พบว่ามันทำงานได้จริงนะ แต่ที่ตัว Jenkins ของ Agents มันจะไม่เห็นงานชิ้นนี้ครับ แต่ CPU วิ่งเต็ม จาก MSBuild มันทำงานครับ
แล้วถ้าต้องการกลับมา Build ที่เครื่อง Agents ตรงๆ ทำอย่างไร ?
- Manage Jenkins > Manage Nodes and Clouds คลิกที่ Built-In Node
- กดที่ Configure แก้ไข Label ให้ตรงกับชื่อ Agent ที่กำหนดไว้กับเครื่อง Controller
- จาก Step ข้างต้นมีกำหนดไว้ที่เครื่อง Controller Agent มีชื่อ jenkins-dotnet เรามาแก้ Label ของ Built-In Node ให้มีค่า jenkins-dotnet ครับ
สรุป
- ตอนนี้เรามีตัว Jenkins Controller ที่สามารถสั่งงานไปยัง Jenkins Agents (Windows) ได้ และมีการปรับ JenkinsFile นิดหน่อย เพื่อให้มันเลือก Agents ที่ได้ถูกต้องครับ
- เดี๋ยวหลังจากลองใช้ไปประมาณสัก 1-2 เดือน เดี๋ยวผมจะมาลองเขียน Blog สรุปปัญหาที่มันเกิดขึ้นครับ
- สำหรับใครที่อยากลองทำ Jenkins Controller กับ Agents ค่ายอื่นๆ เช่น Linux / MacOS สามารถลองนำ Blog นี้ไปปรับใช้ได้ครับ โดยมีขั้นตอนสำคัญ
- Jenkins Agent - Config SSH + เตรียม Path temp
- Jenkins Controller - เพิ่ม Private Key ของเครื่อง Agent / Add Agents เพิ่มเข้ามา โดยมีช่องทางการสื่อสารแบบ ssh และสร้าง Job สำหรับ Build ขึ้นมาครับ
Reference
Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.