
目前笔者参与的 KubeEdge 边缘计算项目已经投入生产并运营了一段时间,对比旧系统架构,在服务版本更新、设备管理、数据处理能力等方面有了质的提升。
监控系统和日志收集平台也是系统架构的组成部分,在实际系统的运行维护中,监控系统可以快速地发现并定位问题,提高故障处理速度,减少故障时间。日志收集平台可以方便开发人员或维护人员排查并定位问题。
因为安全原因连不上生产环境,笔者以开发环境示例,来聊聊怎么收集日志和监控指标数据,各位读者朋友如果有更酷解决方案,我们可以探讨下~
root@k8s-dev-master01:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-dev-master01 Ready master 57d v1.22.2
kubeedge-dev-node01 Ready agent,edge 17h v1.19.3-kubeedge-v1.8.1
root@k8s-dev-master01:~# kubectl top nodes
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-dev-master01 251m 6% 3117Mi 39%
kubeedge-dev-node01 170m 4% 584Mi 15%
Prometheus
在云原生领域,prometheus 已经成为了监控领域事实上的标准,生态圈比较成熟,常见的应用都有 exporter ,社区也提供了主流语言的 SDK,与业务集成也较为方便。我们都知道 prometheus server 是主动拉取监控指标数据的,但是边缘端设备是没有固定 IP 的,基本都是插 4G 卡或连接边缘网关设备,故 pull 模式不适用,只能走 pushgateway 的 push 模式。
实际上我们有两种 exporter,一种是社区的 exporter (如 node-exporter),一种是业务服务集成的 exporter ,业务服务集成的 exporter 直接 push 到 pushgateway 。社区的 exporter 通过 curl post 到 pushgateway 。

以 node-exporter 为例,在 node-exporter pod 里面运行一个 curl 容器,每 10S 向 pushgateway 推送数据。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: edge-node-exporter
namespace: monitoring
labels:
k8s-app: edge-node-exporter
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
version: v1.2.2
spec:
selector:
matchLabels:
k8s-app: edge-node-exporter
version: v1.2.2
updateStrategy:
type: OnDelete
template:
metadata:
labels:
k8s-app: edge-node-exporter
version: v1.2.2
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/edge
operator: Exists
priorityClassName: system-node-critical
containers:
- name: node-exporter
image: "prom/node-exporter:v1.2.2"
imagePullPolicy: "IfNotPresent"
args:
- --path.procfs=/host/proc
- --path.sysfs=/host/sys
ports:
- name: metrics
containerPort: 9100
hostPort: 9100
volumeMounts:
- name: proc
mountPath: /host/proc
readOnly: true
- name: sys
mountPath: /host/sys
readOnly: true
resources:
limits:
memory: 50Mi
requests:
cpu: 100m
memory: 50Mi
- name: curl
image: "curlimages/curl:7.76.1"
imagePullPolicy: "IfNotPresent"
args:
- /bin/sh
- -c
- while true ;do curl ${NODE_IP}:${NODE_EXPORTER_PORT}/metrics|curl --data-binary @- ${PUSHGATEWAY_URL}/metrics/job/node_exporter/instance/${NODE_IP}:${NODE_EXPORTER_PORT}/hostname/${HOSTNAME} ; sleep 10s; done;
env:
- name: HOSTNAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
- name: NODE_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.hostIP
- name: PUSHGATEWAY_URL
value: "https://{user}:{pass}@pushgateway.prodanlabs.cn"
- name: NODE_EXPORTER_PORT
value: "9100"
hostNetwork: true
hostPID: true
volumes:
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys
根据系统安全管理规定,在公网运行的系统,API 接口需要认证,目前我们使用 kubernetes ingress 做的 Basic Auth 认证。
使用 DaemonSet 部署
root@k8s-dev-master01:~/yaml/prometheus# kubectl get po -n monitoring -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
edge-node-exporter-d574g 2/2 Running 0 114m 192.168.13.102 kubeedge-dev-node01 <none> <none>
kube-state-metrics-5c8d5785c5-6l9bz 1/1 Running 0 2d4h 192.168.239.24 k8s-dev-master01 <none> <none>
node-exporter-dhn8j 1/1 Running 0 3h55m 172.31.6.142 k8s-dev-master01 <none> <none>
prometheus-0 1/1 Running 0 2d3h 192.168.239.29 k8s-dev-master01 <none> <none>
pushgateway-8656cd88cc-rwlhn 1/1 Running 0 128m 192.168.239.32 k8s-dev-master01 <none> <none>
到 pushgateway 查看

到 prometheus查询指标

PLG
目前流行的日志技术栈主要有两种,传统的 EFK 和新兴的 PLG ,相比 EFK 而言,PLG 有轻量、操作简单、低成本等优势,经过衡量和思考,我们选择了 PLG 。
我们边缘端的设备的容器运行时基本使用的是 docker,最初我们使用 DaemonSet 把 promtail 部署边缘端,因为 docker 日志格式问题,promtail采集上来的日志没有按容器名分离,所有的容器日志混在一起。

后面查看文档,发现 Loki 提供了一个 docker 插件,可以把日志上传到云端。
安装 Loki 插件,目前社区只提供 amd64 架构的插件,arm 等架构需要自己交叉编译下。或者安装 amd64 的插件,然后把交叉编译的 docker-driver 替换掉原来的。(/var/lib/docker/plugins/{id}/rootfs/bin)
root@raspberrypi:~# docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions
root@raspberrypi:~# docker plugin ls
ID NAME DESCRIPTION ENABLED
61f740d9d1ef loki:latest Loki Logging Driver true
修改 daemon.json 配置,日志驱动使用 Loki,重启 docker 。
root@raspberrypi:~# cat /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"storage-driver": "overlay2",
"log-driver": "loki",
"log-opts": {
"loki-url": "https://{user}:{pass}@loki.prodanlabs.cn/loki/api/v1/push",
"max-size": "100m",
"max-file": "5"
},
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
可以通过 container_name 字段来分离日志,虽然查看日志时需要做通配或过滤查询,但也基本达到了目的。





