Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion README-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,43 @@ BFE的架构说明见[概览](docs/zh_cn/introduction/overview.md)文档

此外,我们也基于 BFE 实现了 [BFE Ingress Controller](https://github.com/bfenetworks/ingress-bfe),用于支持在 Kubernetes 中使用 Ingress


## 🚀 快速开始

快速开始面向想尽快跑起来的用户:先构建 Docker 镜像,再用 Kubernetes 示例快速部署。

### 1)构建 Docker 镜像

在仓库根目录执行:

```bash
make docker
```

说明:
- `make docker` 会构建 prod + debug 两个镜像,镜像 tag 来自 `VERSION` 文件。
- 如需自定义镜像名,可通过 `BFE_IMAGE_NAME` 覆盖,例如:

```bash
make docker BFE_IMAGE_NAME=your-registry/bfe
```

如果你希望 Kubernetes 部署使用你本地构建的镜像:需要将镜像推送到集群节点可访问的镜像仓库(或在本地集群中加载镜像),并在 `examples/kubernetes/kustomization.yaml` 的 `images:` 中将 bfe 镜像替换为你的镜像地址与 tag。

Docker 镜像的构建与推送(包含 `make docker-push`)详见:
- [docs/zh_cn/installation/install_using_docker.md](docs/zh_cn/installation/install_using_docker.md)

### 2)使用 Kubernetes 示例快速部署(kustomize)

```bash
cd examples/kubernetes
kubectl apply -k .
kubectl apply -f whoami-deploy.yaml
```

更多部署细节(包含镜像统一替换/mirror、初始化说明、清理与 finalizers 排障等)请参考:
- [examples/kubernetes/README-CN.md](examples/kubernetes/README-CN.md)

## 特性及优点

- 丰富协议支持:支持HTTP、HTTPS、SPDY、HTTP/2、WebSocket、TLS、gRPC、FastCGI等
Expand All @@ -50,7 +87,7 @@ BFE的架构说明见[概览](docs/zh_cn/introduction/overview.md)文档

- 数据平面:BFE核心转发引擎的[编译及运行](docs/zh_cn/installation/install_from_source.md)
- 控制平面:请参考控制平面的[部署说明](https://github.com/bfenetworks/api-server/blob/develop/docs/zh_cn/deploy.md)
- Kubernetes 部署示例(kustomize):[examples/kubernetes/README.md](examples/kubernetes/README.md)
- Kubernetes 部署示例(kustomize):[examples/kubernetes/README-CN.md](examples/kubernetes/README-CN.md)

## 运行测试

Expand Down
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,42 @@ Refer to [Overview](docs/en_us/introduction/overview.md) in BFE document for mor

Besides, we also implement [BFE Ingress Controller](https://github.com/bfenetworks/ingress-bfe) based on BFE, to fulfill Ingress in Kubernetes

## 🚀 Quick Start

This quick start is for users who want to get a running setup fast: build Docker images first, then deploy the Kubernetes example.

### 1) Build Docker images

From the repository root:

```bash
make docker
```

Notes:
- `make docker` builds both prod and debug images. Image tags are derived from the `VERSION` file.
- To override the image name, set `BFE_IMAGE_NAME`, for example:

```bash
make docker BFE_IMAGE_NAME=your-registry/bfe
```

If you want the Kubernetes deployment to use your locally built image, push it to a registry reachable by your cluster nodes (or load it into a local cluster), then update the bfe image mapping under `images:` in `examples/kubernetes/kustomization.yaml`.

For more details on building and pushing images (including `make docker-push`), see:
- [docs/en_us/installation/install_using_docker.md](docs/en_us/installation/install_using_docker.md)

### 2) Deploy via Kubernetes example (kustomize)

```bash
cd examples/kubernetes
kubectl apply -k .
kubectl apply -f whoami-deploy.yaml
```

For details (image mirror settings, initialization notes, cleanup and finalizer troubleshooting, etc.), see:
- [examples/kubernetes/README.md](examples/kubernetes/README.md)

## Advantages

- Multiple protocols supported, including HTTP, HTTPS, SPDY, HTTP2, WebSocket, TLS, FastCGI, etc.
Expand Down
8 changes: 8 additions & 0 deletions bfe_balance/backend/bfe_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

import (
"github.com/bfenetworks/bfe/bfe_config/bfe_cluster_conf/cluster_table_conf"
"github.com/bfenetworks/bfe/bfe_route/bfe_cluster"
)

// BfeBackend is a backend server.
Expand Down Expand Up @@ -219,3 +220,10 @@ func (back *BfeBackend) OnFail(cluster string) {
back.AddFailNum()
UpdateStatus(back, cluster)
}

func (back *BfeBackend) OnFailByCluster(cluster *bfe_cluster.BfeCluster) {
if cluster.DisableHealthCheck {
return
}
back.OnFail(cluster.Name)
}
13 changes: 13 additions & 0 deletions bfe_config/bfe_cluster_conf/cluster_conf/cluster_conf_load.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ type ClusterBasicConf struct {
ReqFlushInterval *int // interval to flush request in ms. if zero, disable periodic flush
ResFlushInterval *int // interval to flush response in ms. if zero, disable periodic flush
CancelOnClientClose *bool // cancel blocking operation on server if client connection disconnected

DisableHostHeader *bool // disable host header when forward to backend
DisableHealthCheck *bool // disable health check for backend
}

// ClusterConf is conf of cluster.
Expand Down Expand Up @@ -630,6 +633,16 @@ func ClusterBasicConfCheck(conf *ClusterBasicConf) error {
conf.CancelOnClientClose = &cancelOnClientClose
}

if conf.DisableHostHeader == nil {
disableHostHeader := false
conf.DisableHostHeader = &disableHostHeader
}

if conf.DisableHealthCheck == nil {
disableHealthCheck := false
conf.DisableHealthCheck = &disableHealthCheck
}

return nil
}

Expand Down
10 changes: 9 additions & 1 deletion bfe_http/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,15 @@ func (b *bytes_body) SetBytes(newBuf []byte, all bool) {
}
}

func NewBytesBody(src io.ReadCloser, maxSize int64) (*bytes_body, error) {
func NewBytesBody(src io.ReadCloser, maxSize int64) (io.ReadCloser, error) {
b, err := newBytesBody(src, maxSize)
if b == nil {
return nil, err
}
return b, err
}

func newBytesBody(src io.ReadCloser, maxSize int64) (*bytes_body, error) {
bb, err := io.ReadAll(io.LimitReader(src, maxSize))
if err != nil {
return nil, fmt.Errorf("io.ReadAll: %s", err.Error())
Expand Down
33 changes: 13 additions & 20 deletions bfe_http/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -604,35 +604,23 @@ func (t *Transport) dialConn(cm *connectMethod) (*persistConn, error) {
// Initiate TLS and check remote host name against certificate.
cfg := t.TLSClientConfig
if cfg == nil || cfg.ServerName == "" {
//host := cm.tlsHost()
var (
host string
rootCAs *x509.CertPool = nil
certs []bfe_tls.Certificate = nil
cert bfe_tls.Certificate
httpsConf = t.HttpsConf
)
if httpsConf.RSInsecureSkipVerify == nil || !*httpsConf.RSInsecureSkipVerify {

// if the host has port, only use the hostname
host = cm.targetHost
if hasPort(host) {
host = host[:strings.LastIndex(host, ":")]
}

if httpsConf.RSHost != nil && *httpsConf.RSHost != "" {
host = *httpsConf.RSHost
}
rootCAs, err = httpsConf.GetRSCAList()
if err != nil {
log.Logger.Debug("debug_https get_cas err=%s", err.Error())
return nil, err
}
}
if cert, err = httpsConf.GetBFECert(); err == nil {
certs = []bfe_tls.Certificate{cert}
if httpsConf.RSHost != nil && *httpsConf.RSHost != "" {
host = *httpsConf.RSHost
} else {
host = cm.tlsHost()
}

if cfg == nil {
if cert, err = httpsConf.GetBFECert(); err == nil {
certs = []bfe_tls.Certificate{cert}
}
if httpsConf.RSInsecureSkipVerify != nil && *httpsConf.RSInsecureSkipVerify {
// should skip Insecure Verify
cfg = &bfe_tls.Config{
Expand All @@ -641,6 +629,11 @@ func (t *Transport) dialConn(cm *connectMethod) (*persistConn, error) {
ServerName: host,
}
} else {
rootCAs, err = httpsConf.GetRSCAList()
if err != nil {
log.Logger.Debug("debug_https get_cas err=%s", err.Error())
return nil, err
}
// do Insecure Verify
if rootCAs == nil {
// use system cas
Expand Down
6 changes: 6 additions & 0 deletions bfe_route/bfe_cluster/bfe_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ type BfeCluster struct {
reqFlushInterval time.Duration // interval to flush request
resFlushInterval time.Duration // interval to flush response
cancelOnClientClose bool // cancel blocking operation in server if client conn gone

DisableHostHeader bool // disable setting host header for backend
DisableHealthCheck bool // disable health check for backend
}

func NewBfeCluster(name string) *BfeCluster {
Expand Down Expand Up @@ -75,6 +78,9 @@ func (cluster *BfeCluster) BasicInit(clusterConf cluster_conf.ClusterConf) {
time.Duration(*clusterConf.ClusterBasic.ResFlushInterval) * time.Millisecond
cluster.cancelOnClientClose = *clusterConf.ClusterBasic.CancelOnClientClose

cluster.DisableHostHeader = *clusterConf.ClusterBasic.DisableHostHeader
cluster.DisableHealthCheck = *clusterConf.ClusterBasic.DisableHealthCheck

log.Logger.Info("cluster %s init success", cluster.Name)
}

Expand Down
15 changes: 10 additions & 5 deletions bfe_server/reverseproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ func (p *ReverseProxy) clusterInvoke(srv *BfeServer, cluster *bfe_cluster.BfeClu

if err == nil {
if checkBackendStatus(cluster.OutlierDetectionHttpCode(), res.StatusCode) {
backend.OnFail(cluster.Name)
backend.OnFailByCluster(cluster)
} else {
backend.OnSuccess()
}
Expand Down Expand Up @@ -437,7 +437,7 @@ func (p *ReverseProxy) clusterInvoke(srv *BfeServer, cluster *bfe_cluster.BfeClu
request.ErrMsg = err.Error()
p.proxyState.ErrBkConnectBackend.Inc(1)
allowRetry = true
backend.OnFail(cluster.Name)
backend.OnFailByCluster(cluster)

case bfe_http.WriteRequestError, bfe_fcgi.WriteRequestError:
request.ErrCode = bfe_basic.ErrBkWriteRequest
Expand All @@ -448,22 +448,22 @@ func (p *ReverseProxy) clusterInvoke(srv *BfeServer, cluster *bfe_cluster.BfeClu
// if error is caused by backend server
rerr := err.(bfe_http.WriteRequestError)
if !rerr.CheckTargetError(request.RemoteAddr) {
backend.OnFail(cluster.Name)
backend.OnFailByCluster(cluster)
}

case bfe_http.ReadRespHeaderError, bfe_fcgi.ReadRespHeaderError:
request.ErrCode = bfe_basic.ErrBkReadRespHeader
request.ErrMsg = err.Error()
p.proxyState.ErrBkReadRespHeader.Inc(1)
allowRetry = checkAllowRetry(cluster.RetryLevel(), outreq)
backend.OnFail(cluster.Name)
backend.OnFailByCluster(cluster)

case bfe_http.RespHeaderTimeoutError:
request.ErrCode = bfe_basic.ErrBkRespHeaderTimeout
request.ErrMsg = err.Error()
p.proxyState.ErrBkRespHeaderTimeout.Inc(1)
allowRetry = checkAllowRetry(cluster.RetryLevel(), outreq)
backend.OnFail(cluster.Name)
backend.OnFailByCluster(cluster)

case bfe_http.TransportBrokenError:
request.ErrCode = bfe_basic.ErrBkTransportBroken
Expand Down Expand Up @@ -797,6 +797,11 @@ func (p *ReverseProxy) ServeHTTP(rw bfe_http.ResponseWriter, basicReq *bfe_basic
// remove hop-by-hop headers
hopByHopHeaderRemove(outreq, req)

if cluster.DisableHostHeader {
// if cluster.DisableHostHeader is true, del outreq.Host
outreq.Host = ""
}

if cluster.AIConf != nil {
// if cluster has AIConf, do model mapping & set api key in outreq
if cluster.AIConf.Key != nil {
Expand Down
Loading