Edited at

kubeadmが何をやっているのかみてみた

More than 1 year has passed since last update.

この記事はKubernetes Advent Calendar 2016 8日目の記事です。


サクッとクラスタを組みたい!

マルチノードでのKubernetesクラスタを構築する方法はいろいろありますが、王道的な方法がなく、いろんな方法で皆さん構築されてるかと思います。

Version 1.4からkubeadmという大抵の環境で簡単にクラスタ構築できる仕組みが入りました。詳しい方法は、こちらの記事が参考になります。

まだalphaなので、本番投入するには怖い感じなのですが、何をしてくれているのかコードを読んでみました。

(とくにCSR周りが怪しいので、間違いがあれば、ご指摘お願いします)


マスターの設定 (kubeadm init)


ノードの状態確認

ノード自身のIPアドレスが自動検出されます。

また、必要なサービスがインストール済みか、ポートが空いているか事前に確認します。このあたりのコードのRunInitMasterChecksあたりにチェック内容があります。


Manifestファイル作成

K8sの各コンポーネント(API Server, Controller manager, Scheduler)のマニフェストファイルを/etc/kubernetes/manifests配下に作成します。etcdのエンドポイントを指定しなかった場合、これも作成します。


PKI assets作成

K8sで使われる鍵やCAなどを/etc/kubernetes/pkiにサクッと作ってくれます。opensslコマンド叩かなくていいです。


クライアント用設定/接続確認

/etc/kubernetes/admin.confを作成した上で、作成したAPI serverに接続確認を行います。マスターにあるはずの3コンポーネントがあるかどうか確認したり、ダミーのPodをデプロイしてみて稼動確認までやってくれます。


kube-discovery立ち上げ

クラスタ情報をjoinしてくるノードに返すために、kube-discoveryなるものを立ち上げます。デフォルトでは9898ポートで待ち受けます。

$ kubectl get deploy kube-discovery --namespace=kube-system

NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
kube-discovery 1 1 1 1 1d

ノードがjoinするときにJWS(JSON Web Signature)を使ってクラスタ情報の署名をしています。その際に使うBearer TokenやAPI serverのエンドポイント、クラスタ用のCAをSecretとして保存します。

$ kubectl describe secret clusterinfo --namespace=kube-system

Name: clusterinfo
Namespace: kube-system
Labels: <none>
Annotations: <none>

Type: Opaque

Data
====
ca.pem: 1025 bytes
endpoint-list.json: 25 bytes
token-map.json: 29 bytes


kube-proxy, kube-dns立ち上げ

kube-proxyはDaemonSet、kube-dnsはDeploymentで。kube-dnsのレプリカ数は1なのでこのノードが落ちたらDNSも落ちます。


接続用情報表示

kubeadm join --token <tokenID>.<token> 192.168.0.2

無事に構築できるとこのクラスタにjoinするためのコマンドが表示されます。トークンはdotをセパレータとして前半がtokenID、後半がtokenとなります。


ノードの追加 (kubeadm join)

ということでjoinしてみます。


ノードの状態確認

マスター構築時と同じようにサービスの状態確認が行われます。


クラスタ情報取得

マスターノードに立ち上げられたkube-discoveryに対して、tokenIDをパラメータとしてクラスタ情報を要求します。

kube-discovery側では、先に作成されているはずのSecretを参照してtokenIDに紐づくtokenがあるか確認します。あった場合は、API serverのエンドポイント情報、クラスタのCAを返します。

返ってきたクラスタ情報はtokenをキーとしてJWSで署名されています。joinする側はそれを検証して、そのエンドポイントに対してアクセスします。


TLSのセットアップ

Certificates APIに対してCSRを投げて、kubeletがAPI serverにアクセスするための証明書を受け取ります。CSRは以下のコマンドで確認可能です。

$ kubectl get csr

NAME AGE REQUESTOR CONDITION
csr-xxxxx 1d kubeadm-node-csr Approved,Issued
$ kubectl describe csr csr-xxxxx

ドキュメントによると証明書は1年間有効(というか使用しているライブラリのデフォルト値)です。期限きれる前に更新しないといけないはずなんですが、どう更新すればいいんでしょうね…

最後に/etc/kubernetes/kubelet.confに設定を書き込んで終わりです。


で、本番に使えそうなのか

テスト環境用に構築するのだとものすごく楽にできるのですが、本番で使おうとすると結局いろいろ設定しなおさないといけないのでオススメできないです。ただ、ちゃんと証明書もきちんとセットアップしてくれるので、どのようにKubernetesをセットアップするべきかというサンプルとしては面白いと思います。