Slide 1

Slide 1 text

,VCFSOFUFTίϯτϩʔϥʔ Λखܰʹࣗಈςετ͢Δ /PWFNCFS !SJJUB

Slide 2

Slide 2 text

Ryota Yamada riita10069 Tokyo Institute of Technology Working on Kubernetes Interested in Distributed Systems, TLA+

Slide 3

Slide 3 text

Kubernetes 使っていますよね?

Slide 4

Slide 4 text

超便利!! 何がどう便利?

Slide 5

Slide 5 text

宣⾔型アプローチによる 
 ⾼い管理⼒ Reconcile Loopによる 
 ⾼い回復⼒ ダウンタイムのない 
 デプロイ ネットワークレイヤを含む 
 ⾼い可観測性 Kubernetesのすごいところ

Slide 6

Slide 6 text

真の⼒には その拡張性が伴う w w w

Slide 7

Slide 7 text

Kubernetesの拡張性がすごい • コンテナの仕様拡張をサポート(CRI, CNI, CSI) • カスタムスケジューラプラグイン • Validating/Mutating Admission WebHook • kube api serverの拡張

Slide 8

Slide 8 text

Kubernetesの拡張性がすごい ,VCFSOFUFT%BUB1MBOF LVCFMFU DPOUBJOFSE $POUBJOFS3VOUJNF*OUFSGBDF $3* SVOD SVOD SVOD 0QFO$POUBJOFS*OJUJBUJWF 0$* IUUQTPQFODPOUBJOFSTPSH IUUQTLVCFSOFUFTJPCMPHDPOUBJOFSSVOUJNFJOUFSGBDFDSJJOLVCFSOFUFT IUUQTRJJUBDPNNBNPNBNPJUFNTFEECBCGB

Slide 9

Slide 9 text

Kubernetesの拡張性がすごい • コンテナの仕様拡張をサポート(CRI, CNI, CSI) • カスタムスケジューラプラグイン • Validating/Mutating Admission WebHook • kube api serverの拡張

Slide 10

Slide 10 text

Kubernetes API とは ,VCFSOFUFT%BUB1MBOF ,VCFSOFUFT$POUSPM1MBOF LVCFBQJTFSWFS LVCFMFU $POUBJOFS 
 SVOUJNF LVCFDUM

Slide 11

Slide 11 text

Kubernetes API の拡張 Aggregation 
 Layer Custom Resources APIリソースを追加 Kubernetesリソースを追加 ⾼い⾃由度を誇る 組み込みリソースと同様に IUUQTLVCFSOFUFTJPKBEPDTDPODFQUTFYUFOELVCFSOFUFTBQJFYUFOTJPOBQJTFSWFSBHHSFHBUJPO IUUQTLVCFSOFUFTJPKBEPDTDPODFQUTFYUFOELVCFSOFUFTBQJFYUFOTJPODVTUPNSFTPVSDFT

Slide 12

Slide 12 text

カスタムコントローラーの ⾃動テストをCIで動かしてますか w w w w

Slide 13

Slide 13 text

なぜテストが難しいのか 多くのコンポーネントで構成され 
 実際に動かすのが困難 IUUQTLVCFSOFUFTJPKBEPDTDPODFQUTPWFSWJFXDPNQPOFOUT

Slide 14

Slide 14 text

より本番環境に近い GBLFDMJFOU FOWUFTU LFU ࣮Ϋϥελ Kubernetes Controller のテスト

Slide 15

Slide 15 text

fake-client • Client-goのモッククライアント • Kube-apiserverの実態をロジックから隠蔽可能 IUUQTQLHHPEFWLTJPDMJFOUHPLVCFSOFUFTGBLF

Slide 16

Slide 16 text

fake-client IUUQTHJUIVCDPNLVCFSOFUFTDMJFOUHPCMPCEFEBBBDDECDBEFGBCBBFYBNQMFTGBLFDMJFOUNBJO@UFTUHP IUUQTCFMMTNFEJVNDPNLVCFSOFUFTDMJFOUHPTGBLFDMJFOUBECFGDC IUUQTQLHHPEFWLTJPDMJFOUHPLVCFSOFUFTGBLF/FX4JNQMF$MJFOUTFU _, err := fakeClient.CoreV1().Pods("namespace1").Create(pod)

Slide 17

Slide 17 text

fake-client Reactorの登録 IUUQTHJUIVCDPNLVCFSOFUFTDMJFOUHPCMPCEFEBBBDDECDBEFGBCBBFYBNQMFTGBLFDMJFOUNBJO@UFTUHP IUUQTCFMMTNFEJVNDPNLVCFSOFUFTDMJFOUHPTGBLFDMJFOUBECFGDC IUUQTQLHHPEFWLTJPDMJFOUHPLVCFSOFUFTGBLF/FX4JNQMF$MJFOUTFU fakeClient.PrependReactor("get", "customResource", func(action clienttesting.Action) (handled bool, ret runtime.Object, err error) { WFSC SFTPVSDF

Slide 18

Slide 18 text

fake-client • Client-goのモッククライアント • Kube-apiserverの実態をロジックから隠蔽可能 • モックの更新管理が必要になる • モックを使ったテストでは、本番の挙動を保証できない IUUQTQLHHPEFWLTJPDMJFOUHPLVCFSOFUFTGBLF Cons. Pros.

Slide 19

Slide 19 text

envtest • controller-runtimeが提供するテスト⽤のパッケージ • kube-apiserverとetcdのバイナリを実際に⽴てる IUUQTCPPLLVCFCVJMEFSJPSFGFSFODFFOWUFTUIUNM IUUQTQLHHPEFWHJUIVCDPNLVCFSOFUFTTJHTDPOUSPMMFSSVOUJNFQLHFOWUFTU IUUQTHJUIVCDPNLVCFSOFUFTTJHTDPOUSPMMFSSVOUJNFUSFFNBTUFSQLHFOWUFTU

Slide 20

Slide 20 text

setup-envtest IUUQTQLHHPEFWTJHTLTJPDPOUSPMMFSSVOUJNFUPPMTTFUVQFOWUFTU • envtest binaries manager • kubeapi-server, etcd, kubectl のバイナリを管理 • curl, tarを使うとk8sやこれらのバージョン管理が煩雑 • ポータビリティの向上

Slide 21

Slide 21 text

envtestの使⽤例 func TestMain(m *testing.M) { os.Exit(func() int { cli, done, err := testutil.TestK8SClient( ) if err != nil { fmt.Fprintf(os.Stdout, "failed to create k8s client: %s\n", err ) return 1 } defer done( ) k8sClient = cl i return m.Run( ) }() ) }

Slide 22

Slide 22 text

envtestの使⽤例 _, file, _, _ := runtime.Caller(0 ) testEnv := envtest.Environment { BinaryAssetsDirectory: filepath.Join(path.Dir(file), "..", "..", "..", "_dev", "bin") , CRDDirectoryPaths: []string{filepath.Join(path.Dir(file), "..", "..", "..", "_kubernetes", “kube-github-operator-api", "apis", "v1alpha1", "crd")} , ControlPlaneStartTimeout: 20 * time.Second , ErrorIfCRDPathMissing: true , AttachControlPlaneOutput: false , KubeAPIServerFlags: []string { "--advertise-address=127.0.0.1" , "--etcd-servers={{ if .EtcdURL }}{{ .EtcdURL.String }}{{ end }}" , "--cert-dir={{ .CertDir }}" , "--insecure-port={{ if .URL }}{{ .URL.Port }}{{else}}0{{ end }}" , "{{ if .URL }}--insecure-bind-address={{ .URL.Hostname }}{{ end }}" , "--secure-port={{ if .SecurePort }}{{ .SecurePort }}{{ end }}", "--disable-admission-plugins=ServiceAccount" , "--service-cluster-ip-range=10.0.0.0/24" , "--allow-privileged=true" , } , } cfg, err := testEnv.Start( ) if err != nil { return nil, nil, fmt.Errorf("failed to start test env: %w", err ) } cli, err := client.New(cfg, client.Options { Scheme: s , })

Slide 23

Slide 23 text

envtest • Controller-runtimeが提供するテスト⽤のパッケージ • kube-apiserverとetcdのバイナリを実際に⽴てる • kube-apiserverリソース操作のみしか再現できない • Podとしてコントローラーを動作することができない Pros. IUUQTCPPLLVCFCVJMEFSJPSFGFSFODFFOWUFTUIUNM IUUQTQLHHPEFWHJUIVCDPNLVCFSOFUFTTJHTDPOUSPMMFSSVOUJNFQLHFOWUFTU IUUQTHJUIVCDPNLVCFSOFUFTTJHTDPOUSPMMFSSVOUJNFUSFFNBTUFSQLHFOWUFTU Cons.

Slide 24

Slide 24 text

構築が容易で使い捨て可能な 
 テスト⽤のKubernetesが欲しくなる w w w w w w

Slide 25

Slide 25 text

https://github.com/kubernetes-sigs/kind Kind

Slide 26

Slide 26 text

Kind • DockerコンテナとしてKubernetesのノードを起動 • 実際のクラスタと同じように振る舞うことができる • リソースやコントローラーのデプロイが必要 • テストフローの構築が⼤変 Pros. Cons.

Slide 27

Slide 27 text

Kindでのe2eテストフロー クラスタのセットアップ コントローラーのビルド・デプロイ 必要なツールのインストール テストシナリオの実⾏

Slide 28

Slide 28 text

Kindでのe2eテストフロー クラスタのセットアップ コントローラーのビルド・デプロイ 必要なツールのインストール テストシナリオの実⾏ Kind, kubectl, skaffoldなどのインストール Kubernetesクラスタを⽴ち上げ、必要なリソース(Namespace, CRDなど)を作成 Docker build したものをImageとしてPodへ反映 クラスタを操作し、適切なリソースの状態を再現する

Slide 29

Slide 29 text

かなり⼤変な実装

Slide 30

Slide 30 text

https://github.com/riita10069/ket

Slide 31

Slide 31 text

KETがやってくれること クラスタのセットアップ コントローラーのビルド・デプロイ 必要なツールのインストール テストシナリオの実⾏ Kind, kubectl, skaffoldなどのインストール Kubernetesクラスタを⽴ち上げ、必要なリソース(Namespace, CRDなど)を作成 Docker build したものをImageとしてPodへ反映 クラスタを操作し、適切なリソースの状態を再現する

Slide 32

Slide 32 text

KETがやってくれること クラスタのセットアップ コントローラーのビルド・デプロイ 必要なツールのインストール テストシナリオの実⾏ Kind, kubectl, skaffoldなどのインストール Kubernetesクラスタを⽴ち上げ、必要なリソース(Namespace, CRDなど)を作成 Docker build したものをImageとしてPodへ反映 クラスタを操作し、適切なリソースの状態を再現する

Slide 33

Slide 33 text

KETがやってくれること

Slide 34

Slide 34 text

Kindでのe2eテストフロー クラスタのセットアップ コントローラーのビルド・デプロイ 必要なツールのインストール テストシナリオの実⾏ Kind, kubectl, skaffoldなどのインストール Kubernetesクラスタを⽴ち上げ、必要なリソース(Namespace, CRDなど)を作成 Docker build したものをImageとしてPodへ反映 クラスタを操作し、適切なリソースの状態を再現する

Slide 35

Slide 35 text

for _, tt := range tests { tt := t t t.Run(tt.name, func(t *testing.T) { ctx := context.Background( ) err := kubectl.ApplyAllManifest(ctx, tt.fixture.manifestPaths, false ) for _, expect := range tt.res.A.Items { // check expec t } err = kubectl.DeleteAllManifest(ctx, tt.fixture.manifestPaths, true ) } ) } 1st, Create resources “declaratively” Maybe notify informer of the change. 2nd, Make sure the behavior of the Controller. 3rd, Restore the state of the resource. テストシナリオの実⾏

Slide 36

Slide 36 text

真の⼒には その拡張性が伴う w w w

Slide 37

Slide 37 text

func (k *Kubectl) ApplyFile(ctx context.Context, filePath string) error { args := []string { "apply" , "-f" , filePath , } err := k.Execute(ctx, args ) if err != nil { return err } return ni l } サポートされていないコマンドの作成

Slide 38

Slide 38 text

IUUQTFOHJOFFSJOHNFSDBSJDPNCMPHFOUSZGCC

Slide 39

Slide 39 text

IUUQTXXXZPVUVCFDPNXBUDI WV&RV+#W[H

Slide 40

Slide 40 text

まとめ より本番環境に近い GBLFDMJFOU FOWUFTU LFU ࣮Ϋϥελ 適切な試験を⾏えるツールを選ぶ

Slide 41

Slide 41 text

No content