repl.info

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

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

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

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

kelmというk8sのリソースとアクションをインタラクティブに選択・実行するツールを作っている

さて、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についても紹介しました。似たようなことをしたい人の参考になれば幸いです。