Istio安装配置及使用

Istio是一个开放平台,提供统一的方法来集成微服务、管理跨微服务的交通流、执行政策和聚合遥测数据。Istio的控制平面在底层的集群管理平台(如Kubernetes)上提供了一个抽象层。

1. k8s安装Istio

软件下载地址:https://github.com/istio/istio/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@k8s-master ~]# wget https://github.com/istio/istio/releases/download/1.12.0/istio-1.12.0-linux-amd64.tar.gz
[root@k8s-master1 ~]# ls
istio-1.12.0-linux-amd64.tar.gz
[root@k8s-master ~]# tar xf istio-1.12.0-linux-amd64.tar.gz
[root@k8s-master ~]# cd istio-1.12.0/
[root@k8s-master istio-1.12.0]# ll
total 28
drwxr-x--- 2 root root 22 Nov 19 01:38 bin
-rw-r--r-- 1 root root 11348 Nov 19 01:38 LICENSE
drwxr-xr-x 5 root root 52 Nov 19 01:38 manifests
-rw-r----- 1 root root 827 Nov 19 01:38 manifest.yaml
-rw-r--r-- 1 root root 5866 Nov 19 01:38 README.md
drwxr-xr-x 21 root root 4096 Nov 19 01:38 samples
drwxr-xr-x 3 root root 57 Nov 19 01:38 tools

# 拷贝istioctl到/usr/bin下
[root@k8s-master istio-1.12.0]# cp bin/istioctl /usr/bin/

安装

1
2
3
4
5
6
7
8
[root@k8s-master istio-1.12.0]# istioctl install --set profile=demo -y
✔ Istio core installed
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete
Making this installation the default for injection and validation.
Thank you for installing Istio 1.12. Please take a few minutes to tell us about your install/upgrade experience! https://forms.gle/FegQbc9UvePd4Z9z7

验证istio是否部署成功

1
2
3
4
5
[root@k8s-master istio-1.12.0]# kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
istio-egressgateway-7f4864f59c-wglp2 1/1 Running 0 16m
istio-ingressgateway-55d9fb9f-zrscz 1/1 Running 0 16m
istiod-555d47cb65-2jm2t 1/1 Running 0 16m

如果需要卸载,执行如下命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@k8s-master istio-1.12.0]# istioctl manifest generate --set profile=demo | kubectl delete -f -

customresourcedefinition.apiextensions.k8s.io "authorizationpolicies.security.istio.io" deleted
customresourcedefinition.apiextensions.k8s.io "destinationrules.networking.istio.io" deleted
customresourcedefinition.apiextensions.k8s.io "envoyfilters.networking.istio.io" deleted
customresourcedefinition.apiextensions.k8s.io "gateways.networking.istio.io" deleted
customresourcedefinition.apiextensions.k8s.io "istiooperators.install.istio.io" deleted
customresourcedefinition.apiextensions.k8s.io "peerauthentications.security.istio.io" deleted
customresourcedefinition.apiextensions.k8s.io "requestauthentications.security.istio.io" deleted
customresourcedefinition.apiextensions.k8s.io "serviceentries.networking.istio.io" deleted
customresourcedefinition.apiextensions.k8s.io "sidecars.networking.istio.io" deleted
customresourcedefinition.apiextensions.k8s.io "telemetries.telemetry.istio.io" deleted
customresourcedefinition.apiextensions.k8s.io "virtualservices.networking.istio.io" deleted
customresourcedefinition.apiextensions.k8s.io "wasmplugins.extensions.istio.io" deleted
........

2. Istio部署在线书店bookinfo

2.1. 在线书城功能介绍

在线书店-bookinfo:该应用由四个单独的微服务构成,这个应用模仿在线书店的一个分类,显示一本书的信息,页面上会显示一本书的描述,书籍的细节(ISBN、页数等),以及关于这本书的一些评论。

Bookinfo应用分为四个单独的微服务
1)productpage这个微服务会调用details和reviews两个微服务,用来生成页面;
2)details这个微服务中包含了书籍的信息;
3)reviews这个微服务中包含了书籍相关的评论,它还会调用ratings微服务;
4)ratings这个微服务中包含了由书籍评价组成的评级信息。

reviews微服务有3个版本
1)v1版本不会调用ratings服务;
2)v2版本会调用ratings服务,并使用1到5个黑色星形图标来显示评分信息;
3)v3版本会调用ratings服务,并使用1到5个红色星形图标来显示评分信息。

Bookinfo应用中的几个微服务是由不同的语言编写的。这些服务对istio并无依赖,但是构成了一个有代表性的服务网格的例子:它由多个服务、多个语言构成,并且reviews服务具有多个版本。

要在Istio中运行这一应用,无需对应用自身做出任何改变。 只要简单的在 Istio 环境中对服务进行配置和运行,具体一点说就是把 Envoy sidecar 注入到每个服务之中。 最终的部署结果将如下图所示:

所有的微服务都和Envoy sidecar集成在一起,被集成服务所有的出入流量都被envoy sidecar 所劫持,这样就为外部控制准备了所需的 Hook,然后就可以利用Istio控制平面为应用提供服务路由、遥测数据收集以及策略实施等功能。

2.2. 在线书城部署

istio默认自动注入 sidecar,需要为default命名空间打上标签istio-injection=enabled

1
2
3
4
5
[root@k8s-master istio-1.12.0]# kubectl label namespace default istio-injection=enabled
namespace/default labeled

[root@k8s-master istio-1.12.0]# kubectl describe ns default |grep istio-injection
Labels: istio-injection=enabled

部署应用bookinfo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@k8s-master istio-1.12.0]# ls samples/bookinfo/platform/kube/bookinfo.yaml 
samples/bookinfo/platform/kube/bookinfo.yaml

[root@k8s-master istio-1.12.0]# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created

确认所有的服务和 Pod 都已经正确的定义和启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@k8s-master istio-1.12.0]# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.106.21.152 <none> 9080/TCP 48s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20d
nginx ClusterIP 10.103.198.110 <none> 8000/TCP 17d
productpage ClusterIP 10.105.235.207 <none> 9080/TCP 48s
ratings ClusterIP 10.98.222.244 <none> 9080/TCP 48s
reviews ClusterIP 10.108.100.54 <none> 9080/TCP 48s

[root@k8s-master istio-1.12.0]# kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-79f774bdb9-x27dm 2/2 Running 0 75s
nginx-6799fc88d8-hfhwt 1/1 Running 3 (2d2h ago) 17d
productpage-v1-6b746f74dc-98prq 2/2 Running 0 75s
ratings-v1-b6994bb9-nf5hl 2/2 Running 0 75s
reviews-v1-545db77b95-snh2s 2/2 Running 0 75s
reviews-v2-7bf8c9648f-s8d8n 2/2 Running 0 75s
reviews-v3-84779c7bbc-9w7vj 2/2 Running 0 75s

确认 Bookinfo 应用是否正在运行,在某个Pod中用curl命令对应用发送请求,例如ratings:

1
2
[root@k8s-master istio-1.12.0]# kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title> #出现这个表示正常

确定Ingress的IP和端口

现在Bookinfo服务已经启动并运行,你需要使应用程序可以从Kubernetes集群外部访问,例如从浏览器访问,那可以用Istio Gateway来实现这个目标。

为应用程序定义gateway网关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
[root@k8s-master istio-1.12.0]# cat samples/bookinfo/networking/bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080

应用yaml文件

1
2
3
4
5
6
7
8
9
10
11
[root@k8s-master istio-1.12.0]# kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created

[root@k8s-master istio-1.12.0]# kubectl get gateway
NAME AGE
bookinfo-gateway 33s

[root@k8s-master istio-1.12.0]# kubectl get virtualservice
NAME GATEWAYS HOSTS AGE
bookinfo ["bookinfo-gateway"] ["*"] 51s

确定ingress ip和端口

1
2
3
[root@k8s-master istio-1.12.0]# kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.102.214.74 <pending> 15021:31077/TCP,80:30181/TCP,443:31334/TCP,31400:32201/TCP,15443:30785/TCP 16m

如果EXTERNAL-IP值已设置,说明环境正在使用外部负载均衡,可以用其为ingress gateway 提供服务。 如果EXTERNAL-IP值为(或持续显示), 说明环境没有提供外部负载均衡,无法使用ingress gateway。在这种情况下,你可以使用服务的NodePort访问网关。

获取Istio Gateway的地址

1
2
3
4
5
6
[root@k8s-master istio-1.12.0]# export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
[root@k8s-master istio-1.12.0]# echo $INGRESS_PORT
30181
[root@k8s-master istio-1.12.0]# export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
[root@k8s-master istio-1.12.0]# echo $SECURE_INGRESS_PORT
31334

设置GATEWAY_URL

1
2
3
4
[root@k8s-master istio-1.12.0]# INGRESS_HOST=192.168.101.201
[root@k8s-master istio-1.12.0]# export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
[root@k8s-master istio-1.12.0]# echo $GATEWAY_URL
192.168.101.201:30181

curl命令来确认是否能够从集群外部访问 Bookinfo 应用程序

1
2
[root@k8s-master istio-1.12.0]# curl -s http://${GATEWAY_URL}/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>

浏览器打开网址http://$GATEWAY_URL/productpage,也就是192.168.101.201:30181/productpage来浏览应用的Web页面,如果刷新几次应用的页面,就会看到 productpage 页面中会随机展示 reviews 服务的不同版本的效果(红色、黑色的星形或者没有显示)

istio的ingressgateway访问:https://istio.io/docs/examples/bookinfo/#determine-the-ingress-ip-and-port

扩展:添加外部IP-extertal-IP

1
2
3
4
5
6
7
8
9
10
11
12
[root@k8s-master istio-1.12.0]# kubectl edit svc istio-ingressgateway -n istio-system
spec:
allocateLoadBalancerNodePorts: true
clusterIP: 10.102.214.74
clusterIPs:
- 10.102.214.74
externalIPs:
- 192.168.101.201

[root@k8s-master istio-1.12.0]# kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.102.214.74 192.168.101.201 15021:31077/TCP,80:30181/TCP,443:31334/TCP,31400:32201/TCP,15443:30785/TCP 27m

配置域名解析

1
192.168.101.201 productpage.kubelet.cn

在浏览器访问:http://productpage.kubelet.cn/productpage

2.3. 卸载bookinfo服务

删除路由规则,并销毁应用的 Pod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@k8s-master istio-1.12.0]# sh samples/bookinfo/platform/kube/cleanup.sh
namespace ? [default]
using NAMESPACE=default
virtualservice.networking.istio.io "bookinfo" deleted
gateway.networking.istio.io "bookinfo-gateway" deleted
Application cleanup may take up to one minute
service "details" deleted
serviceaccount "bookinfo-details" deleted
deployment.apps "details-v1" deleted
service "ratings" deleted
serviceaccount "bookinfo-ratings" deleted
deployment.apps "ratings-v1" deleted
service "reviews" deleted
serviceaccount "bookinfo-reviews" deleted
deployment.apps "reviews-v1" deleted
deployment.apps "reviews-v2" deleted
deployment.apps "reviews-v3" deleted
service "productpage" deleted
serviceaccount "bookinfo-productpage" deleted
deployment.apps "productpage-v1" deleted
Application cleanup successful

确认应用已经关停

1
2
3
4
kubectl get virtualservices     #-- there should be no virtual services
kubectl get destinationrules #-- there should be no destination rules
kubectl get gateway #-- there should be no gateway
kubectl get pods #-- the Bookinfo pods should be deleted
-------------本文结束感谢您的阅读-------------