Kubernetes 文件采集实践:Sidecar + hostPath 卷

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 本文通过一个简单的示例应用(Dockerfile)以及相应的部署配置(YAML),介绍了如何结合 Sidecar + hostPath 来实现 Kubernetes 文件的采集并保证数据在极端情况(Pod 崩溃、Node 宕机)下的安全性。

Kubernetes 日志查询分析实践中,我们介绍了如何通过 DaemonSet 方式部署 logtail 并采集标准输出/文件两种形式的数据。DaemonSet 部署的优势在于其能够尽可能地减少采集 agent 所占用的资源且支持标准输出采集,但因为每个 DaemonSet pod 需要负责 node 级别的数据采集,所以同一个 node 上的各个业务 pod 之间可能会相互影响,比如大数据量的业务 pod 可能会消耗更多的 logtail 处理时间片,进而影响到其他业务 pod 的数据采集。


因此,针对这类数据比较重要的业务文件,我们推荐采用 Sidecar 方式部署 logtail,即在业务 pod 内增加额外一个容器来运行 logtail,专注于该 pod 的文件采集。关于两种部署方式更为详细的优劣对比,可以参考采集方式对比,本文不再赘述。


考虑到使用 Sidecar 进行采集的业务往往对于数据安全性要求较高,所以本文将结合这一需求,介绍在 Sidecar 的基础上,通过配置 hostPath 卷来保证极端情况下(Node 宕机、Pod 崩溃等)数据的安全性。为了使内容更加易于理解和使用,本文会给出一个简单的示例应用(Dockerfile)以及相应的部署配置(YAML),方便读者在此基础上进行改造。


设计简介

Pod 崩溃

首先考虑下 pod 崩溃的场景。在默认情况下,Pod 内业务容器所产生的文件都是临时存在的,当 Pod 发生崩溃的时候,这些数据都会丢失。为了保证它们不丢,一个简单的思路就是把它们挂载到持久化卷,将数据与 pod 生命周期解耦,达到 pod 挂而数据活的效果。

在本文中,我们选择利用 hostPath 卷,将 pod 的数据目录挂载到其所运行的宿主机(node)上。由于单个 node 上会同时运行多个业务 pod,我们需要做一定的空间划分,一个可行的办法是在宿主机上提供一个数据目录(比如 /data),而每个 pod 在运行时从这个数据目录下创建一个子目录作为自己的数据空间(比如 /data/<pod_name>)。在这个数据空间下,pod 可以根据自己的需要再作划分,比如增加 logs 目录存放日志,data 目录存放业务逻辑生成的数据。


Node 宕机

在基于 hostPath 卷 + 宿主机数据目录这套方案的基础上,解决 node 宕机的方式非常简单,把数据目录和 node 本身解耦就行,比如使用云盘作为数据目录。这样 node 崩溃也无所谓,拉一个新的节点起来,重新

挂载上这块云盘即可恢复数据。如何挂载可以参考云盘存储卷概述



示例

以下将给出一个示例应用和部署配置(源码)来进一步说明上述设计。


应用及其部署配置

应用逻辑很简单,先按照我们之间设计中所说的,创建相应的 pod 数据目录,然后产生日志。


#!/bin/bashecho"Data directory: ${POD_DATA_DIR}"# 根据环境变量创建指定的日志目录(顺带创建了数据目录)。# 如果目录已存在,说明发生冲突,拼接当前时间并调整环境变量。if [ -d${POD_DATA_DIR} ]; thenecho"Existing data directory ${POD_DATA_DIR}, concat timestamp"POD_DATA_DIR="${POD_DATA_DIR}-$(date +%s)"echo"New data directory: ${POD_DATA_DIR}"fiPOD_LOG_DIR="${POD_DATA_DIR}/logs"mkdir-p${POD_LOG_DIR}# 为了统一 logtail 采集配置中的日志路径,创建软链接。ln-s${POD_LOG_DIR} /share/logs
# 产生日志。LOG_FILE_PATH=${POD_LOG_DIR}/app.log
for((i=0;i<10000000000000;i++)); doecho"Log ${i} to file" >> ${LOG_FILE_PATH}sleep1done

示例代码 run.sh 如上,分为以下几个步骤:

  1. 根据环境变量 POD_DATA_DIR(部署配置中指定),创建相应的数据目录及日志目录(logs)。
  2. 创建软链接以统一 logtail 采集配置中的日志路径,这个下一节会结合 sidecar 配置展开说明。此步骤非必须,对于在本地管理采集配置的 agent(比如 filebeat),直接采集 POD_LOG_DIR 目录就可以。
  3. 产生日志,实际应用可以根据需要执行相应 binary,但需要确保相关数据/日志落在 pod 数据目录下。


结合如下 Dockerfile,我们将 run.sh 打包为应用镜像,URL:registry.cn-hangzhou.aliyuncs.com/log-service/docker-log-test:sidecar-app

FROM registry.cn-hangzhou.aliyuncs.com/log-service/centos:centos7.7.1908
ADD run.sh /run.sh
RUN chmod +x /run.sh
ENTRYPOINT ["/run.sh"]


最后来看下应用部分的部署配置(YAML):

apiVersion: v1
kind: Pod
metadata:# 后缀不固定,随机生成名字。  generateName: app-sidecar-logtail-
  namespace: default
spec:  volumes:# 定义应用容器和 Logtail Sidecar 容器的共享目录。  - emptyDir: {}    name: share
# 定义宿主机上的数据目录,应用容器将在该目录下创建子目录作为自己的数据目录。  - hostPath:      path: /data
      type: DirectoryOrCreate
    name: parent-data-dir-on-host
  containers:# 应用容器,以文件形式输出日志。  - name: app
# 应用程序执行逻辑:# 1. 在宿主机数据目录下创建相应的子目录作为自身的数据目录。# 2. 为该数据目录创建相应的软链接,通过共享目录分享给 Sidecar 容器。# 3. 执行应用程序逻辑(此处为不断产生 mock 数据)。# 该镜像的 Dockerfile 及启动脚本参考目录 app。    image: registry.cn-hangzhou.aliyuncs.com/log-service/docker-log-test:sidecar-app
    imagePullPolicy: Always
    volumeMounts:# 挂载共享目录,以向 Sidecar 容器分享数据。    - mountPath: /share
      name: share
# 挂载宿主机数据目录,以创建相应的子目录。    - mountPath: /data
      name: parent-data-dir-on-host
    env:# 获取 PodName 以在宿主机上为该 Pod 创建相应的数据目录。    - name: POD_NAME
      valueFrom:        fieldRef:          fieldPath: metadata.name
    - name: POD_DATA_DIR
      value: /data/$(POD_NAME)

主要关注两个部分的配置:

  • volumes/volumeMounts: 此处将宿主机目录 /data 作为所有 pod 数据目录的父目录,并以相同的路径挂载到 pod 内。
  • env POD_NAME, POD_DATA_DIR: 此处我们使用 pod name 作为 pod 数据目录的命名,在父目录下创建相应的子目录。


完整部署配置(含 Sidecar)

接下来需要在上面的应用部署配置中增加 Sidecar 的配置,此处我们以 logtail 为例(其他 agent 可以根据其文档作相应调整),完整配置如下:

apiVersion: v1
kind: Pod
metadata:# 后缀不固定,随机生成名字。  generateName: app-sidecar-logtail-
  namespace: default
spec:  volumes:# 定义应用容器和 Logtail Sidecar 容器的共享目录。  - emptyDir: {}    name: share
# 定义宿主机上的数据目录,应用容器将在该目录下创建子目录作为自己的数据目录。  - hostPath:      path: /data
      type: DirectoryOrCreate
    name: parent-data-dir-on-host
  containers:# 应用容器,以文件形式输出日志。  - name: app
# 应用程序执行逻辑:# 1. 在宿主机数据目录下创建相应的子目录作为自身的数据目录。# 2. 为该数据目录创建相应的软链接,通过共享目录分享给 Sidecar 容器。# 3. 执行应用程序逻辑(此处为不断产生 mock 数据)。# 该镜像的 Dockerfile 及启动脚本参考目录 app。    image: registry.cn-hangzhou.aliyuncs.com/log-service/docker-log-test:sidecar-app
    imagePullPolicy: Always
    volumeMounts:# 挂载共享目录,以向 Sidecar 容器分享数据。    - mountPath: /share
      name: share
# 挂载宿主机数据目录,以创建相应的子目录。    - mountPath: /data
      name: parent-data-dir-on-host
    env:# 获取 PodName 以在宿主机上为该 Pod 创建相应的数据目录。    - name: POD_NAME
      valueFrom:        fieldRef:          fieldPath: metadata.name
    - name: POD_DATA_DIR
      value: /data/$(POD_NAME)
# Logtail Sidecar 容器,共享应用容器日志目录采集日志。  - name: logtail
    image: registry-vpc.cn-hangzhou.aliyuncs.com/log-service/logtail:v1.0.25.0-eca7ef7-aliyun
    volumeMounts:# 只读挂载共享目录,获取日志数据。    - mountPath: /share
      name: share
      readOnly: true    - mountPath: /data
      name: parent-data-dir-on-host
      readOnly: true    env:# 为每条日志附加 Pod 相关的属性,以便溯源。# 可通过修改 ALIYUN_LOG_ENV_TAGS 的值按需增/删字段,字段间使用 | 分隔。# 如何获取 Pod 属性可参考此文档:https://kubernetes.io/zh/docs/tasks/inject-data-application/environment-variable-expose-pod-information/    - name: ALIYUN_LOG_ENV_TAGS
      value: _node_name_|_node_ip_|_pod_name_|_pod_namespace_
    - name: _node_name_
      valueFrom:        fieldRef:          apiVersion: v1
          fieldPath: spec.nodeName
    - name: _node_ip_
      valueFrom:        fieldRef:          apiVersion: v1
          fieldPath: status.hostIP
    - name: _pod_name_
      valueFrom:        fieldRef:          fieldPath: metadata.name
    - name: _pod_namespace_
      valueFrom:        fieldRef:          fieldPath: metadata.namespace
# 设置 Logtail 使用的配置文件,以访问到指定区域的 SLS。# 规则:/etc/ilogtail/conf/<region>-<network_type>/ilogtail_config.json# - <region> 表示区域,比如 cn-hangzhou, cn-shanghai# - <network_type> 表示使用的网络类型,intranet 内网、internet 公网、acceleration 全球加速# 示例:# - 公网访问杭州公有云:/etc/ilogtail/conf/cn-hangzhou-internet/ilogtail_config.json# - 全球加速访问上海公有云:/etc/ilogtail/conf/cn-shanghai-acceleration/ilogtail_config.json    - name: ALIYUN_LOGTAIL_CONFIG
      value: '/etc/ilogtail/conf/cn-hangzhou-internet/ilogtail_config.json'# 设置 Logtail 实例的自定义标识符,以关联机器组并获取采集配置。可设置多个,使用英文逗号(,)分隔。    - name: ALIYUN_LOGTAIL_USER_DEFINED_ID
      value: sidecar-logtail-1,sidecar-logtail-2
# 设置 ALIUID,以访问相应的 SLS Project。可设置多个,使用英文逗号(,)分隔。    - name: ALIYUN_LOGTAIL_USER_ID
      value: "123456789"# 其他启动参数:参考 https://help.aliyun.com/document_detail/32278.html    - name: cpu_usage_limit
      value: "2.0"    - name: mem_usage_limit
      value: "1024"

主要增加了 -name: logtail 往下的内容,和应用配置类似,也分为两部分:

  • volumeMounts: 增加两个相同的挂载,但作为采集侧,只需要 readOnly 即可。
  • env: 通过环境变量对 logtail 进行配置,包括指定连接的 SLS endpoint、日志附带属性、自定义标识符、ALIUID 等信息,实际应用需要相应地调整这些参数。


创建应用 pod

将上面的完整配置保存为 sidecar.yaml,使用 kubectl create -f sidecar.yaml 创建应用 pod。

$for((i=0;i<4;i++)); do kubectl create -f sidecar.yaml; donepod/app-sidecar-logtail-c8gsg created
pod/app-sidecar-logtail-k74lp created
pod/app-sidecar-logtail-5fqrl created
pod/app-sidecar-logtail-764vm created
$kubectlget pods -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP          NODE                       NOMINATED NODE   READINESS GATES
app-sidecar-logtail-5fqrl   2/2     Running   0          16s   10.7.0.37   cn-hangzhou.172.16.0.171   <none>           <none>
app-sidecar-logtail-764vm   2/2     Running   0          15s   10.7.0.70   cn-hangzhou.172.16.0.172   <none>           <none>
app-sidecar-logtail-c8gsg   2/2     Running   0          16s   10.7.0.36   cn-hangzhou.172.16.0.171   <none>           <none>
app-sidecar-logtail-k74lp   2/2     Running   0          16s   10.7.0.68   cn-hangzhou.172.16.0.172   <none>           <none>

每个 node 上有两个 pod,我们可以任选一个 pod,进入 app 容器中查看数据目录的情况。

$kubectl exec -it app-sidecar-logtail-5fqrl -c app bash[root@app-sidecar-logtail-5fqrl /]# ls -al /data/total 16drwxr-xr-x 4 root root 4096 Nov  802:40 .
drwxr-xr-x 1 root root 4096 Nov  802:40 ..
drwxr-xr-x 3 root root 4096 Nov  802:40 app-sidecar-logtail-5fqrl
drwxr-xr-x 3 root root 4096 Nov  802:40 app-sidecar-logtail-c8gsg
[root@app-sidecar-logtail-5fqrl /]# tail /share/logs/app.logLog 120 to file
Log 121 to file
Log 122 to file
Log 123 to file
Log 124 to file
Log 125 to file
Log 126 to file
Log 127 to file
Log 128 to file
Log 129 to file
  • /data/ 下每个 pod 以自己的名字创建了相应的数据目录。
  • /share/logs 是每个 pod 中创建的日志目录软链接,可以从中访问到相应的文件。


采集至 SLS(控制台操作)

这里仅简单说明下配置的过程,相关概念在Kubernetes 日志查询分析实践有介绍,不清楚 SLS 采集相关概念的读者可以先参考下该文章。


创建单行文本采集配置

008i3skNgy1gw6o9t8cg3j30u0123q7c.jpeg


其中我们以 /share/logs/app.log 作为采集目标。


这里补充解释下前面没有说明的 share 挂载。在上述的过程中,每个 pod 创建的数据目录的名字都是动态的,但它们都是以相同的 sidecar.yaml 创建的,所以从逻辑上来说,它们从属于同一个应用。一般来说,针对每个应用,我们一般都希望使用一个 SLS 采集配置来实现对它的采集,无论它实际上有多少个 pod。因此,我们增加了 share 挂载以及 /share/logs 软链接,以屏蔽掉每个 pod 的动态目录。


创建机器组并应用采集配置


注意:需要创建自定义标识符机器组(和配置中的 ALIYUN_LOGTAIL_USER_DEFINED_ID 保持一致),以在逻辑上区分不同应用所产生的 sidecar logtail 实例,进而向它们下发不同的采集配置,避免冲突。


控制台查看日志

在 SLS 控制台完成配置并稍等采集配置下发至 logtail 侧后,即可在控制台查询到相应的日志(需开启索引)。


通过我们附加的 pod 属性字段(pod_name 等),可以很容易地区分出每条数据的来源。


更多

借助前述的设计,我们保障了业务数据在极端情况下不会丢失,但这个设计还需要一些额外工作来配合,包括:

  • 宿主机数据目录的定期归档:因为 pod 和数据的生命周期进行了解耦,所以在 pod 正常销毁时,相应的数据目录会残留在宿主机上,所以我们需要增加相应的巡检脚本,来定期归档这些数据。比如周期性地扫描宿主机的数据目录,当发现某 pod 目录下的文件超过一段时间不再更新,则判定其已经过期,对其进行归档(比如转存到 OSS)。
  • 监控 Pod 异常崩溃:一般来说可以借助 K8s 事件来设置告警,推荐使用 SLS 提供的 Kubernetes 事件中心
  • Logtail 自身状态的监控:主要是为了及时发现应用数据量突增、网络不稳定等情况,参考全方位 Logtail 状态监控
相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
10月前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
421 2
|
5月前
|
存储 负载均衡 测试技术
ACK Gateway with Inference Extension:优化多机分布式大模型推理服务实践
本文介绍了如何利用阿里云容器服务ACK推出的ACK Gateway with Inference Extension组件,在Kubernetes环境中为多机分布式部署的LLM推理服务提供智能路由和负载均衡能力。文章以部署和优化QwQ-32B模型为例,详细展示了从环境准备到性能测试的完整实践过程。
|
6月前
|
存储 人工智能 Kubernetes
ACK Gateway with AI Extension:面向Kubernetes大模型推理的智能路由实践
本文介绍了如何利用阿里云容器服务ACK推出的ACK Gateway with AI Extension组件,在Kubernetes环境中为大语言模型(LLM)推理服务提供智能路由和负载均衡能力。文章以部署和优化QwQ-32B模型为例,详细展示了从环境准备到性能测试的完整实践过程。
|
6月前
|
存储 人工智能 物联网
ACK Gateway with AI Extension:大模型推理的模型灰度实践
本文介绍了如何使用 ACK Gateway with AI Extension 组件在云原生环境中实现大语言模型(LLM)推理服务的灰度发布和流量分发。该组件专为 LLM 推理场景设计,支持四层/七层流量路由,并提供基于模型服务器负载感知的智能负载均衡能力。通过自定义资源(CRD),如 InferencePool 和 InferenceModel,可以灵活配置推理服务的流量策略,包括模型灰度发布和流量镜像。
|
10月前
|
Kubernetes 持续交付 开发者
探索并实践Kubernetes集群管理与自动化部署
探索并实践Kubernetes集群管理与自动化部署
374 93
|
7月前
|
Kubernetes 监控 Serverless
基于阿里云Serverless Kubernetes(ASK)的无服务器架构设计与实践
无服务器架构(Serverless Architecture)在云原生技术中备受关注,开发者只需专注于业务逻辑,无需管理服务器。阿里云Serverless Kubernetes(ASK)是基于Kubernetes的托管服务,提供极致弹性和按需付费能力。本文深入探讨如何使用ASK设计和实现无服务器架构,涵盖事件驱动、自动扩展、无状态设计、监控与日志及成本优化等方面,并通过图片处理服务案例展示具体实践,帮助构建高效可靠的无服务器应用。
|
7月前
|
监控 Kubernetes Cloud Native
基于阿里云容器服务Kubernetes版(ACK)的微服务架构设计与实践
本文介绍了如何基于阿里云容器服务Kubernetes版(ACK)设计和实现微服务架构。首先概述了微服务架构的优势与挑战,如模块化、可扩展性及技术多样性。接着详细描述了ACK的核心功能,包括集群管理、应用管理、网络与安全、监控与日志等。在设计基于ACK的微服务架构时,需考虑服务拆分、通信、发现与负载均衡、配置管理、监控与日志以及CI/CD等方面。通过一个电商应用案例,展示了用户服务、商品服务、订单服务和支付服务的具体部署步骤。最后总结了ACK为微服务架构提供的强大支持,帮助应对各种挑战,构建高效可靠的云原生应用。
|
8月前
|
存储 Kubernetes 安全
k8s存储类型:emptyDir、hostPath、nfs、pvc及存储类storageclass的静态/动态创建pv
Kubernetes提供了多种存储类型,满足不同的应用需求。`emptyDir`和 `hostPath`适用于临时和宿主机存储需求,`nfs`适用于共享存储,`PersistentVolumeClaim`和 `StorageClass`实现了持久存储的灵活管理。通过理解和配置这些存储类型,可以有效提升Kubernetes集群的存储管理能力。
341 13
|
7月前
|
监控 Cloud Native Java
基于阿里云容器服务(ACK)的微服务架构设计与实践
本文介绍如何利用阿里云容器服务Kubernetes版(ACK)构建高可用、可扩展的微服务架构。通过电商平台案例,展示基于Java(Spring Boot)、Docker、Nacos等技术的开发、容器化、部署流程,涵盖服务注册、API网关、监控日志及性能优化实践,帮助企业实现云原生转型。
|
9月前
|
人工智能 运维 监控
阿里云ACK容器服务生产级可观测体系建设实践
本文整理自2024云栖大会冯诗淳(花名:行疾)的演讲,介绍了阿里云容器服务团队在生产级可观测体系建设方面的实践。冯诗淳详细阐述了容器化架构带来的挑战及解决方案,强调了可观测性对于构建稳健运维体系的重要性。文中提到,阿里云作为亚洲唯一蝉联全球领导者的容器管理平台,其可观测能力在多项关键评测中表现优异,支持AI、容器网络、存储等多个场景的高级容器可观测能力。此外,还介绍了阿里云容器服务在多云管理、成本优化等方面的最新进展,以及即将推出的ACK AI助手2.0,旨在通过智能引擎和专家诊断经验,简化异常数据查找,缩短故障响应时间。
阿里云ACK容器服务生产级可观测体系建设实践

推荐镜像

更多