TT Lab
はじめる
学ぶ 学習パス コース

Kubespray と Terraform でクラスターを構築する

failed=0 は始まりにすぎない — Kubespray クラスターを層ごとに確かめる

TT Labで続きを見る

一言でいうと

kubesprayで構築したクラスターは、kubeadmのクラスターと見た目は同じですが、etcd・DNS・証明書の3か所が異なる形で置かれているので、検証もその3か所を別々に見る必要があります。

なぜ必要なのか

インストールが終わると、人はkubectl get nodesの1行を見て、Readyなら終わりにします。ところがノードのReadyは、kubeletがAPIサーバーに状態を報告していて、CNIの設定ファイルがあるという意味にすぎません。Podがイメージを取得できるか、サービスIPにリクエストが届くか、名前が解決されるか、1年後に何が止まるかは、その1行にはありません。しかもkubesprayは、kubeadmのデフォルトと異なる選択をいくつかします。その違いを知らないと、kubeadmのドキュメントの点検手順をそのまま行って、肝心な場所を飛ばしてしまいます。

どう動くのか

ノードとテイント。kubeadmは、コントロールプレーンのノードにnode-role.kubernetes.io/control-plane:NoScheduleテイントを付けます。kubesprayは、インベントリでそのノードがkube_nodeにも入っていれば、「Remove taint for control plane node with node role」というタスクで、このテイントを削除します。そのため、ノード1台のkubesprayクラスターは、何もしなくても一般のPodを受け入れます。インベントリのグループ配置が、そのままスケジューリングポリシーになるわけです。

etcdはPodではありません。group_vars/all/etcd.ymlのetcd_deployment_typeのデフォルトがhostなので、etcdはkubesprayがダウンロードしたバイナリで、ホストのetcd.serviceとして起動します。kube-systemをいくら見ても、etcdのPodはなく、状態はsystemctl status etcdと/etc/etcd.envで見ます。APIサーバーは、このetcdを「外部etcd」として結び付きます。

証明書は2系統あります。kubeadmが作るもの(APIサーバー、コントローラーとスケジューラーのkubeconfigなど)は、kubesprayでは/etc/kubernetes/sslにあり、リーフ証明書は1年、CAは10年です。このVMでkubeadm certs check-expirationは、リーフ364日、CA 9年を表示し、etcdは一覧にありませんでした。外部etcdだからです。etcdの証明書は、kubesprayのmake-ssl-etcd.shがopensslで作り、期間はcertificates_duration(デフォルトは36500日、約100年)です。どちらが先に期限切れになるかを見ると、1年以内にやることはkubeadm側の更新だということが、はっきりします。

DNSは2段構成です。kubesprayはデフォルトでnodelocaldnsを有効にします。ノードごとにDaemonSetが、リンクローカルアドレス(デフォルトは169.254.25.10)でキャッシュDNSを動かし、kubeletのclusterDNSが、そのアドレスをPodに知らせます。キャッシュが知らない名前だけがCoreDNSに渡ります。そのため、「DNSが動く」ことを確認するには、CoreDNSのServiceのアドレスとnodelocaldnsのアドレスの両方に問い合わせる必要があり、Podが実際に使うのは後者です。KubernetesのドキュメントのNodeLocal DNSCacheの説明のとおり、この配置は、conntrackの競合とCoreDNSの負荷を減らすためのものです。

インストールの記録。kubesprayは、kubeadmを呼び出すときに使った/etc/kubernetes/kubeadm-config.yaml、etcdの/etc/etcd.env、ダウンロードしたバイナリのキャッシュ/tmp/releases(local_release_dir)を、ノードに残します。3か月後に「このクラスターは、どの値で構築したのか」を尋ねるとき、インベントリの次に見る一次資料です。

現場での姿

このコースの実測クラスター(1.35.8、calico)で、kube-systemにはcalico-kube-controllers、calico-node、coredns、dns-autoscaler、kube-apiserver、kube-controller-manager、kube-proxy、kube-scheduler、nodelocaldnsが起動しました。CoreDNSは1つでしたが、レプリカ数をdns-autoscalerがノードとコアの数に合わせて決めるからです。ノードが増えると、CoreDNSも増えます。

現場で最もよくある勘違いは、証明書です。モニタリングがkubeadm certs check-expirationの結果だけを取得していると、etcdの証明書は永遠に監視されません。今回の配置では、etcd側が100年なので問題になりませんが、誰かがcertificates_durationを短くしていたり、etcdをkubeadmの配置に変えていたりすれば、話が変わります。チェックリストでは、「どのツールがどの証明書を作ったか」が先に来る必要があります。

最後の証拠は、ワークロードです。Pod 2つのDeploymentとServiceの1つにリクエストを送り、2つのPod名が両方とも返ってくれば、レジストリへのエグレス・スケジューリング・Podネットワーク・kube-proxyが、一度に確認できます。緑の表示が複数あるよりも、リクエスト1回のほうが、多くを語ってくれます。

次のラボですること

クラスターを構築した後、ノードのロールとテイントを読み取り、コアPodの一覧でetcdが抜けている理由をsystemdで確認します。nodelocaldnsとCoreDNSにそれぞれ名前を問い合わせて、2段のDNSを確認し、kubeadmの証明書とetcdの証明書の有効期限をopensslで読み取ります。kubesprayが残した設定ファイルを確認したうえで、小さなワークロードに実際にリクエストを送って締めくくります。