使用服務條目資源(ServiceEntry)可以將條目新增到 Istio 內部維護的服務登錄檔中。新增服務條目後,Envoy 代理可以將流量傳送到該服務,就好像該服務條目是網格中的服務一樣。通過配置服務條目,可以管理在網格外部執行的服務的流量。
此外,可以配置虛擬服務和目標規則,以更精細的方式控制到服務條目的流量,就像為網格中的其他任何服務配置流量一樣。
serviceentry樣例
- client.yaml # istio 要注入的客戶端資原始檔
- baidu-se.yaml # baidu ServiceEntry
- baidu-dr.yaml # baidu DestinationRule
- baidu-vs.yaml # baidu VirtualService
Sidercar 注入
手動注入
# istioctl kube-inject -f xxx.yaml|kubectl apply -f -
自動注入
# kubectl label namespace default istio-injection=enabled
服務條目資源
client.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: client
spec:
replicas: 1
selector:
matchLabels:
app: client
template:
metadata:
labels:
app: client
spec:
containers:
- name: busybox
image: busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","sleep 3600"]
# kubectl get po
NAME READY STATUS RESTARTS AGE
client-86bc9bd5f-mj2pq 2/2 Running 0 11m
Istio 注入後,client 就處於 Istio 服務網格之中。
baidu-se.yaml
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: baidu-se
spec:
hosts:
- www.baidu.com
location: MESH_EXTERNAL # 定義網格外部還是內部,表示服務在網格外部。通常用於指示通過API使用的外部服務。
# location: MESH_INTERNAL # 表示服務是網格的一部分。通常用於指示在擴充套件服務網格以包括不受管理的基礎架構時顯式新增的服務
ports:
- name: http
number: 80
protocol: HTTP
resolution: DNS
該服務條目資源定義了一個外部網站 baidu,並將它納入到 Istio 內部維護的服務登錄檔中。
# kubectl get se
NAME HOSTS LOCATION RESOLUTION AGE
baidu-se [www.baidu.com] MESH_EXTERNAL DNS 53m
- hosts:DNS名稱。可以具有萬用字元字首。
- ports:關聯的埠。
- ports.protocol: 以下之一:HTTP,HTTPS,HTTP2,GRPC,MONGO,TCP或TLS。
- exportTo:預設情況下使用“*”,這意味著該ServiceEntry公開給每個名稱空間。 “.”僅將其限制為當前名稱空間。目前,exportTo值僅限於這兩個。
- resolution:主機的服務發現模式
- location:從網格的角度來看,應將此服務視為內部或外部服務。
驗證服務條目案例
# kubectl exec -it $(kubectl get pods | grep -i client | awk '{print $1}') -- sh
# wget -q -O - http://www.baidu.com
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=truew.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新聞</a> <a href=http://www.hao123.com name=tj_tr class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地圖</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>視訊</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>貼吧</a> <noscript> <a hrp://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登入</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登入</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: bloc">更多產品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>關於百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必讀</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>意見反饋</a> 京ICP證030173號 <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
對剛才編寫的 ServiceEntry 資源做一些改動
baidu-se-gai.yaml
...
#resolution: DNS
resolution: STATIC # 靜態
endpoints:
- address: 10.10.10.10 # 自定義一個內網的ip
驗證
# kubectl exec -it $(kubectl get pods | grep -i client | awk '{print $1}') -- sh
Defaulting container name to busybox.
Use 'kubectl describe pod/client-86bc9bd5f-mj2pq -n default' to see all of the containers in this pod.
/ # wget -q -O - http://www.baidu.com
wget: server returned error: HTTP/1.1 503 Service Unavailable
- 出現此問題的原因是,serviceentry 一直都在發揮作用,前面沒報錯的原因是預設指定的域名解析是基於DNS的。而調整後,設定了靜態域名解析的方式,並隨意給了一個內網IP來標識baidu。kubectl apply serviceentry後此配置立刻就被應用在網格內(client)的 envoy,那麼在網格內訪問baidu的時候,流量就被路由到了所指定的 10.10.10.10去了。
精細的流控
使用 service entry 使用場景有哪些?這裡假設一個場景,比如工作過程中需要呼叫外部合作方服務,該服務跟你的叢集毫無關係,甚至對方服務可以佈置在美國。但是通過服務條目,你可以將對方服務納入到自己的 Istio 網格之內,就像它本身存在你的叢集之內一樣,就好像你做了內網攔截一樣。而且服務條目可以結合虛擬服務(virtual service)、目的地規則(destination rule)做更加精細的流量控制,不僅如此,還可以做失敗注入、重試等功能。
baidu-se.yaml
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: baidu-se
spec:
hosts:
- www.baidu.com
location: MESH_EXTERNAL
ports:
- name: http
number: 80
protocol: HTTP
resolution: DNS
# kubectl get se
NAME HOSTS LOCATION RESOLUTION AGE
baidu-se [www.baidu.com] MESH_EXTERNAL DNS 67m
# kubectl exec -it $(kubectl get pods | grep -i client | awk '{print $1}') -- sh
Defaulting container name to busybox.
Use 'kubectl describe pod/client-86bc9bd5f-mj2pq -n default' to see all of the containers in this pod.
/ # wget -q -O - http://www.baidu.com
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=truew.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新聞</a> <a href=http://www.hao123.com name=tj_tr class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地圖</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>視訊</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>貼吧</a> <noscript> <a hrp://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登入</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登入</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: bloc">更多產品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>關於百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必讀</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>意見反饋</a> 京ICP證030173號 <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
baidu-dr.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: baidu-dr
spec:
host: www.baidu.com
trafficPolicy: # 流量策略,包括:負載平衡策略、連線池大小、異常檢測
loadBalancer: # 預設LB策略
simple: ROUND_ROBIN # ROUND_ROBIN-迴圈,LEAST_CONN-最小連線,RANDOM-隨機,PASSTHROUGH-只連
# kubectl get dr
NAME HOST AGE
baidu-dr www.baidu.com 54m
baidu-vs.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: baidu-vs
spec:
hosts:
- www.baidu.com
http:
- route:
- destination:
host: www.baidu.com
port:
number: 80
#subset: tls-origination
timeout: 1ms
# kubectl get vs
NAME GATEWAYS HOSTS AGE
baidu-vs [www.baidu.com] 54m
再次測試
# kubectl exec -it $(kubectl get pods | grep -i client | awk '{print $1}') -- sh
Defaulting container name to busybox.
Use 'kubectl describe pod/client-86bc9bd5f-mj2pq -n default' to see all of the containers in this pod.
/ # wget -q -O - http://www.baidu.com
wget: server returned error: HTTP/1.1 408 Request Timeout
?!經過簡單的測試可以對網格外部服務進行精細的流控