一边逐步安装Istio组件,一边进行解释说明
这篇帖子是2019年富士通圣诞日历活动的第十天文章。
需要注意的是,这篇文章仅代表个人观点,并不代表公司或组织的立场。
概括
随着服务网格认知的普及,备受关注的开源软件Istio成为代表。
一方面,我们听到了想要尝试使用Istio的声音,但也有人声称Istio的组件太多,弄不懂。
确实,作为整体而言,Istio非常庞大。
然而,由于各个组件之间松散耦合,也可以只安装所需组件。
在这篇文章中,我们将一一安装并对各个组件进行解释说明。
环境
-
- MacBook Air
-
- CPU: 3, Memory: 8GiB
-
- Docker Version: 19.03.5
-
- Kubernetes Version: v1.15.5
-
- Istio Version: 1.4.1
- Helm Version: v2.12.0
※Kubernetes正在使用Docker for Kubernetes。
Istio的整体图景
首先,我将解释Istio的整体框架。
Istio有大致如上所述的组件存在。
其大概的运作方式是,在服务之间的通信中有一个名为Envoy的代理,它充当着所有通信(入站和出站)的中间人。
在服务之间的通信中,Envoy替我们承担了一些麻烦的事情,比如超时和流量控制等。
其他组件将在后面进行说明,但它们主要是控制和收集Envoy的相关信息。
那么,我们将在实际安装时进行逐步解释。
请参考以下网址:https://istio.io/docs/ops/deployment/architecture/
Istio安装前的准备工作
我打算使用helm命令来安装组件。以下是helm安装和准备istio模板的方法。
$ brew install helm
$ helm version
$ curl -L https://istio.io/downloadIstio | sh -
$ sudo cp istio-1.4.1/bin/istioctl /usr/local/bin
$ istioctl version
然后,安装用于组件安装的前置步骤的Namespsce和CRD(Custom Resource Definition)。
$ kubectl create namespace istio-system
$ helm template istio-1.4.1/install/kubernetes/helm/istio-init --name istio-init --namespace istio-system | k apply -f -
参考: 下面是中文的原生释义,只需要提供一种选项:
– 参考:
- helmでのセットアップ: https://istio.io/docs/setup/install/helm/
核心组件
飞行员
Pilot是一个用于将用户在Kubernetes中设置的CRD(自定义资源定义)的值传递给Envoy的组件。通过这个组件,可以解析DestinationRule和VirtualService等资源,并将其反映为Envoy的配置。
通过安装Pilot,可以实现的操作。
可以实现负载均衡和根据特定版本发送请求的流量管理。
-
- Traffic Management一覧
特定のバージョンのみへのルーティング
Fault Injection(強制的にInternal Server Errorを返すなど)
リクエストにtimeoutを設定
Circuit Breaking
部署指令
本次,我们准备了helm的value文件,并且使用template命令从那里开始创建kubernetes的yaml文件。
$ vi values-pilot.yaml
# ※下記参照
$ helm template istio-1.4.1/install/kubernetes/helm/istio --name istio --namespace istio-system --values values-pilot.yaml > pilot.yaml
$ kubectl apply -f pilot.yaml
pilot:
enabled: true
sidecar: false
gateways:
enabled: false
security:
enabled: false
sidecarInjectorWebhook:
enabled: false
galley:
enabled: false
mixer:
policy:
enabled: false
telemetry:
enabled: false
prometheus:
enabled: false
# Common settings.
global:
proxy:
envoyStatsd:
enabled: false
useMCP: false
考试 shì)
这个测试应用程序将使用BookInfo。我想在这次只发送所有请求到v1。
$ vi istio-1.4.1/samples/bookinfo/platform/kube/bookinfo.yaml
# とりあえずアクセスするためにProductpageのServiceをNodePortにします(下記参照)
$ istioctl kube-inject -f istio-1.4.1/samples/bookinfo/platform/kube/bookinfo.yaml | kubectl apply -f -
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-5c76c87c6-5w2pr 2/2 Running 0 4m53s
productpage-v1-7bc5cb86bd-9srfr 2/2 Running 0 4m50s
ratings-v1-5597f5d56d-zr225 2/2 Running 0 4m51s
reviews-v1-67b6db665d-48968 2/2 Running 0 4m52s
reviews-v2-5f78d5fdf9-zvcff 2/2 Running 0 4m52s
reviews-v3-69f68ff8bd-fxsfc 2/2 Running 0 4m52s
# 動作しているかブラウザから確認(http://localhost:30000/productpage)
# 何度か更新するとレビューの星が黒や赤や無くなったりするはずです
$ kubectl apply -f istio-1.4.1/samples/bookinfo/networking/destination-rule-all.yaml
$ kubectl apply -f istio-1.4.1/samples/bookinfo/networking/virtual-service-all-v1.yaml
# ブラウザからアクセスするとreviewの星がない状態しか表示されなくなる
# ・・・(省略)
# 240行目付近
apiVersion: v1
kind: Service
metadata:
name: productpage
labels:
app: productpage
service: productpage
spec:
type: NodePort
ports:
- port: 9080
name: http
nodePort: 30000
selector:
app: productpage
---
# ・・・(省略)
我认为由于Pod使用Envoy启动,所以可以确认READY状态为2/2。
此外,我认为可以确认只能路由到特定版本。
请参考:
-
- Traffic Management: https://istio.io/docs/tasks/traffic-management/
BookInfoアプリ: https://istio.io/docs/examples/bookinfo/
政策
Policy是Mixer的一个组件,用于为Envoy设置访问策略,包括流量控制和黑名单/白名单的访问控制。
部署指令
我們將先前的values-pilot.yaml文件中的policy項目設置為enable。
同時,將disablePolicyChecks設置為false。
# ・・・(省略)
mixer:
policy:
enabled: true
telemetry:
enabled: false
# ・・・(省略)
global:
disablePolicyChecks: false
# ・・・(省略)
$ helm template istio-1.4.1/install/kubernetes/helm/istio --name istio --namespace istio-system --values values-policy.yaml > policy.yaml
$ kubectl apply -f policy.yaml
考试 shì)
我們這次將通過黑名單禁止對helloworld服務的v3版本(評論星星為紅色)進行訪問。
# all-v1のルールは削除しておきます
$ kubectl delete -f istio-1.4.1/samples/bookinfo/networking/virtual-service-all-v1.yaml
$ kubectl apply -f istio-1.4.1/samples/bookinfo/policy/mixer-rule-deny-label.yaml
# ブラウザを更新し続けると以下のようにアクセスできなくなっているのが確認できると思います
# Ratings service is currently unavailable
遥测
遥测(Telemetry)也是Mixer的一部分,它从Envoy收集指标和日志信息。收集到的数据通过Mixer适配器发送到连接的后端,例如Prometheus和Datadog。适配器的作用是将istio的数据格式转换为各个后端的数据格式,例如,Prometheus适配器会将从Envoy收集的指标转换为Prometheus的格式并发送。你也可以自己制作适配器,以将数据发送到任意后端。
部署指令
这次我们也会像之前一样创建values文件。
※由于遥测通常有非常多的资源请求,默认进行了减少。
# ・・・(省略)
mixer:
policy:
enabled: true
telemetry:
enabled: true
resources:
requests:
cpu: 200m
memory: 500Mi
# ・・・(省略)
$ helm template istio-1.4.1/install/kubernetes/helm/istio --name istio --namespace istio-system --values values-telemetry.yaml > telemetry.yaml
$ kubectl apply -f telemetry.yaml
考试 shì)
我认为最简单易懂的使用方法是将信息发送到Prometheus,所以顺便也试着安装Prometheus。
我将通过修改 values-telemetry.yaml 文件将 Prometheus 设置为开启状态。
# ・・・(省略)
prometheus:
enabled: true
service:
nodePort:
enabled: true
security:
enabled: false
# ・・・(省略)
当您访问http://localhost:32090时,您应该能够看到Prometheus的用户界面,并确认可以获取到度量信息。
入口/出口网关
首先,Ingress Gateway是用于控制外部与集群之间通信的组件。
类似于Kubernetes的Ingress Controller(都用于控制L7通信),但Istio Ingress Gateway可以进行更详细的配置。
Egress Gateway则是控制集群内向外部的通信的组件。
本次只介绍Ingress Gateway。
部署指令
我們將從之前的values-telemetry.yaml文件中設置gateways的項目。
# ・・・(省略)
gateways:
istio-ingressgateway:
autoscaleEnabled: false
resources:
requests:
cpu: 10m
memory: 40Mi
istio-egressgateway:
enabled: false
# ・・・(省略)
$ helm template istio-1.4.1/install/kubernetes/helm/istio --name istio --namespace istio-system --values values-gateways.yaml > gateways.yaml
$ kubectl apply -f gateways.yaml
考试
首先,我们会删除先前设置的bookinfo的NodePort配置,因为它不再需要。
然后,我们会部署适用于Istio IngressGateway的资源。
$ vi istio-1.4.1/samples/bookinfo/platform/kube/bookinfo.yaml
# ※下記参照
$ istioctl kube-inject -f istio-1.4.1/samples/bookinfo/platform/kube/bookinfo.yaml | kubectl apply -f -
$ kubectl apply -f istio-1.4.1/samples/bookinfo/networking/bookinfo-gateway.yaml
# ・・・(省略)
# 240行目付近
apiVersion: v1
kind: Service
metadata:
name: productpage
labels:
app: productpage
service: productpage
spec:
ports:
- port: 9080
name: http
selector:
app: productpage
---
# ・・・(省略)
最后,我们将通过浏览器访问http://localhost/productpage(istio-ingressgateway的服务地址)。
城堡
Citadel是Istio的安全组件。
Istio有以下两个安全功能:
-
- Mutual TLS(相互認証)
- Istio RBAC(Role Based Access Control)
互相验证
在SSL服务等常规https的情况下,认证是指客户端对服务器的身份进行验证。
而在互相认证中,客户端在认证服务器的同时,服务器也会对客户端的身份进行验证。
通过这种方式,可以确保在服务之间进行安全的通信。
通常需要SSL证书进行认证。
证书的发行和管理等处理是相当复杂的,但在Istio中,Citadel会负责管理所有这些证书。
Istio 访问控制
Istio RBAC是Istio访问控制功能之一。
类似于Kubernetes的RBAC,可以用于控制服务之间的通信访问。(k8s用于资源访问控制)
例如,可以设置只允许用户A访问serviceA的GET /path接口。
山寨堡可以做的事情。
-
- サービス間(Envoy間)通信の暗号化
-
- 通信先の認証(※k8s Cluster外サービスを除く)
- Roleによる通信の認可
如果您想要更详细地了解k8s、istio的安全性方面的问题,请务必参考我的GitHub(https://github.com/sh-miyoshi/sectest)。
部署流程
我将打开先前的values-gateways.yaml中有关Citadel部分的项目。
# ・・・(省略)
security:
enabled: true
# ・・・(省略)
global:
disablePolicyChecks: false
proxy:
envoyStatsd:
enabled: false
useMCP: false
mlts:
enabled: true
# ・・・(省略)
$ helm template istio-1.4.1/install/kubernetes/helm/istio --name istio --namespace istio-system --values values-citadel.yaml > citadel.yaml
$ kubectl apply -f citadel.yaml
考试
為了外觀的一致性,本次將省略。請注意,在關閉安全模式後,請先刪除已建立的bookinfo應用,然後再重新部署。有關測試方法等,請參考我的GitHub(https://github.com/sh-miyoshi/sectest)。
侧车注入器
Sidecar Injector是一個組件,它可以檢測Pod的啟動並自動插入Envoy(istio-proxy)。
以前,我們需要使用istioctl kube-inject命令來創建一個插入Envoy(istio-proxy)的YAML文件,然後使用kubectl apply命令來部署它。
有了這個組件,它可以自動插入,非常方便。
部署指令
我会从之前的values-citadel.yaml文件中将sidecarInjectorWebhook的项目设置为enable。
*在我的环境中,如果没有启用Citadel,无法启动。
# ・・・(省略)
sidecarInjectorWebhook:
enabled: true
# ・・・(省略)
$ helm template istio-1.4.1/install/kubernetes/helm/istio --name istio --namespace istio-system --values values-injector.yaml > injector.yaml
$ kubectl apply -f injector.yaml
使用方法
只需为auto inject的命名空间添加标签,然后使用kubectl命令部署即可。
# 一旦削除
$ ./istio-1.4.1/samples/bookinfo/platform/kube/cleanup.sh
$ kubectl label namespace default istio-injection=enabled
$ kubectl apply -f istio-1.4.1/samples/bookinfo/platform/kube/bookinfo.yaml
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-74f858558f-krpqv 2/2 Running 0 3m36s
productpage-v1-8554d58bff-2l57q 2/2 Running 0 3m33s
ratings-v1-7855f5bcb9-xzcvc 2/2 Running 0 3m36s
reviews-v1-59fd8b965b-7nm8r 2/2 Running 0 3m34s
reviews-v2-d6cfdb7d6-kdmg2 2/2 Running 0 3m35s
reviews-v3-75699b5cfb-86tqh 2/2 Running 0 3m35s
舱
听说这个组件可以帮助用户执行自定义的Istio设置验证。
不好意思,我对Galley的了解不是很详细,无法具体解释会发生什么……
附加组件
最后,我会介绍一些似乎会有用的istio核心组件,但不包括核心部分。
追溯
基本来说,它可以帮助你引入Jaeger或zipkin等分布式追踪工具。你可以知道在多个服务之间的通信中,每个部分花费了多长时间。
部署指令
请按照以往修改values文件,并使用helm命令进行部署。
# ・・・(省略)
tracing:
enabled: true
service:
type: LoadBalancer
# ・・・(省略)
$ helm template istio-1.4.1/install/kubernetes/helm/istio --name istio --namespace istio-system --values values-tracing.yaml > tracing.yaml
$ kubectl apply -f tracing.yaml
确认步骤
当您访问 http://localhost:(node-port) ,将能够看到Jaeger的仪表盘。
请尝试发送一些请求并查看数据。您可以使用类似于 kubectl get svc -n istio-system tracing -o json | jq .spec.ports[0].nodePort 的命令来获取 node-port 信息。
Kiali 凯利
Kiali是一个用于可视化微服务中发生的情况的图形用户界面(GUI)组件。
在Web UI界面上,您可以通过Kiali直观地确认哪些服务正在通信,以及它们目前的状态。
部署指令
请像之前一样修改values文件,并使用helm命令进行部署。
# ・・・(省略)
kiali:
enabled: true
createDemoSecret: true
# ・・・(省略)
$ helm template istio-1.4.1/install/kubernetes/helm/istio --name istio --namespace istio-system --values values-kiali.yaml > kiali.yaml
$ kubectl apply -f kiali.yaml
确认的方式
由于Kiali没有使用NodePort或LoadBalancer来访问的方式,所以我们可以使用kubectl port-forward命令来进行访问。
$ kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=kiali -o jsonpath='{.items[0].metadata.name}') 20001:20001
当你访问http://localhost:20001时,你将能够看到各种不同的图表。
值得注意的是,登录信息为admin/admin。(※如果createDemoSecret为true)
总结
Istio整体上很庞大,但每个组件都是独立的,您可以根据需要进行安装。
本次介绍了逐个组件进行安装的步骤。
如果本文对您理解Istio有所帮助,我将感到非常荣幸。
额外的东西
最终的values.yaml文件
pilot:
enabled: true
sidecar: false
gateways:
istio-ingressgateway:
autoscaleEnabled: false
resources:
requests:
cpu: 10m
memory: 40Mi
istio-egressgateway:
enabled: false
security:
enabled: true
sidecarInjectorWebhook:
enabled: true
galley:
enabled: false
mixer:
policy:
enabled: true
telemetry:
enabled: true
resources:
requests:
cpu: 200m
memory: 500Mi
prometheus:
enabled: true
service:
nodePort:
enabled: true
security:
enabled: true
# Common settings.
global:
disablePolicyChecks: false
proxy:
envoyStatsd:
enabled: false
useMCP: true
mlts:
enabled: true
tracing:
enabled: true
service:
type: NodePort
kiali:
enabled: true
createDemoSecret: true