CI/CD ฉบับย่อ พร้อมยกตัวอย่าง Jenkins pipeline

Siripoom Luengsaard
5 min readMar 29, 2024

--

https://blog.cloudhm.co.th/wp-content/uploads/2021/03/ci-cd.png

รู้จักกันก่อนว่า CI/CD คืออะไร CI/CD ย่อมาจาก Continuous Integration / Continuous Deployment / Delivery

CI (Continuous Integration) คือการรวมโค้ดจาก Developer และทำการทดสอบโดยใช้ Test script เพื่อตรวจสอบว่าโค้ดที่รวมกันแต่ละส่วนต้องเข้ากันและไม่เกิดข้อผิดพลาดก่อนการรวมโค้ด เครื่องมีที่ใช้ในการทำ CI

  1. Jenkins
  2. Bitbucket pipeline
  3. AWS codePipeline

ซึ่งการเขียน Pipeline ของ CI/CD ขึ้นอยู่กับโครงสร้าง Project นั้นๆ DevOps จะต้องวิเคราะห์และหาเครื่อมือในการทดสอบโค้ดที่เหมาะที่สุดของแต่ละ Project นั้น และเขียน Pipeline ตามความเหมาะสม

เครื่องมือที่ใช้ในการตรวจสอบ code quality, security, static analysis

  1. Sonarqube
  2. Coverity
  3. Semgrep
  4. Embold

CD (Continuous Deployment) คือการรวมโค้ดตรวจสอบโค้ดทำทุกอย่างเสร็จจาก CI และจะทำการ Deploy ขึ้น Server จริงโดยอัตโนมัติทั้งหมด

CD (Continuous Delivery) แตกต่างจาก Continuous Deployment คือจะไม่ Deploy ขึ้น Server จริงอัตโนมัติแต่ DevOps สามารถ Configuration ได้ว่าอยากให้ส่งไปที่ไหน ยกตัวอย่างเมื่อ CI process ผมเสร็จแล้ว ผมได้ Image ของ app มา ผมอยาก push image ขึ้น AWS ECS เพื่อที่จะเก็บ image ไว้แล้วทำอะไรสักอย่างเป็นต้น

เครื่องมือที่ใช้สำหรับการทำ CD

  1. Argo CD
  2. Harness
  3. Jenkins X

ทำไม CI/CD ถึงสำคัญ ?

CD/CD เป็นเครื่องมือที่จะทำการ automate ทั้งหมดอย่างเช่น การอัพเดทโค้ดที่มากจาก commit เข้าไปสู่ production โดยอัติโนมัติและ down time จะมีได้น้อยจึงทำให้การ release codeใหม่สามารถทำได้เร็วกว่าเดิม ตัวอย่าง

เมื่อก่อนถ้าไม่มีการทำ CI/CD จะมี admin คนหนึ่งที่จะต้องรับโค้ดมาจาก Repository และทำการ build, test, check code quality, deploy ด้วยตัวเขาเองซึ่งคนเราก็ต้องมีเวลาพักผ่อนใช่มั้ยละครับ ถ้าเกิดมี Dev คนหนึ่งเขาอยู่ดีๆแก้บัคของ release ได้ตอนดึกๆหรือไม่ได้อยู่ในเวลาทำงาน เขาอยากจะ test และ deploy เขาจะต้องรอให้ admin คนนั้นมาทำให้ซึ่ง work flow จะเป็นอะไรที่ช้ามากๆ

และนี่เป็นรูปภาพตัวอย่างของกระบวนการ CI/CD

https://github.com/msssrp/Jenkins-Zero-To-Hero/tree/main/java-maven-sonar-argocd-helm-k8s

ต่อไปผมจะพาเขียน CI pipeline โดยใช้ Jenkins ที่อยู่บน AWS EC2 โดยจะใช้ agent เป็น Docker นะครับ

ให้เราทำการ Login / Register Aws เพื่อที่จะ Launch EC2 เป็น Visual machine นะครับ

ผมใช้เป็น ubuntu นะครับและก็เป็น t2.micro type

ตอนนี้ EC2 instance ของเราก็พร้อมใช้งานแล้วนะครับ

จากนั้นให้เรา Connect เข้า EC2 Jenkins-Demo ของเราผ่าน SSH ครับ Key สำหรับการ Connect จะได้มาตอนที่เรา Initialize Instance ของเรานะครับ

และตอนนี้ผมก็ Connect เข้ามาที่ตัว EC2 instance ของผมได้แล้วจากนั้น ให้อัพเดท ubuntu ให้เรียบร้อยแล้วก็ติดตั้ง Java SDK ด้วยนะครับเพราะเป็น pre-required สำหรับการติดตั้ง Jenkins

sudo apt update
sudo apt install openjdk-11-jre

หลักจากติดตั้งเสร็จแล้วก็เช็ค java sdk version ดูหน่อยนะครับ

java --version

ต่อไปผมจะทำการติดตั้ง Jenkins นะครับ โดยก็อป shell script ไปวางลงใน terminal ของเราได้เลยครับ

curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee \
/usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
https://pkg.jenkins.io/debian binary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins

ค่า Default ของ Jenkins เราจะไม่สามารถเข้าถึงได้จาก Network ข้างนอกนะครับเราต้องไปตั้งค่า Inbound ของตัว EC2 ของเราก่อนนะครับ

เพิ่ม inbound traffic ไปนะครับจะเพิ่มแค่ port 8080 ก็ได้แต่ผมจะ Allow ให้เข้าถึง port ทั้งหมด

ทีนี้ก็ให้ทำการ Login เข้าตัว Jenkins ของเราผ่าน URL

http://[ip EC2 ของตัวเอง]:8080

พอเราทำทุกขั้นตอนหมดแล้ว เมื่อเราเข้าไปที่ url นี้เราจะต้องเจอกับหน้า Login ของ Jenkins ตามนี้ครับ

หลังจากนั้นให้เรา run command นี้เพื่อ copy password นะครับ

sudo cat /var/lib/jenkins/secrets/initialAdminPassword

ให้เรา copy password ที่ได้มาแล้วไปวางในหน้า Jenkins ของเราได้เลยครับ

หลังจากนั้น Jenkins จะถามเราว่าจะติดตั้ง plugin แบบไหน

  1. Suggested plugins
  2. Manual plugins

ผมจะเลือกให้ Jenkins install plugins แบบ Suggested นะครับ

หลังจาก install plugins เสร็จแล้ว Jenkins จะให้เราสร้าง Admin user ไว้ login ตัว Jenkins ของเรานะครับ เราสามารถใส่อะไรไปก็ได้นะครับเอาที่จำได้พอ

ต่อมา Jenkins จะเลือกให้เรา config ตัว url ที่จะเข้าถึง Jenkins ของเรา เราจะแก้ไขก็ได้ไม่แก้ก็ได้นะครับ

และเราก็ติดตั้ง Jenkins สำเร็จหมดแล้ว ง่ายมั้ยครับ

ต่อมาผมจะทำการติดตั้ง Docker pipeline plugin ใน Jenkins ทำตามขั้นตอนนี้ได้เลยครับ

  1. Login Jenkins
  2. ไปที่ Mange Jenkins
  3. ตรงหัวข้อ system configuration เลือก plugins
  4. กดเลือกเมนู Available plugins
  5. ค้นหา Docker Pipeline กดเลือก Plugin และกดปุ่ม Install

รอให้ติดตั้งเสร็จ Jenkins จะทำการ Restart ตัวเอง

ทีนี้เราก็จะมาติดตั้ง Docker slave กันนะครับ

run command นี้เพื่อติดตั้ง Docker slave ได้เลยครับ

sudo apt update
sudo apt install docker.io

ต่อมาเราจะ Grant jenkins และ ubuntu user permission ให้ใช้ Docker deamon ได้นะครับ

sudo su - 
usermod -aG docker jenkins
usermod -aG docker ubuntu
systemctl restart docker

หลังจากทำเสร็จแล้วให้ restart jenkins นะครับ

http://[ec2 ip]:8080/restart

ต่อมาผมจะพาไปเขียน pipeline แรกของเรากัน โดยให้คลิกที่ปุ่ม new item ของหน้าแรก jenkins นะครับ

จากนั้นให้เราเลือก pipeline ตั้งชื่อให้เรียบร้อยแล้วกด ok ผมจะไม่ลงรายละเอียดเกี่ยวกับแต่ละเมนูนะครับสามารถหาดูได้ตาม youtube เลยครับ

หลังจากนั้นเราก็สามารถใส่ pipeline script ของเราได้เลย

pipeline {
agent {
docker { image 'node:16-alpine' }
}
stages {
stage('Test') {
steps {
sh 'node --version'
}
}
}
}

จากนั้นให้กด save นะครับ Jenkins จะ redirect เรามาที่หน้า job ของเรา

ทีนี้เราลองกด build ดูครับจะเกิดอะไรขึ้น

FAILURE ครับ 555555 เพราะว่า Jenkins เราไม่มี permission ของ docker deamon ครับเลยเกิด Error make sure นะครับว่าเรา Grant user permission ถูกต้อง

ผมลอง build อีกทีครับ

Success ครับ ผมจะได้ log version ของ node เราตาม script ที่เราเขียนเลยครับ

เราสามารถ run pipeline แบบ multi agent ได้นะครับนี่คือตัวอย่างโค้ด

pipeline {
agent none
stages {
stage('Back-end') {
agent {
docker { image 'maven:3.8.1-adoptopenjdk-11' }
}
steps {
sh 'mvn --version'
}
}
stage('Front-end') {
agent {
docker { image 'node:16-alpine' }
}
steps {
sh 'node --version'
}
}
}
}

ส่วนข้อดีของการใช้ Docker pipeline plugin นี่ดีมากครับเพราะว่าเมื่อเรา run pipeline ของเรา docker จะทำการสร้าง container เพื่อที่จะใช้ run stage นั้น และเมื่อ stage นั้น run success docker จะทำการ terminate container ของ stage นั้น ซึ่ง approach นี้จะช่วย save cost, save load latency, save time ของเรามากขึ้นครับ ซึ่งถ้าเราลองเอา pipeline multi stage ตัวนี้ไป build ดูแล้วไปที่ terminal ของเรา ให้ลอง spam docker ps ดูเรื่อยๆเราจะเห็นได้เลยว่า docker จะสร้าง stage Back-end และเมื่อ stage นั้นทำงานสำเร็จ Docker จะ terminate container นั้นและดำเนินการ stage ต่อไปต่อเลย

ซึ่ง blog นี้ผมพูดในเรื่องของ CI/CD คืออะไรและยกตัวอย่างการเขียน Pipeline โดยใช้ Jenkins และใช้ Docker as agent ให้ดูนิดหน่อยหวังว่าจะมีประโยชน์ครับ

ความรู้ทั้งหมดนี้ผมได้มาจากช่อง Abhishek.Veeramalla ผมมองว่าอธิบายได้ง่ายและเข้าใจได้ง่ายมากครับ

--

--

Siripoom Luengsaard
Siripoom Luengsaard

Written by Siripoom Luengsaard

Dev with affection in cloud. Passionate about crafting efficient solutions. (BSc.) in Software Engineering (SE) Nakhon Pathom Rajabhat University

No responses yet