本番環境で Kubernetes を使用して Istio を実行する方法。 パート1

何ですか イスティオ? これはいわゆるサービス メッシュであり、ネットワーク上に抽象化レイヤーを追加するテクノロジーです。 クラスター内のトラフィックのすべてまたは一部をインターセプトし、それに対して特定の一連の操作を実行します。 どれ? たとえば、スマート ルーティングを実行したり、サーキット ブレーカー アプローチを実装したり、「カナリア デプロイメント」を組織してトラフィックを新しいバージョンのサービスに部分的に切り替えたり、外部インタラクションを制限してクラスタからクラスタへのすべてのトリップを制御したりできます。外部ネットワーク。 ポリシー ルールを設定して、異なるマイクロサービス間の移動を制御することができます。 最後に、ネットワーク相互作用マップ全体を取得し、統合されたメトリクスの収集をアプリケーションに対して完全に透過的に行うことができます。

動作のメカニズムについては、 公式ドキュメント。 Istio は、多くのタスクや問題を解決できる非常に強力なツールです。 この記事では、Istio を使い始めるときによく起こる主な質問に答えたいと思います。 これにより、より迅速に対処できるようになります。

本番環境で Kubernetes を使用して Istio を実行する方法。 パート1

どのように動作します

Istio は、コントロール プレーンとデータ プレーンという 1.0 つの主要な領域で構成されます。 コントロール プレーンには、残りのコンポーネントの正しい動作を保証する主要コンポーネントが含まれています。 現在のバージョン (XNUMX) では、コントロール プレーンには Pilot、Mixer、Citadel の XNUMX つの主要コンポーネントがあります。 Citadel については考慮しません。サービス間の相互 TLS を保証するために証明書を生成する必要があります。 Pilot と Mixer のデバイスと目的を詳しく見てみましょう。

本番環境で Kubernetes を使用して Istio を実行する方法。 パート1

Pilot は、クラスター内のサービス、そのエンドポイント、ルーティング ルール (カナリア デプロイメントのルールやサーキット ブレーカー ルールなど) に関するすべての情報を配布する主要な制御コンポーネントです。

ミキサーは、メトリクス、ログ、およびネットワーク相互作用に関する情報を収集する機能を提供するオプションのコントロール プレーン コンポーネントです。 また、ポリシー ルールの遵守とレート制限の遵守も監視します。

データ プレーンは、サイドカー プロキシ コンテナを使用して実装されます。 デフォルトでは強力が使用されます。 特使代理。 これは、nginx (nginmesh) などの別の実装に置き換えることができます。

Istio がアプリケーションに対して完全に透過的に動作するために、自動挿入システムがあります。 最新の実装は、Kubernetes 1.9 以降のバージョン (ミューテーションアドミッション Webhook) に適しています。 Kubernetes バージョン 1.7、1.8 では、Initializer を使用できます。

サイドカー コンテナーは GRPC プロトコルを使用して Pilot に接続されるため、クラスター内で発生する変更に合わせてプッシュ モデルを最適化できます。 GRPC は Envoy ではバージョン 1.6 から使用されており、Istio ではバージョン 0.8 から使用されており、パイロット エージェント (起動オプションを構成する envoy の Golang ラッパー) です。

パイロットとミキサーは完全にステートレスなコンポーネントであり、すべての状態がメモリに保持されます。 これらの構成は Kubernetes カスタム リソースの形式で設定され、etcd に保存されます。
Istio エージェントはパイロットのアドレスを取得し、それへの GRPC ストリームを開きます。

先ほども述べたように、Istio はすべての機能をアプリケーションに対して完全に透過的に実装します。 方法を見てみましょう。 アルゴリズムは次のとおりです。

  1. 新しいバージョンのサービスをデプロイします。
  2. サイドカー コンテナーを挿入するアプローチに応じて、 istio-init コンテナーと istio-agent コンテナー (エンボイ) は構成を適用する段階で追加されるか、すでに手動で Kubernetes ポッド エンティティの記述に挿入されている可能性があります。
  3. istio-init コンテナは、iptables ルールをポッドに適用するスクリプトです。 istio-agent コンテナにラップされるトラフィックを構成するには XNUMX つのオプションがあります。iptables リダイレクト ルールを使用するか、または Tプロキシ。 この記事の執筆時点では、デフォルトのアプローチはリダイレクト ルールを使用しています。 istio-init では、どのトラフィックをインターセプトして istio-agent に送信するかを設定できます。 たとえば、すべての受信トラフィックとすべての送信トラフィックをインターセプトするには、パラメータを設定する必要があります。 -i и -b 意味に *。 インターセプトする特定のポートを指定できます。 特定のサブネットを傍受しないようにするには、フラグを使用して指定できます。 -x.
  4. init コンテナーが実行された後、パイロット エージェント (エンボイ) を含む主要なコンテナーが起動されます。 GRPC 経由で既に展開されている Pilot に接続し、クラスター内のすべての既存のサービスとルーティング ポリシーに関する情報を受信します。 受信したデータに従って、彼はクラスターを構成し、それらを Kubernetes クラスター内のアプリケーションのエンドポイントに直接割り当てます。 また、重要な点に注意する必要があります。envoy は、リッスンを開始するリスナー (IP、ポートのペア) を動的に構成します。 したがって、リクエストがポッドに入り、サイドカーのリダイレクト iptables ルールを使用してリダイレクトされると、envoy はすでにこれらの接続を正常に処理し、トラフィックをさらにプロキシする場所を理解できます。 また、この段階では、後で説明するミキサーに情報が送信され、トレース スパンが送信されます。

その結果、XNUMX つのポイント (パイロット) から構成できる Envoy プロキシ サーバーのネットワーク全体が得られます。 すべてのインバウンドおよびアウトバウンドのリクエストは envoy を経由します。 さらに、TCP トラフィックのみが傍受されます。 これは、Kubernetes サービス IP が、変更せずに UDP 上の kube-dns を使用して解決されることを意味します。 次に、解決後、発信リクエストはエンボイによってインターセプトされ、処理されます。エンボイは、リクエストをどのエンドポイントに送信するか(アクセス ポリシーまたはアルゴリズムのサーキット ブレーカーの場合は送信しないか)をすでに決定しています。

Pilot については理解しました。次に、Mixer がどのように機能するのか、なぜそれが必要なのかを理解する必要があります。 公式ドキュメントを読むことができます ここで.

現在の形式の Mixer は、istio-telemetry、istio-policy の 0.8 つのコンポーネントで構成されています (バージョン XNUMX より前は、XNUMX つの istio-mixer コンポーネントでした)。 どちらもミキサーであり、それぞれが独自のタスクを担当します。 Istio テレメトリは、GRPC 経由でサイドカー レポート コンテナから、誰がどこにどのパラメータを使用して移動したかに関する情報を受け取ります。 Istio-policy は、ポリシー ルールが満たされていることを確認するための Check リクエストを受け入れます。 もちろん、ポリシー チェックはリクエストごとに実行されるわけではありませんが、一定期間クライアント (サイドカー内) にキャッシュされます。 レポートチェックはバッチリクエストとして送信されます。 設定方法とどのパラメータを送信する必要があるかを少し後で見てみましょう。

ミキサーは、テレメトリ データの組み立てと処理の中断のない作業を保証する高可用性コンポーネントであると想定されています。 結果として、システムは多層バッファとして得られます。 最初に、データはコンテナのサイドカー側でバッファリングされ、次にミキサー側でバッファリングされ、いわゆるミキサー バックエンドに送信されます。 その結果、システム コンポーネントのいずれかに障害が発生すると、バッファが増大し、システムが復元された後にフラッシュされます。 ミキサー バックエンドは、統計データ、newrelic などのテレメトリ データを送信するためのエンドポイントです。 独自のバックエンドを作成することもできます。それは非常に簡単です。その方法については後ほど説明します。

本番環境で Kubernetes を使用して Istio を実行する方法。 パート1

要約すると、istio-telemetry を使用するためのスキームは次のとおりです。

  1. サービス 1 はサービス 2 にリクエストを送信します。
  2. サービス 1 を終了するとき、リクエストは独自のサイドカーにラップされます。
  3. Sidecar envoy は、リクエストがサービス 2 にどのように送信されるかを監視し、必要な情報を準備します。
  4. 次に、Report リクエストを使用してそれを istio-telemetry に送信します。
  5. Istio テレメトリは、このレポートをバックエンドに送信するかどうか、どのデータを送信するかを決定します。
  6. Istio-telemetry は、必要に応じてレポート データをバックエンドに送信します。

次に、主要コンポーネント (Pilot と Sidecar Envoy) のみで構成されるシステムに Istio をデプロイする方法を見てみましょう。

まず、Pilot が読み取る主な構成 (メッシュ) を見てみましょう。

apiVersion: v1
kind: ConfigMap
metadata:
  name: istio
  namespace: istio-system
  labels:
    app: istio
    service: istio
data:
  mesh: |-

    # пока что не включаем отправку tracing информации (pilot настроит envoy’и таким образом, что отправка не будет происходить)
    enableTracing: false

    # пока что не указываем mixer endpoint’ы, чтобы sidecar контейнеры не отправляли информацию туда
    #mixerCheckServer: istio-policy.istio-system:15004
    #mixerReportServer: istio-telemetry.istio-system:15004

    # ставим временной промежуток, с которым будет envoy переспрашивать Pilot (это для старой версии envoy proxy)
    rdsRefreshDelay: 5s

    # default конфигурация для envoy sidecar
    defaultConfig:
      # аналогично как rdsRefreshDelay
      discoveryRefreshDelay: 5s

      # оставляем по умолчанию (путь к конфигурации и бинарю envoy)
      configPath: "/etc/istio/proxy"
      binaryPath: "/usr/local/bin/envoy"

      # дефолтное имя запущенного sidecar контейнера (используется, например, в именах сервиса при отправке tracing span’ов)
      serviceCluster: istio-proxy

      # время, которое будет ждать envoy до того, как он принудительно завершит все установленные соединения
      drainDuration: 45s
      parentShutdownDuration: 1m0s

      # по умолчанию используются REDIRECT правила iptables. Можно изменить на TPROXY.
      #interceptionMode: REDIRECT

      # Порт, на котором будет запущена admin панель каждого sidecar контейнера (envoy)
      proxyAdminPort: 15000

      # адрес, по которому будут отправляться trace’ы по zipkin протоколу (в начале мы отключили саму отправку, поэтому это поле сейчас не будет использоваться)
      zipkinAddress: tracing-collector.tracing:9411

      # statsd адрес для отправки метрик envoy контейнеров (отключаем)
      # statsdUdpAddress: aggregator:8126

      # выключаем поддержку опции Mutual TLS
      controlPlaneAuthPolicy: NONE

      # адрес, на котором будет слушать istio-pilot для того, чтобы сообщать информацию о service discovery всем sidecar контейнерам
      discoveryAddress: istio-pilot.istio-system:15007

すべての主要な制御コンポーネント (コントロール プレーン) は、Kubernetes の名前空間 istio-system に配置されます。

少なくとも、Pilot をデプロイするだけで済みます。 このために使用します そういった構成。

そして、コンテナーの注入サイドカーを手動で構成します。

コンテナの初期化:

initContainers:
 - name: istio-init
   args:
   - -p
   - "15001"
   - -u
   - "1337"
   - -m
   - REDIRECT
   - -i
   - '*'
   - -b
   - '*'
   - -d
   - ""
   image: istio/proxy_init:1.0.0
   imagePullPolicy: IfNotPresent
   resources:
     limits:
       memory: 128Mi
   securityContext:
     capabilities:
       add:
       - NET_ADMIN

そしてサイドカー:

       name: istio-proxy
       args:
         - "bash"
         - "-c"
         - |
           exec /usr/local/bin/pilot-agent proxy sidecar 
           --configPath 
           /etc/istio/proxy 
           --binaryPath 
           /usr/local/bin/envoy 
           --serviceCluster 
           service-name 
           --drainDuration 
           45s 
           --parentShutdownDuration 
           1m0s 
           --discoveryAddress 
           istio-pilot.istio-system:15007 
           --discoveryRefreshDelay 
           1s 
           --connectTimeout 
           10s 
           --proxyAdminPort 
           "15000" 
           --controlPlaneAuthPolicy 
           NONE
         env:
         - name: POD_NAME
           valueFrom:
             fieldRef:
               fieldPath: metadata.name
         - name: POD_NAMESPACE
           valueFrom:
             fieldRef:
               fieldPath: metadata.namespace
         - name: INSTANCE_IP
           valueFrom:
             fieldRef:
               fieldPath: status.podIP
         - name: ISTIO_META_POD_NAME
           valueFrom:
             fieldRef:
               fieldPath: metadata.name
         - name: ISTIO_META_INTERCEPTION_MODE
           value: REDIRECT
         image: istio/proxyv2:1.0.0
         imagePullPolicy: IfNotPresent
         resources:
           requests:
             cpu: 100m
             memory: 128Mi
           limits:
             memory: 2048Mi
         securityContext:
           privileged: false
           readOnlyRootFilesystem: true
           runAsUser: 1337
         volumeMounts:
         - mountPath: /etc/istio/proxy
           name: istio-envoy

すべてを正常に開始するには、Pilot 用の ServiceAccount、ClusterRole、ClusterRoleBinding、CRD を作成する必要があります。その説明は次のとおりです。 ここで.

その結果、エンボイを使用してサイドカーを挿入したサービスは正常に開始され、パイロットからすべてのディスカバリを受信して​​リクエストを処理するはずです。

すべてのコントロール プレーン コンポーネントはステートレス アプリケーションであり、問​​題なく水平方向にスケーリングできることを理解することが重要です。 すべてのデータは、Kubernetes リソースのカスタム記述の形式で etcd に保存されます。

また、Istio (まだ実験段階) には、クラスターの外部で実行する機能と、複数の Kubernetes クラスター間でサービスの検出を監視および探求する機能があります。 これについて詳しく読むことができます ここで.

マルチクラスターのインストールでは、次の制限事項に注意してください。

  1. ポッド CIDR とサービス CIDR はすべてのクラスター間で一意である必要があり、重複してはなりません。
  2. すべての CIDR ポッドは、クラスター間のどの CIDR ポッドからもアクセスできる必要があります。
  3. すべての Kubernetes API サーバーは相互にアクセスできる必要があります。

これは、Istio を使い始めるのに役立つ最初の情報です。 ただし、落とし穴はまだた​​くさんあります。 たとえば、外部トラフィック (クラスターの外側) のルーティング機能、サイドカーのデバッグへのアプローチ、プロファイリング、ミキサーのセットアップとカスタム ミキサー バックエンドの作成、トレース メカニズムのセットアップと envoy を使用したその操作などです。
これらすべてについては、次の出版物で検討します。 ご質問がございましたら、お答えいたします。

出所: habr.com

コメントを追加します