我们可以基于haproxy 提供的dataplaneapi 动态进行haproxy 配置的修改,增强haproxy的可编程能力,以下是一个简单
的测试,基于docker-compose运行

环境准备

  • docker-compose文件
version: "3"
services:
    grafana:
     image: grafana/grafana
     ports:
     - "3000:3000"
    prometheus:
     image: prom/prometheus
     volumes:
     - "./prometheus.yml:/etc/prometheus/prometheus.yml"
     ports:
     - "9090:9090"
    haproxy:
     image: dalongrong/haproxy-dataplaneapi:2.0.5
     build: ./
     volumes:
     - "./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg"
     ports:
     - "80:80"
     - "5555:5555"
     - "8404:8404"
     - "8080:8080"
     - "9000:9000"
     - "9001:9001"
     - "9002:9002"
     - "1000-1005:1000-1005"
     - "10080:10080"
    nginx1:
     image: nginx
     ports:
     - "8090:80"
    nginx2:
     image: nginx
     ports:
     - "8091:80"

  • haproxy 配置
#
# This is the ultimate HAProxy 2.0 "Getting Started" config
# It demonstrates many of the features available which are now available 
# While you may not need all of these things, this can serve
# as a reference for your own configurations.
#
# Have questions? Check out our community Slack:
# https://slack.haproxy.org/
#
global
    # master-worker required for `program` section
    # enable here or start with -Ws
    master-worker
    mworker-max-reloads 3
    # enable core dumps
    set-dumpable
    user root
    group root
    log stdout local0
    stats socket /run/haproxy.sock mode 600 level admin
    stats timeout 2m
defaults
    mode http
    log global
    timeout client 5s
    timeout server 5s
    timeout connect 5s
    option redispatch
    option httplog
resolvers dns
    parse-resolv-conf
    resolve_retries 3
    timeout resolve 1s
    timeout retry 1s
    hold other 30s
    hold refused 30s
    hold nx 30s
    hold timeout 30s
    hold valid 10s
    hold obsolete 30s
program dataplane-api
    command /usr/local/sbin/dataplaneapi --host 0.0.0.0 --port 5555 --haproxy-bin /usr/local/sbin/haproxy --config-file /usr/local/etc/haproxy/haproxy.cfg --reload-cmd "kill -SIGUSR2 1" --reload-delay 5 --userlist api
    no option start-on-reload
userlist api 
   # user admin password $5$aVnIFECJ$2QYP64eTTXZ1grSjwwdoQxK/AP8kcOflEO1Q5fc.5aA
    user admin insecure-password dalong
frontend stats
    bind *:8404
    # Enable Prometheus Exporter
    http-request use-service prometheus-exporter if { path /metrics }
    stats enable
    stats uri /stats
    stats refresh 10s
frontend fe_main
    bind *:8080
    # Enable log sampling
    # One out of 10 requests would be logged to this source
    log 127.0.0.1:10001 sample 1:10 local0
    # For every 11 requests, log requests 2, 3, and 8-11
    log 127.0.0.1:10002 sample 2-3,8-11:11 local0
    # Log profiling data
    log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r cpu_calls:%[cpu_calls] cpu_ns_tot:%[cpu_ns_tot] cpu_ns_avg:%[cpu_ns_avg] lat_ns_tot:%[lat_ns_tot] lat_ns_avg:%[lat_ns_avg]"
    # gRPC path matching
    acl is_grpc_codename path /CodenameCreator/KeepGettingCodenames 
    # Dynamic 'do-resolve' trusted hosts
    acl dynamic_hosts req.hdr(Host) api.local admin.local haproxy.com
    # Activate Traffic Mirror
    # Redirect if not SSL
    # http-request redirect scheme https unless { ssl_fc }
    # Enable src tracking
    # http-request track-sc0 src table mypeers/src_tracking
    # Enable rate limiting
    # Return 429 Too Many Requests if client averages more than
    # 10 requests in 10 seconds.
    # (duration defined in stick table in peers section)
    http-request deny deny_status 429 if { sc_http_req_rate(0) gt 10 }
    # Enable local resolving of Host if within dynamic_hosts ACL
    # Allows connecting to dynamic IP address specified in Host header
    # Useful for DNS split view or split horizon
    http-request do-resolve(txn.dstip,dns) hdr(Host),lower if dynamic_hosts
    http-request capture var(txn.dstip) len 40 if dynamic_hosts
    # return 503 when dynamic_hosts matches but the variable 
    # txn.dstip is not set which mean DNS resolution error
    # otherwise route to be_dynamic
    use_backend be_503 if dynamic_hosts !{ var(txn.dstip) -m found }
    use_backend be_dynamic if dynamic_hosts
    # route to gRPC path
    use_backend be_grpc if is_grpc_codename 
    default_backend be_main
backend be_main
    # Enable Power of Two Random Choices Algorithm
    balance random(2)
    # Enable Layer 7 retries
    retry-on all-retryable-errors
    retries 3 
    # retrying POST requests can be dangerous
    # make sure you understand the implications before removing
    http-request disable-l7-retry if METH_POST
    server server1 nginx1:80 check inter 3s
    server server2 nginx2:80 check inter 3s
backend be_grpc
    default-server ssl verify none alpn h2 check maxconn 50
    server grpc1 10.1.0.11:3000 
    server grpc2 10.1.0.12:3000 
backend be_dynamic
    default-server ssl verify none check maxconn 50
    # rule to prevent HAProxy from reconnecting to services
    # on the local network (forged DNS name used to scan the network)
    http-request deny if { var(txn.dstip) -m ip 127.0.0.0/8 10.0.0.0/8 }
    http-request set-dst var(txn.dstip)
    server dynamic 0.0.0.0:0
backend spoe-traffic-mirror
    mode tcp
    balance roundrobin
    timeout connect 5s
    timeout server 1m
    server spoa1 127.0.0.1:12345
    server spoa2 10.1.0.20:12345
backend be_503
    # dummy backend used to return 503.
    # You can use the 'errorfile' directive to send a nice
    # 503 error page to end users.
    errorfile 503 /usr/local/etc/haproxy/errors/503.http
 
 
 
  • 启动
docker-compose up -d
  • 效果

动态添加代理配置

dataplaneapi 有一个事物的概念,我们可以基于次模型进行动态haproxy 的操作,以下是一个简单的演示

  • 创建代理的流程
    首选创建backend
    添加server到backend
    创建frontend
    添加bind 到frontend
  • 一个简单的操作
    初始化事物:
curl -X POST --user admin:dalong \
-H "Content-Type: application/json" \
http://localhost:5555/v1/services/haproxy/transactions?version=1

效果:

{"_version":1,"id":"1f9630d9-665d-43f8-8ad9-f15652fbfbbe","status":"in_progress"}

查询事物:

curl -X GET --user admin:dalong \
-H "Content-Type: application/json" \
"http://localhost:5555/v1/services/haproxy/transactions"

效果:

[{"_version":1,"id":"1f9630d9-665d-43f8-8ad9-f15652fbfbbe","status":"in_progress"}]

创建backend 服务:

curl -X POST --user admin:dalong \
-H "Content-Type: application/json" \
-d '{"name": "test_backend", "mode":"http", "balance": {"algorithm":"roundrobin"}, "httpchk": {"method": "HEAD", "uri": "/", "version": "HTTP/1.1"}}' \
"http://localhost:5555/v1/services/haproxy/configuration/backends?transaction_id=1f9630d9-665d-43f8-8ad9-f15652fbfbbe" 

效果:

{"balance":{"algorithm":"roundrobin","arguments":null},"httpchk":{"method":"HEAD","uri":"/","version":"HTTP/1.1"},"mode":"http","name":"test_backend"}

添加server 到backend 服务:

curl -X POST --user admin:dalong \
-H "Content-Type: application/json" \
-d '{"name": "server1", "address": "192.168.0.104", "port":8888, "check": "enabled", "maxconn": 30, "weight": 100}' \
"http://localhost:5555/v1/services/haproxy/configuration/servers?backend=test_backend&transaction_id=1f9630d9-665d-43f8-8ad9-f15652fbfbbe"

效果:

{"address":"192.168.0.104","check":"enabled","maxconn":30,"name":"server1","port":8888,"weight":100}

创建frontend 服务:

curl -X POST --user admin:dalong \
-H "Content-Type: application/json" \
-d '{"name": "test_frontend", "mode": "http", "default_backend": "test_backend", "maxconn": 2000}' \
"http://localhost:5555/v1/services/haproxy/configuration/frontends?transaction_id=1f9630d9-665d-43f8-8ad9-f15652fbfbbe"

效果:

{"default_backend":"test_backend","maxconn":2000,"mode":"http","name":"test_frontend"}

创建bind 服务:

curl -X POST --user admin:dalong \
-H "Content-Type: application/json" \
-d '{"name": "http", "address": "*", "port": 10080}' \
"http://localhost:5555/v1/services/haproxy/configuration/binds?frontend=test_frontend&transaction_id=1f9630d9-665d-43f8-8ad9-f15652fbfbbe"

效果:

{"address":"*","name":"http","port":10080}

应用变更:

curl -X PUT --user admin:dalong \
-H "Content-Type: application/json" \
"http://localhost:5555/v1/services/haproxy/transactions/1f9630d9-665d-43f8-8ad9-f15652fbfbbe"

效果:

{"_version":1,"id":"1f9630d9-665d-43f8-8ad9-f15652fbfbbe","status":"success"}
  • 修改的haproxy 配置文件

实际上我们应用变更之后,会生成新的配置文件
内容如下:

  • 启动demo backend 服务
 
live-server  --port=8888
  • 效果

live-server 服务:

haproxy 代理服务:

haproxy 监控服务:

prometheus metrics服务:

说明

以上是一个简单的操作,官方文档提供了比较全的说明,很值得看看,同时基于dataplaneapi 我们可以方便的 扩展haproxy

参考资料

https://www.haproxy.com/documentation/hapee/1-9r1/configuration/dataplaneapi/
https://www.haproxy.com/documentation/dataplaneapi/latest/
https://github.com/rongfengliang/haproxy2.0-prometheus

haproxy 2.0 dataplaneapi rest api 试用的更多相关文章

  1. haproxy 2.0 dataplaneapi rest api 转为graphql

    haproxy 2.0 dataplaneapi rest api 是比较全的,以下是一个简单的集成graphql,通过swagger-to-graphql 转换为graphql api 方便使用 环 ...

  2. haproxy 2.0 dataplaneapi rest api 几个方便的问题排查接口

    在使用haproxy 2.0 dataplaneapi的时候,刚开始的时候我们可能需要进行调试,保证我们的配置在我们的系统环境中 是可以使用的,以下是自己在当前学习中为了排查问题会使用的几个api 创 ...

  3. haproxy 2.0 dataplaneapi rest api 转为graphql docker 镜像

    为了方便直接使用haproxy dataplaneapi graphql 格式的查询,制作了一个简单的docker 镜像 基于dotenv 进行配置管理,可以直接通过环境变量传入参数,处理不同hapr ...

  4. haproxy 2.0 dataplaneapi docker 镜像

    为了方便测试dataplaneapi 基于官方的docker镜像,制作了一个简单的包含dataplaneapi 的镜像 下载dataplaneapi https://github.com/haprox ...

  5. haproxy 2.0 dataplaneapi 类似的工具haproxyadmin

    haproxyadmin 是一个python 的pip 包,提供了类似dataplaneapi 的功能,使用上也比较简单,同时提供的方法也比较全 使用的技术与dataplaneapi 基本类似,也是一 ...

  6. haproxy2.0 dataplaneapi 简单说明

    haproxy2.0 支持基于dataplaneapi 的haproxy 动态配置修改以及服务生效,早期大家为了动态 可以会基于dsn 的服务发现模式,基于confd 结合consul 动态生成配置并 ...

  7. 使用haproxy 2.0 prometheus metrics 监控系统状态

    haproxy 2.0 已经发布一段时间了,提供内部直接暴露的prometheus metrics 很方便 ,可以快速的监控系统的状态 以下是一个简单的demo 环境准备 docker-compose ...

  8. HAProxy 2.0 and Beyond

    转自:https://www.haproxy.com/blog/haproxy-2-0-and-beyond/  关于haproxy 2.0 的新特性说明 HAProxy Technologies i ...

  9. ElasticSearch 5.0.1 java API操作

    今天来说下使用ES 5.0.1的API来进行编码. 开始之前,简单说下5.0.1跟之前的几个变化.之前的ES自身是不支持delete-by-query的,也就是通过查询来删除,可以达到批量的效果,是因 ...

随机推荐

  1. 配置 Nginx 反向代理 WebSocket

    用Nginx给网站做反向代理和负载均衡是广泛使用的一种Web服务器部署技术.不仅能够保证后端服务器的隐蔽性,还可以提高网站部署灵活性. 今天我们来讲一下,如何用Nginx给WebSocket服务器实现 ...

  2. Java之利用Freemarker模板引擎实现代码生成器,提高效率

    https://blog.csdn.net/huangwenyi1010/article/details/71249258  java模板引擎freemarker代码生成器 更多 个人分类: 一步一步 ...

  3. C#使用表达式树动态调用方法并实现99乘法表

    我们在使用C#编程的时候,经常使用反射来动态调用方法,但有时候需要动态的生成方法,下面介绍使用表达式树的方式来自动生成方法,并调用. 首先需要说明什么是表达式,熟悉Linq的程序猿都用过类似于下面的代 ...

  4. 【翻译】nginx初学者指南

    nginx初学者指南 本文翻译自nginx官方网站:http://nginx.org/en/docs/beginners_guide.html#control 该指南会对nginx做一个简要的介绍,同 ...

  5. rsyslog详解实战和避坑

    目标是要把线上环境的debug日志及集中化收集起来,一方面是方便开发调试:一方面是避免直接到线上环境查看,存在安全隐患. 常用可选方案: rsyslog发送端 + rsyslog接收端: 直接存在接收 ...

  6. 31、splice()用法

    改变数组,向数组中添加/删除元素: eg: 1.删除元素: let arr=['bob','lily','bike','sam']; arr.splice(2,1) console.log(arr) ...

  7. Sping注解开发

    基本注解 @Configuration 作用: 标记在类上表示是一个配置类(相当于一个配置类) @Bean 作用: 在容器中放一个bean相当于xml文件里的bean标签 @Configuration ...

  8. VMware虚拟机文件夹中各文件作用详解

    虚拟机的文件管理由VMware Workstation来执行 一个虚拟机一般以一系列文件的形式储存在宿主机中,这些文件一般在由workstation为虚拟机所创建的那个目录中 这里列出了这些关键文件及 ...

  9. webdriver 属于selenium 体系中设计出来操作浏览器的一套API

    1.元素的定位   1.id属性定位 实例:   find_element_by_id("kw")  2.name属性定位,同id一样是属性值 实例:  find_element_ ...

  10. nginx 405错误

    nginx配置文件加上location / { try_files $uri $uri/ /index.php?$query_string; }