1、istio gateway
如果说 AWS API Gateway 是为了对 REST/Websocket API 进行管理和维护,那么作为当下流行的 Service Mesh 的产品之一 istio,其中的 istio gateway 也扮演了类似的角色。
2、istio gateway 的一个官方的例子
在官方的例子中,无论是通过手动注入 Sidecar
还是自动注入 Sidecar
,在破除重重困难把 httpbin 部署之后,你就可以通过 gateway 设置的规则来访问部署的 httpbin 服务了。
curl -I -HHost:httpbin.example.com http://$INGRESS_HOST/status/200
HTTP/1.1 200 OK
server: istio-envoy
date: Tue, 21 May 2019 07:42:22 GMT
content-type: text/html; charset=utf-8
access-control-allow-origin: *
access-control-allow-credentials: true
content-length: 0
x-envoy-upstream-service-time: 4
通过 Gateway
的 hosts
设置允许请求的 header 里必须带 httpbin.example.com
才能进入 gateway
,进而抵达内部服务。
gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "httpbin.example.com"
与此同时,通过 virtualservice
可以更细粒度地设置请求的访问规则,如这里放出了两个 url:/status
和 /delay
,从而通过 INGRESS_HOST/status/200
(返回状态 200) 和 INGRESS_HOST/delay/2
(延迟 2 秒) 可以访问到内部服务。
virtualservice.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "httpbin.example.com"
gateways:
- httpbin-gateway
http:
- match:
- uri:
prefix: /status
- uri:
prefix: /delay
route:
- destination:
port:
number: 8000
host: httpbin
3、istio 的强大与复杂
istio 虽然好,可是使用起来却有时让人望而却步,每一个功能都要备好长长的 yaml 文件,这就像在 AWS API Gateway 在使用时,每一个资源的配置都要经过一番复杂的配置才能享用。相处久了,就会产生又爱又恨的思绪。
4、基于 istio 的发布系统
在 CI/CD 系统中,CI 一般比较简单,大多数编译系统支持一条命令就能实现代码的编译,如 go test/build
或者 mvn clean/test/package
。
CD 是软件发布的重要一环,而基于 istio 的发布,每个待发布的服务需要维护一套 yaml 配置文件(包括 gateway, virtualservice, serviceentry 等),这无疑是一项繁琐的工作,我们可以为这些配置编写模版,利用 gitlab 的 .gitlab-ci.yml
来为模版填充内容,从而满足日常的编译和发布的需要。
搭建基于 gitlab 的 CI/CD,需要我们和 kubernetes、istio 等诸多系统集成,集成工作主要涉及以下几方面:
- 集成 Gitlab 的 kubernetes Runner 来完成 CI
- 单独的模版工程用来发布项目,模版需要包括 istio 相关组件如
gateway
virtualservice
serviceentry
等,发布成功的服务将服务会写入 etcd - 利用 confd 来读取 etcd 中的服务列表,每个服务通过 confd 的模版扩展为 haproxy 的 acl + use_backend,经过 haproxy 的流量统一经过同一个 frontend(
frontend istio
) 进行管理 - 利用 confd 来读取 etcd 中的服务列表,每个服务通过 confd 的模版扩展为 haproxy 的 backend,backend 中的 server 为 istio ingress gateway
- 利用 haproxy 来读取发布的服务列表,通过 acl 对 HOST 的控制做流量分流。通过对 HOST 做 acl 的方法正好和之前提到的 istio gateway 的 hosts 功能对接
- 配置 AWS ELB 来访问内部的 haproxy 集群
- 通过 nginx 的
proxy_set_header
来为 ELB 流量分流
另外,可以通过配置 ELB 使流量直接进入 istio ingressgateway,不过目前还处于 alpha 功能,不建议用于生产环境。
5、一个 devops 问题
这里介绍一个删除异常 istio-ingressgateway
的方法
istio-ingressgateway
是通过 ReplicaSet
来运行,默认 replicas
的数量为 1,出现异常时(如手动在 dashboard 删除了 pod)可以通过修改 pod 的 label 来对异常 pod 进行隔离,隔离后的 pod 不属于 ReplicaSet
,kubernetes 会启动新的 pod 来代替异常 pod,此时我们可以通过 kubectl delete pod
来删除异常 pod。
通过 kubectl -n istio-system edit pod
来修改 istio-ingressgateway
的 label
:
labels:
app: istio-ingressgateway
istio: ingressgateway-changed
通过 kubectl -n istio-system delete pod <istio-ingressgateway-pod-name> --grace-period=0 --force
来删除处于 Terminating
的 pod。