kubernetes便利ですよね。
golangでkubernetesを操作するときはclient-goという便利なライブラリがあるので、基本的にはこれを見れば完結します。
しかし、最近CRD(Custom Resource Definition)という自作Objectを作成したときに色々ハマったので、記事として残しておきます。
Objectとは
要はDeploymentとかServiceとかのことです。
今回は簡単のために、Jobを使います。
適宜自分が使いたいものに変えてください。
CRDを使わない場合
1つ目の方法はclient-goを使うものです。
client-goは名前そのままでkubernetesと通信をするためのクライアントのライブラリです。
以下のコードは簡単なJobを起動するためのコードです。
package main
import (
"log"
batchv1 "k8s.io/api/batch/v1"
apiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
func main() {
config, err := rest.InClusterConfig()
if err != nil {
panic(err.Error())
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
jobClient := clientset.BatchV1().Jobs("default")
job := &batchv1.Job{
// 省略...
}
job, err = jobClient.Create(job)
if err != nil {
log.Printf("Failed to create job: %v", err)
}
}
この方法の欠点としては k8s.io/client-go/kubernetes
に存在しているものしか作ることは出来ません。(DeploymentとかJobとか)
なので、もしCRD(Custom Resource Definition)を使う場合は上の方法では作成することは出来ないようです。(* 後ろの方にCRDでも実装する方法を書いています。)
その場合は以下の方法で作成してみてください。
CRDを使う場合
こっちもclient-goは使ってはいるのですが、メインはcontroller-runtime/pkg/client
です。
package main
import (
"context"
"fmt"
"log"
batchv1 "k8s.io/api/batch/v1"
apiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"
clientPkg "sigs.k8s.io/controller-runtime/pkg/client"
)
func main() {
// Kubernetesの設定
config, err := rest.InClusterConfig()
if err != nil {
panic(err.Error())
}
scheme := runtime.NewScheme()
batchv1.AddToScheme(scheme)
option := clientPkg.Options{
Scheme: scheme,
}
client, err := clientPkg.New(config, option)
if err != nil {
fmt.Println(err)
return
}
job := &batchv1.Job{
// 省略...
}
ctx := context.Background()
err = client.Create(ctx, job)
if err != nil {
log.Printf("Failed to create job %v\n", err)
}
}
気をつけるポイントとしては、
batchv1.AddToScheme(scheme)
の部分です。ここを適宜CRDのディレクトリのSchemeとして指定すると良いです。
ちなみにCRDを使って最初の方法で実装出来るらしいです。
上の記事はちゃんと見たわけでは無いですが、自分でClientを自作して呼び出している感じですね。
地味にハマったポイント
今回は client-go
のv11.0.0を使っていたんですが、以下のようなエラーが結構出てきました。
ググればすぐに解決策が出てくるのですが、念の為ここにも書いておきます。
# k8s.io/client-go/rest
../pkg/mod/k8s.io/client-go@v11.0.0+incompatible/rest/request.go:598:31: not enough arguments in call to watch.NewStreamWatcher
have (*versioned.Decoder)
want (watch.Decoder, watch.Reporter)
Go modulesを使っている場合は以下のようになると思います。
引用元: client-go/INSTALL.md
$ go get k8s.io/client-go@v11.0.0 # replace v11.0.0 with the required version (or use kubernetes-1.x.y tags if desired)
$ go get k8s.io/api@kubernetes-1.14.0 # replace kubernetes-1.14.0 with the required version
$ go get k8s.io/apimachinery@kubernetes-1.14.0 # replace kubernetes-1.14.0 with the required version