全部產品
Search
文件中心

Alibaba Cloud Service Mesh:結合Ktctl Mesh和服務網格進行本地開發測試

更新時間:Apr 24, 2025

KtConnect是面向Kubernetes的本地開發人員協助工具輔助,其部署的代理可以相容服務網格的核心流量管理能力。通過與服務網格的流量資源配合,可以更高效地調試本地應用,加速本地開發測試。本文將介紹如何結合KtConnect和ASM進行本地開發測試。

背景資訊

KtConnect是一款開源工具,主要設計用於改善開發人員在Kubernetes環境中的工作流程。它支援在Kubernetes中部署代理程式Pod,將發往特定服務的流量重新導向至本地部署的應用,實現本地環境與Kubernetes叢集的雙向互聯。KtConnect的核心功能有:

  • 本地直接存取Kubernetes叢集內網。

    通過KtConnect可以直接連接Kubernetes叢集內部網路,在不修改代碼的情況下完成本地聯調測試。

  • 本地解析Kubernetes服務內網網域名稱。

    直接使用服務名解析服務Cluster IP,本地開發也能獲得真正的雲原生體驗。

  • 重新導向叢集服務流量到本地。

    將叢集中的流量轉移到本地,使得叢集中的服務無需額外配置即可訪問本地服務。

  • 測試環境多人協作互不干擾。

    通過自動或手工設定流量規則,在不影響測試環境正常使用的情況下,僅將指定請求重新導向到本地。

  • 支援Windows/MacOS/Linux開發環境。

    不同的作業系統,相同的使用方式,讓所有開發人員輕鬆共用Kubernetes網路互連的便利。

前提條件

準備工作

本文樣本示範以下情境:

  • 在叢集中部署v1版本的helloworld應用,以及對應的流量策略。

  • 本地環境使用docker部署v2版本的helloworld應用,通過ktctl命令列在叢集中部署代理程式Pod聯通本地環境和叢集環境。

  • 更新流量策略,通過不同的要求標頭來區分叢集中的v1版本應用和本地的v2版本應用。

  1. 安裝並配置ktctl

  2. 在叢集中建立命名空間。

    kubectl create ns mesh-demo
  3. 為命名空間啟用Sidecar注入。

    kubectl label ns mesh-demo istio-injection=enabled

操作步驟

步驟一:部署應用及流量策略

  1. mesh-demo命名空間部署應用。

    kubectl apply -f - <<EOF
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: helloworld
      labels:
        app: helloworld
        version: v1
        stage: online
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: helloworld 
          version: v1
          stage: online
      template:
        metadata:
          labels:
            app: helloworld 
            version: v1
            stage: online
        spec:
          containers:
          - name: helloworld 
            env:
            - name: PODIP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: STAGE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['stage']
            - name: VERSION 
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['version']
            command: ["/http-echo"]
            args:
              - "-text"
              - "Welcome to helloworld stage: $(STAGE), version: $(VERSION), ip: $(PODIP)"
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/asm-http-echo:1.0
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 5678
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: helloworld
      labels:
        app: helloworld
        service: helloworld
    spec:
      ports:
      - port: 8000
        name: http
        targetPort: 5678
      selector:
        app: helloworld
    EOF
  2. 部署策略。

    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: helloworld-gateway
    spec:
      selector:
        istio: ingressgateway
      servers:
      - hosts:
        - 'helloworld.mesh.com'
        port:
          name: http
          number: 80
          protocol: HTTP
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: helloworld
    spec:
      host: helloworld
      subsets:
      - name: v1
        labels:
          version: v1
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: helloworld
    spec:
      gateways:
      - helloworld-gateway
      hosts:
      - helloworld.mesh.com
      http:
      - route:
        - destination:
            host: helloworld
            subset: v1
    EOF
  3. 驗證策略。

    export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    curl ${INGRESS_HOST} -H 'host: helloworld.mesh.com'

    預期輸出:

    Welcome to helloworld stage: online, version: v1, ip: 172.23.16.246

    可以看到,輸出中的stageonlineversionv1,與預期一致。

步驟二:部署本地開發環境

  1. 通過docker部署v2版本的helloworld應用。

    docker run -itd --rm \
        --name local-container \
        -p 5678:5678 \
        registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/asm-http-echo:1.0 \
        -text "Welcome to helloworld stage: local, version: v2, ip: 127.0.0.1"
  2. 在叢集中部署KtConnect代理。這將在您的叢集mesh-demo命名空間下部署代理程式 Pod。其帶有標籤version=hzall

    ktctl -n mesh-demo mesh helloworld --expose 5678 --mode manual

    預期輸出:

    4:22PM INF Using cluster context cluster-4KvcBF (kubernetes)
    4:22PM INF KtConnect 0.3.7 start at 59150 (darwin amd64)
    4:22PM INF Fetching cluster time ...
    4:22PM INF Using manual mode
    4:22PM INF Successful create config map helloworld-kt-mesh-hzall
    4:22PM INF Deploying shadow pod helloworld-kt-mesh-hzall in namespace mesh-demo
    4:22PM INF Waiting for pod helloworld-kt-mesh-hzall ...
    4:22PM INF Waiting for pod helloworld-kt-mesh-hzall ...
    4:22PM INF Pod helloworld-kt-mesh-hzall is ready
    4:22PM INF Forwarding pod helloworld-kt-mesh-hzall to local via port 5678
    4:22PM INF Port forward local:17982 -> pod helloworld-kt-mesh-hzall:22 established
    4:22PM INF Reverse tunnel 0.0.0.0:5678 -> 127.0.0.1:5678 established
    4:22PM INF ---------------------------------------------------------
    4:22PM INF  Now you can update Istio rule by label 'version=hzall' 
    4:22PM INF ---------------------------------------------------------
  3. 查看代理Pod。

    kubectl get pod -n mesh-demo

    預期輸出:

    NAME                         READY   STATUS    RESTARTS   AGE
    helloworld-5cbdxxxxx-xxxxx   2/2     Running   0          116m
    helloworld-kt-mesh-hzall     2/2     Running   0          106m

    其中helloworld-kt-mesh-hzall為部署的代理 pod

步驟三:更新流量策略並驗證串連

  1. 更新策略。將包含x-env=local要求標頭的請求轉寄至v2版本的helloworld本地應用,其他請求仍然發往叢集中的v1版本的helloworld應用。

    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: helloworld
    spec:
      host: helloworld
      subsets:
      - name: v1
        labels:
          version: v1
      - name: local
        labels:
          version: hzall
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: helloworld
    spec:
      gateways:
      - helloworld-gateway
      hosts:
      - helloworld.mesh.com
      http:
      - match:
        - headers: 
            x-env:
              exact: local
        route:
        - destination:
            host: helloworld
            subset: local
      - route:
        - destination:
            host: helloworld
            subset: v1
    EOF
  2. 訪問本地應用。

    curl ${INGRESS_HOST} -H 'host: helloworld.mesh.com' -H 'x-env: local'

    預期輸出:

    Welcome to helloworld stage: local, version: v2, ip: 127.0.0.1

    可以看到,輸出中的stagelocalversionv2。表明本地和叢集的雙向互聯配置成功,可以從叢集訪問到本地服務。

  3. 訪問叢集應用。

    curl ${INGRESS_HOST} -H 'host: helloworld.mesh.com'

    預期輸出:

    Welcome to helloworld stage: online, version: v1, ip: 172.23.16.246

(可選)步驟四:清理環境

  1. 刪除建立的叢集測試資源。

    kubectl delete ns mesh-demo
  2. 停止本地應用。

    docker stop local-container