2016/11/15 10:15 追記
この記事では kubernetes/kubernetes リポジトリに含まれているクライアントライブラリを紹介していますが、今年の8月だか9月になって API クライアントだけが別リポジトリとして切り出されました。
今後何かツールを作るときは、この client-go を使うのがよいでしょう。
というわけで、以下の内容は__記事初公開時点の、client-go がなかった時代の__ものとなっております。その点ご留意いただいた上でお読みください。
追記終わり
あまり知られてないようですが、Kubernetes には公式の Go 製 API クライアントライブラリがあります。kubectl
もこのライブラリを用いて実装されています。
kubectl
は確かに万能なんですが、実運用に投入するとなるとその万能さがマイナスに効いてくることもあります。で、自分たちが使いやすいように kubectl
をラップした何かを作りたくなるのですが、他の言語から kubectl
をサブコマンド呼び出しするのは筋が悪いです。API ライブラリを使ってネイティブレベルで Kubernetes を操作するようにしましょう。
いきなりサンプルコード
というわけで、Pod の名前一覧を表示するだけのサンプルコードです。
package main
import (
"fmt"
"os"
"k8s.io/kubernetes/pkg/api"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
)
func newKubeClient() (*client.Client, error) {
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
loadingRules.ExplicitPath = clientcmd.RecommendedHomeFile
loader := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{})
clientConfig, err := loader.ClientConfig()
if err != nil {
return nil, err
}
kubeClient, err := client.New(clientConfig)
if err != nil {
return nil, err
}
return kubeClient, nil
}
func main() {
kubeClient, err := newKubeClient()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
pods, err := kubeClient.Pods(api.NamespaceDefault).List(api.ListOptions{})
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
for _, pod := range pods.Items {
fmt.Println(pod.Name)
}
}
出力は以下のようになります。
$ go run listpods.go
hello-world-e2d3x
wordpress-mysql-488205646-t6v4k
ちなみに kubectl get pods
だとこうなります。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world-e2d3x 1/1 Running 0 8d
wordpress-mysql-488205646-t6v4k 1/1 Running 0 8d
コード解説
API クライアントインスタンスの作成
最初に、ローカルのコンフィグファイルを読み込みます。
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
loadingRules.ExplicitPath = clientcmd.RecommendedHomeFile
clientConfig, err := loader.ClientConfig()
if err != nil {
return nil, err
}
kubeClient, err := client.New(clientConfig)
if err != nil {
return nil, err
}
loadingRules.ExplicitPath
にコンフィグファイルのパスを指定します。定数 RecommendedHomeFile
は ~/.kube/config
を指しています。kubectl
がデフォルトで見に行くパスですね。
kubectl --kubeconfig /path/to/kubecfg
のようにパスを明示的に指定したい場合は、
loadingRules.ExplicitPath = /path/to/kubecfg
にそのパスを代入すればよいです。
API を叩く
kubeClient.リソース.操作
の形になっています。
pods, err := kubeClient.Pods(api.NamespaceDefault).List(api.ListOptions{})
まず Pods
や Secrets
のように操作対象リソースを指定します。引数には Namespace を指定します。自分で指定することもできますが、api.NamespaceDefault
や api.NamespaceSystem
のように定数も用意されてます。
続いて操作内容を指定します。名前を指定して Pod を取得するなら Get(name)
ですし、全部の Pod を撮りたいなら List()
です。
得られた Pod 一覧の中身を出力する
for _, pod := range pods.Items {
fmt.Println(pod.Name)
}
実際の配列は pods
ではなく pods.Items
に格納されています。
注意
k8s.io/kubernetes
は Kubernetes 本体のリポジトリなので、API クライアントを import するには Kubernetes のソースコード (+ 依存リポジトリ、docker/docker とか) を全部落としてくる必要があります。数百 Mbyte あるので、Godeps みたいにリポジトリへ vendor を含める場合は要注意です。glide 使いましょう。
おわりに
Kubernetes の Go API クライアントライブラリを用いて、Go から直接 Kubernetes を操作する手法を紹介しました。最初に書き方さえ覚えてしまえば、あとはどのリソースや操作に対しても比較的簡単に実装できると思います。
自分は最近、このライブラリを使って k8sec というツールを作りました。k8sec は Heroku の config のように、k8sec set key1=val1 key2=val2
の形で Kubernetes の Secret を管理できるコマンドラインツールです。あわせてご覧 & ご利用ください。
REF
- https://godoc.org/k8s.io/kubernetes/pkg/api
-
https://godoc.org/k8s.io/kubernetes/pkg/client/unversioned
- ライブラリのドキュメントです。ただ、実装するときはエディタ補完や godef を駆使していくほうがやりやすいです(個人の感想です)
-
kubernetes/client-libraries.md at master · kubernetes/kubernetes
- API クライアントライブラリ一覧。Go 以外の言語は有志が作成したものです。
- How can I create a simple client app with the Kubernetes Go library? - Stack Overflow
- timoreimann/kubernetes-goclient-example: An example implementation of a Golang client for Kubernetes.