Closed vieyahn2017 closed 7 months ago
深度剖析Service Mesh服务网格新生代Istio https://blog.csdn.net/karamos/article/details/80131863
Istio在服务集群之间建立起了服务网格,从运维层面提供了负载均衡、流量管理、服务间认证、访问控制、指标监控等功能,不需要我们对服务代码进行任何改动。虽然Istio与平台无关,但是将其与Kubernetes结合使用,其优势会更大。参考Istio官方文档,在Kubernetes上安装部署好Istio之后,默认提供了分布式链路跟踪、指标监控可视化、服务依赖动态图展示等平台,功能非常强大,安装方法也很简单,只是安装过程中有一些需要注意的地方,这里做一个记录。安装过程基本参考自官方文档。
下载Istio发布包 直接运行如下命令下载最新发布包并自动解压,也可以到Istio Release选择指定版本手动下载。
# curl -L https://git.io/getLatestIstio | sh -
# cd istio-1.0.5
# cp bin/istioctl /usr/local/bin/
Istio包中install目录包含了在Kubernetes中安装所需的yaml文件,samples目录包含了官方文档中介绍的各种示例。
修改配置 这里不需要对服务间通信使用双向TLS认证,所以选择install/kubernetes/istio-demo.yaml配置文件进行安装,在安装之前还需要对这个文件进行部分修改,请自己对原文件做好备份。istio-demo.yaml文件里面提供了安装Istio需要创建的各种资源,所有资源默认创建在kubernetes的istio-system空间中,能够对建立在其他命名空间中的服务进行管理。
我们需要对istio-demo.yaml文件做如下修改:
如果没有外部LoadBalancer可用,需要将istio-ingressgateway Service的type改成NodePort。虽然这一步不修改也没有关系,但是创建之后这个Service会一直处于Pending状态。 放开外网访问限制。在Istio服务网格中默认会对所有网络请求进行拦截,不支持对外部服务的访问,我们需要配置放开外网访问限制,只拦截内部服务地址。Calico默认使用的服务地址范围为10.96.0.0/12,将其配置到istio-sidecar-injector ConfigMap中的includeOutboundIPRanges选项中,详细方法参考后面问题二。 将Jaeger-query, Prometheus, Grafana, ServiceGraph几个Service配置成NodePort,否则在外部环境中无法访问。另外最好把这几个Service的NodePort设置为固定值,避免与其他服务端口冲突,也更方便访问,不会经常变动。这里配置Jaeger-query使用32762端口,Grafana使用32760端口,Prometheus使用32761端口,ServiceGraph使用32763端口。
# kubectl apply -f install/kubernetes/istio-demo.yaml
如果对配置文件进行了新的修改,重新执行该命令即可更新相关资源。这一步运行之后因为需要下载镜像,可能需要等待几分钟。安装成功之后,可以查看到如下Pods。
# kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
grafana-59b8896965-h24xf 1/1 Running 0 19h
istio-citadel-856f994c58-jp64r 1/1 Running 0 19h
istio-cleanup-secrets-5dvtn 0/1 Completed 0 19h
istio-egressgateway-5649fcf57-cst7n 1/1 Running 0 19h
istio-galley-7665f65c9c-ttdsn 1/1 Running 0 19h
istio-grafana-post-install-gz64t 0/1 Completed 4 19h
istio-ingressgateway-6755b9bbf6-dw2zv 1/1 Running 0 19h
istio-pilot-698959c67b-qgcqb 2/2 Running 0 19h
istio-policy-6fcb6d655f-xqb8w 2/2 Running 0 19h
istio-security-post-install-mbzds 0/1 Completed 3 19h
istio-sidecar-injector-768c79f7bf-mdd6g 1/1 Running 0 19h
istio-telemetry-664d896cf5-7kcmw 2/2 Running 0 19h
istio-tracing-6b994895fd-8sq4k 1/1 Running 0 19h
prometheus-76b7745b64-t42p9 1/1 Running 0 19h
servicegraph-5c4485945b-fzs9q 1/1 Running 0 19h
# kubectl get namespace -L istio-injection
NAME STATUS AGE ISTIO-INJECTION
default Active 3d21h
istio-system Active 3d19h disabled
kube-public Active 3d21h
kube-system Active 3d21h
namespace/default labeled
NAME STATUS AGE ISTIO-INJECTION default Active 3d21h enabled istio-system Active 3d19h disabled kube-public Active 3d21h kube-system Active 3d21h
自动注入开启之后对已经启动的Pods并不会起作用,需要将Pods重新创建一下。当自动注入生效之后会发现,在创建应用时每个Pod会包含2个容器,如下所示。
```sh
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-54458cd494-49dcl 2/2 Running 0 6s 192.168.0.40 szx1000317012 <none> <none>
另外在Pod创建的时候会先启动一个istio-init容器,是用于进行初始化操作的,只有当所有init容器启动并执行完成之后才会启动应用容器,istio-init在执行完成之后就会自动Exited掉。
Dashboard 访问地址 监控平台Dashboard Grafana http://master-ip:32760 监控平台Prometheus http://master-ip:32761 分布式跟踪Dashboard Jaeger http://master-ip:32762/search 服务依赖关系Dashboard http://master-ip:32763/force/forcegraph.html 对于监控这一块,从Grafana中只能看到业务指标的监控数据,并没有节点和容器的资源使用情况监控。其实Prometheus中已经采集到了资源相关的监控数据,不过还需要我们在Grafana中配置相应的Dashboard进行数据展示。我们下载Kubernetes cluster**ing (via Prometheus) Dashboard的json配置文件,然后导入到Grafana中即可查看到资源使用监控数据。另外Istio并没有引入告警系统,需要我们另外引入。
Istio对服务提供了强大的流量管理能力,可以考虑如何在其之上实现满足于业务需求的灰度发布机制。另外,Istio也提供了一系列如熔断、超时、重试等服务治理机制,还有提供了故障注入能力,可用于实现灵活的测试方案。
问题1:执行kubectl apply -f 命令时报"unable to recognize"错误 修改完配置之后执行kubectl apply -f istio-demo.yaml命令创建资源,但是报如下错误:
unable to recognize "istio-demo.yaml": no matches for kind "Gateway" in version "networking.istio.io/v1alpha3"
unable to recognize "istio-demo.yaml": no matches for kind "attributemanifest" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "attributemanifest" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "stdio" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "logentry" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "logentry" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "rule" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "rule" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "metric" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "metric" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "metric" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "metric" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "metric" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "metric" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "prometheus" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "rule" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "rule" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "kubernetesenv" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "rule" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "rule" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "kubernetes" in version "config.istio.io/v1alpha2"
unable to recognize "istio-demo.yaml": no matches for kind "DestinationRule" in version "networking.istio.io/v1alpha3"
unable to recognize "istio-demo.yaml": no matches for kind "DestinationRule" in version "networking.istio.io/v1alpha3"
解决方法: 该问题不是必现,有时候安装会出现,只需要重新执行一次该命令即可成功创建。
问题2:网格内不能访问外部系统 服务网格内默认是无法访问外部服务的,所有请求都会被sidecar拦截,但是通常系统不可避免地要对外部服务进行调用,此时我们可以通过下面两种方法达到该目的。
解决方法一:为外部调用定义一个ServiceEntry,声明好外部调用的地址和端口。但是该方法需要为每一个外部服务都创建一个ServiceEntry,比较麻烦。
解决方法二:为istio-sidecar-injector配置includeOutboundIPRanges,注明需要拦截的地址范围。因为我们使用的是cslico网络插件,这里配置内部服务地址范围为10.96.0.0/12。
修改istio-demo.yaml文件中的istio-sidecar-injector ConfigMap,内容如下:
......
- "[[ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` "10.96.0.0/12" ]]"
- "-x"
- "[[ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` "" ]]"
- "-b"
......
这里配置只拦截10.96.0.0/12网段的请求,另外也可以配置exclude地址。如果使用的是其他Network Plugin,在这里配置对应的服务地址即可。如果使用的是minikube,则配置10.0.0.1/24,如果使用的是rancher,则配置10.43.0.1/24。
问题3:分布式追踪Dashboard Jaeger里面找不到服务 当所有服务都重启并且都成功注入sidecar之后,在分布式追踪Dashboard Jaeger里面并没有发现服务。
解决方案: 这里一是需要服务有发出或者收到请求,才会有调用记录,二是在声明Service的时候需要给端口加上名字,这里不加name的话Jaeger是没有记录的。如下:
ports:
- protocol: TCP
port: 80
name: http
问题4:使用Nginx作为转发路由,请求报426 Upgrade Required错误 当服务启动之后,我运行一个Nginx作为网关进行路由转发,但是请求却报426 Upgrade Required错误,直接调用服务就可以成功调通。
解决方法:因为使用Nginx转发,默认是使用HTTP 1.0协议进行转发的,但是Istio貌似是不支持HTTP 1.0的,只支持HTTP 1.1/2。因此这里需要在Nginx转发的时候进行如下配置,使用HTTP 1.1协议进行转发。
location / {
proxy_pass http://service_endpotin;
proxy_http_version 1.1;
}
入口消息路由:nodeIP:31380 (kube-proxy) -> KUBE-SVC-xxxx (iptables规则) -> KUBE-SEP-xxxx (iptables规则) -> 172.16.0.38:80 (istio-ingressgateway pod里面的envoy) -> 172.16.0.30:9080 (productpage) 服务间路由:productpage -> envoy 15001 (iptables) -> reviews pod IP 9080 -> VXLAN (如果是跨节点了) -> reviews pod IP 9080 -> envoy 15001(被iptables转发一次)-> reviews (envoy再次转发给9080,reviews才真正收到这个消息) 31380是istio-ingressgateway的http协议的nodePort,9080是bookinfo所有服务统一使用的服务端口,15001是envoy的业务端口,15000是envoy的管理端口。
参照官网指导,安装istio-1.1.11: https://istio.io/docs/setup/kubernetes/install/kubernetes/
以及安装示例程序bookinfo:
https://istio.io/docs/examples/bookinfo/ 安装好之后,可以通过如下url访问bookinfo:
http://nodeIP:31380/productpage 我的环境有2个node节点,由于使用NodePort模式,随便哪个节点的IP,都可以访问。下面,从31380端口开始分析整个路由过程。
一、istio-ingressgateway入口的消息路由 二、服务间消息路由
详解如何使用Istio监控基于容器的服务 https://www.cnblogs.com/davidwang456/articles/9311470.html
https://github.com/istio/istio