Giới thiệu DevOps
Xem thửTình huống: 2 giờ 7 phút sáng thứ Bảy, gdev-api trả lỗi 500
Đây là một tình huống dựng cho bài học, các con số là số của câu chuyện, không phải thống kê thật. Đội GDev phát hành gdev-api sáu tuần một lần. Minh viết mã, hợp nhất (merge) vào nhánh release rồi chuyển một phiếu yêu cầu (ticket) cho đội vận hành. Tối thứ Sáu, Hà bên vận hành làm theo một trang wiki 23 bước để đưa bản mới lên production.
Lúc 2 giờ 7 phút sáng thứ Bảy, giám sát báo gdev-api trả lỗi 500. Hà gọi Minh dậy. Minh nói: "Trên máy em chạy bình thường." Hà nói: "Chị chỉ làm đúng theo wiki." Bản phát hành này gộp 12 thay đổi của sáu tuần làm việc, nên không ai biết thay đổi nào gây lỗi. Cuối cùng cả hai mất 5 giờ để tìm ra, và sáng thứ Hai họ họp để xem lỗi thuộc về ai.
Lỗi kỹ thuật chỉ là một phần. Phần lớn thiệt hại đến từ cấu trúc: người viết mã được đánh giá bằng số tính năng giao ra, người vận hành được đánh giá bằng thời gian hệ thống không sập. Hai mục tiêu đó va nhau đúng ở thao tác thay đổi. Mỗi bên tự bảo vệ phần của mình bằng cách làm ít thay đổi hơn, nên các thay đổi dồn lại thành một cục lớn và rủi ro hơn.
DevOps là câu trả lời cho cấu trúc này. Sau bài này bạn làm được các việc sau:
- Định nghĩa DevOps là văn hóa cộng với thực hành, và chỉ ra ba thứ nó không phải là.
- Giải thích vì sao thay đổi nhỏ và thường xuyên an toàn hơn một bản phát hành lớn.
- Tự tính thời gian từ commit đến phát hành (lead time) và tần suất phát hành từ lịch sử Git, và kể tên năm chỉ số DORA.
Bạn không cần kiến thức kỹ thuật nào ngoài việc gõ được lệnh trong terminal. Phần lab dùng bash và Git.
Ba mô hình cần nhớ
- Bức tường giữa Dev và Ops đến từ động cơ lệch nhau, không phải từ con người xấu: DevOps gỡ bức tường bằng trách nhiệm chung, tự động hóa và cùng đo một thứ.
- Thay đổi nhỏ chảy nhanh và dễ sửa: một lô 1 thay đổi thì lỗi chỉ có một nghi phạm, một lô 12 thay đổi thì có 12.
- Cái gì không đo được thì không biết có tốt lên không: năm chỉ số DORA đo tốc độ và độ ổn định của việc giao phần mềm.
Chuẩn bị môi trường lab
Lab không tạo tài nguyên đám mây và không tốn tiền. Bạn cần bash, git và lệnh date của GNU (có sẵn trên Linux, WSL và Git Bash trên Windows; macOS dùng date kiểu BSD nên chạy lab trong Linux hoặc WSL). Kiểm tra nhanh:
bash --version | head -n 1
git --version
date --version | head -n 1
Kết quả minh họa (phiên bản của bạn có thể khác):
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
git version 2.25.1
date (GNU coreutils) 8.30
Nếu date --version báo lỗi, bạn đang dùng date kiểu BSD và nên chuyển sang Linux hoặc WSL cho bài này.
Mô hình 1: bức tường và cách gỡ nó
Trước khi xem sơ đồ, hãy dự đoán: trong câu chuyện ở đầu bài, có bao nhiêu chỗ mà công việc phải nằm chờ một người khác?
Đang tải sơ đồ…
Cách đọc sơ đồ:
- Có hai chỗ chờ: phiếu nằm trong hàng đợi của Ops, và bản phát hành nằm chờ đến kỳ release tiếp theo. Thời gian chờ này không tạo ra giá trị nào cho người dùng.
- Nhánh
yesquay về chờ kỳ sau, nghĩa là ngay cả khi mọi thứ tốt, thay đổi của Minh vẫn đến tay người dùng chậm hàng tuần. - Nhánh
nolà vòng lặp tệ nhất: người bị gọi dậy không phải người hiểu mã, và cuộc tranh luận "lỗi do mã hay do triển khai" quay ngược lại hàng đợi mà chưa ai học được gì.
Kết luận: vấn đề nằm ở các điểm bàn giao (hand-off), không nằm ở một người cụ thể. DevOps nhắm vào các điểm bàn giao đó.
DevOps là văn hóa cộng với thực hành, không phải một chức danh hay một bộ công cụ. Văn hóa là việc cả hai phía cùng chịu trách nhiệm cho kết quả cuối cùng: phần mềm chạy đúng trước người dùng. Thực hành là những việc cụ thể làm cho trách nhiệm chung đó khả thi, như tự động hóa kiểm thử và triển khai, cấu hình lưu trong Git, giám sát chung.
Khung CALMS là cách phổ biến để kiểm tra một đội đã có đủ các mặt hay chưa. Đây là khung do cộng đồng DevOps đặt ra, thường được gắn với Jez Humble, không phải một tiêu chuẩn chính thức.
| Chữ cái | Nghĩa | Trong GDev nó trông như thế nào |
|---|---|---|
| C, Culture | Văn hóa trách nhiệm chung | Minh và Hà cùng xem dashboard của gdev-api và cùng nhận cảnh báo |
| A, Automation | Tự động hóa việc lặp lại | 23 bước wiki được thay bằng pipeline gdev-ci |
| L, Lean | Giảm chờ đợi và lượng việc dang dở | Thay đổi nhỏ, không có hàng đợi phiếu giữa hai đội |
| M, Measurement | Đo bằng dữ liệu | Theo dõi lead time và tỉ lệ lỗi của từng lần deploy |
| S, Sharing | Chia sẻ kiến thức | Runbook, postmortem không đổ lỗi, ai cũng đọc được |
Điều DevOps không phải:
| Hiểu lầm | Thực tế |
|---|---|
| "Mua Jenkins hay GitHub Actions là đã làm DevOps" | Công cụ chỉ là một phần của chữ A. Nếu Minh và Hà vẫn đổ lỗi cho nhau thì chữ C vẫn trống |
| "DevOps là một chức danh, tuyển một DevOps engineer là xong" | Chức danh này có tồn tại trên thị trường, nhưng nếu chỉ một người gánh việc triển khai thì bạn chỉ dời bức tường, không gỡ nó |
| "DevOps là một đội làm hết mọi thứ" | Một đội trung gian mới thành thêm một điểm bàn giao. Mục tiêu là mỗi đội sản phẩm tự làm được phần lớn việc của mình |
Mô hình 2: cùng một lỗi, hai cách phát hành
Sơ đồ ở trên cho thấy cấu trúc bàn giao. Animation dưới đây cho thấy điều sơ đồ không cho thấy: thời gian trôi bao lâu, và sự cố khó sửa đến mức nào khi lô thay đổi lớn. Cả hai trường hợp đều có một thay đổi gây lỗi 500. Trước khi bấm, dự đoán: khi lỗi xuất hiện, bên nào mất ít thời gian hơn để khôi phục, và vì sao?
Các con số lead time lấy từ phần lab bên dưới, còn thời gian khôi phục là số dựng cho minh họa.
Đang tải Animation…
Vì sao lô nhỏ tốt hơn? Cuốn The Phoenix Project và The DevOps Handbook của Gene Kim cùng các tác giả gọi nguyên lý nền của DevOps là Three Ways (ba con đường):
| Con đường | Ý chính | Ví dụ trong câu chuyện của GDev |
|---|---|---|
| First Way, Flow (dòng chảy) | Tối ưu cho cả hệ thống từ ý tưởng đến người dùng, không tối ưu cho một đội riêng lẻ | Bỏ hàng đợi phiếu giữa Dev và Ops, thay bằng pipeline chung |
| Second Way, Feedback (phản hồi) | Rút ngắn và khuếch đại vòng phản hồi | Cảnh báo tới Minh sau 2 phút thay vì tới Hà sau cả tuần |
| Third Way, Continual Learning and Experimentation (học hỏi và thử nghiệm liên tục) | Văn hóa chấp nhận rủi ro có kiểm soát và học từ thất bại | Postmortem không đổ lỗi, thêm test sau mỗi sự cố |
Hai điều rút ra từ bảng này. Thứ nhất, lô nhỏ không phải sở thích mà là hệ quả của Flow và Feedback: lô càng nhỏ thì chờ càng ít và phản hồi càng sớm. Thứ hai, Third Way giải thích vì sao Hà và Minh cần một cuộc họp khác với cuộc họp quy trách nhiệm: mục tiêu của họ là sửa hệ thống.
Lab: đo lead time từ lịch sử Git
Ta dựng hai kho Git giả lập với ngày tháng cố định để kết quả giống nhau trên mọi máy. Kho wall mô phỏng cách phát hành sáu tuần một lần: 12 commit, một tag duy nhất ở cuối. Kho flow mô phỏng cách phát hành nhỏ: mỗi commit có tag riêng 4 giờ sau đó, tức pipeline mất 4 giờ.
Đầu tiên là script tạo hai kho. Lưu thành make-repos.sh:
#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
BASE=$(date -u -d "2026-08-03 09:00" +%s)
stamp() { date -u -d "@$((BASE + $1 * 3600))" +%Y-%m-%dT%H:%M:%SZ; }
commit_at() {
echo "$2" >> changes.txt
git add changes.txt
GIT_AUTHOR_DATE=$(stamp "$1") GIT_COMMITTER_DATE=$(stamp "$1") git commit -qm "$2"
}
tag_at() {
GIT_COMMITTER_DATE=$(stamp "$1") git tag -a "$2" -m "release $2"
}
new_repo() {
rm -rf "$1" && git init -q "$1" && cd "$1"
git config user.name "gdev-demo"
git config user.email "demo@example.invalid"
}
(
new_repo wall
for i in $(seq 0 11); do commit_at $((i * 80)) "wall change $i"; done
tag_at 1008 v1.0.0
)
(
new_repo flow
for i in $(seq 0 11); do
commit_at $((i * 80)) "flow change $i"
tag_at $((i * 80 + 4)) "v1.$i.0"
done
)
echo "created: wall (1 release), flow (12 releases)"
Mỗi commit cách nhau 80 giờ, khoảng 3,3 ngày. Ở kho wall, tag v1.0.0 nằm ở giờ thứ 1008, tức 42 ngày hay 6 tuần. Script thứ hai tính lead time: với mỗi tag, nó lấy các commit nằm giữa tag trước và tag này, rồi cộng khoảng cách thời gian từ commit đến tag. Lưu thành report.sh:
#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
report() {
cd "$1"
prev=""; total=0; n=0; releases=0
for tag in $(git tag --sort=creatordate); do
tag_time=$(git for-each-ref --format='%(taggerdate:unix)' "refs/tags/$tag")
range=${prev:+$prev..}$tag
for c in $(git log --format=%ct "$range"); do
total=$((total + tag_time - c)); n=$((n + 1))
done
releases=$((releases + 1)); prev=$tag
done
first=$(git log --format=%ct | tail -1)
last=$(git for-each-ref --format='%(taggerdate:unix)' --sort=-creatordate --count=1 refs/tags)
awk -v name="$1" -v r="$releases" -v a="$first" -v b="$last" -v t="$total" -v n="$n" \
'BEGIN { printf "%-5s releases=%d span=%.1f weeks avg lead time=%.1f hours\n", name, r, (b - a) / 604800, t / n / 3600 }'
}
(report wall)
(report flow)
Chạy trong một thư mục trống:
mkdir gdev-dora-lab && cd gdev-dora-lab
bash ../make-repos.sh
bash ../report.sh
Kết quả (ngày tháng cố định nên bạn sẽ thấy đúng các số này):
created: wall (1 release), flow (12 releases)
wall releases=1 span=6.0 weeks avg lead time=568.0 hours
flow releases=12 span=5.3 weeks avg lead time=4.0 hours
Đọc kết quả:
wallcó 1 lần phát hành trong 6 tuần, tức tần suất phát hành (deployment frequency) rất thấp. Lead time trung bình 568 giờ, khoảng 23,7 ngày: commit đầu tiên chờ 42 ngày, commit cuối chờ khoảng 3 ngày, trung bình ở giữa.flowcó 12 lần phát hành trong 5,3 tuần và lead time đúng 4 giờ, vì mỗi commit được phát hành ngay sau khi pipeline chạy xong.- Tổng số thay đổi hai bên bằng nhau (12). Khác biệt hoàn toàn đến từ cách gói chúng.
Hạn chế quan trọng: Git chỉ biết commit và tag. Nó không biết bản phát hành nào gây sự cố, nên không tính được tỉ lệ lỗi khi thay đổi (change fail rate) hay thời gian khôi phục. Các chỉ số đó cần dữ liệu sự cố từ hệ thống giám sát hoặc công cụ quản lý sự cố. Một vài đội dùng quy ước như tag hotfix- làm số đo gần đúng, nhưng đó chỉ là ước lượng, không phải số thật.
Dọn dẹp sau lab:
cd .. && rm -rf gdev-dora-lab
Mô hình 3: năm chỉ số DORA
DORA (DevOps Research and Assessment) là chương trình nghiên cứu về hiệu quả giao phần mềm. Theo hướng dẫn chính thức trên trang dora.dev, hiện có năm chỉ số, chia thành hai nhóm: thông lượng (throughput) và mất ổn định (instability). Chỉ số thứ năm, deployment rework rate, được bổ sung sau so với bộ bốn chỉ số mà nhiều tài liệu cũ vẫn nhắc.
| Nhóm | Chỉ số | Nghĩa, theo định nghĩa của DORA | Lab ở trên đo được không |
|---|---|---|---|
| Thông lượng | Change lead time | Thời gian từ khi thay đổi được commit vào hệ thống quản lý phiên bản đến khi chạy ở production | Có, nếu coi tag là thời điểm lên production |
| Thông lượng | Deployment frequency | Số lần deploy trong một khoảng thời gian, hoặc khoảng cách giữa các lần deploy | Có, đếm tag |
| Thông lượng | Failed deployment recovery time | Thời gian khôi phục sau một lần deploy thất bại cần can thiệp ngay | Không, cần dữ liệu sự cố |
| Mất ổn định | Change fail rate | Tỉ lệ deploy cần can thiệp ngay sau khi triển khai | Không, cần dữ liệu sự cố |
| Mất ổn định | Deployment rework rate | Tỉ lệ deploy không có kế hoạch nhưng xảy ra do một sự cố ở production | Không, cần dữ liệu sự cố |
Cách dùng đúng, theo chính hướng dẫn của DORA:
- Áp dụng ở mức một ứng dụng hoặc dịch vụ, ví dụ
gdev-api, không áp cho cả công ty. - Mục tiêu là cải thiện đội của bạn theo thời gian, không phải so sánh với đội khác.
- Đừng biến chỉ số thành mục tiêu giao việc, vì khi đó mọi người sẽ tìm cách làm đẹp con số. Hãy theo dõi nhiều chỉ số cùng lúc, trong đó có những chỉ số kéo nhau, ví dụ muốn deploy nhiều hơn nhưng không để tỉ lệ lỗi tăng.
Bài này cố ý không đưa ra con số chuẩn như "bao nhiêu lần deploy mỗi ngày là tốt". Trang chính thức của DORA cũng không định nghĩa các mức xếp hạng cụ thể; nó chỉ nói nhóm làm tốt thì tốt ở cả năm chỉ số.
Một lưu ý khi đọc tài liệu cũ: nhiều bài viết cũ chỉ nói về bốn chỉ số, trong đó chỉ số "recovery" được gọi là time to restore service. Tên hiện hành trên dora.dev là failed deployment recovery time.
Failure lab: tăng tốc độ mà bỏ qua phản hồi
Một hiểu lầm hay gặp là "DevOps nghĩa là deploy nhanh hơn". Hãy tự kiểm chứng: thêm sáu đợt phát hành vội vào kho flow, mô phỏng một đội bỏ qua test để deploy liên tục. Trong thư mục lab, sau khi đã chạy make-repos.sh:
cd flow
for i in 1 2 3 4 5 6; do
echo "rush $i" >> changes.txt && git add changes.txt && git commit -qm "rush $i (no tests)"
git tag -a "v2.$i.0" -m "rush release $i"
done
git tag | wc -l
cd ..
Kết quả:
18
Số tag tăng từ 12 lên 18, nghĩa là tần suất phát hành tăng. Nếu chỉ nhìn một chỉ số thì đội này "tốt lên". Nhưng ta không có dữ liệu nào cho thấy các bản này có chạy được hay không: không test, không giám sát, không đo lỗi. Triệu chứng là con số đẹp, nguyên nhân là chỉ đo một nửa bức tranh, cách kiểm chứng là xem chỉ số thuộc nhóm mất ổn định (change fail rate, rework rate) có song song với deployment frequency không, và cách sửa là đo cả hai nhóm cùng lúc. Đây chính là lý do DORA khuyên theo dõi nhiều chỉ số có sức kéo lẫn nhau.
Dọn dẹp: xóa thư mục gdev-dora-lab như ở phần lab.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân hay gặp | Cách xử lý |
|---|---|---|
| Có pipeline nhưng vẫn 6 tuần mới phát hành | Tự động hóa (A) xong nhưng Lean (L) chưa làm: lô vẫn lớn | Cắt lô thành thay đổi nhỏ, hợp nhất thường xuyên |
| Sự cố nào cũng có "người có lỗi" | Thiếu văn hóa học hỏi (Third Way, chữ C) | Postmortem tập trung vào hệ thống: thiếu test nào, thiếu cảnh báo nào |
| Chỉ số deploy rất đẹp nhưng người dùng phàn nàn | Chỉ đo thông lượng, bỏ qua mất ổn định | Đo cả nhóm mất ổn định, đặt cạnh nhau trên một dashboard |
| Đội DevOps riêng nhận mọi phiếu triển khai | Bức tường dời chỗ chứ chưa mất | Cho đội sản phẩm tự phục vụ qua pipeline và template dùng chung |
| So sánh chỉ số giữa hai dịch vụ rất khác nhau | Dịch vụ khác bản chất, so sánh vô nghĩa | So sánh gdev-api hôm nay với chính nó tháng trước |
Quy tắc thực tế: nếu một thay đổi không thể hoàn tác trong vài phút, hãy thu nhỏ nó trước khi nghĩ đến công cụ mới.
Tự kiểm tra
Hãy trả lời trước khi đọc đáp án ngay bên dưới mỗi câu.
Câu 1. Đội A có pipeline hoàn toàn tự động nhưng vẫn gộp mọi thay đổi của quý vào một bản phát hành. Theo CALMS, chữ nào còn thiếu nhiều nhất và biểu hiện là gì?
Đáp án: chữ L (Lean). Lô lớn và hàng đợi dài vẫn còn, dù chữ A đã có. Biểu hiện là lead time tính bằng tuần và sự cố khó khoanh vùng.
Câu 2. Trong lab, kho wall và flow có cùng 12 commit. Vì sao lead time khác nhau tới hơn 100 lần?
Đáp án: vì lead time tính từ commit đến lúc phát hành. Ở wall, mọi commit phải chờ tới tag cuối, kể cả commit đầu tiên chờ 42 ngày. Ở flow, mỗi commit được phát hành sau 4 giờ pipeline.
Câu 3. Đội muốn báo cáo change fail rate chỉ bằng cách đếm tag trong Git. Vì sao cách đó không đủ?
Đáp án: Git không ghi lại bản phát hành nào gây sự cố. Cần dữ liệu từ giám sát hoặc quản lý sự cố để biết deploy nào phải can thiệp ngay.
Nếu chỉ nhớ 3 điều
- DevOps là văn hóa trách nhiệm chung cộng với thực hành tự động và đo lường, không phải chức danh hay bộ công cụ.
- Thay đổi nhỏ và thường xuyên làm lead time ngắn, nghi phạm ít và hoàn tác dễ.
- Dùng đủ năm chỉ số DORA, ở mức một dịch vụ, để cải thiện chính đội mình chứ không để so sánh hay đặt mục tiêu giả.
Bài tiếp theo là Kiến thức tiên quyết: bạn cần biết gì trước khi vào các chương công cụ, kèm một bài tự kiểm tra chạy được trong terminal.
Nguồn: Các chỉ số DORA, dora.dev, Three Ways, IT Revolution, Khung CALMS, Atlassian.