istio 配置解讀


Istio在服務網絡中統一提供了許多關鍵功能:

  • 流量管理:控制服務之間的流量和API調用的流向,使得調用更可靠,並使網絡在惡劣情況下更加健壯。

  • 可觀察性:了解服務之間的依賴關系,以及它們之間流量的本質和流向,從而提供快速識別問題的能力。

  • 策略執行:將組織策略應用於服務之間的互動,確保訪問策略得以執行,資源在消費者之間良好分配。策略的更改是通過配置網格而不是修改應用程序代碼。

  • 服務身份和安全:為網格中的服務提供可驗證身份,並提供保護服務流量的能力,使其可以在不同可信度的網絡上流轉。

 

Istio針對可擴展性進行了設計,以滿足不同的部署需要:

  • 平台支持:Istio旨在在各種環境中運行,包括跨雲, 預置,Kubernetes,Mesos等。最初專注於Kubernetes,但很快將支持其他環境。

  • 集成和定制:策略執行組件可以擴展和定制,以便與現有的ACL,日志,監控,配額,審核等解決方案集成。

 

 

Envoy:

    istio 使用Envoy 代理的擴展版本,Envoy是以c++開發的高性能代理,用於解釋服務網格中所有服務的所有入站和出站的流量,Envoy的許多內置功能被iosio發揚光大,例如動態發現,負載均衡,TLS終止,HTTP1/2&Grpc代理,熔斷器,健康檢查,基於百分比流量拆分的分段推出,故障注入和豐富指標。

    Envoy被部署為邊車,和對應服務在同一個pod中,這允許istio將大量關於流量行為的型號作為屬性提取出來,而這些屬性又可以在Mixer中用於執行策略決策,並發送到監控系統,以提供整個網格行為的信息

 

Mixer:

    負責在服務網格上執行訪問控制和使用策略,並從Envoy代理和其他服務收集遙測數據,代理提取請求級屬性,發送到Mixer進行評估。

 

Pilot

   負責手機和驗證配置,並將其傳播到各種istio組件,它從Mixer和Envoy中提取環境特定的實現細節,為他們提供用戶服務的抽象表示,獨立於底層平台,此外,流量管理規則可以在運行時通過pilot進行編程。

 

lstio-auth

     提供強大的服務間認證和終端用戶認證,使用交互tls,內置身份和證書管理,可以升級服務網格中的未加密流量,並為運維人員提供基於服務身份而不是網絡控制來執行策略的能力。

 

 

 

安裝Istio Sidecar

 在Kubernetes 1.9及更高版本中默認啟用。從Istio 0.5.0開始,自動代理注入使用突變webhooks,並且已經刪除了對初始化程序注入的支持。無法升級到Kubernetes 1.9的用戶應使用手動注入。

 

自動把 sidecar 插入到 pod中, 需要在api中打開 

 

[root@master1 addons]# cat /lib/systemd/system/kube-apiserver.service 
[Unit]
Description=Kubernetes API Server Documentation=https://github.com/GoogleCloudPlatform/kubernetes After=network.target [Service] User=root ExecStart=/usr/local/bin/kube-apiserver \ --admission-control=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota,,MutatingAdmissionWebhook,ValidatingAdmissionWebhook \ --advertise-address=192.168.200.51 \ --allow-privileged=true \ --anonymous-auth=false \ --apiserver-count=1 \ --audit-policy-file=/etc/kubernetes/audit-policy.yaml \ --audit-log-maxage=30 \ --audit-log-maxbackup=3 \ --audit-log-maxsize=100 \ --audit-log-path=/var/log/kubernetes/audit.log \ --authorization-mode=Node,RBAC \ --bind-address=0.0.0.0 \ --secure-port=6443 \ --client-ca-file=/etc/kubernetes/ssl/ca.pem \ --enable-swagger-ui=true \ --etcd-cafile=/etc/kubernetes/ssl/ca.pem \ --etcd-certfile=/etc/kubernetes/ssl/kubernetes.pem \ --etcd-keyfile=/etc/kubernetes/ssl/kubernetes-key.pem \ --etcd-servers=https://192.168.200.51:2379,https://192.168.200.52:2379,https://192.168.200.53:2379 \ --event-ttl=1h \ --kubelet-https=true \ --insecure-bind-address=192.168.200.51 \ --insecure-port=8080 \ --service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \ --service-cluster-ip-range=10.254.0.0/16 \ --service-node-port-range=30000-32000 \ --tls-cert-file=/etc/kubernetes/ssl/kubernetes.pem \ --tls-private-key-file=/etc/kubernetes/ssl/kubernetes-key.pem \ --enable-bootstrap-token-auth=true \ --token-auth-file=/etc/kubernetes/token.csv \ --requestheader-client-ca-file=/etc/kubernetes/ssl/front-proxy-ca.pem \ --proxy-client-cert-file=/etc/kubernetes/ssl/front-proxy-client.pem \ --proxy-client-key-file=/etc/kubernetes/ssl/front-proxy-client-key.pem \ --requestheader-allowed-names=aggregator \ --requestheader-group-headers=X-Remote-Group \ --requestheader-extra-headers-prefix=X-Remote-Extra- \ --requestheader-username-headers=X-Remote-User \ --runtime-config=admissionregistration.k8s.io/v1alpha1 \ --runtime-config=api/all=true \ --enable-aggregator-routing=true \ --v=0 Restart=on-failure RestartSec=5 Type=notify LimitNOFILE=65536 [Install] WantedBy=multi-user.target

 

 

 

Pod規格要求

1.服務關聯

2.命名端口

服務端口必須命名。端口名稱必須是形式<protocol>[-<suffix>]與 HTTP, http2, GRPC,或 Redis的作為<protocol>,以便采取的Istio的路由功能。例如,name: http2-foo或者name: http是有效的端口名稱,但name: http2foo不是。如果端口名稱未以可識別的前綴開頭,或者端口未命名,則端口上的流量將被視為純TCP流量(除非端口明確用於Protocol: UDP表示UDP端口

 

3. 使用應用標簽進行部署建議使用Kubernetes部署的Pod在部署規范中Deployment具有明確的app標簽。每個部署規范都應該有一個明確的app標簽,其中有一個值表示有意義的值 app標簽用於在分布式跟蹤中添加上下文信息

 

自動邊車注入

使用webhook准入控制器,可將Sidecars自動添加到適用的Kubernetes Pod中此功能需要Kubernetes 1.9或更高版本。驗證kube-apiserver進程是否已設置admission-control標記,MutatingAdmissionWebhookValidatingAdmissionWebhook按照正確的順序添加並准許控制器,並且啟用許可注冊API。

kubectl api-versions | grep admissionregistration
admissionregistration.k8s.io/v1beta1

 

安裝webhook

kubectl apply -f install/kubernetes/istio.yaml

 

Webhooks需要簽名的證書/密鑰對。使用install/kubernetes/webhook-create-signed-cert.sh來產生由Kubernetes' CA簽名的證書/密鑰對 生成的證書/密鑰文件作為Kubernetes機密文件存儲,供邊車注入器webhook使用。

注意:Kubernetes CA批准需要創建和批准CSR的權限

./install/kubernetes/webhook-create-signed-cert.sh \
    --service istio-sidecar-injector \
    --namespace istio-system \
    --secret sidecar-injector-certs

 

安裝邊車注入配置圖。

kubectl apply -f install/kubernetes/istio-sidecar-injector-configmap-release.yaml

 

Set the caBundle in the webhook install YAML that the Kubernetes api-server uses to invoke the webhook.

cat install/kubernetes/istio-sidecar-injector.yaml | \
     ./install/kubernetes/webhook-patch-ca-bundle.sh > \
     install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml

 

Install the sidecar injector webhook.

kubectl apply -f install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml

 

The sidecar injector webhook should now be running.

kubectl -n istio-system get deployment -listio=sidecar-injector

NAME                     DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
istio-sidecar-injector   1         1         1            1           1d

 

NamespaceSelector根據該對象的名稱空間是否與選擇器匹配來決定是否在對象上運行webhook,默認的webhook配置使用istio-injection=enabled

查看顯示istio-injection標簽的default名稱空間並驗證名稱空間未被標記。

kubectl get namespace -L istio-injection

NAME           STATUS        AGE       ISTIO-INJECTION
default        Active        1h        
istio-system   Active        1h        
kube-public    Active        1h        
kube-system    Active        1h

 

default名稱空間標簽istio-injection=enabled

kubectl label namespace default istio-injection=enabled
kubectl get namespace -L istio-injection

NAME           STATUS    AGE       ISTIO-INJECTION
default        Active    1h        enabled
istio-system   Active    1h        
kube-public    Active    1h        
kube-system    Active    1h  

 

部署一個應用程序

kubectl apply -f samples/sleep/sleep.yaml 

 

 

禁用default名稱空間的注入

kubectl label namespace default istio-injection-

 

 

卸載webhook

kubectl delete -f install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml

 

kubectl -n istio-system delete secret sidecar-injector-certs
kubectl delete csr istio-sidecar-injector.istio-system
kubectl label namespace default istio-injection-

 

 

 

流量管理
介紹演示Istio服務網格的流量路由功能的任務。

配置請求路由:  此任務向您展示如何根據權重和HTTP標頭配置動態請求路由。
故障注入  :  此任務顯示如何注入延遲並測試應用程序的彈性。
交通轉移  :  此任務向您顯示如何將流量從舊版本遷移到新版本的服務。
設置請求超時:  本任務向您展示如何使用Istio在Envoy中設置請求超時。
Istio Ingress  :  介紹如何在Kubernetes上配置Istio Ingress。
控制出口流量:  介紹如何配置Istio以將流量從網格中的服務路由到外部服務。
控制出口TCP流量:介紹如何配置Istio以將TCP流量從網格中的服務路由到外部服務。
斷路    :  這項任務演示了彈性應用的斷路能力
鏡像    :  演示Istio的流量投影/鏡像功能

 

 

 deployment 和 service 模版 ,使用標簽 app version, 一個服務對應不同的deployment

apiVersion: v1
kind: Service
metadata:
  name: reviews
  labels:
    app: reviews
spec:
  type: NodePort
  ports:
  - port: 9080
    name: http
  selector:
    app: reviews
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: reviews-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: reviews
        version: v1
    spec:
      containers:
      - name: reviews
        image:  192.168.200.10/istio/examples-bookinfo-reviews-v1:1.5.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: reviews-v2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: reviews
        version: v2
    spec:
      containers:
      - name: reviews
        image:  192.168.200.10/istio/examples-bookinfo-reviews-v2:1.5.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: reviews-v3
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: reviews
        version: v3
    spec:
      containers:
      - name: reviews
        image:  192.168.200.10/istio/examples-bookinfo-reviews-v3:1.5.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080

 

配置請求路由

 

原理: 首先使用istio將100%的請求流量路由到了 v1 版本上, 然后設置了一條路由規則, 該規則基於請求header(一個用戶的cookie)將流量路由到了 v2 版本,  如果v2 版本經過測試后滿足要求,我們就可以一次性

或者漸進的路由到v2版本上。

 

1. 默認訪問 version v1 版本

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: reviews-default
spec:
  destination:
    name: reviews
  precedence: 1
  route:
  - labels:
      version: v1

 

2. 將特定用戶的請求路由到 version v2上

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: reviews-test-v2
spec:
  destination:
    name: reviews
  precedence: 2
  match:
    request:
      headers:
        cookie:
          regex: "^(.*?;)?(user=jason)(;.*)?$"
  route:
  - labels:
      version: v2

 

 

故障注入

istio 注入延遲 測試應用彈性

2個服務, serverA  和 serverB

serverA 用戶(feng) 和 serverB 之間 注入7秒延遲,    serverA 針對 serverB 服務設置了10秒超時,期望 端對端的流程能無錯持續。

 注意: 其他用戶沒有注入7秒延遲。

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: ratings-test-delay
spec:
  destination:
    name: ratings
  precedence: 2
  match:
    request:
      headers:
        cookie:
          regex: "^(.*?;)?(user=jason)(;.*)?$"
  route:
  - labels:
      version: v1
  httpFault:
    delay:
      percent: 100
      fixedDelay: 7s

 

使用賬戶 feng 登錄, 如果應用首頁已經設置了正確處理延遲,那么首頁將會在 7秒加載完成,但是 serverA 到 serverB 需要等待10秒,那么將超時。

 

 流量轉移:

應用流量 逐步有舊版本的服務 遷移到新版本, 通過istio 可以使用不同權重的規則,將流量平穩的從舊版本服務 遷移到新版本上, 金絲雀 灰度發布。

 1. 請求v1 版本

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: reviews-default spec: destination: name: reviews precedence: 1 route: - labels: version: v1

 

 2. 把50% 的流量從 v1 版本 轉移到 v3版本

 

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: reviews-default
spec:
  destination:
    name: reviews
  precedence: 1
  route:
  - labels:
      version: v1
    weight: 50
  - labels:
      version: v3
    weight: 50

用 kubectl  apply/ replace 替換

 

3. v3 和 v1 版本交替出現后, 將100%的流量路由到v3 版本中

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: reviews-default
spec:
  destination:
    name: reviews
  precedence: 1
  route:
  - labels:
      version: v3
    weight: 100

 

 

 ###################################################################################################

 實戰:

一個服務,對應3個deployment, 最后通過istio-ingress 映射域名

 

nginx.yaml

apiVersion: v1
kind: Service
metadata:
  namespace: fengjian
  name: nginx
  labels:
    app: nginx
spec:
  type: NodePort
  ports:
  - port: 80
    name: http
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: fengjian
  name: nginx-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
        version: v1
    spec:
      containers:
      - name: nginx
        image:  192.168.200.10/test/nginx:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: fengjian
  name: nginx-v2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
        version: v2
    spec:
      containers:
      - name: nginx
        image:  192.168.200.10/test/nginx:v2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: fengjian
  name: nginx-v3
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
        version: v3
    spec:
      containers:
      - name: nginx
        image:  192.168.200.10/test/nginx:v3
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

 

2. 通過istio-ingress 讓外網訪問,注意: pod 注入 enovy后,nodeport 不起作用了,服務無法訪問。

istio-ingress-bookinfo.yaml 

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: gatewayfengjian
  namespace: fengjian
  annotations:
    kubernetes.io/ingress.class: "istio"
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: nginx
          servicePort: 80

 

創建執行

[root@master1 nginx-istio]# kubectl create -f booktest.yaml  -f istio-ingress-bookinfo.yaml 

 

 

 默認情況, 訪問應該輪訓到 3個deployment的上的nginx ,  通過流量管理中的 配置請求路由規則,指定到 deployment  nginx:v1 版本上

vim rule-choice-deployment-nginx-v1.yaml

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  namespace: fengjian
  name: nginx-default
spec:
  destination:
    name: nginx
  precedence: 1
  route:
  - labels:
      version: v1

 

創建規則

kubectl create -f rule-choice-deployment-nginx-v1.yaml

 

 訪問istio-ingress 

 

 注意的問題: 

 

 

 

流量轉移

流量從 舊版本中遷移到新版本中, 通過istio,可以使用一系列不同權重的規則(10%,20%.....100%),將流量平穩的遷移到新版本中

1. 遷移50%到新版本中

route-rule-reviews-50.yaml

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  namespace: fengjian
  name: nginx-50
spec:
  destination:
    name: nginx
  precedence: 1
  route:
  - labels:
      version: v1
    weight: 50
  - labels:
      version: v3
    weight: 50

 

通過訪問頁面,基本上是50%的輪訓到頁面。

 

2. 遷移100%到新版本中

route-rule-reviews-100.yaml

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  namespace: fengjian
  name: nginx-50
spec:
  destination:
    name: nginx
  precedence: 1
  - labels:
      version: v3
    weight: 100

 

 是更新,不是創建

kubectl apply -f route-rule-reviews-100.yaml

 

 注意該方式和使用容器編排平台的部署特點來進行版本遷移是完全不同的,容器編排平台使用了實例scaling來對流量進行管理,而通過istio,兩個版本的的服務可以獨立進行

scale up 和 scale down,並不會影響這兩個版本的服務之間的流量分發。

 

 

 熔斷

限制因為故障、延遲高峰以及其他預計外的網絡異常所造成的影響范圍。

服務端使用 nginx

 

 

配置目的策略,對nginx 的調用過程進行斷路設置。

 

nginx-destinaionpolicy.yaml

apiVersion: config.istio.io/v1beta1
kind: DestinationPolicy
metadata:
 name: nginx-circuit-breaker
spec:
 destination:
   name: nginx
   labels:
     version: v1
 circuitBreaker:
   simpleCb:
     maxConnections: 1
     httpMaxPendingRequests: 1
     sleepWindow: 3m
     httpDetectionInterval: 1s
     httpMaxEjectionPercent: 100
     httpConsecutiveErrors: 1
     httpMaxRequestsPerConnection: 1

 

kubectl  create -f  nginx-destinaionpolicy.yaml

istioctl get destinationpolicy

NAME                    KIND                                            NAMESPACE
nginx-circuit-breaker DestinationPolicy.v1alpha2.config.istio.io        istio-samples

 

設置客戶端

客戶端調用ginx服務的規則, 創建一個客戶端,向服務端發送流量, 使用負載測試工具fortio, 使用fortio 可以控制連接數量,並發數以及外發http調用的延遲。

kubectl apply -f <(istioctl kube-inject -f samples/httpbin/sample-client/fortio-deploy.yaml)

 

使用-curl 指定只執行一次調用。

FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1 }')
kubectl exec -it $FORTIO_POD  -c fortio /usr/local/bin/fortio -- load -curl  http://nginx:8000

 

測試斷路器

在斷路器設置中,我們指定maxConnections: 1以及httpMaxPendingRequests: 1。這樣的設置下,如果我們並發超過一個連接和請求,istio-proxy就會斷掉后續的請求和連接。設置兩個並發鏈接(-c 2),發送20個請求(-n 20):

[root@master1 httpbin]# kubectl exec -it fortio-deploy-d86464f9d-ks4hm   -c fortio /usr/local/bin/fortio -- load -c 2 -qps 0 -n 20 -loglevel Warning http://nginx.fengjian
08:10:21 I logger.go:97> Log level is now 3 Warning (was 2 Info)
Fortio 0.9.0 running at 0 queries per second, 4->4 procs, for 20 calls: http://nginx.fengjian
Starting at max qps with 2 thread(s) [gomax 4] for exactly 20 calls (10 per thread + 0)
Ended after 18.157183ms : 20 calls. qps=1101.5
Aggregated Function Time : count 20 avg 0.0016854434 +/- 0.0008323 min 0.000847509 max 0.004309432 sum 0.033708867
# range, mid point, percentile, count
>= 0.000847509 <= 0.001 , 0.000923755 , 15.00, 3
> 0.001 <= 0.002 , 0.0015 , 65.00, 10
> 0.002 <= 0.003 , 0.0025 , 95.00, 6
> 0.004 <= 0.00430943 , 0.00415472 , 100.00, 1
# target 50% 0.0017
# target 75% 0.00233333
# target 90% 0.00283333
# target 99% 0.00424755
# target 99.9% 0.00430324
Sockets used: 2 (for perfect keepalive, would be 2)
Code 200 : 20 (100.0 %)
Response Header Sizes : count 20 avg 237 +/- 0 min 237 max 237 sum 4740
Response Body/Total Sizes : count 20 avg 246 +/- 0 min 246 max 246 sum 4920
All done 20 calls (plus 0 warmup) 1.685 ms avg, 1101.5 qps

 

 

設置兩個並發鏈接(-c 100000),發送20個請求(-n 200000

kubectl exec -it fortio-deploy-d86464f9d-ks4hm   -c fortio /usr/local/bin/fortio -- load -c 100000 -qps 0 -n 20000 -loglevel Warning http://nginx.fengjian

> 50 <= 75 , 62.5 , 42.37, 12001
> 75 <= 100 , 87.5 , 47.88, 5515
> 100 <= 283.465 , 191.733 , 100.00, 52118
# target 50% 107.452
# target 75% 195.459
# target 90% 248.263
# target 99% 279.945
# target 99.9% 283.113
Sockets used: 100001 (for perfect keepalive, would be 100000)
Code  -1 : 62857 (62.9 %)
Code 200 : 19587 (19.6 %)
Code 503 : 17558 (17.6 %)
Response Header Sizes : count 100002 avg 46.731345 +/- 94.69 min 0 max 240 sum 4673228
Response Body/Total Sizes : count 100002 avg 86.594238 +/- 113 min 0 max 249 sum 8659597
All done 100002 calls (plus 0 warmup) 123391.636 ms avg, 352.1 qps

 

 

策略實施

限流

如果是一個外部付費API服務, 限制1 qps免費, 使用istio 控制。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM