介绍
官网地址:https://higress.io/zh-cn/
以开源Istio与Envoy为核心构建的一个遵循开源Ingress/Gateway API标准,提供实现了安全防护网关、流量网关、微服务网关三层网关合一的高集成、易使用、易扩展、热更新的下一代云原生网关。
使用场景
- Kubernetes Ingress 网关:
Higress 可以作为 K8s 集群的 Ingress 入口网关, 并且兼容了大量 K8s Nginx Ingress 的注解,可以从 K8s Nginx Ingress 快速平滑迁移到 Higress。
支持 Gateway API 标准,支持用户从 Ingress API 平滑迁移到 Gateway API。 - 微服务网关:
Higress 可以作为微服务网关, 能够对接多种类型的注册中心发现服务配置路由,例如 Nacos, ZooKeeper, Consul, Eureka 等。
并且深度集成了 Dubbo, Nacos, Sentinel 等微服务技术栈,基于 Envoy C++ 网关内核的出色性能,相比传统 Java 类微服务网关,可以显著降低资源使用率,减少成本。 - 安全防护网关:
Higress 可以作为安全防护网关, 提供 WAF 的能力,并且支持多种认证鉴权策略,例如 key-auth, hmac-auth, jwt-auth, basic-auth, oidc 等。
核心优势
- 生产等级
脱胎于阿里巴巴2年多生产验证的内部产品,支持每秒请求量达数十万级的大规模场景。
彻底摆脱 reload 引起的流量抖动,配置变更毫秒级生效且业务无感。 - 平滑演进
支持 Nacos/Zookeeper/Eureka 等多种注册中心,可以不依赖 K8s Service 进行服务发现,支持非容器架构平滑演进到云原生架构。
支持从 Nginx Ingress Controller 平滑迁移,支持平滑过渡到 Gateway API,支持业务架构平滑演进到 ServiceMesh。 - 兼收并蓄
兼容 Nginx Ingress Annotation 80%+ 的使用场景,且提供功能更丰富的 Higress Annotation 注解。
兼容 Ingress API/Gateway API/Istio API,可以组合多种 CRD 实现流量精细化管理。 - 便于扩展
提供 Wasm、Lua、进程外三种插件扩展机制,支持多语言编写插件,生效粒度支持全局级、域名级,路由级。
插件支持热更新,变更插件逻辑和配置都对流量无损。
和ingress nginx的对比:
安装
Higress 默认只会监听 IngressClassName 为 higress 的 Ingress。可以通过 helm 参数设置 –set global.ingressClass="",这样 Higress 会监听所有 Ingress,从而实现平滑迁移。
# 添加Higress的官方helm仓库
helm repo add higress.io https://higress.io/helm-charts
# 安装Higress
helm install higress higress.io/higress -n higress-system --create-namespace --render-subchart-notes --set global.ingressClass=nginx --set higress-console.domain=console.higress.io
我这里higress-gateway卡在了ContainerCreating,查看日志报错:"Failed to create pod sandbox: rpc error: code = Unknown desc = failed to create containerd task: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: open /proc/sys/net/ipv4/ip_unprivileged_port_start: no such file or directory: unknown"
issue中也有这个:https://github.com/alibaba/higress/issues/97
我的内核版本是3.10,k8s版本是1.22.3,网上搜了一下说是要升级内核或者降级k8s。查看5.4版本内核确实有这个文件。
升级内核,我这里升级的版本是5.4.205,其他版本暂未测试。
rpm -ivh kernel-lt-5.4.205-1.el7.elrepo.x86_64.rpm
grub2-set-default 0
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot
再次安装,pod全部正常启动。
访问
输出中显示了hingress console的用户名密码
export ADMIN_USERNAME=$(kubectl get secret --namespace higress-system higress-console -o jsonpath="{.data.adminUsername}" | base64 -d)
export ADMIN_PASSWORD=$(kubectl get secret --namespace higress-system higress-console -o jsonpath="{.data.adminPassword}" | base64 -d)
echo -e "Username: ${ADMIN_USERNAME}\nPassword: ${ADMIN_PASSWORD}"
我这里没有loadbalancer,所以直接改为NodePort.
k edit svc -n higress-system higress-gateway
k get svc -n higress-system higress-gateway
访问console,添加本地hosts,http://console.higress.io:32327/
测试
创建测试服务
kind: Pod
apiVersion: v1
metadata:
name: foo-app
labels:
app: foo
spec:
containers:
- name: foo-app
image: higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/http-echo:0.2.4-alpine
args:
- "-text=foo"
---
kind: Service
apiVersion: v1
metadata:
name: foo-service
spec:
selector:
app: foo
ports:
# Default port used by the image
- port: 5678
创建域名
点击左侧“域名管理”导航栏,然后点击页面右侧的“创建域名”按钮。按照下图所示内容填写表单并点击“确定”按钮。
创建路由
点击左侧“路由配置”导航栏,然后点击页面右侧的“创建路由”按钮。按照下图片所示内容填写表单并点击“确定”按钮。其中域名和目标服务都可以下拉选择,无需手动输入。
测试访问
访问失败
使用ip+端口可以正常访问。
查看ingress,address中ip为空
重新安装
查看官方文档,可以设置这个参数--set enableStatus=true
,来实现将入口IP写入Ingress的status。
使用本地安装,开启监控,设置密码为admin,监听ingressClass为nginx的ingress。
helm uninstall higress -n higress-system
helm install higress -n higress-system higress.io/higress --create-namespace --render-subchart-notes --set global.kind=true --set higress-console.o11y.enabled=true --set higress-controller.domain=console.higress.io --set higress-console.admin.password.value=admin --set ingressClass=nginx --set enableStatus=true
部署后grafana和prometheus会处于pending状态,因为pvc处于pending。
查看template文件中的pvc配置,没有设置storageclas的地方。
导出yaml,设置storageclass,删除原pvc,再次部署即可。
如果集群中已经部署了nginx ingress,higress-gateway也会处于pending状态,报错1 node(s) didn't have free ports for the requested pod ports
这是因为higress-gateway容器使用了80,443的主机端口,而这两个端口已经被nginx ingress占用。
修改ingress ds和svc的端口配置
higress-gateway pod正常启动。
再次访问
路由可以正常工作。
curl http://172.16.255.183/foo -H 'host: foo.bar.com'
查看监控
当然,你也可以对接已有的 Prometheus&Grafana,使用这份Higress官方提供的Dashboard配置即可:https://higress.io/grafana/dashboard.json
开启插件
这是官方提供的插件:https://github.com/alibaba/higress/tree/main/plugins
这里以request_block插件为例,request-block插件实现了基于URL、请求头等特征屏蔽HTTP请求,可以用于防护部分站点资源不对外部暴露。
https://github.com/alibaba/higress/tree/main/plugins/wasm-cpp/extensions/request_block
cat request_block.yaml
apiVersion: extensions.higress.io/v1alpha1
kind: WasmPlugin
metadata:
name: request-block
namespace: higress-system
spec:
defaultConfig:
block_urls:
- "swagger.html"
- foo=bar
- foo
block_headers:
- example-key
- example-value
- foo.bar.com
block_bodies:
- "hello world"
case_sensitive: false
url: oci://higress-registry.cn-hangzhou.cr.aliyuncs.com/plugins/request-block:1.0.0
k apply -f request-block.yaml
k get wasmplugins -n higress-system
屏蔽请求url路径
根据该配置,下列请求将被禁止访问:
curl http://example.com?foo=bar
curl http://exmaple.com/Swagger.html
屏蔽请求header
根据该配置,下列请求将被禁止访问:
curl http://example.com -H 'example-key: 123'
curl http://exmaple.com -H 'my-header: example-value'
屏蔽请求body
根据该配置,下列请求将被禁止访问:
curl http://example.com -d 'Hello World'
curl http://exmaple.com -d 'hello world'
对特定路由或域名开启
# 使用 _rules_ 字段进行细粒度规则配置
_rules_:
# 规则一:按路由名称匹配生效
- _match_route_:
- route-a
- route-b
block_bodies:
- "hello world"
# 规则二:按域名匹配生效
- _match_domain_:
- "*.example.com"
- test.com
block_urls:
- "swagger.html"
block_bodies:
- "hello world"
此例 _matchroute 中指定的 route-a 和 route-b 即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将使用此段配置; 此例 _matchdomain 中指定的 *.example.com 和 test.com 用于匹配请求的域名,当发现域名匹配时,将使用此段配置; 配置的匹配生效顺序,将按照 rules 下规则的排列顺序,匹配第一个规则后生效对应配置,后续规则将被忽略。
请求Body大小限制
当配置了 block_bodies 时,仅支持小于 32 MB 的请求 Body 进行匹配。若请求 Body 大于此限制,并且不存在匹配到的 block_urls 和 block_headers 项时,不会对该请求执行屏蔽操作。
当配置了 block_bodies 时,若请求 Body 超过全局配置 DownstreamConnectionBufferLimits,将返回 413 Payload Too Large。
curl http://172.16.255.183/foo
curl http://172.16.255.183/foo -H 'host: foo.bar.com'
curl http://172.16.255.183?foo=bar
curl http://172.16.255.183/Swagger.html
curl http://10.107.33.216:5678
curl http://10.107.33.216:5678/foo -H 'host: foo.bar.com'
k delete -f request-block.yaml
测试在开启request_block插件后,再次访问foo.bar.com
返回为空。关闭后恢复访问。
其他
开启强制 HTTPS 访问
在 higress-system 命名空间下先创建好 TLS 证书和私钥对应的 secret
apiVersion: v1
kind: Secret
type: kubernetes.io/tls
data:
tls.crt: -----BEGIN CERTIFICATE-----...
tls.key: -----BEGIN RSA PRIVATE KEY-----...
metadata:
name: my-tls-secret
namespace: higress-system
helm upgrade higress -n higress-system higress.io/higress --set higress-console.tlsSecretName=my-tls-secret
支持Istio CRD
集群里需要提前安装好 Istio 的 CRD,如果不希望安装 Istio,也可以只安装 Istio 的 CRD:
helm repo add istio https://istio-release.storage.googleapis.com/charts
helm install istio-base istio/base -n istio-system
helm upgrade higress -n higress-system --set global.enableIstioAPI=true higress.io/higress