Istio client-go の発表
Istio リソースへのプログラム的なアクセスを実現。
Kubernetes 環境で Istio API へのプログラム的なアクセスを開発者が行えるようにする Istio client go リポジトリの最初のリリースを発表できることを嬉しく思います。このリポジトリで生成された Kubernetes インフォーマーとクライアントセットにより、開発者はコントローラーを作成し、すべての Istio カスタムリソース定義 (CRD) に対して作成、読み取り、更新、削除 (CRUD) 操作を簡単に行うことができます。
これは、Aspen Mesh および Knative プロジェクトによって生成されたクライアントに対する機能リクエストから明らかなように、多くの Istio ユーザーから非常に要望の多かった機能でした。現在、上記のクライアントのいずれかを使用している場合は、次のように Istio client go を簡単に使用するように切り替えることができます。
import (
...
- versionedclient "github.com/aspenmesh/istio-client-go/pkg/client/clientset/versioned"
+ versionedclient "istio.io/client-go/pkg/clientset/versioned"
)
生成されたクライアントセットは機能的に同等であるため、新しく生成されたライブラリを利用するために、インポートされたクライアントライブラリを切り替えるだけで十分です。
client-go の使用方法
Istio client go リポジトリは、クライアントリポジトリが API 定義に依存しているため、Istio API リポジトリと同じブランチ戦略に従います。安定したクライアントセットを使用したい場合は、client go リポジトリのリリースブランチまたはタグ付きバージョンを使用できます。クライアントセットの使用は、Kubernetes client go の使用と非常によく似ています。以下は、クライアントを使用して渡された名前空間内のすべての Istio virtual service を一覧表示する簡単な例です。
package main
import (
"log"
"os"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/clientcmd"
versionedclient "istio.io/client-go/pkg/clientset/versioned"
)
func main() {
kubeconfig := os.Getenv("KUBECONFIG")
namespace := os.Getenv("NAMESPACE")
if len(kubeconfig) == 0 || len(namespace) == 0 {
log.Fatalf("Environment variables KUBECONFIG and NAMESPACE need to be set")
}
restConfig, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
log.Fatalf("Failed to create k8s rest client: %s", err)
}
ic, err := versionedclient.NewForConfig(restConfig)
if err != nil {
log.Fatalf("Failed to create istio client: %s", err)
}
// Print all VirtualServices
vsList, err := ic.NetworkingV1alpha3().VirtualServices(namespace).List(metav1.ListOptions{})
if err != nil {
log.Fatalf("Failed to get VirtualService in %s namespace: %s", namespace, err)
}
for i := range vsList.Items {
vs := vsList.Items[i]
log.Printf("Index: %d VirtualService Hosts: %+v\n", i, vs.Spec.GetHosts())
}
}
より詳細な例は こちらにあります。
Istio client-go を生成するために作成された便利なツール
このクライアントセットの生成に時間がかかった理由や、なぜ難しかったのか疑問に思っている場合は、このセクションをご覧ください。Istio では、protobuf 仕様を使用して API を記述し、protobuf ツールチェーンを使用して Go 定義に変換しています。protobuf で生成された API から Kubernetes クライアントセットを生成しようとする場合に直面する可能性のある 3 つの大きな課題があります。
Kubernetes ラッパー型の作成 - Kubernetes クライアント生成ライブラリは、認証ポリシー Kubernetes ラッパーなど、Kubernetes オブジェクト仕様に従う Go オブジェクトに対してのみ機能します。つまり、プログラムでアクセスする必要があるすべての API に対して、これらのラッパーを作成する必要があります。さらに、クライアントコード生成が必要なすべての
CRD
グループ、バージョン、および種類に対して、かなりの量のボイラープレートが必要です。このプロセスを自動化するために、アノテーションに基づいて Kubernetes 型を自動的に作成できる Kubernetes 型ジェネレーターツールを作成しました。このツールによって解析されるアノテーションと、利用可能なさまざまなオプションについては、README で説明しています。protobuf ツールを使用して Go 型を生成する場合は、これらのアノテーションを proto ファイルにコメントとして追加して、このツールで使用される生成された Go ファイルにコメントが存在するようにする必要があります。ディープコピーメソッドの生成 - Kubernetes クライアント機構では、クライアントセットから返されたオブジェクトを変更する場合、キャッシュストア内でオブジェクトがインプレースで変更されるのを防ぐために、オブジェクトのコピーを作成する必要があります。これを行うための標準的な方法は、ネストされたすべての型に
deepcopy
メソッドを作成することです。protoc
プラグインである protoc ディープコピー ジェネレーターツールを作成しました。このツールは、Proto ライブラリユーティリティ Proto Clone を使用してアノテーションに基づいてdeepcopy
メソッドを自動的に作成できます。以下は、生成されたdeepcopy
メソッドの例です。JSON との間での型のマーシャリングとアンマーシャリング - proto 定義から生成された型の場合、protobuf の
oneof
など、特別な処理が必要なさまざまなフィールドがあるため、デフォルトの Go JSON エンコーダー/デコーダーを使用することはしばしば問題があります。さらに、名前の中にアンダースコアを持つ Proto フィールドは、Go struct タグが 異なる方法で生成されるため、エンコーダー/デコーダーに応じて異なるフィールド名にシリアル化/デシリアル化される可能性があります。デフォルトの Go ライブラリに依存する代わりに、JSON にシリアル化/デシリアル化するには、常に protobuf プリミティブを使用することをお勧めします。protoc
プラグインである protoc JSON shim ツールを作成しました。このツールは、Proto 定義から生成されたすべての Go 型のマーシャラー/アンマーシャラーを自動的に作成できます。以下は、このツールによって生成されたコードの例です。
新しくリリースされたクライアントライブラリにより、ユーザーが Istio API の統合とコントローラーをさらに作成できるようになり、上記で説明したツールを開発者が Proto API から Kubernetes クライアントセットを生成するために使用できることを願っています。