由于Ingressgateway是使用NodePort的方式暴露在31380和31390端口,当外部访问集群内暴露的服务时,需要在URL中添加端口才能正常访问。由于Gateway并不允许在hosts中指定带端口的域名,导致我们在创建Gateway时只能指定*泛域名,这就会造成我们不能使用host来区分服务的功能。为了解决这个问题,通常可以创建一个代理服务来转发流量到Ingressgateway中,一般情况下,这个代理服务会监听Web常用的80和443端口。在使用代理服务的情况下,后端的Ingressgateway还可以创建多个副本来做高可用。
由于Istio使用Envoy作为服务网格的代理,因此我们也可以直接使用Envoy作为我们的代理服务器,代理后端的Ingressgateway。通过给Kubernetes集群中的节点设置特定的标签,如edgenode=true,来标记这些节点作为集群中的边界节点,在这些节点上部署Envoy代理,接收外部流量。
虽然我们使用了Envoy作为前端代理Ingressgateway,接收外部流量,但是我们仍然需要对外部调用方提供唯一的IP地址。我们需要在Envoy前面再加一层代理,比如,可以使用Keepalived与LVS配合,保证当集群中的节点出现问题,导致Ingressgateway部分实例出现故障或者Envoy代理部分实例出现故障时,不会改变集群外的流量入口IP地址,进而减少对服务调用方的影响。由于篇幅问题,本书不进行此部分的实验。
【实验】
1)创建Ingressgateway的Envoy代理服务器配置文件:
$ kubectl create configmap front-envoy -n istio-system --from-file=front-envoy.yaml=istio/miscellaneous/istio-ingressgateway-proxy.yaml $ kubectl get configmap front-envoy -n istio-system NAME DATA AGE front-envoy 1 10s
2)给需要部署Envoy代理服务器的边界节点打标签:
$ kubectl get no --show-labels NAME STATUS ROLES AGE VERSION LABELS lab1 Ready master 12d v1.12.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=lab1,node-role.kubernetes.io/master= lab2 Ready <none> 12d v1.12.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=lab2 lab3 Ready <none> 12d v1.12.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=lab3 $ kubectl label nodes lab1 edgenode=true $ kubectl get no --show-labels NAME STATUS ROLES AGE VERSION LABELS lab1 Ready master 12d v1.12.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,edgenode=true,kubernetes.io/hostname=lab1,node-role.kubernetes.io/master= lab2 Ready <none> 12d v1.12.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=lab2 lab3 Ready <none> 12d v1.12.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=lab3
3)部署Envoy代理服务器:
$ kubectl apply -f service/envoy/envoy.yaml -n istio-system $ kubectl get pod -n istio-system -l app=front-envoy NAME READY STATUS RESTARTS AGE front-envoy-5df48f5dc7-tkp6n 1/1 Running 0 102s
4)部署httpbin服务:
$ kubectl apply -f kubernetes/httpbin.yaml $ kubectl get pod -l app=httpbin NAME READY STATUS RESTARTS AGE httpbin-b67975b8f-6rcv2 2/2 Running 0 92s
5)创建Gateway暴露服务:
$ kubectl apply -f istio/miscellaneous/gateway-httpbin-use-host.yaml
6)服务访问测试:
$ curl -I http://11.11.11.111/ HTTP/1.1 404 Not Found date: Wed, 09 Jan 2019 03:16:40 GMT server: envoy transfer-encoding: chunked
7)配置hosts解析:
11.11.11.111 httpbin.will
8)使用curl访问:
$ curl http://httpbin.will/get { "args": {}, "headers": { "Accept": "*/*", "Content-Length": "0", "Host": "httpbin.will", "User-Agent": "curl/7.29.0", "X-B3-Sampled": "1", "X-B3-Spanid": "3be937ed7ed61086", "X-B3-Traceid": "3be937ed7ed61086", "X-Envoy-Internal": "true", "X-Request-Id": "51c91552-2e83-98bb-853f-f31ff7923c42" }, "origin": "10.244.0.0", "url": "http://httpbin.will/get" }
9)使用浏览器访问。
访问地址http://httpbin.will/get ,得到的结果如图13-3所示。
图13-3 实验结果
从上面的服务访问测试可以看出,当创建了使用指定域名的Gateway时,访问时必须使用指定的域名,当使用其他域名访问时,会直接返回404响应码。
10)清理:
$ kubectl delete -f istio/miscellaneous/gateway-httpbin-use-host.yaml $ kubectl delete -f kubernetes/httpbin.yaml $ kubectl delete -f service/envoy/envoy.yaml -n istio-system $ kubectl delete configmap front-envoy -n istio-system $ kubectl label nodes lab1 edgenode-