K8s 日志收集-Day 07
主要演示了在k8s中两种日志收集的方式
1. 日志收集方式简介
官方文档:https://kubernetes.io/zh/docs/concepts/cluster-administration/logging/
(1)node节点收集
基于daemonset部署日志收集进程,实现json-file类型(标准输出/dev/stdout、错误输出/dev/stderr)日志收集;
该方式的优点:日志收集架构简单,易部署、易维护。
该方式的缺点:node节点产生的日志、路径、类型、日志内容都不同,很难做到把每个容器的日志都完整的处理好。
(2)边车模式
使用sidcar容器(一个pod多容器)收集当前pod内一个或者多个业务容器的日志(通常基于emptyDir实现业务容器与sidcar之间的日志共享)。
该方式的优点:对当前收集日志的pod能做更详细的处理,按照预定义规则处理好的日志,再输出到kafka或者filebeat。
该方式的缺点:性能可能没那么好,因为一个pod就需要一个sidecar,如果有100个pod,那就需要100个sidecar,那么这个日志收集的agent就必须选用一个轻量级的工具,不然会占用很多额外资源。
(3)在业务容器中内置日志收集服务进程。
就是除了业务容器,再另外起一个日志收集的进程。
一般公有云的话,第一种方式较多,能够更好的节约系统资源。
2. 日志收集示例一:daemonset收集日志(ELK)
2.1 介绍
基于daemonset运行日志收集服务,主要收集以下类型日志:
(1)node节点收集,基于daemonset部署日志收集进程,实现json-file类型(标准输出/dev/stdout、错误输出/dev/stderr)日志收集,即收集应用程序产生的标准输出和错误输出的日志。
(2)宿主机系统日志等以日志文件形式保存的日志。
2.2 不同容器运行时的日志路径
2.2.1 containerd
(1)日志存储路径
真实路径:/var/log/pods/$CONTAINER_NAMEs #真实路径
软连接:同时kubelet也会在/var/log/containers目录下创建软链接指向/var/log/pods/$CONTAINER_NAMEs
(2)日志配置参数
配置文件:
/etc/systemd/system/kubelet.service
配置参数:
- --container-log-max-files=5 \
--container-log-max-size="100Mi" \
--logging-format="json"
2.2.2 docker
(1)日志存储路径
真实路径:/var/lib/docker/containers/$CONTAINERID
软连接:kubelet会在/var/log/pods和/var/log/containers创建软连接指向/var/lib/docker/containers/$CONTAINERID
(2)日志配置参数
配置文件:
/etc/docker/daemon.json
参数:
"log-driver": "json-file",
"log-opts": {
"max-file": "5",
"max-size": "100m"
}
2.3 daemonset日志收集架构
2.3.1 注意事项
首先要规划好pod日志输出方式,是标准输出,还是自定义路径。
因为如果是标准输出的话,路径相对固定,因为都是/dev/stdout、/dev/stderr。
如果是自定义路径的话,就得提前进行规划,以为不同的进程,默认情况下的日志输出路径是不同的。
2.4 环境准备
2.4.1 基础环境
(1)elasticsearch cluster
本次演示准备3台节点组成es集群。
zookeeper && kafka
3个节点,部署zk和kafka
(2)logsatsh
准备2个节点。
kibana
2.5 二进制部署ES集群-7.12.1
安装包就是官网直接下载带jdk的就行,过程略
2.5.1 配置es01
[root@es01 ~]# ls
anaconda-ks.cfg elasticsearch-7.12.1-linux-x86_64.tar.gz update.sh
[root@es01 ~]# tar xf elasticsearch-7.12.1-linux-x86_64.tar.gz -C /opt
[root@es01 ~]# cd /opt/elasticsearch-7.12.1/
[root@es01 elasticsearch-7.12.1]# ls
bin config jdk lib LICENSE.txt logs modules NOTICE.txt plugins README.asciidoc
# 修改配置文件
[root@es01 elasticsearch-7.12.1]# cd config
[root@es01 config]# vim elasticsearch.yml
[root@es01 config]# grep -v "^#" elasticsearch.yml
cluster.name: myserver-cluster # 同一个集群中,不同节点的cluster.name相同
node.name: es01 # 同一个集群中,node.name不能相同
path.data: /data/es-data # 数据目录,可自定义
path.logs: /data/es-log # 日志目录,可自定义
network.host: 10.31.200.130 # 本机IP
http.port: 9200 # es端口
discovery.seed_hosts: ["10.31.200.130", "10.31.200.131","10.31.200.132"] # 服务发现
cluster.initial_master_nodes: ["10.31.200.130", "10.31.200.131","10.31.200.132"] # 可以参与选主的节点
action.destructive_requires_name: true # 通过api删除索引时,是否需要指定详细的索引名称。true为必须指定。
# 创建数据目录并授权
[root@es01 config]# mkdir -p /data/es-data /data/es-log
[root@es01 config]# useradd -s /sbin/nologin -M elasticsearch
[root@es01 config]# chown elasticsearch. -R /data/es-* /opt/elasticsearch-7.12.1
[root@es01 config]# ll /data/
总用量 4
drwxr-xr-x 2 elasticsearch elasticsearch 6 11月 23 16:31 es-data
drwxr-xr-x 2 elasticsearch elasticsearch 4096 11月 23 16:32 es-log
# 编辑启动脚本
[root@es01 es-log]# cat /etc/systemd/system/elasticsearch.service
[Unit]
Description=Elasticsearch
Documentation=https://www.elastic.co
Wants=network-online.target
After=network-online.target
[Service]
Environment=ES_HOME=/opt/elasticsearch-7.12.1/
Environment=ES_USER=elasticsearch
Environment=ES_GROUP=elasticsearch
ExecStart=/opt/elasticsearch-7.12.1/bin/elasticsearch
Restart=always
User=elasticsearch
LimitMEMLOCK=infinity
LimitNOFILE=65536
StandardOutput=journal
StandardError=journal
SyslogIdentifier=elasticsearch
[Install]
WantedBy=multi-user.target
# 调整虚拟内存区域数量,es默认需要262144
[root@es01 es-log]# cat /etc/sysctl.conf
vm.max_map_count = 262144
[root@es01 es-log]# sysctl -p
vm.max_map_count = 262144
[root@es01 es-log]# sysctl vm.max_map_count
vm.max_map_count = 262144
# 启动服务
[root@es01 es-log]# systemctl daemon-reload
[root@es01 es-log]# systemctl restart elasticsearch.service
[root@es01 es-log]# systemctl enable elasticsearch.service
[root@es01 es-log]# netstat -lntup|grep 9
tcp6 0 0 10.31.200.130:9200 :::* LISTEN 15501/java
tcp6 0 0 10.31.200.130:9300 :::* LISTEN 15501/java
2.5.2 配置es02
安装步骤一样,这里只展示配置文件
[root@es02 ~]# grep -v "^#" /opt/elasticsearch-7.12.1/config/elasticsearch.yml
cluster.name: myserver-cluster
node.name: es02
path.data: /data/es-data
path.logs: /data/es-log
network.host: 10.31.200.131
http.port: 9200
discovery.seed_hosts: ["10.31.200.130", "10.31.200.131","10.31.200.132"]
cluster.initial_master_nodes: ["10.31.200.130", "10.31.200.131","10.31.200.132"]
action.destructive_requires_name: true
2.5.3 配置es03
安装步骤一样,这里只展示配置文件
[root@es03 ~]# grep -v "^#" /opt/elasticsearch-7.12.1/config/elasticsearch.yml
cluster.name: myserver-cluster
node.name: es03
path.data: /data/es-data
path.logs: /data/es-log
network.host: 10.31.200.132
http.port: 9200
discovery.seed_hosts: ["10.31.200.130", "10.31.200.131","10.31.200.132"]
cluster.initial_master_nodes: ["10.31.200.130", "10.31.200.131","10.31.200.132"]
action.destructive_requires_name: true
2.5.4 验证集群状态
2.5.4.1 安装插件
我这样操作要翻墙,可以提前下载下来安装
2.5.4.2 连接集群
2.6 部署zk和kafka集群
2.6.1 二进制安装zk3.7.2
2.6.1.1 下载软件包
官网地址:https://zookeeper.apache.org/index.html
[root@es03 opt]# wget https://dlcdn.apache.org/zookeeper/zookeeper-3.7.2/apache-zookeeper-3.7.2-bin.tar.gz
[root@zk01 ~]# ll -h
-rw-r--r-- 1 root root 14M Nov 24 22:46 apache-zookeeper-3.7.2-bin.tar.gz
2.6.1.2 查看3.7.2所需jdk版本
2.6.1.3 安装jdk8
所有节点操作相同
[root@zk01 ~]# yum -y install java
[root@zk01 ~]# java -version
openjdk version "1.8.0_392"
OpenJDK Runtime Environment (build 1.8.0_392-b08)
OpenJDK 64-Bit Server VM (build 25.392-b08, mixed mode)
2.6.1.4 解压并配置
所有节点操作相同
# 解压
[root@zk01 ~]# tar xf apache-zookeeper-3.7.2-bin.tar.gz -C /opt/
[root@zk01 ~]# cd /opt/
[root@zk01 opt]# ls
apache-zookeeper-3.7.2-bin
# 调整配置文件名称
[root@zk01 opt]# cd apache-zookeeper-3.7.2-bin/conf/
[root@zk01 conf]# ls
configuration.xsl log4j.properties zoo_sample.cfg
[root@zk01 conf]# cp zoo_sample.cfg zoo.cfg # 这就是zk的配置文件
# 修改配置
[root@zk01 conf]# grep -v "^#" zoo.cfg
# 默认配置
tickTime=2000
# 默认配置,如果10个2000(tickTime)毫秒后,集群还没有初始化成功,就认为失败
initLimit=10
# 集群创建好后,每隔5个2000毫秒进行一次探测,检查集群内的节点是否正常。如果检查失败就下线节点,然后开始重新选举
syncLimit=5
# zk数据目录,可自定义
dataDir=/data/zk-data
# 默认客户端端口
clientPort=2181
# 新增集群配置
server.1=10.31.200.133:2888:3888 # 1为集群id,需要手动生成
server.2=10.31.200.134:2888:3888 # 2为集群id,需要手动生成
server.3=10.31.200.135:2888:3888 # 3为集群id,需要手动生成
# 创建数据目录
[root@zk01 conf]# mkdir -p /data/zk-data
# 生成集群ID
[root@zk01 conf]# echo 1 > /data/zk-data/myid
2.6.1.5 3个节点同时启动zk
这里3个节点一定要在initLimit内启动并初始化完毕
# 查看帮助
[root@zk01 conf]# ../bin/zkServer.sh
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /opt/apache-zookeeper-3.7.2-bin/bin/../conf/zoo.cfg
Usage: ../bin/zkServer.sh [--config <conf-dir>] {start|start-foreground|stop|version|restart|status|print-cmd}
# 启动zk
[root@zk01 conf]# ../bin/zkServer.sh start
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /opt/apache-zookeeper-3.7.2-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
2.6.1.6 查看集群状态
[root@zk01 conf]# ../bin/zkServer.sh status
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /opt/apache-zookeeper-3.7.2-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower # 只要是follower 或者leader就说明集群部署完毕
2.6.2 二进制安装kafka2.6.2
2.6.2.1 下载并解压
所有节点操作相同
[root@zk01 ~]# wget https://archive.apache.org/dist/kafka/2.6.2/kafka_2.12-2.6.2.tgz
[root@zk01 ~]# tar xf kafka_2.12-2.6.2.tgz -C /opt/
[root@zk01 ~]# cd /opt/kafka_2.12-2.6.2/
[root@zk01 kafka_2.12-2.6.2]# ll
total 40
drwxr-xr-x 3 root root 4096 Apr 8 2021 bin
drwxr-xr-x 2 root root 4096 Apr 8 2021 config
drwxr-xr-x 2 root root 8192 Nov 26 13:20 libs
-rw-r--r-- 1 root root 14556 Apr 8 2021 LICENSE
drwxr-xr-x 2 root root 236 Apr 8 2021 licenses
-rw-r--r-- 1 root root 952 Apr 8 2021 NOTICE
drwxr-xr-x 2 root root 44 Apr 8 2021 site-docs
2.6.2.2 调整kafka配置文件
所有节点操作相同
[root@zk01 config]# vim server.properties
……省略部分默认配置,只展示修改的配置
# 每个节点唯一,不能相同
broker.id=133
# 监听地址,ip写宿主机的
listeners=PLAINTEXT://10.31.200.133:9092
# 日志目录,程序启动时会自动创建
log.dirs=/data/kafka-logs
# zk连接地址
zookeeper.connect=10.31.200.133:2181,10.31.200.134:2181,10.31.200.135:2181
# 连接超时时间
zookeeper.connection.timeout.ms=30000
2.6.2.3 启动kafka
所有节点操作相同
[root@zk01 config]# /opt/kafka_2.12-2.6.2/bin/kafka-server-start.sh -daemon /opt/kafka_2.12-2.6.2/config/server.properties
[root@zk01 logs]# netstat -lntup|grep 9092
tcp6 0 0 10.31.200.133:9092 :::* LISTEN 3637/java
2.6.3.4 连接kafka
客户端下载地址:https://www.kafkatool.com/
2.7 k8s部署logstash收集pod日志(消息生产者)
2.7.1 相关配置
2.7.1.1 Dockerfile
[root@master1 1.logstash-image-Dockerfile]# cat Dockerfile
# 使用官方的镜像
FROM logstash:7.12.1
# 设置用户为root
USER root
# 定义工作目录
WORKDIR /usr/share/logstash
#RUN rm -rf config/logstash-sample.conf
# 替换容器中原有的配置文件
ADD logstash.yml /usr/share/logstash/config/logstash.yml
ADD logstash.conf /usr/share/logstash/pipeline/logstash.conf
2.7.1.2 logstash.yml
[root@master1 1.logstash-image-Dockerfile]# cat logstash.yml
http.host: "0.0.0.0" # 调整监听地址
#xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch:9200" ]
2.7.1.3 logstash.conf
[root@master1 1.logstash-image-Dockerfile]# cat logstash.conf
input { # 日志收集配置
file {
#path => "/var/lib/docker/containers/*/*-json.log" #docker
# 容器日志文件路径,这个是宿主机上的,等下daemonset的yaml中会把这个路径挂在到pod中
path => "/var/log/pods/*/*/*.log"
start_position => "beginning" # beginning表示从日志首行开始收集
type => "jsonfile-daemonset-applog" # 定义该日志类型为app日志
}
file {
path => "/var/log/*.log"
start_position => "beginning" # beginning表示从日志首行开始收集
type => "jsonfile-daemonset-syslog" # 这里是定义为系统日志
}
}
output { # 日志输出配置
if [type] == "jsonfile-daemonset-applog" {
kafka { # 日志输出到kafka
bootstrap_servers => "${KAFKA_SERVER}" # ${KAFKA_SERVER}为kafka地址,具体的地址会在ds的yaml中体现
topic_id => "${TOPIC_ID}" # 这个变量也会在ds的yaml中体现
batch_size => 16384 #logstash每次向ES传输的数据量大小(默认配置),单位为字节
codec => "${CODEC}" # 字符集,这里的变量也会在ds的yaml中体现
} }
if [type] == "jsonfile-daemonset-syslog" {
kafka {
bootstrap_servers => "${KAFKA_SERVER}"
topic_id => "${TOPIC_ID}"
batch_size => 16384
codec => "${CODEC}" #系统日志不是json格式
}}
}
2.7.1.4 2.DaemonSet-logstash.yaml
[root@master1 1.logstash-image-Dockerfile]# cd ../
[root@master1 1.daemonset-logstash]# cat 2.DaemonSet-logstash.yaml
ind: DaemonSet
metadata:
name: logstash-elasticsearch
namespace: kube-system
labels:
k8s-app: logstash-logging
spec:
selector:
matchLabels:
name: logstash-elasticsearch
template:
metadata:
labels:
name: logstash-elasticsearch
spec:
tolerations: # 污点容忍配置,这样master上也可以收集日志
# this toleration is to have the daemonset runnable on master nodes
# remove it if your masters can't run pods
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
containers:
- name: logstash-elasticsearch
image: registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/logstash:v7.12.1-json-file-log-v1
env:
- name: "KAFKA_SERVER" # 这就是之前说到的变量
value: "10.31.200.111:9092,10.31.200.112:9092,10.31.200.113:9092"
- name: "TOPIC_ID" # 这就是之前说到的变量
value: "jsonfile-log-topic"
- name: "CODEC" # 这就是之前说到的变量
value: "json"
# resources:
# limits:
# cpu: 1000m
# memory: 1024Mi
# requests:
# cpu: 500m
# memory: 1024Mi
volumeMounts:
- name: varlog #定义宿主机系统日志挂载路径
mountPath: /var/log #宿主机系统日志挂载点
- name: varlibdockercontainers #定义容器日志挂载路径,和logstash配置文件中的收集路径保持一直
#mountPath: /var/lib/docker/containers #docker挂载路径
mountPath: /var/log/pods #containerd挂载路径,此路径与logstash的日志收集路径必须一致
readOnly: false
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log #宿主机系统日志
- name: varlibdockercontainers
hostPath:
#path: /var/lib/docker/containers #docker的宿主机日志路径
path: /var/log/pods #containerd的宿主机日志路径
2.7.2 构建logstash镜像
[root@master1 1.logstash-image-Dockerfile]# cat build-commond.sh
#!/bin/bash
nerdctl build -t registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/logstash:v7.12.1-json-file-log-v1 .
nerdctl push registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/logstash:v7.12.1-json-file-log-v1
[root@master1 1.logstash-image-Dockerfile]# sh build-commond.sh
[root@master1 1.logstash-image-Dockerfile]# nerdctl images|grep log
registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/logstash v7.12.1-json-file-log-v1 79eb662f2a7b 2 hours ago linux/amd64 990.5 MiB 470.6 MiB
2.7.3 部署logstash
logstash启动后,会收集挂载点的日志,输出到kafka
[root@master1 1.daemonset-logstash]# kubectl apply -f 2.DaemonSet-logstash.yaml
daemonset.apps/logstash-elasticsearch created
[root@master1 1.daemonset-logstash]# kubectl get po -A |grep log
kube-system logstash-elasticsearch-2p4mc 1/1 Running 0 8s
kube-system logstash-elasticsearch-45j7q 1/1 Running 0 8s
kube-system logstash-elasticsearch-n22zf 1/1 Running 0 8s
2.7.4 查看topic生成结果
2.8 二进制部署logstash消费者
2.8.1 下载并解压
# 这个包可以直接去官网下载二进制的,里面还包含了java 11
[root@logstash ~]# ll -h logstash-7.12.0-linux-x86_64.tar.gz
-rw-r--r-- 1 root root 352M Dec 12 2023 logstash-7.12.0-linux-x86_64.tar.gz
[root@logstash ~]# tar xf logstash-7.12.0-linux-x86_64.tar.gz -C /opt/
[root@logstash ~]# cd /opt/logstash-7.12.0/
[root@logstash logstash-7.12.0]# ls
bin config CONTRIBUTORS data Gemfile Gemfile.lock jdk lib LICENSE.txt logstash-core logstash-core-plugin-api modules NOTICE.TXT tools vendor x-pack
2.8.2 修改配置文件
[root@logstash logstash-7.12.0]# cat config/logstash-sample.conf
input {
kafka {
bootstrap_servers => "10.31.200.133:9092,10.31.200.134:9092,10.31.200.135:9092"
topics => ["jsonfile-log-topic"]
codec => "json"
}
}
output {
if [type] == "jsonfile-daemonset-applog" {
elasticsearch {
hosts => ["10.31.200.130:9200","10.31.200.131:9200","10.31.200.132:9200"]
index => "jsonfile-daemonset-applog-%{+YYYY.MM.dd}"
}}
if [type] == "jsonfile-daemonset-syslog" {
elasticsearch {
hosts => ["10.31.200.130:9200","10.31.200.131:9200","10.31.200.132:9200"]
index => "jsonfile-daemonset-syslog-%{+YYYY.MM.dd}"
}}
}
[root@logstash-consumer logstash-7.12.0]# egrep -v "^#|^$" config/logstash.yml
pipeline.ordered: auto
http.host: 10.31.200.140
http.port: 9600-9700
log.level: info
path.logs: /var/log/logstash
2.8.3 启动服务
[root@logstash-consumer logstash-7.12.0]# /opt/logstash-7.12.0/bin/logstash -f /opt/logstash-7.12.0/config/logstash-sample.conf
[root@logstash-consumer ~]# netstat -ltnup|grep 9600
tcp6 0 0 10.31.200.140:9600 :::* LISTEN 2287/java
2.8.4 查看es是否有数据
只要消费者能正常消费数据到es,这个时候es应该是有数据的
2.9 二进制部署Kibana
2.9.1 下载软件包
[root@logstash-consumer ~]# wget https://artifacts.elastic.co/downloads/kibana/kibana-7.12.0-linux-x86_64.tar.gz
[root@logstash-consumer ~]# ll -h kibana-7.12.0-linux-x86_64.tar.gz
-rw-r--r-- 1 root root 269M Mar 23 2021 kibana-7.12.0-linux-x86_64.tar.gz
2.9.2 配置并启动
2.9.2.1 调整配置
root@logstash-consumer ~]# tar xf kibana-7.12.0-linux-x86_64.tar.gz -C /opt/
[root@logstash-consumer ~]# cd /opt/kibana-7.12.0-linux-x86_64/
[root@logstash-consumer kibana-7.12.0-linux-x86_64]# ls
bin config data LICENSE.txt node node_modules NOTICE.txt package.json plugins README.txt src x-pack
[root@logstash-consumer kibana-7.12.0-linux-x86_64]# egrep -v "^$|^#" config/kibana.yml
server.port: 5601
server.host: "10.31.200.140"
elasticsearch.hosts: ["http://10.31.200.130:9200"]
i18n.locale: "zh-CN"
2.9.2.2 启动kibana
[root@logstash-consumer bin]# nohup ./kibana --allow-root &
root@logstash-consumer bin]# netstat -lntup |grep 5601
tcp 0 0 10.31.200.140:5601 0.0.0.0:* LISTEN 12589/./../node/bin
2.9.3 添加所索引并查看日志
2.9.3.1 添加索引
2.9.3.2 查看日志
2.10 该方式的缺点
使用该方式去收集日志,运行的pod一多,需要通过调整logstash配置文件,去匹配每一个服务,来按服务名生成索引,然后写入es存储,非常繁琐。
2.11 清理环境
[root@master1 ~]# cd /opt/ELK\ cases-N76/1.daemonset-logstash
[root@master1 1.daemonset-logstash]# kubectl delete -f 2.DaemonSet-logstash.yaml
daemonset.apps "logstash-elasticsearch" deleted
3. 日志收集示例二:sidecar模式实现日志收集(ELK)
所谓sidecar模式,就是一个pod中,运行了2个容器,一个业务容器,一个负责收集日志的容器。
但是同一个pod中,不同的容器之间文件系统是隔离的,怎么来收集这个日志呢?这就要用到emptyDir(临时数据目录)。
emptyDir主要是负责临时存储数据的,一旦pod被删除,持久化的数据也会跟着被删除,非常适合存储日志和一些临时数据。
我们在创建pod的时候,可以让两个容器都挂载到同一个emptyDir,这样业务容器负责把日志输出进去,日志收集容器负责收集这些日志数据并写入kafka。
但是这里有个问题,集成到pod中的sidecar容器,必须非常轻量级(如filebeat),不能占用过多的cpu和内存资源,尽量让sidecar只收集日志,写入kafka,处理日志的工作就交给负责消费消息的logstash进行。
3.1 sidecar模式架构
3.2 构建sidecar镜像
3.2.1 相关配置文件
[root@master1 1.daemonset-logstash]# cd ../2.sidecar-logstash/
[root@master1 2.sidecar-logstash]# ls
1.logstash-image-Dockerfile 2.tomcat-app1.yaml 3.tomcat-service.yaml 4.logsatsh-sidecar-kafka-to-es.conf
[root@master1 2.sidecar-logstash]# cd 1.logstash-image-Dockerfile/
[root@master1 1.logstash-image-Dockerfile]# ls
build-commond.sh Dockerfile logstash.conf logstash.yml
# dockerfile
[root@master1 1.logstash-image-Dockerfile]# cat Dockerfile
FROM logstash:7.12.1
USER root
WORKDIR /usr/share/logstash
#RUN rm -rf config/logstash-sample.conf
ADD logstash.yml /usr/share/logstash/config/logstash.yml
ADD logstash.conf /usr/share/logstash/config/logstash.conf
# 日志收集配置文件
[root@master1 1.logstash-image-Dockerfile]# cat logstash.conf
input {
file {
path => "/var/log/applog/catalina.out" # 指定应用程序日志文件路径
start_position => "beginning"
type => "app1-sidecar-catalina-log" # 定义日志类型
}
file {
path => "/var/log/applog/localhost_access_log.*.txt" # 指定应用程序日志文件路径
start_position => "beginning"
type => "app1-sidecar-access-log" # 定义日志类型
}
}
output { # 判断不同的日志type,写入不同的topic中
if [type] == "app1-sidecar-catalina-log" {
kafka {
bootstrap_servers => "${KAFKA_SERVER}" # 这些变量也是在pod的yaml中定义的
topic_id => "${TOPIC_ID}"
batch_size => 16384 #logstash每次向ES传输的数据量大小,单位为字节
codec => "${CODEC}"
} }
if [type] == "app1-sidecar-access-log" {
kafka {
bootstrap_servers => "${KAFKA_SERVER}"
topic_id => "${TOPIC_ID}"
batch_size => 16384
codec => "${CODEC}"
}}
}
# 2.tomcat-app1.yaml
[root@master1 1.logstash-image-Dockerfile]# cat ../2.tomcat-app1.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: magedu-tomcat-app1-deployment-label
name: magedu-tomcat-app1-deployment #当前版本的deployment 名称
spec:
replicas: 2
selector:
matchLabels:
app: magedu-tomcat-app1-selector
template:
metadata:
labels:
app: magedu-tomcat-app1-selector
spec:
containers:
- name: magedu-tomcat-app1-container # 业务容器。注意:exec的时候,一般是进入第一个容器,所以多容器环境,建议把主容器放在第一个,不然进去得-c指定容器。
image: registry.cn-hangzhou.aliyuncs.com/zhangshijie/tomcat-app1:v1
imagePullPolicy: IfNotPresent
#imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: http
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
resources:
limits:
cpu: 1
memory: "512Mi"
requests:
cpu: 500m
memory: "512Mi"
volumeMounts:
- name: applogs
mountPath: /apps/tomcat/logs
startupProbe:
httpGet:
path: /myapp/index.html
port: 8080
initialDelaySeconds: 5 #首次检测延迟5s
failureThreshold: 3 #从成功转为失败的次数
periodSeconds: 3 #探测间隔周期
readinessProbe:
httpGet:
#path: /monitor/monitor.html
path: /myapp/index.html
port: 8080
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
livenessProbe:
httpGet:
#path: /monitor/monitor.html
path: /myapp/index.html
port: 8080
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
- name: sidecar-container # sidecar容器
image: harbor.linuxarchitect.io/baseimages/logstash:v7.12.1-sidecar
imagePullPolicy: IfNotPresent
#imagePullPolicy: Always
env:
- name: "KAFKA_SERVER" # sidecar收集日志引用的变量
value: "10.31.200.133:9092,10.31.200.134:9092,10.31.200.135:9092"
- name: "TOPIC_ID"
value: "tomcat-app1-topic"
- name: "CODEC"
value: "json"
volumeMounts:
- name: applogs
mountPath: /var/log/applog
volumes:
- name: applogs
emptyDir: {} # 定义通过emptyDir实现业务容器与sidecar容器的日志共享,以让sidecar收集业务容器中的日志
[root@master1 2.sidecar-logstash]# cat 3.tomcat-service.yaml
---
kind: Service
apiVersion: v1
metadata:
labels:
app: magedu-tomcat-app1-service-label
name: magedu-tomcat-app1-service
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
selector:
app: magedu-tomcat-app1-selector
# logstash.yml
[root@master1 1.logstash-image-Dockerfile]# cat logstash.yml
http.host: "0.0.0.0"
#xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch:9200" ]
# build-commond.sh
[root@master1 1.logstash-image-Dockerfile]# cat build-commond.sh
#!/bin/bash
nerdctl build -t registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/logstash:v7.12.1-sidecar .
nerdctl push registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/logstash:v7.12.1-sidecar
3.2.2 构建日志收集镜像
[root@master1 1.logstash-image-Dockerfile]# sh build-commond.sh
3.2.3 调整镜像
root@master1 2.sidecar-logstash]# grep ".*-sidecar" 2.tomcat-app1.yaml
image: registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/logstash:v7.12.1-sidecar
3.3 创建sidecar pod
[root@master1 2.sidecar-logstash]# kubectl apply -f 2.tomcat-app1.yaml
deployment.apps/magedu-tomcat-app1-deployment created
[root@master1 2.sidecar-logstash]# kubectl get po -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
magedu-tomcat-app1-deployment-dd85ddc8-2xpc5 2/2 Running 0 2m18s 10.100.154.4 node1 <none> <none>
magedu-tomcat-app1-deployment-dd85ddc8-4mfjr 2/2 Running 0 2m18s 10.100.44.1 node2 <none> <none>
3.3.1 临时目录创建情况
[root@node1 ~]# find / -type d -name applogs
/var/lib/kubelet/pods/b405281e-bca1-4716-893a-9f9b8a35deed/volumes/kubernetes.io~empty-dir/applogs
/var/lib/kubelet/pods/b405281e-bca1-4716-893a-9f9b8a35deed/plugins/kubernetes.io~empty-dir/applogs
3.4 查看kafka topic创建情况
上述配置无误的话,kafka中会自动生成topic
3.5 调整logstash消费者配置
[root@logstash-consumer config]# cat logstash-sample.conf
input {
kafka {
bootstrap_servers => "10.31.200.133:9092,10.31.200.134:9092,10.31.200.135:9092"
topics => ["tomcat-app1-topic"]
codec => "json"
}
}
output {
if [type] == "app1-sidecar-catalina-log" { # 这里要和dockefile中add的配置type相同
elasticsearch {
hosts => ["10.31.200.130:9200","10.31.200.131:9200","10.31.200.132:9200"]
index => "sidecar-app1-catalina-log--%{+YYYY.MM.dd}"
}}
if [type] == "app1-sidecar-access-log" { # 这里要和dockefile中add的配置type相同
elasticsearch {
hosts => ["10.31.200.130:9200","10.31.200.131:9200","10.31.200.132:9200"]
index => "sidecar-app1-access-log-%{+YYYY.MM.dd}"
}}
}
然后重启logstash消费者。
3.6 kibana查看日志
更多推荐
所有评论(0)