使用Kubernetes和Istio實現藍綠部署

banq發表於2018-10-22

Istio是一種服務網格,使微服務之間的通訊可靠,透明和安全。Istio攔截Kubernetes中部署的服務訪問。

儘管Istio能夠執行許多操作,包括服務到服務通訊、指標的自動記錄、實施訪問控制策略,速率限制和配額,但我們這裡講專注於流量管理功能。

Istio允許DevOps團隊建立規則,智慧地將流量路由到內部服務。配置服務級屬性(如斷路器,超時和重試)非常簡單,可以設定各種部署模式,包括藍/綠部署和金絲雀部署。

本教程的目的是幫助您瞭解如何使用Istio配置在Kubernetes中執行的微服務的藍/綠部署。除了在Kubernetes中部署pod和服務的基本思想之外,你無需具備探索此方案的任何先決條件。我們將配置從Minikube到Istio的所有內容到示例應用程式。

本教程分為四個步驟 :
1. 安裝Minikube,
2. 安裝和驗證Istio
3. 部署同一應用程式的兩個版本,
4. 最後配置藍/綠部署服務。

我們將使用兩個簡單的預先構建的容器映象來表示藍色(V1)和綠色(V2)版本。

第1步:安裝Minikube
為了最大限度地減少依賴關係,我們將使用Minikube作為我們設定的測試平臺。由於我們需要Minikube的自定義配置,因此請先刪除現有設定並使用其他引數重新啟動群集。

minikube start --memory=8192 --cpus=4 --kubernetes-version=v1.10.0 \
--extra-config=controller-manager.cluster-signing-cert-file="/var/lib/localkube/certs/ca.crt" \
--extra-config=controller-manager.cluster-signing-key-file="/var/lib/localkube/certs/ca.key" \
--vm-driver=virtualbox


我們需要至少8GB的RAM和4核CPU才能在Minikube上執行Istio。等待群集啟動。。。

第2步:安裝Istio
隨著Kubernetes的啟動和執行,現在是我們安裝Istio的時候了。請按照以下步驟進行配置。

$ curl -L https://git.io/getLatestIstio | sh -

在執行上述命令的同一目錄中找到一個資料夾istio-1.0.2。將位置istio-1.0.2 / bin新增到PATH變數,以便於訪問Istio二進位制檔案。

由於我們使用Minikube執行Istio,我們需要進行一次更改,然後再繼續下一步 - 將Ingress Gateway服務從LoadBalancer型別更改為NodePort。

開啟檔案istio-1.0.2 / install / kubernetes / istio-demo.yaml,搜尋LoadBalancer並將其替換為NodePort。 Istio為Kubernetes提供了許多自定義資源定義(CRD)。它們幫助我們從kubectl操縱虛擬服務,規則,閘道器和其他特定於Istio的物件。讓我們在部署實際服務網格之前安裝CRD。

$ kubectl apply -f install/kubernetes/helm/istio/templates/crds.yaml

最後,讓我們在Kubernetes中安裝Istio。

$ kubectl apply -f install/kubernetes/istio-demo.yaml

上面的步驟導致建立一個新的名稱空間 - istio-system - 在其下部署多個物件。
透過kubectl get ns能夠查詢到。

幾分鐘後,您將看到Istio部署的多個pod。透過執行kubectl get pods -n = istio-system驗證這一點

所有pod必須處於執行或完整模式,這表示已成功安裝和配置Istio。
現在,我們已準備好為藍/綠模式部署和配置服務。

第3步:部署同一應用程式的兩個版本
為了表示兩個不同版本的應用程式,我構建了簡單的基於Nginx的Docker映象 - janakiramm /myapp:v1和janakiramm/myapp:v2。部署後,它們會顯示帶有藍色或綠色背景的靜態頁面。我們將使用這些影像作為教程。

apiVersion: v1
kind: Service
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  type: ClusterIP
  ports:
  - port: 80
    name: http
  selector:
    app: myapp
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myapp-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: myapp
        version: v1
    spec:
      containers:
      - name: myapp
        image: janakiramm/myapp:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myapp-v2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: myapp
        version: v2
    spec:
      containers:
      - name: myapp
        image: janakiramm/myapp:v2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80



上面配置檔案在:gist

讓我們首先建立一個YAML檔案,該檔案定義V1和V2的部署以及公開它們的ClusterIP。請注意用於標識pod的標籤labels格式是需要 app和version兩個欄位。雖然應用名稱保持不變,但兩個部署之間的版本不同。

Istio希望將它們視為單個應用程式,但要根據版本區分它們。

ClusterIP服務定義也是如此。labels標籤app:myapp與基於不同版本的兩個部署中的pod相關聯。

  labels:
        app: myapp
        version: v1或v2 這裡版本不同


使用下面kubectl命令建立部署和服務。請注意,這些是簡單的Kubernetes物件,它們不知道Istio是否存在,它們與Istio的唯一連線是我們為其部署和服務建立標籤的方式。

$ kubectl apply -f myapp.yaml

在配置Istio路由之前,讓我們看看我們的應用程式的版本。

要訪問應用程式的V1版本,請執行以下命令並點選localhost:8080。完成後按CTRL + C.

$ kubectl port-forward deployment/myapp-v1 8080:80

對於V2,執行以下命令並點選localhost:8081。完成後按CTRL + C.

$ kubectl port-forward deployment/myapp-v2 8081:80

第4步:配置藍/綠部署

我們的目標是在沒有停機的情況下有選擇地將流量驅動到其中一個部署。為實現這一目標,我們需要告訴Istio根據權重來路由流量。

實現這一目標涉及三個物件:
1.Gateway
Antio Gateway描述了在網格邊緣操作的負載均衡器,用於接收傳入或傳出的HTTP / TCP連線。規範描述了應該公開的一組埠,要使用的協議型別,負載均衡器的SNI配置等。在下面的定義中,我們將閘道器指向安裝期間由Istio建立的預設Ingress Gateway。

讓我們將閘道器建立為Kubernetes物件。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: myapp
spec:
  hosts:
  - "*"
  gateways:
  - app-gateway
  http:
    - route:
      - destination:
          host: myapp
          subset: v1
        weight: 50
      - destination:
          host: myapp
          subset: v2
        weight: 50        



YAML檔案以Github Gist的形式提供

$ kubectl apply -f app-gateway.yaml


現在,讓我們繼續訪問該服務。由於我們將Minikube與NodePort一起使用,因此我們需要獲得執行Ingress Gateway的確切埠。

執行以下命令以訪問Ingress主機(Minikube)和Ingress埠。

$ export INGRESS_HOST=$(minikube ip)

$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')

如果您從瀏覽器訪問URI,您將看到在藍色和綠色頁面之間均勻路由的流量。
我們可以從終端視窗看到結果。從終端視窗執行以下命令,檢視V1和V2的交替響應。

while : ;do export GREP_COLOR='1;33';curl -s 192.168.99.100:31380 \ | grep --color=always "V1" ; export GREP_COLOR='1;36';\ curl -s 192.168.99.100:31380 \ | grep --color=always "vNext" ; sleep 1; done

當上面的命令在迴圈中執行時,讓我們回到app-gateway.yaml檔案來調整權重。將V1的權重設定為0,將V2的權重設定為100。
將新定義提交給Istio。
$ istioctl replace -f app-gateway.yaml

您可以繼續調整權重並觀察動態重新路由的流量,不會導致任何停機。

 

相關文章