雲原生服務網格Istio 1.4 部署指南


雲原生服務網格Istio 1.4 部署指南

Istio 一直處於快速迭代更新的過程中,它的部署方法也在不斷更新,之前我在 1.0 版本中介紹的安裝方法,對於最新的 1.4 版本已經不適用了。以後主流的部署方式都是用 istioctl 進行部署,helm 可以漸漸靠邊站了~~

在部署 Istio 之前,首先需要確保 Kubernetes 集群(kubernetes 版本建議在 1.13 以上)已部署並配置好本地的 kubectl 客戶端。

1. Kubernetes 環境準備

為了快速準備 kubernetes 環境,我們可以使用 sealos 來部署,步驟如下:

前提條件


  • 下載http://store.lameleg.com/
  • 下載https://github.com/fanux/sealos/releases
  • 務必同步服務器時間
  • 主機名不可重複

安裝 kubernetes 集群


<code>$ sealos init --master 192.168.0.2 \\    --node 192.168.0.3 \\    --node 192.168.0.4 \\    --node 192.168.0.5 \\    --user root \\    --passwd your-server-password \\    --version v1.16.3 \\    --pkg-url /root/kube1.16.3.tar.gz /<code>

檢查安裝是否正常:

<code>$ kubectl get nodeNAME       STATUS   ROLES    AGE   VERSIONsealos01   Ready    master   18h   v1.16.3sealos02   Ready    <none>   18h   v1.16.3sealos03   Ready    <none>   18h   v1.16.3sealos04   Ready    <none>   18h   v1.16.3/<none>/<none>/<none>/<code>


2. 下載 Istio 部署文件

你可以從 GitHub 的 https://github.com/istio/istio/releases/tag/1.4.2 頁面下載 istio,或者直接通過下面的命令下載:

<code>$ curl -L https://istio.io/downloadIstio | sh -/<code>

下載完成後會得到一個 istio-1.4.2 目錄,裡面包含了:

  • install/kubernetes : 針對 Kubernetes 平臺的安裝文件
  • samples : 示例應用
  • bin : istioctl 二進制文件,可以用來手動注入 sidecar proxy

進入 istio-1.4.2 目錄。

<code>$ cd istio-1.4.2$ tree -L 1 ././├── bin├── demo.yaml├── install├── LICENSE├── manifest.yaml├── README.md├── samples└── tools4 directories, 4 files/<code>

將 istioctl 拷貝到 /usr/local/bin/ 中:

<code>$ cp bin/istioctl /usr/local/bin//<code>


開啟 istioctl 的自動補全功能


bash

將 tools 目錄中的 istioctl.bash 拷貝到 $HOME 目錄中:

<code>$ cp tools/istioctl.bash ~//<code>

在 ~/.bashrc 中添加一行:

<code>source ~/istioctl.bash/<code>

應用生效:

<code>$ source ~/.bashrc/<code>


zsh

將 tools 目錄中的 _istioctl 拷貝到 $HOME 目錄中:

<code>$ cp tools/_istioctl ~//<code>

在 ~/.zshrc 中添加一行:

<code>source ~/_istioctl/<code>

應用生效:

<code>$ source ~/.zshrc/<code>


3. 部署 Istio

istioctl 提供了多種安裝配置文件,可以通過下面的命令查看:

<code>$ istioctl profile listIstio configuration profiles:    minimal    remote    sds    default    demo/<code>

如果只是想快速試用並體驗完整的功能,可以直接使用配置文件 demo 來部署。

在正式部署之前,需要先說明兩點:

Istio CNI Plugin

當前實現將用戶 pod 流量轉發到 proxy 的默認方式是使用 privileged 權限的 istio-init 這個 init container 來做的(運行腳本寫入 iptables),需要用到 NET_ADMIN capabilities。對 linux capabilities 不瞭解的同學可以參考我的 https://fuckcloudnative.io/posts/linux-capabilities-why-they-exist-and-how-they-work/。

Istio CNI 插件的主要設計目標是消除這個 privileged 權限的 init container,換成利用 Kubernetes CNI 機制來實現相同功能的替代方案。具體的原理就是在 Kubernetes CNI 插件鏈末尾加上 Istio 的處理邏輯,在創建和銷燬 pod 的這些 hook 點來針對 istio 的 pod 做網絡配置:寫入 iptables,讓該 pod 所在的 network namespace 的網絡流量轉發到 proxy 進程。

詳細內容請參考https://istio.io/docs/setup/additional-setup/cni/。

使用 Istio CNI 插件來創建 sidecar iptables 規則肯定是未來的主流方式,不如我們現在就嘗試使用這種方法。

Kubernetes 關鍵插件(Critical Add-On Pods)

眾所周知,Kubernetes 的核心組件都運行在 master 節點上,然而還有一些附加組件對整個集群來說也很關鍵,例如 DNS 和 metrics-server,這些被稱為關鍵插件。一旦關鍵插件無法正常工作,整個集群就有可能會無法正常工作,所以 Kubernetes 通過優先級(PriorityClass)來保證關鍵插件的正常調度和運行。要想讓某個應用變成 Kubernetes 的關鍵插件,只需要其 priorityClassName 設為 system-cluster-critical 或 system-node-critical,其中 system-node-critical 優先級最高。

注意:關鍵插件只能運行在 kube-system namespace 中!

詳細內容可以參考https://v1-16.docs.kubernetes.io/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/。

接下來正式安裝 istio,命令如下:

<code>$ istioctl manifest apply --set profile=demo \\   --set cni.enabled=true --set cni.components.cni.namespace=kube-system \\   --set values.gateways.istio-ingressgateway.type=ClusterIP/<code>

istioctl 支持兩種 API:

  • https://istio.io/docs/reference/config/istio.operator.v1alpha12.pb/
  • https://istio.io/docs/reference/config/installation-options/

在上述安裝命令中,cni 參數使用的是 IstioControlPlane API,而 values.* 使用的是 Helm API。

部署完成後,查看各組件狀態:

<code>$ kubectl -n istio-system get podNAME                                      READY   STATUS    RESTARTS   AGEgrafana-6b65874977-8psph                  1/1     Running   0          36sistio-citadel-86dcf4c6b-nklp5             1/1     Running   0          37sistio-egressgateway-68f754ccdd-m87m8      0/1     Running   0          37sistio-galley-5fc6d6c45b-znwl9             1/1     Running   0          38sistio-ingressgateway-6d759478d8-g5zz2     0/1     Running   0          37sistio-pilot-5c4995d687-vf9c6              0/1     Running   0          37sistio-policy-57b99968f-ssq28              1/1     Running   1          37sistio-sidecar-injector-746f7c7bbb-qwc8l   1/1     Running   0          37sistio-telemetry-854d8556d5-6znwb          1/1     Running   1          36sistio-tracing-c66d67cd9-gjnkl             1/1     Running   0          38skiali-8559969566-jrdpn                    1/1     Running   0          36sprometheus-66c5887c86-vtbwb               1/1     Running   0          39s/<code>


<code>$ kubectl -n kube-system get pod -l k8s-app=istio-cni-nodeNAME                   READY   STATUS    RESTARTS   AGEistio-cni-node-k8zfb   1/1     Running   0          10mistio-cni-node-kpwpc   1/1     Running   0          10mistio-cni-node-nvblg   1/1     Running   0          10mistio-cni-node-vk6jd   1/1     Running   0          10m/<code>

可以看到 cni 插件已經安裝成功,查看配置是否已經追加到 CNI 插件鏈的末尾:

<code>$ cat /etc/cni/net.d/10-calico.conflist{  "name": "k8s-pod-network",  "cniVersion": "0.3.1",  "plugins": [  ...    {      "type": "istio-cni",      "log_level": "info",      "kubernetes": {        "kubeconfig": "/etc/cni/net.d/ZZZ-istio-cni-kubeconfig",        "cni_bin_dir": "/opt/cni/bin",        "exclude_namespaces": [          "istio-system"        ]      }    }  ]}/<code>

默認情況下除了 istio-system namespace 之外,istio cni 插件會監視其他所有 namespace 中的 Pod,然而這並不能滿足我們的需求,更嚴謹的做法是讓 istio CNI 插件至少忽略 kube-system、istio-system 這兩個 namespace,怎麼做呢?

也很簡單,還記得之前提到的 IstioControlPlane API 嗎?可以直接通過它來覆蓋之前的配置,只需要創建一個 IstioControlPlane CRD 就可以了。例如:

<code>$ cat cni.yamlapiVersion: install.istio.io/v1alpha2kind: IstioControlPlanespec:  cni:    enabled: true    components:      namespace: kube-system  values:    cni:      excludeNamespaces:       - istio-system       - kube-system       - monitoring  unvalidatedValues:    cni:      logLevel: info/<code>


<code>$ istioctl manifest apply -f cni.yaml/<code>

刪除所有的 istio-cni-node Pod:

<code>$ kubectl -n kube-system delete pod -l k8s-app=istio-cni-node/<code>

再次查看 CNI 插件鏈的配置:

<code>$ cat /etc/cni/net.d/10-calico.conflist{  "name": "k8s-pod-network",  "cniVersion": "0.3.1",  "plugins": [  ...    {      "type": "istio-cni",      "log_level": "info",      "kubernetes": {        "kubeconfig": "/etc/cni/net.d/ZZZ-istio-cni-kubeconfig",        "cni_bin_dir": "/opt/cni/bin",        "exclude_namespaces": [          "istio-system",          "kube-system",          "monitoring"        ]      }    }  ]}/<code>


4. 暴露 Dashboard

這個沒什麼好說的,通過 Ingress Controller 暴露就好了,可以參考我以前寫的 https://fuckcloudnative.io/posts/istio-1.0-deploy/。如果使用 Contour 的可以參考我的另一篇文章:https://fuckcloudnative.io/posts/use-envoy-as-a-kubernetes-ingress/。

這裡我再介紹一種新的方式,istioctl 提供了一個子命令來從本地打開各種 Dashboard:

<code>$ istioctl dashboard --helpAccess to Istio web UIsUsage:  istioctl dashboard [flags]  istioctl dashboard [command]Aliases:  dashboard, dash, dAvailable Commands:  controlz    Open ControlZ web UI  envoy       Open Envoy admin web UI  grafana     Open Grafana web UI  jaeger      Open Jaeger web UI  kiali       Open Kiali web UI  prometheus  Open Prometheus web UI  zipkin      Open Zipkin web UI/<code>

例如,要想在本地打開 Grafana 頁面,只需執行下面的命令:

<code>$ istioctl dashboard grafanahttp://localhost:36813/<code>

咋一看可能覺得這個功能很雞肋,我的集群又不是部署在本地,而且這個命令又不能指定監聽的 IP,在本地用瀏覽器根本打不開呀!其實不然,你可以在本地安裝 kubectl 和 istioctl 二進制文件,然後通過 kubeconfig 連接到集群,最後再在本地執行上面的命令,就可以打開頁面啦,開發人員用來測試是不是很方便?Windows 用戶當我沒說。。。

5. 暴露 Gateway

為了暴露 Ingress Gateway,我們可以使用 HostNetwork 模式運行,但你會發現無法啟動 ingressgateway 的 Pod,因為如果 Pod 設置了 HostNetwork=true,則 dnsPolicy 就會從 ClusterFirst 被強制轉換成 Default。而 Ingress Gateway 啟動過程中需要通過 DNS 域名連接 pilot 等其他組件,所以無法啟動。

我們可以通過強制將 dnsPolicy 的值設置為 ClusterFirstWithHostNet 來解決這個問題,詳情參考:https://fuckcloudnative.io/posts/kubernetes-dns/。

修改後的 ingressgateway deployment 配置文件如下:

<code>apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: istio-ingressgateway  namespace: istio-system  ...spec:  ...  template:    metadata:    ...    spec:      affinity:        nodeAffinity:          ...          requiredDuringSchedulingIgnoredDuringExecution:            nodeSelectorTerms:            - matchExpressions:              - key: kubernetes.io/hostname                operator: In                values:                - 192.168.0.4   # 假設你想調度到這臺主機上      ...      dnsPolicy: ClusterFirstWithHostNet      hostNetwork: true      restartPolicy: Always      .../<code>

接下來我們就可以在瀏覽器中通過 Gateway 的 URL 來訪問服務網格中的服務了。後面我會開啟一系列實驗教程,本文的所有步驟都是為後面做準備,如果想跟著我做後面的實驗,請務必做好本文所述的準備工作。


分享到:


相關文章: