Như chúng ta đã biết, docker container trong k8s sẽ ghi logs băng phương thức stream sdtout và sdterr ( standard output và errer). Sau đó, Docker sẽ chuyển hướng những stream này đến logging driver, tiếp đến, k8s sẽ ghi ra file những Log này với định dạng Json. Đây là cách thức ghi logs thông thường trong Kubernetes.
Tuy nhiên, việc này sẽ có một vài khuyết điểm. Những log này sẽ bị mất nếu các pod hoặc các node bị xóa đi. Lúc này chúng ta sẽ không có Logs để trace được vấn đề khi có sự cố xảy ra. Để giải quyết vấn đề này, chúng ta cần phải chuyển những logs này đi một nơi khác để lưu trữ. K8s cho phép chúng ta dễ dàng thiết lập việc này thông qua Kubernetes API và controller. Để vận chuyển logs sẽ có những cách thức sau:
+ thứ nhất, cài đặt sidecar chạy trực tiếp trong mỗi service.
+ thứ hai, cài agent trên mỗi node, từ đó lấy logs những service chạy trên node đó.
+ cuối cùng, đẩy logs trực tiếp từ trong service đến central log.
Sử dụng Sidecar containers
Với cách này, chúng ta có thể cài 1 hoặc nhiều sidecar bên trong apps. Sidecar này sẽ đảm nhiệm việc lấy logs sdtout/stderror từ trong. Việc này sẽ có những lợi ích sau:
- Có thể lấy được những logs độc lập cho từng app. Điều này sẽ rất có ích nếu chúng ta có nhiều định dạng logs khác nhau, nhiều định dạng hỗn độn sẽ khó cho việc quản lý, thì đây là lựa chọn tốt.
- Lấy được logs thực tế của apps mà không cần phải ghi ra stdout hoặc stderr.
Tuy nhiên, nó cũng sẽ có khuyết điểm:
- Logs sẽ được ghi ra một file và sau đó mới stream chúng đến stdout, Việc này sẽ làm tăng dung lượng disk.
- Nếu như chúng ta có quá nhiều ứng dụng, thì cứ mỗi app bắt buộc phải cài 1 sidecar. Điều này quá thủ công và tốn thời gian.
Cài đặt Agent trên mỗi Node
Ưu điểm:
Các Agent khi được cài trên mỗi Node, chúng có thể truy cập được các Logs của các service chạy trên đó. Với cách này có thể sẽ khắc phục được 2 khuyết điểm của Sidecar đã đề cập phía trên. Cách đơn giản nhất để triển khai các agent này là sử dụng “Daemonset”. với Daemonset này, nó sẽ đảm bảo là trên mỗi node đều sẽ có ít nhất 1 agent chạy trên đó, đồng thời nó sẽ định kỳ kiểm tra các trạng thái của Node.
Khuyết Điểm:
Deamonset chỉ làm việc với stdout và stderror của app.
Deploying Fluentd để thu thập Application Logs
Việc triển khai theo cách thức Node-level agent này được sử dụng phổ biến trong K8s. Vì chúng ta chỉ cần cài 1 agent trên mỗi node là có thể lấy được Logs của tất cả service chạy trên nó. Ở đây, chúng ta sẽ chọn Fluenttd agent bởi vì sự phố biến của nó, đồng thời nó hỗ trợ nhiều đầu ra như: Elasticsearch, Splunnk, Kafka, RabbitMQ, Slack ….
Bước 1: Cấp quyền cho Fluentd
apiVersion: v1
kind: ServiceAccount
metadata:
name: fluentd
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: fluentd
namespace: kube-system
rules:
- apiGroups:
- ""
resources:
- pods
- namespaces
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: fluentd
roleRef:
kind: ClusterRole
name: fluentd
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: fluentd
namespace: kube-system
Lưu lại file và thực thi:
kubectl create -f rbac.yml
Bước 2: Triển khai DaemonSet
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: fluentd
namespace: kube-system
labels:
k8s-app: fluentd-logging
version: v1
kubernetes.io/cluster-service: "true"
spec:
template:
metadata:
labels:
k8s-app: fluentd-logging
version: v1
kubernetes.io/cluster-service: "true"
spec:
serviceAccount: fluentd
serviceAccountName: fluentd
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:elasticsearch
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "f505e785.qb0x.com"
- name: FLUENT_ELASTICSEARCH_PORT
value: "30216"
- name: FLUENT_ELASTICSEARCH_SCHEME
value: "https"
- name: FLUENT_UID
value: "0"
# X-Pack Authentication
# =====================
- name: FLUENT_ELASTICSEARCH_USER
value: "abf54990f0a286dc5d76"
- name: FLUENT_ELASTICSEARCH_PASSWORD
value: "75c4bd6f7b"
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
Lưu ý:
+ fluent/fluentd-kubernetes-daemonset:elasticsearch : images Fluentd
+ chúng ta nên cung cấp các biến môi trường để connect tới Cluster Elastcsearch.
+ Fluent cần quyền root để có thể đọc, ghi được file trong /var/log. Để tránh lỗi phân quyền, do đó chúng ta sẽ set biến môi trường FLUENT_UID = 0.
lưu file và tiến hành thực thi:
kubectl create -f fluentd-elasticsearch.yml
Kiểm tra xem trạng thái fluentd có kết nối thành công hay không, chúng ta sẽ thấy được output như sau:
2018–09–11 09:20:05 +0000 [info]:
Connection opened to Elasticsearch cluster => {:host=>”f505e785.qb0x.com”,
:port=>30216, :scheme=>”https”, :user=>”abf54990f0a286dc5d76", :password=>”obfuscated”}
Kiểm tra logs được thu thập từ Fluentd trên Dashboard Kibana:
Management -> Index Patterns -> Create New Index Pattern
Ở đây, chúng ta sẽ thấy logs của App và Log của hệ thống K8s, với các thông tin: namespace, Docker container ID, labels …
log:INFO: == Kubernetes addon reconcile completed at 2018-09-11T09:31:39+0000 == stream:stdout docker.container_id:9b596c9195003246af0f71406f05ab4d339601dadc213048202992739fe9267e kubernetes.container_name:kube-addon-manager kubernetes.namespace_name:kube-system kubernetes.pod_name:kube-addon-manager-minikube kubernetes.pod_id:f6d8ff9d-8a6e-11e8-9e55-0800270c281a kubernetes.labels.component:kube-addon-manager kubernetes.labels.version:v8.6
Tóm lại
Fluentd là một trong những cách tốt nhất cho giải pháp logging của K8s. Trong bài hướng dẫn này, chúng tôi đã chứng minh cách mà Fluentd có thể dễ dàng để tập trung các logs từ nhiều application khác nhau và gửi chúng đến Elasticsearch hoặc bất kỳ ứng dụng đầu ra khác. Không giống như sidecar containers, bắt buộc phải cài đặt theo từng service, Node-level với Fluentd chỉ cần một agent chạy trên mỗi Node là đủ.
Nguồn:
congdonglinux.com
Đăng ký liền tay Nhận Ngay Bài Mới
Subscribe ngay
Cám ơn bạn đã đăng ký !
Lỗi đăng ký !
Add Comment