Istio Service Mesh可以使用ingress and egress當作Service Mesh的出入口,統一且有效的管理。
Istio Service Mesh內的Pod,由於其iptables設定將所有流量都透過Sidecar,所以這些Pod無法訪問Cluster外部的服務,而只能處理Kubernetes Cluster內部的Service。
如何將外部服務註冊到 Istio Service Mesh。Istio 有一項特別的設定 ServiceEntry,他可以定義外部服務類似Kubernetes Service ExternalName;或者也可以對Istio進行配置,要求對特定IP範圍的服務進行訪問。
Istio部署配置的global.outboundTrafficPolicy參數,在1.1版本以後開始默認ALLOW_ANY,這種情況下如果不設定Istio ServiceEntry,訪問外部服務時會返回httpstatus code 404,而HTTPS流量可以正常訪問,為了測試Istio ServiceEntry效果,將改為R設定EGISTRY_ONLY,方便觀察ServiceEntry。
#check global.outboundTrafficPolicy
kubectl get configmap istio -n istio-system -o yaml | grep -o "mode: ALLOW_ANY"
mode: ALLOW_ANY
#replace setting
kubectl get configmap istio -n istio-system -o yaml | sed 's/mode: REGISTRY_ONLY/mode: ALLOW_ANY/g' | kubectl replace -n istio-system -f -
deploy istio again
helm template install/kubernetes/helm/istio --name istio --namespace istio-system --values install/kubernetes/helm/istio/values-istio-demo.yaml | kubectl apply -f -
kubectl apply -f samples/sleep/sleep.yaml
export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
通過設定Istio ServiceEntry,可以從Istio中訪問任何公開外部服務。 這裏我們會使用httpbin.org以及www.google.com。
創建一個ServiceEntry,註冊一個外部HTTP Service:
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: httpbin-ext
spec:
hosts:
- httpbin.org
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
location: MESH_EXTERNAL
EOF
創建一個ServiceEntry 以及 VirtualService,註冊外部 HTTPS 服務。需要特別注意包括 HTTPS 在內的 TLS 協議,在 ServiceEntry 之外,還需要創建 TLS VirtualService。TLS VirtualService必須在 match 子句中包含 tls 規則和 sni_hosts 以啟用 SNI 路由。
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: google
spec:
hosts:
- www.google.com
ports:
- number: 443
name: https
protocol: HTTPS
resolution: DNS
location: MESH_EXTERNAL
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: google
spec:
hosts:
- www.google.com
tls:
- match:
- port: 443
sni_hosts:
- www.google.com
route:
- destination:
host: www.google.com
port:
number: 443
weight: 100
EOF
如果想要跳過 Istio,直接訪問某個 IP 範圍內的外部服務,就需要對 Envoy Proxy sidecar進行額外的設定,阻止 Envoy Proxy對外部請求的攔截。可以在 Helm 中設置global.proxy.includeIPRanges,然後使用kubectl apply命令來更新名為istio-sidecar-injector的 Configmap。在 istio-sidecar-injector更新之後,global.proxy.includeIPRanges會在所有未來部署的Pod中生效。
使用 global.proxy.includeIPRanges 最簡單方式就是把內部服務的 IP 地址範圍傳遞給它,這樣就在 Sidecar proxy 的重定向列表中排除掉了外部服務的地址了。
我們可以使用兩種方式從Istio Service Mesh內部來完成對外部服務的調用:
使用 ServiceEntry (推薦方式)
配置 Istio sidecar,從它的重定向 IP 表中排除外部服務的 IP 範圍
第一種方式(ServiceEntry)中,Service Mesh內部的服務不論是訪問內部還是外部的服務,都可以使用同樣的 Istio Service Mesh的特性。
第二種方式越過了 Istio sidecar proxy,讓服務直接訪問到對應的外部地址。然而要進行這種配置,需要了解特定的知識和配置。