首页

    kubernetes中使用influxdb+openresty

    标签:influxdb,openresty,kubernetes

    在openresty定制prometheus metrics监控nginx1,2中,我们可以看到数据的变化趋势,但是如果我们想看具体的信息,把鼠标移到曲线上,只能看到由label聚合的数据.像下图

    绿线由status聚合,只能看到不同status(status维度)的请求之和;同理,黄线由url聚合,只能看到不同url(url维度)的请求之和,其他信息当然看不到.

    influxdb

    influxdb是流行的时序数据库(time series database),可以作为prometheusRemote Endpoints and Storage,用于长期存储,配置参见.
    可以将openresty定制prometheus metrics监控nginx(1)里供prometheus拉取的metrics数据也存入influxdb

    lua-resty-http

    influxdb提供http api,在openresty中使用http client调用就行了,这里用lua-resty-http.注意openresty默认没有安装它

    local request_type
    if is_google_request then
      request_type='google'
    else
      request_type='other'
    end
    
    local http = require "resty.http"
    local httpc = http.new()
    local path=ngx.re.gsub(ngx.var.request_uri, "[.|/]html", "")
    
    local res, err = httpc:request_uri("http://influxdb-ip:8086/write?db=blog_stat", {
      method = "POST",
      body = 'request url="'..path..'",type="'..request_type..'"',
    })
    
    if not res then
      ngx.log(ngx.ERR,err)
      return
    end
    
    ngx.log(ngx.ERR,res.status,res.body)
    

    这里只存了path,request_type

    influxdb quoting

    influxdb http api里的/write,写入的数据放在--data-binary,格式需要满足Line Protocol format,具体内容文档里写的很清楚,不过要注意字符串上引号的使用

    Never single quote field values (even if they’re strings!).
    Do double quote field values that are strings.

    不注意的话很容易出现下面错误

    INSERT weather,location=us-midwest temperature='too warm'
    ERR: {"error":"unable to parse 'weather,location=us-midwest temperature='too warm'': invalid boolean"}
    

    知道这个事实后,上面lua代码里的post body就不能写成

    body = "request url='"..path.."',type='"..request_type.."'",
    

    kubernetes dns

    由于博客已经迁移到kubernetes,上面lua代码里的influxdb-ip就可以用kubernetes dns

    • nginx.conf http block添加
    resolver kube-dns.kube-system.svc.cluster.local valid=5s;
    

    当然也可以cat /etc/resolv.conf

    nameserver 10.96.0.10
    search default.svc.cluster.local svc.cluster.local cluster.local
    
    resolver 10.96.0.10 valid=5s;
    
    • lua代码使用influxdb service的dns
    local res, err = httpc:request_uri("http://influxdb.default.svc.cluster.local:8086/write?db=blog_stat", {
      method = "POST",
      body = 'request url="'..path..'",type="'..request_type..'"',
    })
    

    注意不能像docker compose中service之间调用一样,用service name就能和另一个service通信.

    local res, err = httpc:request_uri("http://influxdb:8086/write?db=blog_stat", {
      ...
    })
    

    nginx proxy_pass dns

    若是在ngx_http_proxy_module中使用kubernetes dns,需要

            location /url {
                set $my_upstream influxdb.default.svc.cluster.local;
                proxy_pass http://${my_upstream}:8086;
            }
    

    不能

            location /url {
                proxy_pass http://influxdb.default.svc.cluster.local:8086;
            }
    

    因为location block里如果

    • 没有定义变量,nginx会在启动时解析proxy_pass的dns,并缓存起来
    • 有定义变量,nginx会在运行时解析proxy_pass的dns

    当然也不能

            location /url {
                proxy_pass http://influxdb:8086;
            }
    

    还有

            location /url {
                set $my_upstream influxdb;
                proxy_pass http://${my_upstream}:8086;
            }
    

    参考Nginx proxy_pass directive string interpolation


    效果