Prometheus的整体设计模型是基于单实例的。如果要打造高可用的Prometheus服务,一般通过2种方式进行:
使用开源产品第一原则:Base官网文档。所以咱们先来看一下官方文档中支持哪些远程存储,以及如何使用
在官方文档中找到了Remote Endpoints and Storage这一节,列举了所有目前官方已知的存储清单及读写支持
《Remote Endpoints and Storage》这篇文档的第一段“remote write”和“remote read”点击超链接即可跳转到官方Configuration文档中相应的小节。
官方文档中还有一个Git Hub的文档,里面给了简单的Demo来展示如何配置adapter
基于如上的文档可以得出一些基本结论
经过公司内部多方了解,当前公司内部提供的在清单内的公共服务有:
根据之前指定的需求目标,真正符合需求的只有TiKV
通过官方文档的Git Hub超链接,我们转到了TiPrometheus这个项目的GitHub主页。
话说真心要吐槽一下这篇文档,只标识了如何构建和启动项目,都没有给到Prometheus内的配置Demo甚至接口API。没办法,这部分只能边分析源码边摸索了(坑爹的是这居然还是Go写的!)
读过我其他文章的童鞋知道前几个月我将整套服务都进行了容器化。由于其他用的都是应用比较广泛的开源项目,官方都放出了Docker image。也有比较完备的官方文档和各种网络事件文章。所以在当前环境下,对于我来说的优选是找到官方镜像
但是!没有官方镜像
好吧,在docker hub上找找有没有其它人已经做好的镜像
太高兴了,找到了红圈中的镜像(ps:另一个镜像是我后来做的,这个后面再说)
但是高兴地太早了。根据Tiprometheus项目内的conf.toml.example进行并启动后,项目总是报错
time="2020-04-23T10:18:51Z" level=info msg="[pd] create pd client with endpoints []"
time="2020-04-23T10:18:51Z" level=error msg="[pd] failed to get cluster id: rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = \"transport: Error while dialing dial tcp: missing address\""
通过如上的报错,可以确定,错误原因是代码内没有拿到PDHost这个配置!!!
经过各种方式排出己方因素后,我发现这个镜像描述中提示:Updated a year ago
好吧,到了这里还是想用起来,所以去翻一番当时的代码是什么样子的。
。。。。。。。(此处省略一万字)
总之,最后也没有能成功使用这个镜像。
好吧,靠人不如靠己。
做镜像的过程中的细节我就不再赘述了,讲一下大体经过
Tiprometheus的文档Quick Start中描述了打包的方法。但实际通过命令打包时,报错了。具体报错已经有人提交了issue#5
说实话,踩了很多坑。下面一个部分会慢慢讲
正确的编译命令
GOOS=linux CGO_ENABLED=0 GOARCH=amd64 go build -a -o tiprometheus cmd/tiprometheus/app.go
这是第一次制作Docker镜像,不过好在之前都接触过公司的发布系统,所以对Dockerfile有一定了解
使用了centos:centos7作为基础镜像,虽然有点儿大,但是能跑起来(各位大佬有好的建议可以留言哈)
FROM busybox:latest
WORKDIR /opt/
COPY ./tiprometheus /ops/tiprometheus
USER nobody
EXPOSE 12350
ENTRYPOINT [ "/ops/tiprometheus" ]
其实最开始编译Tiprometheus的时候,命令跟GitHub的文档一样
go build -o tiprometheus cmd/tiprometheus/app.go
高高兴兴的打包,部署。结果:
[root@01 ti]# docker-compose -f docker-compose.yml up
WARNING: The Docker Engine you're using is running in swarm mode.
Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.
To deploy your application across the swarm, use `docker stack deploy`.
Removing ti_tiprometheus_1
Recreating d140c131ffe8_ti_tiprometheus_1 ... done
Attaching to ti_tiprometheus_1
tiprometheus_1 | standard_init_linux.go:190: exec user process caused "no such file or directory"
划重点:
standard_init_linux.go:190: exec user process caused "no such file or directory"
心里一万匹草泥马踏过……
各种百度,有说启动脚本不对的,有说编码不对的。。。。
后来将镜像换成了centos:centos7其他脚本不变,运行成功
我靠!
所以问题点定位为:更换了镜像之后能够成功运行
后来注意到了这篇文章:《以alpine镜像为基础将go应用部署在docker中》
最终定位到原因:
所以正确的打包姿势:
GOOS=linux CGO_ENABLED=0 GOARCH=amd64 go build -a -o tiprometheus cmd/tiprometheus/app.go
是的,你们猜对了,这就镜像是我做的
关于这个镜像的具体信息,可以查看详细的良心文档
好了,正菜在这里,相信来这里的大部分小伙伴不是看我自嗨的,是想知道怎么用
version: '2'
services:
tiprometheus:
image: shikaiwei/tiprometheus:20200428.RELEASE
restart: always
ports:
- 12350:12350
volumes:
- /usr/local/tipromethuse-docker/conf/conf.toml:/opt/conf.toml
container_name: tiprometheus
在良心文档中有提过,这里要再强调一下:镜像中没有自带conf.toml这个配置文件,必须要在启动Docker的时候将它映射到路径/opt/conf.toml下!
[dev]
AdapterListen = "127.0.0.1:12350"
PDHost = "10.0.0.221:2000"
TimeInterval = 5
AdapterEnableTLS = false
TiKVEnableTLS = false
[default]
AdapterListen = ":12350"
PDHost = "10.0.0.221:2000"
TimeInterval = 5
AdapterEnableTLS = false
AdapterCACertificate = "/path/to/certs/ca.pem"
AdapterServerCertificate = "/path/to/certs/adapter.pem"
AdapterServerKey = "/path/to/certs/adapter.key"
TiKVEnableTLS = false
TiKVCACertificate = "/path/to/certs/ca.pem"
TiKVClientCertificate = "/path/to/certs/client.pem"
TiKVClientKey = "/path/to/certs/client.key"
这里实际生效的是default部分,除非你在启动命令中使用command属性另行定义
注意大坑:AdapterListen如果写成127.0.0.1:12350的形式,那么服务会监听本机请求,并拒绝外部请求。如果使用容器部署则一定要写成:
AdapterListen = ":12350"
这里仅给到需要配置的部分
remote_write:
- url: 'http://tiprometheus:12350/write'
remote_read:
- url: 'http://tiprometheus:12350/read'
read_recent: false
注意:
http://[宿主机IP]:[宿主机映射端口]/write
http://[宿主机IP]:[宿主机映射端口]/read
如果成功部署,则会在Tiprometheus的容器日志中看到如下数据:
2020-04-26 11:41:48:2020/04/26 03:39:42 Naive write data: [name:"__name__" value:"node_network_receive_multicast_total" name:"device" value:"lo" name:"instance" value:"node-exporter:9100" name:"job" value:"node" ] [{0 1587872369102}]
2020-04-26 11:41:48:2020/04/26 03:39:42 Naive write data: [name:"__name__" value:"process_open_fds" name:"instance" value:"localhost:9090" name:"job" value:"prometheus" ] [{158 1587872377008}]
2020-04-26 11:41:48:2020/04/26 03:39:42 Naive write data: [name:"__name__" value:"net_conntrack_dialer_conn_failed_total" name:"dialer_name" value:"remote_storage" name:"instance" value:"localhost:9090" name:"job" value:"prometheus" name:"reason" value:"resolution" ] [{0 1587872377008}]
2020-04-26 11:41:48:2020/04/26 03:39:42 Naive write data: [name:"__name__" value:"go_memstats_mspan_sys_bytes" name:"instance" value:"localhost:9090" name:"job" value:"prometheus" ] [{2.146304e+06 1587872377008}]
2020-04-26 11:41:48:2020/04/26 03:39:42 Naive write data: [name:"__name__" value:"prometheus_engine_query_duration_seconds" name:"instance" value:"localhost:9090" name:"job" value:"prometheus" name:"quantile" value:"0.5" name:"slice" value:"inner_eval" ] [{0.000308029 1587872377008}]
2020-04-26 11:41:48:2020/04/26 03:39:42 Naive write data: [name:"__name__" value:"prometheus_engine_query_duration_seconds" name:"instance" value:"localhost:9090" name:"job" value:"prometheus" name:"quantile" value:"0.9" name:"slice" value:"inner_eval" ] [{0.014236842 1587872377008}]
2020-04-26 11:41:48:2020/04/26 03:39:42 Naive write data: [name:"__name__" value:"prometheus_config_last_reload_successful" name:"instance" value:"localhost:9090" name:"job" value:"prometheus" ] [{1 1587872377008}]
2020-04-26 11:41:48:2020/04/26 03:39:42 Naive write data: [name:"__name__" value:"prometheus_engine_query_duration_seconds" name:"instance" value:"localhost:9090" name:"job" value:"prometheus" name:"quantile" value:"0.99" name:"slice" value:"inner_eval" ] [{0.099016172 1587872377008}]