# 安裝并試用Istio service mesh
**注意:本文檔已失效,請瀏覽 [Istio 官方文檔](https://istio.io/zh)。本書中的 Service Mesh 章節已不再維護,請轉到 [istio-handbook](https://jimmysong.io/istio-handbook) 中瀏覽。**
官方文檔地址 [快速開始](https://istio.io/docs/setup/kubernetes/)
本文根據官網的文檔整理而成,步驟包括安裝**istio 0.5.1**并創建一個bookinfo的微服務來測試istio的功能。
文中使用的yaml文件可以在[kubernetes-handbook](https://github.com/rootsongjc/kubernetes-handbook)的`manifests/istio`目錄中找到,如果鏡像pull失敗,請根據官網的鏡像自行修改。
## 安裝環境
- CentOS 7.4.1708
- Docker 17.12.0-ce
- Kubernetes 1.8.5
## 部署結構
Istio 的控制平面部署在 Kubernetes 中的部署架構如下圖所示。

我們可以清楚的看到 Istio 控制平面的幾個組件的部署運行的命令與開發的端口,以及端口與服務之間的映射的關系。
## 安裝
**1.下載安裝包**
下載地址:https://github.com/istio/istio/releases
下載Linux版本的當前最新版安裝包
```bash
wget https://github.com/istio/istio/releases/download/0.5.1/istio-0.5.1-linux.tar.gz
```
**2.解壓**
解壓后,得到的目錄結構如下:
```bash
├── bin
│?? └── istioctl
├── install
│?? ├── ansible
│?? ├── consul
│?? ├── eureka
│?? ├── gcp
│?? ├── kubernetes
│?? ├── README.md
│?? └── tools
├── istio.VERSION
├── LICENSE
├── README.md
├── samples
│?? ├── bookinfo
│?? ├── CONFIG-MIGRATION.md
│?? ├── helloworld
│?? ├── httpbin
│?? ├── kubernetes-blog
│?? ├── rawvm
│?? ├── README.md
│?? └── sleep
└── tools
├── cache_buster.yaml
├── deb
├── githubContrib
├── minikube.md
├── perf_istio_rules.yaml
├── perf_k8svcs.yaml
├── README.md
├── rules.yml
├── setup_perf_cluster.sh
├── setup_run
├── update_all
└── vagrant
```
從文件里表中可以看到,安裝包中包括了kubernetes的yaml文件,示例應用和安裝模板。
**3.先決條件**
以下說明要求您可以訪問啟用了RBAC(基于角色的訪問控制)的Kubernetes1.7.3或更新的群集。您還需要安裝1.7.3或更高版本。如果您希望啟用automatic sidecar injection,則需要Kubernetes 1.9或更高版本。kubectl
注意:如果您安裝了Istio 0.1.x,請在安裝新版本之前徹底卸載它(包括適用于所有啟用Istio的應用程序窗口的Istio支架)。
安裝或升級Kubernetes CLIkubectl以匹配群集支持的版本(CRD支持版本為1.7或更高版本)。
根據您的Kubernetes提供者:
要在本地安裝Istio,請安裝最新版本的Minikube(版本0.22.1或更高版本)。
**4.安裝步驟**
從0.2版本開始,Istio安裝在它自己的istio-system命名空間中,并且可以管理來自所有其他命名空間的服務。
轉至Istio發布頁面以下載與您的操作系統相對應的安裝文件。如果您使用的是MacOS或Linux系統,以下命令自動下載并提取最新版本:
```bash
curl -L https://git.io/getLatestIstio | sh -
```
解壓縮安裝文件并將目錄更改為文件位置。
*安裝目錄包含*:
Installation .yaml Kubernetes的安裝文件
Sample/ 示例應用程序
bin/istioctl 二進制bin/文件 在手動注入Envoy作為附屬代理并創建路由規則和策略時使用.
istio.VERSION配置文件
例如,如果包是istio-0.5(初步)
```bash
cd istio-0.5 (preliminary)
```
將istioctl客戶端添加到您的PATH。例如,在MacOS或Linux系統上運行以下命令:
```bash
export PATH=$PWD/bin:$PATH
```
安裝Istio的核心組件。從下面兩個互相排斥的選項中選擇一個,或者用Helm Chart交替安裝:
a)安裝Istio而不啟用側車間的相互TLS認證。為具有現有應用程序的群集,使用Istio輔助車的服務需要能夠與其他非Istio Kubernetes服務以及使用活動性和準備就緒探測器,無頭服務或StatefulSets的應用程序通信的應用程序選擇此選項。
```bash
kubectl apply -f install/kubernetes/istio.yaml
```
**要么**
b)安裝Istio并啟用側柜之間的相互TLS認證:
```bash
kubectl apply -f install/kubernetes/istio-auth.yaml
```
這兩個選項都會創建istio-system命名空間以及所需的RBAC權限,并部署Istio-Pilot,Istio-Mixer,Istio-Ingress和Istio-CA(證書頒發機構)。
可選:如果您的群集的Kubernetes版本是1.9或更高,并且您希望啟用自動代理注入,請安裝sidecar injector webhook。
驗證安裝
請確保以下Kubernetes服務部署:istio-pilot,istio-mixer,istio-ingress。
```bash
kubectl get svc -n istio-system
```
```bash
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingress 10.83.245.171 35.184.245.62 80:32730/TCP,443:30574/TCP 5h
istio-pilot 10.83.251.173 <none> 8080/TCP,8081/TCP 5h
istio-mixer 10.83.244.253 <none> 9091/TCP,9094/TCP,42422/TCP 5h
```
> **注意**:如果您的集群中不支持外部負載平衡(例如,Minikube)的環境中運行,該external-ip的istio-ingress會顯示<pending>。您必須使用NodePort訪問應用程序,或使用端口轉發。
修改istio.yaml中的istio-ingress service的type為ClusterIP,并設置`nodePort`,默認為32000。
確保相應Kubernetes容器都運行起來:`istio-pilot-*`、`istio-mixer-*`、`istio-ingress-*`、`istio-ca-*`,和可選的`istio-sidecar-injector-*`。
```bash
kubectl get pods -n istio-system
```
```bash
istio-ca-3657790228-j21b9 1/1 Running 0 5h
istio-ingress-1842462111-j3vcs 1/1 Running 0 5h
istio-sidecar-injector-184129454-zdgf5 1/1 Running 0 5h
istio-pilot-2275554717-93c43 1/1 Running 0 5h
istio-mixer-2104784889-20rm8 2/2 Running 0 5h
```
**部署您的應用程序**
您現在可以部署您自己的應用程序或者像Bookinfo一樣隨安裝提供的示例應用程序之一。注意:應用程序必須對所有HTTP通信使用HTTP/1.1或HTTP/2.0協議,因為HTTP/1.0不受支持。
如果您啟動了Istio-sidecar-injector,如上所示,您可以直接使用應用程序部署應用程序kubectl create。
Istio Sidecar注入器會自動將Envoy容器注入到您的應用程序窗格中,假設運行在標有名稱空間的名稱空間中`istio-injection=enabled`
```bash
kubectl label namespace <namespace> istio-injection=enabled
```
```bash
kubectl create -n <namspace> -f <your-app-spec>.yaml
```
如果您沒有安裝Istio-sidecar-injector,則在部署它們之前,必須使用istioctl kube-inject將Envoy容器手動注入應用程序窗格中:
```bash
kubectl create -f <(istioctl kube-inject -f <your-app-spec>.yaml)
```
**卸載**
卸載Istio sidecar進樣器:
如果您啟用Istio-sidecar-injector,請將其卸載:
```bash
kubectl delete -f install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml
```
卸載Istio核心組件。對于0.6(初始)發行版,卸載將刪除RBAC權限,istio-system命名空間和分層下的所有資源。忽略不存在資源的錯誤是安全的,因為它們可能已被分層刪除。
a)如果您在禁用相互TLS身份驗證的情況下安裝了Istio:
```bash
kubectl delete -f install/kubernetes/istio.yaml
```
要么
b)如果您在啟用相互TLS身份驗證的情況下安裝了Istio:
```bash
kubectl delete -f install/kubernetes/istio-auth.yaml
```
**7.安裝監控插件**
安裝插件
```bash
kubectl apply -f install/kubernetes/addons/prometheus.yaml
kubectl apply -f install/kubernetes/addons/grafana.yaml
kubectl apply -f install/kubernetes/addons/servicegraph.yaml
kubectl apply -f install/kubernetes/addons/zipkin.yaml
```
在traefik ingress中增加增加以上幾個服務的配置,同時增加istio-ingress配置。
```yaml
- host: grafana.istio.io
http:
paths:
- path: /
backend:
serviceName: grafana
servicePort: 3000
- host: servicegraph.istio.io
http:
paths:
- path: /
backend:
serviceName: servicegraph
servicePort: 8088
- host: prometheus.istio.io
http:
paths:
- path: /
backend:
serviceName: prometheus
servicePort: 9090
- host: zipkin.istio.io
http:
paths:
- path: /
backend:
serviceName: zipkin
servicePort: 9411
- host: ingress.istio.io
http:
paths:
- path: /
backend:
serviceName: istio-ingress
servicePort: 80
```
## 測試
我們使用Istio提供的測試應用[bookinfo](https://istio.io/docs/samples/bookinfo.html)微服務來進行測試。
該微服務用到的鏡像有:
```
istio/examples-bookinfo-details-v1
istio/examples-bookinfo-ratings-v1
istio/examples-bookinfo-reviews-v1
istio/examples-bookinfo-reviews-v2
istio/examples-bookinfo-reviews-v3
istio/examples-bookinfo-productpage-v1
```
該應用架構圖如下:

**部署應用**
```
kubectl create -f <(istioctl kube-inject -f samples/apps/bookinfo/bookinfo.yaml)
```
`Istio kube-inject`命令會在`bookinfo.yaml`文件中增加Envoy sidecar信息。參考 https://istio.io/docs/reference/commands/istioctl/#istioctl-kube-inject
在本機的`/etc/hosts`下增加VIP節點和`ingress.istio.io`的對應信息,具體步驟參考:[邊緣節點配置](../practice/edge-node-configuration.md),或者使用gateway ingress來訪問服務,
如果將`productpage`配置在了ingress里了,那么在瀏覽器中訪問`http://ingress.istio.io/productpage`,如果使用了istio默認的`gateway` ingress配置的話,ingress service使用`nodePort`方式暴露的默認使用32000端口,那么可以使用 `http://任意節點的IP:32000/productpage` 來訪問。

多次刷新頁面,你會發現有的頁面上的評論里有星級打分,有的頁面就沒有,這是因為我們部署了三個版本的應用,有的應用里包含了評分,有的沒有。Istio根據默認策略隨機將流量分配到三個版本的應用上。
查看部署的bookinfo應用中的`productpage-v1` service和deployment,查看`productpage-v1`的pod的詳細json信息可以看到這樣的結構:
```bash
$ kubectl get pod productpage-v1-944450470-bd530 -o json
```
見[productpage-v1-istio.json](../manifests/istio/productpage-v1-istio.json)文件。從詳細輸出中可以看到這個Pod中實際有兩個容器,這里面包括了`initContainer`,作為istio植入到kubernetes deployment中的sidecar。
```json
"initContainers": [
{
"args": [
"-p",
"15001",
"-u",
"1337"
],
"image": "docker.io/istio/init:0.1",
"imagePullPolicy": "Always",
"name": "init",
"resources": {},
"securityContext": {
"capabilities": {
"add": [
"NET_ADMIN"
]
}
},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"name": "default-token-3l9f0",
"readOnly": true
}
]
},
{
"args": [
"-c",
"sysctl -w kernel.core_pattern=/tmp/core.%e.%p.%t \u0026\u0026 ulimit -c unlimited"
],
"command": [
"/bin/sh"
],
"image": "alpine",
"imagePullPolicy": "Always",
"name": "enable-core-dump",
"resources": {},
"securityContext": {
"privileged": true
},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"name": "default-token-3l9f0",
"readOnly": true
}
]
}
],
```
## 監控
不斷刷新productpage頁面,將可以在以下幾個監控中看到如下界面。
**Grafana頁面**
`http://grafana.istio.io`

**Prometheus頁面**
`http://prometheus.istio.io`

**Zipkin頁面**
`http://zipkin.istio.io`

**ServiceGraph頁面**
`http://servicegraph.istio.io/dotviz`
可以用來查看服務間的依賴關系。
訪問` http://servicegraph.istio.io/graph` 可以獲得json格式的返回結果。

## 更進一步
BookInfo示例中有三個版本的`reviews`,可以使用istio來配置路由請求,將流量分發到不同版本的應用上。參考[Configuring Request Routing](https://istio.io/docs/tasks/request-routing.html)。
還有一些更高級的功能,我們后續將進一步探索。
## 參考
- [安裝 Istio](https://istio.io/zh/docs/setup/kubernetes/)
- [BookInfo 應用](https://istio.io/zh/docs/examples/bookinfo/)
- 序言
- 云原生
- 云原生(Cloud Native)的定義
- CNCF - 云原生計算基金會簡介
- CNCF章程
- 云原生的設計哲學
- Play with Kubernetes
- 快速部署一個云原生本地實驗環境
- Kubernetes與云原生應用概覽
- 云原生應用之路——從Kubernetes到Cloud Native
- 云原生編程語言
- 云原生編程語言Ballerina
- 云原生編程語言Pulumi
- 云原生的未來
- Kubernetes架構
- 設計理念
- Etcd解析
- 開放接口
- CRI - Container Runtime Interface(容器運行時接口)
- CNI - Container Network Interface(容器網絡接口)
- CSI - Container Storage Interface(容器存儲接口)
- Kubernetes中的網絡
- Kubernetes中的網絡解析——以flannel為例
- Kubernetes中的網絡解析——以calico為例
- 具備API感知的網絡和安全性管理開源軟件Cilium
- Cilium架構設計與概念解析
- 資源對象與基本概念解析
- Pod狀態與生命周期管理
- Pod概覽
- Pod解析
- Init容器
- Pause容器
- Pod安全策略
- Pod的生命周期
- Pod Hook
- Pod Preset
- Pod中斷與PDB(Pod中斷預算)
- 集群資源管理
- Node
- Namespace
- Label
- Annotation
- Taint和Toleration(污點和容忍)
- 垃圾收集
- 控制器
- Deployment
- StatefulSet
- DaemonSet
- ReplicationController和ReplicaSet
- Job
- CronJob
- Horizontal Pod Autoscaling
- 自定義指標HPA
- 準入控制器(Admission Controller)
- 服務發現
- Service
- Ingress
- Traefik Ingress Controller
- 身份與權限控制
- ServiceAccount
- RBAC——基于角色的訪問控制
- NetworkPolicy
- 存儲
- Secret
- ConfigMap
- ConfigMap的熱更新
- Volume
- Persistent Volume(持久化卷)
- Storage Class
- 本地持久化存儲
- 集群擴展
- 使用自定義資源擴展API
- 使用CRD擴展Kubernetes API
- Aggregated API Server
- APIService
- Service Catalog
- 資源調度
- QoS(服務質量等級)
- 用戶指南
- 資源對象配置
- 配置Pod的liveness和readiness探針
- 配置Pod的Service Account
- Secret配置
- 管理namespace中的資源配額
- 命令使用
- Docker用戶過度到kubectl命令行指南
- kubectl命令概覽
- kubectl命令技巧大全
- 使用etcdctl訪問kubernetes數據
- 集群安全性管理
- 管理集群中的TLS
- kubelet的認證授權
- TLS bootstrap
- 創建用戶認證授權的kubeconfig文件
- IP偽裝代理
- 使用kubeconfig或token進行用戶身份認證
- Kubernetes中的用戶與身份認證授權
- Kubernetes集群安全性配置最佳實踐
- 訪問Kubernetes集群
- 訪問集群
- 使用kubeconfig文件配置跨集群認證
- 通過端口轉發訪問集群中的應用程序
- 使用service訪問群集中的應用程序
- 從外部訪問Kubernetes中的Pod
- Cabin - Kubernetes手機客戶端
- Kubernetic - Kubernetes桌面客戶端
- Kubernator - 更底層的Kubernetes UI
- 在Kubernetes中開發部署應用
- 適用于kubernetes的應用開發部署流程
- 遷移傳統應用到Kubernetes中——以Hadoop YARN為例
- 最佳實踐概覽
- 在CentOS上部署Kubernetes集群
- 創建TLS證書和秘鑰
- 創建kubeconfig文件
- 創建高可用etcd集群
- 安裝kubectl命令行工具
- 部署master節點
- 安裝flannel網絡插件
- 部署node節點
- 安裝kubedns插件
- 安裝dashboard插件
- 安裝heapster插件
- 安裝EFK插件
- 生產級的Kubernetes簡化管理工具kubeadm
- 使用kubeadm在Ubuntu Server 16.04上快速構建測試集群
- 服務發現與負載均衡
- 安裝Traefik ingress
- 分布式負載測試
- 網絡和集群性能測試
- 邊緣節點配置
- 安裝Nginx ingress
- 安裝配置DNS
- 安裝配置Kube-dns
- 安裝配置CoreDNS
- 運維管理
- Master節點高可用
- 服務滾動升級
- 應用日志收集
- 配置最佳實踐
- 集群及應用監控
- 數據持久化問題
- 管理容器的計算資源
- 集群聯邦
- 存儲管理
- GlusterFS
- 使用GlusterFS做持久化存儲
- 使用Heketi作為Kubernetes的持久存儲GlusterFS的external provisioner
- 在OpenShift中使用GlusterFS做持久化存儲
- GlusterD-2.0
- Ceph
- 用Helm托管安裝Ceph集群并提供后端存儲
- 使用Ceph做持久化存儲
- 使用rbd-provisioner提供rbd持久化存儲
- OpenEBS
- 使用OpenEBS做持久化存儲
- Rook
- NFS
- 利用NFS動態提供Kubernetes后端存儲卷
- 集群與應用監控
- Heapster
- 使用Heapster獲取集群和對象的metric數據
- Prometheus
- 使用Prometheus監控kubernetes集群
- Prometheus查詢語言PromQL使用說明
- 使用Vistio監控Istio服務網格中的流量
- 分布式跟蹤
- OpenTracing
- 服務編排管理
- 使用Helm管理Kubernetes應用
- 構建私有Chart倉庫
- 持續集成與發布
- 使用Jenkins進行持續集成與發布
- 使用Drone進行持續集成與發布
- 更新與升級
- 手動升級Kubernetes集群
- 升級dashboard
- 領域應用概覽
- 微服務架構
- 微服務中的服務發現
- 使用Java構建微服務并發布到Kubernetes平臺
- Spring Boot快速開始指南
- Service Mesh 服務網格
- 企業級服務網格架構
- Service Mesh基礎
- Service Mesh技術對比
- 采納和演進
- 定制和集成
- 總結
- Istio
- 安裝并試用Istio service mesh
- 配置請求的路由規則
- 安裝和拓展Istio service mesh
- 集成虛擬機
- Istio中sidecar的注入規范及示例
- 如何參與Istio社區及注意事項
- Istio教程
- Istio免費學習資源匯總
- 深入理解Istio Service Mesh中的Envoy Sidecar注入與流量劫持
- 深入理解Istio Service Mesh中的Envoy Sidecar代理的路由轉發
- Linkerd
- Linkerd 使用指南
- Conduit
- Condiut概覽
- 安裝Conduit
- Envoy
- Envoy的架構與基本術語
- Envoy作為前端代理
- Envoy mesh教程
- SOFAMesh
- SOFAMesh中的Dubbo on x-protocol
- SOFAMosn
- 使用 SOFAMosn 構建 SOFAMesh
- 大數據
- Spark standalone on Kubernetes
- 運行支持Kubernetes原生調度的Spark程序
- Serverless架構
- 理解Serverless
- FaaS-函數即服務
- OpenFaaS快速入門指南
- 邊緣計算
- 人工智能