- vừa được xem lúc

Kubernetes Practice - Logging with Logstash and FluentD by Sidecar Container

0 0 15

Người đăng: Quân Huỳnh

Theo Viblo Asia

Giới thiệu

Chào mọi người đến với series practice về kubernetes. Ở bài này chúng ta sẽ tìm hiểu cách cài đặt Logstash và FluentD trên kubernetes để thiết kế một hệ thống thu lập log.

image.png

Đối với bất kì hệ thống nào thì việc ghi log và tổng hợp log đều rất quan trọng. Khi ta sử dụng kubernetes để triển khai ứng dụng, log của ta chỉ tồn tại trên một Pod, nếu Pod đó bị xóa đi thì log cũng mất theo. Do đó, nếu ta muốn truy vết được lỗi của hệ thống thì ta phải có công cụ để thu thập log về một chỗ. Hai tech stack phổ biến nhất hiện nay cho việc log là ELK (Elasticsearch Logstash Kibana) và EFK (Elasticsearch FluentD Kibana).

Chúng ta sẽ sử dụng sidecar container để cài đặt Logstash và FluentD lên trên từng Pod cho việc thu thập log.

Sidecar container

Thay vì để application container thực hiện việc thu thập log, ta có thể tách công việc đó ra cho một container khác để tránh làm ảnh hưởng tới hiệu suất của application container.

Container mà sẽ thực hiện các công việc hỗ trợ cho application container được gọi là sidecar container, mình sẽ giải thích kĩ trong bài Kubernetes Patterns - Structural Patterns: Sidecar Container.

image.png

Image from Microsoft

Logging with Logstash

Ta có thể dùng Logstash để thu thập log từ hệ thống, nhưng từ năm 2015 Elastichsearch đã ra mắt Filebeat để chuyên cho việc theo dõi log, thu thập log và chuyển log đi chỗ khác. Logstash thì tập trung vào việc nhận log từ nhiều đầu và tiến hành phân tích, lọc và chuyển đổi log thành dạng phù hợp để lưu vào Elasticsearch.

Giờ ta bắt tay vào làm nào, đầu tiên ta deploy một Pod có application container sẽ ghi log vào file /var/log/access.log và có một sidecar container chạy filebeat để thu thập log và bắn tới Logstash.

image.png

Tạo một file tên là filebeat.cm.yaml để chứa cấu hình filebeat.

apiVersion: v1
kind: ConfigMap
metadata: name: filebeat-config labels: component: filebeat
data: conf.yaml: | filebeat.inputs: - type: log paths: - '/var/log/*.log' output: logstash: hosts: [ "logstash:5044" ]

Input của filebeat ta đọc từ file /var/log/*.log, sau đó ta output log này tới logstash. Tiếp theo ta tạo file deployment application.yaml.

apiVersion: apps/v1
kind: Deployment
metadata: name: busybox labels: component: busybox
spec: strategy: type: Recreate selector: matchLabels: component: busybox template: metadata: labels: component: busybox spec: containers: - name: busybox image: busybox args: - sh - -c - > while true; do echo $(date) - filebeat log >> /var/log/access.log; sleep 10; done volumeMounts: - name: log mountPath: /var/log - name: filebeat image: elastic/filebeat:7.16.3 args: - -c - /etc/filebeat/conf.yaml - -e volumeMounts: - name: filebeat-config mountPath: /etc/filebeat - name: log mountPath: /var/log volumes: - name: log emptyDir: {} - name: filebeat-config configMap: name: filebeat-config

Trong Pod ở trên ta sẽ mount config của filebeat vào file /etc/filebeat/conf.yaml và sử dụng thuộc tính args để chỉ định file config đó cho filbeat. Application container của ta ghi log vào file /var/log/access.log 10s một lần. Ta dùng emptyDir volumes để share storage giữa hai container.

Tạo file logstash.cm.yaml để chứa cấu hình của logstash.

apiVersion: v1
kind: ConfigMap
metadata: name: logstash labels: component: logstash
data: access-log.conf: | input { beats { port => "5044" } } output { elasticsearch { hosts => [ "elasticsearch:9200" ] } }

Input ta lấy từ filebeat, sau đó nó output log ra cho elasticsearch. Tạo file deployment để chạy logstash.

apiVersion: apps/v1
kind: Deployment
metadata: name: logstash labels: component: logstash
spec: strategy: type: Recreate selector: matchLabels: component: logstash template: metadata: labels: component: logstash spec: containers: - name: logstash image: logstash:7.16.3 ports: - containerPort: 5044 volumeMounts: - name: logstash-config mountPath: /usr/share/logstash/pipeline volumes: - name: logstash-config configMap: name: logstash ---
apiVersion: v1
kind: Service
metadata: name: logstash labels: component: logstash
spec: ports: - port: 5044 selector: component: logstash

Ta mount cấu hình vào folder /usr/share/logstash/pipeline, logstash sẽ đọc cấu hình từ folder này.

Tạo elasticsearch và kibana, này chỉ là test thôi nhé, để tạo elasticsearch và kibana trên môi trường production, các bạn xem bài này nhé Kubernetes Practice - Elasticsearch Cloud on Kubernetes (ECK).

apiVersion: apps/v1
kind: Deployment
metadata: name: elasticsearch labels: component: elasticsearch
spec: strategy: type: Recreate selector: matchLabels: component: elasticsearch template: metadata: labels: component: elasticsearch spec: containers: - name: elasticsearch image: elasticsearch:7.16.3 ports: - containerPort: 9200 name: client - containerPort: 9300 name: nodes env: - name: JAVA_TOOL_OPTIONS value: -Xmx256m -Xms256m - name: discovery.type value: single-node resources: requests: memory: 500Mi cpu: 0.5 limits: memory: 500Mi cpu: 0.5 ---
apiVersion: v1
kind: Service
metadata: name: elasticsearch labels: component: elasticsearch
spec: ports: - port: 9200 name: client - port: 9300 name: nodes selector: component: elasticsearch

Kibana.

apiVersion: apps/v1
kind: Deployment
metadata: name: kibana labels: component: kibana
spec: strategy: type: Recreate selector: matchLabels: component: kibana template: metadata: labels: component: kibana spec: containers: - name: kibana image: kibana:7.16.3 ports: - containerPort: 5601 ---
apiVersion: v1
kind: Service
metadata: name: kibana labels: component: kibana
spec: ports: - port: 5601 selector: component: kibana

Giờ ta tạo toàn bộ resource nào.

kubectl apply -f . --recursive

Dùng port-forward để truy cập kibana.

kubectl port-forward svc/kibana 5601:5601

Vào mục Stack Management > Index patterns, sau đó vào mục Discover bạn sẽ thấy log mà ta thu thập được từ busybox container.

Logging with FluentD

FluentD cũng là một công cụ dùng để thu thập log giống như Filebeat và Logstash. FluentD bao gồm các tính năng như theo dõi log, thu thập, phân tích và chuyển đổi log thành dạng thích hợp để lưu vào Elasticsearch.

FluentD được phát triển bởi Cloud Native Computing Foundation (CNCF), đây là tổ chức phát triển và bảo trì kubernetes.

image.png

Để thu thập log bằng FluentD, ta sẽ deploy nó như một sidecar container y như cách ta dùng Filebeat ở trên. Tạo một file tên là fluentd.cm.yaml để chứa config của FluentD.

apiVersion: v1
kind: ConfigMap
metadata: name: fluentd-config labels: component: fluentd
data: fluent.conf: | <source> @type tail path /var/log/access.log pos_file /tmp/app.logs.pos tag app.logs <parse> @type none </parse> </source> <match app.logs> @type elasticsearch host elasticsearch port 9200 logstash_format true logstash_prefix fluentd flush_interval 1s </match>

Ở trong file config, ta dùng <source> tag để chỉ định nơi ta thu thập log, sau đó ta dùng <match> tag để chuyển log tới Elasticsearch. Tiếp theo ta tạo file application.yaml.

apiVersion: apps/v1
kind: Deployment
metadata: name: busybox labels: component: busybox
spec: strategy: type: Recreate selector: matchLabels: component: busybox template: metadata: labels: component: busybox spec: containers: - name: busybox image: busybox args: - sh - -c - > while true; do echo $(date) - filebeat log >> /var/log/access.log; sleep 10; done volumeMounts: - name: log mountPath: /var/log - name: fluentd image: govtechsg/fluentd-elasticsearch volumeMounts: - name: fluentd-config mountPath: /fluentd/etc - name: log mountPath: /var/log volumes: - name: log emptyDir: {} - name: fluentd-config configMap: name: fluentd-config

Tương như khi ta khai báo filebeat sidecar container. Chạy câu lệnh apply để tạo resource.

kubectl apply -f . --recursive

Fluentd Plugin

Ta có một điều quan trọng cần lưu ý là để ta có thể chuyển được log tới Elasticsearch, chúng ta phải dùng Fluentd Elasticsearch Plugin.

Các bạn thấy ở trên ta đang dùng container govtechsg/fluentd-elasticsearch, trong container này nó có sẵn Elasticsearch Plugin nên thằng fluentd mới chuyển log tới Elasticsearch được.

Nếu bạn dùng container fluent/fluentd mặc định của fluentd thì khi bạn chạy nó sẽ báo lỗi là không tìm thấy config cho @type elasticsearch.

Để install plugin thì ta có thể viết Dockerfile như sau.

FROM fluent/fluentd:v1.12.0-debian-1.0
USER root
RUN gem install fluent-plugin-elasticsearch --version 5.0.3
USER fluent

Danh sách toàn bộ plugin của fluentd https://www.fluentd.org/plugins/all.

Kết luận

Vậy là ta đã tìm hiểu xong cách dùng sidecar container pattern để cấu hình thu thập log của application container về một chỗ. ELK và EFK là hai log stack rất phổ biến, nếu ta biết cả hai và biết trường hợp nào nên xài cái nào thì rất tuyệt vời. Mình thì chưa đạt tới cảnh giới này :)))). Nếu có thắc mắc hoặc cần giải thích rõ thêm chỗ nào thì các bạn có thể hỏi dưới phần comment.

Mục tìm kiếm đồng đội

Hiện tại thì công ty bên mình, là Hoàng Phúc International, với hơn 30 năm kinh nghiệm trong lĩnh vực thời trang. Và sở hữu trang thương mại điện tử về thời trang lớn nhất Việt Nam. Team công nghệ của HPI đang tìm kiếm đồng đội cho các vị trí như:

Với mục tiêu trong vòng 5 năm tới về mảng công nghệ là:

  • Sẽ có trang web nằm trong top 10 trang web nhanh nhất VN với 20 triệu lượt truy cập mỗi tháng.
  • 5 triệu loyal customers và có hơn 10 triệu transactions mỗi năm.

Team đang xây dựng một hệ thống rất lớn với rất nhiều vấn đề cần giải quyết, và sẽ có rất nhiều bài toán thú vị cho các bạn. Nếu các bạn có hứng thú trong việc xây dựng một hệ thống lớn, linh hoạt, dễ dàng mở rộng, và performance cao với kiến trúc microservices thì hãy tham gia với tụi mình.

Nếu các bạn quan tâm hãy gửi CV ở trong trang tuyển dụng của Hoàng Phúc International hoặc qua email của mình nha _@.com. Cảm ơn các bạn đã đọc.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Đề thi interview DevOps ở Châu Âu

Well. Chào mọi người, mình là Rice - một DevOps Engineers ở đâu đó tại Châu Âu.

0 0 66

- vừa được xem lúc

In calculus, love also means zero.

Mình nhớ hồi năm 2 đại học, thầy giáo môn calculus, trong một giây phút ngẫu hứng, đã đưa ra cái definition này. Lúc đấy mình cũng không nghĩ gì nhiều.

0 0 52

- vừa được xem lúc

Chuyện thay đổi

Thay đổi là một thứ gì đó luôn luôn đáng sợ. Cách đây vài tháng mình có duyên đi làm cho một banking solution tên là X.

0 0 31

- vừa được xem lúc

Pet vs Cattle - Thú cưng và gia súc

Khái niệm. Pets vs Cattle là một khái niệm cơ bản của DevOps. Bài viết này sẽ nói về sự phát triển của các mô hình dịch vụ từ cốt lõi Pets and Cattle. 1.

0 0 22

- vừa được xem lúc

Git workflow được Google và Facebook sử dụng có gì hay ho

Với developer thì Git hẳn là công cụ rất quen thuộc và không thể thiếu rồi. Thế nhưng có mấy ai thực sự hiểu được Git.

0 0 66

- vừa được xem lúc

Kubernetes - Học cách sử dụng Kubernetes Namespace cơ bản

Namespace trong Kubernetes là gì. Tại sao nên sử dụng namespace.

0 0 96