Kubernetes 日志收集与监控实战
在 Kubernetes 环境中,日志收集和监控是确保系统稳定性和性能的关键环节。本文将详细介绍如何在 Kubernetes 中进行应用程序日志收集、Kubernetes 日志处理、etcd 日志收集以及主节点和工作节点的监控。
1. 应用程序日志收集
在管理应用程序时,日志收集和分析对于跟踪应用程序状态至关重要。但在 Docker/Kubernetes 环境中,由于日志文件位于容器内部,从容器外部访问它们并不容易。为了解决这个问题,可以使用集中式日志收集平台,如 ELK(Elasticsearch、Logstash、Kibana)。
1.1 准备 Elasticsearch 服务器
首先,需要准备 Elasticsearch 服务器。可以通过以下步骤下载并设置 Elasticsearch:
# 下载 Kubernetes 压缩包
curl -L -O https://github.com/kubernetes/kubernetes/releases/download/v1.1.4/kubernetes.tar.gz
# 解压文件
tar zxf kubernetes.tar.gz
# 进入 Elasticsearch 示例目录
cd kubernetes/examples/elasticsearch/
# 创建 ServiceAccount
kubectl create -f service-account.yaml
# 创建 Elasticsearch 复制控制器
kubectl create -f es-rc.yaml --validate=false
# 创建 Elasticsearch 服务
kubectl create -f es-svc.yaml
创建完成后,可以通过 Kubernetes 服务访问 Elasticsearch 接口:
# 获取服务信息
kubectl get service
# 访问 Elasticsearch
curl http://192.168.45.152:9200/
1.2 准备示例应用程序
使用一个 Python Flask 程序作为示例应用程序:
# cat entry.py
from flask import Flask, request
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
@app.route("/addition/<int:x>/<int:y>")
def add(x, y):
return "%d" % (x+y)
if __name__ == "__main__":
app.run(host='0.0.0.0')
1.3 使用 Logstash 发送日志
Logstash 可以将应用程序日志从纯文本格式转换为 Elasticsearch 所需的 JSON 格式。首先,需要创建一个 Logstash 配置文件:
# cat logstash.conf.temp
input {
stdin {}
}
filter {
grok {
match => {
"message" => "%{IPORHOST:clientip} %{HTTPDUSER:ident} %{USER:auth} \[%{DATA:timestamp}\] \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})\" %{NUMBER:response} (?:%{NUMBER:bytes}|-)"
}
}
}
output {
elasticsearch {
hosts => ["_ES_IP_:_ES_PORT_"]
index => "mycalc-access"
}
stdout { codec => rubydebug }
}
然后,创建一个启动脚本,用于替换配置文件中的占位符:
#!/bin/sh
TEMPLATE="logstash.conf.temp"
LOGSTASH="logstash-2.2.2/bin/logstash"
cat $TEMPLATE | sed "s/_ES_IP_/$ELASTICSEARCH_SERVICE_HOST/g" | sed "s/_ES_PORT_/$ELASTICSEARCH_SERVICE_PORT/g" > logstash.conf
python entry.py 2>&1 | $LOGSTASH -f logstash.conf
1.4 构建 Docker 镜像
使用 Dockerfile 构建示例应用程序的 Docker 镜像:
FROM ubuntu:14.04
# 更新软件包
RUN apt-get update -y
# 安装 Python Setuptools
RUN apt-get install -y python-setuptools git telnet curl openjdk-7-jre
# 安装 pip
RUN easy_install pip
# 复制应用程序代码
ADD . /src
WORKDIR /src
# 下载 LogStash
RUN curl -L -O https://download.elastic.co/logstash/logstash/logstash-2.2.2.tar.gz
RUN tar -zxf logstash-2.2.2.tar.gz
# 安装 Python 模块
RUN pip install Flask
# 暴露端口
EXPOSE 5000
# 运行启动脚本
CMD ["./startup.sh"]
构建并上传镜像到 Docker Hub:
# 构建镜像
docker build -t hidetosaito/my-calc-elk .
# 登录 Docker Hub
docker login
# 推送镜像
docker push hidetosaito/my-calc-elk
1.5 创建 Kubernetes 复制控制器和服务
使用 YAML 文件创建 Kubernetes 复制控制器和服务:
# cat my-calc-elk.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: my-calc-elk-rc
spec:
replicas: 2
selector:
app: my-calc-elk
template:
metadata:
labels:
app: my-calc-elk
spec:
containers:
- name: my-calc-elk
image: hidetosaito/my-calc-elk
---
apiVersion: v1
kind: Service
metadata:
name: my-calc-elk-service
spec:
ports:
- protocol: TCP
port: 5000
type: ClusterIP
selector:
app: my-calc-elk
创建复制控制器和服务:
# 创建复制控制器和服务
kubectl create -f my-calc-elk.yaml
# 获取服务信息
kubectl get service
# 访问应用程序
curl http://192.168.121.63:5000/
curl http://192.168.121.63:5000/addition/3/5
1.6 使用 Kibana 可视化日志
Kibana 是一个用于 Elasticsearch 的可视化工具。下载并启动 Kibana:
# 下载 Kibana
curl -O https://download.elastic.co/kibana/kibana/kibana-4.1.6-linux-x64.tar.gz
# 解压文件
tar -zxf kibana-4.1.6-linux-x64.tar.gz
# 查找 Elasticsearch IP 地址
kubectl get services
# 指定 Elasticsearch IP 地址
sed -i -e "s/localhost/192.168.101.143/g" kibana-4.1.6-linux-x64/config/kibana.yml
# 启动 Kibana
kibana-4.1.6-linux-x64/bin/kibana
启动后,在浏览器中访问 Kibana 界面,即可查看应用程序日志。
2. 处理 Kubernetes 日志
Kubernetes 主节点上有三个守护进程:API 服务器、调度器和控制器管理器,它们的日志文件分别记录在
/var/log
文件夹下:
| 主节点守护进程 | 日志文件 | 描述 |
| — | — | — |
| API 服务器 | apiserver.log | API 调用日志 |
| 调度器 | k8s-scheduler.log | 容器调度事件的调度器数据日志 |
| 控制器管理器 | controller-manager.log | 与控制器管理器相关的事件或问题日志 |
节点上有一个 kubelet 进程,用于处理容器操作并向主节点报告,其日志文件为
kubelet.log
。此外,主节点和节点上还有一个
kube-proxy.log
文件,用于记录网络连接问题。
2.1 准备工作
使用 ELK 作为集中式日志平台收集 Kubernetes 日志。在收集日志之前,需要了解日志的数据结构,其格式如下:
<log level><date> <timestamp> <indicator> <source file>:<line number>] <logs>
例如:
E0328 00:46:50.870875 3189 reflector.go:227] pkg/proxy/config/api.go:60: Failed to watch *api.Endpoints: too old resource version: 45128 (45135)
通过日志文件中每行的首字符可以判断日志的严重程度:
- D: DEBUG
- I: INFO
- W: WARN
- E: ERROR
- F: FATAL
2.2 收集 Kubernetes 日志
使用 Logstash 的 grok 过滤器处理日志。首先,创建一个自定义模式文件:
# cat ./patterns/k8s
LOGLEVEL [DEFIW]
DATE [0-9]{4}
K8SLOGLEVEL %{LOGLEVEL:level}%{DATE}
然后,创建一个 Logstash 配置文件,用于收集
k8s-apiserver.log
日志:
# cat apiserver.conf
input {
file {
path => "/var/log/k8s-apiserver.log"
}
}
filter {
grok {
patterns_dir => ["./patterns"]
match => { "message" => "%{K8SLOGLEVEL} %{TIME} %{NUMBER} %{PROG:program}:%{POSINT:line}] %{GREEDYDATA:message}" }
}
}
output {
elasticsearch {
hosts => ["_ES_IP_:_ES_PORT_"]
index => "k8s-apiserver"
}
stdout { codec => rubydebug }
}
启动 Logstash 处理日志:
# 启动 Logstash
bin/logstash -f apiserver.conf
3. 处理 etcd 日志
etcd 是 Kubernetes 的数据存储,用于保存 Kubernetes 资源的信息。在 etcd 服务器上,日志文件记录在
/var/log/etcd.log
中,其格式如下:
<date> <time> <subpackage>: <logs>
例如:
2016/04/4 08:43:51 etcdserver: starting server... [version: 2.1.1, cluster version: to_be_decided]
3.1 准备工作
在收集 etcd 日志之前,需要准备好 ELK 服务器。如果 etcd 服务器是 Kubernetes 集群之外的独立机器,需要将 Elasticsearch 服务暴露出来:
# cat es-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: elasticsearch
labels:
component: elasticsearch
spec:
type: LoadBalancer
selector:
component: elasticsearch
ports:
- name: http
port: 9200
nodePort: 30000
protocol: TCP
- name: transport
port: 9300
protocol: TCP
3.2 收集 etcd 日志
创建一个 Logstash 配置文件,用于收集 etcd 日志:
# cat etcd.conf
input {
file {
path => "/var/log/etcd.log"
}
}
filter {
grok {
match => {
"message" => "%{DATA:date} %{TIME:time} %{PROG:subpackage}: %{GREEDYDATA:message}"
}
}
}
output {
elasticsearch {
hosts => ["<ELASTIC_SERVICE_IP>:<EXPOSE_PORT>"]
index => "etcd-log"
}
stdout { codec => rubydebug }
}
启动 Logstash 处理日志:
# 启动 Logstash
./bin/logstash -f etcd.conf
4. 监控主节点和工作节点
监控主节点和工作节点可以帮助我们了解资源消耗情况,提高资源利用率。在设置监控集群之前,需要完成以下两个先决条件:
- 更新 Kubernetes 到最新版本(1.2.1)
- 设置 DNS 服务器
4.1 更新 Kubernetes 到最新版本
更新运行中的 Kubernetes 系统版本的步骤如下:
1. 停止所有 Kubernetes 服务:
service <KUBERNETES_DAEMON> stop
- 下载最新的 tarball 文件:
cd /tmp && wget https://storage.googleapis.com/kubernetes-release/release/v1.2.1/kubernetes.tar.gz
- 解压文件:
tar -xvf /tmp/kubernetes.tar.gz -C /opt/
cd /opt && tar -xvf /opt/kubernetes/server/kubernetes-server-linux-amd64.tar.gz
- 复制新文件并覆盖旧文件:
cd /opt/kubernetes/server/bin/
# 主节点
cp kubectl hypercube kube-apiserver kube-controller-manager kube-scheduler kube-proxy /usr/local/bin
# 节点
cp kubelet kube-proxy /usr/local/bin
- 启动系统服务并验证版本:
kubectl version
4.2 设置 DNS 服务器
使用官方模板在 Kubernetes 系统中设置 DNS 服务器,步骤如下:
1. 复制模板文件并修改:
cp skydns-rc.yaml.in skydns-rc.yaml
cp skydns-svc.yaml.in skydns-svc.yaml
替换模板文件中的变量:
| 输入变量 | 替换值 | 示例 |
| — | — | — |
| {{ pillar[‘dns_domain’] }} | 集群的域名 | k8s.local |
| {{ pillar[‘dns_replicas’] }} | 复制控制器的副本数 | 1 |
| {{ pillar[‘dns_server’] }} | DNS 服务器的私有 IP | 192.168.0.2 |
2. 创建资源:
kubectl create -f skydns-svc.yaml
kubectl create -f skydns-rc.yaml
- 在 kubelet 中启用 Kubernetes DNS:
# 对于 init 服务
# cat /etc/init.d/kubernetes-node
# 添加 DNS 信息
daemon $kubelet_prog \
--api_servers=<MASTER_ENDPOINT_URL>:<EXPOSED_PORT> \
--v=2 \
--cluster-dns=192.168.0.2 \
--cluster-domain=k8s.local \
--address=0.0.0.0 \
--enable_server \
--hostname_override=${hostname} \
> ${logfile}-kubelet.log 2>&1 &
# 对于 systemd 服务
# cat /etc/kubernetes/kubelet
# 添加 DNS 信息
KUBELET_ARGS="--cluster-dns=192.168.0.2 --cluster-domain=k8s.local"
重启 kubelet 服务。
4.3 安装监控集群
使用 Heapster、influxDB 和 Grafana 构建监控系统。步骤如下:
1. 检查监控集群的目录:
cd /opt/kubernetes/cluster/addons/cluster-monitoring/influxdb && ls
- 保留大部分服务模板的默认设置,但暴露 Grafana 服务:
# cat heapster-service.yaml
apiVersion: v1
kind: Service
metadata:
name: monitoring-grafana
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "Grafana"
spec:
type: NodePort
ports:
- port: 80
nodePort: 30000
targetPort: 3000
selector:
k8s-app: influxGrafana
- 修改 Heapster 和 influxDB-Grafana 复制控制器的模板:
# cat influxdb-grafana-controller.yaml
# 修改 Grafana 容器的环境变量
- image: gcr.io/google_containers/heapster_grafana:v2.6.0-2
name: grafana
env:
resources:
limits:
cpu: 100m
memory: 100Mi
requests:
cpu: 100m
memory: 100Mi
env:
- name: INFLUXDB_SERVICE_URL
value: http://monitoring-influxdb.kube-system:8086
- name: GF_AUTH_BASIC_ENABLED
value: "false"
- name: GF_AUTH_ANONYMOUS_ENABLED
value: "true"
- name: GF_AUTH_ANONYMOUS_ORG_ROLE
value: Admin
- name: GF_SERVER_ROOT_URL
value: /
# cat heapster-controller.yaml
# 修改 Heapster 容器的参数
containers:
- image: gcr.io/google_containers/heapster:v1.0.2
name: heapster
resources:
limits:
cpu: 100m
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
command:
- /heapster
- --source=kubernetes:<MASTER_ENDPOINT_URL>:<EXPOSED_PORT>?inClusterConfig=false
- --sink=influxdb:http://monitoring-influxdb.kube-system:8086
- --metric_resolution=60s
- 创建资源:
kubectl create -f influxdb-service.yaml
kubectl create -f grafana-service.yaml
kubectl create -f heapster-service.yaml
kubectl create -f influxdb-grafana-controller.yaml
kubectl create -f heapster-controller.yaml
- 检查 Kubernetes 资源:
kubectl get svc --namespace=kube-system
kubectl get pod --namespace=kube-system
4.4 介绍 Grafana 仪表盘
在浏览器中访问 Grafana 仪表盘:
<NODE_ENDPOINT>:30000
。默认情况下,有两个仪表盘:Cluster 和 Pods。Cluster 仪表盘显示节点的资源利用率,Pods 仪表盘显示每个 Pod 的资源使用情况。
4.5 创建自定义监控指标
创建自定义监控指标的步骤如下:
1. 进入 Pods 仪表盘,点击 ADD ROW,选择添加图形面板。
2. 给面板命名,例如 CPU Rate。
3. 设置查询参数:
- FROM: cpu/usage_rate
- WHERE: type = pod_container
- AND: namespace_name=$namespace, pod_name= $podname
- GROUP BY: tag(container_name)
- ALIAS BY: $tag_container_name
4. 保存面板。
通过以上步骤,我们可以在 Kubernetes 环境中实现应用程序日志收集、Kubernetes 日志处理、etcd 日志收集以及主节点和工作节点的监控。这些操作可以帮助我们更好地了解系统的运行状态,及时发现和解决问题。
Kubernetes 日志收集与监控实战
5. 总结与最佳实践
5.1 日志收集总结
- 应用程序日志 :通过 ELK 堆栈(Elasticsearch、Logstash、Kibana)可以有效地收集和可视化应用程序日志。将 Logstash 与应用程序容器捆绑在一起,即使复制控制器增加副本数量,也能无配置更改地捕获所有应用程序日志。
- Kubernetes 日志 :利用 Logstash 的 grok 过滤器可以解析 Kubernetes 主节点和节点上各种守护进程的日志,将其发送到 Elasticsearch 进行集中存储和分析。
- etcd 日志 :同样使用 Logstash 收集 etcd 日志,通过自定义的 grok 模式解析日志格式,方便后续的查询和分析。
5.2 监控总结
- 前置条件 :更新 Kubernetes 到最新版本并设置 DNS 服务器是搭建监控系统的重要前提。DNS 服务器可以简化服务连接,减少配置依赖。
- 监控系统 :基于 Heapster、influxDB 和 Grafana 构建的监控系统,可以实时监控节点和 Pod 的资源使用情况。Grafana 提供了直观的可视化界面,方便用户查看和分析数据。
5.3 最佳实践
-
日志管理
- 定期清理 Elasticsearch 中的过期日志,避免占用过多磁盘空间。
- 为不同类型的日志设置不同的索引,便于管理和查询。
- 对日志进行备份,以防数据丢失。
-
监控管理
- 定期检查监控系统的运行状态,确保数据收集和可视化的正常进行。
- 根据实际需求调整监控指标和阈值,及时发现潜在的问题。
- 对监控数据进行长期存储和分析,以便进行容量规划和性能优化。
6. 未来展望
随着 Kubernetes 的不断发展,日志收集和监控领域也会有更多的创新和改进。以下是一些可能的发展方向:
6.1 自动化日志分析
未来可能会出现更多的自动化日志分析工具,能够自动识别和分类日志中的异常信息,提供更智能的问题诊断和解决方案。
6.2 集成更多监控数据源
除了现有的资源使用监控,可能会集成更多的数据源,如网络流量、存储 I/O 等,提供更全面的系统监控。
6.3 云原生监控解决方案
随着云原生技术的普及,可能会出现更多专门为 Kubernetes 设计的云原生监控解决方案,提供更高效、更便捷的监控服务。
7. 流程图回顾
以下是整个日志收集和监控流程的 mermaid 流程图:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
A([开始]):::startend --> B(应用程序日志收集):::process
B --> B1(准备 Elasticsearch):::process
B --> B2(准备示例应用):::process
B --> B3(使用 Logstash 发送日志):::process
B --> B4(构建 Docker 镜像):::process
B --> B5(创建 Kubernetes 资源):::process
B --> B6(使用 Kibana 可视化):::process
A --> C(Kubernetes 日志处理):::process
C --> C1(了解日志结构):::process
C --> C2(创建自定义模式):::process
C --> C3(创建 Logstash 配置):::process
C --> C4(启动 Logstash 收集):::process
A --> D(etcd 日志收集):::process
D --> D1(准备 ELK 服务器):::process
D --> D2(暴露 Elasticsearch 服务):::process
D --> D3(创建 Logstash 配置):::process
D --> D4(启动 Logstash 收集):::process
A --> E(监控主节点和工作节点):::process
E --> E1(更新 Kubernetes 版本):::process
E --> E2(设置 DNS 服务器):::process
E --> E3(安装监控集群):::process
E --> E4(使用 Grafana 仪表盘):::process
E --> E5(创建自定义指标):::process
B6 & C4 & D4 & E5 --> F([结束]):::startend
这个流程图展示了从开始到结束的整个日志收集和监控过程,包括应用程序日志、Kubernetes 日志、etcd 日志的收集,以及主节点和工作节点的监控。每个步骤都有明确的操作和依赖关系,帮助读者更好地理解整个流程。
8. 常见问题解答
8.1 日志收集问题
-
问题
:Logstash 无法连接到 Elasticsearch。
- 解决方案 :检查 Elasticsearch 的 IP 地址和端口是否正确,确保 Logstash 配置文件中的占位符已正确替换为实际值。同时,检查网络连接是否正常。
-
问题
:日志解析错误。
- 解决方案 :检查 grok 模式是否正确,确保模式能够匹配日志的实际格式。可以使用 Logstash 的调试模式进行验证。
8.2 监控问题
-
问题
:Grafana 仪表盘无法显示数据。
- 解决方案 :检查 Heapster 是否正常工作,确保它能够正确收集资源使用数据。同时,检查 influxDB 是否正常存储数据,以及 Grafana 配置中数据源的设置是否正确。
-
问题
:监控系统性能下降。
- 解决方案 :检查 influxDB 的磁盘使用情况,确保有足够的空间存储数据。同时,调整 Heapster 的数据收集频率,避免过度收集数据导致性能问题。
通过以上的总结、展望、流程图和常见问题解答,希望读者能够更好地掌握 Kubernetes 日志收集和监控的相关知识,在实际应用中更加得心应手。不断学习和实践,将有助于我们更好地管理和优化 Kubernetes 集群。
超级会员免费看
3万+

被折叠的 条评论
为什么被折叠?



