Istio における Kubernetes ネイティブサイドカー

Istio での新しい SidecarContainers 機能のデモ。

2023年8月15日 | ジョン・ハワード (Google) 著

サービスメッシュについて何か聞いたことがあるなら、それはサイドカーパターンを使って動作することでしょう。プロキシサーバーがアプリケーションコードと一緒にデプロイされます。サイドカーパターンはまさにそれ、パターンです。今まで、Kubernetes ではサイドカーコンテナに対する正式なサポートはまったくありませんでした。

これにより、多くの問題が発生しました。設計上終了するジョブがあるが、サイドカーコンテナは終了しない場合はどうでしょうか?この正確なユースケースは、Kubernetes の Issue トラッカーで最も人気のあるものです

Kubernetes にサイドカーのサポートを追加する正式な提案は 2019 年に提起されました。多くの停滞と開始を経て、昨年プロジェクトが再開された後、サイドカーの正式なサポートが Kubernetes 1.28 でアルファ版としてリリースされます。Istio はこの機能のサポートを実装しており、この記事では、その利用方法を学ぶことができます。

サイドカーの悩み

サイドカーコンテナは多くの機能を提供しますが、いくつかの問題も伴います。ポッド内のコンテナはいくつかのものを共有できますが、そのライフサイクルは完全に切り離されています。Kubernetes にとって、これらのコンテナは両方とも機能的に同じです。

しかし、Istio では同じではありません。Istio コンテナはプライマリアプリケーションコンテナを実行するために必要であり、プライマリアプリケーションコンテナなしでは価値がありません。

この期待のミスマッチは、さまざまな問題を引き起こします。

これらの問題を回避するために、Istio コミュニティ内外で数え切れないほどの時間が費やされてきましたが、成功は限定的でした。

根本原因の解決

Istio のますます複雑化する回避策は、Istio ユーザーの苦痛を軽減するのに役立ちますが、理想的には、これらすべてが機能するはずです。そして、Istio だけではなく、Kubernetes コミュニティは、これらを Kubernetes で直接解決するために懸命に取り組んできました。

Kubernetes 1.28 では、サイドカーのネイティブサポートを追加する新機能がマージされ、5 年以上にわたる継続的な作業が完了しました。これがマージされたことで、すべての問題を回避策なしで解決できます!

「GitHub Issue ホールオブフェイム」では、これら 2 つの Issue は、Kubernetes での全期間の Issue の #1 および #6 に相当し、ついに解決しました!

これを完了させるために貢献した多くの個人に特別な感謝を申し上げます。

試してみる

Kubernetes 1.28 がリリースされたばかりですが、新しい SidecarContainers 機能はアルファ版 (したがって、デフォルトではオフ) であり、Istio でのこの機能のサポートはまだ出荷されていません。それでも、今日試すことはできます。ただし、実稼働環境では試さないでください!

まず、SidecarContainers 機能が有効になっている Kubernetes 1.28 クラスターを起動する必要があります。

$ cat <<EOF | kind create cluster --name sidecars --image gcr.io/istio-testing/kind-node:v1.28.0 --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
  SidecarContainers: true
EOF

次に、最新の Istio 1.19 プレリリースをダウンロードできます (1.19 はまだリリースされていないため)。ここでは Linux を使用しました。これは Istio のプレリリースであるため、繰り返しますが、実稼働環境では試さないでください!Istio をインストールする際に、ネイティブサイドカーサポートの機能フラグを有効にし、後でデモを支援するためにアクセスログをオンにします。

$ TAG=1.19.0-beta.0
$ curl -L https://github.com/istio/istio/releases/download/$TAG/istio-$TAG-linux-amd64.tar.gz | tar xz
$ ./istioctl install --set values.pilot.env.ENABLE_NATIVE_SIDECARS=true -y --set meshConfig.accessLogFile=/dev/stdout

そして、最後にワークロードをデプロイできます。

$ kubectl label namespace default istio-injection=enabled
$ kubectl apply -f samples/sleep/sleep.yaml

ポッドを見てみましょう。

$ kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
sleep-7656cf8794-8fhdk   2/2     Running   0          51s

一見するとすべて正常に見えます... しかし、内部を見ると魔法を見ることができます。

$ kubectl get pod -o "custom-columns="\
"NAME:.metadata.name,"\
"INIT:.spec.initContainers[*].name,"\
"CONTAINERS:.spec.containers[*].name"

NAME                     INIT                     CONTAINERS
sleep-7656cf8794-8fhdk   istio-init,istio-proxy   sleep

ここでは、ポッド内のすべての containersinitContainers を見ることができます。

驚き! istio-proxyinitContainer になりました。

より具体的には、restartPolicy: Always が設定された initContainer です (SidecarContainers 機能によって有効になる新しいフィールド)。これにより、Kubernetes はそれをサイドカーとして扱うようになります。

これは、initContainers のリストの後続のコンテナ、およびすべての通常の containers は、プロキシコンテナの準備が整うまで起動しないことを意味します。さらに、プロキシコンテナがまだ実行されている場合でも、ポッドは終了します。

Init コンテナのトラフィック

これをテストするために、ポッドに実際に何かを実行させてみましょう。ここでは、initContainer でリクエストを送信する単純なポッドをデプロイします。通常、これは失敗します。

apiVersion: v1
kind: Pod
metadata:
  name: sleep
spec:
  initContainers:
  - name: check-traffic
    image: istio/base
    command:
    - curl
    - httpbin.org/get
  containers:
  - name: sleep
    image: istio/base
    command: ["/bin/sleep", "infinity"]

プロキシコンテナをチェックすると、リクエストが成功し、Istio サイドカーを介して渡されたことがわかります。

$ kubectl logs sleep -c istio-proxy | tail -n1
[2023-07-25T22:00:45.703Z] "GET /get HTTP/1.1" 200 - via_upstream - "-" 0 1193 334 334 "-" "curl/7.81.0" "1854226d-41ec-445c-b542-9e43861b5331" "httpbin.org" ...

ポッドを調べると、サイドカーが check-traffic initContainerに実行されるようになっていることがわかります。

$ kubectl get pod -o "custom-columns="\
"NAME:.metadata.name,"\
"INIT:.spec.initContainers[*].name,"\
"CONTAINERS:.spec.containers[*].name"

NAME    INIT                                  CONTAINERS
sleep   istio-init,istio-proxy,check-traffic   sleep

ポッドの終了

以前に、アプリケーションが終了した場合 (Jobs で一般的)、ポッドは永遠に生き続けると述べました。幸い、これも解決しました!

まず、1 秒後に終了し、再起動しないポッドをデプロイします。

apiVersion: v1
kind: Pod
metadata:
  name: sleep
spec:
  restartPolicy: Never
  containers:
- name: sleep
  image: istio/base
  command: ["/bin/sleep", "1"]

そして、その進行状況を監視できます。

$ kubectl get pods -w
NAME    READY   STATUS     RESTARTS   AGE
sleep   0/2     Init:1/2   0          2s
sleep   0/2     PodInitializing   0          2s
sleep   1/2     PodInitializing   0          3s
sleep   2/2     Running           0          4s
sleep   1/2     Completed         0          5s
sleep   0/2     Completed         0          12s

ここでは、アプリケーションコンテナが終了し、その後すぐに Istio のサイドカーコンテナも終了することがわかります。以前は、ポッドは Running のままになっていましたが、現在は Completed に移行できます。もうゾンビポッドはありません!

アンビエントモードはどうですか?

昨年、Istio はアンビエントモードを発表しました。これは、サイドカーコンテナに依存しない Istio の新しいデータプレーンモードです。では、アンビエントモードが登場すると、これらはすべて意味がなくなるのでしょうか?

私は断固として「はい」と言います!

ワークロードにアンビエントモードが使用されると、サイドカーの影響は軽減されますが、大規模な Kubernetes ユーザーのほぼすべてがデプロイメントに何らかのサイドカーを使用していると予想されます。これは、アンビエントに移行したくない Istio ワークロード、まだ移行していないワークロード、または Istio に関連しないものの場合があります。したがって、これが重要となるシナリオは少なくなる可能性がありますが、サイドカーが使用される場合は、それでも大きな改善です。

逆のことを疑問に思うかもしれません。サイドカーの悩みがすべて解決した場合、なぜアンビエントモードがそもそも必要なのでしょうか?サイドカーの制限が解決されても、アンビエントには依然としてさまざまなメリットがあります。たとえば、このブログ記事では、プロキシをワークロードから分離することが有利である理由について詳しく説明しています。

自分で試してみる

冒険好きな読者の皆様には、テスト環境で自分でこれを試してみることをお勧めします!これらの実験的およびアルファ機能のフィードバックは、それらが安定しており、プロモーションする前に期待を満たしていることを確認するために重要です。試してみたら、Istio Slack で感想をお聞かせください!

特に、Kubernetes チームは次の点についてさらに詳しく知りたいと考えています。

この投稿を共有する