destination rule、virtual service、subset、gateway
destionationrule(服務注冊)
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: productpage # 注冊的服務名稱
spec:
host: productpage # kubernetes下對應的service
subsets: # 關聯pod中version標簽
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
# 查看destinationrules
wangw@DESKTOP:~$ kubectl get destinationrules -n istio-sample
NAME HOST AGE
details details 10m
productpage productpage 10m
ratings ratings 10m
reviews reviews 10m
virtualservice(流量管理)
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: productpage # 定義virtualservice名稱
spec:
hosts:
- productpage # kubernetes下service
http:
- route:
- destination:
host: productpage # 已注冊到istio的服務
subset: v1 # 已注冊服務中的subsets版本
# 查看virtualservice
wangw@DESKTOP:~$ kubectl get virtualservice -n istio-sample
NAME GATEWAYS HOSTS AGE
bookinfo [bookinfo-gateway] [*] 17m
details [details] 16m
productpage [productpage] 16m
ratings [ratings] 16m
reviews [reviews] 16m
gateway(流量入口)
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway # 網關名稱
spec:
selector:
istio: ingressgateway # 使用istio提供的ingress控制器
servers:
- port:
number: 80 # 網關使用的端口
name: http
protocol: HTTP # 網絡協議,支持http和https
hosts: # 定義網關用於訪問的地址,可以是ip或者域名
- "*" # *代表可用任何方式訪問
# 查看gateway
wangw@DESKTOP:~$ kubectl get gateway -n istio-sample
NAME AGE
bookinfo-gateway 23m
服務路由(配置服務在網關上的路由)
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*" # 訪問地址,這里允許任何方式
gateways:
- bookinfo-gateway # 選擇網關
http:
- match: # 定義服務匹配模式
- uri: # 以uri的方式
exact: /productpage # exact代表絕對路徑,只能匹配定義的字段
- uri:
prefix: /static # prefix代表前綴,可以匹配到二級子目錄上
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route: # 選擇路由的服務
- destination:
host: productpage # 已注冊istio服務
port:
number: 9080
# 查找istio-ingressgateway地址
wangw@DESKTOP:~$ kubectl get service istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.43.138.125 192.168.199.140 80:32047/TCP,443:31406/TCP 17h
# 訪問bookinfo
wangw@DESKTOP:~$ curl http://192.168.199.140/productpage -I
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 4183
server: istio-envoy
date: Wed, 20 Nov 2019 02:38:45 GMT
x-envoy-upstream-service-time: 30
# 驗證prefix子路徑支持
wangw@DESKTOP:~$ curl http://192.168.199.140/static/jquery.min.js -I
HTTP/1.1 200 OK
content-length: 84380
content-type: application/javascript
last-modified: Tue, 19 Mar 2019 18:04:24 GMT
cache-control: public, max-age=43200
expires: Wed, 20 Nov 2019 14:40:06 GMT
etag: "1553018664.0-84380-810225459"
date: Wed, 20 Nov 2019 02:40:06 GMT
accept-ranges: bytes
server: istio-envoy
x-envoy-upstream-service-time: 6
基於http header的服務訪問控制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user: # 如果請求header中有"end-user",並且值為"jason",就匹配此規則
exact: jason
route:
- destination: # 滿足請求header條件后,流量導向到reviews的v2版本上
host: reviews
subset: v2
- route:
- destination: # 普通請求流量導向到reviews的v3版本上
host: reviews
subset: v3
故障注入(測試微服務彈性)
注入HTTP延遲故障
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
...
spec:
hosts:
- ratings
http:
- fault: # 定義了一個7s延時的故障,實際上是sidecar將請求hold住了,
delay: # 時間一到請求轉發到ratings服務,對原有服務沒任何影響
fixedDelay: 7s
percentage:
value: 100
match:
- headers:
end-user:
exact: jason
route:
- destination:
host: ratings
subset: v1
- route:
- destination:
host: ratings
subset: v1
注入HTTP abort故障
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
...
spec:
hosts:
- ratings
http:
- fault: # sidecar在遇到end-user:jason請求時,直接返回500,不會將流量發送到ratings
abort:
httpStatus: 500
percentage:
value: 100
match:
- headers:
end-user:
exact: jason
route:
- destination:
host: ratings
subset: v1
- route:
- destination:
host: ratings
subset: v1
流量轉移
基於權重的路由
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
...
spec:
hosts:
- reviews
http:
- route: # 50%流量到v1,50%流量到v3
- destination:
host: reviews
subset: v1
weight: 50
- destination:
host: reviews
subset: v3
weight: 50
請求超時
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v2
timeout: 0.5s # 真實應用響應超過這個值,則sidecar判斷為超時,返回5xx響應
熔斷(限制並發)
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
trafficPolicy: # 流量傳輸策略
connectionPool: # 定義鏈接池
tcp: # tcp連接
maxConnections: 1 # 最大連接數
http: # http連接
http1MaxPendingRequests: 1 # 最大Pending請求數
maxRequestsPerConnection: 1 # 每個連接最大請求數
outlierDetection: # 檢測配置
consecutiveErrors: 1
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100
# 測試2並20請求
wangw@DESKTOP:~$ kubectl exec -n istio-sample -it $FORTIO_POD -c fortio /usr/bin/fortio -- load -c 2 -qps 0 -n 20 \
-loglevel Warning http://httpbin:8000/get
05:29:53 I logger.go:97> Log level is now 3 Warning (was 2 Info)
Fortio 1.3.1 running at 0 queries per second, 32->32 procs, for 20 calls: http://httpbin:8000/get
Starting at max qps with 2 thread(s) [gomax 32] for exactly 20 calls (10 per thread + 0)
Ended after 41.76631ms : 20 calls. qps=478.85
Aggregated Function Time : count 20 avg 0.0040754377 +/- 0.0007991 min 0.00322531 max 0.006563978 sum 0.081508754
# range, mid point, percentile, count
>= 0.00322531 <= 0.004 , 0.00361266 , 70.00, 14
> 0.004 <= 0.005 , 0.0045 , 90.00, 4
> 0.005 <= 0.006 , 0.0055 , 95.00, 1
> 0.006 <= 0.00656398 , 0.00628199 , 100.00, 1
# target 50% 0.00376163
# target 75% 0.00425
# target 90% 0.005
# target 99% 0.00645118
# target 99.9% 0.0065527
Sockets used: 2 (for perfect keepalive, would be 2)
Code 200 : 20 (100.0 %) # 這里可以看到,所有請求都通過了,說明Istio-proxy 允許存在一些誤差。
Response Header Sizes : count 20 avg 230 +/- 0 min 230 max 230 sum 4600
Response Body/Total Sizes : count 20 avg 601 +/- 0 min 601 max 601 sum 12020
All done 20 calls (plus 0 warmup) 4.075 ms avg, 478.9 qps
# 測試3並發30請求
wangw@DESKTOP:~$ kubectl exec -n istio-sample -it $FORTIO_POD -c fortio /usr/bin/fortio -- load -c 3 -qps 0 -n 30 \
-loglevel Warning http://httpbin:8000/get
05:30:09 I logger.go:97> Log level is now 3 Warning (was 2 Info)
Fortio 1.3.1 running at 0 queries per second, 32->32 procs, for 30 calls: http://httpbin:8000/get
Starting at max qps with 3 thread(s) [gomax 32] for exactly 30 calls (10 per thread + 0)
05:30:09 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
05:30:09 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
05:30:09 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
05:30:09 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
05:30:09 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
05:30:09 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
05:30:09 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
05:30:09 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
05:30:09 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
05:30:09 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
Ended after 81.134688ms : 30 calls. qps=369.76
Aggregated Function Time : count 30 avg 0.0056269946 +/- 0.005095 min 0.0003608 max 0.021076954 sum 0.168809838
# range, mid point, percentile, count
>= 0.0003608 <= 0.001 , 0.0006804 , 33.33, 10
> 0.005 <= 0.006 , 0.0055 , 53.33, 6
> 0.006 <= 0.007 , 0.0065 , 73.33, 6
> 0.007 <= 0.008 , 0.0075 , 86.67, 4
> 0.008 <= 0.009 , 0.0085 , 90.00, 1
> 0.012 <= 0.014 , 0.013 , 93.33, 1
> 0.02 <= 0.021077 , 0.0205385 , 100.00, 2
# target 50% 0.00583333
# target 75% 0.007125
# target 90% 0.009
# target 99% 0.0209154
# target 99.9% 0.0210608
Sockets used: 12 (for perfect keepalive, would be 3)
Code 200 : 20 (66.7 %) # 熔斷行為按照之前的設計生效了,只有 66.7% 的請求獲得通過,剩余請求被斷路器攔截了
Code 503 : 10 (33.3 %)
Response Header Sizes : count 30 avg 153.43333 +/- 108.5 min 0 max 231 sum 4603
Response Body/Total Sizes : count 30 avg 481.1 +/- 169.8 min 241 max 602 sum 14433
All done 30 calls (plus 0 warmup) 5.627 ms avg, 369.8 qps
流量鏡像
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- httpbin
http:
- route:
- destination: # 此路由規則將100%的流量發送到v1
host: httpbin
subset: v1
weight: 100
mirror: #指定鏡像到httpbin:v2服務
host: httpbin
subset: v2
# 當流量被鏡像時,請求將通過其主機/授權報頭發送到鏡像服務附上 -shadow。例如,將cluster-1變為cluster-1-shadow
# 這些被鏡像的請求是“即發即棄”的,也就是說這些請求引發的響應是會被丟棄的
邊緣流量控制(Ingress Gateway)
通過自動掛載文件模式
1: 生成證書
2: 在istio-system下創建證書secret,名稱只能使用istio-ingressgateway-certs,創建后會 \
自動掛載到istio-ingressgateway容器/etc/istio/istio-ingressgateway-certs目錄下
kubectl create secret -n istio-system tls istio-ingressgateway-certs \
--key privkey1.pem --cert fullchain1.pem
3: 查看文件掛載情況
wangw@DESKTOP:$ kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=ingressgateway \
-o jsonpath='{.items[0].metadata.name}') -- ls -al /etc/istio/ingressgateway-certs
total 0
drwxrwxrwt 3 root root 120 Nov 21 06:08 .
drwxr-xr-x 1 root root 78 Nov 21 06:04 ..
drwxr-xr-x 2 root root 80 Nov 21 06:08 ..2019_11_21_06_08_28.453045493
lrwxrwxrwx 1 root root 31 Nov 21 06:08 ..data -> ..2019_11_21_06_08_28.453045493
lrwxrwxrwx 1 root root 14 Nov 21 06:08 tls.crt -> ..data/tls.crt
lrwxrwxrwx 1 root root 14 Nov 21 06:08 tls.key -> ..data/tls.key
4: 修改網關配置
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
servers:
- hosts:
- '*'
port:
name: https
number: 443
protocol: HTTPS
tls:
mode: SIMPLE
privateKey: /etc/istio/ingressgateway-certs/tls.key
serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
selector:
istio: ingressgateway
5: 請求網關(使用證書中的域名訪問)
wangw@DESKTOP:~$ curl -I https://bookinfo.gisuni.dev/productpage
HTTP/2 200
content-type: text/html; charset=utf-8
content-length: 4183
server: istio-envoy
date: Thu, 21 Nov 2019 07:17:27 GMT
x-envoy-upstream-service-time: 37
通過SDS為Gateway提供HTTPS加密支持
創建Ingress Gateway代理,通過SDS獲取secret中的證書。
Ingress Gateway代理和Ingress Gateway在同一個Pod中運行,監視Ingress Gateway所在命名空間中新建的Secret
# 重新生成ingress gateway配置
istioctl manifest generate \
--set values.gateways.istio-egressgateway.enabled=false \
--set values.gateways.istio-ingressgateway.sds.enabled=true > \
$HOME/istio-ingressgateway.yaml
# 應用新配置
kubectl apply -n istio-system -f $HOME/istio-ingressgateway.yaml
創建新的證書secret,並修改gateway引用證書
# 創建名稱為gistack-org的證書secret
kubectl create -n istio-system secret tls gisstack-org \
--key privkey1.pem --cert fullchain1.pem
# 修改gateway配置
kind: Gateway
apiVersion: networking.istio.io/v1alpha3
metadata:
name: bookinfo-gateway
spec:
servers:
- hosts:
- '*'
port:
name: https
number: 443
protocol: HTTPS
tls:
mode: SIMPLE # 單向認證,MUTUAL為雙向認證
credentialName: "gisstack-org" # 此處直接指定證書secret名稱
selector:
istio: ingressgateway
訪問
wangw@DESKTOP:~$ curl -I https://bookinfo.gisstack.org/productpage
HTTP/2 200
content-type: text/html; charset=utf-8
content-length: 4183
server: istio-envoy
date: Thu, 21 Nov 2019 07:43:44 GMT
x-envoy-upstream-service-time: 39
配置多個主機名
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mygateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https-httpbin
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: "httpbin-credential"
hosts:
- "httpbin.example.com"
- port:
number: 443
name: https-helloworld
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: "helloworld-credential"
hosts:
- "helloworld-v1.example.com"
配置直通模式(直接認證后端應用的證書)
# 網關
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mygateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: PASSTHROUGH # 直通模式不需要配置證書,網關按原樣傳遞入口流量,不終止TLS
hosts:
- nginx.example.com
# 路由
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx
spec:
hosts:
- nginx.example.com
gateways:
- mygateway
tls:
- match:
- port: 443
sni_hosts: # 指定sni主機名
- nginx.example.com
route:
- destination:
host: my-nginx
port:
number: 443
Egress流量
引入外部服務
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry # 通過ServiceEntry創建外部服務代理(相當於注冊到istio)
metadata:
name: httpbin
spec:
hosts:
- httpbin.org # 外部服務地址
ports:
- number: 443
name: https
protocol: HTTPS
resolution: DNS
location: MESH_EXTERNAL
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService # 配置外部服務路由
metadata:
name: httpbin
spec:
hosts:
- httpbin.org
tls:
- match:
- port: 443
sni_hosts: # 指定通過SNI方式訪問tls
- httpbin.org
route:
- destination:
host: httpbin.org
port:
number: 443
weight: 100
管理外部服務
# 與網格內流量配置方法相同
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin-ext
spec:
hosts:
- httpbin.org
http:
- timeout: 3s
route:
- destination:
host: httpbin.org
weight: 100