1.istio sidecar代理默认只处理集群内部的目标

先做一个测试,首先将default namespace开启sidecar代理的自动注入:

1kubectl label namespace default istio-injection=enabled

部署sleep示例应用:

1kubectl apply -f samples/sleep/sleep.yaml

sleep应用启动后,进入到容器内部,使用curl访问http://httpbin.org/uuid,出现404:

1kubectl get pod
2NAME                     READY   STATUS    RESTARTS   AGE
3sleep-7549f66447-47sls   2/2     Running   0          2m24s
4
5
6kubectl exec sleep-7549f66447-47sls -c sleep -it sh
7# curl -s -w "%{http_code}\n" http://httpbin.org/uuid
8404

而在node节点上是可以访问http://httpbin.org/uuid的。

1 curl -s -w "%{http_code}\n" http://httpbin.org/uuid
2{
3  "uuid": "1bd6212c-2008-40a3-976e-66d51f465f60"
4}
5200

也就是默认情况istio ServiceMesh内的Pod无法访问Kubernetes集群外部的服务。这是因为iptables将Pod的所有外出流量都透明的转发给了sidecar代理,而sidecar代理默认只处理集群内部的目标。

2.将集群外部的服务暴露给集群内的Pod

将集群外部的服务暴露给集群内的Pod,可以采用两种方式:

  • 方式一:需要在Istio中定义ServiceEntry配置外部服务可被访问;
  • 方式二:配置跳过Istio,让容器直接访问集群外部服务

使用方式一,外出流量仍然会经过sidecar proxy,这样可以对集群外部的服务进行流量管理,也就是可以说对于集群外部的服务也可以使用享受istio的功能。

2.1 定义ServiceEntry配置外部服务可被访问

创建一个 ServiceEntry 对象,放行外部服务httpbin.org的访问:

 1cat <<EOF | kubectl apply -f -
 2apiVersion: networking.istio.io/v1alpha3
 3kind: ServiceEntry
 4metadata:
 5  name: httpbin-ext
 6spec:
 7  hosts:
 8  - httpbin.org
 9  ports:
10  - number: 80
11    name: http
12    protocol: HTTP
13  resolution: DNS
14  location: MESH_EXTERNAL
15EOF
1ubectl get ServiceEntry
2NAME          AGE
3httpbin-ext   12s

此时再进入到sleep容器内部访问httpbin.org,已经可以访问:

1kubectl exec sleep-7549f66447-47sls -c sleep -it sh
2# curl -s -w "%{http_code}\n" http://httpbin.org/uuid
3{
4  "uuid": "65af6e8b-340f-4098-b04e-61f7723dd080"
5}
6200

httpbin.org同时也支持https访问的,接下来在sleep容器内部尝试使用https协议访问:

1curl -s -w "%{http_code}\n" https://httpbin.org/uuid
2000

无法在集群内部以https访问集群外部的服务,这是因为对于暴露HTTPS的服务,除了需要ServiceEntry外,还需要VirtualService:

 1cat <<EOF | kubectl apply -f -
 2apiVersion: networking.istio.io/v1alpha3
 3kind: ServiceEntry
 4metadata:
 5  name: httpbin
 6spec:
 7  hosts:
 8  - httpbin.org
 9  ports:
10  - number: 443
11    name: https
12    protocol: HTTPS
13  resolution: DNS
14---
15apiVersion: networking.istio.io/v1alpha3
16kind: VirtualService
17metadata:
18  name: httpbin
19spec:
20  hosts:
21  - httpbin.org
22  tls:
23  - match:
24    - port: 443
25      sni_hosts:
26      - httpbin.org
27    route:
28    - destination:
29        host: httpbin.org
30        port:
31          number: 443
32      weight: 100
33EOF

此时再次进入到sleep容器内部可以正常访问https://httpbin.org/uuid了。

2.2 直接访问集群外部服务

如果想要跳过istio直接访问外部服务,需要配置envoy sidecar不再劫持到指定ip范围向外部服务的请求。 可以通过修改ConfigMap istio-sidecar-injector中的global.proxy.includeIPRanges,将集群内部服务的ip地址范围给它如10.244.0.1/24。 将对后续部署的服务起作用。

1kubectl edit cm istio-sidecar-injector -n istio-system

参考