Kubernetes —Pod 和容器日志

news2024/9/22 1:08:27

日志架构

应用日志可以让你了解应用内部的运行状况。日志对调试问题和监控集群活动非常有用。 大部分现代化应用都有某种日志记录机制。同样地,容器引擎也被设计成支持日志记录。 针对容器化应用,最简单且最广泛采用的日志记录方式就是写入标准输出和标准错误流。

但是,由容器引擎或运行时提供的原生功能通常不足以构成完整的日志记录方案。

例如,如果发生容器崩溃、Pod 被逐出或节点宕机等情况,你可能想访问应用日志。

在集群中,日志应该具有独立的存储,并且其生命周期与节点、Pod 或容器的生命周期相独立。 这个概念叫集群级的日志。

集群级日志架构需要一个独立的后端用来存储、分析和查询日志。 Kubernetes 并不为日志数据提供原生的存储解决方案。 相反,有很多现成的日志方案可以集成到 Kubernetes 中。 下面各节描述如何在节点上处理和存储日志。

Pod 和容器日志

Kubernetes 从正在运行的 Pod 中捕捉每个容器的日志。

此示例使用带有一个容器的 Pod 的清单,该容器每秒将文本写入标准输出一次。


 debug/counter-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox:1.28
    args: [/bin/sh, -c,
            'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']

要运行此 Pod,请执行以下命令:

kubectl apply -f https://k8s.io/examples/debug/counter-pod.yaml

输出为:

pod/counter created

要获取这些日志,请执行以下 kubectl logs 命令:

kubectl logs counter

输出类似于:

0: Fri Apr  1 11:42:23 UTC 2022
1: Fri Apr  1 11:42:24 UTC 2022
2: Fri Apr  1 11:42:25 UTC 2022

你可以使用 kubectl logs --previous 从容器的先前实例中检索日志。 如果你的 Pod 有多个容器,请如下通过将容器名称追加到该命令并使用 -c 标志来指定要访问哪个容器的日志:

kubectl logs counter -c count

节点的容器日志处理方式

容器运行时对写入到容器化应用程序的 stdout 和 stderr 流的所有输出进行处理和转发。 不同的容器运行时以不同的方式实现这一点;不过它们与 kubelet 的集成都被标准化为 CRI 日志格式

默认情况下,如果容器重新启动,kubelet 会保留一个终止的容器及其日志。 如果一个 Pod 被逐出节点,所对应的所有容器及其日志也会被逐出。

kubelet 通过 Kubernetes API 的特殊功能将日志提供给客户端访问。 访问这个日志的常用方法是运行 kubectl logs

日志轮转

特性状态: Kubernetes v1.21 [stable]

你可以配置 kubelet 令其自动轮转日志。

如果配置轮转,kubelet 负责轮转容器日志并管理日志目录结构。 kubelet(使用 CRI)将此信息发送到容器运行时,而运行时则将容器日志写到给定位置。

你可以使用 kubelet 配置文件配置两个 kubelet 配置选项、 containerLogMaxSize 和 containerLogMaxFiles。 这些设置分别允许你分别配置每个日志文件大小的最大值和每个容器允许的最大文件数。

当类似于基本日志示例一样运行 kubectl logs 时, 节点上的 kubelet 会处理请求并直接从日志文件读取。kubelet 将返回该日志文件的内容。

说明:

只有最新的日志文件的内容可以通过 kubectl logs 获得。

例如,如果 Pod 写入 40 MiB 的日志,并且 kubelet 在 10 MiB 之后轮转日志, 则运行 kubectl logs 将最多返回 10 MiB 的数据。

系统组件日志

系统组件有两种类型:通常在容器中运行的组件和直接参与容器运行的组件。例如:

  • kubelet 和容器运行时不在容器中运行。kubelet 运行你的容器 (一起按 Pod 分组)
  • Kubernetes 调度器、控制器管理器和 API 服务器在 Pod 中运行 (通常是静态 Pod。 etcd 组件在控制平面中运行,最常见的也是作为静态 Pod。 如果你的集群使用 kube-proxy,则通常将其作为 DaemonSet 运行。

日志位置

kubelet 和容器运行时写入日志的方式取决于节点使用的操作系统:

  • Linux
  • Windows

在使用 systemd 的 Linux 节点上,kubelet 和容器运行时默认写入 journald。 你要使用 journalctl 来阅读 systemd 日志;例如:journalctl -u kubelet。

如果 systemd 不存在,kubelet 和容器运行时将写入到 /var/log 目录中的 .log 文件。 如果你想将日志写入其他地方,你可以通过辅助工具 kube-log-runner 间接运行 kubelet, 并使用该工具将 kubelet 日志重定向到你所选择的目录。

kubelet 始终指示你的容器运行时将日志写入 /var/log/pods 中的目录。

有关 kube-log-runner 的更多信息,请阅读系统日志。

对于在 Pod 中运行的 Kubernetes 集群组件,其日志会写入 /var/log 目录中的文件, 相当于绕过默认的日志机制(组件不会写入 systemd 日志)。 你可以使用 Kubernetes 的存储机制将持久存储映射到运行该组件的容器中。

同样,你可以使用 Kubernetes 的存储机制将持久存储映射到运行该组件的容器中。

说明:

如果你部署 Kubernetes 集群组件(例如调度器)以将日志记录到从父节点共享的卷中, 则需要考虑并确保这些日志被轮转。 Kubernetes 不管理这种日志轮转

你的操作系统可能会自动实现一些日志轮转。例如,如果你将目录 /var/log 共享到一个组件的静态 Pod 中, 则节点级日志轮转会将该目录中的文件视同为 Kubernetes 之外的组件所写入的文件。

一些部署工具会考虑日志轮转并将其自动化;而其他一些工具会将此留给你来处理。

集群级日志架构

虽然 Kubernetes 没有为集群级日志记录提供原生的解决方案,但你可以考虑几种常见的方法。 以下是一些选项:

  • 使用在每个节点上运行的节点级日志记录代理。
  • 在应用程序的 Pod 中,包含专门记录日志的边车(Sidecar)容器。
  • 将日志直接从应用程序中推送到日志记录后端。

使用节点级日志代理

你可以通过在每个节点上使用节点级的日志记录代理来实现集群级日志记录。 日志记录代理是一种用于暴露日志或将日志推送到后端的专用工具。 通常,日志记录代理程序是一个容器,它可以访问包含该节点上所有应用程序容器的日志文件的目录。

由于日志记录代理必须在每个节点上运行,推荐以 DaemonSet 的形式运行该代理。

节点级日志在每个节点上仅创建一个代理,不需要对节点上的应用做修改。

容器向标准输出和标准错误输出写出数据,但在格式上并不统一。 节点级代理收集这些日志并将其进行转发以完成汇总。

使用边车容器运行日志代理

你可以通过以下方式之一使用边车(Sidecar)容器:

  • 边车容器将应用程序日志传送到自己的标准输出。
  • 边车容器运行一个日志代理,配置该日志代理以便从应用容器收集日志。

传输数据流的边车容器

利用边车容器,写入到自己的 stdout 和 stderr 传输流, 你就可以利用每个节点上的 kubelet 和日志代理来处理日志。 边车容器从文件、套接字或 journald 读取日志。 每个边车容器向自己的 stdout 和 stderr 流中输出日志。

这种方法允许你将日志流从应用程序的不同部分分离开,其中一些可能缺乏对写入 stdout 或 stderr 的支持。重定向日志背后的逻辑是最小的,因此它的开销不大。 另外,因为 stdout 和 stderr 由 kubelet 处理,所以你可以使用内置的工具 kubectl logs

例如,某 Pod 中运行一个容器,且该容器使用两个不同的格式写入到两个不同的日志文件。 下面是这个 Pod 的清单:


 admin/logging/two-files-counter-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox:1.28
    args:
    - /bin/sh
    - -c
    - >
      i=0;
      while true;
      do
        echo "$i: $(date)" >> /var/log/1.log;
        echo "$(date) INFO $i" >> /var/log/2.log;
        i=$((i+1));
        sleep 1;
      done      
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  volumes:
  - name: varlog
    emptyDir: {}

不建议在同一个日志流中写入不同格式的日志条目,即使你成功地将其重定向到容器的 stdout 流。 相反,你可以创建两个边车容器。每个边车容器可以从共享卷跟踪特定的日志文件, 并将文件内容重定向到各自的 stdout 流。

下面是运行两个边车容器的 Pod 的清单:


 admin/logging/two-files-counter-pod-streaming-sidecar.yaml

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox:1.28
    args:
    - /bin/sh
    - -c
    - >
      i=0;
      while true;
      do
        echo "$i: $(date)" >> /var/log/1.log;
        echo "$(date) INFO $i" >> /var/log/2.log;
        i=$((i+1));
        sleep 1;
      done      
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  - name: count-log-1
    image: busybox:1.28
    args: [/bin/sh, -c, 'tail -n+1 -F /var/log/1.log']
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  - name: count-log-2
    image: busybox:1.28
    args: [/bin/sh, -c, 'tail -n+1 -F /var/log/2.log']
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  volumes:
  - name: varlog
    emptyDir: {}

现在当你运行这个 Pod 时,你可以运行如下命令分别访问每个日志流:

kubectl logs counter count-log-1

输出类似于:

0: Fri Apr  1 11:42:26 UTC 2022
1: Fri Apr  1 11:42:27 UTC 2022
2: Fri Apr  1 11:42:28 UTC 2022
...
kubectl logs counter count-log-2

输出类似于:

Fri Apr  1 11:42:29 UTC 2022 INFO 0
Fri Apr  1 11:42:30 UTC 2022 INFO 0
Fri Apr  1 11:42:31 UTC 2022 INFO 0
...

如果你在集群中安装了节点级代理,由代理自动获取上述日志流,而无需任何进一步的配置。 如果你愿意,你可以将代理配置为根据源容器解析日志行。

即使对于 CPU 和内存使用率较低的 Pod(CPU 为几毫核,内存为几兆字节),将日志写入一个文件, 将这些日志流写到 stdout 也有可能使节点所需的存储量翻倍。 如果你有一个写入特定文件的应用程序,则建议将 /dev/stdout 设置为目标文件,而不是采用流式边车容器方法。

边车容器还可用于轮转应用程序本身无法轮转的日志文件。 这种方法的一个例子是定期运行 logrotate 的小容器。 但是,直接使用 stdout 和 stderr 更直接,而将轮转和保留策略留给 kubelet。

集群中安装的节点级代理会自动获取这些日志流,而无需进一步配置。 如果你愿意,你也可以配置代理程序来解析源容器的日志行。

注意,尽管 CPU 和内存使用率都很低(以多个 CPU 毫核指标排序或者按内存的兆字节排序), 向文件写日志然后输出到 stdout 流仍然会成倍地增加磁盘使用率。 如果你的应用向单一文件写日志,通常最好设置 /dev/stdout 作为目标路径, 而不是使用流式的边车容器方式。

如果应用程序本身不能轮转日志文件,则可以通过边车容器实现。 这种方式的一个例子是运行一个小的、定期轮转日志的容器。 然而,还是推荐直接使用 stdout 和 stderr,将日志的轮转和保留策略交给 kubelet。

具有日志代理功能的边车容器

如果节点级日志记录代理程序对于你的场景来说不够灵活, 你可以创建一个带有单独日志记录代理的边车容器,将代理程序专门配置为与你的应用程序一起运行。

说明:

在边车容器中使用日志代理会带来严重的资源损耗。 此外,你不能使用 kubectl logs 访问日志,因为日志并没有被 kubelet 管理。

下面是两个配置文件,可以用来实现一个带日志代理的边车容器。 第一个文件包含用来配置 fluentd 的 ConfigMap。

admin/logging/fluentd-sidecar-config.yaml 

apiVersion: v1
kind: ConfigMap
metadata:
  name: fluentd-config
data:
  fluentd.conf: |
    <source>
      type tail
      format none
      path /var/log/1.log
      pos_file /var/log/1.log.pos
      tag count.format1
    </source>

    <source>
      type tail
      format none
      path /var/log/2.log
      pos_file /var/log/2.log.pos
      tag count.format2
    </source>

    <match **>
      type google_cloud
    </match>    

说明:

你可以将此示例配置中的 fluentd 替换为其他日志代理,从应用容器内的其他来源读取数据。

第二个清单描述了一个运行 fluentd 边车容器的 Pod。 该 Pod 挂载一个卷,flutend 可以从这个卷上拣选其配置数据。


 admin/logging/two-files-counter-pod-agent-sidecar.yaml

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox:1.28
    args:
    - /bin/sh
    - -c
    - >
      i=0;
      while true;
      do
        echo "$i: $(date)" >> /var/log/1.log;
        echo "$(date) INFO $i" >> /var/log/2.log;
        i=$((i+1));
        sleep 1;
      done      
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  - name: count-agent
    image: registry.k8s.io/fluentd-gcp:1.30
    env:
    - name: FLUENTD_ARGS
      value: -c /etc/fluentd-config/fluentd.conf
    volumeMounts:
    - name: varlog
      mountPath: /var/log
    - name: config-volume
      mountPath: /etc/fluentd-config
  volumes:
  - name: varlog
    emptyDir: {}
  - name: config-volume
    configMap:
      name: fluentd-config

从应用中直接暴露日志目录

从各个应用中直接暴露和推送日志数据的集群日志机制已超出 Kubernetes 的范围。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/733148.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaEE】前后端综合项目-博客系统(下)

【JavaEE】前后端综合项目-博客系统&#xff08;下&#xff09; 文章目录 【JavaEE】前后端综合项目-博客系统&#xff08;下&#xff09;1. 博客登录页1.1 用户名密码校验1.1.1 约定前后端交互接口1.1.2 后端代码1.1.3 前端代码 1.2 登录信息记忆功能1.2.1 约定前后端交互接口…

【Kerberos-KafkaTool】在大数据Kerberos认证下使用KafkaTool工具

【Kerberos-KafkaTool】在大数据Kerberos认证下使用KafkaTool工具 1&#xff09;安装 Kafka Tool 工具2&#xff09;配置 Kafka Tool 属性3&#xff09;添加相关配置3.1.新建连接3.2.Properties3.3.Security3.4.Advanced3.5.JAAS Config 1&#xff09;安装 Kafka Tool 工具 下…

驱动开发 作业2

使用 ioctl 替换 write/read 控制 LED、蜂鸣器、马达、风扇&#xff0c;并使用 udev 来自动创建设备文件 完整代码目录&#xff0c;请看这个仓库依然使用之前 ARM 课程中的 common 中的结构体代码都差不多&#xff0c;就贴个 led.c &#xff0c;用户空间测试代码 test.c 和头文…

多元回归预测 | Matlab主成分分析PCA降维,PLS偏小二乘回归预测。PCA-PLS回归预测模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元回归预测 | Matlab主成分分析PCA降维,PLS偏小二乘回归预测。PCA-PLS回归预测模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码 %% 清空环境变量 warn…

硬件性能 - 磁盘瓶颈分析

简介 本文章通过Linux命令输出指标项&#xff0c;简单的介绍硬件资源-磁盘的性能瓶颈分析。其他硬件性能分析如下&#xff1a; 1. 硬件性能 - CPU瓶颈分析 2. 硬件性能 - 掌握内存知识 3. 硬件性能 - 网络瓶颈分析 目录 1. 测试磁盘性能 1.1. 读性能 1.2. 写性能 1.3. 同时…

MachineLearningWu_5_MultipleLinearRegression

在进行多元线性回归的时候&#xff0c;我们需要规定一些基本法则。例如我们使用 x j ( i ) x_j^{(i)} xj(i)​来表示第i个sample的第j个特征。 将单元的线性回归变为多元线性回归&#xff0c;公式将变换为如下&#xff0c; 为了实现更简单的数学表达式&#xff0c;我们将表达式…

haproxy负载均衡

目录 一.常见的web集群调度器 二.haproxy的概念 三.特性 四 图解haproxy 五 haproxy的配置文件详解 一.常见的web集群调度器 1.目前常见的web集群调度器分为软件和硬件 2.软件通常使用开源的lvs/haproxy/nginx 3.硬件一般使用比较多的是f5 也有国内的产品 二.haproxy的…

LeetCode:合并区间

题目&#xff1a;56. 合并区间 - 力扣&#xff08;Leetcode&#xff09; 讲这道题之前&#xff0c;先介绍一下sort函数的骚操作。 sort函数可以用于二维数组的排序&#xff01;&#xff01;&#xff01; 解释&#xff1a; 这里sort函数也是从小到大进行排序&#xff0c;只…

确保无缝、安全的云转型

随着云计算继续主导数字化转型&#xff08;这是理所当然的&#xff09;&#xff0c;组织面临着双重挑战&#xff1a;将运营无缝转移到云并确保这种转型的安全。 虽然云的采用保证了可扩展性、成本效率和生产力的提高&#xff0c;但保持警惕对于组织防范网络安全威胁和安全漏洞…

webpack5搭建与基本概念

webpack基础构建 新建文件夹进入文件夹查看是否安装node&#xff0c;命令&#xff1a;node-v创建package.json文件&#xff0c;命令&#xff1a;npm init -y安装webpack和webpack-cli&#xff0c;&#xff08;命令自动创建出package-lock.json文件和node_modules文件夹&#x…

【智慧交通项目实战】《 OCR车牌检测与识别》(一)项目介绍

👨‍💻作者简介: CSDN、阿里云人工智能领域博客专家,新星计划计算机视觉导师,百度飞桨PPDE,专注大数据与AI知识分享。✨公众号:GoAI的学习小屋 ,免费分享书籍、简历、导图等,更有交流群分享宝藏资料,关注公众号回复“加群”或➡️点击链接 加群。 🎉专栏推荐: 点…

指针进阶(1)(字符指针,指针数组,数组指针,函数指针)

目录 前言&#xff1a; 字符指针 TIP&#xff1a; 指针数组 数组指针 概念辨析 形式辨析 数组名的理解&#xff1a; 数组指针如何使用&#xff1f; 二维数组的传参 函数指针 函数的地址&#xff1a; 函数指针的形式 函数指针的作用 关于函数指针一些奇特的点 前言&…

Java基础知识 之 java Applet 小训练

import java.applet.Applet; import java.awt.*; import java.util.Random;import static java.lang.Math.cos; import static java.lang.Math.sin;public class HelloWorldApplet extends Applet {public void paint(Graphics g) {// 将Graphics对象转换为Graphics2D类型java.…

Linux 系统编辑 --文件IO

目录 1.文件 IO 1.1系统调用 1.2 C 标准库文件 IO 函数 1.3 open/close 函数 1.4 文件描述符表 1.7 read/write 函数 1.8 缓冲区 1.9 错误处理函数 2.0 阻塞、非阻塞 2.1 lseek 函数 辅助学习资料 参考书 1 &#xff1a;《 Unix 环境高级编程》 W.Richard St…

MFC学习日记(二)——VS2012应用程序工程中文件的组成结构

上一篇我们用应用程序向导生成框架程序后&#xff0c;我们可以打开工程所在的文件夹看到以下以解决方案命名的文件夹&#xff0c;此文件夹中包含了几个文件和一个以工程名命名的子文件夹&#xff0c;这个子文件夹中又包含了若干个文件和一个res文件夹&#xff0c;创建工程时的选…

Vue2:axios解决跨域的问题(vue2没有config情况下)

在vue2上用axios发起Post模拟注册的时候&#xff0c;调用接口&#xff0c;提示报错&#xff1a; axios({method: post,url: http://1.12.254.80:8080/api/user/register,// url: /user/api/user/register,data: { // 请求体数据userAccount: userName,userPassword: pwd1,check…

离线环境下安装微软Visual Studio 2022 生成工具

1. 前言 最近&#xff0c;在学习cython的时候&#xff0c;需要安装windows下的C/C编译、链接工具。开始觉得传统的msvc太大了&#xff0c;想要尝试Mingw&#xff0c;但是都是编译错误。无奈之下&#xff0c;还是要安装msvc。 微软提供了Visual Studio 2022 Build Tools &…

MySQl数据库第五课 --------在SQl的简单命令--------学习学习

作者前言 欢迎小可爱们前来借鉴我的gtiee秦老大大 (qin-laoda) - Gitee.com ———————————————————————————— 目录 数据库的简单介绍 1.数据储存 2.数据库类型 &#xff08;1&#xff09;.关系型数据库 &#xff08;2&#xff09;.非关系型数据库…

大学英语六级相当于雅思考试多少分

雅思考试的难度&#xff0c;可以和大学英语六级进行对应&#xff0c;大家可以通过分数来基本确认雅思考试的难度系数。跟着小编来一起看看大学英语六级相当于雅思考试多少分&#xff1f; 英语六级相当于雅思多少分 大学英语六级和雅思没有直接的分数对应关系&#xff0c;一般大…

部署LVS+Keepalived高可用集群

目录 一、keepalived概述 1.1管理LVS负载均衡软件 1.2VRRP(Virtual Router Redundancy Protocol) 原理 二、keepalived服务的重要功能 2.1自动切换&#xff08;failover&#xff09; 2.2健康检查&#xff08;health checking&#xff09; 2.3高可用&#xff08;HA&#x…