Tüm Ürünler
Search
Belge Merkezi

Alibaba Cloud Service Mesh:Obtain client source IP in Alibaba Cloud Service Mesh

Son Güncelleme:Oct 07, 2026

Bu konu, hizmetlerinize erişim sağlanırken istemci kaynak IP'sinin korunması için Service Mesh yapılandırmasının nasıl yapılacağını açıklar.

Önkoşullar

Arka plan bilgileri

İstemci kaynak IP'si aşağıdakiler dahil olmak üzere birçok senaryoda kullanılır:

  • Uygulama erişim kontrolü: Örneğin, birçok uygulama kullanıcı farklı bir bölgeden oturum açtığında ek kimlik doğrulama uygular; bu durum istemcinin orijinal IP'sinin alınmasını gerektirir.

  • Basit oturum yakınlığı: Aynı istemciden gelen istekleri aynı hizmet örneğine iletmek için kaynak IP tabanlı yük dengeleme yapabilirsiniz.

  • Erişim günlükleri ve izleme: Gerçek kaynak adresini içeren erişim günlükleri ve izleme ölçümleri, geliştiricilerin trafiği analiz etmesine ve istatistik toplamasına yardımcı olur.

Server Load Balancer (SLB) gibi bulut yük dengeleyiciler, istemci kaynak IP'sini arka uç hizmetlere iletebilir. Istio da bu yeteneği sunmalıdır. Ancak, Istio kullanırken her pod'a bir sidecar proxy enjekte edilir. Bu proxy, tüm gelen trafiği engeller ve yerel bir bağlantı (127.0.0.1) üzerinden uygulamanıza iletir. Sonuç olarak, uygulamanız gerçek istemci kaynak IP'sini göremez.

Örnek uygulamaları dağıtma

  1. sleep uygulamasını dağıtın.

    1. Aşağıdaki içeriğe sahip sleep.yaml adlı bir dosya oluşturun.

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: sleep
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: sleep
        labels:
          app: sleep
          service: sleep
      spec:
        ports:
        - port: 80
          name: http
        selector:
          app: sleep
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: sleep
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: sleep
        template:
          metadata:
            labels:
              app: sleep
          spec:
            terminationGracePeriodSeconds: 0
            serviceAccountName: sleep
            containers:
            - name: sleep
              image: curlimages/curl
              command: ["/bin/sleep", "3650d"]
              imagePullPolicy: IfNotPresent
              volumeMounts:
              - mountPath: /etc/sleep/tls
                name: secret-volume
            volumes:
            - name: secret-volume
              secret:
                secretName: sleep-secret
                optional: true
    2. sleep uygulamasını dağıtmak için aşağıdaki komutu çalıştırın.

      kubectl -n default apply -f  sleep.yaml
  2. httpbin uygulamasını dağıtın.

    1. Aşağıdaki içeriğe sahip httpbin.yaml adlı bir dosya oluşturun.

      apiVersion: v1
      kind: Service
      metadata:
        name: httpbin
        labels:
          app: httpbin
      spec:
        ports:
        - name: http
          port: 8000
        selector:
          app: httpbin
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: httpbin
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: httpbin
            version: v1
        template:
          metadata:
            labels:
              app: httpbin
              version: v1
          spec:
            containers:
            - image: docker.io/citizenstig/httpbin
              imagePullPolicy: IfNotPresent
              name: httpbin
              ports:
              - containerPort: 8000
    2. httpbin uygulamasını dağıtmak için aşağıdaki komutu çalıştırın.

      kubectl -n default apply -f  httpbin.yaml

Senaryo 1: Doğu-batı trafiği

1. Adım: Varsayılan istemci kaynak IP davranışını doğrulayın

Istio'da, her hizmetin sidecar proxy'si tüm doğu-batı trafiğini engeller. Bu proxy, istekleri uygulama konteynerine iletir; bu nedenle uygulamanın gördüğü kaynak adresi, proxy'nin loopback adresi olan 127.0.0.6 olur.

  1. Pod durumunu kontrol etmek için aşağıdaki komutu çalıştırın.

    kubectl -n default get pods -o wide

    Beklenen çıktı:

    NAME                            READY   STATUS        RESTARTS   AGE     IP             NODE                     NOMINATED NODE   READINESS GATES
    httpbin-c85bdb469-4ll2m         2/2     Running       0          3m22s   172.17.X.XXX   cn-hongkong.10.0.0.XX    <none>           <none>
    sleep-8f764df66-q7dr2           2/2     Running       0          3m9s    172.17.X.XXX   cn-hongkong.10.0.0.XX    <none>           <none>

    Çıktı, sleep uygulamasının adresinin 172.17.X.XXX olduğunu gösterir.

  2. sleep konteynerinden bir istek göndermek için aşağıdaki komutu çalıştırın.

    kubectl -n default exec -it deploy/sleep -c sleep -- curl http://httpbin:8000/ip

    Beklenen çıktı:

    {
      "origin": "127.0.0.6"
    }

    Çıktı, httpbin uygulaması tarafından alınan isteğin kaynak adresinin sleep uygulamasının adresi değil, Envoy proxy adresi olan 127.0.0.6 olduğunu gösterir.

  3. Kaynak IP adresinin 127.0.0.6 olduğunu soket bilgilerini inceleyerek doğrulayın.

    1. httpbin konteynerine oturum açın ve netstat yüklemek için aşağıdaki komutu çalıştırın.

      apt update & apt install net-tools
    2. httpbin konteynerinden çıkın ve 8000 bağlantı noktasıyla ilgili bilgileri görüntülemek için aşağıdaki komutu çalıştırın.

      kubectl -n default exec -it deploy/httpbin -c httpbin -- netstat -ntp | grep 8000

      Beklenen çıktı:

      tcp        0      0 172.17.X.XXX:8000         127.0.0.6:42691         TIME_WAIT   -

      Çıktı, kaynak IP adresinin 127.0.0.6 olduğunu gösterir.

  4. httpbin pod'undaki erişim günlüğünün içeriğini görüntüleyin.

    Aşağıda örnek biçimlendirilmiş bir günlük girişi verilmiştir:

    {
      "trace_id":null,
      "bytes_received":0,
      "upstream_host":"172.17.X.XXX:8000",
      "authority":"httpbin:8000",
      "downstream_remote_address":"172.17.X.XXX:56160",
      "upstream_service_time":"1",
      "upstream_transport_failure_reason":null,
      "istio_policy_status":null,
      "path":"/ip",
      "bytes_sent":28,
      "request_id":"4501a50a-dab0-44c9-b52c-2a4f425a****",
      "protocol":"HTTP/1.1",
      "method":"GET",
      "duration":1,
      "start_time":"2022-11-22T16:09:30.394Z",
      "user_agent":"curl/7.86.0-DEV",
      "upstream_local_address":"127.0.0.6:42169",
      "response_flags":"-",
      "route_name":"default",
      "response_code":200,
      "upstream_cluster":"inbound|80||",
      "x_forwarded_for":null,
      "downstream_local_address":"172.17.X.XXX:8000",
      "requested_server_name":"outbound_.8000_._.httpbin.default.svc.cluster.local"
    }

    Günlük aşağıdaki bilgileri gösterir:

    • "downstream_remote_address":"172.17.X.XXX:56160": Sleep uygulamasının adresi.

    • "downstream_local_address":"172.17.X.XXX:8000": Sleep uygulamasının eriştiği hedef adres.

    • "upstream_local_address":"127.0.0.6:42169": httpbin Envoy proxy'sinin httpbin uygulamasına bağlanmak için kullandığı yerel adres. Bu noktada, uygulamanın gördüğü kaynak IP 127.0.0.6 olur.

    • "upstream_host":"172.17.X.XXX:8000": httpbin Envoy proxy'sinin eriştiği hedef adres.

2. Adım: Kaynak IP korumayı yapılandırın

Yöntem 1: TPROXY modunu kullanma

httpbin dağıtımını TPROXY şeffaf engelleme modunu kullanacak şekilde yapılandırın.

  1. httpbin uygulamasının dağıtımını değiştirmek için aşağıdaki komutu çalıştırın.

    kubectl patch deployment -n default httpbin -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/interceptionMode":"TPROXY"}}}}}'                       
  2. sleep konteynerinden bir istek göndermek için aşağıdaki komutu çalıştırın.

    kubectl -n default exec -it deploy/sleep -c sleep -- curl http://httpbin:8000/ip

    Beklenen çıktı:

    {
      "origin": "172.17.X.XXX"
    }

    Çıktı, httpbin uygulamasının sleep uygulamasının gerçek IP adresini alabildiğini gösterir.

  3. 8000 bağlantı noktasıyla ilgili bilgileri görüntülemek için aşağıdaki komutu çalıştırın.

    Not

    Pod yeniden başlatıldıktan sonra netstat öğesini yeniden yüklemeniz gerekir.

    kubectl -n default exec -it deploy/httpbin -c httpbin -- netstat -ntp | grep 8000

    Beklenen çıktı:

    tcp        0      0 172.17.X.XXX:8000         172.17.X.XXX:36728      ESTABLISHED -

    Çıktı, kaynak IP adresinin 172.17.X.XXX olduğunu gösterir.

  4. httpbin pod'undaki erişim günlüğünün içeriğini görüntüleyin.

    Aşağıda örnek biçimlendirilmiş bir günlük girişi verilmiştir:

    {
      "route_name":"default",
      "bytes_received":0,
      "trace_id":null,
      "request_id":"1ccabe60-63cf-469b-8565-99cac546****",
      "upstream_cluster":"inbound|80||",
      "response_flags":"-",
      "protocol":"HTTP/1.1",
      "upstream_transport_failure_reason":null,
      "requested_server_name":"outbound_.8000_._.httpbin.default.svc.cluster.local",
      "response_code":200,
      "user_agent":"curl/7.86.0-DEV",
      "start_time":"2022-11-22T16:03:32.803Z",
      "path":"/ip",
      "authority":"httpbin:8000",
      "bytes_sent":31,
      "downstream_remote_address":"172.17.X.XXX:39058",
      "upstream_service_time":"1",
      "method":"GET",
      "downstream_local_address":"172.17.X.XXX:8000",
      "duration":1,
      "upstream_host":"172.17.X.XXX:8000",
      "istio_policy_status":null,
      "upstream_local_address":"172.17.X.XXX:46129",
      "x_forwarded_for":null
    }

    Günlük aşağıdaki bilgileri gösterir:

    • "downstream_remote_address":"172.17.X.XXX:39058": Sleep uygulamasının adresi.

    • "downstream_local_address":"172.17.X.XXX:8000": Sleep uygulamasının eriştiği hedef adres.

    • "upstream_local_address":"172.17.X.XXX:46129": httpbin Envoy proxy'sinin httpbin uygulamasına bağlanmak için kullandığı yerel adres; bu, sleep uygulamasının IP adresidir.

    • "upstream_host":"172.17.X.XXX:8000": httpbin Envoy proxy'sinin eriştiği hedef adres.

Yöntem 2: XFF üst bilgisini kullanma

Aşağıdaki yapılandırma, sunucu tarafındaki sidecar proxy'nin gelen isteklere bir X-Forwarded-For (XFF) üst bilgisi eklemesini sağlar. Proxy, isteği uygulamaya iletmeden önce bu üst bilginin değerini istemcinin gerçek IP adresine ayarlar. Bu yöntemin işletim sistemi sınırlaması yoktur, ancak uygulamanızın istemcinin kaynak IP'sini X-Forwarded-For (XFF) üst bilgisinden okumasını gerektirir.

  1. Bir EnvoyFilter şablonu kullanarak aşağıdaki EnvoyFilter'ı ASM örneğine uygulayın. Daha fazla bilgi için bkz. Envoy filter şablonu kullanarak Envoy filter oluşturma.

    apiVersion: networking.istio.io/v1alpha3
    kind: EnvoyFilter
    metadata:
      name: enable-xff-for-sidecar-inbound
      namespace: istio-system  # Change this to the namespace where your gateway is located.
      labels:
        asm-system: "true"
        provider: "asm"
    spec:
      configPatches:
      - applyTo: NETWORK_FILTER
        match:
          proxy:
            proxyVersion: "^1.*"
          context: SIDECAR_INBOUND 
          listener:
            name: "virtualInbound"
            filterChain:
              filter:
                name: "envoy.filters.network.http_connection_manager"
        patch:
          operation: MERGE
          value:
            typed_config:
              "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
              use_remote_address: true
  2. sleep konteynerinden bir istek göndermek için aşağıdaki komutu çalıştırın.

    kubectl -n default exec -it deploy/sleep -c sleep -- curl http://httpbin:8000/ip
  3. Beklenen çıktı:

    {
      "origin": "172.17.X.XXX"
    }

    Çıktı, httpbin'in sleep uygulamasının gerçek IP adresini aldığını gösterir. httpbin uygulaması bunu, sidecar proxy'nin artık eklediği X-Forwarded-For (XFF) üst bilgisinden kaynak IP'yi okuyacak şekilde tasarlandığı için yapabilir. Uygulamanız XFF üst bilgisini okuyamıyorsa bu yöntem işe yaramaz.

Senaryo 2: Kuzey-güney trafiği

Kuzey-güney trafiğinde istekler bir istemciden yük dengeleyici ve Istio giriş ağ geçidi üzerinden arka uç hizmetine akar. Giriş ağ geçidi üzerinden yapılan bu ekstra atlama, istemci kaynak IP'sinin korunmasını daha karmaşık hale getirir. Aşağıdaki bölümlerde HTTP ve HTTPS istekleri için kaynak IP korumanın nasıl yapılandırılacağı ve doğrulanacağı açıklanmaktadır.

HTTP istekleri

Kaynak IP koruma olmadan

  1. httpbin uygulamasına HTTP üzerinden erişmek için aşağıdaki içeriğe sahip http-demo.yaml adlı bir dosya oluşturun.

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: httpbin-gw-httpprotocol
      namespace: default
    spec:
      selector:
        istio: ingressgateway
      servers:
        - hosts:
            - '*'
          port:
            name: http
            number: 80
            protocol: HTTP
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: httpbin
      namespace: default
    spec:
      gateways:
        - httpbin-gw-httpprotocol
      hosts:
        - '*'
      http:
        - route:
            - destination:
                host: httpbin
                port:
                  number: 8000
  2. Ağ geçidini ve VirtualService'i dağıtmak için aşağıdaki komutu çalıştırın.

    kubectl -n default apply -f  http-demo.yaml
  3. Giriş ağ geçidi üzerinden httpbin uygulamasına erişmek için aşağıdaki komutu çalıştırın.

    export GATEWAY_URL=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    curl http://$GATEWAY_URL:80/ip

    Beklenen çıktı:

    {
      "origin": "10.0.0.93"
    }

    Çıktı, döndürülen IP adresinin bir Kubernetes düğümünün adresi olduğunu gösterir.

  4. Giriş ağ geçidinin erişim günlüğünü görüntüleyin.

    Aşağıda örnek bir günlük girişi verilmiştir:

    {
      "upstream_service_time":"1",
      "response_code":200,
      "protocol":"HTTP/1.1",
      "bytes_sent":28,
      "upstream_cluster":"outbound|8000||httpbin.default.svc.cluster.local",
      "start_time":"2022-11-23T03:29:20.017Z",
      "istio_policy_status":null,
      "upstream_transport_failure_reason":null,
      "trace_id":null,
      "route_name":null,
      "request_id":"292903be-a889-4d5d-83a0-ab1f5d1a****",
      "method":"GET",
      "upstream_host":"172.17.X.XXX:8000",
      "duration":1,
      "path":"/ip",
      "downstream_local_address":"172.17.X.XXX:80",
      "authority":"47.242.XXX.XX",
      "user_agent":"curl/7.79.1",
      "downstream_remote_address":"10.0.0.93:5899",
      "upstream_local_address":"172.17.X.XXX:54322",
      "requested_server_name":null,
      "x_forwarded_for":"10.0.0.93",
      "response_flags":"-",
      "bytes_received":0
    }

    Günlük aşağıdaki bilgileri gösterir:

    • "downstream_remote_address":"10.0.0.93:5899": İstemcinin gerçek kaynak IP'si değildir.

    • "downstream_local_address":"172.17.X.XXX:80": Giriş ağ geçidi pod'unun adresi.

    • "upstream_local_address":"172.17.X.XXX:54322": Giriş ağ geçidi pod'unun IP adresi korunur ancak bağlantı noktası numarası değiştirilir.

    • "upstream_host":"172.17.X.XXX:8000": httpbin pod'unun adresi.

With source IP preservation

  1. Harici trafik ilkesini Local olarak ayarlayın. (Terway ağ modunu kullanan kümeler için bu adımı atlayabilirsiniz.)

    1. ASM konsolu üzerinde oturum açın. Sol gezinme bölmesinde Service Mesh > Mesh Management seçeneğini belirleyin.

    2. Mesh Management sayfasında ASM örneğinin adını tıklayın. Sol gezinme bölmesinde ASM Gateways > Ingress Gateway seçeneğini belirleyin.

    3. Ingress Gateway sayfasında hedef ağ geçidinin sağındaki View YAML seçeneğini tıklayın.

    4. Edit iletişim kutusunda spec bölümünü bulun, externalTrafficPolicy alanını Local olarak ayarlayın ve OK seçeneğini tıklayın.

      spec:
        affinity: {}
        autoCreateGatewayYaml: false
        clusterIds:
          - cf0243f2c3009406xxx
        compression: {}
        cpu: {}
        dnsPolicy: ClusterFirst
        externalTrafficPolicy: Local
        gatewayType: ingress
  2. Giriş ağ geçidi üzerinden httpbin uygulamasına erişmek için aşağıdaki komutu çalıştırın.

    curl http://$GATEWAY_URL:80/ip

    Beklenen çıktı:

    {
      "origin": "120.244.xxx.xxx"
    }

    Çıktı, döndürülen IP adresinin gerçek istemci kaynak IP'si olduğunu gösterir.

  3. Giriş ağ geçidinin erişim günlüğünü görüntüleyin.

    Aşağıda örnek bir günlük girişi verilmiştir:

    {
      "istio_policy_status":null,
      "upstream_transport_failure_reason":null,
      "path":"/ip",
      "x_forwarded_for":"120.244.XXX.XXX",
      "route_name":null,
      "method":"GET",
      "duration":2,
      "downstream_remote_address":"120.244.XXX.XXX:28504",
      "bytes_received":0,
      "upstream_cluster":"outbound|8000||httpbin.default.svc.cluster.local",
      "bytes_sent":34,
      "protocol":"HTTP/1.1",
      "response_flags":"-",
      "upstream_local_address":"172.17.X.XXX:57498",
      "upstream_service_time":"2",
      "request_id":"9c0295d4-e77f-4a3a-b292-e5c58d92****",
      "start_time":"2022-11-23T03:24:04.413Z",
      "response_code":200,
      "trace_id":null,
      "authority":"47.242.XXX.XX",
      "user_agent":"curl/7.79.1",
      "downstream_local_address":"172.17.X.XXX:80",
      "upstream_host":"172.17.X.XXX:80",
      "requested_server_name":null
    }

    Günlük aşağıdaki bilgileri gösterir:

    • "downstream_remote_address":"120.244.XXX.XXX:28504": Beklendiği gibi istemci kaynak adresi.

    • "downstream_local_address":"172.17.X.XXX:80": Giriş ağ geçidi pod'unun adresi.

    • "upstream_local_address":"172.17.X.XXX:57498": Giriş ağ geçidi pod'unun adresi korunur ancak bağlantı noktası numarası değiştirilir.

    • "upstream_host":"172.17.X.XXX:80": httpbin pod'unun adresi.

HTTPS istekleri

Önceki bölümde HTTP istekleri ayrıntılı olarak açıklandığından, bu bölüm yalnızca HTTPS istekleri için yapılandırma ve doğrulamaya odaklanır.

  1. Kaynak IP korumayı yapılandırma.

  2. httpbin uygulamasına HTTPS üzerinden erişmek için aşağıdaki içeriğe sahip https-demo.yaml adlı bir dosya oluşturun.

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: httpbin-gw-https
      namespace: default
    spec:
      selector:
        istio: ingressgateway
      servers:
        - hosts:
            - '*'
          port:
            name: https
            number: 443
            protocol: HTTPS
          tls:
            credentialName: myexample-credential
            mode: SIMPLE
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: httpbin-https
      namespace: default
    spec:
      gateways:
        - httpbin-gw-https
      hosts:
        - '*'
      http:
        - route:
            - destination:
                host: httpbin
                port:
                  number: 8000
  3. Ağ geçidini ve VirtualService'i dağıtmak için aşağıdaki komutu çalıştırın.

    kubectl -n default apply -f  https-demo.yaml
  4. Giriş ağ geçidi üzerinden httpbin uygulamasına erişmek için aşağıdaki komutu çalıştırın.

    export GATEWAY_URL=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    curl -k https://$GATEWAY_URL:443/ip

    Beklenen çıktı:

    {
      "origin": "120.244.XXX.XXX"
    }

    Çıktı, döndürülen IP adresinin gerçek istemci kaynak IP'si olduğunu gösterir.