# 安裝和拓展 Istio mesh
**注意:本文檔已失效,請瀏覽 [Istio 官方文檔](https://istio.io/zh)。本書中的 Service Mesh 章節已不再維護,請轉到 [istio-handbook](https://jimmysong.io/istio-handbook) 中瀏覽。**
## 前置條件
下面的操作說明需要您可以訪問 kubernetes **1.7.3 后更高版本** 的集群,并且啟用了 [RBAC (基于角色的訪問控制)](https://kubernetes.io/docs/admin/authorization/rbac/)。您需要安裝了 **1.7.3 或更高版本** 的 `kubectl` 命令。如果您希望啟用自動注入 sidecar,您需要啟用 kubernetes 集群的 alpha 功能。
> 注意:如果您安裝了 Istio 0.1.x,在安裝新版本前請先卸載它們(包括已啟用 Istio 應用程序 Pod 中的 sidecar)。
- 取決于您的 kubernetes 提供商:
- 本地安裝 Istio,安裝最新版本的 [Minikube](https://kubernetes.io/docs/getting-started-guides/minikube/) (version 0.22.1 或者更高)。
- [Google Container Engine](https://cloud.google.com/container-engine)
- 使用 kubectl 獲取證書 (使用您自己的集群的名字替換 `<cluster-name>` ,使用集群實際所在的位置替換 `<zone>` ):
```bash
gcloud container clusters get-credentials <cluster-name> --zone <zone> --project <project-name>
```
- 將集群管理員權限授予當前用戶(需要管理員權限才能為Istio創建必要的RBAC規則):
```bash
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value core/account)
```
- [IBM Bluemix Container Service](https://www.ibm.com/cloud-computing/bluemix/containers)
- 使用 kubectl 獲取證書 (使用您自己的集群的名字替換):
```bash
<cluster-name>
```
```bash
$(bx cs cluster-config <cluster-name>|grep "export KUBECONFIG")
```
- [Openshift Origin](https://www.openshift.org/) 3.7 或者以上版本:
- 默認情況下,Openshift 不允許以 UID 0運行容器。為 Istio 的入口(ingress)和出口(egress)service account 啟用使用UID 0運行的容器:
```bash
oc adm policy add-scc-to-user anyuid -z istio-ingress-service-account -n istio-system
oc adm policy add-scc-to-user anyuid -z istio-egress-service-account -n istio-system
oc adm policy add-sc-to-user anyuid -z default -n istio-system
```
- 運行應用程序 Pod 的 service account 需要特權安全性上下文限制,以此作為 sidecar 注入的一部分:
```bash
oc adm policy add-scc-to-user privileged -z default -n <target-namespace>
```
- 安裝或升級 Kubernetes 命令行工具 [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) 以匹配您的集群版本(1.7或以上版本)。
## 安裝步驟
不論對于哪個 Istio 發行版,都安裝到 `istio-system` namespace 下,即可以管理所有其它 namespace 下的微服務。
1. 到 [Istio release](https://github.com/istio/istio/releases) 頁面上,根據您的操作系統下載對應的發行版。如果您使用的是 MacOS 或者 Linux 系統,可以使用下面的額命令自動下載和解壓最新的發行版:
```bash
curl -L https://git.io/getLatestIstio | sh -
```
2. 解壓安裝文件,切換到文件所在目錄。安裝文件目錄下包含:
- `install/` 目錄下是 kubernetes 使用的 `.yaml` 安裝文件
- `samples/` 目錄下是示例程序
- `istioctl` 客戶端二進制文件在 `bin` 目錄下。`istioctl` 文件用戶手動注入 Envoy sidecar 代理、創建路由和策略等。
- `istio.VERSION` 配置文件
3. 切換到 istio 包的解壓目錄。例如 istio-0.2.7:
```bash
cd istio-0.2.7
```
4. 將 `istioctl` 客戶端二進制文件加到 PATH 中。
例如,在 MacOS 或 Linux 系統上執行下面的命令:
```bash
export PATH=$PWD/bin:$PATH
```
5. 安裝 Istio 的核心部分。選擇面兩個 **互斥** 選項中的之一:
a) 安裝 Istio 的時候不啟用 sidecar 之間的 TLS 雙向認證:
為具有現在應用程序的集群選擇該選項,使用 Istio sidecar 的服務需要能夠與非 Istio Kubernetes 服務以及使用 [liveliness 和 readiness 探針](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/)、headless service 和 StatefulSet 的應用程序通信。
```bash
kubectl apply -f install/kubernetes/istio.yaml
```
**或者**
b) 安裝 Istio 的時候啟用 sidecar 之間的 TLS 雙向認證:
```bash
kubectl apply -f install/kubernetes/istio-auth.yaml
```
這兩個選項都會創建 `istio-system` 命名空間以及所需的 RBAC 權限,并部署 Istio-Pilot、Istio-Mixer、Istio-Ingress、Istio-Egress 和 Istio-CA(證書頒發機構)。
6. *可選的*:如果您的 kubernetes 集群開啟了 alpha 功能,并想要啟用自動注入 sidecar,需要安裝 Istio-Initializer:
```bash
kubectl apply -f install/kubernetes/istio-initializer.yaml
```
## 驗證安裝
1. 確認系列 kubernetes 服務已經部署了: `istio-pilot`、 `istio-mixer`、`istio-ingress`、 `istio-egress`:
```bash
kubectl get svc -n istio-system
```
```bash
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-egress 10.83.247.89 <none> 80/TCP 5h
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), `istio-ingress` 服務的 `EXTERNAL-IP` 顯示`<pending>`。你必須改為使用 NodePort service 或者 端口轉發方式來訪問應用程序。
2. 確認對應的 Kubernetes pod 已部署并且所有的容器都啟動并運行: `istio-pilot-*`、 `istio-mixer-*`、 `istio-ingress-*`、 `istio-egress-*`、`istio-ca-*`, `istio-initializer-*` 是可以選的。
```bash
kubectl get pods -n istio-system
```
```bash
istio-ca-3657790228-j21b9 1/1 Running 0 5h
istio-egress-1684034556-fhw89 1/1 Running 0 5h
istio-ingress-1842462111-j3vcs 1/1 Running 0 5h
istio-initializer-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/1.1 或 HTTP/2.0 協議來傳輸 HTTP 流量,因為 HTTP/1.0 已經不再支持。
如果您啟動了 Istio-Initializer,如上所示,您可以使用 `kubectl create` 直接部署應用。Istio-Initializer 會向應用程序的 pod 中自動注入 Envoy 容器:
```bash
kubectl create -f <your-app-spec>.yaml
```
如果您沒有安裝 Istio-initializer 的話,您必須使用 istioctl kube-inject 命令在部署應用之前向應用程序的 pod 中手動注入 Envoy 容器:
```bash
kubectl create -f <(istioctl kube-inject -f <your-app-spec>.yaml)
```
## 卸載
- 卸載 Istio initializer:
如果您安裝 Isto 的時候啟用了 initializer,請卸載它:
```bash
kubectl delete -f install/kubernetes/istio-initializer.yaml
```
- 卸載 Istio 核心組件。對于某一 Istio 版本,刪除 RBAC 權限,`istio-system` namespace,和該命名空間的下的各層級資源。
不必理會在層級刪除過程中的各種報錯,因為這些資源可能已經被刪除的。
a) 如果您在安裝 Istio 的時候關閉了 TLS 雙向認證:
```bash
kubectl delete -f install/kubernetes/istio.yaml
```
**或者**
b) 如果您在安裝 Istio 的時候啟用到了 TLS 雙向認證:
```bash
kubectl delete -f install/kubernetes/istio-auth.yaml
```
# 安裝 Istio Sidecar
## Pod Spec 需滿足的條件
為了成為 Service Mesh 中的一部分,kubernetes 集群中的每個 Pod 都必須滿足如下條件:
1. **Service 注解**:每個 pod 都必須只屬于某**一個** [Kubernetes Service](https://kubernetes.io/docs/concepts/services-networking/service/) (當前不支持一個 pod 同時屬于多個 service)。
2. **命名的端口**:Service 的端口必須命名。端口的名字必須遵循如下格式 `<protocol>[-<suffix>]`,可以是http、http2、 grpc、 mongo、 或者 redis 作為 `<protocol>` ,這樣才能使用 Istio 的路由功能。例如`name: http2-foo` 和 `name: http` 都是有效的端口名稱,而 `name: http2foo` 不是。如果端口的名稱是不可識別的前綴或者未命名,那么該端口上的流量就會作為普通的 TCP 流量(除非使用 `Protocol: UDP` 明確聲明使用 UDP 端口)。
3. **帶有 app label 的 Deployment**:我們建議 kubernetes 的`Deploymenet` 資源的配置文件中為 Pod 明確指定 `app` label。每個Deployment 的配置中都需要有個不同的有意義的 `app` 標簽。`app` label 用于在分布式墜重中添加上下文信息。
4. **Mesh 中的每個 pod 里都有一個 Sidecar**: 最后,Mesh 中的每個 pod 都必須運行與 Istio 兼容的sidecar。下面部分介紹了將 sidecar 注入到 pod 中的兩種方法:使用`istioctl` 命令行工具手動注入,或者使用 istio initializer 自動注入。注意 sidecar 不涉及到容器間的流量,因為它們都在同一個 pod 中。
## 手動注入 sidecar
`istioctl` 命令行中有一個稱為 kube-inject 的便利工具,使用它可以將 Istio 的 sidecar 規范添加到 kubernetes 工作負載的規范配置中。與 Initializer 程序不同,`kube-inject` 只是將 YAML 規范轉換成包含 Istio sidecar 的規范。您需要使用標準的工具如 `kubectl` 來部署修改后的 YAML。例如,以下命令將 sidecar 添加到 sleep.yaml 文件中指定的 pod 中,并將修改后的規范提交給 kubernetes:
```bash
kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml)
```
### 示例
我們來試一試將 Istio sidecar 注入到 sleep 服務中去。
```bash
kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml)
```
Kube-inject 子命令將 Istio sidecar 和 init 容器注入到 deployment 配置中,轉換后的輸出如下所示:
```yaml
... 略過 ...
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
sidecar.istio.io/status: injected-version-root@69916ebba0fc-0.2.6-081ffece00c82cb9de33cd5617682999aee5298d
name: sleep
spec:
replicas: 1
template:
metadata:
annotations:
sidecar.istio.io/status: injected-version-root@69916ebba0fc-0.2.6-081ffece00c82cb9de33cd5617682999aee5298d
labels:
app: sleep
spec:
containers:
- name: sleep
image: tutum/curl
command: ["/bin/sleep","infinity"]
imagePullPolicy: IfNotPresent
- name: istio-proxy
image: docker.io/istio/proxy_debug:0.2.6
args:
... 略過 ...
initContainers:
- name: istio-init
image: docker.io/istio/proxy_init:0.2.6
imagePullPolicy: IfNotPresent
args:
... 略過 ...
---
```
注入 sidecar 的關鍵在于 `initContainers` 和 istio-proxy 容器。為了簡潔起見,上述輸出有所省略。
驗證 sleep deployment 中包含 sidecar。injected-version 對應于注入的 sidecar 鏡像的版本和鏡像的 TAG。在您的設置的可能會有所不同。
```bash
echo $(kubectl get deployment sleep -o jsonpath='{.metadata.annotations.sidecar\.istio\.io\/status}')
```
```bash
injected-version-9c7c291eab0a522f8033decd0f5b031f5ed0e126
```
你可以查看包含注入的容器和掛載的 volume 的完整 deployment 信息。
```bash
kubectl get deployment sleep -o yaml
```
## 自動注入 sidecar
Istio sidecar 可以在部署之前使用 Kubernetes 中一個名為 [Initializer](https://kubernetes.io/docs/admin/extensible-admission-controllers/#what-are-initializers) 的 Alpha 功能自動注入到 Pod 中。
> 注意:Kubernetes InitializerConfiguration沒有命名空間,適用于整個集群的工作負載。不要在共享測試環境中啟用此功能。
### 前置條件
Initializer 需要在集群設置期間顯示啟用,如 [此處](https://kubernetes.io/docs/admin/extensible-admission-controllers/#enable-initializers-alpha-feature) 所述。
假設集群中已啟用RBAC,則可以在不同環境中啟用初始化程序,如下所示:
- _GKE_
```bash
gcloud container clusters create NAME \
--enable-kubernetes-alpha \
--machine-type=n1-standard-2 \
--num-nodes=4 \
--no-enable-legacy-authorization \
--zone=ZONE
```
- _IBM Bluemix_ kubernetes v1.7.4 或更高版本的集群已默認啟用 initializer。
- _Minikube_
Minikube v0.22.1 或更高版本需要為 GenericAdmissionWebhook 功能配置適當的證書。獲取最新版本: https://github.com/kubernetes/minikube/releases.
```bash
minikube start \
--extra-config=apiserver.Admission.PluginNames="Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,GenericAdmissionWebhook,ResourceQuota" \
--kubernetes-version=v1.7.5
```
### 安裝
您現在可以從 Istio 安裝根目錄設置 Istio Initializer。
```bash
kubectl apply -f install/kubernetes/istio-initializer.yaml
```
將會創建下列資源:
1. `istio-sidecar` InitializerConfiguration 資源,指定 Istio sidecar 注入的資源。默認情況下 Istio sidecar 將被注入到 `deployment`、 `statefulset`、 `job` 和 `daemonset`中。
2. `istio-inject` ConfigMap,initializer 的默認注入策略,一組初始化 namespace,以及注入時使用的模版參數。這些配置的詳細說明請參考配置選項。
3. `istio-initializer` Deployment,運行 initializer 控制器。
4. `istio-initializer-service-account` ServiceAccount,用于 `istio-initializer` deployment。`ClusterRole` 和 `ClusterRoleBinding` 在 `install/kubernetes/istio.yaml` 中定義。注意所有的資源類型都需要有 `initialize` 和 `patch` 。正式處于這個原因,initializer 要作為 deployment 的一部分來運行而不是嵌入到其它控制器中,例如 istio-pilot。
### 驗證
為了驗證 sidecar 是否成功注入,為上面的 sleep 服務創建 deployment 和 service。
```bash
kubectl apply -f samples/sleep/sleep.yaml
```
驗證 sleep deployment 中包含 sidecar。injected-version 對應于注入的 sidecar 鏡像的版本和鏡像的 TAG。在您的設置的可能會有所不同。
```bash
$ echo $(kubectl get deployment sleep -o jsonpath='{.metadata.annotations.sidecar\.istio\.io\/status}')
```
```bash
injected-version-9c7c291eab0a522f8033decd0f5b031f5ed0e126
```
你可以查看包含注入的容器和掛載的 volume 的完整 deployment 信息。
```bash
kubectl get deployment sleep -o yaml
```
### 了解發生了什么
以下是將工作負載提交給 Kubernetes 后發生的情況:
1) kubernetes 將 `sidecar.initializer.istio.io` 添加到工作負載的 pending initializer 列表中。
2) istio-initializer 控制器觀察到有一個新的未初始化的工作負載被創建了。pending initializer 列表中的第一個個將作為 `sidecar.initializer.istio.io` 的名稱。
3) istio-initializer 檢查它是否負責初始化 namespace 中的工作負載。如果沒有為該 namespace 配置 initializer,則不需要做進一步的工作,而且 initializer 會忽略工作負載。默認情況下,initializer 負責所有的 namespace。
4) istio-initializer 將自己從 pending initializer 中移除。如果 pending initializer 列表非空,則 Kubernetes 不回結束工作負載的創建。錯誤配置的 initializer 意味著破損的集群。
5) istio-initializer 檢查 mesh 的默認注入策略,并檢查所有單個工作負載的策略負載值,以確定是否需要注入 sidecar。
6) istio-initializer 向工作負載中注入 sidecar 模板,然后通過 PATCH 向 kubernetes 提交。
7) kubernetes 正常的完成了工作負載的創建,并且工作負載中已經包含了注入的 sidecar。
### 配置選項
istio-initializer 具有用于注入的全局默認策略以及每個工作負載覆蓋配置。全局策略由 `istio-inject` ConfigMap 配置(請參見下面的示例)。Initializer pod 必須重新啟動以采用新的配置更改。
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: istio-inject
namespace: istio-system
data:
config: |-
policy: "enabled"
namespaces: [""] # everything, aka v1.NamepsaceAll, aka cluster-wide
# excludeNamespaces: ["ns1", "ns2"]
initializerName: "sidecar.initializer.istio.io"
params:
initImage: docker.io/istio/proxy_init:0.2.6
proxyImage: docker.io/istio/proxy:0.2.6
verbosity: 2
version: 0.2.6
meshConfigMapName: istio
imagePullPolicy: IfNotPresent
```
下面是配置中的關鍵參數:
1. **policy**
`off` - 禁用 initializer 修改資源。pending 的 `sidecar.initializer.istio.io` initializer 將被刪除以避免創建阻塞資源。
`disable` - initializer 不會注入 sidecar 到 watch 的所有 namespace 的資源中。啟用 sidecar 注入請將 `sidecar.istio.io/inject` 注解的值設置為 `true`。
`enable` - initializer 將會注入 sidecar 到 watch 的所有 namespace 的資源中。禁用 sidecar 注入請將 `sidecar.istio.io/inject` 注解的值設置為 `false`。
2. **namespaces**
要 watch 和初始化的 namespace 列表。特殊的 `""` namespace 對應于 `v1.NamespaceAll` 并配置初始化程序以初始化所有 namespace。`kube-system`、`kube-publice` 和 `istio-system` 被免除初始化。
1. **excludeNamespaces**
從 Istio initializer 中排除的 namespace 列表。不可以定義為 `v1.NamespaceAll` 或者與 `namespaces` 一起定義。
1. **initializerName**
這必須與 InitializerConfiguration 中 initializer 設定項的名稱相匹配。Initializer 只處理匹配其配置名稱的工作負載。
1. **params**
這些參數允許您對注入的 sidecar 進行有限的更改。更改這些值不會影響已部署的工作負載。
### 重寫自動注入
單個工作負載可以通過使用 `sidecar.istio.io/inject` 注解重寫全局策略。如果注解被省略,則使用全局策略。
如果注解的值是 `true`,則不管全局策略如何,sidecar 都將被注入。
如果注解的值是 `false`,則不管全局策略如何,sidecar 都不會被注入。
下表顯示全局策略和每個工作負載覆蓋的組合。
| policy | workload annotation | injected |
| -------- | ------------------- | -------- |
| off | N/A | no |
| disabled | omitted | no |
| disabled | false | no |
| disabled | true | yes |
| enabled | omitted | yes |
| enabled | false | no |
| enabled | true | yes |
例如,即使全局策略是 `disable`,下面的 deployment 也會被注入sidecar。
```yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: myapp
annotations:
sidecar.istio.io/inject: "true"
spec:
replicas: 1
template:
...
```
這是在包含 Istio 和非 Istio 服務的混合群集中使用自動注入的好方法。
### 卸載 Initializer
運行下面的命令,刪除 Istio initializer:
```bash
kubectl delete -f install/kubernetes/istio-initializer.yaml
```
注意上述命令并不會刪除已注入到 Pod 中的 sidecar。要想刪除這些 sidecar,需要在不使用 initializer 的情況下重新部署這些 pod。
# 拓展 Istio Mesh
將虛擬機或裸機集成到部署在 kubernetes 集群上的 Istio mesh 中的說明。
## 前置條件
- 按照安裝指南在 kubernetes 集群上安裝 Istio service mesh。
- 機器必須具有到 mesh 端點的 IP 地址連接。這通常需要一個 VPC 或者 VPN,以及一個向端點提供直接路由(沒有 NAT 或者防火墻拒絕)的容器網絡。及其不需要訪問有 Kubernetes 分配的 cluster IP。
- 虛擬機必須可以訪問到 Istio 控制平面服務(如Pilot、Mixer、CA)和 Kubernetes DNS 服務器。通常使用 [內部負載均衡器](https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer) 來實現。
您也可以使用 NodePort,在虛擬機上運行 Istio 的組件,或者使用自定義網絡配置,有幾個單獨的文檔會涵蓋這些高級配置。
## 安裝步驟
安裝過程包括準備用于拓展的 mesh 和安裝和配置虛擬機。
[install/tools/setupMeshEx.sh](https://raw.githubusercontent.com/istio/istio/master/install/tools/setupMeshEx.sh) :這是一個幫助大家設置 kubernetes 環境的示例腳本。檢查腳本內容和支持的環境變量(如 GCP_OPTS)。
[install/tools/setupIstioVM.sh](https://raw.githubusercontent.com/istio/istio/master/install/tools/setupIstioVM.sh):這是一個用于配置主機環境的示例腳本。
您應該根據您的配置工具和DNS要求對其進行自定義。
準備要拓展的 Kubernetes 集群:
- 為 Kube DNS、Pilot、Mixer 和 CA 安裝內部負載均衡器(ILB)。每個云供應商的配置都有所不同,根據具體情況修改注解。
> 0.2.7 版本的 YAML 文件的 DNS ILB 的 namespace 配置不正確。
> 使用 [這一個](https://raw.githubusercontent.com/istio/istio/master/install/kubernetes/mesh-expansion.yaml) 替代。
> `setupMeshEx.sh` 中也有錯誤。使用上面鏈接中的最新文件或者從 [GitHub.com/istio/istio](https://github.com/istio/istio/) 克隆。
```bash
kubectl apply -f install/kubernetes/mesh-expansion.yaml
```
- 生成要部署到虛擬機上的 Istio `cluster.env` 配置。該文件中包含要攔截的 cluster IP 地址范圍。
```bash
export GCP_OPTS="--zone MY_ZONE --project MY_PROJECT"
```
```bash
install/tools/setupMeshEx.sh generateClusterEnv MY_CLUSTER_NAME
```
該示例生成的文件:
```bash
cat cluster.env
```
```bash
ISTIO_SERVICE_CIDR=10.63.240.0/20
```
- 產生虛擬機使用的 DNS 配置文件。這樣可以讓虛擬機上的應用程序解析到集群中的服務名稱,這些名稱將被 sidecar 攔截和轉發。
```bash
# Make sure your kubectl context is set to your cluster
install/tools/setupMeshEx.sh generateDnsmasq
```
該示例生成的文件:
```bash
cat kubedns
```
```bash
server=/svc.cluster.local/10.150.0.7
address=/istio-mixer/10.150.0.8
address=/istio-pilot/10.150.0.6
address=/istio-ca/10.150.0.9
address=/istio-mixer.istio-system/10.150.0.8
address=/istio-pilot.istio-system/10.150.0.6
address=/istio-ca.istio-system/10.150.0.9
```
### 設置機器
例如,您可以使用下面的“一條龍”腳本復制和安裝配置:
```bash
# 檢查該腳本看看它是否滿足您的需求
# 在 Mac 上,使用 brew install base64 或者 set BASE64_DECODE="/usr/bin/base64 -D"
export GCP_OPTS="--zone MY_ZONE --project MY_PROJECT"
```
```bash
install/tools/setupMeshEx.sh machineSetup VM_NAME
```
或者等效得手動安裝步驟如下:
------ 手動安裝步驟開始 ------
- 將配置文件和 Istio 的 Debian 文件復制到要加入到集群的每臺機器上。重命名為 `/etc/dnsmasq.d/kubedns` 和`/var/lib/istio/envoy/cluster.env`。
- 配置和驗證 DNS 配置。需要安裝 `dnsmasq` 或者直接將其添加到 `/etc/resolv.conf` 中,或者通過 DHCP 腳本。驗證配置是否有效,檢查虛擬機是否可以解析和連接到 pilot,例如:
在虛擬機或外部主機上:
```bash
host istio-pilot.istio-system
```
產生的消息示例:
```bash
# Verify you get the same address as shown as "EXTERNAL-IP" in 'kubectl get svc -n istio-system istio-pilot-ilb'
istio-pilot.istio-system has address 10.150.0.6
```
檢查是否可以解析 cluster IP。實際地址取決您的 deployment:
```bash
host istio-pilot.istio-system.svc.cluster.local.
```
該示例產生的消息:
```bash
istio-pilot.istio-system.svc.cluster.local has address 10.63.247.248
```
同樣檢查 istio-ingress:
```bash
host istio-ingress.istio-system.svc.cluster.local.
```
該示例產生的消息:
```
istio-ingress.istio-system.svc.cluster.local has address 10.63.243.30
```
- 驗證連接性,檢查迅即是否可以連接到 Pilot 的端點:
```bash
curl 'http://istio-pilot.istio-system:8080/v1/registration/istio-pilot.istio-system.svc.cluster.local|http-discovery'
```
```json
{
"hosts": [
{
"ip_address": "10.60.1.4",
"port": 8080
}
]
}
```
```bash
# 在虛擬機上使用上面的地址。將直接連接到運行 istio-pilot 的 pod。
curl 'http://10.60.1.4:8080/v1/registration/istio-pilot.istio-system.svc.cluster.local|http-discovery'
```
- 提取出實話 Istio 認證的 secret 并將它復制到機器上。Istio 的默認安裝中包括 CA,即使是禁用了自動 `mTLS` 設置(她為每個 service account 創建 secret,secret 命名為 `istio.<serviceaccount>`)也會生成 Istio secret。建議您執行此步驟,以便日后啟用 mTLS,并升級到默認啟用 mTLS 的未來版本。
```bash
# ACCOUNT 默認是 'default',SERVICE_ACCOUNT 是環境變量
# NAMESPACE 默認為當前 namespace,SERVICE_NAMESPACE 是環境變量
# (這一步由 machineSetup 完成)
# 在 Mac 上執行 brew install base64 或者 set BASE64_DECODE="/usr/bin/base64 -D"
install/tools/setupMeshEx.sh machineCerts ACCOUNT NAMESPACE
```
生成的文件(`key.pem`, `root-cert.pem`, `cert-chain.pem`)必須拷貝到每臺主機的 /etc/certs 目錄,并且讓 istio-proxy 可讀。
- 安裝 Istio Debian 文件,啟動 `istio` 和 `istio-auth-node-agent` 服務。
從 [github releases](https://github.com/istio/istio/releases) 獲取 Debian 安裝包:
```bash
# 注意:在軟件源配置好后,下面的額命令可以使用 'apt-get' 命令替代。
source istio.VERSION # defines version and URLs env var
curl -L ${PILOT_DEBIAN_URL}/istio-agent.deb > ${ISTIO_STAGING}/istio-agent.deb
curl -L ${AUTH_DEBIAN_URL}/istio-auth-node-agent.deb > ${ISTIO_STAGING}/istio-auth-node-agent.deb
curl -L ${PROXY_DEBIAN_URL}/istio-proxy.deb > ${ISTIO_STAGING}/istio-proxy.deb
dpkg -i istio-proxy-envoy.deb
dpkg -i istio-agent.deb
dpkg -i istio-auth-node-agent.deb
systemctl start istio
systemctl start istio-auth-node-agent
```
------ 手動安裝步驟結束 ------
安裝完成后,機器就能訪問運行在 Kubernetes 集群上的服務或者其他的 mesh 拓展的機器。
```bash
# 假設您在 'bookinfo' namespace 下安裝的 bookinfo
curl productpage.bookinfo.svc.cluster.local:9080
```
```bash
... html content ...
```
檢查進程是否正在運行:
```bash
ps aux |grep istio
```
```bash
root 6941 0.0 0.2 75392 16820 ? Ssl 21:32 0:00 /usr/local/istio/bin/node_agent --logtostderr
root 6955 0.0 0.0 49344 3048 ? Ss 21:32 0:00 su -s /bin/bash -c INSTANCE_IP=10.150.0.5 POD_NAME=demo-vm-1 POD_NAMESPACE=default exec /usr/local/bin/pilot-agent proxy > /var/log/istio/istio.log istio-proxy
istio-p+ 7016 0.0 0.1 215172 12096 ? Ssl 21:32 0:00 /usr/local/bin/pilot-agent proxy
istio-p+ 7094 4.0 0.3 69540 24800 ? Sl 21:32 0:37 /usr/local/bin/envoy -c /etc/istio/proxy/envoy-rev1.json --restart-epoch 1 --drain-time-s 2 --parent-shutdown-time-s 3 --service-cluster istio-proxy --service-node sidecar~10.150.0.5~demo-vm-1.default~default.svc.cluster.local
```
檢查 Istio auth-node-agent 是否健康:
```bash
sudo systemctl status istio-auth-node-agent
```
```bash
● istio-auth-node-agent.service - istio-auth-node-agent: The Istio auth node agent
Loaded: loaded (/lib/systemd/system/istio-auth-node-agent.service; disabled; vendor preset: enabled)
Active: active (running) since Fri 2017-10-13 21:32:29 UTC; 9s ago
Docs: http://istio.io/
Main PID: 6941 (node_agent)
Tasks: 5
Memory: 5.9M
CPU: 92ms
CGroup: /system.slice/istio-auth-node-agent.service
└─6941 /usr/local/istio/bin/node_agent --logtostderr
Oct 13 21:32:29 demo-vm-1 systemd[1]: Started istio-auth-node-agent: The Istio auth node agent.
Oct 13 21:32:29 demo-vm-1 node_agent[6941]: I1013 21:32:29.469314 6941 main.go:66] Starting Node Agent
Oct 13 21:32:29 demo-vm-1 node_agent[6941]: I1013 21:32:29.469365 6941 nodeagent.go:96] Node Agent starts successfully.
Oct 13 21:32:29 demo-vm-1 node_agent[6941]: I1013 21:32:29.483324 6941 nodeagent.go:112] Sending CSR (retrial #0) ...
Oct 13 21:32:29 demo-vm-1 node_agent[6941]: I1013 21:32:29.862575 6941 nodeagent.go:128] CSR is approved successfully. Will renew cert in 29m59.137732603s
```
## 在拓展的 mesh 中的機器上運行服務
- 配置 sidecar 攔截端口。在 `/var/lib/istio/envoy/sidecar.env` 中通過 `ISTIO_INBOUND_PORTS` 環境變量配置。
例如(運行服務的虛擬機):
```bash
echo "ISTIO_INBOUND_PORTS=27017,3306,8080" > /var/lib/istio/envoy/sidecar.env
systemctl restart istio
```
- 手動配置 selector-less 的 service 和 endpoint。“selector-less” service 用于那些不依托 Kubernetes pod 的 service。
例如,在有權限的機器上修改 Kubernetes 中的 service:
```bash
# istioctl register servicename machine-ip portname:port
istioctl -n onprem register mysql 1.2.3.4 3306
istioctl -n onprem register svc1 1.2.3.4 http:7000
```
安裝完成后,Kubernetes pod 和其它 mesh 擴展將能夠訪問集群上運行的服務。
## 整合到一起
請參閱拓展 BookInfo Mesh 指南。
------
## 部署 bookinfo 示例應用
該示例部署由四個單獨的微服務組成的簡單應用程序,用于演示Istio服務網格的各種功能。
## 概況
在本示例中,我們將部署一個簡單的應用程序,顯示書籍的信息,類似于網上書店的書籍條目。在頁面上有書籍的描述、詳細信息(ISBN、頁數等)和書評。
BookInfo 應用程序包括四個獨立的微服務:
- productpage:productpage(產品頁面)微服務,調用 *details* 和 *reviews* 微服務來填充頁面。
- details:details 微服務包含書籍的詳細信息。
- reviews:reviews 微服務包含書籍的點評。它也調用 *ratings* 微服務。
- ratings:ratings 微服務包含隨書評一起出現的評分信息。
有3個版本的 reviews 微服務:
- 版本v1不調用 ratings 服務。
- 版本v2調用 ratings ,并將每個評級顯示為1到5個黑色星。
- 版本v3調用 ratings ,并將每個評級顯示為1到5個紅色星。
應用程序的端到端架構如下所示。

該應用程序是多語言構建的,即這些微服務是用不同的語言編寫的。值得注意的是,這些服務與 Istio 沒有任何依賴關系,單這是個有趣的 Service Mesh 示例,特別是因為評論服務和眾多的語言和版本。
## 開始之前
如果您還沒有這樣做,請按照與您的平臺安裝指南對應的說明安裝Istio。
## 部署應用程序
使用 Istio 運行應用程序示例不需要修改應用程序本身。相反,我們只需要在支持 Istio 的環境中配置和運行服務, Envoy sidecar 將會注入到每個服務中。所需的命令和配置根據運行時環境的不同而有所不同,但在所有情況下,生成的部署將如下所示:

所有的微服務都將與一個 Envoy sidecar 一起打包,攔截這些服務的入站和出站的調用請求,提供通過 Istio 控制平面從外部控制整個應用的路由,遙測收集和策略執行所需的 hook。
要啟動該應用程序,請按照以下對應于您的 Istio 運行時環境的說明進行操作。
### 在 Kubernetes 中運行
> 注意:如果您使用 GKE,清確保您的集群至少有 4 個標準的 GKE 節點。如果您使用 Minikube,請確保您至少有 4GB 內存。
1. 將目錄更改為 Istio 安裝目錄的根目錄。
2. 構建應用程序容器:
如果您使用 **自動注入 sidecar** 的方式部署的集群,那么只需要使用 `kubectl` 命令部署服務:
```bash
kubectl apply -f samples/bookinfo/kube/bookinfo.yaml
```
如果您使用 **手動注入 sidecar** 的方式部署的集群,清使用下面的命令:
```bash
kubectl apply -f <(istioctl kube-inject -f samples/apps/bookinfo/bookinfo.yaml)
```
請注意,該 `istioctl kube-inject` 命令用于在創建部署之前修改 `bookinfo.yaml` 文件。這將把 Envoy 注入到 Kubernetes 資源。
上述命令啟動四個微服務并創建網關入口資源,如下圖所示。3 個版本的評論的服務 v1、v2、v3 都已啟動。
> 請注意在實際部署中,隨著時間的推移部署新版本的微服務,而不是同時部署所有版本。
3. 確認所有服務和 pod 已正確定義并運行:
```bash
kubectl get services
```
這將產生以下輸出:
```bash
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details 10.0.0.31 <none> 9080/TCP 6m
istio-ingress 10.0.0.122 <pending> 80:31565/TCP 8m
istio-pilot 10.0.0.189 <none> 8080/TCP 8m
istio-mixer 10.0.0.132 <none> 9091/TCP,42422/TCP 8m
kubernetes 10.0.0.1 <none> 443/TCP 14d
productpage 10.0.0.120 <none> 9080/TCP 6m
ratings 10.0.0.15 <none> 9080/TCP 6m
reviews 10.0.0.170 <none> 9080/TCP 6m
```
而且
```bash
kubectl get pods
```
將產生:
```bash
NAME READY STATUS RESTARTS AGE
details-v1-1520924117-48z17 2/2 Running 0 6m
istio-ingress-3181829929-xrrk5 1/1 Running 0 8m
istio-pilot-175173354-d6jm7 2/2 Running 0 8m
istio-mixer-3883863574-jt09j 2/2 Running 0 8m
productpage-v1-560495357-jk1lz 2/2 Running 0 6m
ratings-v1-734492171-rnr5l 2/2 Running 0 6m
reviews-v1-874083890-f0qf0 2/2 Running 0 6m
reviews-v2-1343845940-b34q5 2/2 Running 0 6m
reviews-v3-1813607990-8ch52 2/2 Running 0 6m
```
# 確定 ingress IP 和端口
1. 如果您的 kubernetes 集群環境支持外部負載均衡器的話,可以使用下面的命令獲取 ingress 的IP地址:
```bash
kubectl get ingress -o wide
```
輸出如下所示:
```bash
NAME HOSTS ADDRESS PORTS AGE
gateway * 130.211.10.121 80 1d
```
Ingress 服務的地址是:
```bash
export GATEWAY_URL=130.211.10.121:80
```
2. GKE:如果服務無法獲取外部 IP,`kubectl get ingress -o wide` 會顯示工作節點的列表。在這種情況下,您可以使用任何地址以及 NodePort 訪問入口。但是,如果集群具有防火墻,則還需要創建防火墻規則以允許TCP流量到NodePort,您可以使用以下命令創建防火墻規則:
```bash
export GATEWAY_URL=<workerNodeAddress>:$(kubectl get svc istio-ingress -n istio-system -o jsonpath='{.spec.ports[0].nodePort}')
gcloud compute firewall-rules create allow-book --allow tcp:$(kubectl get svc istio-ingress -n istio-system -o jsonpath='{.spec.ports[0].nodePort}')
```
3. IBM Bluemix Free Tier:在免費版的 Bluemix 的 kubernetes 集群中不支持外部負載均衡器。您可以使用工作節點的公共 IP,并通過 NodePort 來訪問 ingress。工作節點的公共 IP可以通過如下命令獲取:
```bash
bx cs workers <cluster-name or id>
export GATEWAY_URL=<public IP of the worker node>:$(kubectl get svc istio-ingress -n istio-system -o jsonpath='{.spec.ports[0].nodePort}')
```
4. Minikube:Minikube 不支持外部負載均衡器。您可以使用 ingress 服務的主機 IP 和 NodePort 來訪問 ingress:
```bash
export GATEWAY_URL=$(kubectl get po -l istio=ingress -o 'jsonpath={.items[0].status.hostIP}'):$(kubectl get svc istio-ingress -o 'jsonpath={.spec.ports[0].nodePort}')
```
### 在 Consul 或 Eureka 環境下使用 Docker 運行
1. 切換到 Istio 的安裝根目錄下。
2. 啟動應用程序容器。
1. 執行下面的命令測試 Consul:
```bash
docker-compose -f samples/bookinfo/consul/bookinfo.yaml up -d
```
2. 執行下面的命令測試 Eureka:
```bash
docker-compose -f samples/bookinfo/eureka/bookinfo.yaml up -d
```
3. 確認所有容器都在運行:
docker ps -a
> 如果 Istio Pilot 容器終止了,重新執行上面的命令重新運行。
4. 設置 `GATEWAY_URL`:
```bash
export GATEWAY_URL=localhost:9081
```
## 下一步
使用以下 `curl` 命令確認 BookInfo 應用程序正在運行:
```bash
curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/productpage
```
```bash
200
```
你也可以通過在瀏覽器中打開 `http://$GATEWAY_URL/productpage` 頁面訪問 Bookinfo 網頁。如果您多次刷新瀏覽器將在 productpage 中看到評論的不同的版本,它們會按照 round robin(紅星、黑星、沒有星星)的方式展現,因為我們還沒有使用 Istio 來控制版本的路由。
現在,您可以使用此示例來嘗試 Istio 的流量路由、故障注入、速率限制等功能。要繼續的話,請參閱 Istio 指南,具體取決于您的興趣。智能路由 是初學者入門的好方式。
## 清理
在完成 BookInfo 示例后,您可以卸載它,如下所示:
### 卸載 Kubernetes 環境
1. 刪除路由規則,終止應用程序 pod
```bash
samples/bookinfo/kube/cleanup.sh
```
2. 確認關閉
```bash
istioctl get routerules #-- there should be no more routing rules
kubectl get pods #-- the BookInfo pods should be deleted
```
### 卸載 docker 環境
1. 刪除路由規則和應用程序容器
1. 若使用 Consul 環境安裝,執行下面的命令:
```bash
samples/bookinfo/consul/cleanup.sh
```
2. 若使用 Eureka 環境安裝,執行下面的命令:
```bash
samples/bookinfo/eureka/cleanup.sh
```
2. 確認清理完成:
```bash
istioctl get routerules #-- there should be no more routing rules
docker ps -a #-- the BookInfo containers should be delete
```
- 序言
- 云原生
- 云原生(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快速入門指南
- 邊緣計算
- 人工智能