1. 简介

在 Kubernetes 的所有组件中,kubelet 是运行在每个节点上的核心代理,负责管理由 Kubernetes 编排的容器。由于其关键作用,我们需要访问和理解 kubelet 日志来调试、监控并确保 Kubernetes 生态系统的健康状态。

然而,定位 Kubernetes 日志可能会让人感到困惑,尤其是在不同的部署环境和配置中。本文将系统讲解在不同 Kubernetes 部署方式下,如何查找和分析 kubelet 日志。

无论你是正在排查节点问题的 DevOps 工程师,还是想了解 Pod 行为的系统管理员,掌握 kubelet 日志的获取方法是深入了解 Kubernetes 集群运行机制的第一步。我们开始吧!

2. kubelet 的作用

kubelet 是 Kubernetes 节点上的核心代理组件,负责与控制平面通信,并管理节点上的容器生命周期。它确保根据 Kubernetes 清单中定义的期望状态,启动、运行并监控由 PodSpec 描述的容器。

此外,kubelet 还负责执行控制平面下发的指令,管理容器生命周期,处理卷挂载、网络配置、资源分配等操作。

由于其核心地位,kubelet 会生成大量日志,记录节点状态、Pod 状态、容器执行情况等信息。这些日志对于诊断容器启动失败、资源配置问题、网络连接异常等问题至关重要。

例如,当某个安全策略阻止了容器启动,或者资源限制导致容器被终止时,kubelet 日志往往能提供关键线索。

3. 不同环境中访问 kubelet 日志的方法

kubelet 日志的位置和访问方式会根据 Kubernetes 的部署方式有所不同。从云厂商托管服务到本地开发环境,每种设置可能存储日志的位置不同,或需要特定命令访问。

以下是一些常见部署方式及其对应的日志获取方法。

3.1. 使用 systemd

大多数现代 Linux 发行版(如 CentOS、Fedora 和 Ubuntu 15.04 及以上版本)都使用 systemd 作为初始化系统。如果 Kubernetes 节点运行在使用 systemd 的操作系统上,那么 kubelet 通常作为一个 systemd 服务运行。

要查看 kubelet 日志,可以使用 journalctl 命令查询 systemd 日志:

$ journalctl -u kubelet
Mar 13 12:00:45 my-k8s-node kubelet[9876]: I0313 12:00:45.789101 9876 server.go:155] Successfully started kubelet
Mar 13 12:01:10 my-k8s-node kubelet[9876]: W0313 12:01:10.456789 9876 container_manager_linux.go:912] Running with swap on is not supported, please disable swap

该日志显示 kubelet 成功启动,并提示当前启用了 Swap(Kubernetes 不支持)。

你也可以使用 journalctl 的其他参数来过滤、分页或实时查看日志。

3.2. 查看 /var/log/syslog

在一些未使用 systemd 的 Linux 系统中,kubelet 日志可能输出到 /var/log/syslog 文件中。这个文件通常用于聚合系统日志。

由于内容较多,建议使用 grep 过滤:

$ grep kubelet /var/log/syslog
Mar 13 14:20:30 my-k8s-node kubelet: I0313 14:20:30.123456 reconciliation.go:104] "Reconciler sync states" pod="my-namespace/my-pod"
Mar 13 14:21:00 my-k8s-node kubelet: E0313 14:21:00.654321 eviction_manager.go:255] "Eviction manager: failed to get get summary stats" err="failed to get node info: node \"my-k8s-node\" not found"

该日志显示了 Pod 状态同步正常,随后出现了驱逐管理器因找不到节点而失败的错误。

3.3. Docker-MultiNode 环境

如果你使用 Docker-MultiNode 部署 Kubernetes(较少使用),kubelet 是运行在 Docker 容器中的。

要访问日志,首先找到运行 kubelet 的容器 ID:

$ docker ps | grep kubelet
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
abcdef123456        kubelet:latest      "/usr/local/bin/kube…"   3 minutes ago       Up 3 minutes                            k8s_kubelet

然后使用 docker logs 查看日志:

$ docker logs abcdef123456
I0313 16:34:20.789101 1 kuberuntime_manager.go:207] "Container runtime status check" runtimeStatus=ok
E0313 16:35:25.654321 1 pod_workers.go:190] "Error syncing pod, skipping" err="failed to \"StartContainer\" for \"my-container\" with CrashLoopBackOff: \"back-off 5m0s restarting failed container=my-container pod=my-pod(my-namespace)\""

该日志显示了容器运行时状态正常,但某个容器因反复崩溃而进入 CrashLoopBackOff 状态。

3.4. 使用 Upstart

Ubuntu 15.04 之前的版本使用 Upstart 作为初始化系统。在这些系统中,kubelet 日志通常位于 /var/log/upstart/ 目录下。

查看日志:

$ less /var/log/upstart/kubelet.log
I0313 10:34:20.123456 1 server.go:408] "Starting to listen" address="0.0.0.0" port=10250
E0313 10:34:25.654321 1 kubelet.go:2187] "Node has no valid hostname and/or IP address" err="node IP not set"

日志显示 kubelet 启动成功,但提示节点缺少 IP 配置。

4. 在 Kubernetes in Docker(kind)中访问日志

如果你在本地使用 kind(Kubernetes in Docker)搭建集群,kubelet 日志可以通过进入 Docker 容器查看。

4.1. 列出运行中的容器

首先列出所有运行中的容器,找到 kind 节点容器:

$ docker container ls
CONTAINER ID   IMAGE                  COMMAND                  CREATED       STATUS       PORTS                       NAMES
...
4a1b2c3d4e5f   kindest/node:v1.20.2   "/usr/local/bin/entr…"   10 minutes ago   Up 10 minutes   127.0.0.1:32768->6443/tcp   kind-control-plane
...

然后进入容器:

$ docker container exec -it kind-control-plane bash

4.2. 查看 /var/log/containers/ 和 /var/log/pods/

在容器内,kubelet 日志通常位于以下两个目录中:

  • **/var/log/containers/**:每个容器日志的符号链接。
  • **/var/log/pods/**:按 Pod 组织的日志目录,每个 Pod 有其 UUID 命名的目录,包含其容器日志。

示例查看某个容器日志:

$ tail -n 100 /var/log/containers/myapp-container_<pod-uuid>.log
2024-03-13T12:34:56.789Z INFO myapp-container "Starting application..."
2024-03-13T12:35:01.234Z INFO myapp-container "Application configuration loaded"
2024-03-13T12:35:05.678Z WARN myapp-container "Deprecated API usage detected"
2024-03-13T12:35:10.123Z ERROR myapp-container "Failed to connect to database"

持续查看日志:

$ tail -f /var/log/pods/<pod-uuid>/myapp-container/0.log
2024-03-13T12:36:20.345Z INFO myapp-container "Listening on port 8080"
2024-03-13T12:40:15.678Z INFO myapp-container "Received new connection"
2024-03-13T12:41:10.123Z INFO myapp-container "Connection closed"

5. 日志中常见问题识别

kubelet 日志是排查集群问题的宝贵资源。以下是一些常见问题及对应的日志特征。

5.1. 容器启动失败

日志中可能出现类似以下内容:

"Failed to start container" 或 "Error response from daemon"

这类日志通常来自容器运行时,提示配置错误、资源不足或镜像拉取失败。

5.2. 资源分配问题

资源限制过低可能导致容器被 OOMKilled(Out Of Memory Killed)或 CPU 资源不足。

日志中可能包含:

"Out Of Memory Killed" 或 "CPU limit exceeded"

这类日志有助于优化资源请求和限制设置。

5.3. 网络连接问题

网络插件异常、DNS 解析失败或连接超时等错误会在日志中体现:

"NetworkPlugin not ready" 或 "Failed to setup network for pod"

这类日志提示网络配置或插件问题。

6. 自动化日志监控

虽然手动查看 kubelet 日志对排查特定问题很有帮助,但自动化监控能让我们更主动地发现和响应问题。

6.1. 使用监控工具

可以使用 Prometheus + Grafana 搭配 Loki(日志聚合系统)进行日志监控。

  • Prometheus 收集指标
  • Loki 收集日志
  • Grafana 可视化并设置告警

也可以使用 EFK(Elasticsearch + Fluentd + Kibana)进行日志聚合和复杂查询。

6.2. 脚本与自动化

可以编写脚本定期检查 kubelet 日志,识别错误并发送报告。例如,以下是一个 Bash 脚本示例:

#!/bin/bash

recipient_email="admin@example.com"
subject="Daily Kubelet Log Report"
report_file=$(mktemp)

echo "Kubelet Log Report for $(date)" >> "$report_file"
echo "----------------------------------------" >> "$report_file"

function count_logs {
    log_level=$1
    message_tag=$2
    count=$(journalctl -u kubelet --since "yesterday" | grep -ic "$log_level")
    echo "$message_tag: $count" >> "$report_file"
}

count_logs "error" "Critical Errors"
count_logs "warn" "Warnings"
count_logs "info" "Informational Messages"

image_pull_errors=$(journalctl -u kubelet --since "yesterday" | grep -ic "Failed to pull image")
echo "Image Pull Errors: $image_pull_errors" >> "$report_file"

mail -s "$subject" "$recipient_email" < "$report_file"
rm "$report_file"

赋予执行权限并添加到 crontab:

$ chmod +x check_all_logs.sh
$ crontab -e
0 1 * * * /path/to/check_all_logs.sh

7. 总结

本文系统讲解了在不同 Kubernetes 部署方式下访问 kubelet 日志的方法。kubelet 日志是管理 Kubernetes 集群不可或缺的资源,能帮助我们诊断问题、优化配置、保障集群稳定运行。

有效的日志管理不仅在于查看日志本身,更在于通过工具和实践实现自动化监控与响应。无论是手动分析还是自动化脚本,掌握 kubelet 日志的获取和分析方法,将有助于你构建一个更健康、高效的 Kubernetes 环境。


原始标题:Where Are the Kubernetes kubelet Logs Located?