结合Ktctl Mesh和服务网格进行本地开发测试

更新时间:2025-04-23 07:41:13

KtConnect是面向Kubernetes的本地开发者辅助工具,其部署的代理可以兼容服务网格的核心流量管理能力。通过与服务网格的流量资源配合,可以更高效地调试本地应用,加速本地开发测试。本文将介绍如何结合KtConnectASM进行本地开发测试。

背景信息

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
  • 本页导读
  • 背景信息
  • 前提条件
  • 准备工作
  • 操作步骤
  • 步骤一:部署应用及流量策略
  • 步骤二:部署本地开发环境
  • 步骤三:更新流量策略并验证连接
  • (可选)步骤四:清理环境