Nginxが展開できない

概要

インカレ技術サークル ICTSC に入ったあなたは、Kubernetesクラスタチームに配属されました。
チームの先輩から、Kubernetes上にチーム紹介のWebサイトをつくるよう頼まれました。
Kubernetesのマニフェストは先輩に渡されたものから変更しないで欲しいそうです。
しかし、クラスタに適用したところ、Webサイト用のPodがPendingになってしまいます。
卒研の進捗が思わしくない先輩は教員の課題から手が離せないため、頑張ってあなたが解決してください。
解決後は、チーム名の書かれたWebサイトが見えるようにしておいてください。
問題が解決できればサークル内で共有したいため、原因と解決方法を報告してください。
先輩から渡され、k8sに適用したマニフェストは/home/user/manifestに保存されています。

前提条件

  • /home/user/manifestにあるファイルの内容を変更してはいけない

初期状態

  • NginxのDeploymentがPendingになっている。

終了状態

  • pendingとなっていたDeploymentが正常に稼働している。
  • 正常化したDeploymentによって稼働するNginxで、解答するチームの名前が書かれたWebサイトが確認できるようになっている。
  • 開始時と同じマニフェストのみが適用されている。

接続情報

VM名ホスト名
kzz-k8s-master192.168.12.1
kzz-k8s-node1192.168.12.2
kzz-k8s-node1192.168.12.3
kzz-k8s-node1192.168.12.4

解説

/home/user/manifestには、Flannel 、MetalLB、Rook、NginxのDeploymentが書かれたtest-nginx.yamlなどのマニフェストが保存されています。
test-nginx.yamlはPVC 、そのPVCを/usr/share/nginx/htmlにマウントするNginx のDeployment 及び、Nginx を公開するためのLoadBalancer Serviceを定義します。
問題環境では、問題名にあるNginx だけでなくPVC もPendingとなっています。
PendingになっているPVCをkubectl describe pvc cephfs-pvc で確認すると、failed to provision volume with StorageClassとエラーが出ています。

このKubernetesクラスタではRookを利用し、CephをPersistent Volumeとして使っています。
このことから、Rookの設定の異常等を予想し、Rookのエラーを確認する必要があります。
そのため、/home/user/manifestにあるRookのマニフェスト(cluster.yaml)では、無効化されているcrash-collectorを有効化し適用します。
立ち上がったcrash-collectorをkubectl describe で確認すると、Unable to attach or mount volumesとなっています。
Rookがマウントしてそうな場所を探すと、 cluster.yamlの33行目にdataDirHostPath: /var/lib/rookなる行があります。
そして、この直前の31行目のコメントに、

  # Important: if you reinstall the cluster, make sure you delete this directory from each host or else the mons will fail to start on the new cluster.

と書かれています。

原因としては、
Rookを削除する際にコンフィグ情報やログデータなどが保存されているdataDirHostPathを削除しなかったことです。
Rookを適用後、気まぐれに削除をした環境で、再度Rookを適用した場合に発生する現象です。
解決方法としては、RookのDocumentに書かれた通りにクラスターの清掃を行うだけです。
はじめに、適用されているRookを削除します。

kubectl delete -f filesystem.yaml
kubectl delete -f storageclass.yaml
kubectl delete -f toolbox.yaml
kubectl delete -f cluster.yaml
kubectl delete -f operator.yaml
kubectl delete -f common.yaml

今回のマニフェストでdataDirHostPathはデフォルトの/var/lib/rookとなっています。
全てのKubernetes Nodeの/var/lib/rookを削除します。
最後に、Rookを適用すると正常に稼働することが確認できます。
ただし、本問題の条件としてマニフェストを変更しないことが挙げられているので、crash-collectorを無効にしておく必要があります。

kubectl apply -f common.yaml
kubectl apply -f operator.yaml
kubectl apply -f cluster.yaml
kubectl apply -f toolbox.yaml
kubectl apply -f storageclass.yaml
kubectl apply -f filesystem.yaml 

ただ、チーム名の書かれたWebサイトは用意されていないので、kubectl exec -it ”Pod名” -- bashをしてNginxのpodに入ります。
そのShellで、 echo -e "<a>”チーム名”</a>" > /usr/share/nginx/html/index.html を行えば終了です。

今回はrook1.2を利用していたので手動で削除しましたが、1.3から自動で消してくれるCleanup Policyなるものがあるらしいです。

採点基準

  • 原因(/var/lib/rookがRook作成時に残っていたので、前のクラスタの認証情報に邪魔されてクラスタが作成できない)が述べられている。 40%
  • 各ノードの/var/lib/rookを削除し、kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') ceph status にてHealthが HEALTH_OKになっている 20%
  • pvcが作成され、PVCを利用したNginxのPodが展開されている。 30%
  • 踏み台から各チーム名が記載されたWebサイトが確認できる。 10%

反省

採点基準を分けたものの、解決していないとどれも満たせないことに採点中気づきました。