Prometheus là thành phần quan trọng nhất trong hệ thống giám sát, có nhiệm vụ thu thập các thơng tin về trạng thái của tất cả các máy và ứng dụng. Các thơng tin cần thu thập bao gồm:
• Tài nguyên sử dụng trên các máy triển khai
• Trạng thái các đối tượng trong Kubernetes cluster
• Các thơng tin khác được sinh ra bởi bản thân các ứng dụng
Cơ chế thu thập thông tin của Prometheus là “scrape”. Nghĩa là máy chủ Prometheus sẽ chủ động tải các thông tin về các đối tượng dựa vào các endpoint mà đối tượng cung cấp. Prometheus được cài đặt ngay trong Kubernetes cluster, sử dụng
docker container.
Đối với tài nguyên sử dụng trên máy triển khai, do bản thân hệ điều hành đã lưu
những thơng tin này tại những vị trí xác định trên máy, người dùng chỉ cần tìm cơ chế chuyển đổi những thông tin này sang dạng mà Prometheus có thể đọc được. Với yêu cầu này, luận văn sử dụng dịch vụ node-exporter, cài đặt trên tất cả các máy. Các
thông tin sau khi chuyển đổi sẽ được cung cấp tại port 9100 trên chính các máy đó, với endpoint là /metrics.
Đối với trạng thái các đối tượng trong Kubernetes cluster (như thông tin về pod,
container, service), luận văn sử dụng kube-state-metrics. Kube-state-metrics sẽ lắng nghe các thông tin trạng thái đối tượng từ API server trên master node trong
Kubernetes, chuyển đổi định dạng và cung cấp endpoint /metrics để Prometheus có thể
“scrape”. Cũng như máy chủ Prometheus, kube-state-metrics được cài đặt bằng cách
sử dụng docker container trong Kubernetes cluster.
Đối với các trường thông tin khác sinh ra bởi ứng dụng, luận văn sử dụng cơ chế
gắn các chú thích vào các docker container. Bằng cách sử dụng các thư viện instrumentation, các ứng dụng vi dịch vụ có thể tự định nghĩa các thước đo mới tùy
theo yêu cầu. Máy chủ Prometheus sẽ “scrape” những thông tin này qua endpoint
được cung cấp trong chú thích của docker container.
Ví dụ: thước đo msa_request_count được tích hợp vào trong forex-service và
ccs-service với 2 nhãn success, error để tính số lượng các yêu cầu thành công hay thất bại gửi tới chúng.
Prometheus được cấu hình để gửi thơng tin cảnh báo tới Alert Manager khi trạng thái của hệ thống vượt qua ngưỡng nhất định. Từ Alert Manager, cảnh báo sẽ được gửi
đi thông qua các kênh thông báo khác nhau (trong bài sử dụng Slack). Alert Manager
trong luận văn được chạy bằng docker, tuy nhiên nằm riêng biệt với Kubernetes
ALERT high_error_request
IF msa_request_count{msa_request_count="error"} > 3 FOR 1m
LABELS { severity = "slack" } ANNOTATIONS {
summary = "Number of error request error is too high", description = "Receives lots of error request%. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}.",
}
Trong luận văn, tất các các quá trình cài đặt hệ thống phức tạp này đều được viết bằng Ansible. Việc cài đặt trên một máy hay một nhóm các máy có thể được thực hiện nhanh chóng thơng qua cấu hình trên một tệp duy nhất.
4.2 Đánh giá kết quả
Luận văn được viết dựa trên kết quả làm việc thực tế của tác giả trong quá trình xây dựng giải pháp triển khai liên tục cho hệ thống phần mềm thương mại điện tử của công ty Works Applications Singapore. Kết quả của việc ứng dụng giải pháp triển khai liên tục này được thể hiện qua bảng sau:
Trước khi dùng giải pháp triển khai
Sau khi dùng giải pháp triển khai liên tục
Thời gian triển khai 1 module
15 phút 5 phút Thời gian triển khai
toàn bộ 30 module
5 tiếng 1 tiếng Thời gian từ lúc có
mã mới tới khi triển khai hoàn toàn
30 phút 5 phút Số lần triển khai được thực hiện trong 1 ngày 2-3 lần/module 8-12 lần/module Người thực hiện việc triển khai
Đội vận hành Đội trưởng (leader) của các đội phát triển và các bên liên
quan được cấp quyền (ví dụ: đội quản lý chất lượng)
Qua kết quả đạt được thể hiện trong Bảng 4-1: Kết quả của giải pháp triển khai liên tục, ta có thể thấy một số lợi ích rõ rệt mà nó mang lại như:
• Giảm chu kỳ phát hành sản phẩm (Cycle Time)
Chu kỳ phát hành được tính từ thời gian có u cầu tới khi bản phát hành được
cập nhật trên môi trường sản phẩm. Bằng hệ thống triển khai liên tục, bất cứ một sự thay đổi mã đều có thể được triển khai ngay lập tức ra mơi trường mà khơng gặp khó
khăn gì. Ngay khi nhận yêu cầu người dùng, nhà phát triển có thể phân tích, sửa đổi mã nguồn và gửi yêu cầu hợp nhất mã mới vào nhánh chính để kích hoạt quá trình
triển khai.
Việc triển khai ngồi cách kích hoạt tự động cịn có thể được thực hiện thơng qua giao diện trên Jenkins (chỉ áp dụng cho người dùng với quyền hạn phù hợp). Với cách sử dụng đơn giản, hệ thống sau khi được cài đặt không đòi hỏi chuyên gia về triển khai
để quản lý mà trách nhiệm có thể được phân phối về từng đội. Điều này cũng góp phần
khuyến khích việc thực hiện cập nhật với tần suất cao hơn, từ đó cải thiện chu kỳ phát hành thay đổi của sản phẩm.
• Tăng năng suất lao động
Tăng năng suất là lợi ích rõ nhất của hệ thống triển khai liên tục. Việc triển khai thường xuyên giúp tổ chức phát hiện ra các vấn đề và nhận được phản hồi sớm từ
người dùng, từ đó đưa ra các giải pháp phù hợp trong thời gian sớm nhất. Bằng việc tự
động hố q trình build, kiểm thử cũng như cung cấp các công cụ triển khai dễ dàng,
các nhà phát triển có thể tập trung vào việc phát triển tính năng còn các đội vận hành
cũng giảm thiểu thời gian giám sát hệ thống để tập trung vào nâng cao chất lượng các dịch vụ khác. Trước đây, việc triển khai, giám sát một cluster gồm hàng trăm máy đòi hỏi ít nhất một đội vận hành hàng chục người. Với hệ thống triển khai liên tục, tích
hợp với các cơ chế giám sát và thông báo lỗi tự động cho các bên liên quan, chỉ cần vài người là có thể đảm bảo mơi trường sản phẩm hoạt động tốt với độ tin cậy cao.
• Thỏa mãn được các yêu cầu cho đội phát triển
Các nhà phát triển thường quen thuộc với cách thức truy cập trực tiếp vào môi trường sản phẩm để đọc và phân tích log khi có lỗi xảy ra. Tuy nhiên, kinh nghiệm
thực tế chỉ ra rằng cách làm này có thể gây ra nhiều thiệt hại hơn lợi ích mà nó mang lại, bởi bất cứ ai cũng có thể tạo ra một sửa đổi khiến máy triển khai chuyển sang trạng thái hoạt động bất thường.
Với việc sử dụng mơ hình triển khai khơng tùy biến, khơng có nhiều khác biệt giữa mơi trường sản phẩm và môi trường local (tất cả các thư viện, các yêu cầu để một dịch vụ chạy đều đã được đóng gói vào trong ảnh container), do vậy các nhà phát triển hồn tồn có thể tự tái hiện và kiểm tra lỗi trên chính máy đang sử dụng.
Ngoài ra, tất cả cấu hình máy triển khai được khai báo trong các tệp kịch bản
Ansible, được lưu và quản lý như mã nguồn trên kho quản lý mã chung mà các nhà
phát triển đều có thể truy cập. Bằng việc tích hợp EFK stack và sử dụng các cơng cụ giám sát với giao diện thể hiện trực quan, những thông tin trước đây cần phải truy cập trực tiếp vào máy mới xem được đều hiện hữu trên giao diện người dùng.
Thiết kế hệ thống triển khai liên tục trong luận văn thực tế đã đáp ứng gần như
tất cả yêu cầu mà bên phát triển mong muốn, đồng thời đã hạn chế được những rủi ro mà những phương pháp làm việc trước đó gây ra.
KẾT LUẬN
Các ứng dụng dựa vào đám mây là xu hướng mới nhất trong ngành công nghiệp công nghệ thông tin, giúp phát triển và triển khai phần mềm một cách nhanh chóng và hiệu quả bằng việc sử dụng các dịch vụ đám mây. Nó giúp cải thiện tốc độ làm việc cho các đội phát triển bởi giờ đây họ có thể tập trung vào việc phát triển tính năng thay vì lo lắng về cơ sở hạ tầng. Nó cũng giúp cho các cơng ty, tổ chức đưa phần mềm ra thị trường nhanh hơn do không phải dành thời gian cho các thủ tục chuẩn bị máy móc phức tạp. Các khái niệm tích hợp, chuyển giao liên tục, kiến trúc vi dịch vụ giúp tận dụng tối đa lợi ích mà đám mây mang lại. Công nghệ container, cùng với sự xuất hiện của Docker, đã cách mạng hóa cách thức đóng gói và triển khai vi dịch vụ. Bản chất nhẹ, sử dụng ít tài nguyên của container giúp việc thiết lập môi trường chạy cho ứng dụng trở nên đơn giản, nhanh chóng (giảm thời gian từ vài chục phút cho việc khởi
động máy ảo gồm toàn bộ hệ điều hành tới chỉ vài phút cho việc bật container). Sự ra đời của container, tích hợp cùng với những cơng nghệ trước đó, đã biến việc triển khai
liên tục trở thành hiện thực. Các công cụ mới cũng liên tục xuất hiện để hỗ trợ cho việc triển khai container như: các công cụ khám phá dịch vụ, các bộ khung điều phối container, các giải pháp thu thập và quản lý log hay các cách thức giám sát hệ thống. Tuy nhiên, tồn bộ những cơng cụ, nền tảng hay công nghệ nêu trên đều xuất hiện và tồn tại một cách rời rạc, chưa có sự thống nhất. Câu hỏi đặt ra hiện tại là làm thế nào để phối hợp những công nghệ này để đưa ra một luồng triển khai liên tục hiệu quả, đảm bảo thỏa mãn yêu cầu của các bên liên quan.
Qua việc thu thập yêu cầu, phân tích cơng nghệ, luận văn đã đưa ra được một
thiết kế hệ thống triển khai liên tục đáp ứng gần như toàn bộ những yêu cầu cơ bản
nhất cho các ứng dụng dựa vào kiến trúc vi dịch vụ sử dụng container. Tuy nhiên, do những giới hạn về thời gian và độ dài, một số vấn đề còn chưa được đề cập tới trong
thiết kế.
Đầu tiên là cơ chế tự động scale-out và scale-in của hệ thống. Việc sử dụng giải
pháp quản lý cấu hình cùng với nền tảng điều phối container trên điện toán đám mây
cho phép hệ thống triển khai liên tục có thể cung ứng thêm máy triển khai và tạo ra các bản sao của container một cách nhanh chóng. Kèm với việc sử dụng các Load Balancer hoặc các Reverse Proxy, việc scale-out và scale-in mà khơng có thời gian ngừng hoạt động hồn tồn có thể thực hiện được. Tuy nhiên, câu hỏi mà luận văn
chưa giải quyết được là lựa chọn thời điểm để scale-out/in phù hợp nhất. Hệ thống
nhân tạo để tự học những dữ liệu này và đưa ra quyết định thì sẽ tối ưu được q trình scale.
Ngồi ra, việc cập nhật và đảo ngược phiên bản triển khai hiện tại chỉ áp dụng đối với cấp bậc container. Nếu container sử dụng cơ sở dữ liệu ngoài, những hành động này cũng đòi hỏi sự thay đổi tương ứng trong các bảng cơ sở dữ liệu. Cách thức
làm thế nào để có thể đảo ngược cơ sở dữ liệu chưa được đề cập tới. Hiện nay, có một số phương án thường được sử dụng như sao lưu gia tăng (incremental backup), áp
dụng các migration script, ... nhưng luận văn cũng chưa đề cập tới và đưa ra những
phân tích, so sánh thỏa đáng để áp dụng.
Trong tương lai, tác giả sẽ tiếp tục nghiên cứu và hoàn thiện giải pháp hiện tại để giải quyết những vấn đề nêu trên cũng như đáp ứng những yêu cầu mới nảy sinh trong quá trình phát triển của ngành công nghiệp phần mềm.
TÀI LIỆU THAM KHẢO
[1] “Survey Agile,” Techbeacon, 2018. [Online]. Available: https://techbeacon.com/survey-agile-new-norm.
[2] Amazon Web Services, Inc, “What is Cloud Computing,” [Online]. Available: https://aws.amazon.com/what-is-cloud-computing/.
[3] IBM, “What is cloud computing?,” [Online]. Available: https://www.ibm.com/cloud/learn/what-is-cloud-computing.
[4] S. Guckenheimer, “What is Continuous Integration?,” [Online]. Available: https://www.visualstudio.com/learn/what-is-continuous-integration/. [5] V. Farcic, The DevOps 2.0 Toolkit, Leanpub, 2016.
[6] P. Maresca, “From Monolithic Three-tiers Architectures to SOA Vs Microservices,” [Online]. Available:
https://thetechsolo.wordpress.com/2015/07/05/from-monolith-three-tiers- architectures-to-soa-vs-microservices/.
[7] A. Kharenko, “Monolithic vs. Microservices Architecture,” [Online]. Available: https://articles.microservices.com/monolithic-vs-microservices-architecture- 5c4848858f59.
[8] I. Miri, “Microservices vs. SOA,” [Online]. Available: https://dzone.com/articles/microservices-vs-soa-2. [9] Docker Inc., “What is a container,” [Online]. Available:
https://www.docker.com/what-container.
[10] Docker Inc. All rights reserved., “Docker overview,” [Online]. Available: https://docs.docker.com/engine/docker-overview/#docker-engine.
[11] M. Hausenblas, Docker Networking and Service Discovery, O’Reilly Media, 2016.
[12] J. Sitakange, “Infrastructure as Code: A Reason to Smile,” [Online]. Available: https://www.thoughtworks.com/insights/blog/infrastructure-code-reason-smile. [13] A. Mouat, Using Docker, O’Reilly Media, 2016.
[14] Fluentd Project, “What is Fluentd?,” [Online]. Available: https://www.fluentd.org/architecture.
[15] A. s. G. b. model, “A successful Git branching model,” [Online]. Available: http://nvie.com/posts/a-successful-git-branching-model/.
[16] S. J. Tirkey, “Setting Up Master Slave Machines Using Jenkins,” [Online]. Available: https://blog.knoldus.com/2018/03/27/setting-up-master-slave- machines-using-jenkins/.
[17] A. Parthasarathy, “Kubernetes vs Docker Swarm,” [Online]. Available: https://platform9.com/blog/kubernetes-docker-swarm-compared/.
[18] A. Parthasarathy, “Kubernetes vs Mesos + Marathon,” [Online]. Available: https://platform9.com/blog/kubernetes-vs-mesos-marathon/.
[19] T. K. Authors, “Services,” [Online]. Available:
Available: https://logz.io/blog/fluentd-logstash/.
[21] V. K. a. V. Marmol, “Resource Usage Monitoring in Kubernetes,” [Online]. Available: https://kubernetes.io/blog/2015/05/resource-usage-monitoring- kubernetes.
[22] Prometheus, “Prometheus,” [Online]. Available: https://github.com/prometheus/prometheus.
[23] NetApp, “What Is Configuration Management (CM),” [Online]. Available: https://www.netapp.com/us/info/what-is-configuration-management.aspx.
[24] Apache Mesos, “What is Mesos?,” [Online]. Available: http://mesos.apache.org/. [25] MongoDB, Inc, “Containers and Orchestration Explained,” [Online]. Available:
https://www.mongodb.com/containers-and-orchestration-explained. [26] https://docs.docker.com/get-started/part4/, “https://docs.docker.com/get-
started/part4/,” [Online]. Available: https://docs.docker.com/get-started/part4/. [27] Mesosphere, Inc., “Marathon,” [Online]. Available:
https://mesosphere.github.io/marathon/.
[28] Amazon Web Services, Inc, “What are Containers,” [Online]. Available: https://aws.amazon.com/what-are-containers/.
[29] Fluentd Project, “Why use Fluentd,” [Online]. Available: https://www.fluentd.org/why.
[30] C. Richardson, “Scale Cube,” [Online]. Available: http://microservices.io/articles/scalecube.html.
[31] “kube-state-metrics,” [Online]. Available: https://github.com/kubernetes/kube- state-metrics.
[32] R. Karanam, “Microservices With Spring Boot,” [Online]. Available:
https://dzone.com/articles/microservices-with-spring-boot-part-1-getting-star. [33] “Flannel,” [Online]. Available: https://github.com/coreos/flannel.
PHỤ LỤC
Phụ lục thể hiện một số phần mã nguồn chính cho Hệ thống triển khai liên tục mẫu
được xây dựng trong luận văn.
I. Các vi dịch vụ
1. Forex-service
• Controller
@RestController
public class ForexController {
@Autowired
private Environment environment;
@Autowired
private ExchangeValueRepository repository;
private static final Counter requestTotal = Counter.build() .name("msa_request_count")
.labelNames("msa_request_count")
.help("Number of request received").register();
@GetMapping("/currency-exchange/from/{from}/to/{to}") public ExchangeValue retrieveExchangeValue
(@PathVariable String from, @PathVariable String to){ ExchangeValue exchangeValue = repository.findByFromAndTo(from, to); if(exchangeValue != null) { requestTotal.labels("success").inc(); exchangeValue.setPort( Integer.parseInt(environment.getProperty("local.server.port"))); } else { requestTotal.labels("error").inc(); } return exchangeValue; } @GetMapping("/health/status") public boolean healthCheck() { return true;
} }
• Dockerfile
FROM release-docker.deanthesis.com:5000/release-test/oracle-jdk:8u121 MAINTAINER Dean Nguyen
RUN mkdir -p /forex-service
COPY script/start.sh /forex-service/
COPY forex-service-0.0.1-SNAPSHOT.jar /forex-service/ RUN chmod +x /forex-service/start.sh
EXPOSE 8000
WORKDIR /forex-service
2. Current-conversion-service
• Controller
@RestController
public class CurrencyConversionController {
private Logger logger = LoggerFactory.getLogger(this.getClass()); private static final Counter requestTotal = Counter.build()
.name("msa_request_count")
.labelNames("msa_request_count")
.help("Number of request received").register(); @Autowired
private CurrencyExchangeServiceProxy proxy; // @GetMapping("/currency-
converter/from/{from}/to/{to}/quantity/{quantity}")
@RequestMapping(value = "/currency-
converter/from/{from}/to/{to}/quantity/{quantity}", method = RequestMethod.GET)
public CurrencyConversionBean convertCurrency(@PathVariable String from, @PathVariable String to,
@PathVariable BigDecimal quantity) {
Map<String, String> uriVariables = new HashMap<>(); uriVariables.put("from", from);
uriVariables.put("to", to);
ResponseEntity<CurrencyConversionBean> responseEntity = new RestTemplate().getForEntity(
"http://localhost:8000/currency-exchange/from/{from}/to/{to}", CurrencyConversionBean.class,
uriVariables);
CurrencyConversionBean response = responseEntity.getBody(); return new CurrencyConversionBean(response.getId(), from, to, response.getConversionMultiple(), quantity, quantity.multiply(response.getConversionMultiple()), response.getPort()); } // @GetMapping("/currency-converter- feign/from/{from}/to/{to}/quantity/{quantity}") @RequestMapping(value = "/currency-converter- feign/from/{from}/to/{to}/quantity/{quantity}", method = RequestMethod.GET)
public CurrencyConversionBean convertCurrencyFeign(@PathVariable String from, @PathVariable String to,
@PathVariable BigDecimal quantity) {
CurrencyConversionBean response = proxy.retrieveExchangeValue(from, to); logger.info("{}", response); if(response != null) { requestTotal.labels("success").inc(); } else { requestTotal.labels("error").inc(); }
return new CurrencyConversionBean(response.getId(), from, to, response.getConversionMultiple(), quantity,
response.getPort()); }
@GetMapping("/health/status") public boolean healthCheck() { return true;
} }
• Dockerfile
FROM release-docker.deanthesis.com:5000/release-test/oracle-jdk:8u121 MAINTAINER Dean Nguyen
RUN mkdir -p /currency-conversion-service
COPY script/start.sh /currency-conversion-service/
COPY currency-conversion-service-0.0.1-SNAPSHOT.jar /currency- conversion-service/
RUN chmod +x /currency-conversion-service/start.sh EXPOSE 8100
WORKDIR /currency-conversion-service
II. Mã nguồn cấu hình triển khai Ansible
1. Khởi tạo máy triển khai
- name: Add work-terminal to the ansible host hosts: localhost
connection: localhost gather_facts: False
vars_files:
- ./vars/main.yml
- ./vars/main-{{ CLUSTER_SETUP }}.yml - ./vars/const.yml
roles:
- { role: on-premises-work-terminal/init-create/set-hosts, tags: work-