OKE ARM64上的Fluentd DaemonSet:8个连续错误直到日志到达OCI Logging
发布于 2026年4月17日

目标:Next.js Pod → OCI日志服务
一个使用ARM64节点(A1.Flex Ampere)的OKE(Oracle Kubernetes Engine)集群需要将应用Pod的错误日志发送到OCI日志服务。应用已经通过stdout/stderr输出结构化日志——工作是使用Fluentd捕获这些日志,按正确的Pod过滤,并通过实例主体认证的HTTPS传输到OCI日志服务。
计划的架构很直接:
Pod (console.error → stdout/stderr)
→ CRI-O (写入 /var/log/containers/*.log)
→ Fluentd DaemonSet (tail + filter + match)
→ OCI日志服务 (通过HTTPS,认证:实例主体)计划之外的是kubectl apply和OCI日志服务中第一条确认日志之间的8个错误。
错误1:OCI容器镜像仓库要求认证
OCI日志官方文档建议使用Oracle自己的容器镜像仓库镜像:
container-registry.oracle.com/oci_logging/fluentbit尝试在OKE节点上拉取此镜像时,kubelet返回认证错误。即使是公开镜像,Oracle容器镜像仓库也需要登录——在所有集群节点上为外部镜像仓库配置ImagePullSecrets并不是正确的方式。
修复:使用Docker Hub公开镜像仓库中的官方Fluent Bit镜像,无需认证:
docker.io/fluent/fluent-bit:3.2错误2:CRI-O拒绝短镜像名称
即使将镜像换为fluent/fluent-bit:3.2,kubelet仍然拒绝:
short name mode is enforcing, but image name "fluent/fluent-bit:3.2"
returns ambiguous list of candidates运行在OKE节点上的Oracle Linux 8.10将CRI-O配置为短名称强制模式——所有镜像名称必须完整指定镜像仓库。
修复:在manifest中所有镜像名称前添加docker.io/前缀:
image: docker.io/fluent/fluent-bit:3.2错误3:Fluent Bit 3.2没有oci_logging插件
Pod启动后,日志显示Fluent Bit无法加载发送到OCI日志服务所需的输出插件。oci_logging插件在Fluent Bit中不存在——它只存在于Fluentd的Ruby gem中。
修复:从Fluent Bit迁移到带有fluent-plugin-oci-logging gem的Fluentd。这需要基于官方Fluentd构建自定义镜像:
FROM docker.io/fluent/fluentd:v1.17-debian-1
# 在后续步骤中安装gem...错误4:构建失败——基础镜像中没有工具链
Fluentd基础镜像(debian)不包含C编译器。安装fluent-plugin-oci-logging gem时在编译原生扩展阶段失败:
make: g++: No such file or directory
make[1]: *** [Makefile:234: <target>.o] Error 127修复:在Dockerfile中gem安装之前添加build-essential:
FROM docker.io/fluent/fluentd:v1.17-debian-1
USER root
RUN apt-get update && apt-get install -y build-essential && rm -rf /var/lib/apt/lists/*
RUN gem install fluent-plugin-oci-logging fluent-plugin-kubernetes_metadata_filter fluent-plugin-parser-cri错误5:Ruby 3.2中删除了File.exists?
安装gem后,Pod启动但立即崩溃:
NoMethodError: undefined method 'exists?' for File:Class
/usr/local/bundle/gems/fluent-plugin-oci-logging-1.0.12/lib/fluent/plugin/os.rbFile.exists?方法在Ruby 3.2中被删除(自Ruby 2.1起已弃用)。fluent-plugin-oci-logging gem 1.0.12版本仍然使用旧方法,尚未更新。
修复:通过sed在Dockerfile中进行内联补丁:
RUN sed -i 's/File\.exists?/File.exist?/g' /usr/local/bundle/gems/fluent-plugin-oci-logging-*/lib/fluent/plugin/os.rb检查gem的未来版本中是否已在上游修复了File.exists?。在gem更新之前需要此补丁。
错误6:创建缓冲区目录时权限被拒绝
Pod启动,gem正常工作——但Fluentd在初始化时挂起:
Permission denied @ dir_s_mkdir - /var/log/fluentd-buffersDaemonSet配置为以默认Fluentd用户(非root)运行。主机上的/var/log目录属于root,fluent用户没有写入权限。
修复:在DaemonSet中添加securityContext: runAsUser: 0,并将缓冲区移至/tmp/fluentd-buffers/:
spec:
template:
spec:
securityContext:
runAsUser: 0
containers:
- name: fluentd
# 在fluent.conf中:
# <buffer>
# path /tmp/fluentd-buffers/
# </buffer>注意:需要从主机读取/var/log/containers/的日志收集DaemonSet通常需要以root身份运行。这对于Fluentd和Fluent Bit等日志收集器是预期且已记录的行为。
错误7:摄取时404——Dynamic Group使用了错误的OCID
Pod运行,权限问题已解决——但摄取到OCI日志服务的尝试失败:
NOT_AUTHORIZED_OR_NOT_FOUND (404) - Authorization failed or resource not foundFluentd使用实例主体认证——OKE节点需要在具有OCI日志访问策略的Dynamic Group中。Dynamic Group创建时使用了以下规则:
# 错误规则——使用OKE节点上不存在的标签
All {tag.Oracle-Tags.CreatedBy.value = '<集群OCID>'}问题在于:OKE节点上的Oracle-Tags.CreatedBy标签包含的是节点池OCID,而不是集群OCID。同一区间中不同集群的节点共享相同的集群OCID——但节点池OCID是唯一的。使用错误的OCID导致Dynamic Group无法识别节点。
修复——最简单且最健壮的选项:使用instance.compartment.id而不是标签:
# 正确规则——区间中的所有节点
All {instance.compartment.id = '<区间OCID>'}使用instance.compartment.id比依赖节点池标签更简单、更健壮。如果集群重建或节点池替换,规则仍然有效。权衡是粒度:区间中的所有节点都进入该组——评估这在您的环境中是否可接受。
错误8:<auth>块破坏认证
修复Dynamic Group后,摄取日志显示关于fluent.conf中auth块的警告:
[warn]: #0 unknown parameter 'auth' in <match>fluent-plugin-oci-logging插件使用认证类型自动检测——它自动检测是否在OCI实例上运行并使用实例主体。添加显式<auth>块不仅不必要,还会干扰自动认证。
修复:从fluent.conf中完全删除<auth>块。插件通过实例主体自动处理认证。
<match kubernetes.**>
@type oci_logging
log_object_id <日志OCID>
# <auth> — 不要添加。插件使用自动检测。
</match>结果:DaemonSet运行,11秒内收到第一条日志
解决所有8个错误后,DaemonSet在两个ARM64节点上无重启地启动:
kubectl get pods -n logging
# fluentd-a1b2c 1/1 Running 0 5m
# fluentd-d3e4f 1/1 Running 0 5mOCI日志中确认的第一条日志在Pod变为Running后11秒到达——恰好是fluent.conf中配置的10秒flush_interval加上网络延迟。
# 第一条摄取的日志:
{
"timestamp": "2026-04-16T18:21:23Z",
"message": "Error: Loading chunk failed.",
"stream": "stderr"
}
# 摄取时间:2026-04-16T18:21:34Z (+11s)8个错误和修复摘要
1. 镜像仓库需要认证 → 使用docker.io/fluent/fluentd:v1.17-debian-1(公开Docker Hub)
2. CRI-O拒绝短名称 → 所有镜像名称添加docker.io/前缀
3. Fluent Bit没有oci_logging → 迁移到Fluentd + fluent-plugin-oci-logging gem
4. 构建没有工具链 → 在Dockerfile中添加build-essential
5. Ruby 3.2删除了File.exists? → Dockerfile中的sed补丁
6. 缓冲区权限被拒绝 → runAsUser: 0 + 缓冲区在/tmp/fluentd-buffers/
7. Dynamic Group使用错误的OCID → 使用instance.compartment.id而不是集群/节点池标签
8. <auth>块干扰认证 → 删除——插件使用实例主体自动检测


