Overview
Kubernetes 環境で複数のクラスターを管理する際、export KUBECONFIG=<kubeconfig>
で指定するか、デフォルトの ${HOME}/.kube/config
で全てを管理できるように kubeconfig をマージしてコンテキストで管理するかの 2 つの方法があります。本稿では、両者の比較と課題を考察します。
export KUBECONFIG=<kubeconfig>
export KUBECONFIG=<kubeconfig> で管理するメリットは簡便で分かりやすいことです。以下のように環境変数を設定することで対象のクラスターに接続できるようになります。
export KUBECONFIG=${HOME}/.kube/k8s-cluster-01
export KUBECONFIG=${HOME}/.kube/k8s-cluster-02
デメリットとしては、kubeconfig 内のクラスター名が重複していると、どのクラスターで操作しているのかわからなくなってしまうことがある点です。これは kubeconfig のクラスター名を書き換えれば良いのですが、人的なチェックに依存してしまうことが課題かもしれません。
コンテキストによる管理
コンテキストによる管理は、複数のクラスターの kubeconfig をマージすることで可能になります。
kubeconfig をマージ
以下のように 2 つの kubeconfig が存在しているとします。各クラスターは、kubeadm init の実行時に一意のクラスター名になるように設定しています。
k8s-cluster-01 は以下の通りです。kubeconfig の構造は、cluster, contexts, users のセクションがあり、cluster, users の情報を使用して contexts が構成されています。kubectl config get-contexts
などで出力される情報は、この contexts そのものです。
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: <certificate-authority-data>
server: https://10.65.9.180:6443
name: k8s-cluster-01
contexts:
- context:
cluster: k8s-cluster-01
user: kubernetes-admin
name: kubernetes-admin@k8s-cluster-01
current-context: kubernetes-admin@k8s-cluster-01
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: <client-certificate-data>
client-key-data: <client-key-data>
k8s-cluster-02 は以下の通りです。
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: <certificate-authority-data>
server: https://10.66.9.180:6443
name: k8s-cluster-02
contexts:
- context:
cluster: k8s-cluster-02
user: kubernetes-admin
name: kubernetes-admin@k8s-cluster-02
current-context: kubernetes-admin@k8s-cluster-02
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: <client-certificate-data>
client-key-data: <client-key-data>
以下のようにマージします。
export KUBECONFIG=${HOME}/.kube/k8s-cluster-01:${HOME}/.kube/k8s-cluster-02
kubectl config view --merge --flatten > ${HOME}/.kube/config
export KUBECONFIG=${HOME}/.kube/config
マージされた kubeconfig は以下の通りですが、これには問題があります。
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: <certificate-authority-data>
server: https://10.65.9.180:6443
name: k8s-cluster-01
- cluster:
certificate-authority-data: <certificate-authority-data>
server: https://10.66.9.180:6443
name: k8s-cluster-02
contexts:
- context:
cluster: k8s-cluster-01
user: kubernetes-admin
name: kubernetes-admin@k8s-cluster-01
- context:
cluster: k8s-cluster-02
user: kubernetes-admin
name: kubernetes-admin@k8s-cluster-02
current-context: kubernetes-admin@k8s-cluster-02
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: <client-certificate-data>
client-key-data: <client-key-data>
元々、k8s-cluster-01, k8s-cluster-02 にはユーザー名として kubernetes-admin が設定されており、マージによって単一の設定に上書きされています。client-certificate-data, client-key-data はそれぞれ異なるため、この場合では、どちらかのクラスターにしか接続できない状態となります。
これを解消する場合、ユーザー名が一意になるように元のファイルを編集してからマージすることで、それぞれの情報が保持されます。
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: <certificate-authority-data>
server: https://10.65.9.180:6443
name: k8s-cluster-01
contexts:
- context:
cluster: k8s-cluster-01
user: kubernetes-admin-01
name: kubernetes-admin-01@k8s-cluster-01
current-context: kubernetes-admin-01@k8s-cluster-01
kind: Config
preferences: {}
users:
- name: kubernetes-admin-01
user:
client-certificate-data: <client-certificate-data>
client-key-data: <client-key-data>
k8s-cluster-02 も同じように編集します。
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: <certificate-authority-data>
server: https://10.66.9.180:6443
name: k8s-cluster-02
contexts:
- context:
cluster: k8s-cluster-02
user: kubernetes-admin-02
name: kubernetes-admin-02@k8s-cluster-02
current-context: kubernetes-admin-02@k8s-cluster-02
kind: Config
preferences: {}
users:
- name: kubernetes-admin-02
user:
client-certificate-data: <client-certificate-data>
client-key-data: <client-key-data>
マージします。
export KUBECONFIG=${HOME}/.kube/k8s-cluster-01:${HOME}/.kube/k8s-cluster-02
kubectl config view --merge --flatten > ${HOME}/.kube/config
export KUBECONFIG=${HOME}/.kube/config
以下のようにユーザー情報が保持されます。
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: <certificate-authority-data>
server: https://10.65.9.180:6443
name: k8s-cluster-01
- cluster:
certificate-authority-data: <certificate-authority-data>
server: https://10.66.9.180:6443
name: k8s-cluster-02
contexts:
- context:
cluster: k8s-cluster-01
user: kubernetes-admin-01
name: kubernetes-admin-01@k8s-cluster-01
- context:
cluster: k8s-cluster-02
user: kubernetes-admin-02
name: kubernetes-admin-02@k8s-cluster-02
current-context: kubernetes-admin-02@k8s-cluster-02
kind: Config
preferences: {}
users:
- name: kubernetes-admin-01
user:
client-certificate-data: <client-certificate-data>
client-key-data: <client-key-data>
- name: kubernetes-admin-02
user:
client-certificate-data: <client-certificate-data>
client-key-data: <client-key-data>
コンテキストの操作
カレントコンテキストの確認
現在のコンテキストを確認するには以下を実行します。
kubectl config current-context
現在のコンテキストが出力されます。
kubernetes-admin-02@k8s-cluster-02
コンテキストの一覧
コンテキストの一覧を表示するには以下を実行します。
kubectl config get-contexts
コンテキストの一覧が表示されます。* はカレントコンテキストを示しています。
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
kubernetes-admin-01@k8s-cluster-01 k8s-cluster-01 kubernetes-admin-01
* kubernetes-admin-02@k8s-cluster-02 k8s-cluster-02 kubernetes-admin-02
コンテキストの切り替え
コンテキストを切り替えるには以下を実行します。
kubectl config use-context kubernetes-admin-01@k8s-cluster-01
コンテキストで管理する場合のメリットとデメリット
おそらく、Kubernetes としては、複数のクラスターを管理する場合はコンテキストを使用することが推奨されると思います。なぜなら、そうでなければコンテキストの管理コマンドが存在意義がないからです。また、kubeconfig をマージする際に、必ず、クラスター名とユーザー名を一意にする必要があることから、環境変数を使用することによるクラスター名の重複表示問題を緩和できます。もちろん、一意にするための操作に問題があれば意味はありません。
一方で、kubeconfig の管理が煩雑になります。特に個人的な不満としては、ユーザー名をクラスター毎に分けないといけない点です。クラスター名で一意になっているので、それを元にユーザー名を同じにできればベストなのですが、それには個別の証明書をインポートするなどの対応が必要なようなので、それは別の機会に実験しようと思います。
まとめ
今回、改めて kubeconfig について調べましたが、署名書や鍵の情報以外は kubeconfig の中に閉じた情報であることに気づいたのはとても良かったと思います。結構、実践から Kubernetes を始めた人は勘違いしている人も多いのではないかと思います。結論としては、小規模なら環境変数で良く、大規模ならコンテキストで管理するのが良いと思いますが、仕事で使うケースがあるなら、コンテキストに慣れておく方が良いと思いました。