Використання зовнішнього HTTPS-проксі

Приклад Налаштування Egress Gateway показує, як спрямовувати трафік до зовнішніх сервісів з вашої сервісної мережі через компонент Istio на периметрі мережі, який називається Egress Gateway. Однак у деяких випадках необхідно використовувати зовнішній, застарілий (non-Istio) HTTPS-проксі для доступу до зовнішніх сервісів. Наприклад, у вашій компанії може вже бути налаштований такий проксі, і всі застосунки в організації можуть бути зобовʼязані спрямовувати свій трафік через нього.

Цей приклад показує, як забезпечити доступ до зовнішнього HTTPS-проксі. Оскільки застосунки використовують метод HTTP CONNECT для встановлення зʼєднань з HTTPS-проксі, конфігурація трафіку до зовнішнього HTTPS-проксі відрізняється від конфігурації трафіку до зовнішніх HTTP та HTTPS-сервісів.

Перш ніж розпочати

  • Налаштуйте Istio, дотримуючися інструкцій у посібнику з встановлення.

  • Розгорніть демонстраційний застосунок curl для використання як джерело тестових запитів. Якщо у вас увімкнено автоматичне додавання sidecar, виконайте наступну команду для розгортання демонстраційного застосунку:

    Zip
    $ kubectl apply -f @samples/curl/curl.yaml@

    Інакше, вручну додайте sidecar перед розгортанням застосунку curl за допомогою наступної команди:

    Zip
    $ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@)
  • Встановіть змінну середовища SOURCE_POD на імʼя вашого podʼа:

    $ export SOURCE_POD=$(kubectl get pod -l app=curl -o jsonpath={.items..metadata.name})

Розгортання HTTPS-проксі

Щоб змоделювати застарілий проксі та лише для цього прикладу, розгорніть HTTPS-проксі всередині вашого кластера. Також, щоб змоделювати більш реалістичний проксі, який працює поза вашим кластером, ви будете звертатися до podʼа проксі за його IP-адресою, а не за доменним іменем сервісу Kubernetes. Цей приклад використовує Squid, але ви можете використовувати будь-який HTTPS-проксі, який підтримує HTTP CONNECT.

  1. Створіть простір імен для HTTPS-проксі, не позначаючи його міткою для інʼєкції sidecar. Без мітки інʼєкція sidecar відключена в новому просторі імен, тому Istio не буде контролювати трафік там. Вам потрібна ця поведінка для моделювання проксі поза кластером.

    $ kubectl create namespace external
  2. Створіть конфігураційний файл для проксі-сервера Squid.

    $ cat <<EOF > ./proxy.conf
    http_port 3128
    
    acl SSL_ports port 443
    acl CONNECT method CONNECT
    
    http_access deny CONNECT !SSL_ports
    http_access allow localhost manager
    http_access deny manager
    http_access allow all
    
    coredump_dir /var/spool/squid
    EOF
  3. Створіть Kubernetes ConfigMap для зберігання конфігурації проксі-сервера:

    $ kubectl create configmap proxy-configmap -n external --from-file=squid.conf=./proxy.conf
  4. Розгорніть контейнер Squid:

    $ kubectl apply -f - <<EOF
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: squid
      namespace: external
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: squid
      template:
        metadata:
          labels:
            app: squid
        spec:
          volumes:
          - name: proxy-config
            configMap:
              name: proxy-configmap
          containers:
          - name: squid
            image: sameersbn/squid:3.5.27
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - name: proxy-config
              mountPath: /etc/squid
              readOnly: true
    EOF
  5. Розгорніть зразок curl у просторі імен external для тестування трафіку на проксі без контролю трафіку Istio.

    Zip
    $ kubectl apply -n external -f @samples/curl/curl.yaml@
  6. Отримайте IP-адресу проксі-сервера і визначте змінну оточення PROXY_IP для її зберігання:

    $ export PROXY_IP="$(kubectl get pod -n external -l app=squid -o jsonpath={.items..podIP})"
  7. Визначте змінну оточення PROXY_PORT для зберігання порту вашого проксі. У цьому випадку Squid використовує порт 3128.

    $ export PROXY_PORT=3128
  8. Надішліть запит з пода curl в просторі імен external до зовнішнього сервіса через проксі:

    $ kubectl exec "$(kubectl get pod -n external -l app=curl -o jsonpath={.items..metadata.name})" -n external -- sh -c "HTTPS_PROXY=$PROXY_IP:$PROXY_PORT curl https://en.wikipedia.org/wiki/Main_Page" | grep -o "<title>.*</title>"
    <title>Wikipedia, the free encyclopedia</title>
  9. Перевірте журнал доступу проксі-сервера на наявність вашого запиту:

    $ kubectl exec "$(kubectl get pod -n external -l app=squid -o jsonpath={.items..metadata.name})" -n external -- tail /var/log/squid/access.log
    1544160065.248    228 172.30.109.89 TCP_TUNNEL/200 87633 CONNECT en.wikipedia.org:443 - HIER_DIRECT/91.198.174.192 -

Наразі ви виконали наступні завдання без Istio:

  • Ви розгорнули HTTPS проксі.
  • Ви використовували curl для доступу до зовнішнього сервісу wikipedia.org через проксі.

Далі, ви повинні налаштувати трафік з podʼів з підтримкою Istio на використання HTTPS-проксі.

Налаштування трафіку до зовнішнього HTTPS-проксі

  1. Визначте Service Entry для HTTPS-проксі з протоколом TCP (не HTTP!). Хоча застосунки використовують метод HTTP CONNECT для встановлення зʼєднань з HTTPS-проксі, вам потрібно налаштувати проксі для TCP-трафіку, а не для HTTP. Як тільки зʼєднання буде встановлено, проксі просто діє як TCP-тунель.

    $ kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1
    kind: ServiceEntry
    metadata:
      name: proxy
    spec:
      hosts:
      - my-company-proxy.com # ignored
      addresses:
      - $PROXY_IP/32
      ports:
      - number: $PROXY_PORT
        name: tcp
        protocol: TCP
      location: MESH_EXTERNAL
      resolution: NONE
    EOF
  2. Надішліть запит з пода curl в просторі імен default. Оскільки под curl має sidecar, Istio контролює його трафік.

    $ kubectl exec "$SOURCE_POD" -c curl -- sh -c "HTTPS_PROXY=$PROXY_IP:$PROXY_PORT curl https://en.wikipedia.org/wiki/Main_Page" | grep -o "<title>.*</title>"
    <title>Wikipedia, the free encyclopedia</title>
  3. Перевірте журнали sidecar-проксі Istio для вашого запиту:

    $ kubectl logs "$SOURCE_POD" -c istio-proxy
    [2018-12-07T10:38:02.841Z] "- - -" 0 - 702 87599 92 - "-" "-" "-" "-" "172.30.109.95:3128" outbound|3128||my-company-proxy.com 172.30.230.52:44478 172.30.109.95:3128 172.30.230.52:44476 -
  4. Перевірте журнал доступу проксі на наявність вашого запиту:

    $ kubectl exec "$(kubectl get pod -n external -l app=squid -o jsonpath={.items..metadata.name})" -n external -- tail /var/log/squid/access.log
    1544160065.248    228 172.30.109.89 TCP_TUNNEL/200 87633 CONNECT en.wikipedia.org:443 - HIER_DIRECT/91.198.174.192 -

Розуміння того, що відбулося

В цьому прикладі ви виконали наступні кроки:

  1. Розгорнули HTTPS-проксі для моделювання зовнішнього проксі.
  2. Створили TCP-сервісний запис, щоб дозволити трафіку під контролем Istio до зовнішнього проксі.

Зверніть увагу, що не слід створювати сервісні записи для зовнішніх сервісів, до яких ви звертаєтеся через зовнішній проксі, таких як wikipedia.org. Це повʼязано з тим, що з погляду Istio запити надсилаються тільки до зовнішнього проксі; Istio не знає, що зовнішній проксі далі пересилає запити.

Очищення

  1. Завершіть роботу сервісу curl:

    Zip
    $ kubectl delete -f @samples/curl/curl.yaml@
  2. Завершіть роботу сервісу curl в просторі імен external:

    Zip
    $ kubectl delete -f @samples/curl/curl.yaml@ -n external
  3. Завершіть роботу проксі Squid, видаліть ConfigMap і конфігураційний файл:

    $ kubectl delete -n external deployment squid
    $ kubectl delete -n external configmap proxy-configmap
    $ rm ./proxy.conf
  4. Видаліть простір імен external:

    $ kubectl delete namespace external
  5. Видаліть Service Entry:

    $ kubectl delete serviceentry proxy
Чи була ця інформація корисною?
Чи є у вас пропозиції щодо покращення?

Дякуємо за ваш відгук!