Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (4.39 MB, 76 trang )
<span class="text_page_counter">Trang 1</span><div class="page_container" data-page="1">
HỌC VIỆN CƠNG NGHỆ BƯU CHÍNH VIỄN THƠNG
<b>KHOA CƠNG NGHỆ THƠNG TIN 1</b>
CỘNG HỊA XÃ HỘI CHỦ NGHĨA VIỆT NAM
<i><b>Độc lập – Tự do – Hạnh phúc</b></i>
<b>Ngành đào tạo: Cơng nghệ thơng tin Hệ đào tạo: Đại học chính quyEmail: ố điện thoại: 0394643981</b>
<b> 1/ Tên đồ án tốt nghiệp: NGHIÊN CỨU GIẢI PHÁP DEVSECOPS TRONG HỖ</b>
<b>TRỢ PHÁT TRIỂN PHẦN MỀM2/ Nội dung chính của đồ án: </b>
- Tìm hiểu cơ sở lý thuyết.
</div><span class="text_page_counter">Trang 3</span><div class="page_container" data-page="3">Lời đầu tiên, cho em xin gửi lời cảm ơn chân thành đến các thầy cô của Học viện Công nghệ Bưu chính Viễn thơng, đặc biệt là các thầy cô khoa Công nghệ thông tin 1 đã trang bị cho em những kiến thức quý báu trong suốt quá trình học tập tại trường, tạo điều kiện thuận lợi nhất để em hoàn thành đồ án.
Em xin trân trọng gửi lời cảm ơn đặc biệt đến thầy Nguyễn Đình Hiến, người đã hướng dẫn và đề xuất hướng giải quyết khi em gặp khó khăn, giúp em hồn thành đồ án đúng tiến độ.
Cuối cùng em cũng xin được cảm ơn gia đình, bạn bè, anh chị khóa trên đã giúp đỡ, bên cạnh quan tâm, ủng hộ trong suốt quá trình thực hiện đồ án.
Dù đã cố gắng nhưng do thời gian và kinh nghiệm còn hạn chế nên trong đồ án chắc chắn còn nhiều điều thiếu sót, em mong nhận được sự góp ý cũng như chỉ bảo tận tình từ các thầy cô.
<i>Hà Nội, tháng 12 năm 2023 </i>
<b>Sinh viên thực hiện Lê Quý Hoàng</b>
</div><span class="text_page_counter">Trang 4</span><div class="page_container" data-page="4"><b>NHẬN XÉT ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC CỦAGIẢNG VIÊN HƯỚNG DẪN</b>
<b>Giảng viên hướng dẫn: Ths. Nguyễn Đình Hiến Sinh viên thực hiện: Lê Quý Hoàng</b>
Tên đồ án:
Đồng ý/Không đồng ý cho sinh viên bảo vệ trước hội đồng chấm đồ án tốt nghiệp?
<i>Hà Nội, ngày...tháng 12 năm 2023 </i>
<b>GIẢNG VIÊN HƯỚNG DẪN Nguyễn Đình Hiến</b>
</div><span class="text_page_counter">Trang 5</span><div class="page_container" data-page="5"><b>NHẬN XÉT ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC CỦAGIẢNG VIÊN PHẢN BIỆN</b>
Giảng viên phản biện: ...
<b>Sinh viên thực hiện: Lê Quý Hoàng</b>
<b>Tên đồ án: Nghiên cứu giải pháp DevSecOps trong hỗ trợ phát triển phần mềm</b> Đồng ý/Không đồng ý cho sinh viên bảo vệ trước hội đồng chấm đồ án tốt nghiệp?
<i>Hà Nội, ngày...tháng 12 năm 2023 </i>
<b>GIẢNG VIÊN PHẢN BIỆN</b>
</div><span class="text_page_counter">Trang 6</span><div class="page_container" data-page="6">1.1.2. Mục tiêu nghiên cứu đề tài...2
1.1.3. Đối tượng và phạm vi...2
1.2. Giải pháp sử dụng...2
1.2.1. Lịch sử phương pháp triển khai ứng dụng...2
1.2.2. DevSecOps và các khái niệm liên quan...5
1.2.3. Các thành phần cần để xây dựng ứng dụng theo mơ hình DevSecOps...8
1.2.4. DevSecOps như quy trình trong phát triển phần mềm...10
2.1. Bài tốn đặt ra...31
2.2. Phân tích bài tốn và đưa ra kiến trúc tổng quan của giải pháp...31
2.3. Thành phần cấu trúc hệ thống theo công nghệ sử dụng...33
2.4. Luồng làm việc tổng quan của cả hệ thống...35
2.5. Tích hợp liên tục...36
2.6. Triển khai liên tục...37
2.7. Giám sát sau triển khai...39
2.8. Mơ hình một microservice triển khai bằng Argo CD trên Kubernetes...40
2.9. Kiến trúc microservice giao tiếp khi áp dụng Istio...42
</div><span class="text_page_counter">Trang 7</span><div class="page_container" data-page="7"><b>CHƯƠNG 3:ÁP DỤNG GIẢI PHÁP DEVSECOPS HỖ TRỢ PHÁT TRIỂN</b>
<b>MỘT WEBSITE MƠ HÌNH MICROSERVICE...43</b>
3.1. Chuẩn bị hệ thống áp dụng giải pháp DevSecOps...43
3.1.1. Cấu hình webhook trên Gitea...43
3.1.2. Cấu hình Jenkins để nhận được webhook từ Gitea...44
3.1.3. Cấu hình token SonarQube để Jenkins sử dụng...46
3.1.4. Cấu hình tài khoản Harbor để tích hợp với Jenkins và cụm K8s...46
3.1.5. Tạo ứng dụng Argo CD và cấu hình tự động đồng bộ...47
3.2. Cấu trúc của ứng dụng web Bookinfo...49
3.5. Giải pháp DevSecOps và giải pháp truyền thống...57
3.5.1. Nếu thực hiện triển khai cập nhật ứng dụng web Bookinfo bằng giải pháp truyền thống...57
3.5.2. So sánh giải pháp DevSecOps và giải pháp truyền thống...57
3.6. Đánh giá việc sử dụng giải pháp DevSecOps trong phát triển phần mềm. .58 <b>KẾT LUẬN...60</b>
<b>TÀI LIỆU THAM KHẢO...61</b>
</div><span class="text_page_counter">Trang 8</span><div class="page_container" data-page="8">Hình 1.1 Cấu trúc của máy ảo...3
Hình 1.2 So sánh mơ hình của container và máy ảo...5
Hình 1.3 Vịng đời của mơ hình DevOps...7
Hình 1.12 Cấu trúc của control plane...24
Hình 1.13 Cấu trúc của worker node...25
Hình 1.14 Deployment, Pod và container...26
Hình 1.15 Một Pod có thể có nhiều container...26
Hình 1.16 Cách các container trong một Pod giao tiếp...27
Hình 1.17 Hướng scale của Pod trong Kubernetes...27
Hình 1.18 Các Service giúp giao tiếp trong Kubernetes...28
Hình 1.19 Logo MetalLB...28
Hình 1.20 Logo Istio...29
Hình 2.1 Vịng lặp quy trình phát triển...33
Hình 2.2 Các cơng nghệ sử dụng phân loại theo nhóm chức năng...34
Hình 2.3 Luồng làm việc của hệ thống...35
Hình 2.8 Kiến trúc ứng dụng với Istio...42
Hình 3.1 Giao diện của một repository trên Gitea...43
Hình 3.2 Cấu hình webhook tới Jenkins...44
Hình 3.3 Giao diện tạo một luồng làm việc trên Jenkins...44
Hình 3.4 Các lựa chọn cần thiết cho Git của Jenkins Pipeline...45
Hình 3.5 Cấu hình URL của reposiory mã nguồn ứng dụng...45
Hình 3.6 Các credential cần thiết để Jenkins giao tiếp với các hệ thống khác...46
Hình 3.7 Giao diện quản lí token của SonarQube...46
Hình 3.8 Giao diện quản lí tài khoản robot của Harbor...47
Hình 3.9 Giao diện cài đặt của một project trên Harbor...47
Hình 3.10 Giao diện tại ứng dụng Argo CD 1...48
Hình 3.11 Giao diện tạo ứng dụng Argo CD 2...48
Hình 3.12 Cấu trúc ứng dụng Bookinfo...49
</div><span class="text_page_counter">Trang 9</span><div class="page_container" data-page="9">Hình 3.14 Phần tiêu đề mong muốn cập nhật...51
Hình 3.15 Giao diện terminal khi lập trình viên thực hiện git push...51
Hình 3.16 Trang web của repository mã nguồn...51
Hình 3.17 Giao diện Jenkins sau khi tự động chạy Pipeline...52
Hình 3.18 Trang chủ của SonarQube với kết quả qt mã nguồn mới...52
Hình 3.19 Giao diện quản lí artifact của repository bookinfo-productpage...53
Hình 3.20 Kết quả quét lỗ hổng bảo mật image của Trivy...53
Hình 3.21 Giao diện của repository cấu hình triển khai sai khi cập nhật...53
Hình 3.22 Giao diện Argo CD sau khi tự động đồng bộ với repository cấu hình triển khai...54
Hình 3.23 Kết quả kubectl trước khi cập nhật...54
Hình 3.24 Kết quả kubectl sau khi cập nhật...55
Hình 3.25 Giao diện ứng dụng sau khi cập nhật...55
Hình 3.26 Giao diện biểu đồ của Kiali để theo dõi ứng dụng...55
Hình 3.27 Giao diện phân tích một request của Jaeger...56
Hình 3.28 Giao diện Grafana...56
</div><span class="text_page_counter">Trang 10</span><div class="page_container" data-page="10">CI Continous integration Tích hợp liên tục CD Continous delivery Cung cấp liên tục CD Continous deployment Triển khai liên tục
IaC Infrastructure as code Quy trình quản lí và triển khai tài nguyên phần cứng bằng các file cấu hình định nghĩa.
FTP File Transfer Protocol Một giao thức truyền file
IDE Integrated development environment Một dạng cơng cụ phần mềm sử dụng cho lập trình
CLI Command line interface Giao diện dùng lệnh để thao tác với máy tính
DSL Domain-Specific Language Ngơn ngữ dành riêng cho một vấn đề
HA High availability Các thành phần cơng nghệ thơng tin có thể chạy liên tục ổn định mà khơng cần có can thiệp của con người.
LDAP Lightweight Directory Access Protocol Một giao thức để tìm kiếm thơng tin hoặc thiết bị trong một mạng
AD Active Directory Giao thức từ điển của Microsoft, cho phép quản lí quyền truy cập các thành phần trong mạng
OIDC OpenID Connect Giao thức xác thực danh tính mở rộng từ OAuth 2.0
YAML YAML Ain't Markup Language Định dạng file phổ biến dùng để chứa thơng tin về cấu hình JSON JavaScript Object Notation Dạng file chứa dữ liệu đọc được
bởi con người theo dạng
SAML Security Assertion Markup Language Một cách tiêu chuẩn để cho ứng dụng hoặc dịch vụ ngoài biết được danh tính của người dùng, dùng cho xác thực.
SSO Single sign-on Kiểu xác thực mà cho phép
</div><span class="text_page_counter">Trang 11</span><div class="page_container" data-page="11">SSH Secure Socket Shell Giao thức cho phép người dùng truy cập vào máy tính qua mạng SSL Secure Sockets Layer Giao thức cung cấp bảo mật, xác thực và tính tồn vẹn cho truyền thơng trên Internet
</div><span class="text_page_counter">Trang 12</span><div class="page_container" data-page="12">Hypervisor Một dạng phần mềm, hoặc phần cứng có thể tạo và chạy máy ảo Microservice Kiến trúc và cách tổ chức phần mềm gồm nhiều thành phần dịch
vụ độc lập với nhau và giao tiếp qua các API được định nghĩa rõ ràng
Metric Ý nghĩa áp dụng trong giám sát, là dữ liệu thô từ nhiều nguồn như phần cứng, phần mềm, ứng dung, website, cung cấp thông tin về tài nguyên sử dụng, hiệu năng và hành vi của người dùng.
Build Thao tác đưa mã nguồn qua các công cụ để biến thành một dạng file chạy được trên máy tính
Script Phương pháp lập trình cho phép thực hiện các thay đổi, tuỳ biến và tự động hoá các thành phần của một hệ thống có sẵn
Docker image Dạng tĩnh của container, dùng để tạo ra các container giống hệt nhau về nội dung bên trong và có thể lưu trữ
Repository Một phần bộ nhớ (có thể trên máy tính hoặc cloud) chứa, quản lí và theo dõi sự thay đổi của file và thư mục. Là thành phần rất quan trọng của Git.
Git merge Thao tác git cho phép ghép hai lịch sử phát triển vào với nhau (thường là khi có xung đột từ hai bên)
Git commit Thao tác git ghi tại các thay đổi vào trong repository
Git tag Thao tác git để đánh dấu các điểm quan trọng trong lịch sử thay đổi của một repository
Git hook Chức năng của git cho phép tự động chạy các script khi một sự kiện quan trọng nào đó trong git xảy ra
Git cherry-pick Thao tác git mà áp dụng thay đổi từ một commit nào đó có sẵn Pull request Là một đề xuất khi muốn ghép các thay đổi từ một nhánh sang
một nhánh khác.
Production Ở đây dùng với nghĩa là một môi trường mà đã có ứng dụng triển khai thành cơng và đang có người sử dụng thực tế
Artifact Tất cả các dạng file có được sau khi thực hiện build từ mã nguồn thành cơng
Orchestration Sử dụng để nói tới các hệ thống có thể cấu hình tự động, phối hợp và quản lí các hệ thống mạng và dịch vụ phức tạp
Monolithic Mơ hình phát triển phần mềm truyền thống khi mọi thứ được build vào thành một đơn vị duy nhất và độc lập với ứng dụng khác Downtime Khoảng thời gian mà các hệ thống không thể hoạt động và cung
cấp dịch vụ
Image tag Tên đặt cho Docker image để có thể quản lí
Scale Khả năng mở rộng và thu nhỏ hệ thống phần mềm và phần cứng Self-hosted Cách triển khai ứng dụng bằng cách sử dụng hạ tầng có sẵn của
bản thân cá nhân, tổ chức
Cloud native Cách build, triển khai và quản lí phần mềm định hướng cho việc chạy ở trên một môi trường cloud
Registry Hệ thống chứa và phân phối container image và artifact
</div><span class="text_page_counter">Trang 13</span><div class="page_container" data-page="13">K8s node La một máy chủ hoặc máy ảo được K8s quản lí.
Bare-metal Là một máy chủ vật lí chỉ được dùng cho một đối tượng duy nhất, hoặc trong ý nghĩa với K8s là việc sử dụng máy chủ vật lí như là node của K8s
Canary testing Một dạng kiểm thử phần mềm khi chỉ phát hành phiên bản mới với một lượng người dùng nhỏ
Reverse proxy Một máy chủ đứng trước các máy chủ web và điều hướng máy khách tới các máy chủ web đó
Push image Thao tác tải lên image lên trên registry Pull image Thao tác tải xuống image từ registry
Rollback K8s Khả năng trong K8s cho phép lùi lại phiên bản đã triển khai trước đó
Rollout K8s Khả năng trong K8s cho phép triển khai tự động theo cấu hình K8s namespace Cung cấp khả năng cơ lập các nhóm tài nguyên trong một cụm
K8s
</div><span class="text_page_counter">Trang 14</span><div class="page_container" data-page="14">Bảng 3.1 Bảng so sánh điểm mạnh của DevSecOps so với phương pháp truyền thống ... 58
</div><span class="text_page_counter">Trang 15</span><div class="page_container" data-page="15"><b>1.1. Giới thiệu đề tài1.1.1. Lí do chọn đề tài</b>
Trong vài thập kỉ gần đây, quy trình phát triển phần mềm đã thay đổi một cách chóng mặt, và đặc biệt với cuộc cách mạng gần nhất: dịch chuyển khỏi việc triển khai thủ công, hướng tới tư duy DevOps và tự động hố (CI/CD). Sự dịch chuyển này khơng những đã tăng năng suất và độ hiệu quả trong vòng đời phát triển phần mềm, mà còn nâng cao sự hợp tác giữ các đội phát triển, vận hành và đảm bảo chất lượng.
Sự thay đổi này sinh ra khơng phải ngẫu nhiên, mà là do chính thị trường công nghệ đi với sự phát triển mạnh của các công nghệ triển khai ứng dụng và sự hỗ trợ, đầu tư cực kì mạnh tay của các ơng lớn trong ngành công nghệ như Google, Amazon, Microsoft. Các dịch vụ ngày một phức tạp, việc thay đổi kiến trúc là điều không thể tránh khỏi, cũng như việc phát triển cực mạnh mẽ của cloud. Hay yêu cầu của khách hàng cũng ngày một tăng cao, yêu cầu việc phát triển phầm mềm ngày càng phải linh hoạt hơn, ổn định hơn, và đặc biệt sản phẩm phải đến với khách hàng nhanh hơn và liên tục hơn. Trong những năm gần đây, chuyển đổi số trong doanh nghiệp trở thành một điều tất yếu, các doanh nghiệp, tổ chức trong mọi lĩnh vực hiện đã và đang khai thác các chiến lược chuyển đổi số, từ các tổ chức tư nhân đến nhà nước. Chuyển đổi số là số hóa tồn bộ cả một tổ chức. Chuyển đổi số là thay đổi quy trình mới, mơ hình tổ chức mới, phương thức cung cấp dịch vụ, tư duy mới cho nhân viên và việc khai thác các công cụ hỗ trợ mới. DevOps và DevSecOps cũng chính là một phần trong chuỗi những thay đổi rất nhiều các doanh nghiệp đã bắt đầu áp dụng để tiến tới chuyển đổi số hoàn toàn. Trải nghiệm người dùng ngày càng trở thành trung tâm, và khi đưa lại những trải nghiệm tốt nhất cho khách hàng thì sẽ đưa lại những lợi thế cạnh tranh khi mà thị trường sản phẩm cơng nghệ thơng tin ngày càng bão hồ. DevOps khơng phải sinh ra để rút ngắn quy trình hay thời gian phát triển, mà là để thời gian từ mã nguồn đến sản phẩm trở thành ngắn nhất, hay tức là đưa sản phẩm đến tay người dùng nhanh nhất có thể. Hơn nữa, việc một sản phẩm đến được tay khách hàng, tất yếu sẽ sinh ra đóng góp, ý kiến và phản ảnh từ khách hàng, từ đó cho phép đổi mới và cải tiến liên tục sản phẩm. Một sản phẩm được cập nhật liên tục, đúng với mong muốn, yêu cầu và có các tính năng mong đợi của khách hàng chắc chắn sẽ có lợi thế cực lớn so với các đối thủ. DevSecOps đóng một vai trị nịng cốt, song hành với việc thay đổi tư duy phát triển sản phẩm để có thể tiến tới chuyển đổi số. Vì vậy nên em đã lựa chọn đề tài “Nghiên cứu giải pháp DevSecOps trong hỗ trợ phát triển phần mềm”. Thông qua đề tài em muốn chứng minh được những lợi ích vô cùng to lớn và thiết thực mà DevSecOps và
</div><span class="text_page_counter">Trang 16</span><div class="page_container" data-page="16">tự động hố có thể mang lại trong phát triển phần mềm, và đưa ra được một giải pháp tổng thể và thực tiễn để có thể áp dụng trong thực tế.
<b>1.1.2. Mục tiêu nghiên cứu đề tài</b>
- Nghiên cứu về lý thuyết của DevOps, và mở rộng ra DevSecOps trong hỗ trợ quy trình phát triển phần mềm.
- Đặt ra một giải pháp mang tính tổng thể theo tư duy DevSecOps để giải quyết bài toàn tự động hoá trong phát triển phàn mềm.
- Áp dụng giải pháp DevSecOps vào trong việc phát triển một ứng dụng web mơ hình microservice.
<b>1.1.3. Đối tượng và phạm vi</b>
Các đội nhóm và doanh nghiệp phát triển sản phẩm, đặc biệt các đội nhóm đã và đang chuyển dịch, áp dụng Agile trong phát triển phần mềm.
<b>1.2. Giải pháp sử dụng</b>
<b>1.2.1. Lịch sử phương pháp triển khai ứng dụng</b>
Ứng dụng là một phần đã giúp việc phổ biến hoá máy tính đến đại chúng, một trang web, một dịch vụ xử lí ảnh, một ứng dịnh tính tốn trên mạng, tất cả đều là ứng dụng. Vậy ứng dụng chạy ở đâu? Hầu hết, nhất là các ứng dụng, dịch vụ online là chạy ở trên các máy chủ.
<b>a) Thời kì máy chủ vật lí</b>
Thời kì sơ khai nhất, gần như chỉ có thể chạy một ứng dụng trên một máy chủ, đây là giới hạn đặc tính kĩ thuật của thời kì này.
Chính vì những hạn chế đó, mỗi khi doanh nghiệp cần có thêm, hoặc triển khai, mở rộng thêm các dịch vụ mới thì sẽ cần thêm một máy chủ mới. Tuy nhiên, yêu cầu về hiệu năng của các ứng dụng hầu như không được làm rõ với những ứng dụng mới đó, nên việc chọn mua máy chủ mới phần lớn phụ thuộc vào suy đoán.
Từ vấn đề trên, sinh ra một các giải quyết đơn giản nhất: mua máy chủ phải to, phải mạnh, tốn nhiều tiền. Lí do giải thích đơn giản là vì u cầu kĩ thuật hiệu năng khơng rõ ràng, các doanh nghiệp không bao giờ muốn ứng dụng sẽ chạy chậm chỉ vì phần cứng q yếu, từ đó có thể mất khách hàng. Kết cục là các máy chủ thường không bao giờ chạy hết hiệu năng tối đa, là một sự lãng phí tiền của rất lớn.
<b>b) Máy ảo</b>
</div><span class="text_page_counter">Trang 17</span><div class="page_container" data-page="17"><i>Hình 1.1 Cấu trúc của máy ảo</i>
Những năm cuối của thế kỉ 20, máy ảo ra đời một cách rộng rãi. Máy ảo ngay lập tức thay đổi các ứng dụng chạy trên máy chủ, cho phép nhiều ứng dụng có thể chạy trên một máy chủ duy nhất. Từ đó cũng làm việc mua máy chủ mới cho ứng dụng mới biến mất, thay vào đó là sử dụng chính tài ngun của những máy chủ sẵn có một các hiệu quả hơn.
Tuy nhiên, máy ảo khơng phải là một giải pháp hồn hảo. Mỗi máy ảo đều phải có một hệ điều hành hồn chỉnh riêng biệt cho chính nó là một điểm trừ lớn. Hệ điều hành sẽ tiêu tốn tài nguyên của máy chủ, gây lãng phí khi những tài nguyên đó có thể để sử dụng để chạy nhiều ứng dụng hơn. Ngoài ra, mỗi hệ điều hành đều cần theo dõi và cập nhật, sửa lỗi. Và trong một số trường hợp, hệ điều hành sẽ yêu cầu bản quyền. Tất cả các điều trên đều gây lãng phí thời gian và tài nguyên.
</div><span class="text_page_counter">Trang 18</span><div class="page_container" data-page="18">Chưa kể thêm mơ hình máy ảo có một số điểm trừ khác như máy ảo thường khởi động chậm và tính di động không cao, một khi đã sử dụng một dạng máy ảo (hypervisor hoặc các nền tảng cloud) thì khá khó để có thể chuyển dịch sang một hypervisor hoặc một nhà cung cấp khác.
<b>c) Container và Docker</b>
Các tập đồn lớn trong mảng dịch vụ web, ví dụ như Google, đã sử dụng container để giải quyết các điểm yếu của máy ảo từ khá lâu.
Cơ bản thì một container có thể nói là ngang hàng với một máy ảo. Điểm khác biệt rõ ràng nhất là container không cần có một hệ điều hành đầy đủ của riêng nó như máy ảo, mà thay vào đó là sẽ chia sẻ hệ điều hành với cả máy chủ (máy cho phép các container chạy trên nó). Điểm khác biệt này cũng giúp một lượng lớn tài nguyên như RAM, CPU và bộ nhớ dược giải phóng. Ngồi ra cịn giúp giảm được chi phí để mua bản quyền hệ điều hành, hay cơng sức để bảo trì, cập nhật, vá lỗi hệ điều hành. Kết quả là giúp tiếp kiệm thời gian, tài nguyên và tiền bạc.
Container cũng có khả năng khởi động nhanh hơn và có tính di động rất cao. Việc chuyển và chạy container từ laptop cá nhân, lên cloud, hay vào trong máy ảo, hoặc chạy trên một máy chủ trực tiếp đều rất dễ dàng.
Container hiện đại bắt nguồn từ thế giới Linux và là một sản phẩm được sinh ra từ sự góp sức khổng lồ từ rất nhiều người trông cộng đồng mã nguồn mở trong một thời gian dài. Ví dụ như Google đã có rất nhiều cơng sức trong việc viết các phần liên quan đến công nghệ container cho Linux kernel, nếu khơng có những thành phần này, container hiện như như có hiện nay có thể khơng tồn tại.
Những cơng nghệ chính đã cho phép sự phát triển cực kì mạnh mẽ của container trong những năm gần đây có thể kể đến như kernel namespace, control group, union filesystem và Docker.
Tuy nhiên, trước khi có Docker, container vẫn là một cơng nghệ rất phực tạp và ngoài tầm với của phần lớn tổ chức. Nhờ có Docker, container đã trở thành một cơng nghệ được phổ rộng hố, cho phép đại chúng sử dụng một cách dễ dàng.
Và từ sự phổ rộng hố của Docker nói riêng và container nói chung, đã sinh ra nhu cầu cần thay đổi từ máy ảo sang container trong quy trình phát triển và triển khai ứng dụng của doanh nghiệp. Cùng với cách mà ứng dụng được phát triển cũng đang dần dịch chuyển theo một hướng mới.
Tuy nhiên container không phải sinh ra để thay thế hoặc cạnh tranh với máy ảo, thay vào đó là một sự cộng hưởng và cùng hỗ trợ với nhau để sinh ra một hệ thống phát triển và vận hành phần mềm phù hợp với thời kì hiện đại.
</div><span class="text_page_counter">Trang 19</span><div class="page_container" data-page="19"><i>Hình 1.2 So sánh mơ hình của container và máy ảo</i>
Container là một đơn vị phần mềm độc lập, chứa tất cả các thành phần cần thiết để chạy một ứng dụng hoặc một website, một container bao gồm mã nguồn, các thư viện phụ thuộc, hệ điều hành độc lập và tài nguyên hệ thống ảo hóa. Container giúp đóng gói và triển khai ứng dụng một cách đáng tin cậy và dễ dàng hơn, cũng như tăng tính di động, linh hoạt của ứng dụng cho phép các nhà phát triển có thể triển khai ứng dụng của mình trên nhiều nền tảng, môi trường khác nhau một cách đơn giản và nhanh chóng.
Mỗi container được xem như một mơi trường độc lập với các container khác trên cùng một máy chủ. Các container được ảo hóa ở mức hệ điều hành và dùng chung nhân hệ điều hành với máy chủ chạy các container này. Container nhỏ gọn và linh hoạt hơn so với máy ảo do đó nó khởi động nhanh chóng hơn một máy ảo tuy nhiên do dùng chung nhân hệ điều hành với máy chủ nên vấn đề bảo mật của container yếu hơn máy ảo, các lỗ hổng bảo mật chạy bên trong container có khả năng truy cập vào phần còn lại của hệ thống máy chủ.
Để dễ dàng trong quá trình quản lý và vận hành các container, một công cụ quản lý tập trung đã ra đời, đó chính là container runtime. Container runtime là một cơng cụ đóng vai trò quản lý tất cả quá trình running của một container, bao gồm tạo và xóa container, đóng gói và chia sẻ container.
<b>1.2.2. DevSecOps và các khái niệm liên quan</b>
- Dev: Software development – phát triển phần mềm. - Sec: Security – bảo mật, an tồn thơng tin.
</div><span class="text_page_counter">Trang 20</span><div class="page_container" data-page="20">- Ops: IT operations – vận hành công nghệ thông tin.
Đây là ba thành phần, ba công việc cơ bản để đưa được một phần mềm từ mức ý tưởng đến tay của người dùng, và DevSecOps dùng sẽ giải quyết cả ba vấn đề này theo một tư tưởng mới, nhất là để áp dụng hiệu quả nhất với container.
<b>a) DevOps và DevSecOps:</b>
DevOps là một sự kết hợp của tư tưởng văn hố, cách thức thực hiện và các cơng cụ giúp tăng khả năng cung cấp phần mềm và dịch vụ ở một nhịp độ cao hơn, tiến hoá và nâng cấp sản phẩm ở một tốc độ cao hơn so với các tổ chức sử dụng quy trình phát triển phần và quy trình quản lí hạ tầng truyền thống.
Trong một mơ hình DevOps, đội ngũ phát triển và đội ngũ vận hành khơng cịn bị tách lẻ ra nữa. Thơng thường hai đội nhóm này sẽ được ghép vào thành một nhóm duy nhất, kĩ sư trong nhóm sẽ làm việc trên tồn bộ vịng đời của phần mềm, từ phát triển, kiểm thử đến triển khai, vận hành, và phát triển các kĩ năng không giới hạn ở một mảng duy nhất.
Một mơ hình mở rộng của DevOps là khi các đội quản lí chất lượng và đội ngũ an tồn thơng tin cũng được tích hợp chặt chẽ vào việc phát triển và vận hành trong suốt vòng đời của ứng dụng – thường được gọi là DevSecOps.
Các đội nhóm DevOps sẽ sử dụng các phương pháp để tự động hố các quy trình mà trước đây làm bằng tay và rất chậm. Kết hợp với việc sử dụng các nhóm cơng nghệ và cơng cụ để giúp vận hành và nâng cấp sản phẩm nhanh và có độ tin cậy cao. Các cơng cụ này cũng giúp cho một kĩ sư có thể hồn thành các công việc một cách độc lập các công việc trước đây là phải yêu cầu sự hỗ trợ của các đội nhóm khác (ví dụ như triển khai hoặc cung cấp hạ tầng), từ đó tăng tốc độ của cả nhóm.
Lợi ích của DevOps:
- Tốc độ: Giúp khả năng thích ứng trước thị trường tốt hơn, phát triển, sáng tạo, cập nhật nhanh hơn.
- Liên tục cung cấp: Tăng số lượng và nhịp độ ra mắt, cập nhật sản phẩm. Giúp cho việc bản sửa lỗi, bản nâng cấp tính năng đến rất nhanh tới người dùng cuối, thích ứng tốt hơn theo nhu cầu cảu khách hàng.
- Độ tin cậy cao: Đảm bảo chất lượng của các bản cập nhật ứng dụng và thay đổi về mặt hạ tầng, đảm bảo việc phân phối ứng dụng nhanh và vẫn đảm bảo trải nghiệm tốt cho người dùng.
- Scale: Vận hành và quản lý hạ tầng cùng với quy trình phát triển với khả năng scale. Tự động hố sẽ tăng tính nhất qn trong việc quản lý các hệ thống phức tạp và thay đổi liên tục một cách hiệu quả với ít rủi ro.
- Bảo mật: Đi nhanh khơng có nghĩa là đánh đổi lấy bảo mật. Các quy tắc bảo mật có thể áp dụng một cách tự động ở nhiều giai đoạn trong quá trình phát triển cũng như triển khai bằng nhiều cơng cụ khác nhau.
</div><span class="text_page_counter">Trang 21</span><div class="page_container" data-page="21">DevOps là một quy trình vịng lặp khép kín, bước trước sẽ là đầu vào của bước sau, bước cuối là đầu vào của bước đầu. Quy trình phát triển sẽ tiếp diễn như vậy trong suốt vòng đời sản phần để liên tục có thể đối mới và phát triển theo đúng hướng đi đặt trong tâm trải nghiệm người dùng là trên hết.
<i>Hình 1.3 Vịng đời của mơ hình DevOps</i>
<b>b) Tại sao DevOps trở nên quan trọng?</b>
Phần mềm và Internet đã thay đổi thế giới và nhiều ngành công nghiệp, từ mua sắm đến giải trí hay ngân hàng. Phần mềm cịn chỉ là một thứ để hỗ trợ một doanh nghiệp nữa mà đã trở thành một phần quan trọng trong mọi thành phần của một doanh nghiệp. Các công ty có thể tương tác với khách hàng thơng qua phần mềm được cung cấp dưới dạng dịch vụ trực tuyến hoặc ứng dụng trên rất nhiều kiểu thiết bị. Ứng dụng cũng giúp tăng tính hiệu quả vận hành của mọi phần của chuỗi giá trị. Cũng giống như cách các công ty sản xuất đã thay đổi cách thiết kế, xây dựng và phân phối sản phẩm trong cuộc cách mạng cơng nghiệp tự động hố trong thế kỉ 20, công ty trong thế giới hiện đại cũng phải chuyển hoá cách xây dựng và phân phối sản phẩm phần mềm.
<b>c) DevOps là một văn hố, khơng phải là một cơng cụ duy nhất</b>
Chuyển hố sang DevOps u cầu sự thay đổi trong văn hoá và tư duy. Ở dạng đơn giản nhất, DevOps là loại bỏ rào cản giữa hai nhóm khác nhau: đội phát triển và đội vận hành. Trong một số tổ chức có thể khơng tồn tại sự phân chia này mà kĩ sư sẽ làm cả hai. Với DevOps, hai nhóm sẽ làm việc với nhau để tối ưu hoá năng suất của lập trình viên và độ tin cậy của vận hành. Đội nhóm sẽ trực tiếp chịu hồn tồn trách nhiệm và quyền sở hữu của dịch vụ của họ, vượt qua cả danh nghĩa trên giấy hay vị trí truyền thống được đặt ra từ trước bằng cách suy nghĩ tới nhu cầu của người dùng cuối, và làm thế nào để giải quyết được các nhu cầu đó. Quản lý chất lượng và an tồn thơng tin cũng có thể được tích hợp vào theo. Một tổ chức sử dụng mơ hình DevOps,
</div><span class="text_page_counter">Trang 22</span><div class="page_container" data-page="22">sẽ có các đội nhóm chịu trách nhiệm tồn bộ vịng đời phát triển và vận hành sản phẩm.
Chính vì DevOps khơng phải là một cơng cụ, mà chỉ là một văn hố, một cách tích hợp các cơng cụ hỗ trợ trong phát triển phần mềm để nâng cao chất lượng sản phẩm, phương pháp hay giải pháp ứng dụng DevOps vào thực tế có vơ số biến thể khác nhau, được tuỳ biến tuỳ vào hoàn cảnh thực tiễn và yêu cầu đặc thù để áp dụng.
<b>d) Các nguyên tắc của DevOps</b>
Một nguyên tắc nền tảng là cung cấp rất đều đặn các bản cập nhật nhỏ. Đây là cách mà tổ chức sẽ đổi mới nhanh hơn cho khách hàng. Những bản cập nhật này thường sẽ mang tính tăng thêm nhỏ so với những bản cập nhật thỉnh thồng có dưới mơ hình cung cấp truyền thống. Nhỏ và đều đặn giúp cho mỗi lần triển khai có ít rủi ro hơn, giúp các đội nhóm có thể xử lí các lỗi nhanh hơn bởi có thể sử dụng bản triển khai nào sinh ra lỗi. Tuy rằng mức độ to nhỏ và nhịp cập nhật của các bản cập nhật này sẽ còn tuỳ thuộc vào nhiều yếu tố khác, thơng thường các tổ chức sử dụng mơ hình DevOps sẽ cung cấp nhiều bản cập nhật hơn so với các tổ chức sử dụng mơ hình phát triển phần mềm truyền thống.
Tổ chức cũng có thể sử dụng mơ hình microservice để làm ứng dụng linh hoạt hơn và cho phép đổi mới nhanh hơn. Kiến trúc microservice biến các hệ thống to lớn phức tạp thành các dự án nhỏ, đơn giản và độc lập. Một ứng dụng được tách lẻ ra thành rất nhiều các thành phần chỉ phụ trách đảm nhận một công việc duy nhất, hoạt động độc lập với các dịch vụ ngang hàng và ứng dụng tổng thể. Kiến trúc này giúp giảm gánh nặng đồng bộ khi cập nhật ứng dụng, bởi mỗi thành phần có thể cập nhật độc lập hoàn toàn.
Tuy nhiên, sự phối hợp của microservice và tăng tần suất cập nhật sẽ dẫn đến nhiều bản triển khai hơn đáng kể, có thể sinh ra các thử thách về mặt vận hành. Vì thế, các phương pháp như tích hợp liên tục và cung cấp liên tục giải quyết các vấn đề đó, và cho phép việc phát triển nhanh nhưng vẫn đảm bảo an toàn và tính ổn định. Các phương pháp tự động hố hạ tầng như IaC và quản lí cấu hình, sẽ giúp tài nguyên có khả năng phản ứng tốt hơn tới các thay đổi theo yêu cầu thực tế. Thêm vào với việc sử dụng theo dõi và ghi log sẽ giúp kiểm soát hiệu năng của ứng dụng và hạ tầng để tăng khả năng phản ứng trước các vấn đề phát sinh.
<b>1.2.3. Các thành phần cần để xây dựng ứng dụng theo mơ hình DevSecOps</b>
Để có thể xây dựng mơ hình ứng dụng theo mơ hình DevSecOps, phải đảm bảo và đi qua các yếu tố, thành phần sau để có thể biến ý tưởng trở thành một sản phẩm dùng
</div><span class="text_page_counter">Trang 23</span><div class="page_container" data-page="23">- Giám sát.
<b>a) Tích hợp liên tục</b>
Tích hợp liên tục nghĩa là một phương pháp để tự động hố việc tích hợp các thay đổi trong mã nguồn từ nhiều người khác nhau trong một dự án phần mềm. Nó là một trong các bước quan trọng của một quy trình DevSecOps, cho phép liên tục merge các thay đổi của mã nguồn vào một repository tập trung và quá trình build và kiểm thử sẽ chạy ở đó. Các cơng cụ tự động sẽ dùng để đảm bảo tính đúng của mã nguồn mới trước khi tích hợp.
Một hệ thống quản lí phiên bản mã nguồn là xương sống của quy trình CI, ngồi ra cũng sẽ cung cấp thêm một số kiểm tra khác như tự động kiểm tra chất lượng mã nguồn hoặc kiểm tra cú pháp mã nguồn.
Để hiểu được tầm quan trọng của CI thì phải nhìn vào trường hợp và các vấn đề sinh ra khi khơng có CI. Lập trình viên sẽ phải thủ cơng hợp tác và liên lạc mỗi khi cần đóng góp các thay đổi vào sản phẩm. Sự hợp tác này kéo dài từ đội phát triển cho đến vận hành, và kể cả tổ chức. Đội sản phẩm thì phải phối hợp khi ra mắt lần lượt các tính năng mới và sửa lỗi.
Việc giao tiếp trong một mơi trường khơng có CI có thể trở thành rất phức tạp, vịng vèo với các công đoạn cần đồng bộ nhưng lại chồng chéo lên nhau, tiêu tốn về cả mặt thời gian và công sức. Điều này cũng dẫn đến chậm trễ trong việc phát hành mã nguồn mới và có khả năng hỏng hóc cao do việc tích hợp phải ln có bàn tay con người trực tiếp tác động vào. Những rủi ro cũng càng nghiêm trọng hơn khi số người đội nhóm và độ lớn của dự án tăng lên.
Nếu khơng có một quy trình CI chắc chắn, sẽ có một rào cản giữa đội ngũ kĩ thuật và phần còn lại của tổ chức. Giao tiếp giữa đội sản phẩm và đội kĩ thuật có thể trở nên khó khăn. Đội kĩ thuật sẽ trở thành một “hộp đen” mà các đội nhóm khác đưa u cầu, hoặc tính năng mong muốn như đầu vào, và mong đợi có thể có được kết quả. Từ đó cũng làm chính đội kĩ thuật khó có thể đốn được thời gian hồn thành u cầu bởi thời gian tích hợp các thay đổi mới là một rủi ro không biết và khơng đốn được. CI thường được sử dụng trong một luồng làm việc phát triển phần mềm Agile. Một tổ chức sẽ xây dựng được một danh sách bao gồm các việc trên con đường phát triển của sản phẩm. Các công việc này sẽ được chia ra cho cái đội ngũ phát triển, và CI sẽ cho phép mọi người trong nhóm này làm việc song song độc lập với nhau cùng lúc. Và khi có một cơng việc hồn tất, lập trình viên sẽ ghép mã nguồn vào và đưa lên hệ thống CI để được tích hợp vào trong phần còn lại của dự án.
<b>b) Cung cấp liên tục</b>
Cung cấp liên tục là tự động hoá tất cả các thay đổi của mã nguồn thành một phiên bản chạy được trên một môi trường thử nghiệm và sẵn sàng để có thể được đưa lên mơi trường production. Cung cấp liên tục thường xảy ra sau tích hợp liên tục. Nếu
</div><span class="text_page_counter">Trang 24</span><div class="page_container" data-page="24">được áp dụng đầy đủ, sẽ ln có một phiên bản artifact sẵn sàng để triển khai mà đã đạt và thông qua các tiến trình kiểm tra.
Cung cấp liên tục cho phép tự đơng hố cao hơn mức chỉ có kiểm thử đơn vị, cho phép lập trình viên kiểm tra việc cập nhật phần mềm ở nhiều khía cạnh khác trước khỉ triển khai tới khách hàng. Kiểm thử bước này có thể bao gồm cả kiểm thử giao diện, kiểm thử tải, kiểm thử tích hợp, kiểm thử tính ổn định của API, … Cái này cho phép mức độ kiểm tra phiên bản cập nhật kĩ càng hơn và có khả năng phát hiện vấn đề sớm hơn.
<b>c) Triển khai liên tục</b>
Triển khai liên tục là mức độ tự động hoá cao hơn cung cấp liên tục. Mã nguồn khi có thay đổi sẽ được phát hành tự động hoàn toàn tới người dùng ngay sau khi các bài kiểm thử đặt trước thành công. Ở đây không thể có sự can thiệp để biến thành thủ cơng, đấy là điểm khác biệt rõ nhất của cung cấp liên tục và triển khai liên tục, vì vậy các bài kiểm thử cũng phải tự động hoàn toàn mà khơng có sự can thiệp của con người trong q trình kiểm thử.
<b>d) Hạ tầng triển khai</b>
Sau khi kết thúc pipeline CI/CD, nghĩa là phần mềm đã chạy được, thì để triển khai cho khách hàng, người dùng thì cần phải có một hạ tầng để phần mềm chạy trên nó. Tuy nhiên hạ tầng khơng có bất kì giới hạn nào, có thể là một máy chủ vật lí, có thể là một máy ảo, có thể làm một hệ thống container orchestration. Tuy nhiên để có thể lấy được nhiều lợi ích nhất thì các hệ thống container orchestration sẽ là nổi bật nhất về các lợi ích thu lại được sau khi triển khai, với vô hạn các khả năng có thể làm được với ứng dụng sau khi triển khai.
<b>e) Giám sát</b>
Giám sát trong DevSecOps bao trọn tồn bộ quy trình phát triển, từ kế hoạch, phát triển, tích hợp và kiểm thử đến triển khai, vận hành. Cung cấp một cái nhìn tổng thể và theo thời gian thực trạng thái của ứng dụng, dịch vụ và hạ tầng trong môi trường production. Các chức năng như theo dõi thời gian thực, xem lại lịch sử và hình tượng hố là thành phần tất yếu của việc giám sát phần mềm, dịch vụ.
Giám sát cũng cho phép các đội nhóm phản ứng nhanh và tự động với bất kì sự giảm sút nào về trải nghiệm của khách hàng. Quan trọng hơn nữa, cho phép các giai đoạn phát triển được tập trung hơn để giảm lượng hỏng hóc sinh ra trong mơi trường production.
Theo dõi các metric để biết được ảnh hưởng của hiệu năng ứng dụng và hạ tầng tới trải nghiệm của người dùng. Thu thập, phân loại và phân tích dữ liệu sinh ra bởi phần mềm và hạ tầng sẽ giúp các tổ chức hiểu hơn thay đổi hoặc cập nhật đã ảnh hưởng đến người dùng như nào, thấu hiểu được gốc rễ của các vấn đề sinh ra hoặc thay đổi ngồi dự kiến. Theo dõi tích cực (active monitoring) ngày càng trở nên quan trọng bởi dịch
</div><span class="text_page_counter">Trang 25</span><div class="page_container" data-page="25">vụ phải đảm bảo 24/7 và ứng dụng, hạ tầng liên tục được cập nhật. Thêm khả năng báo động và phân tích theo thời gian thực các dữ liệu này càng cho phép kiểm soát các dịch vụ tốt hơn.
<b>1.2.4. DevSecOps như quy trình trong phát triển phần mềm</b>
Như đã nói ở trên, DevOps và DevSecOps là một khái niệm tổng hợp của văn hoá, cách thức và cơng cụ.
Nếu chỉ nói ở mặt cách thức, hay coi như DevSecOps là một quy trình có thể áp dụng được vào trong quy trình phát triển phần mềm, với các công nghệ và công cụ liên quan thì có thể nói DevSecOps có thể áp dụng rất sâu, rất tốt và hiệu quả, cả với phần mềm monolithic lẫn microservice.
Quay lại về mơ hình monolithic, mặc dù đúng là tất cả các dịch vụ ở trong đều sẽ được đóng gói lại thành một khối duy nhất (ví dụ thành một file nhị phân chạy được) nhưng vậy trong các giai đoạn phát triển sẽ như nào?
<b>a) Triển khai truyền thống</b>
Ở ngay bước đầu tiên của phát triển, coi như giai đoạn thiết kế đã hoàn tất, vậy một ứng dụng cho doanh nghiệp lớn sẽ có nhiều người cùng lập trình, ví dụ là sản phẩm đang sử dụng SpringBoot, Java 11 kèm với MySQL 8.0.35. Để đảm bảo môi trường phát triển giống hệt nhau khi code, sẽ phải cài chính xác tất cả các phiên bản của các công cụ trên cho mọi máy để khi chạy, môi trường giống hệt nhau. Việc đảm bảo này sẽ là quản lí bằng tay, hoặc một phần tự động bằng các cấp máy tính cài sẵn mơi trường cho lập trình viên. Và việc phát triển hầu như sẽ kẹt ở chuỗi công nghệ này, hầu như không nâng cấp được lên các bản cập nhật mới hơn của công nghệ hay ứng dụng các công nghệ mới khác.
Tiếp theo, ở công đoạn xây dựng ứng dụng sau khi lập trình viên làm xong, sẽ là các đoạn kiểm thử, xây dựng, tiếp tục là các công đoạn chạy bằng tay hoặc bán tự động với một dạng script nào đó. Sẽ yêu cầu ít nhất một người của đội vận hành lấy mã nguồn, chạy lệnh build, kiểm tra xem build thành công khơng? Sau đó chuyển sang cho đội kiểm thử để kiểm thử ứng dụng sau khi build đó.
Tiếp tục, sau khi kiểm thử xong, nếu đạt mọi chỉ tiêu sẽ đến cơng đoạn triển khai. Tiếp tục lại có một người ở đội vận hành, chuyển tiếp file nhị phân chạy được sau build đã được kiểm thử đó lên máy chủ đang chạy sẵn ứng dụng đó để cập nhật – lại là một việc làm thủ công hoặc bán tự động. Và đặc biệt rủi ro lớn nếu như bản cập nhật khi chạy trên máy chủ lại lỗi (ví dụ do thiếu một thư viện nào đó mới thêm vào ở giai đoạn phát triển), gây ra downtime cho dịch vụ mà khách hàng sử dụng.
Ở trong môi trường production, theo dõi sức khoẻ của ứng dụng khi triển khai dạng truyền thống gần như là khơng có hoặc rất ít vì hầu như chỉ có hai trạng thái: ứng dụng có chạy, và ứng dụng khơng chạy. Tất nhiên có thể áp dụng ghi log ra file, hoặc báo lỗi ra terminal, nhưng hầu hết theo dõi chỉ hạn chế ở dạng theo dõi xem phần cứng có đầy khơng, có chậm khơng, ứng dụng cịn “sống” khơng.
</div><span class="text_page_counter">Trang 26</span><div class="page_container" data-page="26">Cuối cùng, vậy nếu đang triển khai ứng dụng dạng truyền thống trên một máy chủ vật lý, hoặc một máy ảo. Vậy nếu lượng người dùng tăng giảm thì sao? Nếu cần giảm thì có thể đành chịu lãng phí tài ngun, nhưng nếu tăng thì rất khó, thường bắt buộc phải có downtime do phải dừng hoàn toàn máy ảo để cấp thêm tài nguyên, hoặc dừng hẳn máy thật để lắp thêm phần cứng.
Tất cả các điểm trừ trên, có các cách khắc phục phần nào đó, tuy nhiên đều chỉ mang lại lợi ích nhỏ, và các giai đoạn đều có sự tác động của con người đáng kể, từ phát triển đến vận hành, mà lỗi con người là lỗi rất dễ xảy ra.
<b>b) Triển khai theo một quy trình DevSecOps</b>
Đầu tiên, những gì ở trong quy trình truyến thống có thể thay đổi để áp dụng vào quy trình DevSecOps?
Giai đoạn phát triển, việc kẹt ở cơng nghệ như Java 11, Spring Boot hay MySQL 8.0.35 thì vẫn không thể thay đổi. Tuy nhiên việc tạo môi trường để lập trình viên làm việc và thử nghiệm sẽ dễ hơn nhiều. Đội vận hành đơn giản sẽ tạo một Docker image gồm đầy đủ và đã cài sẵn mọi mơi trường cần thiết, khi lập trình viên muốn thử nghiệm trên máy cá nhân, chỉ cần có Docker image là có thể build được ứng dụng mà khơng cần phải suy nghĩ là có thiếu thư viện A, phần mềm B hay không nữa. Và tất cả các máy có thể được triển khai điều này rất nhanh và đơn giản, hầu như chỉ với một lệnh duy nhất để lấy Docker image. Từ đó khơng cịn phải lo vấn đề như nhân viên mới cài sẵn Java 17 mới mất rồi hay MySQL tự động cập nhật lên bản mới hơn trên máy cá nhân.
Vậy sau khi lập trình xong, lập trình viên đã cho mã nguồn lên trên git repository của dự án, việc xây dựng và kiểm thử thì sao?
Các đoạn kiểm thử có thể được tự động hoá cùng với việc tự động hoá xây dựng. Ở đây biến thành một mảnh của giai đoạn CI. Chính Docker image dùng cho lập trình viên, có thể sử dụng để build thành phiên bản mới bằng công cụ CI tự động, các công cụ này cho phép tự động hố hồn tồn giai đoạn build bằng cách tự nhận biết thay đổi theo git commit. Thêm vào đó cũng cho phép chạy cơng cụ kiểm thử tự động trên giai đoạn build này, vởi khả năng theo dõi q trình build để biết có lỗi có xảy ra hay khơng. Giai đoạn này cũng có thể do chính lập trình viên làm mà khơng cần sự giúp đỡ của người khác khi hạ tầng đã được cấu hình đúng.
Sau giai đoạn này, cơng cụ CI đã sinh ra được một binary chạy được, hoặc phổ biến nhất là một Docker image chạy được. Vậy triển khai thì sao?
Triển khai cũng có thể biến trở thành một thao tác tự động hồn tồn. Ví dụ khi đã có một hệ thống triển khai container. Phiên bản cũ có thể đang chạy sẵn, khi cập nhật, hệ thống sẽ tự động lấy phiên bản mới (tự động có chọn lọc), chạy trên hệ thống cho đến khi ứng dụng thực sự chạy được thì mới dừng và tắt phiên bản cũ. Điều này nghĩa là khơng có bất kì downtime nào cả, kể cả một giây. Trong trường hợp bản mới lỗi khi triển khai như này thì cũng khơng ảnh hưởng gì vì bản cũ vẫn sẽ chạy cho đến khi nào
</div><span class="text_page_counter">Trang 27</span><div class="page_container" data-page="27">bản mới hoàn toàn chạy được. Thêm nữa nếu trong trường hợp bất khả kháng phải hạ phiên bản về bản cũ thì cũng khơng sinh ra downtime và tốn nhiều công sức.
Theo dõi ứng dụng sau khi triển khai thành cơng cũng có rất nhiều cơng cụ để giám sát rất nhiều metric khác nhau, từ phần cứng đến phần mềm. Tuy nhiên với ứng dụng dạng monolithic đang nói thì chủ yếu sẽ là các metric liên quan đến lượng người dùng, hoặc lỗi trả về là gì, cịn việc xác định lỗi ở đâu thì vẫn khó khăn do toàn bộ ứng dụng vẫn là một khối duy nhất.
Cuối cùng là khả năng scale, có thể scale tuỳ ý bằng tay, hoặc tự động theo số lượng người dùng, lượng tải hoặc nhiều yếu tố khác. Bởi vì các hệ thống triển khai container có khả năng mở rộng gần như vô hạn, kể cả khi yêu cầu thêm phần cứng mới vẫn sẽ không gây ra downtime. Nhưng tất nhiên việc scale lúc này vẫn là scale cả ứng dụng trong một lần, dù đã tiết kiệm tài nguyên hơn trước nhưng vẫn chưa tối ưu nhất.
Triển khai theo quy trình DevSecOps, kể cả với một ứng dụng monolithic từ trước đó, vẫn mang lại vơ cùng nhiều lợi ích vì nó loại bỏ đi các thao tác lặp đi lặp lại mà trước đây phải làm thủ công, loại bỏ được yếu tố lỗi con người khi mọi thứ được cấu hình đúng và đủ. Tuy nhiên các hạn chế vẫn tồn tại do sự giới hạn của mơ hình ứng dụng monolithic.
<b>c) Quy trình DevSecOps với mơ hình microservice</b>
Bài tốn đặt ra: nếu ứng dụng trên chuyển sang mơ hình microservice thì sao?
Ứng dụng đó, kể cả vẫn viết hết dùng SpringBoot đi chăng nữa, khi áp dụng mơ hình microservice sẽ cho phép ứng dụng này phát triển vượt ra ngồi chuỗi cơng nghệ cũ gồm SpringBoot, Java và MySQL.
Bởi vì các microservice là độc lập, và giao tiếp qua mạng, nên hoàn toàn có thể nâng cấp, mở rộng ứng dụng dùng các cơng nghệ khác hồn tồn, thêm một microservice viết bằng Django và SQLite làm cơ sở dữ liệu, một microservice khác viết bằng Ruby và tất cả vẫn sẽ hoạt động được với nhau mà khơng có rào cản về cơng nghệ nữa. Từ đó dễ dàng thích ứng và chuyển đổi sang các công nghệ mới mà vẫn không mất khả năng sử dụng với các dịch vụ viết bằng công nghệ cũ.
Áp dụng CI với microservice cũng đưa lại rất nhiều lợi ích, đặc biệt bởi tính tự động hố của CI. Khi nhìn vào CI trong monolithic, khơng thấy có q nhiều lợi ích, bởi bản chất lượng build vẫn chỉ là một ứng dụng chứa rất nhiều dịch vụ duy nhất. Tuy nhiên microservice, có thể có hàng chục, thậm chí cả trăm dịch vụ, nếu tất cả đều build một cách thủ cơng thì việc áp dụng microservice khơng đưa lại một lợi ích gì, chưa kể vào đó, microservice mà khơng đi kèm với container, thì lại càng vơ nghĩa. Vì vậy áp dụng CI vào quy trình phát triển ứng dụng mơ hình microservice là cấp thiết và giúp sử dụng tối đa lợi ích của mơ hình này.
Khả năng theo dõi giám sát sẽ ở mức sâu hơn do có thể lấy được metric từ từng microservice một, cho phép kiểm soát ứng dụng theo từng thành phần của nó, dễ dàng
</div><span class="text_page_counter">Trang 28</span><div class="page_container" data-page="28">tìm kiếm, tìm và đốn được lỗi đến từ đâu, do dịch vụ nào kể cả sau khi triển khai ở mơi trường thực tế và có người dùng đang sử dụng.
Triển khai và khả năng scale là cả một bước tiến lớn hồn tồn, bởi vì kể cả khi áp dụng quy trình tự động và triển khai DevSecOps đi chăng nữa, khi một dịch vụ con trong monolithic hỏng thì cả ứng dụng vẫn sẽ “chết”. Microservice giải quyết vấn đề này trọn vẹn khi các dịch vụ con đều được biến thành các microservice độc lập. Một hoặc vài dịch vụ hỏng? Các dịch vụ khác vẫn sẽ không bị ảnh hưởng và vẫn chạy bình thường, ít nhất là các chức năng khơng cần gọi đến dịch vụ đã hỏng. Khả năng scale thì cũng hiệu quả và tối ưu hơn nhiều do từng microservice có thể scale một cách độc lập theo nhu cầu của chính microservice đó. Từ đó tiết kiệm hơn và tối ưu hơn về tài nguyên.
<b>1.3. Công nghệ sử dụng</b>
<b>1.3.1. Hệ thống quản lí mã nguồn và Gitea</b>
Hệ thống quản lí mã nguồn sử dụng để theo dõi các thay đổi xảy ra trong một repository mã nguồn. Cho phép lưu trữ lại lịch sử các thay đổi và giải quyết tranh chấp xảy ra khi ghép mã nguồn lại từ nhiều người khác nhau. Để đảm bảo việc đội nhóm làm việc hiệu quả, hệ thống quản lí mã nguồn là tất yếu thay cho tất cả việc giao tiếp và quản lí mã nguồn bằng tay.
<b>a) Tầm quan trọng của hệ thống quản lí mã nguồn</b>
Khi có nhiều người cùng làm trên một dự án, sẽ có trường hợp hai hoặc nhiều người cùng sửa một file mã nguồn cùng lúc. Hai người có thể đang làm các chức năng khác hẳn nhau và cô lập với nhau, nhưng lại cùng sử dụng chung một module nào đó. Vậy người 1 đang làm chức năng 1, có thể sẽ chỉnh sửa một file cùng với người 2 đang làm chức năng 2.
Trước khi có hệ thống quản lí mã nguồn, xung đột khi cùng chỉnh sửa một file có thể dẫn đến mất mát dữ liệu. Bởi chỉ có các dạng giao thức lưu trữ file phổ thơng như FTP, khơng có lịch sử nào lưu lại, người 1 có thể ghi đè lên những gì người 2 đã chỉnh sửa khi cùng phải sử dụng một file đó, dẫn đến mọi thay đổi của người 2 mất hồn tồn do bị ghi đè.
Hệ thống quản lí mã nguồn với khả năng quản lí phiên bản bảo đảm khỏi việc mất mất dữ liệu vì xung đột ghi đè file. Đảm bảo bằng cách theo dõi mọi sự thay đổi từ mọi người và phát hiện ra các chỗ có xung đột và chống ghi đè. Và hệ thống sẽ cho phép người dùng dễ dàng kiểm định các chỗ có xung đột và xử lí một cách an tồn.
Ngồi ra, hệ thống cũng có cung cấp tồn lịch sử thay đổi của mã nguồn, cho phép tìm kiếm và xác định được lần chỉnh sửa nào đã gây ra lỗi hoặc giảm chất lượng phần mềm.
<b>b) Lợi ích của hệ thống quản lí mã nguồn</b>
</div><span class="text_page_counter">Trang 29</span><div class="page_container" data-page="29">Hệ thống quản lí mã nguồn ln đi kèm theo các công cụ giúp việc phối hợp công việc thân thiện cho người sử dụng hơn. Từ việc hệ thống theo dõi sự thay đổi của mã nguồn sẽ cho phép sinh ra một lịch sử chi tiết về những thay đổi. Và lịch sử này cho phép lùi lại những thay đổi gây ra lỗi, hỏng một cách rất đơn giản, cho phép chống lỗi diễn ra liên tục trên nhiều bản cập nhật và sửa lỗi dễ dàng hơn.
Lịch sử cũng có thể được sử dụng để sinh ra danh sách thay đổi giữa các phiên bản. Vừa có thể giúp người dùng biết điều gì đã thay đổi qua các bản cập nhật và tiến độ của dự án.
Loại bỏ được tiêu tốn thời gian do giao tiếp khi ghép mã nguồn thủ công, tăng tốc độ cung cấp sản phẩm, cho phép nhiều người làm việc cùng lúc, song song và độc lập trên nhiều tính năng khác nhau và có thể ghép lại sau đó.
<b>c) Git</b>
Thực tế hiện tại, hệ thống quản lí mã nguồn phổ biến nhất thế giới là Git. Git là một dự án mã nguồn mở vẫn đang được liên tục phát triển, phát triển đầu tiên bởi cha đẻ nổi tiếng của Linux kernel Linus Torvalds.
Một lượng khổng lồ các dự án phần mềm hiện nay phụ thuộc vào Git để quản lí mã nguồn, từ dự án thương mại đến các dự án mã nguồn mở. Git có thể hoạt động trên hầu hết các hệ điều hành và các IDE phổ biến.
Git sử dụng kiến trúc phân tán, là một điển hình của hệ thống quản lí mã nguồn phân tán. Khác với các hệ thống cũ mà chỉ chứa thay đổi trong mã nguồn ở một chỗ duy nhất như CVS hoặc Subversion (cịn có tên khác là SVN), khi dùng Git, mỗi người có bản sao của tồn bộ repository mã nguồn cũng đều có toàn bộ lịch sử thay đổi.
Git cũng được thiết kế để đảm bảo hiệu năng, bảo mật và tính linh hoạt.
Sử dụng Git làm lõi, rất nhiều các dịch vụ đã được sinh ra như GitHub, GitLab, BitBucket. Các dịch vụ này sinh ra nhằm cung cấp một giao diện web hồn chỉnh hơn cho Git với nhiều các tính năng hỗ trợ khác giúp làm việc với Git dễ dàng hơn.
<b>d) Gitea</b>
<i>Hình 1.4 Logo Gitea</i>
</div><span class="text_page_counter">Trang 30</span><div class="page_container" data-page="30">Gitea là một dịch vụ self-hosted cho quy trình phát triển phần mềm với rất nhiều tính năng và dễ dàng có thể cài đặt nhanh chóng.
Các chức năng chính của Gitea:
- Nơi chứa mã nguồn: Gitea cho phép tạo và quản lí repository, duyệt lịch sử commit và các file mã nguồn, duyệt và merge mã nguồn, quản lí cộng tác viên, quản lí nhánh và nhiều tính năng khác. Cũng như kèm theo các tính năng phổ biến của Git như tag, cherry-pick, hook, …
- Nhẹ và nhanh: Mục tiêu thiết kế của Gitea là đạt được phản hồi nhanh và nhẹ nhất có thể để có thể hoạt động trên các mơi trường máy chủ có giới hạn tài ngun.
- Dễ triển khai và bảo trì: Có thể dễ dàng triển khai với nhiều máy chủ khác nhau mà khơng cần cấu hình phức tạp hoặc lo đến các thư viện, phần mềm phụ thuộc khác, từ đó cho phép kể cả các đội nhóm nhỏ cũng có thể tự dựng lên các dịch vụ Git dành riêng cho nhóm.
- Bảo mật: Gỉtea cung cấp các tính năng liên quan đến an tồn thơng tin như quản lí quyền người dùng, danh sách quyền truy cập và nhiều tính năng liên quan để đảm bảo an tồn cho mã nguồn và dữ liệu.
- Chức năng đánh giá mã nguồn: Cho phép người dùng xem, đánh giá và duyệt các luồng làm việc dạng Pull request hoặc Agit. Người đánh giá có thể duyệt mã nguồn online và cung cấp bình luận đánh giá hoặc phản hồi. Những người lập trình thì có thể nhận được các bình luận và phản hồi, hoặc chỉnh sửa mã nguồn online trực tiếp. Giúp cho cá nhân và tổ chức tăng chất lượng mã nguồn. - CI/CD: Gitea có hỗ trợ các tính năng cho luồng CI/CD, tương thích với Github
Actions. Người dùng có thể viết luồng làm việc trong định dạng YAML quen thuộc và dùng lại nhiều plugin có sẵn từ Github Actions. Tuy nhiên chức năng này vẫn đang trong giai đoạn thử nghiệm.
- Quản lí dự án: Gitea có thể theo dõi các yêu cầu, chức năng và lỗi của dự án. - Artifact Repository: Gitea hỗ trợ hơn 20 kiểu quản lí gói phần mềm, bao gồm
Cargo, Chef, Composer, Conan, Conda, Container, Helm, Maven, npm, NuGet, Pub, PyPI, RubyGems, Vagrant,...
- Mã nguồn mở với cộng đồng: Gitea là một dự án mã nguồn mở, dùng giấy phép MIT. Có một cộng đồng mã nguồn mở rộng rãi và liên tục nâng cấp và phát triển.
- Đa ngôn ngữ : Hỗ trợ nhiều ngôn ngữ trong giao diện, cho phép dễ tiếp cận người dùng trên toàn cầu.
</div><span class="text_page_counter">Trang 31</span><div class="page_container" data-page="31"><b>1.3.2. Jenkins</b>
<i>Hình 1.5 Logo Jenkins</i>
Jenkins là một phần mềm máy chủ tự động hoá mã nguồn mở. Sử dụng để tự động hố các cơng đoạn trong phát triển phần mềm liên quan đến xây dựng, kiểm thử và triển khai, hỗ trợ tích hợp liên tục và cung cấp liên tục.
Jenkins có thể hoạt động dưới dạng là một máy chủ trên nhiều hệ điều hành: Windows, macOS, Linux và Unix. Bản thân Jenkins thì là một phần mềm tự đóng gói, chủ yếu viết bằng Java.
<b>a) Jenkins Plugin</b>
Các plugin là một phần đã giúp Jenkins có khả năng mở rộng rất lớn, từ việc thêm tính năng, hay tích hợp Jenkins với các hệ thống khác đều có thể sử dụng plugin để thêm vào. Có thể tải các plugin từ UI web hoặc CLI của Jenkins. Tính đến thời điểm viết đồ án này, Jenkins đã có hơn 1800 plugin trên repository có thể tải về.
Plugin có thể thêm vào các giao diện mới cho web Jenkins, giúp quản trị Jenkins nhiều tính năng hơn, nâng cao khả năng của Jenkins trong việc build và quản lí mã nguồn. Một cách dùng plugin rất phổ biến là để cung cấp khả năng tích hợp vào trong một luồng CI/CD. Như là khả năng tích hợp với các dịch vụ Git phổ biến Github, GitLab, Gitea, với các container runtime như Docker, hypervisor cho máy ảo như QEMU, VMware vSphere, hay các dịch vụ public cloud như AWS, Google Cloud Platform, Microsoft Azure, private cloud như Red Hat OpenStack. Cũng có các plugin giúp kết nối đến các hệ điều hành qua các giao thức như FTP hay SSH.
<b>b) Jenkins Pipeline</b>
Pipeline là chức năng quan trọng nhất của Jenkins. Một pipeline là một danh sách các bước mà một máy chủ Jenkins sẽ thực hiện để hoàn thành các thao tác cần thế cho một chu trình CI/CD. Nếu nói ở trong Jenkins thì pipeline là một tập hợp các công việc (hoặc sự kiện) liên kết với nhau và có thứ tự.
Jenkins Pipeline thì được viết dưới dạng Pipeline DSL, tức là cho phép tạo quy trình CI/CD giống như lập trình. Có nhiều cách để định nghĩa file Jenkinsfile – chính là file chứa các thao tác muốn Jenkins thực hiện, tuy nhiên cách thông thường dùng nhất là
</div><span class="text_page_counter">Trang 32</span><div class="page_container" data-page="32">viết trực tiếp Jenkinsfile trước, sau đó đưa vào trong một repository của hệ thống quản lí mã nguồn nào đó, chẳng hạn cho vào một repository của Git.
Pipeline của Jenkins thì cũng khơng có giới hạn gì về vấn đề ngơn ngữ lập trình, nhất là khi kết hợp với Docker. Dùng Jenkins như là một công cụ CI để build image Docker, tích hợp cùng với một máy chủ quét chất lượng mã nguồn khác là đều có thể thực hiện được một cách tự động hố hồn tồn sau khi đã viết Jenkinsfile và cấu hình Pipeline đúng.
Jenkins cũng cho phép lưu lại các bản artifact, các file sinh ra trong quá trình thực hiện Pipeline. Các bản artifact này cho phép tải về để có thể chạy trên mơi trường khác, ví dụ một lập trình viên có thể tải về và kiểm tra xem tại sao có lỗi xảy ra trong chạy ứng dụng ở các giai đoạn sau.
Pipeline của Jenkins sẽ tự chạy sau khi nhận được thông báo từ webhook kết nối từ hệ thống quản lí mã nguồn, nghĩa là bất kì thay đổi nào được đưa lên trên repository mã nguồn đều sẽ được build bằng Jenkins tự động. Đây là cách làm phổ biến nhất và hiệu quả nhất của Jenkins để đạt được tích hợp liên tục.
<b>1.3.3. SonarQube</b>
<i>Hình 1.6 Logo SonarQube</i>
SonarQube là công cụ tự động kiểm tra chất lượng mã nguồn để thực hiện kiểm thử tĩnh mã nguồn, phát hiện lỗi và đánh giá chất lượng mã nguồn. SonarQube hỗ trợ khá nhiều ngôn ngữ lập trình, đối với bản Community mã nguồn mở bao gồm: Java, C#, JavaScript, TypeScript, CloudFormation, Terraform, Docker, Kubernetes, Kotlin, Ruby, Go, Scala, Flex, Python, PHP, HTML, CSS, XML, VB.NET and Azure Resource Manager.
Các dạng báo cáo sau khi quét mã nguồn mà SonarQube có thể cung cấp là: mã nguồn trùng lặp, mã nguồn có viết đúng theo tiêu chuẩn không, kiểm thử đơn vị, độ phủ của các bài kiểm thử trong toàn bộ mã nguồn, độ phức tạp mã nguồn, phát hiện lỗi và đề xuất cho các vấn đề bảo mật khác.
SonarQube cũng có thể được tích hợp kèm vào các cơng cụ CI như Jenkins để cho phép tự động hoá quy trình kiểm tra ngay trong pha tích hợp liên tục của một quy trình CI/CD.
Cũng có thể cài đặt quality gate trong SonarQube: nghĩa là một danh sách mức độ các chất lượng trong mã nguồn mà SonarQube có thể cung cấp như lỗi, lỗ hổng bảo mật, chất lượng mã nguồn, độ phủ, … Và có thể sử dụng SonarQube để chặn hoặc thông
</div><span class="text_page_counter">Trang 33</span><div class="page_container" data-page="33">báo các merge các pull request không đảm bảo chất lượng để tránh đưa các phần mã nguồn khơng tốt đó vào trong repository mã nguồn.
<b>1.3.4. Harbor</b>
<i>Hình 1.7 Logo Harbor</i>
Harbor là một dự án cloud native registry mã nguồn mở, có thể chứa, kí và qt nội dung trong nó. Harbor mở rộng khả năng từ Docker Distribution mã nguồn mở bằng cách thêm các tính năng thường yêu cầu bởi người dùng như bảo mật, quản lí người dùng. Có một registry gần mới môi trường build và môi trường chạy thực tế có thể nâng cao tính hiệu quả của việc truyền image. Harbor cũng hỗ trợ tạo bản sao của image giữa nhiều registry, và cũng có các tính năng bảo mật nâng cao như quản lí người dùng, quản lí quyền truy cập và kiểm tra các thao tác trên hệ thống.
Tính năng của Harbor:
- Cloud native registry: Hỗ trợ chứa cả container image và Helm chart. Harbor đóng vai trị là một registry cho mơi trường cloud native như các container runtime hoặc các nền tảng orchestration.
- Phân quyền truy cập dựa theo chức danh: Người dùng có thể truy cập vào các repository khác nhau qua các “project” và một người dùng có thể có nhiều quyền hạn khác nhau cho image hay Helm chart trong một project.
- Tạo bản sao dựa theo chính sách: Image và chart có thể được tạo bản sao (chính là đồng bộ) giữa nhiều registry khác nhau dựa theo chính sách đặt ra bằng các dùng bộ lọc (theo repository, tag hoặc label). Harbor sẽ tự động thử thực hiện lại việc đồng bộ nếu như có lỗi xảy ra. Chức năng này cho phép hỗ trợ trong cân bẳng tải, đạt được HA và cho phép việc triển khai Harbor ở các hạ tầng khác nhau, cả on-promise, hybrid hoặc cloud.
- Quét lỗ hổng bảo mật: Harbor có thể thực hiện việc quét lỗ hổng bảo mật của image và có thể đặt các cấu hình để chặn triển khai các image có lỗ hổng bảo mật.
- Hỗ trợ LDAP/AD: Harbor có thể tích hợp vào các hạ tầng doanh nghiệp LDAP/AD có sẵn để quản lí, xác thực người dùng và phân quyền.
- Hỗ trợ OIDC: Harbor cũng có thể sử dụng OIDC để xác thực người dùng bằng các dịch vụ xác thực, đăng nhập bên ngồi. Có thể cho phép single sign-on để đăng nhập vào Harbor.
- Xoá image và dọn rác: Cho phép quản trị viên sử dụng các công cụ dọn rác để dọn những image cũ, không cần thiết và không sử dụng để tiết kiệm tài nguyên.
</div><span class="text_page_counter">Trang 34</span><div class="page_container" data-page="34">- Hỗ trợ kí image bằng Docker Content Trust (sử dụng Notary): Đảm bảo tính toàn vẹn của image trên hệ thống, tránh các image giả, hoặc khơng có chữ kí số có thể được triển khai.
- Giao diện người dùng dễ sử dụng cho việc duyệt, tìm kiếm và quản lí các dự án.
- Tất cả các hoạt động trên hệ thống đều được ghi log lại, cho phép kiểm định về sau.
- Có RESTful API cung cấp cho phép tích hợp các hệ thống ngồi vào Harbor dễ dàng hơn. Có bộ cơng cụ Swagger UI nhúng sẵn ở trong Harbor cho phép thử nghiệm với các API.
- Dễ dàng triển khai: Có thể triển khai bằng Docker Compose và Helm Chart.
<b>1.3.5. Trivy</b>
<i>Hình 1.8 Logo Trivy</i>
Trivy chính là trình qt lỗ hổng bảo mật có thể tích hợp và cài đặt cùng với Harbor. Những gì Trivy có thể qt và tìm ra:
- Các gói phần mềm của hệ thống và các thư viện phụ thuộc đang dùng (SBOM). - Các lỗ hổng bảo mật đã được phát hiện (CVE).
- Các vấn đề và cấu hình sai của IaC.
- Thơng tin cần bí mật (như mật khẩu, token). - Giấy phép phần mềm.
Việc cho phép Trivy quét các image có trên Harbor sẽ cho phép có được thơng tin về mức độ an tồn của các container image có trên đó, và từ đó có thể đưa ra các lựa chọn như có triển khai hay khơng, lỗi ở chỗ nào, lỗ hổng bảo mật này do vấn đề nào gây ra và có thể sửa bằng cách nào.
Trivy cũng cho phép tồn bộ quy trình đảm bảo về tính an tồn thông tin và bảo mật hơn.
</div><span class="text_page_counter">Trang 35</span><div class="page_container" data-page="35"><b>1.3.6. Argo CD</b>
<i>Hình 1.9 Logo Argo CD</i>
Argo CD là một công cụ cung cấp liên tục cho Kubernetes theo tư tưởng GitOps. Định nghĩa ứng dụng, cấu hình và mơi trường nên có tính miêu tả cao và được quản lí theo phiên bản. Việc triển khai ứng dụng và quản lí vịng đời cũng nên được tự động hoá, dễ dàng kiểm tra và dễ hiểu.
<b>a) Cách Argo CD hoạt động</b>
Argo CD tn theo mơ hình GitOps, sử dụng Git repository làm nguồn sự thật duy nhất để định nghĩa trạng thái mong muốn của ứng dụng, Manifest của Kubernetes có thể định nghĩa theo nhiều cách:
- Ứng dụng kustomize - Helm chart
- File jsonnet
- Thư mục YAML/JSON manifest
- Các định dạng tuỳ biến khác được cấu hình như là một plugin.
Argo CD tự động hoá việc triển khai ứng dụng theo một trạng thái mong đợi trên một môt trường mục tiêu định trước. Các ứng dụng đã được triển khai có thể được cập nhật cách thức, trạng thái triển khai thông qua việc thay đổi những thông tin mong muốn bằng Git.
<b>b) Kiến trúc của Argo CD</b>
</div><span class="text_page_counter">Trang 36</span><div class="page_container" data-page="36"><i>Hình 1.10 Kiến trúc tổng quan của Argo CD</i>
Argo CD được cài đặt như một Controller của Kubernetes, sẽ liên tục giám sát ứng dụng đang chạy, và so sánh trạng thái thực tế đó với trạng thái mong đợi đã định nghĩa ở trong Git repo. Một ứng dụng đã triển khai, nhưng lại có trạng thái thực tế khác với trạng thái mong đợi đó thì coi như bị OutOfSync. Argo CD sẽ có báo cáo lại sự khác biệt này, và cung cấp khả năng tự động hoặc thủ công đồng bộ lại trạng thái thực tế về trạng thái mong đợi. Bất kì thay đổi nào đến trạng thái mong đợi ở trên Git repo sẽ tự động được áp dụng cho mơi trường đích.
<b>c) Thành phần trong kiến trúc của ArgoCD</b>
API Server: là một máy chủ gRPC/REST, mở API cho phép giao diện web, CLI và các hệ thống CI/CD sử dụng. Phụ trách các việc sau:
- Quản lí ứng dụng và báo cáo trạng thái.
- Thực hiện các thao tác lên ứng dụng (đồng bộ, rollback, thao tác người dùng).
</div><span class="text_page_counter">Trang 37</span><div class="page_container" data-page="37">- Quản lí các thơng tin liên quan đến đăng nhập và xác thực repository và cụm (chứa dưới dạng Kubernetes secret).
- Xác thực và cho phép đăng nhập, hoặc cho phép các dịch vụ đăng nhập ngoài xác thực hộ.
- Bắt buộc RBAC.
- Chờ hoặc chuyển tiếp sự kiện webhook từ Git.
Repository Server: là một dịch vụ trong Argo CD đảm bảo một bản đệm nội bộ của Git repo mà chứa các mainfest của ứng dụng. Phụ trách việc tạo và trả về manifest Kubernetes khi được cung cấp các đầu vào sau:
- URL của repository
- Revision (commit, tag, branch)
- Đường dẫn ứng dụng (thường là thư mục trên Git). - Các trường phụ khác.
Application Controller: là một controller của Kubernetes giám sát và so sánh trạng thái thực tế của ứng dụng đã triển khai so với trạng thái mong muốn từ repo. Phát hiện ra trạng thái OutOfSync của ứng dụng và thực hiện các hành động để giải quyết nó. Phụ trách thực hiện các thao tác người dùng có thể đặt ra trong các trường hợp xảy ra trong vòng đời ứng dụng mà Argo CD quản lí (PreSync, Sync và PostSync).
<b>d) Các tính năng quan trọng của Argo CD</b>
- Tự động triển khai đến mơi trường đích.
- Hỗ trợ nhiều dạng đầu vào và cơng cụ cấu hình (Kustomize, Helm, Jsonnet, YAML).
- Có thể quản lí và triển khai trên nhiều cụm.
- Có thể tích hợp SSO (OIDC, OAuth2, LDAP, SAML 2.0, GitHub, GitLab, Microsoft, LinkedIn).
- Cho phép rollback cho các ứng dụng cấu hình trên Git. - Phân tích sức khoẻ tài nguyên của ứng dụng.
- Đồng bộ tự động hoặc thủ công trạng thái ứng dụng mong muốn.
- Giao diện web cho phép theo dõi trong thời gian thực các hoạt động của ứng dụng.
- CLI cho tự động hố và tích hợp với các cơng cụ CI.
<b>1.3.7. Kubernetes</b>
<i>Hình 1.11 Logo Kubernetes</i>
</div><span class="text_page_counter">Trang 38</span><div class="page_container" data-page="38">Kubernetes ngắn gọn nhất, thì là hai thứ sau:
- Là một cụm hạ tầng cho phép chạy ứng dụng trên nó.
- Là một “nhạc trưởng” lo cho việc triển khai và quản lí ứng dụng. Quy trình đơn giản nhất để chạy ứng dụng trên Kubernetes:
- Bước 1: Viết ứng dụng theo mơ hình microservice.
- Bước 2: Đóng gói mỗi microservice vào container của riêng nó. - Bước 3: “Bọc” mỗi container đấy vào thành một Kubernetes Pod.
- Bước 4: Triển khai các Pod đó bằng các trình điều khiển cấp cao như: Deployment, DaemonSet, StatefulSet, CronJob.
Các trình điều khiển có trong Kubernetes cịn có các khả năng như thêm các khả năng tự hồi phục, scaling, rollout cho ứng dụng. Có trình điều khiển sinh ra cho các ứng dụng có trạng thái, và cũng có trình điều khiển dành cho các ứng dụng phi trạng thái. Kubernetes quản lí ứng dụng theo một cách mang tính “miêu tả” là tốt nhất, khi mà mọi thứ muốn triển khai được biến thành một hoặc nhiều file cấu hình, đưa file đó lên Kubernetes và mọi thứ sẽ được thực hiện.
Tuy nhiên Kubernetes không chỉ đơn giản là cứ triển khai ứng dụng lên trên nó, mà nó cịn có khả năng biết được ứng dụng đang chạy và có trạng thái ra sao, có đúng với những cấu hình đã định từ trước trong các file cấu hình khơng, và khi có các trạng thái sai, lỗi đó, Kubernetes cũng sẽ cố thử tự sửa lỗi bằng nhiều cách.
Một cụm Kubernetes thì bao gồm một hoặc nhiều các control plane node và worker
</div>