参考资料
- https://github.com/aws/eks-node-monitoring-agent
- https://docs.amazonaws.cn/en_us/eks/latest/userguide/auto-get-logs.html
本文尝试在中国区EKS 集群中部署官方的节点监控eks-node-monitoring-agent并利用该组件来收集日志。该组件以DS的形式在每个节点运行,持续监控节点内核日志、系统日志、容器运行时状态,将检测结果上报到 Kubernetes API Server,通过 NodeCondition 体现。
相关的基础概念
eks-node-monitoring-agent的核心功能如下
- 日志监控:实时读取和分析系统日志文件
- 问题检测:使用预定义的正则表达式匹配错误模式
- 状态上报:通过 Kubernetes API 设置 NodeCondition
监控的日志源如下
go
// 主要日志文件
/var/log/messages // 系统消息日志
/var/log/kubelet.log // Kubelet 服务日志
/var/log/aws-routed-eni/ipamd.log // VPC CNI 日志
/var/log/pods/ // Pod 容器日志
// systemd 日志
journal -u kubelet // Kubelet systemd 日志
journal -k // 内核日志
发布的NodeCondition 类型包括如下几种

但是目前中国区的eks节点组无法开启-node-repair-config enabled=true,因此无法自动修复节点,后续可以考虑自行开发controller来实现节点异常状态触发节点替换。
首先在集群中部署eks-node-monitoring-agent组件,命令如下
shell
cat > /tmp/agent-values.yaml << 'EOF'
nodeAgent:
image:
tag: v1.6.0-eksbuild.1
containerRegistry: "xxxxxx.dkr.ecr.cn-north-1.amazonaws.com.cn"
EOF
helm install eks-node-monitoring-agent \
/home/ec2-user/eksagent/eks-node-monitoring-agent-main/charts/eks-node-monitoring-agent/ \
-n eks-node-monitoring --create-namespace \
-f /tmp/agent-values.yaml
节点日志收集
本次我们参考官方文档(https://docs.amazonaws.cn/en_us/eks/latest/userguide/auto-get-logs.html)利用agent来实现边界的节点日志获取。具体的步骤如下
创建s3预签名url,agent会使用这个url来上传日志
shell
aws s3 presign s3://eks-node-logs-test127/node-logs-my-node.tar.gz --expires-in 3600 --region cn-north-1
然后在集群中创建
yaml
apiVersion: eks.amazonaws.com/v1alpha1
kind: NodeDiagnostic
metadata:
name: <node-name>
spec:
logCapture:
destination: "<presign URL>"
实际资源的结果如下

检查agent的日志可以看到具体的日志收集和上传动作

具体而言,ageng的组件NodeDiagnostic Controller负责具体的日志收集动作
go
func (c *nodeDiagnosticController) Reconcile(ctx context.Context, nodeDiagnostic *v1alpha1.NodeDiagnostic) (reconcile.Result, error) {
// 1. 更新状态为 Running
captureStatus := v1alpha1.CaptureStatus{
Type: v1alpha1.CaptureTypeLog,
State: v1alpha1.CaptureState{
Running: &v1alpha1.CaptureStateRunning{StartedAt: metav1.Now()},
},
}
// 2. 收集日志
archiveReader, issueCount, err := c.collectLogs(ctx, nodeDiagnostic.Spec.Categories)
// 3. 上传
uploadRequest, _ := http.NewRequestWithContext(ctx, http.MethodPut,
string(nodeDiagnostic.Spec.UploadDestination), archiveReader)
netutil.DoRequest(uploadRequest)
// 4. 更新状态为 Completed
captureStatus.State = v1alpha1.CaptureState{
Completed: &v1alpha1.CaptureStateCompleted{
Reason: v1alpha1.CaptureStateSuccess,
Message: "successfully uploaded logs with no errors",
FinishedAt: metav1.Now(),
},
}
}
这个日志和通过eks日志收集脚本收集到的内容时相同的,使用这种方式即使无法登录节点也可以收集节点日志,以便于后续的故障排查。
