前边有简单说过基于go-swagger 生成haproxy dataplaneapi api 以下一个简单说明
环境准备
- 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:
build: ./
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 dockerfile
基于haproxy 团队的docker镜像(内置了dataplaneapi)
FROM haproxytech/haproxy-debian:2.2.1
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
- demo haproxy 配置
global
user root
group root
master-worker
stats socket /run/haproxy.sock mode 600 level admin
stats timeout 2m
log stdout local0
mworker-max-reloads 3
set-dumpable
defaults
mode http
log global
option httplog
option redispatch
timeout connect 5s
timeout client 5s
timeout server 5s
userlist api
user admin insecure-password dalong
resolvers dns
hold nx 30s
hold obsolete 30s
hold other 30s
hold refused 30s
hold timeout 30s
hold valid 10s
timeout resolve 1s
timeout retry 1s
resolve_retries 3
parse-resolv-conf
frontend stats
bind *:8404
stats enable
stats uri /stats
stats refresh 10s
http-request use-service prometheus-exporter if { path /metrics }
frontend test_frontend
mode http
maxconn 2000
bind *:10080 name http
default_backend test_backend
backend be_503
errorfile 503 /usr/local/etc/haproxy/errors/503.http
backend test_backend
mode http
balance roundrobin
server server1 nginx1:80 check maxconn 30 weight 100
program dataplane-api
command /usr/bin/dataplaneapi --log-level=debug --host 0.0.0.0 --port 5555 --haproxy-bin /usr/sbin/haproxy --config-file /usr/local/etc/haproxy/haproxy.cfg --reload-cmd "kill -SIGUSR2 1" --restart-cmd="" --reload-delay 5 --userlist=api
no option start-on-reload
- 启动效果
会有一个示例demo,以下是stat 界面
代码集成
以下是一个简单的代码集成,具体操作处理流程我有写过,可以参考 https://www.cnblogs.com/rongfengliang/p/12914925.html
package main
import (
"context"
"log"
httptransport "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/rongfengliang/haproxy-golang/client"
"github.com/rongfengliang/haproxy-golang/client/backend"
"github.com/rongfengliang/haproxy-golang/client/bind"
"github.com/rongfengliang/haproxy-golang/client/frontend"
"github.com/rongfengliang/haproxy-golang/client/server"
"github.com/rongfengliang/haproxy-golang/client/transactions"
"github.com/rongfengliang/haproxy-golang/models"
)
// String point
func String(s string) *string {
return &s
}
// Bool point
func Bool(s bool) *bool {
return &s
}
// Int64 point
func Int64(s int64) *int64 {
return &s
}
func main() {
// context object for control connet
ctx := context.Background()
// 1. first get transaction version
client := client.New(httptransport.New("localhost:5555", "/v2", []string{"http"}), strfmt.Default)
// make the authenticated request to get all items
basicAuth := httptransport.BasicAuth("admin", "dalong")
frontends, err := client.Frontend.GetFrontends(nil, basicAuth)
if err != nil {
log.Panicln("some wrong:", err)
}
versionID := frontends.ConfigurationVersion
log.Println(versionID)
// for test print frontend info
for _, frontend := range frontends.GetPayload().Data {
log.Println("get frontend info :", frontend.Name, frontend.Mode, frontend.DefaultBackend)
}
// 2. create transaction for generate id
commitTransaction, err := client.Transactions.StartTransaction(&transactions.StartTransactionParams{Version: versionID, Context: ctx}, basicAuth)
if err != nil {
log.Panicln("create transaction some wrong:", err.Error())
}
transactionID := commitTransaction.Payload.ID
log.Println(transactionID)
// 3. create backend object
createBackendCreated, createBackendAccepted, err := client.Backend.CreateBackend(&backend.CreateBackendParams{
Context: ctx,
Data: &models.Backend{
Name: "dalongrong",
Mode: "http",
Balance: &models.Balance{
Algorithm: String("roundrobin"),
},
Httpchk: &models.Httpchk{
Method: "HEAD",
URI: "/",
Version: "HTTP/1.1",
},
},
TransactionID: &transactionID,
}, basicAuth)
if err != nil {
log.Panicln("create backend some wrong:", err.Error())
}
if createBackendCreated == nil {
log.Println(createBackendAccepted.GetPayload())
}
// 4. add backend server to backend use create server wrapper
createServerCreated, createServerAccepted, err := client.Server.CreateServer(&server.CreateServerParams{
TransactionID: &transactionID,
Backend: "dalongrong",
Context: ctx,
Data: &models.Server{
Name: "server1",
Address: "nginx2",
Port: Int64(80),
Check: "disabled",
Maxconn: Int64(30),
Weight: Int64(100),
},
}, basicAuth)
if err != nil {
log.Panicln("add backend server has some wrong:", err.Error())
}
if createServerCreated == nil {
log.Println(createServerAccepted.GetPayload())
}
// 5. create frontend
createFrontendCreated, createFrontendAccepted, err := client.Frontend.CreateFrontend(&frontend.CreateFrontendParams{
TransactionID: &transactionID,
Data: &models.Frontend{
Name: "dalongrong_frontend",
Mode: "http",
DefaultBackend: "dalongrong",
Maxconn: Int64(1000),
},
Context: ctx,
}, basicAuth)
if err != nil {
log.Panicln("create frontend has some wrong:", err.Error())
}
if createFrontendCreated == nil {
log.Println(createFrontendAccepted.GetPayload())
}
// 6. create frontend && backend bind
createBindCreated, createBindAccepted, err := client.Bind.CreateBind(&bind.CreateBindParams{
TransactionID: &transactionID,
Frontend: "dalongrong_frontend",
Data: &models.Bind{
Name: "httpdemo",
Address: "*",
Port: Int64(9000),
},
Context: ctx,
}, basicAuth)
if err != nil {
log.Panicln("create bind has some wrong:", err.Error())
}
if createBindCreated == nil {
log.Println(createBindAccepted.GetPayload())
}
// 7. apply transaction && do commit
commitTransactionOK, commitTransactionAccepted, err := client.Transactions.CommitTransaction(&transactions.CommitTransactionParams{
ID: transactionID,
Context: ctx,
}, basicAuth)
if err != nil {
log.Panicln("apply haproxy config has some wrong:", err.Error())
}
if commitTransactionOK != nil {
// apply config ok
log.Println(commitTransactionOK.GetPayload())
}
if commitTransactionAccepted != nil {
// accept but not apply success
log.Println(commitTransactionAccepted.GetPayload())
}
}
- 运行
go run main.go
- 效果
说明
以上是一个简单的使用说明,实际上我们基于swagger api 也可以提供其他语言的支持(nodejs,golang)同时也可以制作一个dashboard,当然新版本对于
haproxy 配置的更新处理使用了一个原子操作的 renameio,简化了以前配置reload 的处理
参考资料
https://hub.docker.com/r/haproxytech/haproxy-debian
https://github.com/rongfengliang/haproxy-dataplaneapi-golang
https://github.com/haproxytech/dataplaneapi
https://github.com/google/renameio