kubectlの接続設定ファイル（kubeconfig）の概要

## 概要と目的

普段`kubectl`を使ってkubernetes(以下k8s)クラスタにAPI呼び出しをしているのですが、`kubectl`コマンドがどのように接続先を選んでいるのかをしっかり把握していなかったので改めて公式Documentを読みました。基本的には[こちら](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)を参照して頂けると`kubectl`の接続設定については理解できると思います。今回はせっかく調べたので備忘録と、Documentを読む前に概要を押さえたいという方のために記事にしました。

## kubeconfigとは？

`kubectl`とは、k8sクラスタのAPIサーバーと通信するためのコマンドラインツールです。

そして、どのk8sクラスタにどのユーザーとして接続するのかの接続設定をkubeconfigファイルが定義し、クライアントにあるkubeconfigファイルを`kubectl`が読み取って接続先を決めています。kubeconfigとはあくまでクラスタへの接続設定ファイルの総称であり、実際に「kubeconfig」という名前のファイルとは限りません。（ではどのようにkubeconfigだと認識できるかは後述します。）

まずは、現在利用しているkubeconfigを確認してみましょう。`kubectl config view`コマンドで確認できます。

以下は、developerというユーザーが開発用のdevelopmentというクラスタへ接続し、experimenterというユーザーが実験用のexperimentクラスタへ接続することができる設定を表しています。

```shell
$ kubectl config view

apiVersion: v1
kind: Config
preferences: {}

users: # 接続可能なユーザー一覧
- name: developer
  user:
    client-certificate: fake-cert-file
    client-key: fake-key-file
- name: experimenter
  user:
    password: some-password
    username: exp

clusters: # 接続可能なクラスタの一覧
- cluster:
    certificate-authority: /Users/some-developer/ca.crt
    server: https://123.456.64.6:8443
  name: development
- cluster:
    insecure-skip-tls-verify: true
    server: https://1.2.3.4
  name: experiment

contexts: # 利用可能なcontextの一覧
- context:
    cluster: development
    namespace: awesome-application
    user: developer
  name: dev-application
- context:
    cluster: experiment
    namespace: default
    user: experimenter
  name: exp-sandbox

# 現在接続時に利用されるContext
current-context: dev-application
```

ここでcontextsという項目がありますが、contextは、接続対象クラスタ、その中のnamespace、接続するユーザーのセットを表現したものです。

[参照](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#context)
> A context element in a kubeconfig file is used to group access parameters under a convenient name. Each context has three parameters: cluster, namespace, and user. 


そしてcurrent-contextの項目でcontextの指定なしで`kubectl`を利用した場合に利用されるcontextが指定されています。これは、以下のコマンドでも確認できます。

```shell
$ kubectl config current-context

dev-application
```

また、現在のcontextに関するkubeconfigの内容だけ確認したい場合は以下の`--minify`フラグが利用できます。

```shell
$ kubectl config view --minify

apiVersion: v1
kind: Config
preferences: {}

users: # 接続可能なユーザー一覧
- name: developer
  user:
    client-certificate: fake-cert-file
    client-key: fake-key-file

clusters: # 接続可能なクラスタの一覧
- cluster:
    certificate-authority: /Users/some-developer/ca.crt
    server: https://123.456.64.6:8443
  name: development

contexts: # 利用可能なcontextの一覧
- context:
    cluster: development
    namespace: awesome-application
    user: developer
  name: dev-application

# 現在接続時に利用されるContext
current-context: dev-application
```

他には、`kubectl config use-context [context name] `でデフォルトで利用されるcontextを指定できたり、`kubectl config set-context [context name]`で利用するcontextを追加できます。

## kubeconfigファイルの指定方法

今まではkubeconfigの内容を見てきましたが、実際はどこのファイルを読み取っているのか、また読み取り先を指定するにはどうしたらいいかを確認していきます。
結論から言うと、kubectlは以下の順番でkubeconfigを探しにいきます。

1. --kubeconfig フラグで指定されたパス
2. $KUBECONFIG 環境変数に指定されたパス一覧
3. ~/.kube/config 

詳しくは[こちら](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#merging-kubeconfig-files)に載っています。

KUBECONFIGは、複数のパスを指定することができ、それらのパスの内容をマージした内容がkubeconfigになります。コロン（Linux, MacOS）もしくはセミコロン(Windows)で複数のパスを区切って指定します。

[参照](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#the-kubeconfig-environment-variable)
> The KUBECONFIG environment variable holds a list of kubeconfig files. For Linux and Mac, the list is colon-delimited. For Windows, the list is semicolon-delimited. 

また、KUBECONFIGは絶対パスでない場合は、kubectl実行時のディレクトリを基準に探されるので注意が必要です。

他には、複数箇所でKUBECONFIGにパスを渡す場合は、前回追加した分を上書きしないように、以下のようにすることで追加することが必要になります。

```shell
export KUBECONFIG=$KUBECONFIG:$HOME/config
```

## 参考

- [Configure Access to Multiple Clusters](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)
- [Organizing Cluster Access Using kubeconfig Files](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/)