精华内容
下载资源
问答
  • 使用log-pilot您可以从Docker主机收集日志并将其发送到集中式日志系统,例如elasticsearch,graylog2,awsog等log-pilot不仅可以收集docker stdout,还可以收集docker容器内的日志文件。 试试吧 先决条件: 码头...
  • Pilot

    2019-04-15 17:02:16
    Pilot高层架构 Pilot在Istio的控制面板中负责流量管理 Istio流量管理相关组件 图中红色的线表示控制流,黑色的线表示数据流。蓝色部分为和Pilot相关的组件。 控制面板组件 Discovery Services 对应的docker为...

    流量管理机制

    Pilot高层架构

    Pilot在Istio的控制面板中负责流量管理

    Istio流量管理相关组件

    图中红色的线表示控制流,黑色的线表示数据流。蓝色部分为和Pilot相关的组件。

    控制面板组件

    • Discovery Services

    对应的docker为istio-release/pilot,进程为pilot-discovery,该组件的功能包括:

    • 从Service provider(如kubernetes)中获取服务信息
    • 从K8S API Server中获取流量规则(K8S CRD Resource)
    • 将服务信息和流量规则转化为数据面可以理解的格式,通过标准的数据面API下发到网格中的各个sidecar中。
    • K8S API Server

    提供Pilot相关的CRD Resource的增、删、改、查。和Pilot相关的CRD有以下几种:

    • Virtualservice:用于定义路由规则,如根据来源或 Header 制定规则,或在不同服务版本之间分拆流量。
    • DestinationRule:定义目的服务的配置策略以及可路由子集。策略包括断路器、负载均衡以及 TLS 等。
    • ServiceEntry:用 ServiceEntry 可以向Istio中加入附加的服务条目,以使网格内可以向istio 服务网格之外的服务发出请求。
    • Gateway:为网格配置网关,以允许一个服务可以被网格外部访问。
    • EnvoyFilter:可以为Envoy配置过滤器。由于Envoy已经支持Lua过滤器,因此可以通过EnvoyFilter启用Lua过滤器,动态改变Envoy的过滤链行为。

    数据面板组件

    在数据面有两个进程Pilot-agent和envoy,这两个进程被放在一个docker容器gcr.io/istio-release/proxyv2中。

    • Pilot-agent
      该进程根据K8S API Server中的配置信息生成Envoy的配置文件,并负责启动Envoy进程。注意Envoy的大部分配置信息都是通过xDS接口从Pilot中动态获取的,因此Agent生成的只是用于初始化Envoy的少量静态配置。在后面的章节中,本文将对Agent生成的Envoy配置文件进行进一步分析。
    • Envoy
      Envoy由Pilot-agent进程启动,启动后,Envoy读取Pilot-agent为它生成的配置文件,然后根据该文件的配置获取到Pilot的地址,通过数据面标准API的xDS接口从pilot拉取动态配置信息,包括路由(route),监听器(listener),服务集群(cluster)和服务端点(endpoint)。Envoy初始化完成后,就根据这些配置信息对微服务间的通信进行寻址和路由。
      image

    XDS服务接口

    为了避免Envoy配置数据更新过程中出现流量丢失的情况,xDS接口应采用下面的顺序:

    1. CDS (Cluster Discovery Service) 首先更新Cluster数据(如果有变化)
    2. EDS (Endpoint Discovery Service) 更新相应Cluster的Endpoint信息(如果有变化)
    3. LDS (Listener Discovery Service) 更新CDS/EDS相应的Listener。
    4. RDS (Route Discovery Service) 最后更新新增Listener相关的Route配置。
    5. 删除不再使用的CDS cluster和 EDS endpoints。

    Envoy

    • Envoy调试方法

    Envoy提供了管理接口,缺省为localhost的15000端口,可以获取listener,cluster以及完整的配置数据导出功能。

    kubectl exec productpage-v1-67c8d9bc58-zq7m2 -c istio-proxy curl http://127.0.0.1:15000/help
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   823    0   823    0     0   3112      0 --:--:-- --:--:-- --:--:--  5715
    admin commands are:
      /: Admin home page
      /certs: print certs on machine
      /clusters: upstream cluster status
      /config_dump: dump current Envoy configs (experimental)
      /cpuprofiler: enable/disable the CPU profiler
      /healthcheck/fail: cause the server to fail health checks
      /healthcheck/ok: cause the server to pass health checks
      /help: print out list of admin commands
      /hot_restart_version: print the hot restart compatibility version
      /listeners: print listener addresses
      /logging: query/change logging levels
      /quitquitquit: exit the server
      /reset_counters: reset all counters to zero
      /runtime: print runtime values
      /runtime_modify: modify runtime values
      /server_info: print server version/status information
      /stats: print server stats
      /stats/prometheus: print server stats in prometheus format
    
    • 查看Envoy监听端口

    进入productpage pod中的Envoy(istio-proxy) container,查看监听端口

    • 9080: productpage进程对外提供的服务端口
    • 15001: Envoy的入口监听器,iptable会将pod的流量导入该端口中由Envoy进行处理
    • 15000: Envoy管理端口,该端口绑定在本地环回地址上,只能在Pod内访问。
    [root@k8-master-1 ~]# kubectl exec productpage-v1-67c8d9bc58-zq7m2 -c istio-proxy -- netstat -ln
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State      
    tcp        0      0 127.0.0.1:15000         0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:9080            0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:15001           0.0.0.0:*               LISTEN     
    Active UNIX domain sockets (only servers)
    Proto RefCnt Flags       Type       State         I-Node   Path
    

    Envoy启动过程

    Istio通过K8s的Admission webhook机制实现了sidecar的自动注入,Mesh中的每个微服务会被加入Envoy相关的容器。以Porductpage为例,容器中除了productpage之外,istio还为该Pod注入了gcr.io/istio-release/proxy_init和gcr.io/istio-release/proxyv2。

    [root@k8-master-1 ~]# kubectl describe pods productpage-v1-67c8d9bc58-zq7m2  | grep Image:
        Image:         gcr.io/istio-release/proxy_init:1.0.0
        Image:          istio/examples-bookinfo-productpage-v1:1.8.0
        Image:         gcr.io/istio-release/proxyv2:1.0.0
    
    • proxy_init

    Productpage的Pod中有一个InitContainer proxy_init,InitContrainer是K8S提供的机制,用于在Pod中执行一些初始化任务.在Initialcontainer执行完毕并退出后,才会启动Pod中的其它container。

    #查看容器内容,一下截取主要部分
    docker inspect gcr.io/istio-release/proxy_init:1.0.0
    

    image

    Proxy_init中执行的命令是istio-iptables.sh,该脚本的作用是通过配置iptable来劫持Pod中的流量。

    image

    该容器的命令行参数-p 15001,可以得知Pod中的数据流量被iptable拦截,并发向Envoy的15001端口。 -u 1337参数用于排除用户ID为1337,即Envoy自身的流量,以避免Iptable把Envoy发出的数据又重定向到Envoy,形成死循环。

    Proxyv2

    查看容器中的Pilot-agent和envoy两个进程信息

    [root@k8-master-1 ~]# kubectl exec productpage-v1-67c8d9bc58-zq7m2 -c istio-proxy -- ps -ef
    UID         PID   PPID  C STIME TTY          TIME CMD
    istio-p+      1      0  0 01:24 ?        00:00:00 /usr/local/bin/pilot-agent proxy sidecar --configPath /etc/istio/proxy --binaryPath /usr/local/bin/envoy --serviceCluster productpage --drainDuration 45s --parentShutdownDuration 1m0s --discoveryAddress istio-pilot.istio-system:15005 --discoveryRefreshDelay 1s --zipkinAddress zipkin.istio-system:9411 --connectTimeout 10s --statsdUdpAddress istio-statsd-prom-bridge.istio-system:9125 --proxyAdminPort 15000 --controlPlaneAuthPolicy MUTUAL_TLS
    istio-p+     12      1  0 01:24 ?        00:02:20 /usr/local/bin/envoy -c /etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --parent-shutdown-time-s 60 --service-cluster productpage --service-node sidecar~10.244.1.120~productpage-v1-67c8d9bc58-zq7m2.default~default.svc.cluster.local --max-obj-name-len 189 -l warn --v2-config-only
    

    Pilot-agent进程根据启动参数和K8S API Server中的配置信息生成Envoy的初始配置文件,并负责启动Envoy进程。从ps命令输出可以看到Pilot-agent在启动Envoy进程时传入了pilot地址和zipkin地址,并为Envoy生成了一个初始化配置文件envoy-rev0.json

    • 导出json文件
    kubectl exec productpage-v1-67c8d9bc58-zq7m2 -c istio-proxy -- cat /etc/istio/proxy/envoy-rev0.json > envoy-ev0.json
    
    • 配置文件结构图
      image
    • node

    包含了Envoy所在节点相关信息

      "node": {
        "id": "sidecar~10.244.1.120~productpage-v1-67c8d9bc58-zq7m2.default~default.svc.cluster.local",
        "cluster": "productpage",
    
        "metadata": {
              "INTERCEPTION_MODE": "REDIRECT",
              "ISTIO_PROXY_SHA": "istio-proxy:6166ae7ebac7f630206b2fe4e6767516bf198313",
              "ISTIO_PROXY_VERSION": "1.0.0",
              "ISTIO_VERSION": "1.0.0",
              "POD_NAME": "productpage-v1-67c8d9bc58-zq7m2",
          "istio": "sidecar"
        }
      }
    
    • admin

    配置Envoy的日志路径及管理端口

    "admin": {
        "access_log_path": "/dev/stdout",
        "address": {
          "socket_address": {
            "address": "127.0.0.1",
            "port_value": 15000
          }
        }
      }
    
    • dynamic_resources

    配置动态资源,这里配置的为ads服务器

    "dynamic_resources": {
        "lds_config": {
            "ads": {}
        },
        "cds_config": {
            "ads": {}
        },
        "ads_config": {
          "api_type": "GRPC",
          "refresh_delay": {"seconds": 1, "nanos": 0},
          "grpc_services": [
            {
              "envoy_grpc": {
                "cluster_name": "xds-grpc"
              }
            }
          ]
        }
      }
    
    • static_resources

    配置静态资源,包括了xds-grpc和zipkin两个cluster。其中xds-grpc cluster对应前面dynamic_resources中ADS配置,指明了Envoy用于获取动态资源的服务器地址。

    "static_resources": {
        "clusters": [
        {
        "name": "xds-grpc",
        "type": "STRICT_DNS",
        "connect_timeout": {"seconds": 10, "nanos": 0},
        "lb_policy": "ROUND_ROBIN",
    
          "tls_context": {
            "common_tls_context": {
              "alpn_protocols": "h2",
              "tls_certificates": {
                "certificate_chain": {
                  "filename": "/etc/certs/cert-chain.pem"
                },
                "private_key": {
                  "filename": "/etc/certs/key.pem"
                }
              },
              "validation_context": {
                "trusted_ca": {
                  "filename": "/etc/certs/root-cert.pem"
                },
                "verify_subject_alt_name": [
                  "spiffe://cluster.local/ns/istio-system/sa/istio-pilot-service-account"
                ]
              }
            }
          }
    
    • tracing

    配置分布式链路跟踪

    "tracing": {
        "http": {
          "name": "envoy.zipkin",
          "config": {
            "collector_cluster": "zipkin"
          }
        }
      }
    
    • stats_sinks

    这里配置的是和Envoy直连的metrics收集sink,和Mixer telemetry没有关系。Envoy自带stats格式的metrics上报。

    "stats_sinks": [
        {
          "name": "envoy.statsd",
          "config": {
            "address": {
              "socket_address": {"address": "10.100.26.51", "port_value": 9125}
            }
          }
        }
      ]
    

    Envoy配置分析

    • Envoy配置初始化流程
      image
    • Pilot-agent根据启动参数和K8S API Server中的配置信息生成Envoy的初始配置文件envoy-rev0.json,该文件告诉Envoy从xDS server中获取动态配置信息,并配置了xDS server的地址信息,即控制面的Pilot。
    • Pilot-agent使用envoy-rev0.json启动Envoy进程。
    • Envoy根据初始配置获得Pilot地址,采用xDS接口从Pilot获取到Listener,Cluster,Route等d动态配置信息。
    • Envoy根据获取到的动态配置启动Listener,并根据Listener的配置,结合Route和Cluster对拦截到的流量进行处理。
    展开全文
  • 该项目提供了多个节点,这些节点将Pilot Things和Node-RED彼此集成在一起。 当前,我们提供的节点允许Node-RED将数据提交到Pilot Things平台进行存储或解码(然后,解码结果可用于流程中以用于其他目的)。 先决...
  • 专注于分享4/5G网优资料:包括网络优化基础原理资料、各厂家常用网管指导、接入、切换、掉线、高丢包、干扰分析、速率、容量负载均衡、覆盖单验簇优化、各类网优常用工具合集
  • Pilot Pioneer9.5.1.0330,9.5最新安装包,不用加密狗,一键安装,此软件非常好用,如果有什么不懂的,可以留言给我
  • pilot_logbook-源码

    2021-04-16 18:17:24
    飞行员日志 飞行机组执照数据库 描述 这个项目是我增强REST技能的...警告:安装和运行前请查看用法本地: git clone https://github.com/Voravomas/pilot_logbook.git export PSQL_LOG=<PSQL> && export PSQL_PASS=<
  • 这里是鼎利测试工具的操作手册,希望帮助网优人员优化好整个网络.Pilot Pioneer Expert V10.4 操作手册.pdf.支持国产多多使用。
  • 01安全设计 第一次亲密接触-操作安全 1.1 HMI系统 1.2接管机制 融入当前社会的少数派-环境安全 2.1环境建模系统 2.2 EMI系统 2.3 DPS系统 2.4 Mobileye RSS模型 经验老到的国宾司机-...7.3黑匣子和远程协助
  • 通过一些基础知识可以知道pilot是专门管理testflight打包审核的,但在百度搜索”pilot fastlane“搜不到完整命令如何写的。 所以在这篇进行一个中间人跳转。 https://www.jianshu.com/p/eafa2fa37c1b 《 iOS项目的...
  • 这里有详细的国内测试鼎利使用说明书,有前台数据采集,到后台分析,希望大家共同使用.共同进步,支持分享.
  • Retouch Pilot v3.10.2是一款非常完美的相片修复工具,能够快速的将一系列老旧照片来进行修复,是一款非常实用的旧照片翻新修复工具,通过它可以对一些损坏的照片进行修复,可以修复旧片中的污点刮痕等细小的瑕疵,...
  • istio-pilot.tar

    2020-08-22 15:36:09
    istio-pilot.tar镜像,istio架构组成部分;方便下载,避免镜像下载时过慢的情况,下载完成后可以手动导入镜像。
  • 百度2018年自动驾驶年度报告,定义了系统的安全框架,运行与测试安全。
  • 一个包含Performance Co-Pilot(PCP)和相关软件(例如Redis和Grafana)的角色的集合。 集合的安排如下: performancecopilot.metrics.pcp PCP核心功能的角色,使用来自内核和系统服务的大量基本指标配置实时...
  • hornet是用Rust编写的Performance Co-Pilot(PCP)内存映射值(MMV)仪器库。 目录什么是PCP MMV工具大WaSP大WaSP是用Rust编写的Performance Co-Pilot(PCP)内存映射值(MMV)仪器库。 目录什么是PCP MMV仪器? ...
  • 阅读Code Pilot的。 Code Pilot是Xcode 5和6的插件,可让您快速找到项目中的文件,方法和符号,而无需使用鼠标。 它使用模糊查询匹配来计算按相关性排序的结果列表。 只需几次按键,您就可以跳到所需的方法。 ...
  • CHM2PDF Pilot能够转换CHM为PDF文件的方便工具,支持命令行方式、批量转换、高级密码保护、字体嵌入以及多种压缩方式
  • 对连续Pilot体制的宽带CDMA系统,提出了根据信道衰变速率对专用导码功率动态调整,从而提高系统容量的方法.该技术使导码与数据码道功率之比下降,对不同业务模型的系统容量均有不同程度的增加.文中对该方法的机理...
  • 操作手册_Pilot Pioneer V9.5.docx
  • pcpViewer是通过出色的“ Performance Co-Pilot”库(http://oss.sgi.com/projects/pcp)收集的3D数据查看器。 您可以看到CPU时间,网络设备,内存,硬盘驱动器以及pcp库和da导出的几乎所有数据的使用情况
  • 通信资料共享,希望你能在其中学到知识,加油
  • 文献Pilot Optimization and Channel Estimation for Multiuser Massive MIMO Systems
  • 通过Rpi GPIO控制PiloT的电源状态,并通过RPi 40引脚接头连接器为PiloT供电。 PiloT与RPi之间的控制和数据通信是通过USB或RPi物理串行端口进行的。 请注意,某些RPi变体使用物理串行端口与WiFi /蓝牙系统上的RPi...
  • Retouch Pilot能够修复相片中的瑕疵,当照片中存在刮痕、污点、头发等细小的瑕疵,不必动用庞大的PS,借助Retouch Pilot就能轻松无痕移除它们。从右侧工具栏中可选择使用刮痕擦除工具、隐藏工具、智能路径工具、...
  • Log-Pilot 源码简析

    2021-09-12 16:35:59
    Log-Pilot 源码简析简单介绍源码简析Pilot结构体Piloter接口main函数Pilot.RunPilot.NewPilot.watchPilot.processEventPilot.newContainerPilot.delContainerLogConfigpilot.getLogConfigspilot.parseLogConfigpilot...

    简单介绍

    Log-Pilot是阿里开源的一款容器日志收集项目,他的基本流程是动态监听容器的事件变化,然后依据容器的标签来进行解析,然后生成filebeat/fluentd的配置文件交由filebeat/fluentd采集插件来进行日志采集,来达到日志收集随容器的动态调度而自动伸缩的效果。

    源码简析

    Pilot结构体

    • 主要监听 docker 容器事件并获取容器日志挂载目录、标签、环境变量等信息,动态生成filebeat/fluentd配置文件
    // Pilot entry point
    type Pilot struct {
        piloter       Piloter               // Piloter 相关
        mutex         sync.Mutex            // 并发锁,多个容器事件触发,谁先抢到锁,谁先处理
        templ         *template.Template    // 日志采集客户端配置文件模板,log-pilot 使用 golang 的 text/template 模块渲染配置文件
        client        *k8s.Client           // docker 容器客户端,通过docker 事件接口 api 获取相关容器信息
        lastReload    time.Time             // 最后一次配置文件重载时间
        reloadChan    chan bool             // 重载通知 chan
        stopChan      chan bool             // 停止通知 chan
        baseDir       string                // docker 在宿主机上面的数据存储位置
        logPrefix     []string              // 定义环境变量以什么字符开头来表示应用日志所在目录,log-pilot 以配置环境变量的方式配置定每个容器中应用程序的日志路径位置,默认为aliyun
        createSymlink bool                  // 是否创建硬连接的方式关联要搜集的日志文件
    }
    
    

    Piloter接口

    • log-pilot支持filebeatfluentd两种日志收集器。 Piloter定义了收集器需要操作的一些方法,主要负责收集工具的启用停止重载的具体操作。
    type Piloter interface {
        Name() string       // "filebeat" 与 "fluentd",分别表示不同的搜集工具
     
        Start() error       // 启动搜集工具
        Reload() error      // 重载配置文件
        Stop() error        // 停止搜集工具
     
        GetBaseConf() string    // 日志采集客户端配置文件位置,如 filebeat 的 /etc/filebeat
        GetConfHome() string    // 日志采集客户端统一配置文件目录,如 filebeat 的 prospectors.d 位置
        GetConfPath(container string) string    // 具体配置文件路径
     
        OnDestroyEvent(container string) error  // 监听容器停止事件
    }
    
    

    main函数

    • 程序的入口、命令行处理:指定日志收集配置模板、收集日志等级、Docker日志路径等。
    • [pilot.Run]( # Pilot.Run) 启动程序
    func main() {
    	// 指定配置模板
    	template := flag.String("template", "", "Template filepath for fluentd or filebeat.")
        // 指定docker日志所在目录
    	base := flag.String("base", "", "Directory which mount host root.")
    	// 指定收集日志等级
    	level := flag.String("log-level", "INFO", "Log level")
        
        // ....
        
        // 读取模板文件
        b, err := ioutil.ReadFile(*template)
        // 启动程序入口
    	log.Fatal(pilot.Run(string(b), baseDir))
    }
    
    

    Pilot.Run

    • [pilot.New](# pilot.New) 初始化 Pilot 数据,Polit 中包含了对应 filebeat/fluentd 配置模版、dokcer client、并发锁、piloter 对象等
    • [pilot.watch](# pilot.watch) 开启容器事件监控
    func Run(templ string, baseDir string) error {
        // 初始化Pilot数据
    	p, err := New(templ, baseDir)
    	if err != nil {
    		panic(err)
    	}
        // 开启监听
    	return p.watch()
    }
    
    

    Pilot.New

    • 初始化Pilot数据
    func New(tplStr string, baseDir string) (*Pilot, error) {
        // 解析模板文件
    	templ, err := template.New("pilot").Parse(tplStr)
    	// ...
    	
        // 创建Docker容器客户端 
    	client, err := k8s.NewEnvClient()
    	// 创建Piloter接口
    	piloter, err := NewPiloter(baseDir)
    	
    	// ...
        
        // 从环境变量中获取日志路径位置,默认aliyun
    	logPrefix := []string{"aliyun"}
    	if os.Getenv(ENV_PILOT_LOG_PREFIX) != "" {
    		envLogPrefix := os.Getenv(ENV_PILOT_LOG_PREFIX)
    		logPrefix = strings.Split(envLogPrefix, ",")
    	}
    	// 从环境变量中获取是否创建硬连接的方式关联要搜集的日志文件
    	createSymlink := os.Getenv(ENV_PILOT_CREATE_SYMLINK) == "true"
    	return &Pilot{
    		client:        client,
    		templ:         templ,
    		baseDir:       baseDir,
    		reloadChan:    make(chan bool),
    		stopChan:      make(chan bool),
    		piloter:       piloter,
    		logPrefix:     logPrefix,
    		createSymlink: createSymlink,
    	}, nil
    }
    

    Pilot.watch

    func (p *Pilot) watch() error {
        // ....
        // 启动收集工具
        err := p.piloter.Start()           
        // ....
        
        // 接受 docker 事件,返回 chan
        msgs, errs := p.client.Events(ctx, options)  
     
        go func() {
            // ....
            // 无限循环获取事件
            for {           
                select {
                case msg := <-msgs:
                    // 处理 docker 事件
                    if err := p.processEvent(msg); err != nil {     
                        log.Errorf("fail to process event: %v,  %v", msg, err)
                    }
                // ....
            }
        }()
        // ....
    }
    

    Pilot.processEvent

    func (p *Pilot) processEvent(msg events.Message) error {
    	// 获取容器id
    	containerId := msg.Actor.ID
        // 上下文
        ctx := context.Background()
    	// ....
        // 判断事件
    	switch msg.Action {
    	case "start", "restart":
                // ....
            	// 返回容器信息
            	containerJSON, err := p.client.ContainerInspect(ctx, containerId)
                return p.newContainer(&containerJSON)
    	case "destroy", "die":
                // ....
    	    err := p.delContainer(containerId)
    	return nil
    }
    

    Pilot.newContainer

    func (p *Pilot) newContainer(containerJSON *types.ContainerJSON) error {
        // .... 
     	// 创建容器对象
        container := container(containerJSON)
     
        for _, e := range env {         // 处理环境变量, env由containerJSON 得到
            // .....
        }
        // 获取配置文件模板数据,属性由ContainerJSON提供
        logConfigs, err := p.getLogConfigs(jsonLogPath, mounts, labels)
        if err != nil {
            return err
        }
     
        // ....
     
        // 关联 docker 容器中应用日志文件或目录
        p.createVolumeSymlink(containerJSON)
     
        // 渲染配置文件模板数据,生成具体的配置文件
        logConfig, err := p.render(id, container, logConfigs)
        if err != nil {
            return err
        }
        // 保存配置文件
        if err = ioutil.WriteFile(p.piloter.GetConfPath(id), []byte(logConfig), os.FileMode(0644)); err != nil {
            return err
        }
        // 重载配置文件
        p.tryReload()
        return nil
    }
    

    Pilot.delContainer

    • 删除配置文件
    • reload 配置文件
    func (p *Pilot) delContainer(id string) error {
        // 移除关联docker 容器中应用日志文件或目录
    	p.removeVolumeSymlink(id)
    	
    	if p.piloter.Name() == PILOT_FLUENTD {
    		clean := func() {
    			// ....
                 // 删除
    			if err := os.Remove(p.piloter.GetConfPath(id)); err != nil {
    				// ...
    				return
    			}
                 // 重载配置文件
    			p.tryReload()
    		}
            // 15分钟后执行clean
    		time.AfterFunc(15*time.Minute, clean)
    		return nil
    	}
    
    	return p.piloter.OnDestroyEvent(id)
    }
    

    LogConfig

    • 动态渲染配置文件模板数据集
    type LogConfig struct {
        Name         string                 // 日志名
        HostDir      string                 // 日志文件在宿主机上的目录
        ContainerDir string                 // 容器应用日志目录
        Format       string                 // 日志采集应用的格式(none, json, csv等)
        FormatConfig map[string]string     
        File         string                 // 具体的日志文件名
        Tags         map[string]string      // 标签数据
        Target       string                 // 自定义输出目标,可以是索引或kafka主题等
        EstimateTime bool
        Stdout       bool
     
        CustomFields  map[string]string     // 自定义添加日志字段
        CustomConfigs map[string]string     // 自定义配置文件项
    }
    

    pilot.getLogConfigs

    func (p *Pilot) getLogConfigs(jsonLogPath string, mounts []types.MountPoint, labels map[string]string) ([]*LogConfig, error) {
    	var ret []*LogConfig
    	// 获取容器的挂载目录
    	mountsMap := make(map[string]types.MountPoint)
    	for _, mount := range mounts {
    		mountsMap[mount.Destination] = mount
    	}
    
    	var labelNames []string
    	// 取出label并排序
    	for k := range labels {
    		labelNames = append(labelNames, k)
    	}
    	sort.Strings(labelNames)
        
        
        // 通过label获取配置的日志所在目录
    	root := newLogInfoNode("")
    	for _, k := range labelNames {
    		for _, prefix := range p.logPrefix {
    			// ....
    		}
    	}
    	// 接续容器数据获得配置文件模板渲染数据
    	for name, node := range root.children {
    		logConfig, err := p.parseLogConfig(name, node, jsonLogPath, mountsMap)
    		// ....
    		ret = append(ret, logConfig)
    	}
    	return ret, nil
    }
    

    pilot.parseLogConfig

    • 接续容器数据获得配置文件模板渲染数据
    func (p *Pilot) parseLogConfig(name string, info *LogInfoNode, jsonLogPath string, mounts map[string]types.MountPoint) (*LogConfig, error) {
        // 获取日志目录
    	path := strings.TrimSpace(info.value)
    	 
    	// 获取标签数据
    	tags := info.get("tags")
    	tagMap, err := p.parseTags(tags)
    	
        // 获取索引或者kafka主题
    	target := info.get("target")
    	// 添加默认索引或主题
    	if _, ok := tagMap["index"]; !ok {
    		// ....
    	}
    	if _, ok := tagMap["topic"]; !ok {
    		// ....
    	}
    
    	// 检查是否有效
    	if err := p.tryCheckKafkaTopic(tagMap["topic"]); err != nil {
    		return nil, err
    	}
    	
        // 日志格式化
    	format := info.children["format"]
    	if format == nil || format.value == "none" {
    		format = newLogInfoNode("nonex")
    	}
    	formatConfig, err := Convert(format)
    
    	//特殊处理路径中通配符 regex
    	if format.value == "regexp" {
    		format.value = fmt.Sprintf("/%s/", formatConfig["pattern"])
    		delete(formatConfig, "pattern")
    	}
    	
        // 如果是stdout, 采集容器的标准输出日志
    	if path == "stdout" {
    		logFile := filepath.Base(jsonLogPath)
    		if p.piloter.Name() == PILOT_FILEBEAT {
    			logFile = logFile + "*"
    		}
    
    		return &LogConfig{
    			Name:         name,
    			HostDir:      filepath.Join(p.baseDir, filepath.Dir(jsonLogPath)),
    			File:         logFile,
    			Format:       format.value,
    			Tags:         tagMap,
    			FormatConfig: map[string]string{"time_format": "%Y-%m-%dT%H:%M:%S.%NZ"},
    			Target:       target,
    			EstimateTime: false,
    			Stdout:       true,
    		}, nil
    	}
    	
     	// 输出到容器内部的具体文件日志路径
    	containerDir := filepath.Dir(path)
    	file := filepath.Base(path)
    	hostDir := p.hostDirOf(containerDir, mounts)
    
    	cfg := &LogConfig{
    		Name:         name,
    		ContainerDir: containerDir,
    		Format:       format.value,
    		File:         file,
    		Tags:         tagMap,
    		HostDir:      filepath.Join(p.baseDir, hostDir),
    		FormatConfig: formatConfig,
    		Target:       target,
    	}
    
    	return cfg, nil
    }
    

    pilot.render

    • 渲染配置文件模板数据,生成具体的配置文件

    参考资料:

    log-pilot源码简析

    容器日志采集利器Log-Pilot

    展开全文
  • Design of Pilot Assignment for Large-Scale Distributed Antenna Systems
  • 4G优化
  • pilot是一种在熟悉的(android.*decoupled)堆栈结构中建模应用程序状态的方法,并为基于视图的ui呈现提供钩子。这有助于:
  • 袖珍飞行员 用于计划航班的网络应用。 公开API / api / v1 / 最近的兴趣点 / poi?lng = {float}&lat = {float}&range = {int}&hasRunway = {1 | 0 | null} 参数 ng 经度。 强制的 拉特 ...参数
  • ITMO-Academy-pilot-course:ITMO学院

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,436
精华内容 4,574
关键字:

pilot