k8sのリソースなどをリストするためのいくつかの方法とkelmの紹介

Pocket

こんにちは、この記事は Kubernetes2 Advent Calendar 2019 の14日目です。まさに当日倒れてしまい書けていなかったのだけど1週間遅れて書きました。

さて、僕は kelm というKubernetesのリソースとアクションをインタラクティブに選択・実行するツールを作っているのだけど、このツールの中でKubernetesのリソースをどのように取得しているかについて今回は紹介します。ついでにkelmの紹介もします(宣伝)。

まずはkelmについてですが、これは過去に記事を書いているのでそちらを読んでみてください。

さて、kelmはリソースをインタラクティブに選択するツールなので、当然リソースの一覧をKubernetesから取得する必要があります。現在は3種類の方法でリソース一覧を取得しています。

  1. client-goのkuberletes.Clientsetを直接使う
  2. client-goのDiscoveryClientを使う
  3. 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についても紹介しました。似たようなことをしたい人の参考になれば幸いです。

Leave a Reply

Your email address will not be published. Required fields are marked *