1.ingress.class示例
通過ingress.class方式暴露服務
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: apisix-dashboard
annotations:
kubernetes.io/ingress.class: apisix
spec:
rules:
- host: apisix-dashboard.example.com
http:
paths:
- backend:
serviceName: apisix-dashboard
servicePort: 80
path: /*
pathType: Prefix
首先確定apifix-ingress-controller配置文件中ingress_class的值绣版, 默認為apisix
注意如果要匹配跟下面的所有路徑,需要將path配置為/*
, 也可以配置pathType: Prefix
會創(chuàng)建/
/*
兩個路徑 其它的用法完全符合ingress的默認配置碉纺,annotation可配置參數(shù)參考官方文檔
2.crd基礎示例
2.1.ApisixRoute基本用法
先在集群中部署httpbin服務
kubectl run httpbin --image kennethreitz/httpbin --port 80
kubectl expose pod httpbin --port 80
創(chuàng)建httpbin-route.yaml文件挽拂,內(nèi)容如下:
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: rule1
match:
hosts:
- httpbin.example.com
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 80
可以使用兩種路徑類型prefix驹暑、exact,默認為exact,如果prefix需要,只需附加一個扒腕,例如擂达,/id/匹配前綴為 的所有路徑/id/土铺。
測試過程如下:
? ~ curl -H "Host: httpbin.example.com" http://internal/headers/ -v
* Trying internal...
* TCP_NODELAY set
* Connected to internal (internal) port 80 (#0)
> GET / HTTP/1.1
> Host: httpbin.example.com
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=utf-8
< Content-Length: 9593
< Connection: keep-alive
< Date: Tue, 16 Aug 2022 09:07:36 GMT
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
< Server: APISIX/2.15.0
2.2.ApisixTls基本用法
ApisixTls主要用來維護https證書
需要先創(chuàng)建tls secret
kubectl -n kube-system create secret tls traefik-ui-tls-cert --key=tls.key --cert=tls.crt
創(chuàng)建httpbin-tls.yaml文件,內(nèi)容如下:
apiVersion: apisix.apache.org/v2
kind: ApisixTls
metadata:
name: wildcard.example.com-ApisixTls
spec:
hosts:
- "*.example.com"
secret:
name: wildcard.example.com-tls-secret
namespace: ingress-apisix
通過該方式創(chuàng)建的ssl證書板鬓,對apisix全局服務都有效悲敷,apisix會根據(jù)請求域名動態(tài)選擇
2.3.ApisixUpstream基本用法
ApisixUpstream 需要配置成和Kubernetes Service相同的名字,通過添加負載均衡俭令、健康檢查后德、重試、超時參數(shù)等使 Kubernetes Service 更加豐富抄腔。
如果不使用ApisixUpstream探遵,則loadbalancer的類型為roundrobin
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
name: httpbin
spec:
loadbalancer:
type: ewma
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
spec:
selector:
app: httpbin
ports:
- name: http
port: 80
targetPort: 8080
其中l(wèi)oadbalancer支持如下四種類型
Round robin: 輪詢,配置為
type: roundrobin
Least loaded: 最小鏈接,配置為
type: least_conn
Peak EWMA: 維護每個副本往返時間的移動平均值妓柜,按未完成請求的數(shù)量加權箱季,并將流量分配到成本函數(shù)最小的副本。配置為
type: ewma
chash: 一致性哈希 配置為
type: chash
3.ApisixRoute使用進階
3.1.ApisixRoute配置多個域名和路徑
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: rule1
match:
hosts:
- local.example.com
- local01.example.com
paths:
- /*
- /api
backends:
- serviceName: httpbin
servicePort: 80
3.2.路徑/api
特殊配制棍掐,路徑/
無特殊配制
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: httpserver-route
match:
hosts:
- local.example.com
paths:
- /api*
backends:
- serviceName: httpbin
servicePort: 8000
plugins:
- name: proxy-rewrite
enable: true
config:
regex_uri: ["^/api(/|$)(.*)", "/$2"]
- name: default-route
match:
hosts:
- local.example.com
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 8000
apisix中會創(chuàng)建兩個route藏雏,分別是httpserver-route 和 default-route
3.3.ApisixRoute添加插件
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpbin-route
spec:
http:
- name: httpbin
match:
hosts:
- local.httpbin.org
paths:
- /*
backends:
- serviceName: foo
servicePort: 80
plugins:
- name: gzip
enable: true
3.4.HTTP強跳HTTPS
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: httpserver-route
match:
hosts:
- local.example.com
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 8000
plugins:
- name: redirect
enable: true
config:
http_to_https: true
3.5.域名跳轉
local.example.com跳轉到local01.example.com
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: httpserver-route
match:
hosts:
- local.example.com
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 8000
plugins:
- name: redirect
enable: true
config:
uri: "https://local01.example.com$request_uri"
3.6.rewrite路徑跳轉
3.6.1./api/header 轉/header
方法一: 使用redirect插件,頁面會發(fā)生302跳轉
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: httpserver-route
match:
hosts:
- local.example.com
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 8000
plugins:
- name: redirect
enable: true
config:
regex_uri: ["^/api(/|$)(.*)", "/$2"]
方法二: 使用proxy-rewrite 插件,頁面不會302跳轉
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: httpserver-route
match:
hosts:
- local.example.com
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 8000
plugins:
- name: proxy-rewrite
enable: true
config:
regex_uri: ["^/api(/|$)(.*)", "/$2"]
3.6.2./header轉/api/header
使用proxy-rewrite 插件掘殴,頁面不會302跳轉
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: httpserver-route
match:
hosts:
- local.example.com
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 8000
plugins:
- name: proxy-rewrite
enable: true
config:
uri: /api/$uri
3.7.基于用戶名和密碼的認證**
basix-auth插件需要與 Consumer 一起使用才能實現(xiàn)該功能赚瘦。 開啟認證的apisixroute會自動匹配用戶名
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: httpserver-basicauth
spec:
authParameter:
basicAuth:
value:
username: admin
password: admin
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: httpserver-route
match:
hosts:
- local.example.com
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 8000
authentication:
enable: true
type: basicAuth
測試:
curl -i -uadmin:admin https://local.example.com/
3.8.基于apikey的認證
key-auth插件需要與 Consumer 一起使用才能實現(xiàn)該功能。 開啟認證的apisixroute會自動匹配key
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: httpserver-basicauth
spec:
authParameter:
keyAuth:
value:
key: admin
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: httpserver-route
match:
hosts:
- local.example.com
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 8000
authentication:
enable: true
type: keyAuth
測試:
curl -H 'apikey:admin' https://local.example.com/
3.9.限制站點的用戶名和密碼
通過3.6.基于用戶名和密碼的認證和3.7.基于apikey的說法奏寨,有沒有辦法用戶名和密碼只針對一個站點生效, 創(chuàng)建兩個consumer起意,分別是admin01和宮秀德,只允許admin可以進行認證病瞳。
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: httpserver-basicauth-admin
spec:
authParameter:
basicAuth:
value:
username: admin
password: admin
---
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: httpserver-basicauth-admin01
spec:
authParameter:
basicAuth:
value:
username: admin01
password: admin01
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: httpserver-route
match:
hosts:
- local.example.com
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 8000
plugins:
- name: consumer-restriction
enable: true
config:
whitelist:
- ingress_apisix_httpserver_basicauth_admin
authentication:
enable: true
type: basicAuth
httpserver-basicauth-admin需要添加ingress-controller添加的默認前綴ingress_apisix揽咕,否則會報403,所以全名為ingress_apisix_httpserver_basicauth_admin
測試admin01訪問
> curl -i -uadmin01:admin01 https://local.example.com/
HTTP/2 403
date: Tue, 30 Aug 2022 08:00:04 GMT
content-type: text/plain; charset=utf-8
server: APISIX/2.15.0
{"message":"The consumer_name is forbidden."}
測試admin訪問
curl -i -uadmin:admin https://local.example.com/
HTTP/2 200
content-type: text/html; charset=utf-8
content-length: 615
date: Tue, 30 Aug 2022 07:55:55 GMT
last-modified: Wed, 25 May 2022 10:01:40 GMT
etag: "628dfe84-267"
accept-ranges: bytes
server: APISIX/2.15.0
.........
3.10.基于IP的白名單配置
ip-restriction插件實現(xiàn)該功能, 只允許10.10.50.207
10.0.0.0/16
訪問站點
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: httpserver-route
match:
hosts:
- local.example.com
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 8000
plugins:
- name: ip-restriction
enable: true
config:
whitelist:
- 10.10.50.207
- 10.0.0.0/16
白名單中地址測試正常打開頁面
非白名單地址測試
> curl https://local.example.com/
{"message":"Your IP address is not allowed"}
3.11.基于IP的黑名單限制
ip-restriction插件實現(xiàn)該功能, 不允許10.10.50.207
訪問站點
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: httpserver-route
match:
hosts:
- local.example.com
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 8000
plugins:
- name: ip-restriction
enable: true
config:
blacklist:
- 10.10.50.207
測試
> curl https://local.example.com/
{"message":"Your IP address is not allowed"}
3.12.添加自定義配置
4.灰度發(fā)布
4.1.準備環(huán)境
4.1.1.stable版本
# vim s1-stable.yaml
---
apiVersion: v1
kind: Service
metadata:
name: myapp-stable-service
namespace: default
spec:
ports:
- port: 80
targetPort: 80
name: http-port
selector:
app: myapp
version: stable
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-stable
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: myapp
version: stable
template:
metadata:
labels:
app: myapp
version: stable
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/public-registry-fzh/myapp:v1
imagePullPolicy: IfNotPresent
name: myapp-stable
ports:
- name: http-port
containerPort: 80
env:
- name: APP_ENV
value: stable
4.1.2.canary版本
# vim s2-canary.yaml
---
apiVersion: v1
kind: Service
metadata:
name: myapp-canary-service
namespace: canary
spec:
ports:
- port: 80
targetPort: 80
name: http-port
selector:
app: myapp
version: canary
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-canary
namespace: canary
spec:
replicas: 1
selector:
matchLabels:
app: myapp
version: canary
template:
metadata:
labels:
app: myapp
version: canary
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/public-registry-fzh/myapp:v2
imagePullPolicy: IfNotPresent
name: myapp-canary
ports:
- name: http-port
containerPort: 80
env:
- name: APP_ENV
value: canary
4.2.基于weight分流
# vim s3-apisixroute-weight.yaml
---
apiVersion: apisix.apache.org/v2beta3
kind: ApisixRoute
metadata:
name: myapp-canary-apisixroute
namespace: canary
spec:
http:
- name: myapp-canary-rule
match:
hosts:
- myapp.example.com
paths:
- /
backends:
- serviceName: myapp-stable-service
servicePort: 80
weight: 10
- serviceName: myapp-canary-service
servicePort: 80
weight: 1
創(chuàng)建服務和路由等
? kubectl apply -f ./
service/myapp-stable-service unchanged
deployment.apps/myapp-stable unchanged
service/myapp-canary-service unchanged
deployment.apps/myapp-canary unchanged
apisixroute.apisix.apache.org/myapp-canary-apisixroute unchanged
? kubectl get pods -n canary
NAME READY STATUS RESTARTS AGE
myapp-canary-9ff4c55f9-ndjrs 1/1 Running 0 15s
myapp-stable-5fdf6bd75-sq8df 1/1 Running 0 75s
? kubectl get apisixroute -n canary
NAME HOSTS URIS AGE
myapp-canary-apisixroute [myapp.example.com] [/] 97s
測試weight灰度
Stable和 Canary 的比例約為10:1
~ for i in `seq 30`;do curl https://myapp.example.com;done
myapp:v1
myapp:v1
.......
myapp:v2
myapp:v1
myapp:v1
myapp:v2
myapp:v1
myapp:v1
myapp:v1
.......
myapp:v1
myapp:v1
myapp:v2
myapp:v1
myapp:v1
myapp:v2
4.3.基于優(yōu)先級分流
# vim s4-priority.yaml
apiVersion: apisix.apache.org/v2beta3
kind: ApisixRoute
metadata:
name: myapp-canary-apisixroute2
namespace: canary
spec:
http:
- name: myapp-stable-rule2
priority: 1
match:
hosts:
- myapp.example.com
paths:
- /
backends:
- serviceName: myapp-stable-service
servicePort: 80
- name: myapp-canary-rule2
priority: 2
match:
hosts:
- myapp.example.com
paths:
- /
backends:
- serviceName: myapp-canary-service
servicePort: 80
測試套菜,流量會優(yōu)先打入優(yōu)先級高的pod
? ~ for i in `seq 30`;do curl https://myapp.example.com;done
myapp:v2
myapp:v2
........
myapp:v2
myapp:v2
myapp:v2
myapp:v2
4.4.基于header分流
# vim canary-header.yaml
---
apiVersion: apisix.apache.org/v2beta3
kind: ApisixRoute
metadata:
name: myapp-canary-apisixroute3
namespace: canary
spec:
http:
- name: myapp-stable-rule3
priority: 1
match:
hosts:
- myapp.example.com
paths:
- /
backends:
- serviceName: myapp-stable-service
servicePort: 80
- name: myapp-canary-rule3
priority: 2
match:
hosts:
- myapp.example.com
paths:
- /
exprs:
- subject:
scope: Header
name: canary
op: RegexMatch
value: ".*myapp.*"
backends:
- serviceName: myapp-canary-service
servicePort: 80
測試
? ~ curl https://myapp.example.com
myapp:v1
? ~ curl https://myapp.example.com
myapp:v1
? ~ curl https://myapp.example.com
myapp:v1
? ~ curl https://myapp.example.com -X GET -H "canary: 124myapp"
myapp:v2
? ~ curl https://myapp.example.com -X GET -H "canary: myapp"
myapp:v2
? ~ curl https://myapp.example.com -X GET -H "canary: xiamyapp"
myapp:v2
? ~ curl https://myapp.example.com -X GET -H "stable: xiamyapp"
myapp:v1
? ~ curl https://myapp.example.com -X GET -H "stable: myapp"
myapp:v1
4.5.基于參數(shù)的分流
# cat vars.yaml
---
apiVersion: apisix.apache.org/v2beta3
kind: ApisixRoute
metadata:
name: myapp-canary-apisixroute3
namespace: canary
spec:
http:
- name: myapp-stable-rule3
priority: 1
match:
hosts:
- myapp.example.com
paths:
- /
backends:
- serviceName: myapp-stable-service
servicePort: 80
- name: myapp-canary-rule3
priority: 2
match:
hosts:
- myapp.example.com
paths:
- /
exprs:
- subject:
scope: Query
name: id
op: In
set:
- "12"
- "23"
- "45"
- "67"
backends:
- serviceName: myapp-canary-service
servicePort: 80
測試
? ~ curl https://myapp.example.com
myapp:v1
? ~ curl https://myapp.example.com
myapp:v1
? ~ curl https://myapp.example.com
myapp:v1
? ~ curl https://myapp.example.com
myapp:v1
? ~ curl https://myapp.example.com/\?id\=12
myapp:v2
? ~ curl https://myapp.example.com/\?id\=23
myapp:v2
? ~ curl https://myapp.example.com/\?id\=45
myapp:v2
? ~ curl https://myapp.example.com/\?id\=67
myapp:v2
? ~ curl https://myapp.example.com/\?id\=89
myapp:v1
? ~ curl https://myapp.example.com/\?id\=143
myapp:v1
4.6.基于cookie分流
apiVersion: apisix.apache.org/v2beta3
kind: ApisixRoute
metadata:
name: myapp-canary-apisixroute
namespace: default
spec:
http:
- name: myapp-stable-rule3
priority: 1
match:
hosts:
- myapp.example.com
paths:
- /
backends:
- serviceName: myapp-stable-service
servicePort: 80
- name: myapp-canary-rule3
priority: 2
match:
hosts:
- myapp.example.com
paths:
- /
exprs:
- subject:
scope: Cookie
name: canary_v5
op: Equal
value: "always"
backends:
- serviceName: myapp-canary-service
servicePort: 80
測試攜帶cookie:
? ~ curl --cookie "canary_v5=always" "http://myapp.example.com"
myapp:v2
測試不攜帶cookie
? ~ curl "http://myapp.example.com"
myapp:v1