跳到主要内容

K8S + Elasticsearch + Fluentd + Kibana(EFK)

2024年12月11日
柏拉文
越努力,越幸运

一、认识


在生产环境中,需要集中收集日志。可以借助 EFK(Elasticsearch + Fluentd + Kibana) 来收集、获取、查询日志。

  1. Fluentd 通过 Kubernetes 的容器标准输出(stdout/stderr)收集日志。FluentdKubernetes 中运行为 DaemonSet,自动收集所有节点上容器的标准输出日志。日志会自动打上 Pod 名称、Namespace、容器名称 等标签。

  2. 将日志发送到 Elasticsearch 进行存储。

  3. 使用 Kibana 可视化和查询日志。

构建 Node.js 服务镜像

二、构建镜像


2.1 目录结构

backend-server 

│── node_modules
│── .dockerignore
│── Dockerfile
│── index.js
└── package.json

2.2 index.js

const Koa = require("koa");
const pino = require("pino");
const KoaRouter = require("koa-router");

const port = 3000;
const app = new Koa();
const router = new KoaRouter();

const logFilePath =
process.env.APP_ENV === "development" || !process.env.APP_ENV
? "logs/backend-server.log"
: "/logs/backend-server.log";

const logFile = pino.destination(logFilePath);
const logger = pino(logFile);

const PORT = process.env.APP_PORT || 3000;
const DB_PASSWORD = process.env.DB_PASSWORD;

console.log("------PORT------", PORT);
console.log("-------DB_PASSWORD--------", DB_PASSWORD);

router.get("/", async (ctx) => {
logger.info("Hello again distributed logs");
ctx.body = {
code: 200,
message: "Hello Koa Server 001",
};
});

app.use(router.routes()).use(router.allowedMethods());

app.listen(port, () => {
console.log(`Koa HTTP Server is running on port ${port}`);
});

访问环境变量: 通过 process.env 可以访问 Dockerfile 以及 Deployment env 环境变量。在 Kubernetes 部署中,环境变量的优先级如下:

  • ConfigMapSecret 注入的环境变量(最高优先级)

  • 容器镜像(Dockerfile)中的 ENV 默认值

  • 应用程序代码中的默认值(如 || 3000

日志写入路径: 如果本地开发,可以将 logs 通过相对路径写入到 logs/xxx.log = ./logs/xxx.log。如果在 K8S 环境中,需要使用绝对路径 /logs/xx.log, 来确保它匹配 volumeMounts 中的 mountPath

2.3 Dockerfile

FROM registry.cn-hangzhou.aliyuncs.com/bolawen/node:22.7.0-linux-arm64
WORKDIR /server
COPY package*.json /server
RUN npm install --registry=https://registry.npmmirror.com
COPY . /server

ENV APP_ENV=test
ENV APP_PORT=3000
ENV DB_PASSWORD=defaultpassword

EXPOSE 3000
CMD ["node","index.js"]

ENV: ENV 指令设置镜像的默认环境变量值。在 Kubernetes 中运行时,Deployment env 的环境变量会覆盖 Dockerfile 中的默认值。

2.4 .dockerignore

dist
node_modules

2.5 构建并推送镜像

# 构建镜像 
docker build -t backend-server:1.0.0 .

# 推送镜像
docker tag backend-server:1.0.0 registry.cn-hangzhou.aliyuncs.com/bolawen/backend-server:1.0.0
docker push registry.cn-hangzhou.aliyuncs.com/bolawen/backend-server:1.0.0

三、部署服务


3.1 DaemonSet

FluentdKubernetes 中运行为 DaemonSet,自动收集所有节点上容器的标准输出日志。创建 backend-server-daemon-set.yaml 配置文件,如下:

apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
spec:
template:
spec:
containers:
- name: fluentd
image: fluent/fluentd:latest
volumeMounts:
- name: varlog
mountPath: /var/log
readOnly: true
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
  • Fluentd 读取 /var/log/var/lib/docker/containers 目录下的日志文件。

  • 这些日志是 Kubernetes 自动保存的容器标准输出(stdout/stderr)。