暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

IoT基础架构的演进 — 指标监控与日志收集

ProdanLabs 2021-09-20
1988

目前笔者参与的 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 字段来分离日志,虽然查看日志时需要做通配或过滤查询,但也基本达到了目的。


文章转载自ProdanLabs,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论