阿里云k8s+log-pilot日志收集

背景说明

项目基本完成容器化与vpc迁移,完成架构改造的第一步。之后计划将服务逐步迁移到k8s上管理,依赖docker+k8s这样的PAAS平台,做到“更轻量的运维,人人都是devops”。

首先项目运行在阿里云的vpc内,需要使用阿里云的k8s容器服务,需要做所有系统的二次迁移。那么在迁移之前,需要了解使用k8s的架构需要有哪些一些基础设施。

k8s作为优秀的PAAS平台,已经帮我们解决资源调度、服务编排、服务发现等工作,从实际场景出发,我们迁移时需要确认以下几点:

  • 容器的日志如何收集
  • 业务监控(这里系统监控与进程监控可以依靠阿里云的基础设施来完成)
  • 服务流量调度(SLB如何接入,即ingress/egress的配置)
  • 发布系统
  • CMDB接入资源伸缩

这次先记录阿里云k8s集群接入日志服务的方式。

日志系统架构

传统的ELK架构

日志系统的解决方案最常见的就是ELK,elasticsearch + logstash + kibana的组合,同时日志采集可以使用filebeat。架构如下:

阿里云k8s+log-pilot日志收集_第1张图片
阿里云k8s+log-pilot日志收集_第2张图片

  • filebeat采集指定文件的日志信息
  • logstash做日志收集,日志格式化,日志内容过滤等工作
  • elasticsearch完成日志索引入库
  • kibana提供可视化的日志查询页面

docker + log-pilot + 阿里SLS

上一篇文章中,我是使用了docker-compose在一台VM上跑多个容器(当时k8s的体系知识还不够完备),基于log-pilot:0.1版本采集容器的stdout的输出。实际上log-pilot的机制与filebeat一样,默认采集了/var/lib/docker/containers目录下的容器日志信息,再根据log-pilot里的配置上报给SLS对应的project和log-store入库。传送门

k8s + log-pilot + 阿里云SLS

在k8s里部署log-pilot有几个优点,通过DaemonSet这个控制器的特性,可以将底层资源的扩缩容操作透明化,不用在跑什么部署脚本安装log-pilot了,另外log-pilot接入SLS解决ELK传统架构里维护es集群的痛苦。

什么是DaemonSet?
A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. As nodes are added to the cluster, Pods are added to them. As nodes are removed from the cluster, those Pods are garbage collected. Deleting a DaemonSet will clean up the Pods it created.

官网上的说明是能够在所有的Node上执行定义好的一个pod,在整个底层的k8s集群里增加与删除node,都会对应的增加与删除控制器定位DaemonSet的Pod。

相关配置

log-pilot.yml

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: log-pilot
  namespace: kube-system
  labels:
    k8s-app: log-pilot
spec:
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        k8s-app: log-pilot
      annotations:
        scheduler.alpha.kubernetes.io/critical-pod: ''
    spec:
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: log-pilot
        image: registry.cn-hangzhou.aliyuncs.com/acs/log-pilot:0.9.6-fluentd
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        env:
          - name: "LOGGING_OUTPUT"
            value: "aliyun_sls"
          - name: "ALIYUNSLS_PROJECT"
            value: "k8s-test"
          - name: "ALIYUNSLS_REGION_ENDPOINT"
            value: "xxx.aliyuncs.com"
          - name: "ALIYUNSLS_ACCESS_KEY_ID"
            value: "xxx"
          - name: "ALIYUNSLS_ACCESS_KEY_SECRET"
            value: "xxx"
          - name: "ALIYUNSLS_NEED_CREATE_LOGSTORE"
            value: "true"
          - name: "NODE_NAME"
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
        volumeMounts:
        - name: sock
          mountPath: /var/run/docker.sock
        - name: root
          mountPath: /host
          readOnly: true
        - name: localtime
          mountPath: /etc/localtime
        securityContext:
          capabilities:
            add:
            - SYS_ADMIN
      terminationGracePeriodSeconds: 30
      volumes:
      - name: sock
        hostPath:
          path: /var/run/docker.sock
      - name: root
        hostPath:
          path: /
      - name: localtime
        hostPath:
          path: /etc/localtime

deployment.yml

apiVersion: apps/v1beta1 # for versions before 1.8.0 use apps/v1beta1
kind: Deployment
metadata:
  name: test
spec:
  replicas: 1
  template: 
    metadata:
      labels:
        app: test
    spec:
      containers:
      - name: test
        image: test:xxx
        resources:
          limits:
            cpu: "1"
            memory: "1000Mi"
          requests:
            cpu: "0.2"
            memory: "50Mi"
        ports:
        - containerPort: 12345
          name: test
        volumeMounts:
        - mountPath: /opt/conf
          name: conf-volume
        env:
         - name: aliyun_logs_test
           value: "stdout"           
         - name: aliyun_logs_test_tags
           value: app=test
      volumes:
      - name: conf-volume
        configMap:
          name: test
          items:
          - key: template.json
            path: prod.json
  • 执行kubectl apply -f log-pilot.yml后,可以在kube-system这个namspace下找到对应的log-pilot pod。
  • 在SLS的控制台里会自动生成一个k8s_test的项目,如果没有设置则默认生成k8s_k8sid这样的项目
  • 在deployment.yml中需要定义aliyun_logs_xxx(这里表示的是logstore的名称), value对应的是stdout(表示标准输出)
  • 执行kubectl apply -f deployment.yml后,就可以在对应的logstore里看到日志数据(当然要开启全文索引/自定义索引)
踩了什么坑
  • 阿里云文档中提供的默认yml配置使用的参数和log-pilot的镜像版本不对,最新的镜像需要使用0.9.6-fluentd版本。
  • 阿里云文档里提供的3种方法,没有直接说明log-pilot与SLS的配置;没有尝试过logtail的配置,可能会比log-pilot更方便一些(有试过的同学可以交流下)
踩了什么坑
  • 阿里云文档中提供的默认yml配置使用的参数和log-pilot的镜像版本不对,最新的镜像需要使用0.9.6-fluentd版本。
  • 阿里云文档里提供的3种方法,没有直接说明log-pilot与SLS的配置;没有尝试过logtail的配置,可能会比log-pilot更方便一些(有试过的同学可以交流下)
  • log-pilot环境变量的配置变化,例如FLUENTD_OUTPUT改为了LOGGING_OUTPUT,这里需要注意下,看了下源码发现前后版本里参数变化挺大。另外FLUENT_FLUSH_INTERVAL等参数已经失效了。可以看一遍repo

你可能感兴趣的:(架构)