基於阿里雲 ASK 的 Istio 微服務應用部署初探
作者:王飛龍(不物)
目前 Kubernetes 已經成為業界容器編排系統的事實標準,基於 Kubernetes 的雲原生應用生態(Helm, Istio, Knative, Kubeflow, Spark on Kubernetes 等)更是讓 Kubernetes 成為雲作業系統。在這樣的背景下,Serverless 容器成為現有 Container as a Service 的進化方向之一,一方面通過 Serverless 方式根本性解決了 Kubernetes 自身的管理複雜性,讓使用者無需受困於 Kubernetes 叢集容量規劃、安全維護、故障診斷;另一方面也進一步釋放了雲端計算的能力,將安全、可用性、可伸縮性等需求由基礎設施實現。
ASK 作為阿里雲 Serverless Kubernetes 平臺 [ 1] ,不僅有免運維、秒級彈性、超大 Pod 容量、彈性預測等重磅能力,更重要的是它依然是一個標準 Kubernetes 平臺。
本文會通過在 ASK 上試用 Istio 部署微服務應用的方式,來驗證 ASK 對標準 Kubernetes 的相容性。Istio 作為 Service Mesh(服務網格)的領導解決方案,一方面本身足夠複雜具有代表性,另一方面它也代表了雲原生時代微服務架構的趨勢具有參考意義。
現在就讓我們開始吧!
建立叢集
試用 Istio 前,需要準備一個 ASK 叢集。登入阿里雲控制檯,選擇產品與服務 > 容器服務 Kubernetes 版,在左側邊欄選擇叢集進入叢集列表頁面。點選右上角建立叢集開始建立叢集,配置叢集引數如下:
- 叢集名稱:hello-istio
- 叢集規格:Pro 版
- 地域:美國(矽谷)
- 付費型別:按量付費
- Kubernetes 版本:1.20.11-aliyun.1
- 專有網路:自動建立
- Service CIDR:172.21.0.0/20
- API Server 訪問:標準型I(slb.s2.small)
- 使用 EIP 暴露 API Server:是
- 時區:Aisa/Shanghai(UTC+08:00)
- 服務發現:CoreDNS
- 使用日誌服務:建立新 Project
確認配置後點擊建立叢集進入等待叢集建立完成。Istio 依賴 DNS 服務,這裡選擇建立叢集時預設安裝 CoreDNS 元件。
叢集建立完成後,進入叢集列表 > hello-istio > 詳情 > 叢集資訊 > 連線資訊頁面,複製公網訪問內容到本地/tmp/kube/config 檔案,並通過如下命令配置好 kubelet:
$ export KUBECONFIG=/tmp/kube/config
試用 Istio
kubectl 配置好後就可以開始在叢集安裝和試用 Istio。
下載 Istio
進入 Istio 釋出頁面 [ 2] 下載針對作業系統的安裝檔案,也可以通過如下命令下載並提取最新版本:
$ curl -L http://istio.io/downloadIstio | sh -
因為我本機~/bin 目錄已加入 PATH,這裡我將提取的 Istio 目錄複製~/bin 目錄,並建好軟連結。
$ cp istio-1.13.3 ~/bin
$ cd ~/bin
$ ln -s istio-1.13.3/bin/istioctl
$ ls -al ~/bin/
total 28
drwxr-xr-x 5 feilong.wfl staff 160 5 4 22:40 ./
drwxr-xr-x+ 95 feilong.wfl staff 3040 5 8 22:30 ../
drwxr-x--- 9 feilong.wfl staff 288 4 15 00:48 istio-1.13.3/
lrwxr-xr-x 1 feilong.wfl staff 25 5 4 22:40 istioctl -> istio-1.13.3/bin/istioctl*
如果 istioctl --help 命令輸出正常,則 istioctl 已正確配置。
安裝 Istio
- 本次安裝採用 demo profile [ 3] ,它包含了一組專為測試準備的功能集合,另外還有使用者生產或效能測試的配置組合。
$ istioctl install --set profile=demo -y
✔ Istio core installed
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete
- 給名稱空間新增標籤,指示 Istio 在部署應用的時候,自動注入 Envoy 邊車代理:
$ kubectl label namespace default istio-injection=enabled
namespace/default labeled
部署示例應用
- 部署 Bookinfo 示例應用 [ 4] :
$ kubectl apply -f ~/bin/istio-1.13.3/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 已就緒:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-79f774bdb9-t2jhq 2/2 Running 0 2m54s
productpage-v1-6b746f74dc-qc9lg 2/2 Running 0 2m46s
ratings-v1-b6994bb9-tmbh6 2/2 Running 0 2m51s
reviews-v1-545db77b95-xdhp4 2/2 Running 0 2m49s
reviews-v2-7bf8c9648f-4gn6f 2/2 Running 0 2m48s
reviews-v3-84779c7bbc-jfndj 2/2 Running 0 2m48s
要等待並確保所有的 Pod 達到此狀態:就緒狀態(READY)的值為 2/2 、狀態(STATUS)的值為 Running。基於平臺的不同,這個操作過程可能會花費幾分鐘的時間。
- 檢查 Service 已就緒:
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 172.21.11.168 <none> 9080/TCP 59s
kubernetes ClusterIP 172.21.0.1 <none> 443/TCP 33m
productpage ClusterIP 172.21.0.124 <none> 9080/TCP 51s
ratings ClusterIP 172.21.9.7 <none> 9080/TCP 57s
reviews ClusterIP 172.21.13.223 <none> 9080/TCP 55s
- 確保網頁服務正常。如果命令返回頁面標題,則應用已在叢集中執行。
$ kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -s productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
對外開放服務
現在,BookInfo 應用已經部署,但還不能被外界訪問。 要開放訪問,需要建立 Istio 入站閘道器(Ingress Gateway), 它會把一個路徑路由到網格內的服務。
- 把應用關聯到 Istio 閘道器:
$ kubectl apply -f ~/bin/istio-1.13.3/samples/bookinfo/networking/bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created
- 確保配置檔案沒有問題:
$ istioctl analyze
✔ No validation issues found when analyzing namespace: default.
確定入站 IP 和埠
使用如下命令為訪問閘道器設定 INGRESS_HOST 和 INGRESS_PORT 兩個變數:
$ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
$ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
設定變數 GATEWAY_URL,並確保 IP 地址和埠均成功的賦值給了該變數:
$ export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
$ echo "$GATEWAY_URL"
47.88.21.82:80
驗證外部訪問
執行下面命令,獲取 Bookinfo 應用的外部訪問地址:
$ echo "http://$GATEWAY_URL/productpage"
http://47.88.21.82:80/productpage
複製上面命令的輸出地址到瀏覽器並訪問,確認 Bookinfo 已經實現了外部訪問。重新整理頁面,發現 Book Reviews 的顯示樣式會不斷變化。
檢視儀表盤
儀表盤能幫助瞭解服務網格的結構、展示網路的拓撲結構、分析網格的健康狀態。
- 首先安裝 Kiali 和其他外掛,等待部署完成。
$ kubectl apply -f ~/bin/istio-1.13.3/samples/addons
$ kubectl rollout status deployment/kiali -n istio-system
Waiting for deployment "kiali" rollout to finish: 0 of 1 updated replicas are available...
deployment "kiali" successfully rolled out
- 訪問 Kiali 儀表板。
$ istioctl dashboard kiali
- 在左側的導航選單,選擇 Graph,然後在 Namespace 下拉列表中,選擇 default。
Kiali 儀表板展示了網格的概覽、以及 Bookinfo 示例應用的各個服務之間的關係。 它還提供過濾器來視覺化流量的流動。
新增預設目標規則
使用 Istio 控制 Bookinfo 版本路由前,需要先在目標規則 [ 5] 中定義好可用的版本。執行以下命令為 Bookinfo 服務建立預設的目標規則:
$ kubectl apply -f ~/bin/istio-1.13.3/samples/bookinfo/networking/destination-rule-all.yaml
destinationrule.networking.istio.io/productpage created
destinationrule.networking.istio.io/reviews created
destinationrule.networking.istio.io/ratings created
destinationrule.networking.istio.io/details created
等待幾秒鐘,目標規則生效。您可以使用如下命令檢視目標規則:
$ kubectl get destinationrules
NAME HOST AGE
details details 30s
productpage productpage 32s
ratings ratings 31s
reviews reviews 32s
路由所有流量到 v1 版本
執行以下命令建立 Virtual Service 將所有流量路由到微服務的 v1 版本:
$ kubectl apply -f ~/bin/istio-1.13.3/samples/bookinfo/networking/virtual-service-all-v1.yaml
virtualservice.networking.istio.io/productpage created
virtualservice.networking.istio.io/reviews created
virtualservice.networking.istio.io/ratings created
virtualservice.networking.istio.io/details created
您可以通過再次重新整理 Bookinfo 應用程式的/productpage 頁面測試新配置。請注意,無論您重新整理多少次,頁面的評論部分都不會顯示評級星標。這是因為當前已將 Istio 配置為評論服務的所有流量路由到版本 reviews:v1,而此版本的服務不訪問星級評分服務。
基於使用者身份的路由
接下來將更改路由配置,實現將來自特定使用者的所有流量路由到特定的服務版本。示例中來自名為 Jason 使用者的所有流量將被路由到服務 review:v2。
Istio 對使用者身份沒有任何特殊的內建機制。本例中,productpage 服務在所有到 reviews 服務的 HTTP 請求中都增加了一個自定義的 end-user 請求頭,從而達到效果。
- 執行以下命令以啟用基於使用者的路由:
$ kubectl apply -f ~/bin/istio-1.13.3/samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
virtualservice.networking.istio.io/reviews created
- 確保規則已建立:
$ kubectl get virtualservice reviews -o yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"networking.istio.io/v1alpha3","kind":"VirtualService","metadata":{"annotations":{},"name":"reviews","namespace":"default"},"spec":{"hosts":["reviews"],"http":[{"match":[{"headers":{"end-user":{"exact":"jason"}}}],"route":[{"destination":{"host":"reviews","subset":"v2"}}]},{"route":[{"destination":{"host":"reviews","subset":"v1"}}]}]}}
creationTimestamp: "2022-05-15T16:05:55Z"
generation: 1
name: reviews
namespace: default
resourceVersion: "1984849"
uid: f3bd3dcb-d83c-4a75-9511-1fc9308ca05b
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
- 在 Bookinfo 應用程式的/productpage 上,以使用者 jason 身份登入。重新整理瀏覽器,看到每個評論旁邊顯示星級評分。
- 以其他使用者身份登入,重新整理瀏覽器。發現星級評分消失了。
原理和限制
資料平面,Istio 通過向 Pod 注入的 Sidecar 代理(istio-proxy)來負責協調和控制微服務之前的所有網路通訊。為了讓 Sidecar 代理(istio-proxy)劫持業務容器流量,Istio 需要向 Pod 所在網路下發 iptables 規則。常規安裝模式下,iptables 規則下發是由 Istio 向 Pod 注入的初始化容器 istio-init 完成。向 Pod 網路下發 iptables 規則需要容器可以使用 NET_ADMIN 和 NET_RAW 兩個高許可權的能力(Capabilities)。ASK 叢集中這兩個高許可權能力受 ASK Pod Security Policy [ 6] 和 ECI Container Security Policy [ 7] 的影響。
ASK Pod Security Policy 的 CAPS 為 *,表示沒有限制。
$ kubectl get psp
NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES
ack.privileged true * RunAsAny RunAsAny RunAsAny RunAsAny false *
ECI Container Security Policy 允許通過容器安全上下文配置即可。Istio 中 Pod 注入模板檔案~/bin/istio-1.13.3/manifests/charts/istio-control/istio-discovery/files/injection-template.yaml 包含如下程式碼:不啟用 Istio CNI 外掛 [ 8] 將新增 NET_ADMIN 和 NET_RAW 兩個高許可權能力:
securityContext:
allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }}
privileged: {{ .Values.global.proxy.privileged }}
capabilities:
{{- if not .Values.istio_cni.enabled }}
add:
- NET_ADMIN
- NET_RAW
{{- end }}
drop:
- ALL
所以從原理上分析當前 ASK 叢集使用 Istio 沒有相容性問題。
總結
本次在 ASK 上試用 Istio 這類高複雜度的軟體,未發現相容性問題。又從原理上正面分析論證了產生相容性問題的可能性較低。因此,ASK 對原生 Kubernetes 還是有著極好的相容性。後續將在 ASK 叢集上深入探索 Istio 其他功能,以進一步驗證 ASK 對原生 Kubernetes 的相容性。
參考連結:
[1] 阿里雲 Serverless Kubernetes
http://help.aliyun.com/document_detail/127525.html
[2] Istio 釋出頁面
http://github.com/istio/istio/releases/tag/1.13.3
[3] demo profile**
http://istio.io/latest/docs/setup/additional-setup/config-profiles/
[4] Bookinfo 示例應用
http://istio.io/latest/zh/docs/examples/bookinfo/
[5] 目標規則
http://istio.io/latest/docs/concepts/traffic-management/#destination-rules)中定義好可用的版本中定義好可用的版本)
[6] ASK Pod Security Policy
http://help.aliyun.com/document_detail/165047.html
[7] ECI Container Security Policy
http://help.aliyun.com/document_detail/163023.html
[8] Istio CNI 外掛
http://istio.io/latest/docs/setup/additional-setup/cni/
點選此處,瞭解阿里雲 ASK 更多詳情和最佳實踐
- 啟動!阿里巴巴程式設計之夏2022
- 雲原生混部最後一道防線:節點水位線設計
- OpenKruise v1.2:新增 PersistentPodState 實現有狀態 Pod 拓撲固定與 IP 複用
- Serverless Job——傳統任務新變革
- 首評 | 阿里雲順利完成國內首個雲原生安全成熟度評估
- Serverless Job——傳統任務新變革
- 阿里雲釋出效能測試 PTS 2.0:低成本、高效率、多場景壓測,業務穩定性保障利器
- ZooKeeper 在阿里巴巴的服務形態演進
- OpenYurt v0.7.0 版本解讀:無侵入的跨網路域解決方案 Raven
- K8s 閘道器選型初判:Nginx 還是 Envoy?
- K8s 閘道器選型初判:Nginx 還是 Envoy?
- ZooKeeper 在阿里巴巴的服務形態演進
- 面向高校 | “雲原生技術應用與實踐”示範課程專案開放申報
- 硬之城獲阿里雲首批產品生態整合認證,攜手阿里雲共建新合作
- 基於阿里雲 ASK 的 Istio 微服務應用部署初探
- Seata 1.5.1 重磅釋出,支援使用者控制檯,企業版正式免費公測
- OpenYurt v0.7.0 版本解讀:無侵入的跨網路域解決方案 Raven
- 最佳實踐|從Producer 到 Consumer,如何有效監控 Kafka
- 報名進入尾聲,趕快申請加入 sealer 開源之夏吧!
- OpenClusterManagement 開源之夏 2022 來了