k8sのリソースなどをリストするためのいくつかの方法とkelmの紹介
こんにちは、この記事は Kubernetes2 Advent Calendar 2019 の14日目です。まさに当日倒れてしまい書けていなかったのだけど1週間遅れて書きました。
さて、僕は kelm というKubernetesのリソースとアクションをインタラクティブに選択・実行するツールを作っているのだけど、このツールの中でKubernetesのリソースをどのように取得しているかについて今回は紹介します。ついでにkelmの紹介もします(宣伝)。
まずはkelmについてですが、これは過去に記事を書いているのでそちらを読んでみてください。
さて、kelmはリソースをインタラクティブに選択するツールなので、当然リソースの一覧をKubernetesから取得する必要があります。現在は3種類の方法でリソース一覧を取得しています。
- client-goのkuberletes.Clientsetを直接使う
- client-goのDiscoveryClientを使う
- kubectlのresource.Builderを使う
1. client-goのkubernetes.Clientsetを直接使う
これはネームスペースをリストするために使っています。よく使う方法なのではないでしょうか?
r, err := k.client.CoreV1().Namespaces().List(metav1.ListOptions{})
if err != nil {
return "", err
}
2. client-goのdiscovery.DiscoveryClientを使う
kindの一覧を取得するために使っています。「kindの一覧」という表現が正しいか自信がないのだけど、podsやdeploymetntsのようなデフォルトのリソース定義名やCRDの定義名などを全て取得することが目的です。
discoveryClient, err := discovery.NewDiscoveryClientForConfig(k.config)
if err != nil {
return "", err
}
lists, err := discoveryClient.ServerPreferredResources()
if err != nil {
return "", err
}
3. kubectlのresource.Builderを使う
2で選択したkindのリソース一覧を取得するために使っています。
kubeConfigFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag()
matchVersionKubeConfigFlags := cmdutil.NewMatchVersionFlags(kubeConfigFlags)
f := cmdutil.NewFactory(matchVersionKubeConfigFlags)
r := f.NewBuilder().
Unstructured().
NamespaceParam(k.namespace).DefaultNamespace().AllNamespaces(false).
ResourceTypeOrNameArgs(true, []string{kind}...).
ContinueOnError().
Latest().
Flatten().
Do()
infos, err := r.Infos()
if err != nil {
return nil, err
}
kelmを作ってみないと色々種類があるのだな、ということを知ることはできなかったと思うので、作ってよかったなあと思います。kubectlのresource.Builderはあまり調べられていないので深掘りしてみたいですね。
kelmでできること紹介
最後に、kelmでどういうことができるのか紹介して終わりにします。kelmはデフォルトでいくつかのコマンドを内蔵しています(v0.0.6時点ではgetとdescribeのみ)。しかし、これだけだと不便なので、ユーザーが拡張できます。~/.kelm にyaml形式でkindとコマンド名、実行するコマンドを定義するだけ。jsonpathを使ってリソース情報を加工し、コマンドに渡すこともできます。
選択したPodのログを見る
actions:
pods:
- name: "log"
command: "kubectl -n {{ .Namespace }} log {{ .Obj.metadata.name }}"
選択したノードにSSHする
僕は「alias kssh “kelm –namespace default –kind nodes –action ssh”」のようにエイリアスを貼って活用しています。
actions:
nodes:
- name: "ssh"
variables:
- name: address
jsonpath: '{.status.addresses[?(@.type=="InternalIP")].address}'
command: 'ssh {{ .address }}'
特定デプロイメントに対してsternでログを見る
actions:
deployments:
- name: "stern"
command: "stern -n {{ .Namespace }} {{ .Obj.metadata.name }}"
特定のDaemonSetについて、Pod一覧を見る
joinLabelsはkelm内で実装しているテンプレート内で使える関数です。
actions:
daemonsets:
- name: "pods"
command: "kubectl -n {{ .Namespace }} get pods -l {{ joinLabels .Obj.spec.selector.matchLabels }}"
特定のDaemonSetについて、Pod一覧をwatchする
actions:
- name: "watchpods"
command: "watch -n 1 kubectl -n {{ .Namespace }} get pods -l {{ joinLabels .Obj.spec.selector.matchLabels }}"
この記事では、僕が作っているkelmをベースにしてKubernetesのいろんなものをリストするための方法をいくつか紹介しました。また、kelmのTipsについても紹介しました。似たようなことをしたい人の参考になれば幸いです。