kubernetes日志备份解决ELK中日志丢失问题

 更新时间:2023年10月31日 09:27:03   作者:DQuery  
这篇文章主要为大家介绍了kubernetes日志备份方案的细节探究分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

背景

为解决日志在ELK中偶发性丢失问题,需要对应用日志进行备份,当关键日志缺失后可以对原始日志进行查询。应用日志除了传ELK,在本地(docker内部)也保存一份原始文件,路径为/opt/logs并且通过logback相关配置可以对日志进行自动归档。

方案

总体方案

总体方案是在主机上通过本地文件系统找到应用在容器内的日志文件,借助rsync进行备份,再通过crontab配置定时任务就能实现日志的备份。

实现

docker本质就是一个根文件系统(roots)+Linux内核程序,docker内部所有的文件在宿主机上都有对应的映射,通过docker inspect命令可以查看容器在宿主机上文件系统路径

# docker inspect 84be0c7fd47b --format '{{.GraphDriver.Data.MergedDir }}'
/u01/docker/overlay2/a3226f727cf8217bff0bfc8036201834260a50502c7e6b5eb0672a5305665c0e/merged

我们进入该目录

root@k8s-node-dev-10:/u01/docker/overlay2/a3226f727cf8217bff0bfc8036201834260a50502c7e6b5eb0672a5305665c0e/merged# ll
total 156444
drwxr-xr-x 1 root root      3488 Oct 19 01:42 ./
drwx--x--- 5 root root      3488 Oct 19 01:42 ../
-rw-r--r-- 1 root root 159961293 Oct 19 01:41 app.jar
drwxr-xr-x 1 root root      3488 May 15 01:13 bin/
drwxr-xr-x 1 root root      3488 Oct 19 01:42 dev/
-rwxr-xr-x 1 root root         0 Oct 19 01:42 .dockerenv*
-rwxrwxrwx 1 root root      1756 May 29 00:59 entrypoint.sh*
drwxr-xr-x 1 root root      3488 Oct 19 01:42 etc/
drwxr-xr-x 2 root root      3488 May  9  2019 home/
drwxr-xr-x 1 root root      3488 May 15 01:15 lib/
drwxr-xr-x 2 root root      3488 May 15 01:13 lib64/
drwxr-xr-x 5 root root      3488 May  9  2019 media/
drwxr-xr-x 2 root root      3488 May  9  2019 mnt/
drwxr-xr-x 1 root root      3488 Oct 19 01:42 opt/
dr-xr-xr-x 2 root root      3488 May  9  2019 proc/
drwx------ 1 root root      3488 Oct 30 06:49 root/
drwxr-xr-x 1 root root      3488 Oct 19 01:42 run/
drwxr-xr-x 1 root root      3488 May 15 01:13 sbin/
drwxr-xr-x 2 root root      3488 May  9  2019 srv/
drwxr-xr-x 2 root root      3488 May  9  2019 sys/
drwxrwxrwt 2 root root      3488 May  9  2019 tmp/
drwxr-xr-x 1 root root      3488 Oct 19 01:42 usr/
drwxr-xr-x 1 root root      3488 May  9  2019 var/

可以发现就是容器内的Linux文件系统,我们可以通过以下脚本,显示出所有容器在主机上的文件系统路径

for container in $(docker ps --all --quiet --format '{{ .Names }}'); do
    log_path=$(docker inspect $container --format '{{.GraphDriver.Data.MergedDir }}')
         echo $log_path
done

由于日志保存在容器内部的/opt/logs目录下,对应主机路径就是log_path/opt/logs目录,找到文件路径后,我们需要知道该文件对应的服务名称,从路径上我们只能得到一个类似a3226f727cf8217bff0bfc8036201834260a50502c7e6b5eb0672a5305665c0e的ID,那怎么根据这个ID获取到服务名称呢,kubernetes在启动应用docker容器时,会给容器打上标签,其中就包含了应用名称,我们通过inspect命令就可以查看

# docker inspect 84be0c7fd47b 
....
 "Labels": {
                "annotation.io.kubernetes.container.hash": "f44b328d",
                "annotation.io.kubernetes.container.ports": "[{\"name\":\"8080tcp2\",\"containerPort\":8080,\"protocol\":\"TCP\"}]",
                "annotation.io.kubernetes.container.restartCount": "0",
                "annotation.io.kubernetes.container.terminationMessagePath": "/dev/termination-log",
                "annotation.io.kubernetes.container.terminationMessagePolicy": "File",
                "annotation.io.kubernetes.pod.terminationGracePeriod": "30",
                "io.kubernetes.container.logpath": "/var/log/pods/xinyou-application_xinyou-service-message-7745fd9699-drkzg_26e825a2-8f5e-4b5b-aed1-758139fc019c/xinyou-service-message/0.log",
                "io.kubernetes.container.name": "xinyou-message-service",
                "io.kubernetes.docker.type": "container",
                "io.kubernetes.pod.name": "xinyou-message-service-7745fd9699-drkzg",
                "io.kubernetes.pod.namespace": "xinyou-application",
                "io.kubernetes.pod.uid": "26e825a2-8f5e-4b5b-aed1-758139fc019c",
                "io.kubernetes.sandbox.id": "7bc9954a02c7e43a1a21b8cc47e09f86ada8f6e8584c49150c67d77dc13b6832"
            }
 ....

其中io.kubernetes.container.name就是服务名称,io.kubernetes.pod.name是pod名称,io.kubernetes.container.name就是命名空间,所以拿到ID后我们可以通过inspect获取到服务 名称,有了原始文件路径,服务名称后,就可以写备份脚本

#!/bin/bash
for container in $(docker ps --all --quiet --format '{{ .Names }}'); do
    log_path=$(docker inspect $container --format '{{.GraphDriver.Data.MergedDir }}')
    log_path=${log_path}/opt/logs/
    service_name=$(docker inspect $container --format '{{ index .Config.Labels "io.kubernetes.container.name" }}')
    pod_name=$(docker inspect $container --format '{{ index .Config.Labels "io.kubernetes.pod.name" }}')
    target_path=/u01/logbackup/$service_name/$pod_name
    if [ -d "$log_path" ]; then
      echo "sync $service_name/$pod_name from $log_path to $target_path"
      mkdir -p $target_path
      rsync -av "$log_path" "$target_path" >log_backup.log
    fi
done

解释下脚本内容

  • 通过docker ps --all 获取到所有容器列表,因为加了--all命令,所以也包含停止运行的容器,这里为什么要包含停止运行的容器,原因是脚本执行是周期性的,假设在执行周期内容器停止运行了,那么就会失去这段时间的日志,所以就算是停止运行的容器也要同步日志。

  • log_path就是日志在主机上的路径

  • service_name就是服务名称,读取的是io.kubernetes.container.name这个标签

  • target_path备份目标路径,这里路径加上了pod_name,原因是一个主机上可能运行服务的多个副本,如果不加上pod_name,有可能两个副本的日志会相互覆盖,因为日志名称是一样的。

  • 通过rsync命令进行同步,rsync命令可以实现增量同步,速度和效率都远远比cp命令高

  • 脚本只对包含opt/logs的容器进行日志备份,如果有额外情况需要更改脚本

配置crontab就可以定时执行脚本进行备份任务

* * * * * /u01/scripts/log_backup.sh

这里是一分钟执行一次,这个频率其实可以更低,因为我们有将停止的容器包含进去,所以频率低一些也不会有日志丢失。

以下是日志同步后的日志备份目录文件夹分布情况:

root@k8s-node-dev-10:/u01/logbackup# tree -d
.
├── xinyou-mes
│   └── xinyou-mes-6c5cd57447-qgk29
├── xinyou-gateway
│   └── xinyou-gateway-67bff75986-qsgsq
├── xinyou-bbc-service
│   └── xinyou-bbc-service-7455c4dc86-kj6tp
├── xinyou-ddr-service
│   └── xinyou-ddr-service-c774bbbb7-mh7fk
├── xinyou-iam-service
│   └── xinyou-iam-service-59b844df47-5h5gs
├── xinyou-review-service
│   └── xinyou-review-service-856c5f545c-lxmz6
├── xinyou-sass-oa
│   └── xinyou-sass-oa-77845c55bb-jjmf2
├── xinyou-service-message
│   └── xinyou-service-message-7745fd9699-drkzg
└── xinyou-tables-service
    └── xinyou-tables-service-7fd66d4c95-7pcst

以上就是kubernetes日志备份方案细节探究的详细内容,更多关于kubernetes日志备份的资料请关注脚本之家其它相关文章!

相关文章

  • k8s控制deamonset中pod数量的方法

    k8s控制deamonset中pod数量的方法

    DaemonSet是Kubernetes中用于确保每个节点运行一个Pod副本的控制器,常用于运行集群守护进程,通过节点选择器、节点亲和性、容忍度和更新策略,可以精确控制Pod的数量和调度,本文介绍k8s控制deamonset中pod数量的方法,感兴趣的朋友一起看看吧
    2025-01-01
  • k8s按需创建PV和使用PVC详解

    k8s按需创建PV和使用PVC详解

    Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收策略和绑定模式
    2025-09-09
  • k8s admin用户生成token方式

    k8s admin用户生成token方式

    用户使用Kubernetes 1.28创建admin命名空间并部署,通过ClusterRoleBinding为jenkins用户授权集群级权限,生成并获取其token,最后检查token是否存在及生效情况
    2025-09-09
  • 快速搞定K8S新老版本的证书续期问题

    快速搞定K8S新老版本的证书续期问题

    本文介绍了Kubernetes集群证书续期的步骤,包括更新证书、替换CCNA证书、重启相关组件以及验证新证书的有效性
    2026-01-01
  • ragflow k8s部署过程图文详解

    ragflow k8s部署过程图文详解

    这篇文章主要介绍了ragflow k8s部署详细过程,本文将使用ragflow-0.18.0,来进行演示详细部署过程,需要的朋友可以参考下
    2025-04-04
  • Kubernetes集群模拟删除k8s重装详解

    Kubernetes集群模拟删除k8s重装详解

    这篇文章主要为大家介绍了Kubernetes集群模拟删除k8s重装详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • 详解K8S apiVersion对照表

    详解K8S apiVersion对照表

    k8s更新迭代比较快,apiVersion也在不断变化中,每个版本的对应的apiVersion略有不同,这篇文章主要介绍了K8S apiVersion对照表,需要的朋友可以参考下
    2022-07-07
  • k8s部署ingress-nginx的详细步骤大全

    k8s部署ingress-nginx的详细步骤大全

    nginx一般是作为服务的入口,其在kubernetes的部署方式也大致相似,这篇文章主要给大家介绍了关于k8s部署ingress-nginx的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • Kubernetes探针使用介绍

    Kubernetes探针使用介绍

    这篇文章主要为大家介绍了Kubernetes探针使用详细介绍,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-03-03
  • K8s Affinity亲和力详解(调度策略)

    K8s Affinity亲和力详解(调度策略)

    文章介绍了Kubernetes中亲和力和反亲和力的调度策略,包括节点和Pod的硬性、软性规则,用于实现Pod与节点的标签匹配、区域均衡负载及避免单节点过载等场景,强调标签匹配和副本数限制对调度结果的影响
    2025-08-08

最新评论